The agent's wallet. Use this skill to safely create a wallet the agent can use for transfers, swaps, and any EVM chain transaction.
---
name: Agent Wallet
description: The agent's wallet. Use this skill to safely create a wallet the agent can use for transfers, swaps, and any EVM chain transaction.
---
# Agent Wallet
Use this skill to safely create a wallet the agent can use for transfers, swaps, and any EVM chain transaction without ever exposing private keys to the agent. Create a wallet, set spending policies, and your agent can transfer tokens, do swaps, and interact with smart contracts within the boundaries you define.
**The agent never sees the private key.** All transactions are executed server-side through a smart account. The wallet owner controls what the agent can do via configurable policies.
## Configuration
- **Base API URL:** Use the `SAFESKILLS_API_URL` environment variable if set, otherwise default to `https://safeskill-production.up.railway.app`
- **Frontend URL:** Use the `SAFESKILLS_FRONTEND_URL` environment variable if set, otherwise default to `https://safeskill-production.up.railway.app`
All API requests require a Bearer token (the API key returned when creating a wallet).
```
Authorization: Bearer <API_KEY>
```
## Quick Start
### 1. Create a Wallet
Create a new smart account wallet for your agent. This generates a private key server-side (you never see it), creates a ZeroDev smart account, and returns an API key for the agent plus a claim URL for the wallet owner.
```bash
curl -X POST "${SAFESKILLS_API_URL:-https://safeskill-production.up.railway.app}/api/secrets" \
-H "Content-Type: application/json" \
-d '{
"type": "EVM_WALLET",
"memo": "My agent wallet",
"chainId": 84532
}'
```
Response includes:
- `apiKey` -- store this securely; use it as the Bearer token for all future requests
- `claimUrl` -- share this with the user so they can claim the wallet and set policies
- `address` -- the smart account address
After creating, tell the user:
> "Here is your wallet claim URL: `<claimUrl>`. Use this to claim ownership, set spending policies, and monitor your agent's wallet activity."
### 2. Get Wallet Address
```bash
curl -X GET "${SAFESKILLS_API_URL:-https://safeskill-production.up.railway.app}/api/skills/evm-wallet/address" \
-H "Authorization: Bearer <API_KEY>"
```
### 3. Check Balances
```bash
# Native balance only
curl -X GET "${SAFESKILLS_API_URL:-https://safeskill-production.up.railway.app}/api/skills/evm-wallet/balance" \
-H "Authorization: Bearer <API_KEY>"
# With ERC-20 tokens
curl -X GET "${SAFESKILLS_API_URL:-https://safeskill-production.up.railway.app}/api/skills/evm-wallet/balance?tokens=0xTokenAddr1,0xTokenAddr2" \
-H "Authorization: Bearer <API_KEY>"
```
### 4. Transfer ETH or Tokens
```bash
# Transfer native ETH
curl -X POST "${SAFESKILLS_API_URL:-https://safeskill-production.up.railway.app}/api/skills/evm-wallet/transfer" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"to": "0xRecipientAddress",
"amount": "0.01"
}'
# Transfer ERC-20 token
curl -X POST "${SAFESKILLS_API_URL:-https://safeskill-production.up.railway.app}/api/skills/evm-wallet/transfer" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"to": "0xRecipientAddress",
"amount": "100",
"token": "0xTokenContractAddress"
}'
```
### 5. Swap Tokens
Swap one token for another using DEX liquidity (powered by 0x).
```bash
# Preview a swap (no execution, just pricing)
curl -X POST "${SAFESKILLS_API_URL:-https://safeskill-production.up.railway.app}/api/skills/evm-wallet/swap/preview" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"sellToken": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"buyToken": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"sellAmount": "0.1",
"chainId": 1
}'
# Execute a swap
curl -X POST "${SAFESKILLS_API_URL:-https://safeskill-production.up.railway.app}/api/skills/evm-wallet/swap/execute" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"sellToken": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"buyToken": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"sellAmount": "0.1",
"chainId": 1,
"slippageBps": 100
}'
```
- `sellToken` / `buyToken`: Token contract addresses. Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for native ETH.
- `sellAmount`: Human-readable amount to sell (e.g. `"0.1"` for 0.1 ETH).
- `chainId`: The chain to swap on (1 = Ethereum, 137 = Polygon, 42161 = Arbitrum, 10 = Optimism, 8453 = Base, etc.).
- `slippageBps`: Optional slippage tolerance in basis points (100 = 1%). Defaults to 100.
The preview endpoint returns expected buy amount, route info, and fees without executing. The execute endpoint performs the actual swap through the smart account, handling ERC20 approvals automatically.
### 6. Send Arbitrary Transaction
Interact with any smart contract by sending custom calldata.
```bash
curl -X POST "${SAFESKILLS_API_URL:-https://safeskill-production.up.railway.app}/api/skills/evm-wallet/send-transaction" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"to": "0xContractAddress",
"data": "0xCalldata",
"value": "0"
}'
```
## Policies
The wallet owner controls what the agent can do by setting policies via the claim URL. If a transaction violates a policy, the API will reject it or require human approval via Telegram.
| Policy | What it does |
|--------|-------------|
| **Address allowlist** | Only allow transfers/calls to specific addresses |
| **Token allowlist** | Only allow transfers of specific ERC-20 tokens |
| **Function allowlist** | Only allow calling specific contract functions (by 4-byte selector) |
| **Spending limit (per tx)** | Max USD value per transaction |
| **Spending limit (daily)** | Max USD value per rolling 24 hours |
| **Spending limit (weekly)** | Max USD value per rolling 7 days |
| **Require approval** | Every transaction needs human approval via Telegram |
| **Approval threshold** | Transactions above a USD amount need human approval |
If no policies are set, all actions are allowed by default. Once the owner claims the wallet and adds policies, the agent operates within those boundaries.
## Important Notes
- **Never try to access raw secret values.** The private key stays server-side -- that's the whole point.
- Always store the API key from wallet creation -- it's the only way to authenticate.
- Always share the claim URL with the user after creating a wallet.
- The default chain ID is `84532` (Base Sepolia testnet). Adjust as needed.
- If a transaction is rejected, it may be blocked by a policy. Tell the user to check their policy settings via the claim URL.
- If a transaction requires approval, it will return `status: "pending_approval"`. The wallet owner will receive a Telegram notification to approve or deny.
don't have the plugin yet? install it then click "run inline in claude" again.
restructured into implexa's six-part format, added explicit decision branches for policy violations and error handling, documented external safeskills connection with auth and env vars, clarified output contract with json examples, and added outcome signals tied to api state changes.
use this skill to safely create a wallet the agent can use for transfers, swaps, and any evm chain transaction without ever exposing private keys to the agent. create a wallet, set spending policies, and your agent can transfer tokens, do swaps, and interact with smart contracts within the boundaries you define. the agent never sees the private key. all transactions are executed server-side through a smart account. the wallet owner controls what the agent can do via configurable policies.
environment variables:
SAFESKILLS_API_URL (optional): base api url for all wallet operations. defaults to https://safeskill-production.up.railway.appSAFESKILLS_FRONTEND_URL (optional): frontend url for wallet claim and policy management. defaults to https://safeskill-production.up.railway.appexternal connection: SafeSkills API
Authorization: Bearer <API_KEY>, Content-Type: application/jsonwallet creation inputs:
type: EVM_WALLET (required)memo: optional label for the wallet (string, max 256 chars)chainId: numeric evm chain id (required). common values: 84532 (base sepolia), 1 (ethereum), 137 (polygon), 42161 (arbitrum), 10 (optimism), 8453 (base mainnet)transaction inputs (transfers/swaps/calls):
to: recipient address or contract address (0x-prefixed, 40 hex chars)amount: human-readable amount (string, e.g. "0.01" or "100")token: erc-20 token contract address (optional; omit for native eth)data: contract calldata (hex string, 0x-prefixed, for arbitrary transactions)value: native eth to send (string, wei or human-readable, defaults to "0")slippageBps: basis points for swap slippage tolerance (integer, optional, defaults to 100 = 1%)user context:
create wallet. post to ${SAFESKILLS_API_URL}/api/secrets with type EVM_WALLET, optional memo, and chainId. store the returned apiKey securely (this is your only auth credential for this wallet). capture the claimUrl and address from the response.
share claim url with wallet owner. communicate the claimUrl to the user so they can claim ownership, set policies, and monitor activity. do not share the api key with the user.
fetch wallet address. if you need to confirm or retrieve the wallet address later, get it from ${SAFESKILLS_API_URL}/api/skills/evm-wallet/address using the api key as bearer token.
check balance (optional). query ${SAFESKILLS_API_URL}/api/skills/evm-wallet/balance to get native eth balance. optionally append query param ?tokens=0xAddr1,0xAddr2 to fetch erc-20 balances for specific token contracts.
preview swap (optional, before execute). post to ${SAFESKILLS_API_URL}/api/skills/evm-wallet/swap/preview with sellToken, buyToken, sellAmount, and chainId. this returns pricing and route info without executing.
execute transfer or swap. for eth/token transfers, post to ${SAFESKILLS_API_URL}/api/skills/evm-wallet/transfer with to, amount, optional token address. for token swaps, post to ${SAFESKILLS_API_URL}/api/skills/evm-wallet/swap/execute with sellToken, buyToken, sellAmount, chainId, optional slippageBps.
send arbitrary transaction (advanced). post to ${SAFESKILLS_API_URL}/api/skills/evm-wallet/send-transaction with to (contract address), data (calldata hex), optional value (native eth to send).
handle pending approval status. if a transaction returns status: "pending_approval", the wallet owner will receive a telegram notification. wait for their approval or denial before retrying or escalating.
if wallet does not exist yet: create one (step 1). you must have an api key to proceed. if you lack safeskills credentials or deployment, you cannot operate this skill.
if transfer amount exceeds balance: the api will reject the request with a 400 error. inform the user to fund the wallet first or reduce the amount.
if transfer violates a policy (address allowlist, token allowlist, spending limit, etc.): the api returns 403 forbidden or status pending_approval. if denied outright, inform the user to check policies via the claim url. if pending approval, inform the owner via telegram and wait.
if swap preview returns zero or low buyAmount: liquidity may be insufficient, slippage too high, or the token pair unsupported. try a smaller sell amount, different chain, or different token pair.
if swap execute fails with "insufficient balance" or "allowance": ensure the wallet holds the sell token and that it has erc-20 approval for the smart account (the api handles this automatically for common dexes, but some contracts may require manual approval).
if api key is expired or revoked: all requests return 401 unauthorized. create a new wallet and regenerate the api key via the claim url.
if network timeout or 5xx error from safeskills api: retry with exponential backoff (wait 2s, then 4s, then 8s, max 3 retries). if persistent, check safeskills deployment status or contact the operator.
if the wallet owner has not claimed the wallet or set policies: all transactions are allowed by default. policies only take effect after the owner claims the wallet and configures them.
wallet creation response:
{
"apiKey": "sk_live_...",
"claimUrl": "https://safeskill-production.up.railway.app/claim/...",
"address": "0x...",
"chainId": 84532
}
balance response:
{
"native": "1500000000000000000",
"tokens": {
"0xTokenAddr": "500000000"
}
}
transfer/swap execute response:
{
"txHash": "0x...",
"status": "pending",
"nonce": 5,
"chainId": 84532
}
or
{
"txHash": "0x...",
"status": "pending_approval",
"nonce": 6
}
arbitrary transaction response:
{
"txHash": "0x...",
"status": "confirmed",
"nonce": 7,
"gasUsed": "45000"
}
all responses include a status field: pending (submitted, awaiting confirmation), confirmed (on-chain), or pending_approval (awaiting owner approval). txHash is always a 0x-prefixed 64-character hex string. nonce tracks the wallet's transaction sequence.
wallet created successfully: you receive an apiKey, claimUrl, and address. the agent can now use the apiKey to sign requests.
owner claimed wallet: the claim url was accessed, and the owner set up policies. you see policy constraints reflected in api responses (e.g. 403 forbidden for disallowed addresses).
transaction executed: api returns status pending or confirmed and a txHash. you can query the tx on the evm block explorer using the txHash and chainId.
balance updated: you query the balance endpoint and see a balance change after a transfer or swap is confirmed (typically within a few blocks, 12-30 seconds on most evm chains).
swap preview succeeded: api returns expected buyAmount and route details. use this to confirm pricing with the user before executing.
transaction pending approval: api returns status pending_approval. the wallet owner receives a telegram message with approve/deny buttons. transaction settles once owner acts.
policy violation rejected: api returns 403 forbidden with a message indicating which policy was violated (e.g. "spending limit exceeded" or "address not in allowlist"). user can adjust policies and retry.