@account-kit/smart-contracts 4.24.0 → 4.25.1
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/esm/src/ma-v2/account/common/modularAccountV2Base.js +4 -8
- package/dist/esm/src/ma-v2/account/common/modularAccountV2Base.js.map +1 -1
- package/dist/esm/src/ma-v2/actions/deferralActions.d.ts +0 -5
- package/dist/esm/src/ma-v2/actions/deferralActions.js +0 -20
- package/dist/esm/src/ma-v2/actions/deferralActions.js.map +1 -1
- package/dist/esm/src/ma-v2/index.d.ts +2 -1
- package/dist/esm/src/ma-v2/index.js +2 -1
- package/dist/esm/src/ma-v2/index.js.map +1 -1
- package/dist/esm/src/ma-v2/permissionBuilder.d.ts +7 -8
- package/dist/esm/src/ma-v2/permissionBuilder.js +43 -34
- package/dist/esm/src/ma-v2/permissionBuilder.js.map +1 -1
- package/dist/esm/src/ma-v2/permissionBuilderErrors.d.ts +99 -0
- package/dist/esm/src/ma-v2/permissionBuilderErrors.js +176 -0
- package/dist/esm/src/ma-v2/permissionBuilderErrors.js.map +1 -0
- package/dist/esm/src/ma-v2/utils.d.ts +20 -0
- package/dist/esm/src/ma-v2/utils.js +28 -1
- package/dist/esm/src/ma-v2/utils.js.map +1 -1
- package/dist/types/src/ma-v2/account/common/modularAccountV2Base.d.ts.map +1 -1
- package/dist/types/src/ma-v2/actions/deferralActions.d.ts +0 -5
- package/dist/types/src/ma-v2/actions/deferralActions.d.ts.map +1 -1
- package/dist/types/src/ma-v2/index.d.ts +2 -1
- package/dist/types/src/ma-v2/index.d.ts.map +1 -1
- package/dist/types/src/ma-v2/permissionBuilder.d.ts +7 -8
- package/dist/types/src/ma-v2/permissionBuilder.d.ts.map +1 -1
- package/dist/types/src/ma-v2/permissionBuilderErrors.d.ts +100 -0
- package/dist/types/src/ma-v2/permissionBuilderErrors.d.ts.map +1 -0
- package/dist/types/src/ma-v2/utils.d.ts +20 -0
- package/dist/types/src/ma-v2/utils.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/ma-v2/account/common/modularAccountV2Base.ts +4 -8
- package/src/ma-v2/actions/deferralActions.ts +0 -31
- package/src/ma-v2/index.ts +2 -1
- package/src/ma-v2/permissionBuilder.ts +58 -78
- package/src/ma-v2/permissionBuilderErrors.ts +153 -0
- package/src/ma-v2/utils.ts +45 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { toHex, zeroAddress, type Address, type Hex } from "viem";
|
|
1
|
+
import { maxUint48, toHex, zeroAddress, type Address, type Hex } from "viem";
|
|
2
2
|
import {
|
|
3
3
|
HookType,
|
|
4
4
|
type HookConfig,
|
|
@@ -23,6 +23,19 @@ import {
|
|
|
23
23
|
import { SingleSignerValidationModule } from "./modules/single-signer-validation/module.js";
|
|
24
24
|
import { AllowlistModule } from "./modules/allowlist-module/module.js";
|
|
25
25
|
import { TimeRangeModule } from "./modules/time-range-module/module.js";
|
|
26
|
+
import {
|
|
27
|
+
AccountAddressAsTargetError,
|
|
28
|
+
DeadlineOverLimitError,
|
|
29
|
+
DuplicateTargetAddressError,
|
|
30
|
+
ExpiredDeadlineError,
|
|
31
|
+
MultipleGasLimitError,
|
|
32
|
+
MultipleNativeTokenTransferError,
|
|
33
|
+
NoFunctionsProvidedError,
|
|
34
|
+
RootPermissionOnlyError,
|
|
35
|
+
UnsupportedPermissionTypeError,
|
|
36
|
+
ValidationConfigUnsetError,
|
|
37
|
+
ZeroAddressError,
|
|
38
|
+
} from "./permissionBuilderErrors.js";
|
|
26
39
|
|
|
27
40
|
// We use this to offset the ERC20 spend limit entityId
|
|
28
41
|
const HALF_UINT32 = 2147483647;
|
|
@@ -209,25 +222,26 @@ export class PermissionBuilder {
|
|
|
209
222
|
private hooks: Hook[] = [];
|
|
210
223
|
private nonce: bigint = 0n;
|
|
211
224
|
private hasAssociatedExecHooks: boolean = false;
|
|
225
|
+
private deadline: number = 0;
|
|
212
226
|
|
|
213
|
-
constructor(
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// Configures the builder
|
|
218
|
-
configure({
|
|
227
|
+
constructor({
|
|
228
|
+
client,
|
|
219
229
|
key,
|
|
220
230
|
entityId,
|
|
221
231
|
nonce,
|
|
222
232
|
selectors,
|
|
223
233
|
hooks,
|
|
234
|
+
deadline,
|
|
224
235
|
}: {
|
|
236
|
+
client: ModularAccountV2Client;
|
|
225
237
|
key: Key;
|
|
226
238
|
entityId: number;
|
|
227
239
|
nonce: bigint;
|
|
228
240
|
selectors?: Hex[];
|
|
229
241
|
hooks?: Hook[];
|
|
230
|
-
|
|
242
|
+
deadline?: number;
|
|
243
|
+
}) {
|
|
244
|
+
this.client = client;
|
|
231
245
|
this.validationConfig = {
|
|
232
246
|
moduleAddress: getDefaultSingleSignerValidationModuleAddress(
|
|
233
247
|
this.client.chain
|
|
@@ -241,10 +255,10 @@ export class PermissionBuilder {
|
|
|
241
255
|
entityId: entityId,
|
|
242
256
|
signer: key.publicKey,
|
|
243
257
|
});
|
|
258
|
+
this.nonce = nonce;
|
|
244
259
|
if (selectors) this.selectors = selectors;
|
|
245
260
|
if (hooks) this.hooks = hooks;
|
|
246
|
-
this.
|
|
247
|
-
return this;
|
|
261
|
+
if (deadline) this.deadline = deadline;
|
|
248
262
|
}
|
|
249
263
|
|
|
250
264
|
addSelector({ selector }: { selector: Hex }): this {
|
|
@@ -256,9 +270,7 @@ export class PermissionBuilder {
|
|
|
256
270
|
// Check 1: If we're adding root, we can't have any other permissions
|
|
257
271
|
if (permission.type === PermissionType.ROOT) {
|
|
258
272
|
if (this.permissions.length !== 0) {
|
|
259
|
-
throw new
|
|
260
|
-
"PERMISSION: ROOT: Cannot add ROOT permission with other permissions"
|
|
261
|
-
);
|
|
273
|
+
throw new RootPermissionOnlyError(permission);
|
|
262
274
|
}
|
|
263
275
|
this.permissions.push(permission);
|
|
264
276
|
// Set isGlobal to true
|
|
@@ -271,9 +283,7 @@ export class PermissionBuilder {
|
|
|
271
283
|
// NOTE: Technically this could be replaced by checking permissions[0] since it should not be possible
|
|
272
284
|
// to have >1 permission with root among them
|
|
273
285
|
if (this.permissions.find((p) => p.type === PermissionType.ROOT)) {
|
|
274
|
-
throw new
|
|
275
|
-
`PERMISSION: ${permission.type} => Cannot add permissions with ROOT enabled`
|
|
276
|
-
);
|
|
286
|
+
throw new RootPermissionOnlyError(permission);
|
|
277
287
|
}
|
|
278
288
|
|
|
279
289
|
// Check 3: If the permission is either CONTRACT_ACCESS or FUNCTIONS_ON_CONTRACT, ensure it doesn't collide with another like it.
|
|
@@ -283,9 +293,7 @@ export class PermissionBuilder {
|
|
|
283
293
|
) {
|
|
284
294
|
// Check 3.1: address must not be the account address, or the user should use the ACCOUNT_FUNCTIONS permission
|
|
285
295
|
if (permission.data.address === this.client.account.address) {
|
|
286
|
-
throw new
|
|
287
|
-
`PERMISSION: ${permission.type} => Account address as target, use ACCOUNT_FUNCTIONS for account address`
|
|
288
|
-
);
|
|
296
|
+
throw new AccountAddressAsTargetError(permission);
|
|
289
297
|
}
|
|
290
298
|
|
|
291
299
|
// Check 3.2: there must not be an existing permission with this address as a target
|
|
@@ -301,20 +309,19 @@ export class PermissionBuilder {
|
|
|
301
309
|
);
|
|
302
310
|
|
|
303
311
|
if (existingPermissionWithSameAddress) {
|
|
304
|
-
throw new
|
|
305
|
-
`PERMISSION: ${permission.type} => Address ${targetAddress} already has a permission. Cannot add multiple CONTRACT_ACCESS or FUNCTIONS_ON_CONTRACT permissions for the same target address.`
|
|
306
|
-
);
|
|
312
|
+
throw new DuplicateTargetAddressError(permission, targetAddress);
|
|
307
313
|
}
|
|
308
314
|
}
|
|
309
315
|
|
|
310
316
|
// Check 4: If the permission is ACCOUNT_FUNCTIONS, add selectors
|
|
311
317
|
if (permission.type === PermissionType.ACCOUNT_FUNCTIONS) {
|
|
318
|
+
if (permission.data.functions.length === 0) {
|
|
319
|
+
throw new NoFunctionsProvidedError(permission);
|
|
320
|
+
}
|
|
312
321
|
this.selectors = [...this.selectors, ...permission.data.functions];
|
|
313
|
-
return this;
|
|
314
322
|
}
|
|
315
323
|
|
|
316
324
|
this.permissions.push(permission);
|
|
317
|
-
|
|
318
325
|
return this;
|
|
319
326
|
}
|
|
320
327
|
|
|
@@ -328,33 +335,24 @@ export class PermissionBuilder {
|
|
|
328
335
|
}
|
|
329
336
|
|
|
330
337
|
// Use for building deferred action typed data to sign
|
|
331
|
-
async compileDeferred({
|
|
332
|
-
deadline,
|
|
333
|
-
}: {
|
|
334
|
-
deadline: number;
|
|
335
|
-
uoValidationEntityId: number;
|
|
336
|
-
uoIsGlobalValidation: boolean;
|
|
337
|
-
}): Promise<{
|
|
338
|
+
async compileDeferred(): Promise<{
|
|
338
339
|
typedData: DeferredActionTypedData;
|
|
339
340
|
fullPreSignatureDeferredActionDigest: Hex;
|
|
340
341
|
}> {
|
|
341
|
-
// Need to remove this because compileRaw may add selectors
|
|
342
|
-
// this.validateConfiguration();
|
|
343
|
-
|
|
344
342
|
// Add time range module hook via expiry
|
|
345
|
-
if (deadline !== 0) {
|
|
346
|
-
if (deadline < Date.now() / 1000) {
|
|
347
|
-
throw new
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
);
|
|
343
|
+
if (this.deadline !== 0) {
|
|
344
|
+
if (this.deadline < Date.now() / 1000) {
|
|
345
|
+
throw new ExpiredDeadlineError(this.deadline, Date.now() / 1000);
|
|
346
|
+
}
|
|
347
|
+
if (this.deadline > maxUint48) {
|
|
348
|
+
throw new DeadlineOverLimitError(this.deadline);
|
|
352
349
|
}
|
|
350
|
+
|
|
353
351
|
this.hooks.push(
|
|
354
352
|
TimeRangeModule.buildHook(
|
|
355
353
|
{
|
|
356
|
-
entityId: this.validationConfig.entityId,
|
|
357
|
-
validUntil: deadline,
|
|
354
|
+
entityId: this.validationConfig.entityId,
|
|
355
|
+
validUntil: this.deadline,
|
|
358
356
|
validAfter: 0,
|
|
359
357
|
},
|
|
360
358
|
getDefaultTimeRangeModuleAddress(this.client.chain)
|
|
@@ -368,7 +366,7 @@ export class PermissionBuilder {
|
|
|
368
366
|
this.client
|
|
369
367
|
).createDeferredActionTypedDataObject({
|
|
370
368
|
callData: installValidationCall,
|
|
371
|
-
deadline: deadline,
|
|
369
|
+
deadline: this.deadline,
|
|
372
370
|
nonce: this.nonce,
|
|
373
371
|
});
|
|
374
372
|
|
|
@@ -377,8 +375,8 @@ export class PermissionBuilder {
|
|
|
377
375
|
).buildPreSignatureDeferredActionDigest({ typedData });
|
|
378
376
|
|
|
379
377
|
// Encode additional information to build the full pre-signature digest
|
|
380
|
-
const fullPreSignatureDeferredActionDigest: `0x${string}` = `
|
|
381
|
-
this.hasAssociatedExecHooks ? "
|
|
378
|
+
const fullPreSignatureDeferredActionDigest: `0x${string}` = `0x0${
|
|
379
|
+
this.hasAssociatedExecHooks ? "1" : "0"
|
|
382
380
|
}${toHex(this.nonce, {
|
|
383
381
|
size: 32,
|
|
384
382
|
}).slice(2)}${preSignatureDigest.slice(2)}`;
|
|
@@ -428,9 +426,7 @@ export class PermissionBuilder {
|
|
|
428
426
|
this.validationConfig.isGlobal === false &&
|
|
429
427
|
this.selectors.length === 0
|
|
430
428
|
) {
|
|
431
|
-
throw new
|
|
432
|
-
"Validation config unset, use permissionBuilder.configure(...)"
|
|
433
|
-
);
|
|
429
|
+
throw new ValidationConfigUnsetError();
|
|
434
430
|
}
|
|
435
431
|
}
|
|
436
432
|
|
|
@@ -449,9 +445,7 @@ export class PermissionBuilder {
|
|
|
449
445
|
case PermissionType.NATIVE_TOKEN_TRANSFER:
|
|
450
446
|
// Should never be added twice, check is on addPermission(s) too
|
|
451
447
|
if (rawHooks[HookIdentifier.NATIVE_TOKEN_TRANSFER] !== undefined) {
|
|
452
|
-
throw new
|
|
453
|
-
"PERMISSION: NATIVE_TOKEN_TRANSFER => Must have at most ONE native token transfer permission"
|
|
454
|
-
);
|
|
448
|
+
throw new MultipleNativeTokenTransferError(permission);
|
|
455
449
|
}
|
|
456
450
|
rawHooks[HookIdentifier.NATIVE_TOKEN_TRANSFER] = {
|
|
457
451
|
hookConfig: {
|
|
@@ -472,9 +466,7 @@ export class PermissionBuilder {
|
|
|
472
466
|
break;
|
|
473
467
|
case PermissionType.ERC20_TOKEN_TRANSFER:
|
|
474
468
|
if (permission.data.address === zeroAddress) {
|
|
475
|
-
throw new
|
|
476
|
-
"PERMISSION: ERC20_TOKEN_TRANSFER => Zero address provided"
|
|
477
|
-
);
|
|
469
|
+
throw new ZeroAddressError(permission);
|
|
478
470
|
}
|
|
479
471
|
rawHooks[HookIdentifier.ERC20_TOKEN_TRANSFER] = {
|
|
480
472
|
hookConfig: {
|
|
@@ -530,9 +522,7 @@ export class PermissionBuilder {
|
|
|
530
522
|
case PermissionType.GAS_LIMIT:
|
|
531
523
|
// Should only ever be added once, check is also on addPermission(s)
|
|
532
524
|
if (rawHooks[HookIdentifier.GAS_LIMIT] !== undefined) {
|
|
533
|
-
throw new
|
|
534
|
-
"PERMISSION: GAS_LIMIT => Must have at most ONE gas limit permission"
|
|
535
|
-
);
|
|
525
|
+
throw new MultipleGasLimitError(permission);
|
|
536
526
|
}
|
|
537
527
|
rawHooks[HookIdentifier.GAS_LIMIT] = {
|
|
538
528
|
hookConfig: {
|
|
@@ -552,9 +542,7 @@ export class PermissionBuilder {
|
|
|
552
542
|
break;
|
|
553
543
|
case PermissionType.CONTRACT_ACCESS:
|
|
554
544
|
if (permission.data.address === zeroAddress) {
|
|
555
|
-
throw new
|
|
556
|
-
"PERMISSION: CONTRACT_ACCESS => Zero address provided"
|
|
557
|
-
);
|
|
545
|
+
throw new ZeroAddressError(permission);
|
|
558
546
|
}
|
|
559
547
|
rawHooks[HookIdentifier.PREVAL_ALLOWLIST] = {
|
|
560
548
|
hookConfig: {
|
|
@@ -582,17 +570,11 @@ export class PermissionBuilder {
|
|
|
582
570
|
};
|
|
583
571
|
break;
|
|
584
572
|
case PermissionType.ACCOUNT_FUNCTIONS:
|
|
585
|
-
|
|
586
|
-
throw new Error(
|
|
587
|
-
"PERMISSION: ACCOUNT_FUNCTION => No functions provided"
|
|
588
|
-
); // should be in add perm
|
|
589
|
-
}
|
|
573
|
+
// This is handled in add permissions
|
|
590
574
|
break;
|
|
591
575
|
case PermissionType.FUNCTIONS_ON_ALL_CONTRACTS:
|
|
592
576
|
if (permission.data.functions.length === 0) {
|
|
593
|
-
throw new
|
|
594
|
-
"PERMISSION: FUNCTIONS_ON_ALL_CONTRACTS => No functions provided"
|
|
595
|
-
);
|
|
577
|
+
throw new NoFunctionsProvidedError(permission);
|
|
596
578
|
}
|
|
597
579
|
rawHooks[HookIdentifier.PREVAL_ALLOWLIST] = {
|
|
598
580
|
hookConfig: {
|
|
@@ -621,14 +603,10 @@ export class PermissionBuilder {
|
|
|
621
603
|
break;
|
|
622
604
|
case PermissionType.FUNCTIONS_ON_CONTRACT:
|
|
623
605
|
if (permission.data.functions.length === 0) {
|
|
624
|
-
throw new
|
|
625
|
-
"PERMISSION: FUNCTIONS_ON_CONTRACT => No functions provided"
|
|
626
|
-
);
|
|
606
|
+
throw new NoFunctionsProvidedError(permission);
|
|
627
607
|
}
|
|
628
608
|
if (permission.data.address === zeroAddress) {
|
|
629
|
-
throw new
|
|
630
|
-
"PERMISSION: FUNCTIONS_ON_CONTRACT => Zero address provided"
|
|
631
|
-
);
|
|
609
|
+
throw new ZeroAddressError(permission);
|
|
632
610
|
}
|
|
633
611
|
rawHooks[HookIdentifier.PREVAL_ALLOWLIST] = {
|
|
634
612
|
hookConfig: {
|
|
@@ -659,9 +637,7 @@ export class PermissionBuilder {
|
|
|
659
637
|
// Root permission handled in addPermission
|
|
660
638
|
break;
|
|
661
639
|
default:
|
|
662
|
-
|
|
663
|
-
`Unsupported permission type: ${(permission as any).type}`
|
|
664
|
-
);
|
|
640
|
+
assertNever(permission);
|
|
665
641
|
}
|
|
666
642
|
|
|
667
643
|
// isGlobal guaranteed to be false since it's only set with root permissions,
|
|
@@ -722,3 +698,7 @@ export class PermissionBuilder {
|
|
|
722
698
|
}
|
|
723
699
|
}
|
|
724
700
|
}
|
|
701
|
+
|
|
702
|
+
export function assertNever(_valid: never): never {
|
|
703
|
+
throw new UnsupportedPermissionTypeError();
|
|
704
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { BaseError, type Address } from "@aa-sdk/core";
|
|
2
|
+
import type { Permission } from "./permissionBuilder";
|
|
3
|
+
|
|
4
|
+
export class RootPermissionOnlyError extends BaseError {
|
|
5
|
+
override name = "PermissionBuilder: RootPermissionOnlyError";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Constructor for initializing an error message indicating that an account could not be found to execute the specified action.
|
|
9
|
+
*
|
|
10
|
+
* @param {Permission} permission The permission trying to be added atop the root permission
|
|
11
|
+
*/
|
|
12
|
+
constructor(permission: Permission) {
|
|
13
|
+
super(`Adding ${permission}: Cannot add permissions with ROOT permission`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class AccountAddressAsTargetError extends BaseError {
|
|
18
|
+
override name = "PermissionBuilder: AccountAddressAsTargetError";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Constructor for initializing an error message indicating that account address is used as target.
|
|
22
|
+
*
|
|
23
|
+
* @param {Permission} permission The permission with account address as target
|
|
24
|
+
*/
|
|
25
|
+
constructor(permission: Permission) {
|
|
26
|
+
super(
|
|
27
|
+
`${permission.type}: Account address as target, use ACCOUNT_FUNCTIONS for account address`
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class DuplicateTargetAddressError extends BaseError {
|
|
33
|
+
override name = "PermissionBuilder: DuplicateTargetAddressError";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Constructor for initializing an error message indicating duplicate target address in permissions.
|
|
37
|
+
*
|
|
38
|
+
* @param {Permission} permission The permission with duplicate target address
|
|
39
|
+
* @param {Address} targetAddress The duplicate target address
|
|
40
|
+
*/
|
|
41
|
+
constructor(permission: Permission, targetAddress: Address) {
|
|
42
|
+
super(
|
|
43
|
+
`${permission.type}: Address ${targetAddress} already has a permission. Cannot add multiple CONTRACT_ACCESS or FUNCTIONS_ON_CONTRACT permissions for the same target address.`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export class NoFunctionsProvidedError extends BaseError {
|
|
49
|
+
override name = "PermissionBuilder: NoFunctionsProvidedError";
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Constructor for initializing an error message indicating no functions were provided.
|
|
53
|
+
*
|
|
54
|
+
* @param {Permission} permission The permission missing functions
|
|
55
|
+
*/
|
|
56
|
+
constructor(permission: Permission) {
|
|
57
|
+
super(`${permission.type}: No functions provided`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export class ExpiredDeadlineError extends BaseError {
|
|
62
|
+
override name = "PermissionBuilder: ExpiredDeadlineError";
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Constructor for initializing an error message indicating the deadline has expired.
|
|
66
|
+
*
|
|
67
|
+
* @param {number} deadline The expired deadline timestamp
|
|
68
|
+
* @param {number} currentTime The current timestamp
|
|
69
|
+
*/
|
|
70
|
+
constructor(deadline: number, currentTime: number) {
|
|
71
|
+
super(
|
|
72
|
+
`compileDeferred(): deadline ${deadline} cannot be before now (${currentTime})`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export class DeadlineOverLimitError extends BaseError {
|
|
78
|
+
override name = "PermissionBuilder: DeadlineOverLimitError";
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Constructor for initializing an error message indicating the deadline has expired.
|
|
82
|
+
*
|
|
83
|
+
* @param {number} deadline The expired deadline timestamp
|
|
84
|
+
*/
|
|
85
|
+
constructor(deadline: number) {
|
|
86
|
+
super(
|
|
87
|
+
`compileDeferred(): deadline ${deadline} cannot be > max uint48 (2^48 - 1)`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export class ValidationConfigUnsetError extends BaseError {
|
|
93
|
+
override name = "PermissionBuilder: ValidationConfigUnsetError";
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Constructor for initializing an error message indicating the validation config is unset.
|
|
97
|
+
*/
|
|
98
|
+
constructor() {
|
|
99
|
+
super("Validation config unset, use permissionBuilder.configure(...)");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export class MultipleNativeTokenTransferError extends BaseError {
|
|
104
|
+
override name = "PermissionBuilder: MultipleNativeTokenTransferError";
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Constructor for initializing an error message indicating multiple native token transfer permissions.
|
|
108
|
+
*
|
|
109
|
+
* @param {Permission} permission The duplicate native token transfer permission
|
|
110
|
+
*/
|
|
111
|
+
constructor(permission: Permission) {
|
|
112
|
+
super(
|
|
113
|
+
`${permission.type}: Must have at most ONE native token transfer permission`
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export class ZeroAddressError extends BaseError {
|
|
119
|
+
override name = "PermissionBuilder: ZeroAddressError";
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Constructor for initializing an error message indicating zero address was provided.
|
|
123
|
+
*
|
|
124
|
+
* @param {Permission} permission The permission with zero address
|
|
125
|
+
*/
|
|
126
|
+
constructor(permission: Permission) {
|
|
127
|
+
super(`${permission.type}: Zero address provided`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export class MultipleGasLimitError extends BaseError {
|
|
132
|
+
override name = "PermissionBuilder: MultipleGasLimitError";
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Constructor for initializing an error message indicating multiple gas limit permissions.
|
|
136
|
+
*
|
|
137
|
+
* @param {Permission} permission The duplicate gas limit permission
|
|
138
|
+
*/
|
|
139
|
+
constructor(permission: Permission) {
|
|
140
|
+
super(`${permission.type}: Must have at most ONE gas limit permission`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export class UnsupportedPermissionTypeError extends BaseError {
|
|
145
|
+
override name = "PermissionBuilder: UnsupportedPermissionTypeError";
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Constructor for initializing an error message indicating an unsupported permission type.
|
|
149
|
+
*/
|
|
150
|
+
constructor() {
|
|
151
|
+
super(`Unsupported permission type`);
|
|
152
|
+
}
|
|
153
|
+
}
|
package/src/ma-v2/utils.ts
CHANGED
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
type Address,
|
|
9
9
|
type Transport,
|
|
10
10
|
parseAbi,
|
|
11
|
+
size,
|
|
12
|
+
concatHex,
|
|
11
13
|
} from "viem";
|
|
12
14
|
import {
|
|
13
15
|
arbitrum,
|
|
@@ -263,3 +265,46 @@ export const buildFullNonceKey = ({
|
|
|
263
265
|
(isGlobalValidation ? 1n : 0n)
|
|
264
266
|
);
|
|
265
267
|
};
|
|
268
|
+
|
|
269
|
+
// Parses out the 3 components from a deferred action
|
|
270
|
+
export const parseDeferredAction = (
|
|
271
|
+
deferredAction: Hex
|
|
272
|
+
): {
|
|
273
|
+
nonce: bigint;
|
|
274
|
+
deferredActionData: Hex;
|
|
275
|
+
hasAssociatedExecHooks: boolean;
|
|
276
|
+
} => {
|
|
277
|
+
return {
|
|
278
|
+
nonce: BigInt(`0x${deferredAction.slice(4, 68)}`),
|
|
279
|
+
deferredActionData: `0x${deferredAction.slice(68)}`,
|
|
280
|
+
hasAssociatedExecHooks: deferredAction[3] === "1",
|
|
281
|
+
};
|
|
282
|
+
};
|
|
283
|
+
export type BuildDeferredActionDigestParams = {
|
|
284
|
+
fullPreSignatureDeferredActionDigest: Hex;
|
|
285
|
+
sig: Hex;
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Creates the digest which must be prepended to the userOp signature.
|
|
290
|
+
*
|
|
291
|
+
* Assumption: The client this extends is used to sign the typed data.
|
|
292
|
+
*
|
|
293
|
+
* @param {object} args The argument object containing the following:
|
|
294
|
+
* @param {Hex} args.fullPreSignatureDeferredActionDigest The The data to append the signature and length to
|
|
295
|
+
* @param {Hex} args.sig The signature to include in the digest
|
|
296
|
+
* @returns {Hex} The encoded digest to be prepended to the userOp signature
|
|
297
|
+
*/
|
|
298
|
+
export const buildDeferredActionDigest = ({
|
|
299
|
+
fullPreSignatureDeferredActionDigest,
|
|
300
|
+
sig,
|
|
301
|
+
}: BuildDeferredActionDigestParams): Hex => {
|
|
302
|
+
const sigLength = size(sig);
|
|
303
|
+
|
|
304
|
+
const encodedData = concatHex([
|
|
305
|
+
fullPreSignatureDeferredActionDigest,
|
|
306
|
+
toHex(sigLength, { size: 4 }),
|
|
307
|
+
sig,
|
|
308
|
+
]);
|
|
309
|
+
return encodedData;
|
|
310
|
+
};
|