agentwallet-sdk 6.0.4 → 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/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/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 +12 -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
|
-
// Look up any agent
|
|
227
|
-
const agent = await identity.lookupAgentIdentity(agentId!);
|
|
228
|
-
console.log(agent.owner, agent.agentURI);
|
|
229
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 ──────────┘
|
|
247
|
+
```
|
|
248
|
+
|
|
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.
|
|
230
250
|
|
|
231
|
-
##
|
|
251
|
+
## Token Registry
|
|
232
252
|
|
|
233
|
-
|
|
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';
|
|
270
|
+
import { sendToken, sendNative, getTokenBalance, getBalances } from 'agentwallet-sdk';
|
|
264
271
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
// Request validation from a validator
|
|
271
|
-
const requestHash = keccak256(toBytes('my-validation-request-v1'));
|
|
272
|
-
await validation.requestValidation(walletClient, {
|
|
273
|
-
validator: '0xValidatorContract',
|
|
274
|
-
agentId: 42n,
|
|
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
|
});
|
|
299
|
-
|
|
300
|
-
// Create escrow — both agent and client stake
|
|
301
|
-
const { escrowId, txHash } = await escrow.create({
|
|
302
|
-
counterparty: '0xOtherAgent',
|
|
303
|
-
token: '0xUSDC',
|
|
304
|
-
stakeAmount: 100000000n, // 100 USDC
|
|
305
|
-
taskHash: '0x...',
|
|
306
|
-
deadline: BigInt(Math.floor(Date.now() / 1000) + 86400),
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
// Counterparty funds their side
|
|
310
|
-
await escrow.fund(escrowId);
|
|
311
|
-
|
|
312
|
-
// After task completion, fulfill
|
|
313
|
-
await escrow.fulfill(escrowId, proofHash);
|
|
314
|
-
|
|
315
|
-
// Verify and release stakes
|
|
316
|
-
await escrow.verify(escrowId);
|
|
317
296
|
```
|
|
318
297
|
|
|
319
|
-
|
|
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) | ✅ | — | — |
|
|
320
308
|
|
|
321
|
-
|
|
309
|
+
## Uniswap V3 Swaps
|
|
322
310
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
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 |
|
|
311
|
+
```typescript
|
|
312
|
+
import { attachSwap } from 'agentwallet-sdk/swap';
|
|
313
|
+
import { BASE_TOKENS } from 'agentwallet-sdk';
|
|
340
314
|
|
|
341
|
-
|
|
315
|
+
const swap = attachSwap(wallet, { chain: 'base' });
|
|
342
316
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
| Yield Staking | Aave V3, Compound V3, Morpho Blue strategies |
|
|
349
|
-
| Tax Reporting | Cost basis and gain/loss reporting |
|
|
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);
|
|
321
|
+
```
|
|
350
322
|
|
|
351
|
-
|
|
323
|
+
## CCTP V2 Bridging
|
|
352
324
|
|
|
353
|
-
|
|
325
|
+
```typescript
|
|
326
|
+
import { createBridge } from 'agentwallet-sdk';
|
|
354
327
|
|
|
355
|
-
|
|
328
|
+
const bridge = createBridge(walletClient, 'base');
|
|
356
329
|
|
|
357
|
-
|
|
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
|
+
```
|
|
358
338
|
|
|
359
|
-
|
|
360
|
-
|---|---|---|---|---|
|
|
361
|
-
| **Base** (Coinbase L2) | Live | USDC | Sub-cent | Primary x402 chain. 15M+ transactions in Jan 2026. |
|
|
362
|
-
| **Etherlink** (Tezos L2) | Live (Mar 2026) | USDC | Sub-cent | EVM-compatible. Same x402 integration, different RPC + chain ID. |
|
|
363
|
-
| **Stripe** (Fiat offramp) | Live (Feb 2026) | USDC -> USD | N/A | Vendors receive USD in Stripe dashboard. Agents pay USDC. |
|
|
339
|
+
## Solana SPL Support
|
|
364
340
|
|
|
365
|
-
|
|
341
|
+
```bash
|
|
342
|
+
npm install @solana/web3.js @solana/spl-token
|
|
343
|
+
```
|
|
366
344
|
|
|
367
345
|
```typescript
|
|
368
|
-
import {
|
|
346
|
+
import { SolanaWallet } from 'agentwallet-sdk/tokens/solana';
|
|
369
347
|
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
chain: 'etherlink', // new: Tezos L2 support
|
|
373
|
-
walletClient,
|
|
348
|
+
const solWallet = new SolanaWallet({
|
|
349
|
+
privateKeyBase58: process.env.SOLANA_PRIVATE_KEY!,
|
|
374
350
|
});
|
|
375
351
|
|
|
376
|
-
|
|
377
|
-
const
|
|
378
|
-
if (response.status === 402) {
|
|
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
|
-
}
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
The SDK handles chain-specific RPC endpoints, gas estimation, and USDC contract addresses automatically. Swap `chain: 'base'` to `chain: 'etherlink'` and the x402 flow works identically.
|
|
388
|
-
|
|
389
|
-
## Cross-Chain Bridge — Verified on Mainnet
|
|
390
|
-
|
|
391
|
-
Live CCTP V2 bridge transfers verified on mainnet (March 15, 2026):
|
|
352
|
+
const { sol } = await solWallet.getSolBalance();
|
|
353
|
+
const sig = await solWallet.sendSol('RecipientBase58Address', 0.1);
|
|
392
354
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
355
|
+
// USDC on Solana
|
|
356
|
+
const usdcMint = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
|
|
357
|
+
const { amount, decimals } = await solWallet.getSplTokenBalance(usdcMint);
|
|
358
|
+
```
|
|
396
359
|
|
|
397
|
-
|
|
360
|
+
## On-Chain Identity (ERC-8004)
|
|
398
361
|
|
|
399
362
|
```typescript
|
|
400
|
-
import {
|
|
363
|
+
import { ERC8004Client, ReputationClient } from 'agentwallet-sdk';
|
|
401
364
|
|
|
402
|
-
const
|
|
403
|
-
|
|
404
|
-
|
|
365
|
+
const identity = new ERC8004Client({ chain: 'base' });
|
|
366
|
+
const { txHash, agentId } = await identity.registerAgent(walletClient, {
|
|
367
|
+
name: 'MyAgent',
|
|
368
|
+
description: 'Autonomous research agent',
|
|
405
369
|
});
|
|
406
370
|
|
|
407
|
-
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
recipient: '0xff86829393C6C26A4EC122bE0Cc3E466Ef876AdD',
|
|
411
|
-
amount: 500000n, // 0.50 USDC
|
|
412
|
-
});
|
|
371
|
+
const reputation = new ReputationClient({ chain: 'base' });
|
|
372
|
+
const rep = await reputation.getAgentReputation(agentId!);
|
|
373
|
+
console.log(`Score: ${rep.totalScore} from ${rep.count} reviews`);
|
|
413
374
|
```
|
|
414
375
|
|
|
415
|
-
##
|
|
376
|
+
## Decimal Helpers
|
|
416
377
|
|
|
417
|
-
|
|
418
|
-
|
|
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) | — | — |
|
|
378
|
+
```typescript
|
|
379
|
+
import { toRaw, toHuman, formatBalance } from 'agentwallet-sdk';
|
|
432
380
|
|
|
433
|
-
|
|
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
|
+
```
|
|
434
385
|
|
|
435
|
-
##
|
|
386
|
+
## Security Model
|
|
436
387
|
|
|
437
|
-
|
|
388
|
+
**What the on-chain spend policy enforces:**
|
|
438
389
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
| **VerifiableIntentClient** | Mastercard-spec signed payment intents with scope enforcement |
|
|
445
|
-
| **ValidationClient** | Request/respond validation workflow (TEE attestations, compliance) |
|
|
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)
|
|
446
395
|
|
|
447
|
-
|
|
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.
|
|
448
397
|
|
|
449
|
-
|
|
450
|
-
import { EmailResolver } from 'agentwallet-sdk';
|
|
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.
|
|
451
399
|
|
|
452
|
-
|
|
400
|
+
## Enterprise Deployment
|
|
453
401
|
|
|
454
|
-
|
|
455
|
-
const wallet = await resolver.resolveEmail('myagent@agentmail.to');
|
|
456
|
-
console.log(wallet.address); // 0x...
|
|
402
|
+
The SDK runs in your infrastructure — no third-party custody, no shared key management, no data leaving your network.
|
|
457
403
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
});
|
|
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
|
|
466
411
|
```
|
|
467
412
|
|
|
413
|
+
Stateless design — wallet state lives on-chain, not in application memory. Multiple SDK instances can safely share a wallet address. Nonce management handled.
|
|
414
|
+
|
|
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
|
|
421
|
+
|
|
468
422
|
## Links
|
|
469
423
|
|
|
470
|
-
- [ERC-8004 Spec](https://eips.ethereum.org/EIPS/eip-8004)
|
|
471
424
|
- [GitHub](https://github.com/up2itnow0822/agent-wallet-sdk)
|
|
472
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
|
|
428
|
+
|
|
429
|
+
## Patent Notice
|
|
430
|
+
|
|
431
|
+
**Patent Pending** — USPTO provisional patent application filed March 2026: "Non-Custodial Multi-Chain Financial Infrastructure System for Autonomous AI Agents."
|
|
432
|
+
|
|
433
|
+
Our provisional filing is defensive — intended to prevent hostile monopolization of open payment rails and protect builders' ability to use open standards.
|
|
434
|
+
|
|
435
|
+
## Disclaimer
|
|
436
|
+
|
|
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
|
-
|