@metamask/delegation-core 0.3.0 → 1.0.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/dist/index.mjs CHANGED
@@ -1,35 +1,77 @@
1
+ // src/internalUtils.ts
2
+ import {
3
+ bytesToHex,
4
+ hexToBytes,
5
+ isHexString,
6
+ remove0x
7
+ } from "@metamask/utils";
8
+ var toHexString = ({
9
+ value,
10
+ size
11
+ }) => {
12
+ return value.toString(16).padStart(size * 2, "0");
13
+ };
14
+ var normalizeHex = (value, errorMessage) => {
15
+ if (typeof value === "string") {
16
+ if (!isHexString(value)) {
17
+ throw new Error(errorMessage);
18
+ }
19
+ return value;
20
+ }
21
+ return bytesToHex(value);
22
+ };
23
+ var normalizeAddress = (value, errorMessage) => {
24
+ if (typeof value === "string") {
25
+ if (!isHexString(value) || value.length !== 42) {
26
+ throw new Error(errorMessage);
27
+ }
28
+ return value;
29
+ }
30
+ if (value.length !== 20) {
31
+ throw new Error(errorMessage);
32
+ }
33
+ return bytesToHex(value);
34
+ };
35
+ var normalizeAddressLowercase = (value, errorMessage) => {
36
+ if (typeof value === "string") {
37
+ if (!isHexString(value) || value.length !== 42) {
38
+ throw new Error(errorMessage);
39
+ }
40
+ return bytesToHex(hexToBytes(value));
41
+ }
42
+ if (value.length !== 20) {
43
+ throw new Error(errorMessage);
44
+ }
45
+ return bytesToHex(value);
46
+ };
47
+ var concatHex = (parts) => {
48
+ return `0x${parts.map(remove0x).join("")}`;
49
+ };
50
+
1
51
  // src/returns.ts
2
- import { bytesToHex, hexToBytes } from "@metamask/utils";
52
+ import { bytesToHex as bytesToHex2, hexToBytes as hexToBytes2 } from "@metamask/utils";
3
53
  var defaultOptions = { out: "hex" };
4
54
  function prepareResult(result, options) {
5
55
  if (options.out === "hex") {
6
- const hexValue = typeof result === "string" ? result : bytesToHex(result);
56
+ const hexValue = typeof result === "string" ? result : bytesToHex2(result);
7
57
  return hexValue.startsWith("0x") ? hexValue : `0x${hexValue}`;
8
58
  }
9
- const bytesValue = result instanceof Uint8Array ? result : hexToBytes(result);
59
+ const bytesValue = result instanceof Uint8Array ? result : hexToBytes2(result);
10
60
  return bytesValue;
11
61
  }
12
62
  var bytesLikeToHex = (bytesLike) => {
13
63
  if (typeof bytesLike === "string") {
14
64
  return bytesLike;
15
65
  }
16
- return bytesToHex(bytesLike);
66
+ return bytesToHex2(bytesLike);
17
67
  };
18
68
  var bytesLikeToBytes = (bytesLike) => {
19
69
  if (typeof bytesLike === "string") {
20
- return hexToBytes(bytesLike);
70
+ return hexToBytes2(bytesLike);
21
71
  }
22
72
  return bytesLike;
23
73
  };
24
74
 
25
- // src/utils.ts
26
- var toHexString = ({
27
- value,
28
- size
29
- }) => {
30
- return value.toString(16).padStart(size * 2, "0");
31
- };
32
-
33
75
  // src/caveats/valueLte.ts
