@metamask/smart-accounts-kit 1.5.0 → 1.6.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.
Files changed (90) hide show
  1. package/CHANGELOG.md +47 -25
  2. package/dist/actions/index.cjs +5 -6
  3. package/dist/actions/index.cjs.map +1 -1
  4. package/dist/actions/index.d.cts +3 -3
  5. package/dist/actions/index.d.ts +3 -3
  6. package/dist/actions/index.mjs +4 -5
  7. package/dist/{caveats-DQ6HoAHe.d.ts → caveats-B2OssjV4.d.ts} +1 -2
  8. package/dist/{caveats-CaSt_VHs.d.cts → caveats-gqMBZKkI.d.cts} +1 -2
  9. package/dist/{chunk-SOFB2MXG.cjs → chunk-2OS36DVV.cjs} +8 -1
  10. package/dist/chunk-2OS36DVV.cjs.map +1 -0
  11. package/dist/{chunk-XEOE25DE.cjs → chunk-2ZOWIAP3.cjs} +98 -68
  12. package/dist/chunk-2ZOWIAP3.cjs.map +1 -0
  13. package/dist/{chunk-BGOSYTKV.mjs → chunk-AZYTTGON.mjs} +38 -8
  14. package/dist/chunk-AZYTTGON.mjs.map +1 -0
  15. package/dist/{chunk-SCS3CFRE.cjs → chunk-DCI2AN4N.cjs} +15 -17
  16. package/dist/chunk-DCI2AN4N.cjs.map +1 -0
  17. package/dist/{chunk-DN4O5VOP.cjs → chunk-EPU4O7FY.cjs} +158 -151
  18. package/dist/chunk-EPU4O7FY.cjs.map +1 -0
  19. package/dist/{chunk-QCULIK3O.mjs → chunk-GMGJRC3D.mjs} +8 -1
  20. package/dist/chunk-GMGJRC3D.mjs.map +1 -0
  21. package/dist/chunk-IMO6XNDJ.mjs +14 -0
  22. package/dist/chunk-IMO6XNDJ.mjs.map +1 -0
  23. package/dist/chunk-IQT6XFDT.cjs +14 -0
  24. package/dist/chunk-IQT6XFDT.cjs.map +1 -0
  25. package/dist/{chunk-FH6HZCHI.cjs → chunk-JKVSTPEC.cjs} +200 -18
  26. package/dist/chunk-JKVSTPEC.cjs.map +1 -0
  27. package/dist/{chunk-N66VAWMO.mjs → chunk-K7GTZGKJ.mjs} +2 -2
  28. package/dist/{chunk-TBHT26BV.mjs → chunk-L3EZCIY6.mjs} +67 -60
  29. package/dist/chunk-L3EZCIY6.mjs.map +1 -0
  30. package/dist/{chunk-7FYDQNJ3.cjs → chunk-PQPAEHJZ.cjs} +12 -12
  31. package/dist/{chunk-7FYDQNJ3.cjs.map → chunk-PQPAEHJZ.cjs.map} +1 -1
  32. package/dist/{chunk-MV2KHN75.mjs → chunk-TNGQTVSY.mjs} +163 -35
  33. package/dist/chunk-TNGQTVSY.mjs.map +1 -0
  34. package/dist/{chunk-YXHUT56Z.mjs → chunk-UJQ3JN3U.mjs} +4 -6
  35. package/dist/{chunk-YXHUT56Z.mjs.map → chunk-UJQ3JN3U.mjs.map} +1 -1
  36. package/dist/{chunk-IBZSNB7D.cjs → chunk-W6HPAK4M.cjs} +202 -74
  37. package/dist/chunk-W6HPAK4M.cjs.map +1 -0
  38. package/dist/{chunk-W7O2UQL5.mjs → chunk-YVU66KSH.mjs} +188 -6
  39. package/dist/chunk-YVU66KSH.mjs.map +1 -0
  40. package/dist/contracts/index.cjs +5 -6
  41. package/dist/contracts/index.cjs.map +1 -1
  42. package/dist/contracts/index.d.cts +4 -4
  43. package/dist/contracts/index.d.ts +4 -4
  44. package/dist/contracts/index.mjs +4 -5
  45. package/dist/{delegation-DbPGWKfP.d.ts → decodeRevertReason-CmmCpmZ_.d.cts} +11 -3
  46. package/dist/{delegation-BKkEyxZY.d.cts → decodeRevertReason-dOTpJx2h.d.ts} +11 -3
  47. package/dist/experimental/index.cjs +364 -9
  48. package/dist/experimental/index.cjs.map +1 -1
  49. package/dist/experimental/index.d.cts +39 -3
  50. package/dist/experimental/index.d.ts +39 -3
  51. package/dist/experimental/index.mjs +357 -2
  52. package/dist/experimental/index.mjs.map +1 -1
  53. package/dist/index-B1Cmezvh.d.cts +61 -0
  54. package/dist/{index-DXdlz7t4.d.ts → index-BkgdU4LI.d.ts} +99 -93
  55. package/dist/{index-G78z6nwi.d.ts → index-DUJmm8Wz.d.ts} +13 -5
  56. package/dist/{index-yU3olCJV.d.cts → index-Dv4jPzhe.d.cts} +99 -93
  57. package/dist/index-LqiEgBjV.d.ts +61 -0
  58. package/dist/{index-DfDAuvr5.d.cts → index-X7Qn3JTg.d.cts} +13 -5
  59. package/dist/index.cjs +22 -24
  60. package/dist/index.cjs.map +1 -1
  61. package/dist/index.d.cts +8 -8
  62. package/dist/index.d.ts +8 -8
  63. package/dist/index.mjs +9 -11
  64. package/dist/index.mjs.map +1 -1
  65. package/dist/{resolveCaveats-DiqGB-T5.d.cts → resolveCaveats-A9xC29l8.d.cts} +160 -62
  66. package/dist/{resolveCaveats-s2snaFEo.d.ts → resolveCaveats-A9xC29l8.d.ts} +160 -62
  67. package/dist/utils/index.cjs +13 -6
  68. package/dist/utils/index.cjs.map +1 -1
  69. package/dist/utils/index.d.cts +8 -5
  70. package/dist/utils/index.d.ts +8 -5
  71. package/dist/utils/index.mjs +16 -9
  72. package/package.json +7 -6
  73. package/dist/chunk-4QXIOE7F.mjs +0 -79
  74. package/dist/chunk-4QXIOE7F.mjs.map +0 -1
  75. package/dist/chunk-BGOSYTKV.mjs.map +0 -1
  76. package/dist/chunk-DN4O5VOP.cjs.map +0 -1
  77. package/dist/chunk-FH6HZCHI.cjs.map +0 -1
  78. package/dist/chunk-IBZSNB7D.cjs.map +0 -1
  79. package/dist/chunk-MOHCTPYQ.cjs +0 -79
  80. package/dist/chunk-MOHCTPYQ.cjs.map +0 -1
  81. package/dist/chunk-MV2KHN75.mjs.map +0 -1
  82. package/dist/chunk-QCULIK3O.mjs.map +0 -1
  83. package/dist/chunk-SCS3CFRE.cjs.map +0 -1
  84. package/dist/chunk-SOFB2MXG.cjs.map +0 -1
  85. package/dist/chunk-TBHT26BV.mjs.map +0 -1
  86. package/dist/chunk-W7O2UQL5.mjs.map +0 -1
  87. package/dist/chunk-XEOE25DE.cjs.map +0 -1
  88. package/dist/types-BWaH4KH1.d.cts +0 -155
  89. package/dist/types-BWaH4KH1.d.ts +0 -155
  90. /package/dist/{chunk-N66VAWMO.mjs.map → chunk-K7GTZGKJ.mjs.map} +0 -0
