agentwallet-sdk 2.4.1 → 2.5.0
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 +46 -19
- package/dist/chains.d.ts +37 -0
- package/dist/chains.d.ts.map +1 -0
- package/dist/chains.js +75 -0
- package/dist/chains.js.map +1 -0
- package/dist/index.d.ts +4 -499
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/swap/SwapModule.d.ts +4 -1
- package/dist/swap/SwapModule.d.ts.map +1 -1
- package/dist/swap/SwapModule.js +7 -2
- package/dist/swap/SwapModule.js.map +1 -1
- package/dist/swap/types.d.ts +4 -2
- package/dist/swap/types.d.ts.map +1 -1
- package/dist/swap/types.js.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/x402/types.d.ts +2 -2
- package/dist/x402/types.d.ts.map +1 -1
- package/dist/x402/types.js +6 -2
- package/dist/x402/types.js.map +1 -1
- package/package.json +27 -12
- package/dist/bridge/__tests__/bridge.test.d.ts +0 -2
- package/dist/bridge/__tests__/bridge.test.d.ts.map +0 -1
- package/dist/bridge/__tests__/bridge.test.js +0 -508
- package/dist/bridge/__tests__/bridge.test.js.map +0 -1
- package/dist/swap/__tests__/swap.test.d.ts +0 -2
- package/dist/swap/__tests__/swap.test.d.ts.map +0 -1
- package/dist/swap/__tests__/swap.test.js +0 -272
- package/dist/swap/__tests__/swap.test.js.map +0 -1
- package/dist/x402/__tests__/budget.test.d.ts +0 -2
- package/dist/x402/__tests__/budget.test.d.ts.map +0 -1
- package/dist/x402/__tests__/budget.test.js +0 -114
- package/dist/x402/__tests__/budget.test.js.map +0 -1
- package/dist/x402/__tests__/client.test.d.ts +0 -2
- package/dist/x402/__tests__/client.test.d.ts.map +0 -1
- package/dist/x402/__tests__/client.test.js +0 -107
- package/dist/x402/__tests__/client.test.js.map +0 -1
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
// [MAX-ADDED] SwapModule tests — 14 tests covering all critical paths
|
|
2
|
-
// All on-chain calls are mocked. No real swaps are executed.
|
|
3
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
4
|
-
import { SwapModule, attachSwap, calcProtocolFee, applySlippage } from '../SwapModule.js';
|
|
5
|
-
import { BASE_TOKENS, PROTOCOL_FEE_BPS, DEFAULT_SLIPPAGE_BPS } from '../types.js';
|
|
6
|
-
// ─── Mock Factories ──────────────────────────────────────────────────────────
|
|
7
|
-
// Valid checksummed Ethereum addresses for testing
|
|
8
|
-
const WALLET_ADDR = '0x0000000000000000000000000000000000000001';
|
|
9
|
-
const FEE_WALLET = '0x0000000000000000000000000000000000000002';
|
|
10
|
-
const MOCK_TX_HASH = '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef';
|
|
11
|
-
const MOCK_FEE_TX = '0xcafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe';
|
|
12
|
-
const MOCK_APPROVAL_TX = '0xaaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbb';
|
|
13
|
-
/** Build a mock publicClient with configurable readContract behavior */
|
|
14
|
-
function makePublicClient(overrides = {}) {
|
|
15
|
-
return {
|
|
16
|
-
readContract: vi.fn(async ({ functionName, args }) => {
|
|
17
|
-
if (functionName === 'quoteExactInputSingle') {
|
|
18
|
-
// Return a mock quote: 95 WETH for 100K USDC at fee tier 500
|
|
19
|
-
return [95000000000000000000n, 0n, 1, 120000n];
|
|
20
|
-
}
|
|
21
|
-
if (functionName === 'allowance') {
|
|
22
|
-
return overrides.allowance ?? 0n;
|
|
23
|
-
}
|
|
24
|
-
return overrides[functionName] ?? 0n;
|
|
25
|
-
}),
|
|
26
|
-
...overrides,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
/** Build a mock walletClient */
|
|
30
|
-
function makeWalletClient(overrides = {}) {
|
|
31
|
-
return {
|
|
32
|
-
account: { address: WALLET_ADDR },
|
|
33
|
-
chain: { id: 8453 },
|
|
34
|
-
sendTransaction: vi.fn(async () => MOCK_TX_HASH),
|
|
35
|
-
...overrides,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
// ─── Unit: Pure Helper Functions ─────────────────────────────────────────────
|
|
39
|
-
describe('calcProtocolFee', () => {
|
|
40
|
-
it('calculates 0.875% fee correctly', () => {
|
|
41
|
-
// 100_000 USDC (6 decimals) = 100_000_000_000 raw
|
|
42
|
-
const amount = 100000000000n;
|
|
43
|
-
const fee = calcProtocolFee(amount, PROTOCOL_FEE_BPS);
|
|
44
|
-
// 0.875% of 100_000_000_000 = 875_000_000
|
|
45
|
-
expect(fee).toBe(875000000n);
|
|
46
|
-
});
|
|
47
|
-
it('floors partial bps (no dust rounding up)', () => {
|
|
48
|
-
const amount = 1n; // 1 wei
|
|
49
|
-
const fee = calcProtocolFee(amount, PROTOCOL_FEE_BPS);
|
|
50
|
-
// 1 * 875 / 100_000 = 0 (floor)
|
|
51
|
-
expect(fee).toBe(0n);
|
|
52
|
-
});
|
|
53
|
-
it('handles large amounts correctly', () => {
|
|
54
|
-
// 1 ETH = 1e18 wei
|
|
55
|
-
const one_eth = 1000000000000000000n;
|
|
56
|
-
const fee = calcProtocolFee(one_eth, PROTOCOL_FEE_BPS);
|
|
57
|
-
// 0.875% of 1e18 = 8_750_000_000_000_000
|
|
58
|
-
expect(fee).toBe(8750000000000000n);
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
describe('applySlippage', () => {
|
|
62
|
-
it('applies 50 bps (0.5%) slippage correctly', () => {
|
|
63
|
-
const amount = 1000000n;
|
|
64
|
-
const minimum = applySlippage(amount, DEFAULT_SLIPPAGE_BPS);
|
|
65
|
-
// 1_000_000 * (10_000 - 50) / 10_000 = 1_000_000 * 9950 / 10_000 = 995_000
|
|
66
|
-
expect(minimum).toBe(995000n);
|
|
67
|
-
});
|
|
68
|
-
it('applies 100 bps (1%) slippage correctly', () => {
|
|
69
|
-
const amount = 1000000n;
|
|
70
|
-
const minimum = applySlippage(amount, 100);
|
|
71
|
-
expect(minimum).toBe(990000n);
|
|
72
|
-
});
|
|
73
|
-
it('returns same amount for 0 bps slippage', () => {
|
|
74
|
-
const amount = 500000n;
|
|
75
|
-
expect(applySlippage(amount, 0)).toBe(500000n);
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
// ─── SwapModule: Quote Fetching ───────────────────────────────────────────────
|
|
79
|
-
describe('SwapModule.getQuote', () => {
|
|
80
|
-
let swapModule;
|
|
81
|
-
let mockPublicClient;
|
|
82
|
-
let mockWalletClient;
|
|
83
|
-
beforeEach(() => {
|
|
84
|
-
mockPublicClient = makePublicClient();
|
|
85
|
-
mockWalletClient = makeWalletClient();
|
|
86
|
-
swapModule = new SwapModule(mockPublicClient, mockWalletClient, WALLET_ADDR, { feeWallet: FEE_WALLET });
|
|
87
|
-
});
|
|
88
|
-
it('fetches quote and deducts protocol fee from amountIn', async () => {
|
|
89
|
-
const amountIn = 100000000n; // 100 USDC (6 decimals)
|
|
90
|
-
const quote = await swapModule.getQuote(BASE_TOKENS.USDC, BASE_TOKENS.WETH, amountIn);
|
|
91
|
-
// Protocol fee should be 0.875% of 100_000_000 = 875_000
|
|
92
|
-
expect(quote.feeAmount).toBe(875000n);
|
|
93
|
-
expect(quote.amountInNet).toBe(99125000n);
|
|
94
|
-
expect(quote.amountInRaw).toBe(amountIn);
|
|
95
|
-
});
|
|
96
|
-
it('selects the fee tier with best (highest) amountOut', async () => {
|
|
97
|
-
// Make 500-tier return better price than others
|
|
98
|
-
mockPublicClient.readContract = vi.fn(async ({ args }) => {
|
|
99
|
-
const fee = args[0].fee;
|
|
100
|
-
if (fee === 500)
|
|
101
|
-
return [200000n, 0n, 1, 100000n]; // best
|
|
102
|
-
if (fee === 3000)
|
|
103
|
-
return [180000n, 0n, 1, 110000n]; // worse
|
|
104
|
-
throw new Error('Pool not found'); // 100 and 10000 don't exist
|
|
105
|
-
});
|
|
106
|
-
const quote = await swapModule.getQuote(BASE_TOKENS.USDC, BASE_TOKENS.WETH, 1000000n);
|
|
107
|
-
expect(quote.poolFeeTier).toBe(500);
|
|
108
|
-
expect(quote.amountOut).toBe(200000n);
|
|
109
|
-
});
|
|
110
|
-
it('throws if no pool found for any fee tier', async () => {
|
|
111
|
-
mockPublicClient.readContract = vi.fn(async () => {
|
|
112
|
-
throw new Error('execution reverted');
|
|
113
|
-
});
|
|
114
|
-
await expect(swapModule.getQuote(BASE_TOKENS.USDC, BASE_TOKENS.WETH, 1000000n)).rejects.toThrow('No Uniswap V3 pool found');
|
|
115
|
-
});
|
|
116
|
-
it('throws if amountIn is too small to cover protocol fee', async () => {
|
|
117
|
-
// With PROTOCOL_FEE_BPS=875, amountIn must be > 875/100_000 per unit
|
|
118
|
-
// For amountIn=1n: fee=0n, net=1n — this actually works due to flooring
|
|
119
|
-
// For a crafted case: if fee somehow = amountIn... hard to trigger naturally.
|
|
120
|
-
// Instead test: amountIn=0
|
|
121
|
-
await expect(swapModule.getQuote(BASE_TOKENS.USDC, BASE_TOKENS.WETH, 0n)).rejects.toThrow('too small');
|
|
122
|
-
});
|
|
123
|
-
it('calculates amountOutMinimum with default 50 bps slippage', async () => {
|
|
124
|
-
// Mock returns amountOut = 1_000_000n
|
|
125
|
-
mockPublicClient.readContract = vi.fn(async () => [1000000n, 0n, 1, 50000n]);
|
|
126
|
-
const quote = await swapModule.getQuote(BASE_TOKENS.USDC, BASE_TOKENS.WETH, 1000000n);
|
|
127
|
-
// amountOutMinimum = 1_000_000 * (10_000 - 50) / 10_000 = 995_000
|
|
128
|
-
expect(quote.amountOutMinimum).toBe(995000n);
|
|
129
|
-
});
|
|
130
|
-
it('respects custom slippage override', async () => {
|
|
131
|
-
mockPublicClient.readContract = vi.fn(async () => [1000000n, 0n, 1, 50000n]);
|
|
132
|
-
const quote = await swapModule.getQuote(BASE_TOKENS.USDC, BASE_TOKENS.WETH, 1000000n, { slippageBps: 200 });
|
|
133
|
-
// 1_000_000 * 9800 / 10_000 = 980_000
|
|
134
|
-
expect(quote.amountOutMinimum).toBe(980000n);
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
// ─── SwapModule: Approval Handling ───────────────────────────────────────────
|
|
138
|
-
describe('SwapModule.ensureApproval', () => {
|
|
139
|
-
it('skips approval if allowance is already sufficient', async () => {
|
|
140
|
-
const publicClient = makePublicClient({ allowance: 10000000000n }); // huge allowance
|
|
141
|
-
const walletClient = makeWalletClient();
|
|
142
|
-
const swapModule = new SwapModule(publicClient, walletClient, WALLET_ADDR);
|
|
143
|
-
const result = await swapModule.ensureApproval(BASE_TOKENS.USDC, '0x2626664c2603336E57B271c5C0b26F421741e481', 1000000n);
|
|
144
|
-
expect(result).toBeUndefined();
|
|
145
|
-
expect(walletClient.sendTransaction).not.toHaveBeenCalled();
|
|
146
|
-
});
|
|
147
|
-
it('submits approval tx when allowance is insufficient', async () => {
|
|
148
|
-
const publicClient = makePublicClient({ allowance: 0n });
|
|
149
|
-
const walletClient = makeWalletClient({
|
|
150
|
-
sendTransaction: vi.fn(async () => MOCK_APPROVAL_TX),
|
|
151
|
-
});
|
|
152
|
-
const swapModule = new SwapModule(publicClient, walletClient, WALLET_ADDR);
|
|
153
|
-
const result = await swapModule.ensureApproval(BASE_TOKENS.USDC, '0x2626664c2603336E57B271c5C0b26F421741e481', 1000000n);
|
|
154
|
-
expect(result).toBe(MOCK_APPROVAL_TX);
|
|
155
|
-
expect(walletClient.sendTransaction).toHaveBeenCalledOnce();
|
|
156
|
-
});
|
|
157
|
-
it('throws if walletClient has no account', async () => {
|
|
158
|
-
const publicClient = makePublicClient({ allowance: 0n });
|
|
159
|
-
const walletClient = makeWalletClient({ account: null });
|
|
160
|
-
const swapModule = new SwapModule(publicClient, walletClient, WALLET_ADDR);
|
|
161
|
-
await expect(swapModule.ensureApproval(BASE_TOKENS.USDC, '0x2626664c2603336E57B271c5C0b26F421741e481', 1000000n)).rejects.toThrow('no account');
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
// ─── SwapModule: Swap Execution ───────────────────────────────────────────────
|
|
165
|
-
describe('SwapModule.swap', () => {
|
|
166
|
-
let mockPublicClient;
|
|
167
|
-
let mockWalletClient;
|
|
168
|
-
let swapModule;
|
|
169
|
-
beforeEach(() => {
|
|
170
|
-
mockPublicClient = makePublicClient({ allowance: 0n });
|
|
171
|
-
let txCallCount = 0;
|
|
172
|
-
mockWalletClient = makeWalletClient({
|
|
173
|
-
sendTransaction: vi.fn(async () => {
|
|
174
|
-
// Call order: 1=approval, 2=fee transfer, 3=swap
|
|
175
|
-
txCallCount++;
|
|
176
|
-
if (txCallCount === 1)
|
|
177
|
-
return MOCK_APPROVAL_TX;
|
|
178
|
-
if (txCallCount === 2)
|
|
179
|
-
return MOCK_FEE_TX;
|
|
180
|
-
return MOCK_TX_HASH;
|
|
181
|
-
}),
|
|
182
|
-
});
|
|
183
|
-
swapModule = new SwapModule(mockPublicClient, mockWalletClient, WALLET_ADDR, { feeWallet: FEE_WALLET });
|
|
184
|
-
});
|
|
185
|
-
it('executes full swap with approval + fee transfer', async () => {
|
|
186
|
-
mockPublicClient.readContract = vi.fn(async ({ functionName, args }) => {
|
|
187
|
-
if (functionName === 'quoteExactInputSingle')
|
|
188
|
-
return [1000000n, 0n, 1, 80000n];
|
|
189
|
-
if (functionName === 'allowance')
|
|
190
|
-
return 0n;
|
|
191
|
-
return 0n;
|
|
192
|
-
});
|
|
193
|
-
const result = await swapModule.swap(BASE_TOKENS.USDC, BASE_TOKENS.WETH, 100000000n);
|
|
194
|
-
expect(result.txHash).toBeDefined();
|
|
195
|
-
expect(result.approvalRequired).toBe(true);
|
|
196
|
-
expect(result.approvalTxHash).toBe(MOCK_APPROVAL_TX);
|
|
197
|
-
expect(result.feeTxHash).toBe(MOCK_FEE_TX);
|
|
198
|
-
expect(result.quote.feeAmount).toBe(875000n); // 0.875% of 100_000_000
|
|
199
|
-
});
|
|
200
|
-
it('skips fee transfer when feeWallet == self (accountAddress)', async () => {
|
|
201
|
-
mockPublicClient.readContract = vi.fn(async ({ functionName }) => {
|
|
202
|
-
if (functionName === 'quoteExactInputSingle')
|
|
203
|
-
return [1000000n, 0n, 1, 80000n];
|
|
204
|
-
if (functionName === 'allowance')
|
|
205
|
-
return 999999999999n; // already approved
|
|
206
|
-
return 0n;
|
|
207
|
-
});
|
|
208
|
-
// Create module with feeWallet = wallet address (default self)
|
|
209
|
-
const selfSwapModule = new SwapModule(mockPublicClient, mockWalletClient, WALLET_ADDR, { feeWallet: WALLET_ADDR });
|
|
210
|
-
const result = await selfSwapModule.swap(BASE_TOKENS.USDC, BASE_TOKENS.WETH, 100000000n);
|
|
211
|
-
expect(result.feeTxHash).toBeUndefined();
|
|
212
|
-
expect(result.approvalRequired).toBe(false);
|
|
213
|
-
expect(result.txHash).toBeDefined();
|
|
214
|
-
});
|
|
215
|
-
it('applies slippage protection — amountOutMinimum encoded in calldata', async () => {
|
|
216
|
-
mockPublicClient.readContract = vi.fn(async ({ functionName }) => {
|
|
217
|
-
if (functionName === 'quoteExactInputSingle')
|
|
218
|
-
return [2000000n, 0n, 1, 80000n];
|
|
219
|
-
if (functionName === 'allowance')
|
|
220
|
-
return 999999999999n;
|
|
221
|
-
return 0n;
|
|
222
|
-
});
|
|
223
|
-
const selfSwapModule = new SwapModule(mockPublicClient, mockWalletClient, WALLET_ADDR, { feeWallet: WALLET_ADDR });
|
|
224
|
-
const result = await selfSwapModule.swap(BASE_TOKENS.USDC, BASE_TOKENS.WETH, 10000000n, { slippageBps: 100 });
|
|
225
|
-
// amountOutMinimum = 2_000_000 * 9900 / 10_000 = 1_980_000
|
|
226
|
-
expect(result.quote.amountOutMinimum).toBe(1980000n);
|
|
227
|
-
expect(result.txHash).toBeDefined();
|
|
228
|
-
});
|
|
229
|
-
it('returns gas estimate from quoter in result quote', async () => {
|
|
230
|
-
mockPublicClient.readContract = vi.fn(async ({ functionName }) => {
|
|
231
|
-
if (functionName === 'quoteExactInputSingle')
|
|
232
|
-
return [500000n, 0n, 1, 150000n];
|
|
233
|
-
if (functionName === 'allowance')
|
|
234
|
-
return 999999999999n;
|
|
235
|
-
return 0n;
|
|
236
|
-
});
|
|
237
|
-
const selfSwapModule = new SwapModule(mockPublicClient, mockWalletClient, WALLET_ADDR, { feeWallet: WALLET_ADDR });
|
|
238
|
-
const result = await selfSwapModule.swap(BASE_TOKENS.cbETH, BASE_TOKENS.WETH, 1000000000000000000n);
|
|
239
|
-
expect(result.quote.gasEstimate).toBe(150000n);
|
|
240
|
-
});
|
|
241
|
-
});
|
|
242
|
-
// ─── SwapModule: Config & attachSwap ─────────────────────────────────────────
|
|
243
|
-
describe('SwapModule config and attachSwap', () => {
|
|
244
|
-
it('getConfig returns correct fee settings', () => {
|
|
245
|
-
const swapModule = new SwapModule(makePublicClient(), makeWalletClient(), WALLET_ADDR, { feeWallet: FEE_WALLET, feeBps: PROTOCOL_FEE_BPS });
|
|
246
|
-
const config = swapModule.getConfig();
|
|
247
|
-
expect(config.feeBps).toBe(875);
|
|
248
|
-
expect(config.feeWallet).toBe(FEE_WALLET);
|
|
249
|
-
expect(config.routerAddress).toBe('0x2626664c2603336E57B271c5C0b26F421741e481');
|
|
250
|
-
expect(config.quoterAddress).toBe('0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a');
|
|
251
|
-
});
|
|
252
|
-
it('attachSwap enriches wallet with .swap() and .getQuote() methods', async () => {
|
|
253
|
-
const publicClient = makePublicClient();
|
|
254
|
-
publicClient.readContract = vi.fn(async ({ functionName }) => {
|
|
255
|
-
if (functionName === 'quoteExactInputSingle')
|
|
256
|
-
return [1000n, 0n, 1, 50000n];
|
|
257
|
-
return 0n;
|
|
258
|
-
});
|
|
259
|
-
const wallet = {
|
|
260
|
-
address: WALLET_ADDR,
|
|
261
|
-
publicClient: publicClient,
|
|
262
|
-
walletClient: makeWalletClient(),
|
|
263
|
-
};
|
|
264
|
-
const swapWallet = attachSwap(wallet, { feeWallet: FEE_WALLET });
|
|
265
|
-
expect(typeof swapWallet.swap).toBe('function');
|
|
266
|
-
expect(typeof swapWallet.getQuote).toBe('function');
|
|
267
|
-
expect(swapWallet.swapModule).toBeInstanceOf(SwapModule);
|
|
268
|
-
const quote = await swapWallet.getQuote(BASE_TOKENS.USDC, BASE_TOKENS.WETH, 1000000n);
|
|
269
|
-
expect(quote.feeAmount).toBe(8750n); // 0.875% of 1_000_000
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
//# sourceMappingURL=swap.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"swap.test.js","sourceRoot":"","sources":["../../../src/swap/__tests__/swap.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"budget.test.d.ts","sourceRoot":"","sources":["../../../src/x402/__tests__/budget.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
// [MAX-ADDED] Tests for x402 Budget Tracker
|
|
2
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
3
|
-
import { X402BudgetTracker } from '../budget.js';
|
|
4
|
-
describe('X402BudgetTracker', () => {
|
|
5
|
-
let tracker;
|
|
6
|
-
beforeEach(() => {
|
|
7
|
-
tracker = new X402BudgetTracker({
|
|
8
|
-
globalDailyLimit: 100000000n, // 100 USDC
|
|
9
|
-
globalPerRequestMax: 10000000n, // 10 USDC
|
|
10
|
-
serviceBudgets: [
|
|
11
|
-
{ service: 'api.example.com', maxPerRequest: 5000000n, dailyLimit: 50000000n },
|
|
12
|
-
{ service: '*', maxPerRequest: 2000000n, dailyLimit: 20000000n },
|
|
13
|
-
],
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
it('allows payments within limits', () => {
|
|
17
|
-
const result = tracker.checkBudget('api.example.com', 1000000n);
|
|
18
|
-
expect(result.allowed).toBe(true);
|
|
19
|
-
});
|
|
20
|
-
it('rejects payments exceeding global per-request max', () => {
|
|
21
|
-
const result = tracker.checkBudget('api.example.com', 15000000n);
|
|
22
|
-
expect(result.allowed).toBe(false);
|
|
23
|
-
expect(result.reason).toContain('global per-request max');
|
|
24
|
-
});
|
|
25
|
-
it('rejects payments exceeding service per-request max', () => {
|
|
26
|
-
const result = tracker.checkBudget('api.example.com', 6000000n);
|
|
27
|
-
expect(result.allowed).toBe(false);
|
|
28
|
-
expect(result.reason).toContain('service per-request max');
|
|
29
|
-
});
|
|
30
|
-
it('uses wildcard budget for unknown services', () => {
|
|
31
|
-
const result = tracker.checkBudget('unknown.com', 3000000n);
|
|
32
|
-
expect(result.allowed).toBe(false);
|
|
33
|
-
expect(result.reason).toContain('service per-request max');
|
|
34
|
-
});
|
|
35
|
-
it('tracks daily spending per service', () => {
|
|
36
|
-
const log = {
|
|
37
|
-
timestamp: Math.floor(Date.now() / 1000),
|
|
38
|
-
service: 'api.example.com',
|
|
39
|
-
url: 'https://api.example.com/data',
|
|
40
|
-
amount: 4000000n,
|
|
41
|
-
token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
42
|
-
recipient: '0x1234567890abcdef1234567890abcdef12345678',
|
|
43
|
-
txHash: '0xabc123',
|
|
44
|
-
network: 'base:8453',
|
|
45
|
-
scheme: 'exact',
|
|
46
|
-
success: true,
|
|
47
|
-
};
|
|
48
|
-
tracker.recordPayment(log);
|
|
49
|
-
const summary = tracker.getDailySpendSummary();
|
|
50
|
-
expect(summary.global).toBe(4000000n);
|
|
51
|
-
expect(summary.byService['api.example.com']).toBe(4000000n);
|
|
52
|
-
});
|
|
53
|
-
it('rejects when daily limit would be exceeded', () => {
|
|
54
|
-
// Spend 48 USDC
|
|
55
|
-
for (let i = 0; i < 12; i++) {
|
|
56
|
-
tracker.recordPayment({
|
|
57
|
-
timestamp: Math.floor(Date.now() / 1000),
|
|
58
|
-
service: 'api.example.com',
|
|
59
|
-
url: 'https://api.example.com/data',
|
|
60
|
-
amount: 4000000n,
|
|
61
|
-
token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
62
|
-
recipient: '0x1234567890abcdef1234567890abcdef12345678',
|
|
63
|
-
txHash: '0xabc123',
|
|
64
|
-
network: 'base:8453',
|
|
65
|
-
scheme: 'exact',
|
|
66
|
-
success: true,
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
// Next 4 USDC would exceed 50 USDC service daily limit
|
|
70
|
-
const result = tracker.checkBudget('api.example.com', 4000000n);
|
|
71
|
-
expect(result.allowed).toBe(false);
|
|
72
|
-
expect(result.reason).toContain('daily limit');
|
|
73
|
-
});
|
|
74
|
-
it('returns transaction log with filters', () => {
|
|
75
|
-
const now = Math.floor(Date.now() / 1000);
|
|
76
|
-
tracker.recordPayment({
|
|
77
|
-
timestamp: now - 100,
|
|
78
|
-
service: 'api.example.com',
|
|
79
|
-
url: 'https://api.example.com/a',
|
|
80
|
-
amount: 1000000n,
|
|
81
|
-
token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
82
|
-
recipient: '0x1234567890abcdef1234567890abcdef12345678',
|
|
83
|
-
txHash: '0xaaa',
|
|
84
|
-
network: 'base:8453',
|
|
85
|
-
scheme: 'exact',
|
|
86
|
-
success: true,
|
|
87
|
-
});
|
|
88
|
-
tracker.recordPayment({
|
|
89
|
-
timestamp: now,
|
|
90
|
-
service: 'other.com',
|
|
91
|
-
url: 'https://other.com/b',
|
|
92
|
-
amount: 500000n,
|
|
93
|
-
token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
94
|
-
recipient: '0x1234567890abcdef1234567890abcdef12345678',
|
|
95
|
-
txHash: '0xbbb',
|
|
96
|
-
network: 'base:8453',
|
|
97
|
-
scheme: 'exact',
|
|
98
|
-
success: true,
|
|
99
|
-
});
|
|
100
|
-
expect(tracker.getTransactionLog()).toHaveLength(2);
|
|
101
|
-
expect(tracker.getTransactionLog({ service: 'other.com' })).toHaveLength(1);
|
|
102
|
-
expect(tracker.getTransactionLog({ since: now - 50 })).toHaveLength(1);
|
|
103
|
-
});
|
|
104
|
-
it('allows runtime budget updates', () => {
|
|
105
|
-
tracker.setServiceBudget({
|
|
106
|
-
service: 'new-api.com',
|
|
107
|
-
maxPerRequest: 1000000n,
|
|
108
|
-
dailyLimit: 5000000n,
|
|
109
|
-
});
|
|
110
|
-
expect(tracker.checkBudget('new-api.com', 500000n).allowed).toBe(true);
|
|
111
|
-
expect(tracker.checkBudget('new-api.com', 2000000n).allowed).toBe(false);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
//# sourceMappingURL=budget.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"budget.test.js","sourceRoot":"","sources":["../../../src/x402/__tests__/budget.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.test.d.ts","sourceRoot":"","sources":["../../../src/x402/__tests__/client.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
// [MAX-ADDED] Tests for x402 Client — protocol parsing and payment selection
|
|
2
|
-
import { describe, it, expect } from 'vitest';
|
|
3
|
-
import { X402Client } from '../client.js';
|
|
4
|
-
// Mock wallet (we test protocol logic, not on-chain execution)
|
|
5
|
-
const mockWallet = {};
|
|
6
|
-
describe('X402Client', () => {
|
|
7
|
-
describe('parse402Response', () => {
|
|
8
|
-
it('parses base64 PAYMENT-REQUIRED header', async () => {
|
|
9
|
-
const client = new X402Client(mockWallet, { autoPay: false });
|
|
10
|
-
const paymentRequired = {
|
|
11
|
-
x402Version: 1,
|
|
12
|
-
resource: { url: '/api/data', description: 'Data API', mimeType: 'application/json' },
|
|
13
|
-
accepts: [
|
|
14
|
-
{
|
|
15
|
-
scheme: 'exact',
|
|
16
|
-
network: 'base:8453',
|
|
17
|
-
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
18
|
-
amount: '1000000',
|
|
19
|
-
payTo: '0xRecipient',
|
|
20
|
-
maxTimeoutSeconds: 30,
|
|
21
|
-
extra: {},
|
|
22
|
-
},
|
|
23
|
-
],
|
|
24
|
-
};
|
|
25
|
-
const b64 = btoa(JSON.stringify(paymentRequired));
|
|
26
|
-
const response = new Response(null, {
|
|
27
|
-
status: 402,
|
|
28
|
-
headers: { 'payment-required': b64 },
|
|
29
|
-
});
|
|
30
|
-
const parsed = await client.parse402Response(response);
|
|
31
|
-
expect(parsed).not.toBeNull();
|
|
32
|
-
expect(parsed.x402Version).toBe(1);
|
|
33
|
-
expect(parsed.accepts).toHaveLength(1);
|
|
34
|
-
expect(parsed.accepts[0].scheme).toBe('exact');
|
|
35
|
-
expect(parsed.accepts[0].amount).toBe('1000000');
|
|
36
|
-
});
|
|
37
|
-
it('parses JSON body fallback', async () => {
|
|
38
|
-
const client = new X402Client(mockWallet, { autoPay: false });
|
|
39
|
-
const paymentRequired = {
|
|
40
|
-
x402Version: 1,
|
|
41
|
-
resource: { url: '/api/data', description: 'Data', mimeType: 'application/json' },
|
|
42
|
-
accepts: [
|
|
43
|
-
{
|
|
44
|
-
scheme: 'exact',
|
|
45
|
-
network: 'base:8453',
|
|
46
|
-
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
|
47
|
-
amount: '500000',
|
|
48
|
-
payTo: '0xRecipient',
|
|
49
|
-
maxTimeoutSeconds: 30,
|
|
50
|
-
extra: {},
|
|
51
|
-
},
|
|
52
|
-
],
|
|
53
|
-
};
|
|
54
|
-
const response = new Response(JSON.stringify(paymentRequired), {
|
|
55
|
-
status: 402,
|
|
56
|
-
headers: { 'content-type': 'application/json' },
|
|
57
|
-
});
|
|
58
|
-
const parsed = await client.parse402Response(response);
|
|
59
|
-
expect(parsed).not.toBeNull();
|
|
60
|
-
expect(parsed.accepts[0].amount).toBe('500000');
|
|
61
|
-
});
|
|
62
|
-
it('returns null for unparseable 402', async () => {
|
|
63
|
-
const client = new X402Client(mockWallet, { autoPay: false });
|
|
64
|
-
const response = new Response('Payment Required', { status: 402 });
|
|
65
|
-
const parsed = await client.parse402Response(response);
|
|
66
|
-
expect(parsed).toBeNull();
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
describe('selectPaymentOption', () => {
|
|
70
|
-
it('selects Base USDC exact scheme', () => {
|
|
71
|
-
const client = new X402Client(mockWallet);
|
|
72
|
-
const accepts = [
|
|
73
|
-
{ scheme: 'exact', network: 'ethereum:1', asset: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', amount: '1000000', payTo: '0x1', maxTimeoutSeconds: 30, extra: {} },
|
|
74
|
-
{ scheme: 'exact', network: 'base:8453', asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', amount: '1000000', payTo: '0x1', maxTimeoutSeconds: 30, extra: {} },
|
|
75
|
-
];
|
|
76
|
-
const selected = client.selectPaymentOption(accepts);
|
|
77
|
-
expect(selected).not.toBeNull();
|
|
78
|
-
expect(selected.network).toBe('base:8453');
|
|
79
|
-
});
|
|
80
|
-
it('prefers lowest amount among compatible options', () => {
|
|
81
|
-
const client = new X402Client(mockWallet);
|
|
82
|
-
const accepts = [
|
|
83
|
-
{ scheme: 'exact', network: 'base:8453', asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', amount: '5000000', payTo: '0x1', maxTimeoutSeconds: 30, extra: {} },
|
|
84
|
-
{ scheme: 'exact', network: 'base:8453', asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', amount: '1000000', payTo: '0x1', maxTimeoutSeconds: 30, extra: {} },
|
|
85
|
-
];
|
|
86
|
-
const selected = client.selectPaymentOption(accepts);
|
|
87
|
-
expect(selected.amount).toBe('1000000');
|
|
88
|
-
});
|
|
89
|
-
it('returns null when no compatible option exists', () => {
|
|
90
|
-
const client = new X402Client(mockWallet);
|
|
91
|
-
const accepts = [
|
|
92
|
-
{ scheme: 'exact', network: 'solana:mainnet', asset: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', amount: '1000000', payTo: 'sol_addr', maxTimeoutSeconds: 30, extra: {} },
|
|
93
|
-
];
|
|
94
|
-
expect(client.selectPaymentOption(accepts)).toBeNull();
|
|
95
|
-
});
|
|
96
|
-
it('prefers exact scheme over others', () => {
|
|
97
|
-
const client = new X402Client(mockWallet);
|
|
98
|
-
const accepts = [
|
|
99
|
-
{ scheme: 'upto', network: 'base:8453', asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', amount: '500000', payTo: '0x1', maxTimeoutSeconds: 30, extra: {} },
|
|
100
|
-
{ scheme: 'exact', network: 'base:8453', asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', amount: '1000000', payTo: '0x1', maxTimeoutSeconds: 30, extra: {} },
|
|
101
|
-
];
|
|
102
|
-
const selected = client.selectPaymentOption(accepts);
|
|
103
|
-
expect(selected.scheme).toBe('exact');
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
//# sourceMappingURL=client.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.test.js","sourceRoot":"","sources":["../../../src/x402/__tests__/client.test.ts"],"names":[],"mappings":"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"}
|