agentwallet-sdk 6.0.3 → 6.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +296 -332
- package/dist/bridge/__tests__/solana.test.js +1 -1
- package/dist/bridge/__tests__/solana.test.js.map +1 -1
- package/dist/convenience.js.map +1 -1
- package/dist/escrow/MutualStakeEscrow.d.ts.map +1 -1
- package/dist/escrow/MutualStakeEscrow.js +3 -5
- package/dist/escrow/MutualStakeEscrow.js.map +1 -1
- package/dist/index.d.ts +48 -252
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -5
- package/dist/index.js.map +1 -1
- package/dist/policy/SpendingPolicy.test.js.map +1 -1
- package/dist/swap/SwapModule.js +1 -1
- package/dist/swap/SwapModule.js.map +1 -1
- package/dist/tokens/__tests__/decimals.test.d.ts +2 -0
- package/dist/tokens/__tests__/decimals.test.d.ts.map +1 -0
- package/dist/tokens/__tests__/decimals.test.js +107 -0
- package/dist/tokens/__tests__/decimals.test.js.map +1 -0
- package/dist/tokens/__tests__/registry.test.d.ts +2 -0
- package/dist/tokens/__tests__/registry.test.d.ts.map +1 -0
- package/dist/tokens/__tests__/registry.test.js +191 -0
- package/dist/tokens/__tests__/registry.test.js.map +1 -0
- package/dist/tokens/__tests__/transfers.test.d.ts +2 -0
- package/dist/tokens/__tests__/transfers.test.d.ts.map +1 -0
- package/dist/tokens/__tests__/transfers.test.js +103 -0
- package/dist/tokens/__tests__/transfers.test.js.map +1 -0
- package/dist/tokens/decimals.d.ts +65 -0
- package/dist/tokens/decimals.d.ts.map +1 -0
- package/dist/tokens/decimals.js +112 -0
- package/dist/tokens/decimals.js.map +1 -0
- package/dist/tokens/index.d.ts +14 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/index.js +14 -0
- package/dist/tokens/index.js.map +1 -0
- package/dist/tokens/registry.d.ts +82 -0
- package/dist/tokens/registry.d.ts.map +1 -0
- package/dist/tokens/registry.js +293 -0
- package/dist/tokens/registry.js.map +1 -0
- package/dist/tokens/solana.d.ts +108 -0
- package/dist/tokens/solana.d.ts.map +1 -0
- package/dist/tokens/solana.js +306 -0
- package/dist/tokens/solana.js.map +1 -0
- package/dist/tokens/transfers.d.ts +95 -0
- package/dist/tokens/transfers.d.ts.map +1 -0
- package/dist/tokens/transfers.js +196 -0
- package/dist/tokens/transfers.js.map +1 -0
- package/dist/x402/__tests__/client.test.js +1 -1
- package/dist/x402/__tests__/client.test.js.map +1 -1
- package/dist/x402/chains/abstract/index.d.ts.map +1 -1
- package/dist/x402/chains/abstract/index.js.map +1 -1
- package/dist/x402/chains/stellar/index.d.ts.map +1 -1
- package/dist/x402/chains/stellar/index.js +2 -0
- package/dist/x402/chains/stellar/index.js.map +1 -1
- package/dist/x402/client.d.ts +7 -1
- package/dist/x402/client.d.ts.map +1 -1
- package/dist/x402/client.js +24 -13
- package/dist/x402/client.js.map +1 -1
- package/dist/x402/index.d.ts +1 -0
- package/dist/x402/index.d.ts.map +1 -1
- package/dist/x402/index.js +2 -0
- package/dist/x402/index.js.map +1 -1
- package/dist/x402/middleware.d.ts.map +1 -1
- package/dist/x402/middleware.js +0 -3
- package/dist/x402/middleware.js.map +1 -1
- package/dist/x402/multi-asset.d.ts +54 -0
- package/dist/x402/multi-asset.d.ts.map +1 -0
- package/dist/x402/multi-asset.js +123 -0
- package/dist/x402/multi-asset.js.map +1 -0
- package/package.json +13 -3
- package/dist/plugins/elizaos.d.ts +0 -52
- package/dist/plugins/elizaos.d.ts.map +0 -1
- package/dist/plugins/elizaos.js +0 -89
- package/dist/plugins/elizaos.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
# AgentWallet SDK
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> **v6.0.0** · MIT · **Patent Pending**
|
|
4
|
+
>
|
|
5
|
+
> USPTO Provisional filed March 2026: "Non-Custodial Multi-Chain Financial Infrastructure System for Autonomous AI Agents"
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
**Your AI agent needs to pay for things. Giving it your credit card is insane.**
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
> **ERC-8004 Ready:** Maps directly to [ERC-8004 (Trustless Agents)](https://eips.ethereum.org/EIPS/eip-8004) — your agent's ERC-6551 wallet NFT doubles as its on-chain identity handle, with built-in Identity Registry, Reputation Registry, and Validation Registry clients.
|
|
9
|
+
The actual problem: your agent is in a loop, it hits a paid API, and it needs to pay. The naive solution (raw wallet + private key) means one prompt injection or runaway loop drains everything. AgentWallet SDK gives your agent a wallet with hard on-chain spending limits, human approval by default, and no custody of your keys.
|
|
10
10
|
|
|
11
11
|
```
|
|
12
|
-
Agent wants to spend $
|
|
13
|
-
Agent wants to spend $
|
|
14
|
-
Agent spent $
|
|
12
|
+
Agent wants to spend $0.50 → ✅ Auto-approved (under your $1/tx threshold)
|
|
13
|
+
Agent wants to spend $50 → ⏳ Queued — you get notified to approve or reject
|
|
14
|
+
Agent spent $9.50 today → 🛑 Next tx blocked ($10/day cap hit)
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
The caps are enforced by smart contract. Application code — including the agent itself — cannot override them.
|
|
18
|
+
|
|
19
|
+
## Why Not Just Give the Agent a Wallet?
|
|
18
20
|
|
|
19
21
|
| Approach | Problem |
|
|
20
22
|
|----------|---------|
|
|
21
|
-
| Raw EOA wallet |
|
|
22
|
-
| Multisig (Safe) | Every
|
|
23
|
-
| Custodial API
|
|
24
|
-
| **
|
|
25
|
-
|
|
26
|
-
Built on **ERC-6551** (token-bound accounts). Your agent's wallet is tied to an NFT — portable, auditable, fully on-chain.
|
|
23
|
+
| Raw EOA wallet | One prompt injection or loop bug = everything drained |
|
|
24
|
+
| Multisig (Safe) | Every transaction needs manual signatures — kills the point of automation |
|
|
25
|
+
| Custodial API | Centralized, KYC friction, not crypto-native |
|
|
26
|
+
| **AgentWallet SDK** | **On-chain limits + human approval threshold + non-custodial. Agent spends within bounds; everything else queues.** |
|
|
27
27
|
|
|
28
28
|
## Quick Start
|
|
29
29
|
|
|
@@ -31,447 +31,411 @@ Built on **ERC-6551** (token-bound accounts). Your agent's wallet is tied to an
|
|
|
31
31
|
npm install agentwallet-sdk viem
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
###
|
|
35
|
-
|
|
36
|
-
The `chain` parameter selects which network the wallet operates on. Supported values:
|
|
37
|
-
`'base'` | `'ethereum'` | `'arbitrum'` | `'polygon'` | `'optimism'` | `'avalanche'` |
|
|
38
|
-
`'unichain'` | `'linea'` | `'sonic'` | `'worldchain'` | `'base-sepolia'`
|
|
34
|
+
### Set Up a Wallet with Spend Caps
|
|
39
35
|
|
|
40
36
|
```typescript
|
|
41
|
-
import { createWallet, setSpendPolicy,
|
|
37
|
+
import { createWallet, setSpendPolicy, NATIVE_TOKEN } from 'agentwallet-sdk';
|
|
42
38
|
import { createWalletClient, http } from 'viem';
|
|
43
39
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
44
40
|
import { base } from 'viem/chains';
|
|
45
41
|
|
|
46
|
-
const account = privateKeyToAccount(
|
|
42
|
+
const account = privateKeyToAccount(process.env.AGENT_PRIVATE_KEY as `0x${string}`);
|
|
47
43
|
const walletClient = createWalletClient({ account, chain: base, transport: http() });
|
|
48
44
|
|
|
49
45
|
const wallet = createWallet({
|
|
50
|
-
accountAddress:
|
|
51
|
-
chain: 'base',
|
|
46
|
+
accountAddress: process.env.AGENT_WALLET_ADDRESS as `0x${string}`,
|
|
47
|
+
chain: 'base',
|
|
52
48
|
walletClient,
|
|
53
49
|
});
|
|
54
50
|
|
|
55
|
-
//
|
|
51
|
+
// Spend policy — lives on-chain, not in your app code
|
|
52
|
+
// Agent cannot spend more than this even if instructed to
|
|
56
53
|
await setSpendPolicy(wallet, {
|
|
57
|
-
token:
|
|
58
|
-
perTxLimit:
|
|
59
|
-
periodLimit:
|
|
60
|
-
periodLength: 86400,
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// Agent executes — auto-approved if within limits, queued if over
|
|
64
|
-
const result = await agentExecute(wallet, {
|
|
65
|
-
to: '0xRecipient',
|
|
66
|
-
value: 10000000000000000n, // 0.01 ETH
|
|
54
|
+
token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC on Base
|
|
55
|
+
perTxLimit: 5_000_000n, // $5 max per transaction
|
|
56
|
+
periodLimit: 50_000_000n, // $50/day hard cap
|
|
57
|
+
periodLength: 86400, // resets every 24 hours
|
|
67
58
|
});
|
|
68
|
-
console.log(result.executed ? 'Sent!' : 'Queued for approval');
|
|
69
59
|
```
|
|
70
60
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
Pay any x402-gated API from any supported chain. The client automatically selects
|
|
74
|
-
the correct USDC address for the network the server requests.
|
|
61
|
+
### Pay for an API (the 402 Flow)
|
|
75
62
|
|
|
76
63
|
```typescript
|
|
77
|
-
import {
|
|
78
|
-
import { createWalletClient, http } from 'viem';
|
|
79
|
-
import { privateKeyToAccount } from 'viem/accounts';
|
|
80
|
-
import { arbitrum } from 'viem/chains';
|
|
81
|
-
|
|
82
|
-
const account = privateKeyToAccount(process.env.AGENT_PRIVATE_KEY as `0x${string}`);
|
|
83
|
-
const walletClient = createWalletClient({ account, chain: arbitrum, transport: http() });
|
|
84
|
-
|
|
85
|
-
// Wallet on Arbitrum — pays with Arbitrum USDC
|
|
86
|
-
const wallet = createWallet({
|
|
87
|
-
accountAddress: '0xYourAgentWallet',
|
|
88
|
-
chain: 'arbitrum',
|
|
89
|
-
walletClient,
|
|
90
|
-
});
|
|
64
|
+
import { createX402Client } from 'agentwallet-sdk';
|
|
91
65
|
|
|
92
66
|
const x402 = createX402Client(wallet, {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
67
|
+
supportedNetworks: ['base:8453'],
|
|
68
|
+
globalDailyLimit: 50_000_000n, // matches spend policy
|
|
69
|
+
globalPerRequestMax: 5_000_000n, // $5 max per request
|
|
70
|
+
requireApproval: true, // human-in-the-loop (default)
|
|
97
71
|
});
|
|
98
72
|
|
|
99
|
-
//
|
|
100
|
-
const response = await x402.fetch('https://api.example.com/premium-
|
|
73
|
+
// Agent hits a premium API and gets 402 — SDK handles it
|
|
74
|
+
const response = await x402.fetch('https://api.example.com/premium-report');
|
|
101
75
|
const data = await response.json();
|
|
76
|
+
// Cost: $0.50 USDC, auto-approved (under $5 threshold)
|
|
77
|
+
// Every payment: tx hash on Base, auditable on basescan.org
|
|
102
78
|
```
|
|
103
79
|
|
|
104
|
-
##
|
|
80
|
+
## The Trust Layer
|
|
105
81
|
|
|
106
|
-
|
|
82
|
+
This is what makes supervised payments different from autonomous payments.
|
|
107
83
|
|
|
108
|
-
|
|
109
|
-
import { createWallet } from 'agentwallet-sdk';
|
|
110
|
-
import { attachSwap } from 'agentwallet-sdk/swap';
|
|
111
|
-
import { BASE_TOKENS, ARBITRUM_TOKENS } from 'agentwallet-sdk';
|
|
84
|
+
### Simulation Mode
|
|
112
85
|
|
|
113
|
-
|
|
114
|
-
const baseWallet = createWallet({ accountAddress: '0x...', chain: 'base', walletClient });
|
|
115
|
-
const baseSwap = attachSwap(baseWallet, { chain: 'base' });
|
|
86
|
+
Before any real payment, run in simulation to see exactly what would happen:
|
|
116
87
|
|
|
117
|
-
|
|
118
|
-
|
|
88
|
+
```typescript
|
|
89
|
+
const x402 = createX402Client(wallet, {
|
|
90
|
+
supportedNetworks: ['base:8453'],
|
|
91
|
+
globalDailyLimit: 50_000_000n,
|
|
92
|
+
globalPerRequestMax: 5_000_000n,
|
|
93
|
+
dryRun: true, // no funds move
|
|
119
94
|
});
|
|
120
|
-
console.log('Swap tx:', result.txHash);
|
|
121
|
-
|
|
122
|
-
// Swap on Arbitrum
|
|
123
|
-
const arbWallet = createWallet({ accountAddress: '0x...', chain: 'arbitrum', walletClient });
|
|
124
|
-
const arbSwap = attachSwap(arbWallet, { chain: 'arbitrum' });
|
|
125
95
|
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
});
|
|
129
|
-
console.log('Arbitrum swap tx:', arbResult.txHash);
|
|
96
|
+
const response = await x402.fetch('https://api.example.com/premium-report');
|
|
97
|
+
// Response: { simulated: true, wouldHavePaid: '0.50 USDC', withinLimits: true, dailyTotal: '2.00 USDC' }
|
|
130
98
|
```
|
|
131
99
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
Bridge USDC between any of the 10 supported EVM chains using Circle's CCTP V2.
|
|
100
|
+
### Human Approval for High-Value Payments
|
|
135
101
|
|
|
136
102
|
```typescript
|
|
137
|
-
import {
|
|
138
|
-
import { createWalletClient, http } from 'viem';
|
|
139
|
-
import { base } from 'viem/chains';
|
|
103
|
+
import { createWallet, agentExecute } from 'agentwallet-sdk';
|
|
140
104
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
105
|
+
// Transactions above your per-tx limit queue for approval
|
|
106
|
+
const result = await agentExecute(wallet, {
|
|
107
|
+
to: '0xRecipient',
|
|
108
|
+
value: 50_000_000_000_000_000n, // 0.05 ETH (~$130)
|
|
145
109
|
});
|
|
146
110
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
console.log('Burn tx:', result.burnTxHash);
|
|
154
|
-
console.log('Mint tx:', result.mintTxHash);
|
|
155
|
-
console.log(`Completed in ${result.elapsedMs}ms`);
|
|
111
|
+
if (result.executed) {
|
|
112
|
+
console.log('Sent:', result.txHash);
|
|
113
|
+
} else {
|
|
114
|
+
console.log('Queued for approval — tx ID:', result.queueId);
|
|
115
|
+
// Your approval system gets notified; agent waits or continues other work
|
|
116
|
+
}
|
|
156
117
|
```
|
|
157
118
|
|
|
158
|
-
|
|
119
|
+
### Explainability — Agent Must Show Its Work
|
|
159
120
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
121
|
+
Before any payment above your threshold, the agent surfaces:
|
|
122
|
+
- What it's paying for
|
|
123
|
+
- What the expected outcome is
|
|
124
|
+
- What it will do if the payment fails
|
|
163
125
|
|
|
164
126
|
```typescript
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
127
|
+
const paymentIntent = {
|
|
128
|
+
url: 'https://api.example.com/market-data',
|
|
129
|
+
amount: '2.00 USDC',
|
|
130
|
+
reason: 'Fetching historical price data for AAPL 2023-2024',
|
|
131
|
+
expectedOutcome: 'CSV with daily OHLCV data, ~500 rows',
|
|
132
|
+
fallback: 'Use cached data from 2024-01-15 (3 months old)',
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
// Human sees this before approving anything above threshold
|
|
136
|
+
const approved = await requestHumanApproval(paymentIntent);
|
|
137
|
+
if (!approved) {
|
|
138
|
+
return useFallback(paymentIntent.fallback);
|
|
139
|
+
}
|
|
140
|
+
```
|
|
168
141
|
|
|
169
|
-
|
|
170
|
-
account: privateKeyToAccount(process.env.AGENT_PRIVATE_KEY as `0x${string}`),
|
|
171
|
-
chain: base,
|
|
172
|
-
transport: http(),
|
|
173
|
-
});
|
|
142
|
+
### Safe Abort
|
|
174
143
|
|
|
175
|
-
|
|
176
|
-
const result = await bridgeEVMToSolana(walletClient, 50_000_000n, {
|
|
177
|
-
fromChain: 'base',
|
|
178
|
-
solanaRecipient: 'YourSolanaWalletAddressInBase58',
|
|
179
|
-
minFinalityThreshold: 0, // FAST (~12s)
|
|
180
|
-
});
|
|
144
|
+
When a payment fails or is rejected, the agent handles it gracefully — not by retrying indefinitely:
|
|
181
145
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
146
|
+
```typescript
|
|
147
|
+
const result = await x402.fetch('https://api.example.com/premium-data');
|
|
148
|
+
|
|
149
|
+
if (!result.ok) {
|
|
150
|
+
switch (result.status) {
|
|
151
|
+
case 402:
|
|
152
|
+
// Payment rejected or limit hit — fall back to free alternative
|
|
153
|
+
return await fetchFreeAlternative();
|
|
154
|
+
case 'limit-exceeded':
|
|
155
|
+
// Daily cap hit — log it, stop trying today
|
|
156
|
+
console.log('Daily spend cap reached. Resuming tomorrow.');
|
|
157
|
+
return null;
|
|
158
|
+
case 'approval-rejected':
|
|
159
|
+
// Human said no — respect that
|
|
160
|
+
console.log('Payment rejected by human. Using cached data.');
|
|
161
|
+
return getCachedResult();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
188
164
|
```
|
|
189
165
|
|
|
190
|
-
##
|
|
166
|
+
## Production-Ready: Failure Handling, Retries, Fallbacks
|
|
191
167
|
|
|
192
|
-
|
|
168
|
+
Real agent deployments fail. Here's how to handle it.
|
|
193
169
|
|
|
194
|
-
|
|
195
|
-
import { receiveFromSolanaOnEVM } from 'agentwallet-sdk';
|
|
196
|
-
|
|
197
|
-
// After initiating a burn on Solana, receive on EVM:
|
|
198
|
-
const result = await receiveFromSolanaOnEVM(walletClient, {
|
|
199
|
-
messageBytes: '0x...', // from Solana burn transaction
|
|
200
|
-
messageHash: '0x...', // keccak256 of messageBytes
|
|
201
|
-
sourceDomain: 5, // Solana CCTP domain
|
|
202
|
-
}, {
|
|
203
|
-
toChain: 'arbitrum',
|
|
204
|
-
evmRecipient: '0xYourEVMAddress',
|
|
205
|
-
});
|
|
170
|
+
### Retry with Backoff
|
|
206
171
|
|
|
207
|
-
|
|
208
|
-
|
|
172
|
+
```typescript
|
|
173
|
+
import { createX402Client } from 'agentwallet-sdk';
|
|
174
|
+
|
|
175
|
+
async function fetchWithRetry(
|
|
176
|
+
x402: ReturnType<typeof createX402Client>,
|
|
177
|
+
url: string,
|
|
178
|
+
maxAttempts = 3,
|
|
179
|
+
): Promise<Response> {
|
|
180
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
181
|
+
try {
|
|
182
|
+
const response = await x402.fetch(url);
|
|
183
|
+
if (response.ok) return response;
|
|
184
|
+
|
|
185
|
+
// Don't retry on rejected payments or limit hits
|
|
186
|
+
if (['limit-exceeded', 'approval-rejected'].includes(response.status as string)) {
|
|
187
|
+
throw new Error(`Payment stopped: ${response.status}`);
|
|
188
|
+
}
|
|
189
|
+
} catch (err) {
|
|
190
|
+
if (attempt === maxAttempts) throw err;
|
|
191
|
+
// Exponential backoff: 1s, 2s, 4s
|
|
192
|
+
await new Promise(resolve => setTimeout(resolve, 1000 * 2 ** (attempt - 1)));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
throw new Error('Max retries exceeded');
|
|
196
|
+
}
|
|
209
197
|
```
|
|
210
198
|
|
|
211
|
-
|
|
199
|
+
### Fallback to Free Data Sources
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
async function getMarketData(symbol: string): Promise<MarketData> {
|
|
203
|
+
// Try paid source first (better data quality)
|
|
204
|
+
try {
|
|
205
|
+
const response = await fetchWithRetry(x402, `https://paid-api.com/data/${symbol}`);
|
|
206
|
+
return await response.json();
|
|
207
|
+
} catch (err) {
|
|
208
|
+
console.warn(`Paid API unavailable: ${err.message}. Falling back to free source.`);
|
|
209
|
+
// Fall back to free source (rate-limited, less complete)
|
|
210
|
+
const fallback = await fetch(`https://free-api.com/data/${symbol}`);
|
|
211
|
+
return await fallback.json();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
212
215
|
|
|
213
|
-
|
|
216
|
+
### Budget Guard — Stop Before You Hit the Cap
|
|
214
217
|
|
|
215
218
|
```typescript
|
|
216
|
-
import {
|
|
219
|
+
import { getRemainingBudget } from 'agentwallet-sdk';
|
|
220
|
+
|
|
221
|
+
async function checkBudgetBeforeLoop(wallet: Wallet, estimatedCostPerCall: bigint, callCount: number) {
|
|
222
|
+
const remaining = await getRemainingBudget(wallet, '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913');
|
|
223
|
+
const estimatedTotal = estimatedCostPerCall * BigInt(callCount);
|
|
224
|
+
|
|
225
|
+
if (estimatedTotal > remaining) {
|
|
226
|
+
const maxCalls = Number(remaining / estimatedCostPerCall);
|
|
227
|
+
console.warn(`Budget allows ${maxCalls} of ${callCount} planned calls. Adjusting.`);
|
|
228
|
+
return maxCalls;
|
|
229
|
+
}
|
|
230
|
+
return callCount;
|
|
231
|
+
}
|
|
232
|
+
```
|
|
217
233
|
|
|
218
|
-
|
|
234
|
+
## Non-Custodial Architecture
|
|
219
235
|
|
|
220
|
-
|
|
221
|
-
const { txHash, agentId } = await identity.registerAgent(walletClient, {
|
|
222
|
-
name: 'MyAgent',
|
|
223
|
-
description: 'Autonomous trading agent',
|
|
224
|
-
});
|
|
236
|
+
Your private key never leaves your infrastructure. The SDK interacts with on-chain contracts; no third party holds or validates your keys.
|
|
225
237
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
238
|
+
```
|
|
239
|
+
Your Infrastructure On-Chain
|
|
240
|
+
───────────────────── ────────────────────────────────────
|
|
241
|
+
Agent process AgentAccountV2 contract
|
|
242
|
+
├── private key (local) ├── SpendingPolicy (your limits)
|
|
243
|
+
├── agentwallet-sdk ├── Tx queue (over-limit txs)
|
|
244
|
+
└── signs transactions └── Audit log (immutable)
|
|
245
|
+
│ ▲
|
|
246
|
+
└──── broadcasts ──────────┘
|
|
229
247
|
```
|
|
230
248
|
|
|
231
|
-
|
|
249
|
+
**What this means:** If you stop using AgentWallet SDK tomorrow, your wallets, keys, and on-chain limits continue to work with any Ethereum-compatible tool. No vendor lock-in.
|
|
232
250
|
|
|
233
|
-
|
|
251
|
+
## Token Registry
|
|
252
|
+
|
|
253
|
+
80+ verified token addresses across 11 EVM chains + Solana. No hard-coded contract addresses.
|
|
234
254
|
|
|
235
255
|
```typescript
|
|
236
|
-
import {
|
|
256
|
+
import { getGlobalRegistry } from 'agentwallet-sdk';
|
|
237
257
|
|
|
238
|
-
const
|
|
258
|
+
const registry = getGlobalRegistry();
|
|
239
259
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
agentId: 42n,
|
|
243
|
-
score: 95n,
|
|
244
|
-
category: 1,
|
|
245
|
-
comment: 'Fast execution, accurate results',
|
|
246
|
-
taskRef: 'task-abc-123',
|
|
247
|
-
verifierRef: '',
|
|
248
|
-
clientRef: '',
|
|
249
|
-
contentHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
250
|
-
});
|
|
260
|
+
const usdc = registry.getToken('USDC', 8453); // Base chain ID
|
|
261
|
+
console.log(usdc?.address); // 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
|
|
251
262
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
console.log(`Score: ${rep.totalScore} from ${rep.count} reviews`);
|
|
263
|
+
const baseTokens = registry.listTokens(8453);
|
|
264
|
+
// ['USDC', 'USDT', 'DAI', 'WETH', 'WBTC', 'LINK', 'UNI', 'AAVE', ...]
|
|
255
265
|
```
|
|
256
266
|
|
|
257
|
-
##
|
|
258
|
-
|
|
259
|
-
Request and receive on-chain validation from validator contracts (TEE attestations, capability proofs, compliance checks).
|
|
267
|
+
## Multi-Token Transfers
|
|
260
268
|
|
|
261
269
|
```typescript
|
|
262
|
-
import {
|
|
263
|
-
import { keccak256, toBytes } from 'viem';
|
|
264
|
-
|
|
265
|
-
const validation = new ValidationClient({
|
|
266
|
-
chain: 'base',
|
|
267
|
-
validationAddress: '0xYourValidationRegistry', // address required until official deployment
|
|
268
|
-
});
|
|
270
|
+
import { sendToken, sendNative, getTokenBalance, getBalances } from 'agentwallet-sdk';
|
|
269
271
|
|
|
270
|
-
//
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
requestURI: 'https://example.com/validation-spec.json',
|
|
276
|
-
requestHash,
|
|
272
|
+
// Send 100 USDC — no manual decimal math
|
|
273
|
+
const txHash = await sendToken(wallet, {
|
|
274
|
+
symbol: 'USDC',
|
|
275
|
+
to: '0xRecipient',
|
|
276
|
+
amount: '100', // → internally 100_000_000 (6 decimals)
|
|
277
277
|
});
|
|
278
278
|
|
|
279
|
-
// Check
|
|
280
|
-
const
|
|
281
|
-
console.log(
|
|
279
|
+
// Check balances
|
|
280
|
+
const usdcBalance = await getTokenBalance(wallet, 'USDC');
|
|
281
|
+
console.log(usdcBalance); // "250.00"
|
|
282
282
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
console.log(`${summary.passCount} passed, ${summary.failCount} failed`);
|
|
283
|
+
const allBalances = await getBalances(wallet);
|
|
284
|
+
// [{ symbol: 'USDC', balance: '250.00', raw: 250000000n }, ...]
|
|
286
285
|
```
|
|
287
286
|
|
|
288
|
-
##
|
|
289
|
-
|
|
290
|
-
Reciprocal collateral for agent-to-agent task settlement. Both parties stake, both lose if the task fails.
|
|
287
|
+
## Multi-Chain Support
|
|
291
288
|
|
|
292
289
|
```typescript
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
chain: 'base',
|
|
290
|
+
// Same API across chains — just change 'chain'
|
|
291
|
+
const wallet = createWallet({
|
|
292
|
+
accountAddress: '0x...',
|
|
293
|
+
chain: 'arbitrum', // or 'base', 'polygon', 'optimism', etc.
|
|
297
294
|
walletClient,
|
|
298
295
|
});
|
|
296
|
+
```
|
|
299
297
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
298
|
+
| Chain | x402 | Bridge | Swap |
|
|
299
|
+
|-------|:----:|:------:|:----:|
|
|
300
|
+
| Base (recommended) | ✅ | ✅ | ✅ |
|
|
301
|
+
| Arbitrum | ✅ | ✅ | ✅ |
|
|
302
|
+
| Optimism | ✅ | ✅ | ✅ |
|
|
303
|
+
| Polygon | ✅ | ✅ | ✅ |
|
|
304
|
+
| Ethereum | ✅ | ✅ | — |
|
|
305
|
+
| Avalanche | ✅ | ✅ | — |
|
|
306
|
+
| Unichain, Linea, Sonic, Worldchain | ✅ | ✅ | — |
|
|
307
|
+
| Base Sepolia (testnet) | ✅ | — | — |
|
|
308
|
+
|
|
309
|
+
## Uniswap V3 Swaps
|
|
308
310
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
+
```typescript
|
|
312
|
+
import { attachSwap } from 'agentwallet-sdk/swap';
|
|
313
|
+
import { BASE_TOKENS } from 'agentwallet-sdk';
|
|
311
314
|
|
|
312
|
-
|
|
313
|
-
await escrow.fulfill(escrowId, proofHash);
|
|
315
|
+
const swap = attachSwap(wallet, { chain: 'base' });
|
|
314
316
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
+
const result = await swap.swap(BASE_TOKENS.USDC, BASE_TOKENS.WETH, 100_000_000n, {
|
|
318
|
+
slippageBps: 50, // 0.5% slippage
|
|
319
|
+
});
|
|
320
|
+
console.log('Swap tx:', result.txHash);
|
|
317
321
|
```
|
|
318
322
|
|
|
319
|
-
##
|
|
323
|
+
## CCTP V2 Bridging
|
|
320
324
|
|
|
321
|
-
|
|
325
|
+
```typescript
|
|
326
|
+
import { createBridge } from 'agentwallet-sdk';
|
|
322
327
|
|
|
323
|
-
|
|
324
|
-
|---------|--------|-------------|
|
|
325
|
-
| Agent Identity | ✅ Live | ERC-8004 Identity Registry — on-chain ERC-721 agent IDs |
|
|
326
|
-
| Agent Reputation | ✅ Live | ERC-8004 Reputation Registry — scored feedback and summaries |
|
|
327
|
-
| Agent Validation | ✅ Live | ERC-8004 Validation Registry — validator request/response |
|
|
328
|
-
| ERC-6551 TBA | ✅ Live | NFT-bound wallets with autonomous spending |
|
|
329
|
-
| Mutual Stake Escrow | ✅ Live | Reciprocal collateral task settlement |
|
|
330
|
-
| Optimistic Escrow | ✅ Live | Time-locked optimistic verification |
|
|
331
|
-
| x402 Payments | ✅ Live | HTTP 402 auto-pay — Base, Ethereum, Arbitrum, Polygon, Optimism, Avalanche, Unichain, Linea, Sonic, Worldchain |
|
|
332
|
-
| CCTP Bridge (EVM) | ✅ Live | Circle CCTP V2 across 10 EVM chains |
|
|
333
|
-
| CCTP Bridge (Solana) | ✅ Live | EVM↔Solana USDC bridging via CCTP V2 domain 5 |
|
|
334
|
-
| Spend Policies | ✅ Live | Per-token, per-period on-chain spending limits |
|
|
335
|
-
| Swap | ✅ Live | Uniswap V3 on Base, Arbitrum, Optimism, Polygon |
|
|
336
|
-
| Fiat Onramp | ✅ Live | Opt-in fiat-to-crypto |
|
|
337
|
-
| AP2 Protocol | ✅ Live | Agent-to-Agent task delegation and payment |
|
|
338
|
-
| Settlement | ✅ Live | On-chain settlement finalization |
|
|
339
|
-
| Gas Sponsorship | ✅ Live | ERC-4337 paymaster-based gas sponsorship |
|
|
328
|
+
const bridge = createBridge(walletClient, 'base');
|
|
340
329
|
|
|
341
|
-
|
|
330
|
+
// Bridge 100 USDC Base → Arbitrum (~12 seconds)
|
|
331
|
+
const result = await bridge.bridge(100_000_000n, 'arbitrum', {
|
|
332
|
+
minFinalityThreshold: 0, // FAST attestation
|
|
333
|
+
});
|
|
334
|
+
console.log('Completed in', result.elapsedMs, 'ms');
|
|
335
|
+
// Verified mainnet: Base → Arbitrum 0.50 USDC
|
|
336
|
+
// Burn: 0xfedbfaa4b3a9fbadd36668c50c2ee7fc7e32072e2bd409e00c46020a35329129
|
|
337
|
+
```
|
|
342
338
|
|
|
343
|
-
|
|
344
|
-
|---------|-------------|
|
|
345
|
-
| CowSwap Solver | Batch auction solutions, earn COW tokens |
|
|
346
|
-
| Flash Executor | Atomic flash loan execution |
|
|
347
|
-
| MEV Protection | Private mempool via Flashbots/MEV Blocker |
|
|
348
|
-
| Yield Staking | Aave V3, Compound V3, Morpho Blue strategies |
|
|
349
|
-
| Tax Reporting | Cost basis and gain/loss reporting |
|
|
339
|
+
## Solana SPL Support
|
|
350
340
|
|
|
351
|
-
|
|
341
|
+
```bash
|
|
342
|
+
npm install @solana/web3.js @solana/spl-token
|
|
343
|
+
```
|
|
352
344
|
|
|
353
|
-
|
|
345
|
+
```typescript
|
|
346
|
+
import { SolanaWallet } from 'agentwallet-sdk/tokens/solana';
|
|
354
347
|
|
|
355
|
-
|
|
348
|
+
const solWallet = new SolanaWallet({
|
|
349
|
+
privateKeyBase58: process.env.SOLANA_PRIVATE_KEY!,
|
|
350
|
+
});
|
|
356
351
|
|
|
357
|
-
|
|
352
|
+
const { sol } = await solWallet.getSolBalance();
|
|
353
|
+
const sig = await solWallet.sendSol('RecipientBase58Address', 0.1);
|
|
358
354
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
| **Stripe** (Fiat offramp) | Live (Feb 2026) | USDC -> USD | N/A | Vendors receive USD in Stripe dashboard. Agents pay USDC. |
|
|
355
|
+
// USDC on Solana
|
|
356
|
+
const usdcMint = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
|
|
357
|
+
const { amount, decimals } = await solWallet.getSplTokenBalance(usdcMint);
|
|
358
|
+
```
|
|
364
359
|
|
|
365
|
-
|
|
360
|
+
## On-Chain Identity (ERC-8004)
|
|
366
361
|
|
|
367
362
|
```typescript
|
|
368
|
-
import {
|
|
363
|
+
import { ERC8004Client, ReputationClient } from 'agentwallet-sdk';
|
|
369
364
|
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
365
|
+
const identity = new ERC8004Client({ chain: 'base' });
|
|
366
|
+
const { txHash, agentId } = await identity.registerAgent(walletClient, {
|
|
367
|
+
name: 'MyAgent',
|
|
368
|
+
description: 'Autonomous research agent',
|
|
374
369
|
});
|
|
375
370
|
|
|
376
|
-
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
const details = await response.json();
|
|
380
|
-
const proof = await wallet.createX402Proof(details);
|
|
381
|
-
const paid = await fetch('https://api.vendor.com/data', {
|
|
382
|
-
headers: { 'X-Payment': proof }
|
|
383
|
-
});
|
|
384
|
-
}
|
|
371
|
+
const reputation = new ReputationClient({ chain: 'base' });
|
|
372
|
+
const rep = await reputation.getAgentReputation(agentId!);
|
|
373
|
+
console.log(`Score: ${rep.totalScore} from ${rep.count} reviews`);
|
|
385
374
|
```
|
|
386
375
|
|
|
387
|
-
|
|
376
|
+
## Decimal Helpers
|
|
388
377
|
|
|
389
|
-
|
|
378
|
+
```typescript
|
|
379
|
+
import { toRaw, toHuman, formatBalance } from 'agentwallet-sdk';
|
|
390
380
|
|
|
391
|
-
|
|
381
|
+
const raw = toRaw('100.50', 6); // → 100_500_000n
|
|
382
|
+
const human = toHuman(100_500_000n, 6); // → "100.5"
|
|
383
|
+
const display = formatBalance(100_500_000n, 6, 'USDC', 2); // → "100.50 USDC"
|
|
384
|
+
```
|
|
392
385
|
|
|
393
|
-
|
|
394
|
-
|-------|--------|---------------|--------|
|
|
395
|
-
| Base → Arbitrum | 0.50 USDC | [`0xfedb...9129`](https://basescan.org/tx/0xfedbfaa4b3a9fbadd36668c50c2ee7fc7e32072e2bd409e00c46020a35329129) | ✅ Confirmed — [0.50 USDC received on Arbitrum](https://arbiscan.io/address/0xff86829393C6C26A4EC122bE0Cc3E466Ef876AdD) |
|
|
386
|
+
## Security Model
|
|
396
387
|
|
|
397
|
-
|
|
388
|
+
**What the on-chain spend policy enforces:**
|
|
398
389
|
|
|
399
|
-
|
|
400
|
-
|
|
390
|
+
Even if an agent is compromised (prompt injection, jailbreak, runaway loop), it cannot:
|
|
391
|
+
1. Spend more than the per-transaction limit you set
|
|
392
|
+
2. Exceed the daily/weekly cap you configured
|
|
393
|
+
3. Access funds outside its ERC-6551 token-bound account
|
|
394
|
+
4. Modify its own spend policy (only the owner wallet can do that)
|
|
401
395
|
|
|
402
|
-
|
|
403
|
-
sourceChain: 'base',
|
|
404
|
-
walletClient,
|
|
405
|
-
});
|
|
396
|
+
**Recommendation:** Start with $1/tx, $10/day. Raise caps only after you've watched the agent run for a week and it behaves exactly as expected.
|
|
406
397
|
|
|
407
|
-
|
|
408
|
-
const { txHash } = await bridge.bridge({
|
|
409
|
-
destinationChain: 'arbitrum',
|
|
410
|
-
recipient: '0xff86829393C6C26A4EC122bE0Cc3E466Ef876AdD',
|
|
411
|
-
amount: 500000n, // 0.50 USDC
|
|
412
|
-
});
|
|
413
|
-
```
|
|
398
|
+
Key management: your private key stays in your infrastructure. Compatible with Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, or local encrypted storage.
|
|
414
399
|
|
|
415
|
-
##
|
|
400
|
+
## Enterprise Deployment
|
|
416
401
|
|
|
417
|
-
|
|
418
|
-
| Chain | Network ID | x402 | Bridge | Swap |
|
|
419
|
-
|-------|-----------|------|--------|------|
|
|
420
|
-
| Base | 8453 | ✅ | ✅ | ✅ |
|
|
421
|
-
| Ethereum | 1 | ✅ | ✅ | — |
|
|
422
|
-
| Arbitrum | 42161 | ✅ | ✅ | ✅ |
|
|
423
|
-
| Polygon | 137 | ✅ | ✅ | ✅ |
|
|
424
|
-
| Optimism | 10 | ✅ | ✅ | ✅ |
|
|
425
|
-
| Avalanche | 43114 | ✅ | ✅ | — |
|
|
426
|
-
| Unichain | 130 | ✅ | ✅ | — |
|
|
427
|
-
| Linea | 59144 | ✅ | ✅ | — |
|
|
428
|
-
| Sonic | 146 | ✅ | ✅ | — |
|
|
429
|
-
| World Chain | 480 | ✅ | ✅ | — |
|
|
430
|
-
| Solana | — | — | ✅ (CCTP) | — |
|
|
431
|
-
| Base Sepolia | 84532 | ✅ (testnet) | — | — |
|
|
402
|
+
The SDK runs in your infrastructure — no third-party custody, no shared key management, no data leaving your network.
|
|
432
403
|
|
|
433
|
-
|
|
404
|
+
```bash
|
|
405
|
+
# Docker deployment
|
|
406
|
+
docker run \
|
|
407
|
+
-e WALLET_PRIVATE_KEY_FILE=/secrets/key \
|
|
408
|
+
-e RPC_URL=https://mainnet.base.org \
|
|
409
|
+
-v /path/to/secrets:/secrets:ro \
|
|
410
|
+
agentwallet-sdk:latest
|
|
411
|
+
```
|
|
434
412
|
|
|
435
|
-
|
|
413
|
+
Stateless design — wallet state lives on-chain, not in application memory. Multiple SDK instances can safely share a wallet address. Nonce management handled.
|
|
436
414
|
|
|
437
|
-
|
|
415
|
+
### Key compliance properties
|
|
416
|
+
- All private keys generated and stored locally — no external key management service
|
|
417
|
+
- No telemetry, analytics, or usage data transmitted to any third party
|
|
418
|
+
- Every transaction on-chain with block number, timestamp, and gas cost — immutable audit log
|
|
419
|
+
- SpendingPolicy changes are on-chain events — tamper-proof
|
|
420
|
+
- NFT transfer = instant revocation of all agent permissions — no "forgot to deprovision" risk
|
|
438
421
|
|
|
439
|
-
|
|
440
|
-
|-----------|-------------|
|
|
441
|
-
| **EmailResolver** *(NEW)* | AgentMail integration — agents get `email@agentmail.to` linked to wallet. Resolve email→wallet, send/receive with embedded x402 payment requests. |
|
|
442
|
-
| **AgentIdentity** | ERC-8004 + ERC-6551: on-chain NFT identity + Token Bound Account |
|
|
443
|
-
| **ReputationClient** | On-chain reputation scoring — give/read feedback, aggregate scores |
|
|
444
|
-
| **VerifiableIntentClient** | Mastercard-spec signed payment intents with scope enforcement |
|
|
445
|
-
| **ValidationClient** | Request/respond validation workflow (TEE attestations, compliance) |
|
|
422
|
+
## Links
|
|
446
423
|
|
|
447
|
-
|
|
424
|
+
- [GitHub](https://github.com/up2itnow0822/agent-wallet-sdk)
|
|
425
|
+
- [npm](https://www.npmjs.com/package/agentwallet-sdk)
|
|
426
|
+
- [ERC-8004 Spec](https://eips.ethereum.org/EIPS/eip-8004)
|
|
427
|
+
- [agentpay-mcp](https://github.com/up2itnow0822/agentpay-mcp) — MCP server wrapping this SDK
|
|
448
428
|
|
|
449
|
-
|
|
450
|
-
import { EmailResolver } from 'agentwallet-sdk';
|
|
429
|
+
## Patent Notice
|
|
451
430
|
|
|
452
|
-
|
|
431
|
+
**Patent Pending** — USPTO provisional patent application filed March 2026: "Non-Custodial Multi-Chain Financial Infrastructure System for Autonomous AI Agents."
|
|
453
432
|
|
|
454
|
-
|
|
455
|
-
const wallet = await resolver.resolveEmail('myagent@agentmail.to');
|
|
456
|
-
console.log(wallet.address); // 0x...
|
|
433
|
+
Our provisional filing is defensive — intended to prevent hostile monopolization of open payment rails and protect builders' ability to use open standards.
|
|
457
434
|
|
|
458
|
-
|
|
459
|
-
await resolver.sendWithPayment({
|
|
460
|
-
to: 'vendor@agentmail.to',
|
|
461
|
-
subject: 'Payment for API access',
|
|
462
|
-
amount: 5_000_000n, // 5 USDC
|
|
463
|
-
token: 'USDC',
|
|
464
|
-
chain: 'base',
|
|
465
|
-
});
|
|
466
|
-
```
|
|
435
|
+
## Disclaimer
|
|
467
436
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
- [ERC-8004 Spec](https://eips.ethereum.org/EIPS/eip-8004)
|
|
471
|
-
- [GitHub](https://github.com/agentnexus/agent-wallet-sdk)
|
|
472
|
-
- [npm](https://www.npmjs.com/package/agentwallet-sdk)
|
|
437
|
+
Non-custodial developer tooling. You control your own keys and set your own spending limits. You are responsible for compliance with applicable laws in your jurisdiction. Provided as-is under the MIT license. Nothing here constitutes financial advice, custody services, or money transmission.
|
|
473
438
|
|
|
474
439
|
## License
|
|
475
440
|
|
|
476
441
|
MIT
|
|
477
|
-
|