@@ -1,7 +1,20 @@
1
1
  import {
2
+ generateSalt
3
+ } from "../chunk-IMO6XNDJ.mjs";
4
+ import "../chunk-UJQ3JN3U.mjs";
5
+ import {
6
+ getSmartAccountsEnvironment
7
+ } from "../chunk-GMGJRC3D.mjs";
8
+ import "../chunk-YVU66KSH.mjs";
9
+ import {
10
+ createOpenDelegation,
11
+ decodeDelegations,
12
+ encodeDelegations,
2
13
  hashDelegation,
14
+ prepareSignDelegationTypedData,
15
+ resolveCaveats,
3
16
  trackSmartAccountsKitFunctionCall
4
- } from "../chunk-MV2KHN75.mjs";
17
+ } from "../chunk-TNGQTVSY.mjs";
5
18
 
6
19
  // src/experimental/delegationStorage.ts
7
20
  import { toHex } from "viem";
@@ -168,8 +181,350 @@ var DelegationStorageClient = class {
168
181
  return responseData.delegationHash;
169
182
  }
170
183
  };
184
+
185
+ // src/experimental/x402DelegationProviderUtils.ts
186
+ import {
187
+ createAllowedCalldataTerms,
188
+ createRedeemerTerms,
189
+ createTimestampTerms,
190
+ decodeRedeemerTerms,
191
+ decodeTimestampTerms
192
+ } from "@metamask/delegation-core";
193
+ import { parseCaipChainId } from "@metamask/utils";
194
+ import { pad } from "viem";
195
+ async function resolveMaybeDeferred(maybeDeferred, requirements) {
196
+ if (typeof maybeDeferred === "function") {
197
+ const deferred = maybeDeferred;
198
+ return await deferred(requirements);
199
+ }
200
+ return maybeDeferred;
201
+ }
202
+ function parseEip155ChainId(network) {
203
+ const { namespace, reference } = parseCaipChainId(
204
+ network
205
+ );
206
+ if (namespace !== "eip155") {
207
+ throw new Error("Unsupported chain namespace");
208
+ }
209
+ const parsedChainId = Number(reference);
210
+ if (isNaN(parsedChainId)) {
211
+ throw new Error("Invalid chain id");
212
+ }
213
+ return parsedChainId;
214
+ }
215
+ var TRANSFER_PAYEE_INDEX = 4;
216
+ var normalizeAddress = (address) => address.toLowerCase();
217
+ var hasMatchingCaveats = (caveats, delegations, match) => {
218
+ for (const caveat of caveats) {
219
+ if (match(caveat)) {
220
+ return true;
221
+ }
222
+ }
223
+ for (const delegation of delegations) {
224
+ for (const caveat of delegation.caveats) {
225
+ if (match(caveat)) {
226
+ return true;
227
+ }
228
+ }
229
+ }
230
+ return false;
231
+ };
232
+ var ensureExpirySufficientlyConstrained = ({
233
+ timestampEnforcer,
234
+ caveats,
235
+ existingDelegations,
236
+ expirySeconds
237
+ }) => {
238
+ if (expirySeconds < 0) {
239
+ throw new Error("Expiry seconds must be a positive number");
240
+ }
241
+ const beforeThreshold = Math.floor(Date.now() / 1e3) + expirySeconds;
242
+ const timestampEnforcerNormalized = normalizeAddress(timestampEnforcer);
243
+ const hasSupersedingTimestampConstraint = hasMatchingCaveats(
244
+ caveats,
245
+ existingDelegations,
246
+ (caveat) => {
247
+ if (normalizeAddress(caveat.enforcer) !== timestampEnforcerNormalized) {
248
+ return false;
249
+ }
250
+ const { beforeThreshold: existingBeforeThreshold } = decodeTimestampTerms(
251
+ caveat.terms
252
+ );
253
+ return existingBeforeThreshold !== 0 && existingBeforeThreshold <= beforeThreshold;
254
+ }
255
+ );
256
+ if (hasSupersedingTimestampConstraint) {
257
+ return caveats;
258
+ }
259
+ const timestampCaveat = {
260
+ enforcer: timestampEnforcer,
261
+ terms: createTimestampTerms({
262
+ afterThreshold: 0,
263
+ beforeThreshold
264
+ }),
265
+ args: "0x"
266
+ };
267
+ return [...caveats, timestampCaveat];
268
+ };
269
+ var ensureRedeemerSufficientlyConstrained = ({
270
+ redeemerEnforcer,
271
+ caveats,
272
+ existingDelegations,
273
+ redeemerAddresses,
274
+ requireRedeemers
275
+ }) => {
276
+ const redeemerAddressNormalized = normalizeAddress(redeemerEnforcer);
277
+ if (redeemerAddresses.length === 0) {
278
+ if (!requireRedeemers) {
279
+ return caveats;
280
+ }
281
+ const hasExistingRedeemerCaveat = hasMatchingCaveats(
282
+ caveats,
283
+ existingDelegations,
284
+ ({ enforcer }) => normalizeAddress(enforcer) === redeemerAddressNormalized
285
+ );
286
+ if (!hasExistingRedeemerCaveat) {
287
+ throw new Error(
288
+ "Redeemer must be constrained, either in the specified `caveats`, `parentPermissionContext`, or the `PaymentRequirements` as `extra.facilitatorAddresses`."
289
+ );
290
+ }
291
+ return caveats;
292
+ }
293
+ const redeemerAddressesNormalized = redeemerAddresses.map(normalizeAddress);
294
+ const redeemerAddressesSet = new Set(redeemerAddressesNormalized);
295
+ const hasSupersedingRedeemerCaveat = hasMatchingCaveats(
296
+ caveats,
297
+ existingDelegations,
298
+ (caveat) => {
299
+ if (normalizeAddress(caveat.enforcer) !== redeemerAddressNormalized) {
300
+ return false;
301
+ }
302
+ const allowedRedeemerAddresses = decodeRedeemerTerms(
303
+ caveat.terms
304
+ ).redeemers.map(normalizeAddress);
305
+ return allowedRedeemerAddresses.every(
306
+ (item) => redeemerAddressesSet.has(item)
307
+ );
308
+ }
309
+ );
310
+ if (hasSupersedingRedeemerCaveat) {
311
+ return caveats;
312
+ }
313
+ const redeemerCaveat = {
314
+ enforcer: redeemerEnforcer,
315
+ terms: createRedeemerTerms({ redeemers: redeemerAddresses }),
316
+ args: "0x"
317
+ };
318
+ return [...caveats, redeemerCaveat];
319
+ };
320
+ var ensurePayeeSufficientlyConstrained = ({
321
+ allowedCalldataEnforcer,
322
+ caveats,
323
+ existingDelegations,
324
+ payee
325
+ }) => {
326
+ const allowedCalldataTerms = createAllowedCalldataTerms({
327
+ startIndex: TRANSFER_PAYEE_INDEX,
328
+ value: pad(payee, { size: 32 })
329
+ });
330
+ const allowedCalldataEnforcerNormalized = normalizeAddress(
331
+ allowedCalldataEnforcer
332
+ );
333
+ const lowercaseCalldataTerms = allowedCalldataTerms.toLowerCase();
334
+ const hasSupersedingAllowedCalldataConstraint = hasMatchingCaveats(
335
+ caveats,
336
+ existingDelegations,
337
+ ({ enforcer, terms }) => normalizeAddress(enforcer) === allowedCalldataEnforcerNormalized && terms.toLowerCase() === lowercaseCalldataTerms
338
+ );
339
+ if (hasSupersedingAllowedCalldataConstraint) {
340
+ return caveats;
341
+ }
342
+ const payeeCaveat = {
343
+ enforcer: allowedCalldataEnforcer,
344
+ terms: allowedCalldataTerms,
345
+ args: "0x"
346
+ };
347
+ return [...caveats, payeeCaveat];
348
+ };
349
+ var resolvex402DelegationCaveats = ({
350
+ environment,
351
+ caveatsConfig,
352
+ existingDelegations,
353
+ facilitatorAddresses,
354
+ payee,
355
+ expirySeconds,
356
+ requireRedeemers,
357
+ redeemerAddresses
358
+ }) => {
359
+ const {
360
+ caveatEnforcers: {
361
+ RedeemerEnforcer: redeemerEnforcer,
362
+ AllowedCalldataEnforcer: allowedCalldataEnforcer,
363
+ TimestampEnforcer: timestampEnforcer
364
+ }
365
+ } = environment;
366
+ if (!redeemerEnforcer) {
367
+ throw new Error("RedeemerEnforcer not found in environment");
368
+ }
369
+ if (!allowedCalldataEnforcer) {
370
+ throw new Error("AllowedCalldataEnforcer not found in environment");
371
+ }
372
+ if (!timestampEnforcer) {
373
+ throw new Error("TimestampEnforcer not found in environment");
374
+ }
375
+ const initialCaveats = resolveCaveats({
376
+ environment,
377
+ caveats: caveatsConfig,
378
+ // Resolve caveats first so downstream constraint checks can append as needed.
379
+ // Scope is still attached later during delegation creation.
380
+ isScopeOptional: true
381
+ });
382
+ const allRedeemerAddresses = new Set(
383
+ [...facilitatorAddresses ?? [], ...redeemerAddresses ?? []].map(
384
+ normalizeAddress
385
+ )
386
+ );
387
+ const caveatsWithRedeemer = ensureRedeemerSufficientlyConstrained({
388
+ redeemerEnforcer,
389
+ caveats: initialCaveats,
390
+ existingDelegations,
391
+ redeemerAddresses: Array.from(allRedeemerAddresses),
392
+ requireRedeemers
393
+ });
394
+ const caveatsWithPayee = ensurePayeeSufficientlyConstrained({
395
+ allowedCalldataEnforcer,
396
+ caveats: caveatsWithRedeemer,
397
+ existingDelegations,
398
+ payee
399
+ });
400
+ if (expirySeconds === void 0) {
401
+ return caveatsWithPayee;
402
+ }
403
+ return ensureExpirySufficientlyConstrained({
404
+ timestampEnforcer,
405
+ caveats: caveatsWithPayee,
406
+ existingDelegations,
407
+ expirySeconds
408
+ });
409
+ };
410
+ var resolveDelegationCreationContext = async (config, requirements) => {
411
+ const account = await resolveMaybeDeferred(config.account, requirements);
412
+ const redeemersConfig = await resolveMaybeDeferred(
413
+ config.redeemers,
414
+ requirements
415
+ );
416
+ const requireRedeemers = redeemersConfig?.requireRedeemers ?? false;
417
+ const redeemerAddresses = await resolveMaybeDeferred(
418
+ redeemersConfig?.addresses,
419
+ requirements
420
+ );
421
+ const specifiedEnvironment = await resolveMaybeDeferred(
422
+ config.environment,
423
+ requirements
424
+ );
425
+ const environment = specifiedEnvironment ?? getSmartAccountsEnvironment(parseEip155ChainId(requirements.network));
426
+ const caveatsConfig = await resolveMaybeDeferred(
427
+ config.caveats,
428
+ requirements
429
+ );
430
+ const parentPermissionContext = await resolveMaybeDeferred(config.parentPermissionContext, requirements);
431
+ const expirySeconds = await resolveMaybeDeferred(
432
+ config.expirySeconds,
433
+ requirements
434
+ );
435
+ const from = await resolveMaybeDeferred(config.from, requirements) ?? account.address;
436
+ const salt = await resolveMaybeDeferred(config.salt, requirements) ?? generateSalt();
437
+ const scope = {
438
+ type: "erc20TransferAmount" /* Erc20TransferAmount */,
439
+ tokenAddress: requirements.asset,
440
+ maxAmount: BigInt(requirements.amount)
441
+ };
442
+ const facilitatorAddresses = requirements.extra?.facilitatorAddresses;
443
+ const existingDelegations = parentPermissionContext ? decodeDelegations(parentPermissionContext) : [];
444
+ const { DelegationManager: delegationManager } = environment;
445
+ const caveats = resolvex402DelegationCaveats({
446
+ environment,
447
+ caveatsConfig,
448
+ existingDelegations,
449
+ facilitatorAddresses,
450
+ payee: requirements.payTo,
451
+ expirySeconds,
452
+ requireRedeemers,
453
+ redeemerAddresses
454
+ });
455
+ let createDelegationConfig;
456
+ if (parentPermissionContext) {
457
+ const parentDelegation = existingDelegations[0];
458
+ if (!parentDelegation) {
459
+ throw new Error("Parent permission context is not a valid delegation");
460
+ }
461
+ createDelegationConfig = {
462
+ environment,
463
+ from,
464
+ caveats,
465
+ salt,
466
+ scope,
467
+ parentDelegation
468
+ };
469
+ } else {
470
+ createDelegationConfig = {
471
+ environment,
472
+ from,
473
+ caveats,
474
+ salt,
475
+ scope
476
+ };
477
+ }
478
+ const rootDelegator = existingDelegations[existingDelegations.length - 1]?.delegator ?? from;
479
+ return {
480
+ account,
481
+ createDelegationConfig,
482
+ delegationManager,
483
+ existingDelegations,
484
+ rootDelegator
485
+ };
486
+ };
487
+
488
+ // src/experimental/x402DelegationProvider.ts
489
+ function createx402DelegationProvider(config) {
490
+ return async (requirements) => {
491
+ const {
492
+ account,
493
+ createDelegationConfig,
494
+ delegationManager,
495
+ existingDelegations,
496
+ rootDelegator
497
+ } = await resolveDelegationCreationContext(config, requirements);
498
+ const delegation = createOpenDelegation(createDelegationConfig);
499
+ const chainId = parseEip155ChainId(requirements.network);
500
+ const typedData = prepareSignDelegationTypedData({
501
+ delegationManager,
502
+ chainId,
503
+ delegation
504
+ });
505
+ if (!account.signTypedData) {
506
+ throw new Error("Account does not support signTypedData");
507
+ }
508
+ const signature = await account.signTypedData(typedData);
509
+ const signedDelegation = {
510
+ ...delegation,
511
+ signature
512
+ };
513
+ const permissionContext = encodeDelegations([
514
+ signedDelegation,
515
+ ...existingDelegations
516
+ ]);
517
+ return {
518
+ delegationManager,
519
+ permissionContext,
520
+ delegator: rootDelegator
521
+ };
522
+ };
523
+ }
171
524
  export {
172
525
  DelegationStorageClient,
173
- DelegationStorageEnvironment
526
+ DelegationStorageEnvironment,
527
+ createx402DelegationProvider,
528
+ parseEip155ChainId
174
529
  };
