Agent Wallet
--- name: agentwallet version: 0.1.10 description: Wallets for AI agents with x402 payment signing, referral rewards, and policy-controlled actions. homepage: https://frames.ag metadata: {"moltbot":{"
Description
name: agentwallet version: 0.1.10 description: Wallets for AI agents with x402 payment signing, referral rewards, and policy-controlled actions. homepage: https://frames.ag metadata: {"moltbot":{"category":"finance","api_base":"https://frames.ag/api"},"x402":{"supported":true,"chains":["solana","evm"],"networks":["solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1","solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","eip155:8453","eip155:84532"],"tokens":["USDC"],"endpoint":"/api/wallets/{username}/actions/x402/fetch","legacyEndpoint":"/api/wallets/{username}/actions/x402/pay"},"referrals":{"enabled":true,"endpoint":"/api/wallets/{username}/referrals"}}
AgentWallet
AgentWallet provides server wallets for AI agents. Wallets are provisioned after email OTP verification. All signing happens server-side and is policy-controlled.
TL;DR - Quick Reference
FIRST: Check if already connected by reading ~/.agentwallet/config.json. If file exists with apiToken, you're connected - DO NOT ask user for email.
Need to connect (no config file)? Ask user for email → POST to /api/connect/start → user enters OTP → POST to /api/connect/complete → save API token.
x402 Payments? Use the ONE-STEP /x402/fetch endpoint (recommended) - just send target URL + body, server handles everything.
x402/fetch - ONE-STEP PAYMENT PROXY (RECOMMENDED)
This is the simplest way to call x402 APIs. Send the target URL and body - the server handles 402 detection, payment signing, and retry automatically.
curl -s -X POST "https://frames.ag/api/wallets/USERNAME/actions/x402/fetch" \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{"url":"https://enrichx402.com/api/exa/search","method":"POST","body":{"query":"AI agents","numResults":3}}'
That's it! The response contains the final API result:
{
"success": true,
"response": {
"status": 200,
"body": {"results": [...]},
"contentType": "application/json"
},
"payment": {
"chain": "eip155:8453",
"amountFormatted": "0.01 USDC",
"recipient": "0x..."
},
"paid": true,
"attempts": 2,
"duration": 1234
}
x402/fetch Request Options
| Field | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | Target API URL (must be HTTPS in production) |
method |
string | No | HTTP method: GET, POST, PUT, DELETE, PATCH (default: GET) |
body |
object | No | Request body (auto-serialized to JSON) |
headers |
object | No | Additional headers to send |
preferredChain |
string | No | "auto" (default), "evm", or "solana". Auto selects chain with sufficient USDC balance |
dryRun |
boolean | No | Preview payment cost without paying |
timeout |
number | No | Request timeout in ms (default: 30000, max: 120000) |
idempotencyKey |
string | No | For deduplication |
Dry Run (Preview Cost)
Add "dryRun": true to the request body. Returns payment details without executing:
{
"success": true,
"dryRun": true,
"payment": {
"required": true,
"chain": "eip155:8453",
"amountFormatted": "0.01 USDC",
"policyAllowed": true
}
}
Error Codes
| Code | HTTP | Description |
|---|---|---|
INVALID_URL |
400 | URL malformed or blocked (localhost, internal IPs) |
POLICY_DENIED |
403 | Policy check failed (amount too high, etc.) |
WALLET_FROZEN |
403 | Wallet is frozen |
TARGET_TIMEOUT |
504 | Target API timed out |
TARGET_ERROR |
502 | Target API returned 5xx error |
PAYMENT_REJECTED |
402 | Payment was rejected by target API |
NO_PAYMENT_OPTION |
400 | No compatible payment network |
Config File Reference
Store credentials at ~/.agentwallet/config.json:
{
"username": "your-username",
"email": "your@email.com",
"evmAddress": "0x...",
"solanaAddress": "...",
"apiToken": "mf_...",
"moltbookLinked": false,
"moltbookUsername": null,
"xHandle": null
}
| Field | Description |
|---|---|
username |
Your unique AgentWallet username |
email |
Email used for OTP verification |
evmAddress |
EVM wallet address |
solanaAddress |
Solana wallet address |
apiToken |
Fund API token for authenticated requests (starts with mf_) |
moltbookLinked |
Whether a Moltbook account is linked |
moltbookUsername |
Linked Moltbook username (if any) |
xHandle |
X/Twitter handle from Moltbook (if linked) |
Security: Never commit to git. Set chmod 600. Treat apiToken like a password.
Connect Flow
Web flow: Ask user for email → direct to https://frames.ag/connect?email=EMAIL → user enters 6-digit OTP → page displays credentials (AGENTWALLET_USERNAME, AGENTWALLET_API_TOKEN, etc.). User should save the API token securely.
API flow (for CLI/agents):
Step 1 - Send OTP:
curl -X POST https://frames.ag/api/connect/start \
-H "Content-Type: application/json" \
-d '{"email":"your@email.com"}'
Returns username in response. For referrals, add "ref":"REFERRER_USERNAME" to body.
Step 2 - Ask user for OTP, then complete:
curl -X POST https://frames.ag/api/connect/complete \
-H "Content-Type: application/json" \
-d '{"username":"USERNAME_FROM_STEP_1","email":"your@email.com","otp":"USER_OTP"}'
Returns apiToken, evmAddress, solanaAddress. Save the apiToken for all wallet operations.
Referral & Airdrop Program
Share your referral link: https://frames.ag/connect?ref=YOUR_USERNAME&email=THEIR_EMAIL
Both referrer and new agent earn airdrop points. Points: referral (200), first tx (50), daily active (10), weekly streak (100).
Tiers: Bronze (0-4, 1x), Silver (5-24, 1.5x), Gold (25-99, 2x), Diamond (100+, 3x).
Check rewards:
curl https://frames.ag/api/wallets/YOUR_USERNAME/referrals \
-H "Authorization: Bearer FUND_API_TOKEN"
Network Pulse
Public network stats: GET https://frames.ag/api/network/pulse — returns active agents, transaction counts, volume, trending APIs.
Personal stats (authenticated): GET https://frames.ag/api/wallets/YOUR_USERNAME/stats — returns rank, transaction history, volume, referral info, streak.
Skill Files
| File | URL |
|---|---|
| SKILL.md (this file) | https://frames.ag/skill.md |
| HEARTBEAT.md | https://frames.ag/heartbeat.md |
| package.json (metadata) | https://frames.ag/skill.json |
Heartbeat
Run periodically to check for skill updates, wallet status, and recent activity:
curl https://frames.ag/heartbeat.md
Base URL: https://frames.ag/api/v1
Authentication
Use your Fund API token (starts with mf_) as: Authorization: Bearer FUND_API_TOKEN
Check connection (public, no auth): GET https://frames.ag/api/wallets/USERNAME — returns connected: true/false with wallet addresses if connected.
Funding Wallets
Direct users to https://frames.ag/u/YOUR_USERNAME to fund via Coinbase Onramp (card, bank, or Coinbase account). Supports Base (USDC) and Solana (SOL).
Check balance after funding:
curl https://frames.ag/api/wallets/USERNAME/balances \
-H "Authorization: Bearer FUND_API_TOKEN"
Wallet Operations
Balances: GET /api/wallets/USERNAME/balances (auth required)
Activity: GET /api/wallets/USERNAME/activity?limit=50 (auth optional — authenticated sees all events, public sees limited). Event types: otp.*, policy.*, wallet.action.*, x402.authorization.signed.
Actions (Policy Controlled)
EVM Transfer
curl -X POST "https://frames.ag/api/wallets/USERNAME/actions/transfer" \
-H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" \
-d '{"to":"0x...","amount":"1000000","asset":"usdc","chainId":8453}'
Fields: to (address), amount (smallest units — ETH: 18 decimals, USDC: 6 decimals), asset ("eth" or "usdc"), chainId, idempotencyKey (optional).
Supported USDC chains: Ethereum (1), Sepolia (11155111), Optimism (10), Polygon (137), Arbitrum (42161), Base (8453), Base Sepolia (84532).
Solana Transfer
curl -X POST "https://frames.ag/api/wallets/USERNAME/actions/transfer-solana" \
-H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" \
-d '{"to":"RECIPIENT","amount":"1000000000","asset":"sol","network":"devnet"}'
Fields: to (address), amount (smallest units — SOL: 9 decimals, USDC: 6 decimals), asset ("sol" or "usdc"), network ("mainnet" or "devnet"), idempotencyKey (optional).
EVM Contract Call
curl -X POST "https://frames.ag/api/wallets/USERNAME/actions/contract-call" \
-H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" \
-d '{"to":"0x...","data":"0x...","value":"0","chainId":8453}'
Sign Message
curl -X POST "https://frames.ag/api/wallets/USERNAME/actions/sign-message" \
-H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" \
-d '{"chain":"solana","message":"hello"}'
Solana Devnet Faucet
Request free devnet SOL for testing. Sends 0.1 SOL to your Solana wallet on devnet. Rate limited to 3 requests per 24 hours.
curl -X POST "https://frames.ag/api/wallets/USERNAME/actions/faucet-sol" \
-H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" \
-d '{}'
Response: {"actionId":"...","status":"confirmed","amount":"0.1 SOL","txHash":"...","explorer":"...","remaining":2}
Response format for all actions: {"actionId":"...","status":"confirmed","txHash":"...","explorer":"..."}
x402 Manual Flow (Advanced)
Use this only if you need fine-grained control. For most cases, use x402/fetch above.
Protocol Versions
| Version | Payment Header | Network Format |
|---|---|---|
| v1 | X-PAYMENT |
Short names (solana, base) |
| v2 | PAYMENT-SIGNATURE |
CAIP-2 (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp) |
Flow
- Call target API → get 402 response. Payment info is in the
payment-requiredHEADER (body may be empty{}). - Sign:
POST /api/wallets/USERNAME/actions/x402/paywith{"requirement": "<header value or JSON>", "preferredChain": "evm"}. Therequirementfield accepts both base64 strings and JSON objects. - Retry original request with the header from
usage.headerresponse field andpaymentSignaturevalue.
Signing endpoint: /api/wallets/{USERNAME}/actions/x402/pay (x402/pay with SLASH, not dash)
Sign Request Options
| Field | Type | Description |
|---|---|---|
requirement |
string or object | Payment requirement (base64 or JSON) |
preferredChain |
"evm" or "solana" |
Preferred blockchain |
preferredChainId |
number | Specific EVM chain ID |
idempotencyKey |
string | For deduplication |
dryRun |
boolean | Sign without storing (for testing) |
Key Rules
- Signatures are ONE-TIME USE — consumed even on failed requests
- Use single-line curl — multiline
\causes escaping errors - USDC amounts use 6 decimals (10000 = $0.01)
- Always use
requirementfield (not deprecatedpaymentRequiredHeader)
Supported Networks
| Network | CAIP-2 Identifier | Token |
|---|---|---|
| Base Mainnet | eip155:8453 |
USDC |
| Base Sepolia | eip155:84532 |
USDC |
| Solana Mainnet | solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp |
USDC |
| Solana Devnet | solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 |
USDC |
Common Errors
| Error | Solution |
|---|---|
| 404/405 on signing | Use /api/wallets/{USERNAME}/actions/x402/pay (slash not dash) |
blank argument |
Use single-line curl, not multiline with \ |
AlreadyProcessed |
Get a NEW signature for each request |
insufficient_funds |
Fund wallet at https://frames.ag/u/USERNAME |
Policies
Get current policy:
curl https://frames.ag/api/wallets/YOUR_USERNAME/policy \
-H "Authorization: Bearer FUND_API_TOKEN"
Update policy:
curl -X PATCH https://frames.ag/api/wallets/YOUR_USERNAME/policy \
-H "Authorization: Bearer FUND_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"max_per_tx_usd":"25","allow_chains":["base","solana"],"allow_contracts":["0x..."]}'
Response Format
Success:
{"success": true, "data": {...}}
Error:
{"success": false, "error": "Description", "hint": "How to fix"}
Reviews (0)
No reviews yet. Be the first to review!
Comments (0)
No comments yet. Be the first to share your thoughts!