agentwallet-sdk 5.0.2 → 5.0.3
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 +37 -1
- package/dist/verifiable-intent/index.d.ts +84 -0
- package/dist/verifiable-intent/index.js +385 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -204,9 +204,45 @@ await escrow.verify(escrowId);
|
|
|
204
204
|
|
|
205
205
|
Premium access: [github.com/up2itnow/AgentNexus2](https://github.com/up2itnow/AgentNexus2)
|
|
206
206
|
|
|
207
|
+
## x402 Protocol: Supported Chains and Payment Rails
|
|
208
|
+
|
|
209
|
+
x402 (HTTP 402 Payment Required) is the native payment protocol for agent-to-service transactions. The agent encounters a 402 response, signs a payment proof, and re-sends the request. One round trip. No accounts, no API keys, no invoices.
|
|
210
|
+
|
|
211
|
+
As of March 2026, x402 is live on 3 chains/rails:
|
|
212
|
+
|
|
213
|
+
| Chain / Rail | Status | Settlement Token | Gas Cost | Notes |
|
|
214
|
+
|---|---|---|---|---|
|
|
215
|
+
| **Base** (Coinbase L2) | Live | USDC | Sub-cent | Primary x402 chain. 15M+ transactions in Jan 2026. |
|
|
216
|
+
| **Etherlink** (Tezos L2) | Live (Mar 2026) | USDC | Sub-cent | EVM-compatible. Same x402 integration, different RPC + chain ID. |
|
|
217
|
+
| **Stripe** (Fiat offramp) | Live (Feb 2026) | USDC -> USD | N/A | Vendors receive USD in Stripe dashboard. Agents pay USDC. |
|
|
218
|
+
|
|
219
|
+
### x402 + Etherlink Quick Start
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import { createWallet, agentExecute } from 'agentwallet-sdk';
|
|
223
|
+
|
|
224
|
+
const wallet = createWallet({
|
|
225
|
+
accountAddress: '0xYourAgent',
|
|
226
|
+
chain: 'etherlink', // new: Tezos L2 support
|
|
227
|
+
walletClient,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
// x402 payment flow is identical across chains
|
|
231
|
+
const response = await fetch('https://api.vendor.com/data');
|
|
232
|
+
if (response.status === 402) {
|
|
233
|
+
const details = await response.json();
|
|
234
|
+
const proof = await wallet.createX402Proof(details);
|
|
235
|
+
const paid = await fetch('https://api.vendor.com/data', {
|
|
236
|
+
headers: { 'X-Payment': proof }
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
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.
|
|
242
|
+
|
|
207
243
|
## Supported Chains
|
|
208
244
|
|
|
209
|
-
Mainnet: Ethereum, Base, Arbitrum, Polygon, Optimism, Avalanche, BSC, Celo, Gnosis, Linea, Mantle, Scroll, and more.
|
|
245
|
+
Mainnet: Ethereum, Base, Arbitrum, Polygon, Optimism, Avalanche, BSC, Celo, Gnosis, Linea, Mantle, Scroll, Etherlink, and more.
|
|
210
246
|
|
|
211
247
|
Testnet: Base Sepolia, Arbitrum Sepolia, and corresponding testnets.
|
|
212
248
|
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mastercard Verifiable Intent module for agentwallet-sdk.
|
|
3
|
+
* @module verifiable-intent
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface AgentIdentity {
|
|
7
|
+
agentId: string;
|
|
8
|
+
principalId: string;
|
|
9
|
+
agenticToken: string;
|
|
10
|
+
issuedAt: number;
|
|
11
|
+
expiresAt: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ScopeConstraints {
|
|
15
|
+
maxAmountPerTx: number;
|
|
16
|
+
maxAmountPerDay: number;
|
|
17
|
+
maxTxPerDay: number;
|
|
18
|
+
allowedMerchantCategories?: string[];
|
|
19
|
+
allowedCurrencies?: string[];
|
|
20
|
+
windowStartUtc?: number;
|
|
21
|
+
windowEndUtc?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface IntentDeclaration {
|
|
25
|
+
intentId: string;
|
|
26
|
+
agentId: string;
|
|
27
|
+
action: 'pay' | 'subscribe' | 'escrow' | 'refund';
|
|
28
|
+
amount: number;
|
|
29
|
+
currency: string;
|
|
30
|
+
recipientId: string;
|
|
31
|
+
description: string;
|
|
32
|
+
createdAt: number;
|
|
33
|
+
expiresAt: number;
|
|
34
|
+
metadata?: Record<string, unknown>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface SignedIntent {
|
|
38
|
+
intent: IntentDeclaration;
|
|
39
|
+
signature: string;
|
|
40
|
+
agenticToken: string;
|
|
41
|
+
signatureAlgorithm: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface VerificationResult {
|
|
45
|
+
valid: boolean;
|
|
46
|
+
errors: string[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface VerifiableIntentConfig {
|
|
50
|
+
agentId: string;
|
|
51
|
+
principalId: string;
|
|
52
|
+
signingSecret: string;
|
|
53
|
+
scope: ScopeConstraints;
|
|
54
|
+
tokenTtlSeconds?: number;
|
|
55
|
+
intentTtlSeconds?: number;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export declare class VerifiableIntentClient {
|
|
59
|
+
identity: AgentIdentity;
|
|
60
|
+
constructor(config: VerifiableIntentConfig);
|
|
61
|
+
createIntent(params: {
|
|
62
|
+
action: 'pay' | 'subscribe' | 'escrow' | 'refund';
|
|
63
|
+
amount: number;
|
|
64
|
+
currency: string;
|
|
65
|
+
recipientId: string;
|
|
66
|
+
description: string;
|
|
67
|
+
metadata?: Record<string, unknown>;
|
|
68
|
+
}): SignedIntent;
|
|
69
|
+
verify(signedIntent: SignedIntent): VerificationResult;
|
|
70
|
+
recordExecution(signedIntent: SignedIntent): void;
|
|
71
|
+
getDailyUsage(): {
|
|
72
|
+
spentToday: number;
|
|
73
|
+
txToday: number;
|
|
74
|
+
remainingBudget: number;
|
|
75
|
+
remainingTx: number;
|
|
76
|
+
};
|
|
77
|
+
static serialize(signedIntent: SignedIntent): string;
|
|
78
|
+
static deserialize(json: string): SignedIntent;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export declare class VerifiableIntentError extends Error {
|
|
82
|
+
context?: unknown;
|
|
83
|
+
constructor(message: string, context?: unknown);
|
|
84
|
+
}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VerifiableIntent — Mastercard Verifiable Intent implementation for agentwallet-sdk
|
|
3
|
+
*
|
|
4
|
+
* Implements the Mastercard Verifiable Intent open standard (March 2026):
|
|
5
|
+
* - Create signed intent declarations for agent transactions
|
|
6
|
+
* - Verify intent signatures and scope constraints
|
|
7
|
+
* - Enforce spending caps, time windows, and merchant category limits
|
|
8
|
+
* - Compatible with Google AP2 (Agent Payments Protocol)
|
|
9
|
+
*
|
|
10
|
+
* The spec defines four pillars:
|
|
11
|
+
* 1. Agent Identity — unique Agentic Token per agent
|
|
12
|
+
* 2. Intent Declaration — structured payload describing the transaction
|
|
13
|
+
* 3. Authorization Chain — proof of human/system delegation
|
|
14
|
+
* 4. Scope Limits — spending caps, time windows, merchant categories
|
|
15
|
+
*
|
|
16
|
+
* @module verifiable-intent
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { createHash, createHmac, randomUUID } from 'crypto';
|
|
20
|
+
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Types
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @typedef {Object} AgentIdentity
|
|
27
|
+
* @property {string} agentId - Unique agent identifier (UUID or DID)
|
|
28
|
+
* @property {string} principalId - Human/system that delegated authority
|
|
29
|
+
* @property {string} agenticToken - Signed token proving agent registration
|
|
30
|
+
* @property {number} issuedAt - Unix timestamp of token issuance
|
|
31
|
+
* @property {number} expiresAt - Unix timestamp of token expiry
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @typedef {Object} ScopeConstraints
|
|
36
|
+
* @property {number} maxAmountPerTx - Maximum amount per single transaction (in minor units)
|
|
37
|
+
* @property {number} maxAmountPerDay - Maximum cumulative daily spend (in minor units)
|
|
38
|
+
* @property {number} maxTxPerDay - Maximum number of transactions per day
|
|
39
|
+
* @property {string[]} [allowedMerchantCategories] - MCC codes the agent can transact with
|
|
40
|
+
* @property {string[]} [allowedCurrencies] - ISO 4217 currency codes permitted
|
|
41
|
+
* @property {number} [windowStartUtc] - Unix timestamp: scope validity start
|
|
42
|
+
* @property {number} [windowEndUtc] - Unix timestamp: scope validity end
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @typedef {Object} IntentDeclaration
|
|
47
|
+
* @property {string} intentId - Unique ID for this intent (UUID v4)
|
|
48
|
+
* @property {string} agentId - Agent making the request
|
|
49
|
+
* @property {string} action - What the agent wants to do ('pay', 'subscribe', 'escrow', 'refund')
|
|
50
|
+
* @property {number} amount - Transaction amount in minor units
|
|
51
|
+
* @property {string} currency - ISO 4217 currency code
|
|
52
|
+
* @property {string} recipientId - Merchant/service/agent receiving payment
|
|
53
|
+
* @property {string} description - Human-readable purpose
|
|
54
|
+
* @property {number} createdAt - Unix timestamp
|
|
55
|
+
* @property {number} expiresAt - Unix timestamp when intent becomes invalid
|
|
56
|
+
* @property {Object} [metadata] - Additional key-value pairs
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @typedef {Object} SignedIntent
|
|
61
|
+
* @property {IntentDeclaration} intent - The intent payload
|
|
62
|
+
* @property {string} signature - HMAC-SHA256 signature of the canonical intent
|
|
63
|
+
* @property {string} agenticToken - The agent's identity token
|
|
64
|
+
* @property {string} signatureAlgorithm - Always 'HMAC-SHA256' in this implementation
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @typedef {Object} VerificationResult
|
|
69
|
+
* @property {boolean} valid - Whether the intent passes all checks
|
|
70
|
+
* @property {string[]} errors - List of validation failures (empty if valid)
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Core Implementation
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* VerifiableIntentClient — Create, sign, and verify Mastercard Verifiable Intent payloads.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* const vi = new VerifiableIntentClient({
|
|
83
|
+
* agentId: 'agent-001',
|
|
84
|
+
* principalId: 'user-bill',
|
|
85
|
+
* signingSecret: process.env.AGENT_SIGNING_SECRET,
|
|
86
|
+
* scope: {
|
|
87
|
+
* maxAmountPerTx: 10000, // $100.00
|
|
88
|
+
* maxAmountPerDay: 50000, // $500.00
|
|
89
|
+
* maxTxPerDay: 20,
|
|
90
|
+
* allowedCurrencies: ['USD', 'EUR'],
|
|
91
|
+
* }
|
|
92
|
+
* });
|
|
93
|
+
*
|
|
94
|
+
* const signed = vi.createIntent({
|
|
95
|
+
* action: 'pay',
|
|
96
|
+
* amount: 5000,
|
|
97
|
+
* currency: 'USD',
|
|
98
|
+
* recipientId: 'merchant-xyz',
|
|
99
|
+
* description: 'API compute credits',
|
|
100
|
+
* });
|
|
101
|
+
*
|
|
102
|
+
* const result = vi.verify(signed);
|
|
103
|
+
* // { valid: true, errors: [] }
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export class VerifiableIntentClient {
|
|
107
|
+
/**
|
|
108
|
+
* @param {Object} config
|
|
109
|
+
* @param {string} config.agentId - Unique agent identifier
|
|
110
|
+
* @param {string} config.principalId - Human/system principal who delegated authority
|
|
111
|
+
* @param {string} config.signingSecret - Secret key for HMAC signing (min 32 chars)
|
|
112
|
+
* @param {ScopeConstraints} config.scope - Spending and authorization constraints
|
|
113
|
+
* @param {number} [config.tokenTtlSeconds=86400] - Agentic token lifetime (default 24h)
|
|
114
|
+
* @param {number} [config.intentTtlSeconds=300] - Intent validity window (default 5 min)
|
|
115
|
+
*/
|
|
116
|
+
constructor(config) {
|
|
117
|
+
if (!config.signingSecret || config.signingSecret.length < 32) {
|
|
118
|
+
throw new VerifiableIntentError('signingSecret must be at least 32 characters');
|
|
119
|
+
}
|
|
120
|
+
this.agentId = config.agentId;
|
|
121
|
+
this.principalId = config.principalId;
|
|
122
|
+
this.signingSecret = config.signingSecret;
|
|
123
|
+
this.scope = config.scope;
|
|
124
|
+
this.tokenTtlSeconds = config.tokenTtlSeconds ?? 86400;
|
|
125
|
+
this.intentTtlSeconds = config.intentTtlSeconds ?? 300;
|
|
126
|
+
|
|
127
|
+
// Daily tracking for scope enforcement
|
|
128
|
+
this._dailySpend = 0;
|
|
129
|
+
this._dailyTxCount = 0;
|
|
130
|
+
this._dailyResetDate = this._todayUtc();
|
|
131
|
+
|
|
132
|
+
// Generate agentic token on initialization
|
|
133
|
+
this.identity = this._issueAgenticToken();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Create and sign a Verifiable Intent declaration.
|
|
138
|
+
*
|
|
139
|
+
* @param {Object} params
|
|
140
|
+
* @param {string} params.action - 'pay' | 'subscribe' | 'escrow' | 'refund'
|
|
141
|
+
* @param {number} params.amount - Amount in minor units (cents)
|
|
142
|
+
* @param {string} params.currency - ISO 4217 currency code
|
|
143
|
+
* @param {string} params.recipientId - Recipient identifier
|
|
144
|
+
* @param {string} params.description - Human-readable purpose
|
|
145
|
+
* @param {Object} [params.metadata] - Additional context
|
|
146
|
+
* @returns {SignedIntent}
|
|
147
|
+
*/
|
|
148
|
+
createIntent(params) {
|
|
149
|
+
const now = Math.floor(Date.now() / 1000);
|
|
150
|
+
|
|
151
|
+
// Check token validity
|
|
152
|
+
if (now >= this.identity.expiresAt) {
|
|
153
|
+
this.identity = this._issueAgenticToken();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const intent = {
|
|
157
|
+
intentId: randomUUID(),
|
|
158
|
+
agentId: this.agentId,
|
|
159
|
+
action: params.action,
|
|
160
|
+
amount: params.amount,
|
|
161
|
+
currency: params.currency,
|
|
162
|
+
recipientId: params.recipientId,
|
|
163
|
+
description: params.description,
|
|
164
|
+
createdAt: now,
|
|
165
|
+
expiresAt: now + this.intentTtlSeconds,
|
|
166
|
+
metadata: params.metadata ?? {},
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// Pre-sign scope validation
|
|
170
|
+
const scopeCheck = this._checkScope(intent);
|
|
171
|
+
if (!scopeCheck.valid) {
|
|
172
|
+
throw new VerifiableIntentError(
|
|
173
|
+
`Intent blocked by scope constraints: ${scopeCheck.errors.join(', ')}`
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const canonical = this._canonicalize(intent);
|
|
178
|
+
const signature = this._sign(canonical);
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
intent,
|
|
182
|
+
signature,
|
|
183
|
+
agenticToken: this.identity.agenticToken,
|
|
184
|
+
signatureAlgorithm: 'HMAC-SHA256',
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Verify a signed intent declaration.
|
|
190
|
+
*
|
|
191
|
+
* Checks:
|
|
192
|
+
* 1. Signature validity (HMAC-SHA256)
|
|
193
|
+
* 2. Intent not expired
|
|
194
|
+
* 3. Agent identity matches
|
|
195
|
+
* 4. Scope constraints satisfied
|
|
196
|
+
*
|
|
197
|
+
* @param {SignedIntent} signedIntent
|
|
198
|
+
* @returns {VerificationResult}
|
|
199
|
+
*/
|
|
200
|
+
verify(signedIntent) {
|
|
201
|
+
const errors = [];
|
|
202
|
+
const { intent, signature, agenticToken } = signedIntent;
|
|
203
|
+
const now = Math.floor(Date.now() / 1000);
|
|
204
|
+
|
|
205
|
+
// 1. Signature check
|
|
206
|
+
const canonical = this._canonicalize(intent);
|
|
207
|
+
const expectedSig = this._sign(canonical);
|
|
208
|
+
if (signature !== expectedSig) {
|
|
209
|
+
errors.push('Invalid signature');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// 2. Expiry check
|
|
213
|
+
if (now >= intent.expiresAt) {
|
|
214
|
+
errors.push(`Intent expired at ${new Date(intent.expiresAt * 1000).toISOString()}`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// 3. Agent identity check
|
|
218
|
+
if (intent.agentId !== this.agentId) {
|
|
219
|
+
errors.push(`Agent ID mismatch: expected ${this.agentId}, got ${intent.agentId}`);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// 4. Agentic token check
|
|
223
|
+
if (agenticToken !== this.identity.agenticToken) {
|
|
224
|
+
errors.push('Agentic token mismatch or expired');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// 5. Scope constraints
|
|
228
|
+
const scopeResult = this._checkScope(intent);
|
|
229
|
+
errors.push(...scopeResult.errors);
|
|
230
|
+
|
|
231
|
+
return { valid: errors.length === 0, errors };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Record a completed transaction against daily limits.
|
|
236
|
+
* Call this after a verified intent is successfully executed.
|
|
237
|
+
*
|
|
238
|
+
* @param {SignedIntent} signedIntent - The executed intent
|
|
239
|
+
*/
|
|
240
|
+
recordExecution(signedIntent) {
|
|
241
|
+
this._resetDailyIfNeeded();
|
|
242
|
+
this._dailySpend += signedIntent.intent.amount;
|
|
243
|
+
this._dailyTxCount += 1;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Get current daily usage against scope limits.
|
|
248
|
+
*
|
|
249
|
+
* @returns {{ spentToday: number, txToday: number, remainingBudget: number, remainingTx: number }}
|
|
250
|
+
*/
|
|
251
|
+
getDailyUsage() {
|
|
252
|
+
this._resetDailyIfNeeded();
|
|
253
|
+
return {
|
|
254
|
+
spentToday: this._dailySpend,
|
|
255
|
+
txToday: this._dailyTxCount,
|
|
256
|
+
remainingBudget: Math.max(0, this.scope.maxAmountPerDay - this._dailySpend),
|
|
257
|
+
remainingTx: Math.max(0, this.scope.maxTxPerDay - this._dailyTxCount),
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Serialize a signed intent to a portable JSON string for transmission.
|
|
263
|
+
*
|
|
264
|
+
* @param {SignedIntent} signedIntent
|
|
265
|
+
* @returns {string} JSON string
|
|
266
|
+
*/
|
|
267
|
+
static serialize(signedIntent) {
|
|
268
|
+
return JSON.stringify(signedIntent);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Deserialize a JSON string back to a SignedIntent object.
|
|
273
|
+
*
|
|
274
|
+
* @param {string} json
|
|
275
|
+
* @returns {SignedIntent}
|
|
276
|
+
*/
|
|
277
|
+
static deserialize(json) {
|
|
278
|
+
const parsed = JSON.parse(json);
|
|
279
|
+
if (!parsed.intent || !parsed.signature || !parsed.agenticToken) {
|
|
280
|
+
throw new VerifiableIntentError('Invalid SignedIntent structure');
|
|
281
|
+
}
|
|
282
|
+
return parsed;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// -------------------------------------------------------------------------
|
|
286
|
+
// Private methods
|
|
287
|
+
// -------------------------------------------------------------------------
|
|
288
|
+
|
|
289
|
+
_issueAgenticToken() {
|
|
290
|
+
const now = Math.floor(Date.now() / 1000);
|
|
291
|
+
const payload = `${this.agentId}:${this.principalId}:${now}`;
|
|
292
|
+
const token = createHmac('sha256', this.signingSecret)
|
|
293
|
+
.update(payload)
|
|
294
|
+
.digest('hex');
|
|
295
|
+
return {
|
|
296
|
+
agentId: this.agentId,
|
|
297
|
+
principalId: this.principalId,
|
|
298
|
+
agenticToken: token,
|
|
299
|
+
issuedAt: now,
|
|
300
|
+
expiresAt: now + this.tokenTtlSeconds,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
_canonicalize(intent) {
|
|
305
|
+
// Deterministic JSON serialization: sorted keys, no whitespace
|
|
306
|
+
const ordered = {
|
|
307
|
+
action: intent.action,
|
|
308
|
+
agentId: intent.agentId,
|
|
309
|
+
amount: intent.amount,
|
|
310
|
+
createdAt: intent.createdAt,
|
|
311
|
+
currency: intent.currency,
|
|
312
|
+
description: intent.description,
|
|
313
|
+
expiresAt: intent.expiresAt,
|
|
314
|
+
intentId: intent.intentId,
|
|
315
|
+
metadata: intent.metadata,
|
|
316
|
+
recipientId: intent.recipientId,
|
|
317
|
+
};
|
|
318
|
+
return JSON.stringify(ordered);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
_sign(canonical) {
|
|
322
|
+
return createHmac('sha256', this.signingSecret)
|
|
323
|
+
.update(canonical)
|
|
324
|
+
.digest('hex');
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
_checkScope(intent) {
|
|
328
|
+
const errors = [];
|
|
329
|
+
this._resetDailyIfNeeded();
|
|
330
|
+
|
|
331
|
+
if (intent.amount > this.scope.maxAmountPerTx) {
|
|
332
|
+
errors.push(`Amount ${intent.amount} exceeds per-tx limit ${this.scope.maxAmountPerTx}`);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (this._dailySpend + intent.amount > this.scope.maxAmountPerDay) {
|
|
336
|
+
errors.push(
|
|
337
|
+
`Daily spend would be ${this._dailySpend + intent.amount}, exceeds limit ${this.scope.maxAmountPerDay}`
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (this._dailyTxCount + 1 > this.scope.maxTxPerDay) {
|
|
342
|
+
errors.push(`Daily tx count would exceed limit ${this.scope.maxTxPerDay}`);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (this.scope.allowedCurrencies && !this.scope.allowedCurrencies.includes(intent.currency)) {
|
|
346
|
+
errors.push(`Currency ${intent.currency} not in allowed list: ${this.scope.allowedCurrencies.join(', ')}`);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const now = Math.floor(Date.now() / 1000);
|
|
350
|
+
if (this.scope.windowStartUtc && now < this.scope.windowStartUtc) {
|
|
351
|
+
errors.push('Current time is before scope validity window');
|
|
352
|
+
}
|
|
353
|
+
if (this.scope.windowEndUtc && now >= this.scope.windowEndUtc) {
|
|
354
|
+
errors.push('Current time is past scope validity window');
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return { valid: errors.length === 0, errors };
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
_todayUtc() {
|
|
361
|
+
return new Date().toISOString().slice(0, 10);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
_resetDailyIfNeeded() {
|
|
365
|
+
const today = this._todayUtc();
|
|
366
|
+
if (today !== this._dailyResetDate) {
|
|
367
|
+
this._dailySpend = 0;
|
|
368
|
+
this._dailyTxCount = 0;
|
|
369
|
+
this._dailyResetDate = today;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// ---------------------------------------------------------------------------
|
|
375
|
+
// Error class
|
|
376
|
+
// ---------------------------------------------------------------------------
|
|
377
|
+
|
|
378
|
+
export class VerifiableIntentError extends Error {
|
|
379
|
+
constructor(message, context) {
|
|
380
|
+
super(message);
|
|
381
|
+
this.context = context;
|
|
382
|
+
this.name = 'VerifiableIntentError';
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentwallet-sdk",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.3",
|
|
4
4
|
"description": "Non-custodial AI agent wallet SDK. ERC-8004 identity & reputation registries, mutual stake escrow, x402 payments, 17-chain CCTP bridging, ERC-6551 TBA, SpendingPolicy guardrails, Uniswap V3 swap. The agent holds the keys.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -48,4 +48,4 @@
|
|
|
48
48
|
"typescript": "5.3.3",
|
|
49
49
|
"vitest": "4.0.18"
|
|
50
50
|
}
|
|
51
|
-
}
|
|
51
|
+
}
|