175
530
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/experimental/delegationStorage.ts"],"sourcesContent":["import { type Hex, toHex } from 'viem';\n\nimport { trackSmartAccountsKitFunctionCall } from '../analytics';\nimport { hashDelegation } from '../delegation';\nimport type { Delegation } from '../types';\n\ntype ErrorResponse = {\n error: string;\n data?: any;\n};\n\nexport type APIStoreDelegationResponse = {\n delegationHash: Hex;\n};\n\n/**\n * Represents the allowed filters when querying the data store for delegations.\n */\nexport enum DelegationStoreFilter {\n Given = 'GIVEN',\n Received = 'RECEIVED',\n All = 'ALL',\n}\n\n/**\n * Public Delegation Storage Service environments. To be used in the\n * DeleGationStorageService config.\n */\nexport const DelegationStorageEnvironment: {\n [K in 'dev' | 'prod']: Environment;\n} = {\n dev: { apiUrl: 'https://passkeys.dev-api.cx.metamask.io' },\n prod: { apiUrl: 'https://passkeys.api.cx.metamask.io' },\n};\n\n/**\n * Returns the DelegationStorageEnvironment ('dev' or 'prod') for a given apiUrl,\n * or 'custom' if the apiUrl does not match a known environment.\n *\n * @param apiUrl - The API URL to check.\n * @returns The environment key ('dev' or 'prod'), or 'custom'.\n */\nfunction getDelegationStorageEnvironment(\n apiUrl: string,\n): 'dev' | 'prod' | 'custom' {\n const matchingEnvironment = Object.entries(DelegationStorageEnvironment).find(\n ([_, env]) => env.apiUrl === apiUrl,\n ) as [keyof typeof DelegationStorageEnvironment, Environment] | undefined;\n\n return matchingEnvironment ? matchingEnvironment[0] : 'custom';\n}\n\nexport type Environment = {\n apiUrl: string;\n};\n\nexport type DelegationStorageConfig = {\n apiKey: string;\n apiKeyId: string;\n environment: Environment;\n fetcher?: typeof fetch;\n};\n\nexport class DelegationStorageClient {\n readonly #apiVersionPrefix = 'api/v0';\n\n readonly #config: DelegationStorageConfig;\n\n readonly #fetcher: typeof fetch;\n\n readonly #apiUrl: string;\n\n constructor(config: DelegationStorageConfig) {\n const { apiUrl } = config.environment;\n\n trackSmartAccountsKitFunctionCall(\n 'experimental.DelegationStorageClient.constructor',\n {\n environment: getDelegationStorageEnvironment(apiUrl),\n },\n );\n\n if (apiUrl.endsWith(this.#apiVersionPrefix)) {\n this.#apiUrl = apiUrl;\n } else {\n const separator = apiUrl.endsWith('/') ? '' : '/';\n this.#apiUrl = `${apiUrl}${separator}${this.#apiVersionPrefix}`;\n }\n this.#fetcher = this.#initializeFetcher(config);\n this.#config = config;\n }\n\n /**\n * Initializes the fetch function for HTTP requests.\n *\n * - Uses `config.fetcher` if provided.\n * - Falls back to global `fetch` if available.\n * - Throws an error if no fetch function is available.\n *\n * @param config - Configuration object that may include a custom fetch function.\n * @returns The fetch function to be used for HTTP requests.\n * @throws Error if no fetch function is available in the environment.\n */\n #initializeFetcher(config: DelegationStorageConfig): typeof fetch {\n if (config.fetcher) {\n return config.fetcher;\n } else if (typeof globalThis?.fetch === 'function') {\n return globalThis.fetch.bind(globalThis);\n }\n throw new Error(\n 'Fetch API is not available in this environment. Please provide a fetch function in the config.',\n );\n }\n\n /**\n * Fetches the delegation chain from the Delegation Storage Service, ending with\n * the specified leaf delegation.\n *\n * @param leafDelegationOrDelegationHash - The leaf delegation, or the hash\n * of the leaf delegation.\n * @returns A promise that resolves to the delegation chain - empty array if the delegation\n * is not found.\n */\n async getDelegationChain(\n leafDelegationOrDelegationHash: Hex | Delegation,\n ): Promise<Delegation[]> {\n trackSmartAccountsKitFunctionCall(\n 'experimental.DelegationStorageClient.getDelegationChain',\n {\n inputKind:\n typeof leafDelegationOrDelegationHash === 'string'\n ? 'hash'\n : 'delegation',\n },\n );\n const leafDelegationHash =\n typeof leafDelegationOrDelegationHash === 'string'\n ? leafDelegationOrDelegationHash\n : hashDelegation(leafDelegationOrDelegationHash);\n\n const response = await this.#fetcher(\n `${this.#apiUrl}/delegation/chain/${leafDelegationHash}`,\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.#config.apiKey}`,\n 'x-api-key-id': this.#config.apiKeyId,\n },\n },\n );\n\n const responseData: Delegation[] | ErrorResponse = await response.json();\n\n if ('error' in responseData) {\n throw new Error(\n `Failed to fetch delegation chain: ${responseData.error}`,\n );\n }\n\n return responseData;\n }\n\n /**\n * Fetches the delegations from the Delegation Storage Service, either `Received`\n * by, or `Given` by, (or both: `All`) the specified deleGatorAddress. Defaults\n * to `Received`.\n *\n * @param deleGatorAddress - The deleGatorAddress to retrieve the delegations for.\n * @param filterMode - The DelegationStoreFilter mode - defaults to Received.\n * @returns A promise that resolves to the list of delegations received by the deleGatorAddress,\n * empty array if the delegations are not found.\n */\n async fetchDelegations(\n deleGatorAddress: Hex,\n filterMode = DelegationStoreFilter.Received,\n ): Promise<Delegation[]> {\n trackSmartAccountsKitFunctionCall(\n 'experimental.DelegationStorageClient.fetchDelegations',\n { filterMode },\n );\n const response = await this.#fetcher(\n `${this.#apiUrl}/delegation/accounts/${deleGatorAddress}?filter=${filterMode}`,\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.#config.apiKey}`,\n 'x-api-key-id': this.#config.apiKeyId,\n },\n },\n );\n\n const responseData: Delegation[] | ErrorResponse = await response.json();\n\n if ('error' in responseData) {\n throw new Error(`Failed to fetch delegations: ${responseData.error}`);\n }\n\n return responseData;\n }\n\n /**\n * Stores the specified delegation in the Delegation Storage Service.\n *\n * @param delegation - The delegation to store.\n * @returns A promise that resolves to the delegation hash indicating successful storage.\n */\n async storeDelegation(delegation: Delegation): Promise<Hex> {\n trackSmartAccountsKitFunctionCall(\n 'experimental.DelegationStorageClient.storeDelegation',\n { caveatCount: delegation.caveats.length },\n );\n if (!delegation.signature || delegation.signature === '0x') {\n throw new Error('Delegation must be signed to be stored');\n }\n\n const delegationHash = hashDelegation(delegation);\n\n const body = JSON.stringify(\n {\n ...delegation,\n metadata: [],\n },\n (_, value: any) =>\n typeof value === 'bigint' || typeof value === 'number'\n ? toHex(value)\n : value,\n 2,\n );\n\n const response = await this.#fetcher(`${this.#apiUrl}/delegation/store`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.#config.apiKey}`,\n 'x-api-key-id': this.#config.apiKeyId,\n 'Content-Type': 'application/json',\n },\n body,\n });\n\n const responseData: APIStoreDelegationResponse | ErrorResponse =\n await response.json();\n\n if ('error' in responseData) {\n throw new Error(responseData.error);\n }\n\n if (responseData.delegationHash !== delegationHash) {\n throw new Error(\n 'Failed to store the Delegation, the hash returned from the MM delegation storage API does not match the hash of the delegation',\n );\n }\n\n return responseData.delegationHash;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/experimental/delegationStorage.ts","../../src/experimental/x402DelegationProviderUtils.ts","../../src/experimental/x402DelegationProvider.ts"],"sourcesContent":["import { type Hex, toHex } from 'viem';\n\nimport { trackSmartAccountsKitFunctionCall } from '../analytics';\nimport { hashDelegation } from '../delegation';\nimport type { Delegation } from '../types';\n\ntype ErrorResponse = {\n error: string;\n data?: any;\n};\n\nexport type APIStoreDelegationResponse = {\n delegationHash: Hex;\n};\n\n/**\n * Represents the allowed filters when querying the data store for delegations.\n */\nexport enum DelegationStoreFilter {\n Given = 'GIVEN',\n Received = 'RECEIVED',\n All = 'ALL',\n}\n\n/**\n * Public Delegation Storage Service environments. To be used in the\n * DeleGationStorageService config.\n */\nexport const DelegationStorageEnvironment: {\n [K in 'dev' | 'prod']: Environment;\n} = {\n dev: { apiUrl: 'https://passkeys.dev-api.cx.metamask.io' },\n prod: { apiUrl: 'https://passkeys.api.cx.metamask.io' },\n};\n\n/**\n * Returns the DelegationStorageEnvironment ('dev' or 'prod') for a given apiUrl,\n * or 'custom' if the apiUrl does not match a known environment.\n *\n * @param apiUrl - The API URL to check.\n * @returns The environment key ('dev' or 'prod'), or 'custom'.\n */\nfunction getDelegationStorageEnvironment(\n apiUrl: string,\n): 'dev' | 'prod' | 'custom' {\n const matchingEnvironment = Object.entries(DelegationStorageEnvironment).find(\n ([_, env]) => env.apiUrl === apiUrl,\n ) as [keyof typeof DelegationStorageEnvironment, Environment] | undefined;\n\n return matchingEnvironment ? matchingEnvironment[0] : 'custom';\n}\n\nexport type Environment = {\n apiUrl: string;\n};\n\nexport type DelegationStorageConfig = {\n apiKey: string;\n apiKeyId: string;\n environment: Environment;\n fetcher?: typeof fetch;\n};\n\nexport class DelegationStorageClient {\n readonly #apiVersionPrefix = 'api/v0';\n\n readonly #config: DelegationStorageConfig;\n\n readonly #fetcher: typeof fetch;\n\n readonly #apiUrl: string;\n\n constructor(config: DelegationStorageConfig) {\n const { apiUrl } = config.environment;\n\n trackSmartAccountsKitFunctionCall(\n 'experimental.DelegationStorageClient.constructor',\n {\n environment: getDelegationStorageEnvironment(apiUrl),\n },\n );\n\n if (apiUrl.endsWith(this.#apiVersionPrefix)) {\n this.#apiUrl = apiUrl;\n } else {\n const separator = apiUrl.endsWith('/') ? '' : '/';\n this.#apiUrl = `${apiUrl}${separator}${this.#apiVersionPrefix}`;\n }\n this.#fetcher = this.#initializeFetcher(config);\n this.#config = config;\n }\n\n /**\n * Initializes the fetch function for HTTP requests.\n *\n * - Uses `config.fetcher` if provided.\n * - Falls back to global `fetch` if available.\n * - Throws an error if no fetch function is available.\n *\n * @param config - Configuration object that may include a custom fetch function.\n * @returns The fetch function to be used for HTTP requests.\n * @throws Error if no fetch function is available in the environment.\n */\n #initializeFetcher(config: DelegationStorageConfig): typeof fetch {\n if (config.fetcher) {\n return config.fetcher;\n } else if (typeof globalThis?.fetch === 'function') {\n return globalThis.fetch.bind(globalThis);\n }\n throw new Error(\n 'Fetch API is not available in this environment. Please provide a fetch function in the config.',\n );\n }\n\n /**\n * Fetches the delegation chain from the Delegation Storage Service, ending with\n * the specified leaf delegation.\n *\n * @param leafDelegationOrDelegationHash - The leaf delegation, or the hash\n * of the leaf delegation.\n * @returns A promise that resolves to the delegation chain - empty array if the delegation\n * is not found.\n */\n async getDelegationChain(\n leafDelegationOrDelegationHash: Hex | Delegation,\n ): Promise<Delegation[]> {\n trackSmartAccountsKitFunctionCall(\n 'experimental.DelegationStorageClient.getDelegationChain',\n {\n inputKind:\n typeof leafDelegationOrDelegationHash === 'string'\n ? 'hash'\n : 'delegation',\n },\n );\n const leafDelegationHash =\n typeof leafDelegationOrDelegationHash === 'string'\n ? leafDelegationOrDelegationHash\n : hashDelegation(leafDelegationOrDelegationHash);\n\n const response = await this.#fetcher(\n `${this.#apiUrl}/delegation/chain/${leafDelegationHash}`,\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.#config.apiKey}`,\n 'x-api-key-id': this.#config.apiKeyId,\n },\n },\n );\n\n const responseData: Delegation[] | ErrorResponse = await response.json();\n\n if ('error' in responseData) {\n throw new Error(\n `Failed to fetch delegation chain: ${responseData.error}`,\n );\n }\n\n return responseData;\n }\n\n /**\n * Fetches the delegations from the Delegation Storage Service, either `Received`\n * by, or `Given` by, (or both: `All`) the specified deleGatorAddress. Defaults\n * to `Received`.\n *\n * @param deleGatorAddress - The deleGatorAddress to retrieve the delegations for.\n * @param filterMode - The DelegationStoreFilter mode - defaults to Received.\n * @returns A promise that resolves to the list of delegations received by the deleGatorAddress,\n * empty array if the delegations are not found.\n */\n async fetchDelegations(\n deleGatorAddress: Hex,\n filterMode = DelegationStoreFilter.Received,\n ): Promise<Delegation[]> {\n trackSmartAccountsKitFunctionCall(\n 'experimental.DelegationStorageClient.fetchDelegations',\n { filterMode },\n );\n const response = await this.#fetcher(\n `${this.#apiUrl}/delegation/accounts/${deleGatorAddress}?filter=${filterMode}`,\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.#config.apiKey}`,\n 'x-api-key-id': this.#config.apiKeyId,\n },\n },\n );\n\n const responseData: Delegation[] | ErrorResponse = await response.json();\n\n if ('error' in responseData) {\n throw new Error(`Failed to fetch delegations: ${responseData.error}`);\n }\n\n return responseData;\n }\n\n /**\n * Stores the specified delegation in the Delegation Storage Service.\n *\n * @param delegation - The delegation to store.\n * @returns A promise that resolves to the delegation hash indicating successful storage.\n */\n async storeDelegation(delegation: Delegation): Promise<Hex> {\n trackSmartAccountsKitFunctionCall(\n 'experimental.DelegationStorageClient.storeDelegation',\n { caveatCount: delegation.caveats.length },\n );\n if (!delegation.signature || delegation.signature === '0x') {\n throw new Error('Delegation must be signed to be stored');\n }\n\n const delegationHash = hashDelegation(delegation);\n\n const body = JSON.stringify(\n {\n ...delegation,\n metadata: [],\n },\n (_, value: any) =>\n typeof value === 'bigint' || typeof value === 'number'\n ? toHex(value)\n : value,\n 2,\n );\n\n const response = await this.#fetcher(`${this.#apiUrl}/delegation/store`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.#config.apiKey}`,\n 'x-api-key-id': this.#config.apiKeyId,\n 'Content-Type': 'application/json',\n },\n body,\n });\n\n const responseData: APIStoreDelegationResponse | ErrorResponse =\n await response.json();\n\n if ('error' in responseData) {\n throw new Error(responseData.error);\n }\n\n if (responseData.delegationHash !== delegationHash) {\n throw new Error(\n 'Failed to store the Delegation, the hash returned from the MM delegation storage API does not match the hash of the delegation',\n );\n }\n\n return responseData.delegationHash;\n }\n}\n","import {\n createAllowedCalldataTerms,\n createRedeemerTerms,\n createTimestampTerms,\n decodeRedeemerTerms,\n decodeTimestampTerms,\n} from '@metamask/delegation-core';\nimport { parseCaipChainId } from '@metamask/utils';\nimport { pad, type Account, type Address, type Hex } from 'viem';\n\nimport type { Caveats } from '../caveatBuilder';\nimport { resolveCaveats } from '../caveatBuilder';\nimport { ScopeType } from '../constants';\nimport type { createOpenDelegation } from '../delegation';\nimport { decodeDelegations } from '../delegation';\nimport { getSmartAccountsEnvironment } from '../smartAccountsEnvironment';\nimport type {\n Caveat,\n Delegation,\n PermissionContext,\n SmartAccountsEnvironment,\n} from '../types';\nimport type {\n MaybeDeferred,\n PaymentRequirements,\n x402DelegationProviderConfig,\n} from './x402DelegationProviderTypes';\nimport { generateSalt } from '../utils/';\n\n/**\n * Inputs for redeemer constraint enforcement.\n */\ntype EnsureRedeemerSufficientlyConstrainedParams = {\n redeemerEnforcer: Hex;\n caveats: Caveat[];\n existingDelegations: Delegation[];\n redeemerAddresses: Hex[];\n requireRedeemers: boolean;\n};\n\n/**\n * Inputs for payee constraint enforcement.\n */\ntype EnsurePayeeSufficientlyConstrainedParams = {\n allowedCalldataEnforcer: Hex;\n caveats: Caveat[];\n existingDelegations: Delegation[];\n payee: Hex;\n};\n\n/**\n * Inputs for expiry constraint enforcement.\n */\ntype EnsureExpirySufficientlyConstrainedParams = {\n timestampEnforcer: Hex;\n caveats: Caveat[];\n existingDelegations: Delegation[];\n expirySeconds: number;\n};\n\n/**\n * Resolved context required to build and sign an x402 delegation.\n */\nexport type DelegationCreationContext = {\n account: Account;\n createDelegationConfig: Parameters<typeof createOpenDelegation>[0];\n delegationManager: Address;\n existingDelegations: Delegation[];\n rootDelegator: Address;\n};\n\n/**\n * Inputs for resolving delegation caveats with x402-specific constraints.\n */\nexport type Resolvex402DelegationCaveatsParams = {\n environment: SmartAccountsEnvironment;\n caveatsConfig: Caveats | undefined;\n existingDelegations: Delegation[];\n facilitatorAddresses: Hex[] | undefined;\n payee: Hex;\n expirySeconds?: number;\n requireRedeemers: boolean;\n redeemerAddresses: Address[] | undefined;\n};\n\n/**\n * Resolves eager or deferred values against payment requirements.\n *\n * @param maybeDeferred - Value or async resolver function.\n * @param requirements - Payment requirements passed to deferred resolvers.\n * @returns The resolved value, or undefined when no value is provided.\n */\nasync function resolveMaybeDeferred<TResult>(\n maybeDeferred: MaybeDeferred<TResult>,\n requirements: PaymentRequirements,\n): Promise<TResult> {\n if (typeof maybeDeferred === 'function') {\n const deferred = maybeDeferred as (\n deferredRequirements: PaymentRequirements,\n ) => Promise<TResult> | TResult;\n\n return await deferred(requirements);\n }\n\n return maybeDeferred;\n}\n\n/**\n * Parses an EIP-155 CAIP network identifier into a numeric chain ID.\n *\n * @param network - CAIP network identifier (for example, `eip155:1`).\n * @returns Parsed numeric chain ID.\n * @throws If the CAIP namespace is not `eip155`.\n */\nexport function parseEip155ChainId(\n network: PaymentRequirements['network'],\n): number {\n const { namespace, reference } = parseCaipChainId(\n network as `${string}:${string}`,\n );\n\n if (namespace !== 'eip155') {\n throw new Error('Unsupported chain namespace');\n }\n\n const parsedChainId = Number(reference);\n\n if (isNaN(parsedChainId)) {\n throw new Error('Invalid chain id');\n }\n\n return parsedChainId;\n}\n\n/**\n * ERC-20 `transfer(address to, uint256 value)` calldata index for `to`.\n */\nconst TRANSFER_PAYEE_INDEX = 4;\n\n/**\n * Normalizes an address-like hex string for case-insensitive comparisons.\n *\n * @param address - Address value to normalize.\n * @returns Lowercased hex string.\n */\nconst normalizeAddress = (address: Address): Address =>\n address.toLowerCase() as Address;\n\n/**\n * Returns whether any caveat in local or inherited delegations matches a predicate.\n *\n * @param caveats - Current caveat list.\n * @param delegations - Existing delegations whose caveats should also be searched.\n * @param match - Predicate used to match caveats.\n * @returns True when at least one caveat satisfies `match`.\n */\nconst hasMatchingCaveats = (\n caveats: Caveat[],\n delegations: Delegation[],\n match: (caveat: Caveat) => boolean,\n): boolean => {\n for (const caveat of caveats) {\n if (match(caveat)) {\n return true;\n }\n }\n\n for (const delegation of delegations) {\n for (const caveat of delegation.caveats) {\n if (match(caveat)) {\n return true;\n }\n }\n }\n\n return false;\n};\n\n/**\n * Ensures caveats include an expiry timestamp constraint when requested.\n *\n * If an existing timestamp caveat already enforces a tighter (earlier) or equal\n * `validBefore` threshold than requested, caveats are returned unchanged.\n * Otherwise a new timestamp caveat is appended with `afterThreshold = 0`.\n *\n * @param options0 - Expiry constraint evaluation inputs.\n * @param options0.timestampEnforcer - Address of the TimestampEnforcer caveat contract.\n * @param options0.caveats - Currently resolved caveats for the delegation being created.\n * @param options0.existingDelegations - Existing parent-chain delegations to inspect for inherited constraints.\n * @param options0.expirySeconds - Relative expiry from \"now\" in seconds.\n * @returns The original caveats when sufficiently constrained, otherwise caveats with a timestamp caveat appended.\n */\nexport const ensureExpirySufficientlyConstrained = ({\n timestampEnforcer,\n caveats,\n existingDelegations,\n expirySeconds,\n}: EnsureExpirySufficientlyConstrainedParams): Caveat[] => {\n if (expirySeconds < 0) {\n throw new Error('Expiry seconds must be a positive number');\n }\n const beforeThreshold = Math.floor(Date.now() / 1000) + expirySeconds;\n const timestampEnforcerNormalized = normalizeAddress(timestampEnforcer);\n\n const hasSupersedingTimestampConstraint = hasMatchingCaveats(\n caveats,\n existingDelegations,\n (caveat) => {\n if (normalizeAddress(caveat.enforcer) !== timestampEnforcerNormalized) {\n return false;\n }\n\n const { beforeThreshold: existingBeforeThreshold } = decodeTimestampTerms(\n caveat.terms,\n );\n return (\n existingBeforeThreshold !== 0 &&\n existingBeforeThreshold <= beforeThreshold\n );\n },\n );\n\n if (hasSupersedingTimestampConstraint) {\n return caveats;\n }\n\n const timestampCaveat: Caveat = {\n enforcer: timestampEnforcer,\n terms: createTimestampTerms({\n afterThreshold: 0,\n beforeThreshold,\n }),\n args: '0x',\n };\n\n return [...caveats, timestampCaveat];\n};\n\n/**\n * Ensures caveats include a sufficiently strict redeemer constraint.\n *\n * Returns the caveat list unchanged when an existing redeemer caveat is already\n * strict enough, or appends a new redeemer caveat scoped to facilitator addresses.\n *\n * @param options0 - Redeemer constraint evaluation inputs.\n * @param options0.redeemerEnforcer - Address of the redeemer enforcer caveat contract.\n * @param options0.caveats - Currently resolved caveats for the delegation being created.\n * @param options0.existingDelegations - Existing parent-chain delegations to inspect for inherited constraints.\n * @param options0.redeemerAddresses - Optional addresses to which redemption should be constrained.\n * @param options0.requireRedeemers - Whether at least one redeemer constraint must exist when no redeemer addresses are supplied.\n * @returns The original caveats when sufficiently constrained, otherwise caveats with a redeemer caveat appended.\n * @throws If no facilitator addresses are provided and no redeemer constraint exists.\n */\nexport const ensureRedeemerSufficientlyConstrained = ({\n redeemerEnforcer,\n caveats,\n existingDelegations,\n redeemerAddresses,\n requireRedeemers,\n}: EnsureRedeemerSufficientlyConstrainedParams): Caveat[] => {\n const redeemerAddressNormalized = normalizeAddress(redeemerEnforcer);\n\n if (redeemerAddresses.length === 0) {\n if (!requireRedeemers) {\n return caveats;\n }\n\n const hasExistingRedeemerCaveat = hasMatchingCaveats(\n caveats,\n existingDelegations,\n ({ enforcer }) =>\n normalizeAddress(enforcer) === redeemerAddressNormalized,\n );\n\n if (!hasExistingRedeemerCaveat) {\n throw new Error(\n 'Redeemer must be constrained, either in the specified `caveats`, `parentPermissionContext`, or the `PaymentRequirements` as `extra.facilitatorAddresses`.',\n );\n }\n\n return caveats;\n }\n\n const redeemerAddressesNormalized = redeemerAddresses.map(normalizeAddress);\n const redeemerAddressesSet = new Set(redeemerAddressesNormalized);\n\n const hasSupersedingRedeemerCaveat = hasMatchingCaveats(\n caveats,\n existingDelegations,\n (caveat) => {\n if (normalizeAddress(caveat.enforcer) !== redeemerAddressNormalized) {\n return false;\n }\n\n const allowedRedeemerAddresses = decodeRedeemerTerms(\n caveat.terms,\n ).redeemers.map(normalizeAddress);\n\n // If this redeemer caveat only allows facilitator addresses, it is sufficiently constrained.\n return allowedRedeemerAddresses.every((item) =>\n redeemerAddressesSet.has(item),\n );\n },\n );\n\n if (hasSupersedingRedeemerCaveat) {\n return caveats;\n }\n\n const redeemerCaveat: Caveat = {\n enforcer: redeemerEnforcer,\n terms: createRedeemerTerms({ redeemers: redeemerAddresses }),\n args: '0x',\n };\n\n return [...caveats, redeemerCaveat];\n};\n\n/**\n * Ensures caveats include an allowed-calldata constraint for the payment payee.\n *\n * Scans both the in-progress caveat list and parent delegation caveats for an\n * `AllowedCalldataEnforcer` caveat whose terms match the encoded payee calldata\n * constraint. If found, returns caveats unchanged; otherwise appends a payee caveat.\n *\n * @param options0 - Payee constraint evaluation inputs.\n * @param options0.allowedCalldataEnforcer - Address of the AllowedCalldataEnforcer caveat contract.\n * @param options0.caveats - Currently resolved caveats for the delegation being created.\n * @param options0.existingDelegations - Existing parent-chain delegations to inspect for inherited constraints.\n * @param options0.payee - Expected ERC-20 transfer recipient to enforce in calldata.\n * @returns The original caveats when an equivalent payee constraint exists, otherwise caveats with a payee caveat appended.\n */\nexport const ensurePayeeSufficientlyConstrained = ({\n allowedCalldataEnforcer,\n caveats,\n existingDelegations,\n payee,\n}: EnsurePayeeSufficientlyConstrainedParams): Caveat[] => {\n const allowedCalldataTerms = createAllowedCalldataTerms({\n startIndex: TRANSFER_PAYEE_INDEX,\n value: pad(payee, { size: 32 }),\n });\n\n const allowedCalldataEnforcerNormalized = normalizeAddress(\n allowedCalldataEnforcer,\n );\n\n const lowercaseCalldataTerms = allowedCalldataTerms.toLowerCase();\n\n const hasSupersedingAllowedCalldataConstraint = hasMatchingCaveats(\n caveats,\n existingDelegations,\n ({ enforcer, terms }) =>\n normalizeAddress(enforcer) === allowedCalldataEnforcerNormalized &&\n terms.toLowerCase() === lowercaseCalldataTerms,\n );\n\n if (hasSupersedingAllowedCalldataConstraint) {\n return caveats;\n }\n\n const payeeCaveat: Caveat = {\n enforcer: allowedCalldataEnforcer,\n terms: allowedCalldataTerms,\n args: '0x',\n };\n\n return [...caveats, payeeCaveat];\n};\n\n/**\n * Resolves caveats and applies x402-specific redeemer and payee constraints.\n *\n * @param options0 - Caveat resolution inputs.\n * @param options0.environment - Environment containing caveat enforcer addresses.\n * @param options0.caveatsConfig - Optional caveat builder config.\n * @param options0.existingDelegations - Existing parent-chain delegations.\n * @param options0.facilitatorAddresses - Optional facilitator addresses used for redeemer constraints.\n * @param options0.payee - Payee address used for allowed calldata constraints.\n * @param options0.expirySeconds - Optional relative expiry in seconds for adding timestamp constraints.\n * @param options0.requireRedeemers - Whether redeemer constraints are mandatory when no facilitator or configured redeemer addresses are present.\n * @param options0.redeemerAddresses - Optional redeemer addresses from provider config to merge with facilitator addresses.\n * @returns Caveats after redeemer and payee constraints are enforced.\n */\nexport const resolvex402DelegationCaveats = ({\n environment,\n caveatsConfig,\n existingDelegations,\n facilitatorAddresses,\n payee,\n expirySeconds,\n requireRedeemers,\n redeemerAddresses,\n}: Resolvex402DelegationCaveatsParams): Caveat[] => {\n const {\n caveatEnforcers: {\n RedeemerEnforcer: redeemerEnforcer,\n AllowedCalldataEnforcer: allowedCalldataEnforcer,\n TimestampEnforcer: timestampEnforcer,\n },\n } = environment;\n\n if (!redeemerEnforcer) {\n throw new Error('RedeemerEnforcer not found in environment');\n }\n\n if (!allowedCalldataEnforcer) {\n throw new Error('AllowedCalldataEnforcer not found in environment');\n }\n\n if (!timestampEnforcer) {\n throw new Error('TimestampEnforcer not found in environment');\n }\n\n const initialCaveats = resolveCaveats({\n environment,\n caveats: caveatsConfig,\n // Resolve caveats first so downstream constraint checks can append as needed.\n // Scope is still attached later during delegation creation.\n isScopeOptional: true,\n });\n\n const allRedeemerAddresses = new Set(\n [...(facilitatorAddresses ?? []), ...(redeemerAddresses ?? [])].map(\n normalizeAddress,\n ),\n );\n\n const caveatsWithRedeemer = ensureRedeemerSufficientlyConstrained({\n redeemerEnforcer,\n caveats: initialCaveats,\n existingDelegations,\n redeemerAddresses: Array.from(allRedeemerAddresses),\n requireRedeemers,\n });\n\n const caveatsWithPayee = ensurePayeeSufficientlyConstrained({\n allowedCalldataEnforcer,\n caveats: caveatsWithRedeemer,\n existingDelegations,\n payee,\n });\n\n if (expirySeconds === undefined) {\n return caveatsWithPayee;\n }\n\n return ensureExpirySufficientlyConstrained({\n timestampEnforcer,\n caveats: caveatsWithPayee,\n existingDelegations,\n expirySeconds,\n });\n};\n\n/**\n * Builds the delegation creation context from provider config and requirements.\n *\n * @param config - Delegation provider config for context construction.\n * @param requirements - Payment requirements used to scope caveats.\n * @returns The resolved context used to create and sign a delegation.\n */\nexport const resolveDelegationCreationContext = async (\n config: x402DelegationProviderConfig,\n requirements: PaymentRequirements,\n): Promise<DelegationCreationContext> => {\n const account = await resolveMaybeDeferred(config.account, requirements);\n const redeemersConfig = await resolveMaybeDeferred(\n config.redeemers,\n requirements,\n );\n\n const requireRedeemers = redeemersConfig?.requireRedeemers ?? false;\n const redeemerAddresses = await resolveMaybeDeferred(\n redeemersConfig?.addresses,\n requirements,\n );\n\n const specifiedEnvironment = await resolveMaybeDeferred(\n config.environment,\n requirements,\n );\n const environment =\n specifiedEnvironment ??\n getSmartAccountsEnvironment(parseEip155ChainId(requirements.network));\n\n const caveatsConfig: Caveats | undefined = await resolveMaybeDeferred(\n config.caveats,\n requirements,\n );\n const parentPermissionContext: PermissionContext | undefined =\n await resolveMaybeDeferred(config.parentPermissionContext, requirements);\n const expirySeconds = await resolveMaybeDeferred(\n config.expirySeconds,\n requirements,\n );\n\n const from =\n (await resolveMaybeDeferred(config.from, requirements)) ?? account.address;\n const salt =\n (await resolveMaybeDeferred(config.salt, requirements)) ?? generateSalt();\n\n const scope = {\n type: ScopeType.Erc20TransferAmount,\n tokenAddress: requirements.asset as Hex,\n maxAmount: BigInt(requirements.amount),\n } as const;\n\n const facilitatorAddresses = requirements.extra?.facilitatorAddresses as\n | Hex[]\n | undefined;\n\n const existingDelegations = parentPermissionContext\n ? decodeDelegations(parentPermissionContext)\n : [];\n\n const { DelegationManager: delegationManager } = environment;\n const caveats = resolvex402DelegationCaveats({\n environment,\n caveatsConfig,\n existingDelegations,\n facilitatorAddresses,\n payee: requirements.payTo as Hex,\n expirySeconds,\n requireRedeemers,\n redeemerAddresses,\n });\n\n let createDelegationConfig: Parameters<typeof createOpenDelegation>[0];\n\n if (parentPermissionContext) {\n const parentDelegation = existingDelegations[0];\n\n if (!parentDelegation) {\n throw new Error('Parent permission context is not a valid delegation');\n }\n\n createDelegationConfig = {\n environment,\n from,\n caveats,\n salt,\n scope,\n parentDelegation,\n };\n } else {\n createDelegationConfig = {\n environment,\n from,\n caveats,\n salt,\n scope,\n };\n }\n\n const rootDelegator =\n existingDelegations[existingDelegations.length - 1]?.delegator ?? from;\n\n return {\n account,\n createDelegationConfig,\n delegationManager,\n existingDelegations,\n rootDelegator,\n };\n};\n","import {\n createOpenDelegation,\n encodeDelegations,\n prepareSignDelegationTypedData,\n} from '../delegation';\nimport type {\n PaymentRequirements,\n x402DelegationProvider,\n x402DelegationProviderConfig,\n x402DelegationProviderPaymentPayload,\n} from './x402DelegationProviderTypes';\nimport {\n parseEip155ChainId,\n resolveDelegationCreationContext,\n} from './x402DelegationProviderUtils';\n\nexport type {\n MaybeDeferred,\n PaymentRequirements,\n x402DelegationProvider,\n x402DelegationProviderConfig,\n x402DelegationProviderPaymentPayload,\n} from './x402DelegationProviderTypes';\n\nexport { parseEip155ChainId } from './x402DelegationProviderUtils';\n\n/**\n * Creates a delegation provider function for x402 payment requirements.\n *\n * The returned provider resolves deferred config values using incoming payment\n * requirements, creates an open delegation, signs it, and returns an encoded\n * permission context payload.\n *\n * @param config - Delegation creation and signing configuration.\n * @returns A provider that maps payment requirements to a signed delegation payload.\n */\nexport function createx402DelegationProvider(\n config: x402DelegationProviderConfig,\n): x402DelegationProvider {\n return async (\n requirements: PaymentRequirements,\n ): Promise<x402DelegationProviderPaymentPayload> => {\n const {\n account,\n createDelegationConfig,\n delegationManager,\n existingDelegations,\n rootDelegator,\n } = await resolveDelegationCreationContext(config, requirements);\n\n const delegation = createOpenDelegation(createDelegationConfig);\n\n const chainId = parseEip155ChainId(requirements.network);\n\n const typedData = prepareSignDelegationTypedData({\n delegationManager,\n chainId,\n delegation,\n });\n\n if (!account.signTypedData) {\n throw new Error('Account does not support signTypedData');\n }\n\n const signature = await account.signTypedData(typedData);\n\n const signedDelegation = {\n ...delegation,\n signature,\n };\n\n const permissionContext = encodeDelegations([\n signedDelegation,\n ...existingDelegations,\n ]);\n\n return {\n delegationManager,\n permissionContext,\n delegator: rootDelegator,\n };\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,61 @@
1
+ import { j as ScopeType, B as Erc20PeriodTransferBuilderConfig, F as Erc20StreamingBuilderConfig, G as Erc20TransferAmountBuilderConfig, J as Erc721TransferBuilderConfig, K as AllowedCalldataBuilderConfig, L as ExactCalldataBuilderConfig, V as ValueLteBuilderConfig, N as AllowedTargetsBuilderConfig, O as AllowedMethodsBuilderConfig, Q as NativeTokenPeriodTransferBuilderConfig, R as NativeTokenStreamingBuilderConfig, U as NativeTokenTransferAmountBuilderConfig, X as OwnershipTransferBuilderConfig } from './resolveCaveats-A9xC29l8.cjs';
2
+
3
+ type Erc20PeriodicScopeConfig = {
4
+ type: ScopeType.Erc20PeriodTransfer;
5
+ } & Erc20PeriodTransferBuilderConfig;
6
+
7
+ type Erc20StreamingScopeConfig = {
8
+ type: ScopeType.Erc20Streaming;
9
+ } & Erc20StreamingBuilderConfig;
10
+
11
+ type Erc20TransferScopeConfig = {
12
+ type: ScopeType.Erc20TransferAmount;
13
+ } & Erc20TransferAmountBuilderConfig;
14
+
15
+ type Erc721ScopeBaseConfig = {
16
+ type: ScopeType.Erc721Transfer;
17
+ };
18
+ type Erc721ScopeConfig = Erc721ScopeBaseConfig & Erc721TransferBuilderConfig;
19
+
20
+ type FunctionCallScopeBaseConfig = {
21
+ type: ScopeType.FunctionCall;
22
+ allowedCalldata?: AllowedCalldataBuilderConfig[];
23
+ exactCalldata?: ExactCalldataBuilderConfig;
24
+ valueLte?: ValueLteBuilderConfig;
25
+ };
26
+ type FunctionCallScopeConfig = FunctionCallScopeBaseConfig & AllowedTargetsBuilderConfig & AllowedMethodsBuilderConfig;
27
+
28
+ type NativeTokenPeriodicScopeConfig = {
29
+ type: ScopeType.NativeTokenPeriodTransfer;
30
+ allowedCalldata?: AllowedCalldataBuilderConfig[];
31
+ exactCalldata?: ExactCalldataBuilderConfig;
32
+ } & NativeTokenPeriodTransferBuilderConfig;
33
+
34
+ type NativeTokenStreamingScopeConfig = {
35
+ type: ScopeType.NativeTokenStreaming;
36
+ allowedCalldata?: AllowedCalldataBuilderConfig[];
37
+ exactCalldata?: ExactCalldataBuilderConfig;
38
+ } & NativeTokenStreamingBuilderConfig;
39
+
40
+ type NativeTokenTransferScopeConfig = {
41
+ type: ScopeType.NativeTokenTransferAmount;
42
+ allowedCalldata?: AllowedCalldataBuilderConfig[];
43
+ exactCalldata?: ExactCalldataBuilderConfig;
44
+ } & NativeTokenTransferAmountBuilderConfig;
45
+
46
+ type OwnershipScopeBaseConfig = {
47
+ type: ScopeType.OwnershipTransfer;
48
+ };
49
+ type OwnershipScopeConfig = OwnershipScopeBaseConfig & OwnershipTransferBuilderConfig;
50
+
51
+ type ConvertScopeConfigsToInputs<T extends {
52
+ type: ScopeType;
53
+ }> = T extends {
54
+ type: ScopeType;
55
+ } ? Omit<T, 'type'> & {
56
+ type: T['type'] | `${T['type']}`;
57
+ } : never;
58
+ type ScopeConfigBase = Erc20TransferScopeConfig | Erc20StreamingScopeConfig | Erc20PeriodicScopeConfig | NativeTokenTransferScopeConfig | NativeTokenStreamingScopeConfig | NativeTokenPeriodicScopeConfig | Erc721ScopeConfig | OwnershipScopeConfig | FunctionCallScopeConfig;
59
+ type ScopeConfig = ConvertScopeConfigsToInputs<ScopeConfigBase>;
60
+
61
+ export type { ScopeConfig as S };