34
76
  function createValueLteTerms(terms, options = defaultOptions) {
35
77
  const { maxValue } = terms;
@@ -103,12 +145,110 @@ function createNativeTokenPeriodTransferTerms(terms, encodingOptions = defaultOp
103
145
  // src/caveats/exactCalldata.ts
104
146
  function createExactCalldataTerms(terms, encodingOptions = defaultOptions) {
105
147
  const { calldata } = terms;
148
+ if (calldata === void 0 || calldata === null) {
149
+ throw new Error("Invalid calldata: calldata is required");
150
+ }
106
151
  if (typeof calldata === "string" && !calldata.startsWith("0x")) {
107
152
  throw new Error("Invalid calldata: must be a hex string starting with 0x");
108
153
  }
109
154
  return prepareResult(calldata, encodingOptions);
110
155
  }
111
156
 
157
+ // src/caveats/exactCalldataBatch.ts
158
+ import { encodeSingle } from "@metamask/abi-utils";
159
+ import { bytesToHex as bytesToHex3 } from "@metamask/utils";
160
+ var EXECUTION_ARRAY_ABI = "(address,uint256,bytes)[]";
161
+ function createExactCalldataBatchTerms(terms, encodingOptions = defaultOptions) {
162
+ const { executions } = terms;
163
+ if (executions.length === 0) {
164
+ throw new Error("Invalid executions: array cannot be empty");
165
+ }
166
+ const encodableExecutions = executions.map((execution) => {
167
+ const targetHex = normalizeAddress(
168
+ execution.target,
169
+ "Invalid target: must be a valid address"
170
+ );
171
+ if (execution.value < 0n) {
172
+ throw new Error("Invalid value: must be a non-negative number");
173
+ }
174
+ let callDataHex;
175
+ if (typeof execution.callData === "string") {
176
+ if (!execution.callData.startsWith("0x")) {
177
+ throw new Error(
178
+ "Invalid calldata: must be a hex string starting with 0x"
179
+ );
180
+ }
181
+ callDataHex = execution.callData;
182
+ } else {
183
+ callDataHex = bytesToHex3(execution.callData);
184
+ }
185
+ return [targetHex, execution.value, callDataHex];
186
+ });
187
+ const hexValue = encodeSingle(EXECUTION_ARRAY_ABI, encodableExecutions);
188
+ return prepareResult(hexValue, encodingOptions);
189
+ }
190
+
191
+ // src/caveats/exactExecution.ts
192
+ import { bytesToHex as bytesToHex4 } from "@metamask/utils";
193
+ function createExactExecutionTerms(terms, encodingOptions = defaultOptions) {
194
+ const { execution } = terms;
195
+ const targetHex = normalizeAddress(
196
+ execution.target,
197
+ "Invalid target: must be a valid address"
198
+ );
199
+ if (execution.value < 0n) {
200
+ throw new Error("Invalid value: must be a non-negative number");
201
+ }
202
+ let callDataHex;
203
+ if (typeof execution.callData === "string") {
204
+ if (!execution.callData.startsWith("0x")) {
205
+ throw new Error(
206
+ "Invalid calldata: must be a hex string starting with 0x"
207
+ );
208
+ }
209
+ callDataHex = execution.callData;
210
+ } else {
211
+ callDataHex = bytesToHex4(execution.callData);
212
+ }
213
+ const valueHex = `0x${toHexString({ value: execution.value, size: 32 })}`;
214
+ const hexValue = concatHex([targetHex, valueHex, callDataHex]);
215
+ return prepareResult(hexValue, encodingOptions);
216
+ }
217
+
218
+ // src/caveats/exactExecutionBatch.ts
219
+ import { encodeSingle as encodeSingle2 } from "@metamask/abi-utils";
220
+ import { bytesToHex as bytesToHex5 } from "@metamask/utils";
221
+ var EXECUTION_ARRAY_ABI2 = "(address,uint256,bytes)[]";
222
+ function createExactExecutionBatchTerms(terms, encodingOptions = defaultOptions) {
223
+ const { executions } = terms;
224
+ if (executions.length === 0) {
225
+ throw new Error("Invalid executions: array cannot be empty");
226
+ }
227
+ const encodableExecutions = executions.map((execution) => {
228
+ const targetHex = normalizeAddress(
229
+ execution.target,
230
+ "Invalid target: must be a valid address"
231
+ );
232
+ if (execution.value < 0n) {
233
+ throw new Error("Invalid value: must be a non-negative number");
234
+ }
235
+ let callDataHex;
236
+ if (typeof execution.callData === "string") {
237
+ if (!execution.callData.startsWith("0x")) {
238
+ throw new Error(
239
+ "Invalid calldata: must be a hex string starting with 0x"
240
+ );
241
+ }
242
+ callDataHex = execution.callData;
243
+ } else {
244
+ callDataHex = bytesToHex5(execution.callData);
245
+ }
246
+ return [targetHex, execution.value, callDataHex];
247
+ });
248
+ const hexValue = encodeSingle2(EXECUTION_ARRAY_ABI2, encodableExecutions);
249
+ return prepareResult(hexValue, encodingOptions);
250
+ }
251
+
112
252
  // src/caveats/nativeTokenStreaming.ts
113
253
  var TIMESTAMP_UPPER_BOUND_SECONDS2 = 253402300799;
114
254
  function createNativeTokenStreamingTerms(terms, encodingOptions = defaultOptions) {
@@ -141,8 +281,53 @@ function createNativeTokenStreamingTerms(terms, encodingOptions = defaultOptions
141
281
  return prepareResult(hexValue, encodingOptions);
142
282
  }
143
283
 
284
+ // src/caveats/nativeTokenTransferAmount.ts
285
+ function createNativeTokenTransferAmountTerms(terms, encodingOptions = defaultOptions) {
286
+ const { maxAmount } = terms;
287
+ if (maxAmount < 0n) {
288
+ throw new Error("Invalid maxAmount: must be zero or positive");
289
+ }
290
+ const hexValue = `0x${toHexString({ value: maxAmount, size: 32 })}`;
291
+ return prepareResult(hexValue, encodingOptions);
292
+ }
293
+
294
+ // src/caveats/nativeTokenPayment.ts
295
+ function createNativeTokenPaymentTerms(terms, encodingOptions = defaultOptions) {
296
+ const { recipient, amount } = terms;
297
+ const recipientHex = normalizeAddressLowercase(
298
+ recipient,
299
+ "Invalid recipient: must be a valid address"
300
+ );
301
+ if (amount <= 0n) {
302
+ throw new Error("Invalid amount: must be positive");
303
+ }
304
+ const amountHex = `0x${toHexString({ value: amount, size: 32 })}`;
305
+ const hexValue = concatHex([recipientHex, amountHex]);
306
+ return prepareResult(hexValue, encodingOptions);
307
+ }
308
+
309
+ // src/caveats/nativeBalanceChange.ts
310
+ function createNativeBalanceChangeTerms(terms, encodingOptions = defaultOptions) {
311
+ const { recipient, balance, changeType: changeTypeNumber } = terms;
312
+ const recipientHex = normalizeAddressLowercase(
313
+ recipient,
314
+ "Invalid recipient: must be a valid Address"
315
+ );
316
+ if (balance <= 0n) {
317
+ throw new Error("Invalid balance: must be a positive number");
318
+ }
319
+ const changeType = changeTypeNumber;
320
+ if (changeType !== 0 /* Increase */ && changeType !== 1 /* Decrease */) {
321
+ throw new Error("Invalid changeType: must be either Increase or Decrease");
322
+ }
323
+ const changeTypeHex = `0x${toHexString({ value: changeType, size: 1 })}`;
324
+ const balanceHex = `0x${toHexString({ value: balance, size: 32 })}`;
325
+ const hexValue = concatHex([changeTypeHex, recipientHex, balanceHex]);
326
+ return prepareResult(hexValue, encodingOptions);
327
+ }
328
+
144
329
  // src/caveats/erc20Streaming.ts
145
- import { bytesToHex as bytesToHex2, isHexString } from "@metamask/utils";
330
+ import { bytesToHex as bytesToHex6, isHexString as isHexString2 } from "@metamask/utils";
146
331
  var TIMESTAMP_UPPER_BOUND_SECONDS3 = 253402300799;
147
332
  function createERC20StreamingTerms(terms, encodingOptions = defaultOptions) {
148
333
  const { tokenAddress, initialAmount, maxAmount, amountPerSecond, startTime } = terms;
@@ -151,7 +336,7 @@ function createERC20StreamingTerms(terms, encodingOptions = defaultOptions) {
151
336
  }
152
337
  let prefixedTokenAddressHex;
153
338
  if (typeof tokenAddress === "string") {
154
- if (!isHexString(tokenAddress) || tokenAddress.length !== 42) {
339
+ if (!isHexString2(tokenAddress) || tokenAddress.length !== 42) {
155
340
  throw new Error("Invalid tokenAddress: must be a valid address");
156
341
  }
157
342
  prefixedTokenAddressHex = tokenAddress;
@@ -159,7 +344,7 @@ function createERC20StreamingTerms(terms, encodingOptions = defaultOptions) {
159
344
  if (tokenAddress.length !== 20) {
160
345
  throw new Error("Invalid tokenAddress: must be a valid address");
161
346
  }
162
- prefixedTokenAddressHex = bytesToHex2(tokenAddress);
347
+ prefixedTokenAddressHex = bytesToHex6(tokenAddress);
163
348
  }
164
349
  if (initialAmount < 0n) {
165
350
  throw new Error("Invalid initialAmount: must be greater than zero");
@@ -190,7 +375,7 @@ function createERC20StreamingTerms(terms, encodingOptions = defaultOptions) {
190
375
  }
191
376
 
192
377
  // src/caveats/erc20TokenPeriodTransfer.ts
193
- import { isHexString as isHexString2, bytesToHex as bytesToHex3 } from "@metamask/utils";
378
+ import { isHexString as isHexString3, bytesToHex as bytesToHex7 } from "@metamask/utils";
194
379
  function createERC20TokenPeriodTransferTerms(terms, encodingOptions = defaultOptions) {
195
380
  const { tokenAddress, periodAmount, periodDuration, startDate } = terms;
196
381
  if (!tokenAddress) {
@@ -198,7 +383,7 @@ function createERC20TokenPeriodTransferTerms(terms, encodingOptions = defaultOpt
198
383
  }
199
384
  let prefixedTokenAddressHex;
200
385
  if (typeof tokenAddress === "string") {
201
- if (!isHexString2(tokenAddress) || tokenAddress.length !== 42) {
386
+ if (!isHexString3(tokenAddress) || tokenAddress.length !== 42) {
202
387
  throw new Error("Invalid tokenAddress: must be a valid address");
203
388
  }
204
389
  prefixedTokenAddressHex = tokenAddress;
@@ -206,7 +391,7 @@ function createERC20TokenPeriodTransferTerms(terms, encodingOptions = defaultOpt
206
391
  if (tokenAddress.length !== 20) {
207
392
  throw new Error("Invalid tokenAddress: must be a valid address");
208
393
  }
209
- prefixedTokenAddressHex = bytesToHex3(tokenAddress);
394
+ prefixedTokenAddressHex = bytesToHex7(tokenAddress);
210
395
  }
211
396
  if (periodAmount <= 0n) {
212
397
  throw new Error("Invalid periodAmount: must be a positive number");
@@ -224,8 +409,146 @@ function createERC20TokenPeriodTransferTerms(terms, encodingOptions = defaultOpt
224
409
  return prepareResult(hexValue, encodingOptions);
225
410
  }
226
411
 
412
+ // src/caveats/erc20TransferAmount.ts
413
+ function createERC20TransferAmountTerms(terms, encodingOptions = defaultOptions) {
414
+ const { tokenAddress, maxAmount } = terms;
415
+ const tokenAddressHex = normalizeAddress(
416
+ tokenAddress,
417
+ "Invalid tokenAddress: must be a valid address"
418
+ );
419
+ if (maxAmount <= 0n) {
420
+ throw new Error("Invalid maxAmount: must be a positive number");
421
+ }
422
+ const maxAmountHex = `0x${toHexString({ value: maxAmount, size: 32 })}`;
423
+ const hexValue = concatHex([tokenAddressHex, maxAmountHex]);
424
+ return prepareResult(hexValue, encodingOptions);
425
+ }
426
+
427
+ // src/caveats/erc20BalanceChange.ts
428
+ function createERC20BalanceChangeTerms(terms, encodingOptions = defaultOptions) {
429
+ const {
430
+ tokenAddress,
431
+ recipient,
432
+ balance,
433
+ changeType: changeTypeNumber
434
+ } = terms;
435
+ const tokenAddressHex = normalizeAddressLowercase(
436
+ tokenAddress,
437
+ "Invalid tokenAddress: must be a valid address"
438
+ );
439
+ const recipientHex = normalizeAddressLowercase(
440
+ recipient,
441
+ "Invalid recipient: must be a valid address"
442
+ );
443
+ if (balance <= 0n) {
444
+ throw new Error("Invalid balance: must be a positive number");
445
+ }
446
+ const changeType = changeTypeNumber;
447
+ if (changeType !== 0 /* Increase */ && changeType !== 1 /* Decrease */) {
448
+ throw new Error("Invalid changeType: must be either Increase or Decrease");
449
+ }
450
+ const changeTypeHex = `0x${toHexString({ value: changeType, size: 1 })}`;
451
+ const balanceHex = `0x${toHexString({ value: balance, size: 32 })}`;
452
+ const hexValue = concatHex([
453
+ changeTypeHex,
454
+ tokenAddressHex,
455
+ recipientHex,
456
+ balanceHex
457
+ ]);
458
+ return prepareResult(hexValue, encodingOptions);
459
+ }
460
+
461
+ // src/caveats/erc721BalanceChange.ts
462
+ function createERC721BalanceChangeTerms(terms, encodingOptions = defaultOptions) {
463
+ const {
464
+ tokenAddress,
465
+ recipient,
466
+ amount,
467
+ changeType: changeTypeNumber
468
+ } = terms;
469
+ const tokenAddressHex = normalizeAddressLowercase(
470
+ tokenAddress,
471
+ "Invalid tokenAddress: must be a valid address"
472
+ );
473
+ const recipientHex = normalizeAddressLowercase(
474
+ recipient,
475
+ "Invalid recipient: must be a valid address"
476
+ );
477
+ if (amount <= 0n) {
478
+ throw new Error("Invalid balance: must be a positive number");
479
+ }
480
+ const changeType = changeTypeNumber;
481
+ if (changeType !== 0 /* Increase */ && changeType !== 1 /* Decrease */) {
482
+ throw new Error("Invalid changeType: must be either Increase or Decrease");
483
+ }
484
+ const changeTypeHex = `0x${toHexString({ value: changeType, size: 1 })}`;
485
+ const amountHex = `0x${toHexString({ value: amount, size: 32 })}`;
486
+ const hexValue = concatHex([
487
+ changeTypeHex,
488
+ tokenAddressHex,
489
+ recipientHex,
490
+ amountHex
491
+ ]);
492
+ return prepareResult(hexValue, encodingOptions);
493
+ }
494
+
495
+ // src/caveats/erc721Transfer.ts
496
+ function createERC721TransferTerms(terms, encodingOptions = defaultOptions) {
497
+ const { tokenAddress, tokenId } = terms;
498
+ const tokenAddressHex = normalizeAddress(
499
+ tokenAddress,
500
+ "Invalid tokenAddress: must be a valid address"
501
+ );
502
+ if (tokenId < 0n) {
503
+ throw new Error("Invalid tokenId: must be a non-negative number");
504
+ }
505
+ const tokenIdHex = `0x${toHexString({ value: tokenId, size: 32 })}`;
506
+ const hexValue = concatHex([tokenAddressHex, tokenIdHex]);
507
+ return prepareResult(hexValue, encodingOptions);
508
+ }
509
+
510
+ // src/caveats/erc1155BalanceChange.ts
511
+ function createERC1155BalanceChangeTerms(terms, encodingOptions = defaultOptions) {
512
+ const {
513
+ tokenAddress,
514
+ recipient,
515
+ tokenId,
516
+ balance,
517
+ changeType: changeTypeNumber
518
+ } = terms;
519
+ const tokenAddressHex = normalizeAddressLowercase(
520
+ tokenAddress,
521
+ "Invalid tokenAddress: must be a valid address"
522
+ );
523
+ const recipientHex = normalizeAddressLowercase(
524
+ recipient,
525
+ "Invalid recipient: must be a valid address"
526
+ );
527
+ if (balance <= 0n) {
528
+ throw new Error("Invalid balance: must be a positive number");
529
+ }
530
+ if (tokenId < 0n) {
531
+ throw new Error("Invalid tokenId: must be a non-negative number");
532
+ }
533
+ const changeType = changeTypeNumber;
534
+ if (changeType !== 0 /* Increase */ && changeType !== 1 /* Decrease */) {
535
+ throw new Error("Invalid changeType: must be either Increase or Decrease");
536
+ }
537
+ const changeTypeHex = `0x${toHexString({ value: changeType, size: 1 })}`;
538
+ const tokenIdHex = `0x${toHexString({ value: tokenId, size: 32 })}`;
539
+ const balanceHex = `0x${toHexString({ value: balance, size: 32 })}`;
540
+ const hexValue = concatHex([
541
+ changeTypeHex,
542
+ tokenAddressHex,
543
+ recipientHex,
544
+ tokenIdHex,
545
+ balanceHex
546
+ ]);
547
+ return prepareResult(hexValue, encodingOptions);
548
+ }
549
+
227
550
  // src/caveats/nonce.ts
228
- import { isHexString as isHexString3 } from "@metamask/utils";
551
+ import { isHexString as isHexString4 } from "@metamask/utils";
229
552
  var MAX_NONCE_STRING_LENGTH = 66;
230
553
  function createNonceTerms(terms, encodingOptions = defaultOptions) {
231
554
  const { nonce } = terms;
@@ -239,7 +562,7 @@ function createNonceTerms(terms, encodingOptions = defaultOptions) {
239
562
  if (hexNonce === "0x") {
240
563
  throw new Error("Invalid nonce: must not be empty");
241
564
  }
242
- if (!isHexString3(hexNonce)) {
565
+ if (!isHexString4(hexNonce)) {
243
566
  throw new Error("Invalid nonce: must be a valid BytesLike value");
244
567
  }
245
568
  if (hexNonce.length > MAX_NONCE_STRING_LENGTH) {
@@ -252,7 +575,7 @@ function createNonceTerms(terms, encodingOptions = defaultOptions) {
252
575
  }
253
576
 
254
577
  // src/caveats/allowedCalldata.ts
255
- import { bytesToHex as bytesToHex4, remove0x } from "@metamask/utils";
578
+ import { bytesToHex as bytesToHex8, remove0x as remove0x2 } from "@metamask/utils";
256
579
  function createAllowedCalldataTerms(terms, encodingOptions = defaultOptions) {
257
580
  const { startIndex, value } = terms;
258
581
  if (startIndex < 0) {
@@ -266,23 +589,262 @@ function createAllowedCalldataTerms(terms, encodingOptions = defaultOptions) {
266
589
  if (!value.startsWith("0x")) {
267
590
  throw new Error("Invalid value: must be a hex string starting with 0x");
268
591
  }
269
- unprefixedValue = remove0x(value);
592
+ unprefixedValue = remove0x2(value);
270
593
  } else {
271
- unprefixedValue = remove0x(bytesToHex4(value));
594
+ unprefixedValue = remove0x2(bytesToHex8(value));
272
595
  }
273
596
  const indexHex = toHexString({ value: startIndex, size: 32 });
274
597
  return prepareResult(`0x${indexHex}${unprefixedValue}`, encodingOptions);
275
598
  }
276
599
 
600
+ // src/caveats/allowedMethods.ts
601
+ import { bytesToHex as bytesToHex9, isHexString as isHexString5 } from "@metamask/utils";
602
+ var FUNCTION_SELECTOR_STRING_LENGTH = 10;
603
+ var INVALID_SELECTOR_ERROR = "Invalid selector: must be a 4 byte hex string, abi function signature, or AbiFunction";
604
+ function createAllowedMethodsTerms(terms, encodingOptions = defaultOptions) {
605
+ const { selectors } = terms;
606
+ if (!selectors || selectors.length === 0) {
607
+ throw new Error("Invalid selectors: must provide at least one selector");
608
+ }
609
+ const normalizedSelectors = selectors.map((selector) => {
610
+ if (typeof selector === "string") {
611
+ if (isHexString5(selector) && selector.length === FUNCTION_SELECTOR_STRING_LENGTH) {
612
+ return selector;
613
+ }
614
+ throw new Error(INVALID_SELECTOR_ERROR);
615
+ }
616
+ if (selector.length !== 4) {
617
+ throw new Error(INVALID_SELECTOR_ERROR);
618
+ }
619
+ return bytesToHex9(selector);
620
+ });
621
+ const hexValue = concatHex(normalizedSelectors);
622
+ return prepareResult(hexValue, encodingOptions);
623
+ }
624
+
625
+ // src/caveats/allowedTargets.ts
626
+ function createAllowedTargetsTerms(terms, encodingOptions = defaultOptions) {
627
+ const { targets } = terms;
628
+ if (!targets || targets.length === 0) {
629
+ throw new Error(
630
+ "Invalid targets: must provide at least one target address"
631
+ );
632
+ }
633
+ const normalizedTargets = targets.map(
634
+ (target) => normalizeAddress(target, "Invalid targets: must be valid addresses")
635
+ );
636
+ const hexValue = concatHex(normalizedTargets);
637
+ return prepareResult(hexValue, encodingOptions);
638
+ }
639
+
640
+ // src/caveats/argsEqualityCheck.ts
641
+ function createArgsEqualityCheckTerms(terms, encodingOptions = defaultOptions) {
642
+ const { args } = terms;
643
+ if (typeof args === "string" && args === "0x") {
644
+ return prepareResult(args, encodingOptions);
645
+ }
646
+ const hexValue = normalizeHex(
647
+ args,
648
+ "Invalid config: args must be a valid hex string"
649
+ );
650
+ return prepareResult(hexValue, encodingOptions);
651
+ }
652
+
653
+ // src/caveats/blockNumber.ts
654
+ function createBlockNumberTerms(terms, encodingOptions = defaultOptions) {
655
+ const { afterThreshold, beforeThreshold } = terms;
656
+ if (afterThreshold < 0n || beforeThreshold < 0n) {
657
+ throw new Error("Invalid thresholds: block numbers must be non-negative");
658
+ }
659
+ if (afterThreshold === 0n && beforeThreshold === 0n) {
660
+ throw new Error(
661
+ "Invalid thresholds: At least one of afterThreshold or beforeThreshold must be specified"
662
+ );
663
+ }
664
+ if (beforeThreshold !== 0n && afterThreshold >= beforeThreshold) {
665
+ throw new Error(
666
+ "Invalid thresholds: afterThreshold must be less than beforeThreshold if both are specified"
667
+ );
668
+ }
669
+ const afterThresholdHex = toHexString({ value: afterThreshold, size: 16 });
670
+ const beforeThresholdHex = toHexString({ value: beforeThreshold, size: 16 });
671
+ const hexValue = `0x${afterThresholdHex}${beforeThresholdHex}`;
672
+ return prepareResult(hexValue, encodingOptions);
673
+ }
674
+
675
+ // src/caveats/deployed.ts
676
+ import { remove0x as remove0x3 } from "@metamask/utils";
677
+ function createDeployedTerms(terms, encodingOptions = defaultOptions) {
678
+ const { contractAddress, salt, bytecode } = terms;
679
+ const contractAddressHex = normalizeAddress(
680
+ contractAddress,
681
+ "Invalid contractAddress: must be a valid Ethereum address"
682
+ );
683
+ const saltHex = normalizeHex(
684
+ salt,
685
+ "Invalid salt: must be a valid hexadecimal string"
686
+ );
687
+ const bytecodeHex = normalizeHex(
688
+ bytecode,
689
+ "Invalid bytecode: must be a valid hexadecimal string"
690
+ );
691
+ const unprefixedSalt = remove0x3(saltHex);
692
+ if (unprefixedSalt.length > 64) {
693
+ throw new Error("Invalid salt: must be a valid hexadecimal string");
694
+ }
695
+ const paddedSalt = `0x${unprefixedSalt.padStart(64, "0")}`;
696
+ const hexValue = concatHex([contractAddressHex, paddedSalt, bytecodeHex]);
697
+ return prepareResult(hexValue, encodingOptions);
698
+ }
699
+
700
+ // src/caveats/id.ts
701
+ var MAX_UINT256 = BigInt(`0x${"f".repeat(64)}`);
702
+ function createIdTerms(terms, encodingOptions = defaultOptions) {
703
+ const { id } = terms;
704
+ let idBigInt;
705
+ if (typeof id === "number") {
706
+ if (!Number.isInteger(id)) {
707
+ throw new Error("Invalid id: must be an integer");
708
+ }
709
+ idBigInt = BigInt(id);
710
+ } else if (typeof id === "bigint") {
711
+ idBigInt = id;
712
+ } else {
713
+ throw new Error("Invalid id: must be a bigint or number");
714
+ }
715
+ if (idBigInt < 0n) {
716
+ throw new Error("Invalid id: must be a non-negative number");
717
+ }
718
+ if (idBigInt > MAX_UINT256) {
719
+ throw new Error("Invalid id: must be less than 2^256");
720
+ }
721
+ const hexValue = `0x${toHexString({ value: idBigInt, size: 32 })}`;
722
+ return prepareResult(hexValue, encodingOptions);
723
+ }
724
+
725
+ // src/caveats/limitedCalls.ts
726
+ function createLimitedCallsTerms(terms, encodingOptions = defaultOptions) {
727
+ const { limit } = terms;
728
+ if (!Number.isInteger(limit)) {
729
+ throw new Error("Invalid limit: must be an integer");
730
+ }
731
+ if (limit <= 0) {
732
+ throw new Error("Invalid limit: must be a positive integer");
733
+ }
734
+ const hexValue = `0x${toHexString({ value: limit, size: 32 })}`;
735
+ return prepareResult(hexValue, encodingOptions);
736
+ }
737
+
738
+ // src/caveats/multiTokenPeriod.ts
739
+ function createMultiTokenPeriodTerms(terms, encodingOptions = defaultOptions) {
740
+ const { tokenConfigs } = terms;
741
+ if (!tokenConfigs || tokenConfigs.length === 0) {
742
+ throw new Error(
743
+ "MultiTokenPeriodBuilder: tokenConfigs array cannot be empty"
744
+ );
745
+ }
746
+ const hexParts = [];
747
+ for (const tokenConfig of tokenConfigs) {
748
+ const tokenHex = normalizeAddress(
749
+ tokenConfig.token,
750
+ `Invalid token address: ${String(tokenConfig.token)}`
751
+ );
752
+ if (tokenConfig.periodAmount <= 0n) {
753
+ throw new Error("Invalid period amount: must be greater than 0");
754
+ }
755
+ if (tokenConfig.periodDuration <= 0) {
756
+ throw new Error("Invalid period duration: must be greater than 0");
757
+ }
758
+ if (tokenConfig.startDate <= 0) {
759
+ throw new Error("Invalid start date: must be greater than 0");
760
+ }
761
+ hexParts.push(
762
+ tokenHex,
763
+ `0x${toHexString({ value: tokenConfig.periodAmount, size: 32 })}`,
764
+ `0x${toHexString({ value: tokenConfig.periodDuration, size: 32 })}`,
765
+ `0x${toHexString({ value: tokenConfig.startDate, size: 32 })}`
766
+ );
767
+ }
768
+ const hexValue = concatHex(hexParts);
769
+ return prepareResult(hexValue, encodingOptions);
770
+ }
771
+
772
+ // src/caveats/ownershipTransfer.ts
773
+ function createOwnershipTransferTerms(terms, encodingOptions = defaultOptions) {
774
+ const { contractAddress } = terms;
775
+ const contractAddressHex = normalizeAddress(
776
+ contractAddress,
777
+ "Invalid contractAddress: must be a valid address"
778
+ );
779
+ return prepareResult(contractAddressHex, encodingOptions);
780
+ }
781
+
782
+ // src/caveats/redeemer.ts
783
+ function createRedeemerTerms(terms, encodingOptions = defaultOptions) {
784
+ const { redeemers } = terms;
785
+ if (!redeemers || redeemers.length === 0) {
786
+ throw new Error(
787
+ "Invalid redeemers: must specify at least one redeemer address"
788
+ );
789
+ }
790
+ const normalizedRedeemers = redeemers.map(
791
+ (redeemer) => normalizeAddress(redeemer, "Invalid redeemers: must be a valid address")
792
+ );
793
+ const hexValue = concatHex(normalizedRedeemers);
794
+ return prepareResult(hexValue, encodingOptions);
795
+ }
796
+
797
+ // src/caveats/specificActionERC20TransferBatch.ts
798
+ import { bytesToHex as bytesToHex10 } from "@metamask/utils";
799
+ function createSpecificActionERC20TransferBatchTerms(terms, encodingOptions = defaultOptions) {
800
+ const { tokenAddress, recipient, amount, target, calldata } = terms;
801
+ const tokenAddressHex = normalizeAddress(
802
+ tokenAddress,
803
+ "Invalid tokenAddress: must be a valid address"
804
+ );
805
+ const recipientHex = normalizeAddress(
806
+ recipient,
807
+ "Invalid recipient: must be a valid address"
808
+ );
809
+ const targetHex = normalizeAddress(
810
+ target,
811
+ "Invalid target: must be a valid address"
812
+ );
813
+ let calldataHex;
814
+ if (typeof calldata === "string") {
815
+ if (!calldata.startsWith("0x")) {
816
+ throw new Error(
817
+ "Invalid calldata: must be a hex string starting with 0x"
818
+ );
819
+ }
820
+ calldataHex = calldata;
821
+ } else {
822
+ calldataHex = bytesToHex10(calldata);
823
+ }
824
+ if (amount <= 0n) {
825
+ throw new Error("Invalid amount: must be a positive number");
826
+ }
827
+ const amountHex = `0x${toHexString({ value: amount, size: 32 })}`;
828
+ const hexValue = concatHex([
829
+ tokenAddressHex,
830
+ recipientHex,
831
+ amountHex,
832
+ targetHex,
833
+ calldataHex
834
+ ]);
835
+ return prepareResult(hexValue, encodingOptions);
836
+ }
837
+
277
838
  // src/delegation.ts
278
- import { encode, encodeSingle, decodeSingle } from "@metamask/abi-utils";
279
- import { hexToBytes as hexToBytes2 } from "@metamask/utils";
839
+ import { encode, encodeSingle as encodeSingle3, decodeSingle } from "@metamask/abi-utils";
840
+ import { hexToBytes as hexToBytes3 } from "@metamask/utils";
280
841
  import { keccak_256 as keccak256 } from "@noble/hashes/sha3";
281
842
  var ANY_BENEFICIARY = "0x0000000000000000000000000000000000000a11";
282
843
  var ROOT_AUTHORITY = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
283
844
  var DELEGATION_TYPEHASH = "0x88c1d2ecf185adf710588203a5f263f0ff61be0d33da39792cde19ba9aa4331e";
284
845
  var CAVEAT_TYPEHASH = "0x80ad7e1b04ee6d994a125f4714ca0720908bd80ed16063ec8aee4b88e9253e2d";
285
846
  var DELEGATION_ARRAY_ABI_TYPES = "(address,address,bytes32,(address,bytes,bytes)[],uint256,bytes)[]";
847
+ var DELEGATION_ABI_TYPE = "(address,address,bytes32,(address,bytes,bytes)[],uint256,bytes)";
286
848
  function encodeDelegations(delegations, options = defaultOptions) {
287
849
  let result;
288
850
  if (delegations.length === 0) {
@@ -301,10 +863,26 @@ function encodeDelegations(delegations, options = defaultOptions) {
301
863
  struct.salt,
302
864
  struct.signature
303
865
  ]);
304
- result = encodeSingle(DELEGATION_ARRAY_ABI_TYPES, encodableStructs);
866
+ result = encodeSingle3(DELEGATION_ARRAY_ABI_TYPES, encodableStructs);
305
867
  }
306
868
  return prepareResult(result, options);
307
869
  }
870
+ function encodeDelegation(delegation, options = defaultOptions) {
871
+ const encodableStruct = [
872
+ delegation.delegate,
873
+ delegation.delegator,
874
+ delegation.authority,
875
+ delegation.caveats.map((caveat) => [
876
+ caveat.enforcer,
877
+ caveat.terms,
878
+ caveat.args
879
+ ]),
880
+ delegation.salt,
881
+ delegation.signature
882
+ ];
883
+ const result = encodeSingle3(DELEGATION_ABI_TYPE, encodableStruct);
884
+ return prepareResult(result, options);
885
+ }
308
886
  var delegationFromDecodedDelegation = (decodedDelegation, convertFn) => {
309
887
  const [delegate, delegator, authority, caveats, salt, signature] = decodedDelegation;
310
888
  return {
@@ -335,6 +913,17 @@ function decodeDelegations(encoded, options = defaultOptions) {
335
913
  (struct) => delegationFromDecodedDelegation(struct, bytesLikeToHex)
336
914
  );
337
915
  }
916
+ function decodeDelegation(encoded, options = defaultOptions) {
917
+ const decodedStruct = decodeSingle(
918
+ DELEGATION_ABI_TYPE,
919
+ encoded
920
+ // return types cannot be inferred from complex ABI types, so we must assert the type
921
+ );
922
+ if (options.out === "bytes") {
923
+ return delegationFromDecodedDelegation(decodedStruct, bytesLikeToBytes);
924
+ }
925
+ return delegationFromDecodedDelegation(decodedStruct, bytesLikeToHex);
926
+ }
338
927
  function hashDelegation(delegation, options = defaultOptions) {
339
928
  const encoded = encode(
340
929
  ["bytes32", "address", "address", "bytes32", "bytes32", "uint256"],
@@ -364,7 +953,7 @@ function getCaveatsArrayHash(caveats) {
364
953
  return keccak256(encoded);
365
954
  }
366
955
  function getCaveatHash(caveat) {
367
- const termsBytes = typeof caveat.terms === "string" ? hexToBytes2(caveat.terms) : caveat.terms;
956
+ const termsBytes = typeof caveat.terms === "string" ? hexToBytes3(caveat.terms) : caveat.terms;
368
957
  const termsHash = keccak256(termsBytes);
369
958
  const encoded = encode(
370
959
  ["bytes32", "address", "bytes32"],
@@ -379,15 +968,39 @@ export {
379
968
  DELEGATION_TYPEHASH,
380
969
  ROOT_AUTHORITY,
381
970
  createAllowedCalldataTerms,
971
+ createAllowedMethodsTerms,
972
+ createAllowedTargetsTerms,
973
+ createArgsEqualityCheckTerms,
974
+ createBlockNumberTerms,
975
+ createDeployedTerms,
976
+ createERC1155BalanceChangeTerms,
977
+ createERC20BalanceChangeTerms,
382
978
  createERC20StreamingTerms,
383
979
  createERC20TokenPeriodTransferTerms,
980
+ createERC20TransferAmountTerms,
981
+ createERC721BalanceChangeTerms,
982
+ createERC721TransferTerms,
983
+ createExactCalldataBatchTerms,
384
984
  createExactCalldataTerms,
985
+ createExactExecutionBatchTerms,
986
+ createExactExecutionTerms,
987
+ createIdTerms,
988
+ createLimitedCallsTerms,
989
+ createMultiTokenPeriodTerms,
990
+ createNativeBalanceChangeTerms,
991
+ createNativeTokenPaymentTerms,
385
992
  createNativeTokenPeriodTransferTerms,
386
993
  createNativeTokenStreamingTerms,
994
+ createNativeTokenTransferAmountTerms,
387
995
  createNonceTerms,
996
+ createOwnershipTransferTerms,
997
+ createRedeemerTerms,
998
+ createSpecificActionERC20TransferBatchTerms,
388
999
  createTimestampTerms,
389
1000
  createValueLteTerms,
1001
+ decodeDelegation,
390
1002
  decodeDelegations,
1003
+ encodeDelegation,
391
1004
  encodeDelegations,
392
1005
  hashDelegation
393
1006
  };