permissionless 0.2.23 → 0.2.25
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/CHANGELOG.md +12 -0
- package/_cjs/accounts/safe/index.js +11 -0
- package/_cjs/accounts/safe/index.js.map +1 -0
- package/_cjs/accounts/safe/signUserOperation.js +97 -0
- package/_cjs/accounts/safe/signUserOperation.js.map +1 -0
- package/_cjs/accounts/safe/toSafeSmartAccount.js +111 -89
- package/_cjs/accounts/safe/toSafeSmartAccount.js.map +1 -1
- package/_esm/accounts/safe/index.js +8 -0
- package/_esm/accounts/safe/index.js.map +1 -0
- package/_esm/accounts/safe/signUserOperation.js +94 -0
- package/_esm/accounts/safe/signUserOperation.js.map +1 -0
- package/_esm/accounts/safe/toSafeSmartAccount.js +112 -92
- package/_esm/accounts/safe/toSafeSmartAccount.js.map +1 -1
- package/_types/accounts/safe/index.d.ts +8 -0
- package/_types/accounts/safe/index.d.ts.map +1 -0
- package/_types/accounts/safe/signUserOperation.d.ts +19 -0
- package/_types/accounts/safe/signUserOperation.d.ts.map +1 -0
- package/_types/accounts/safe/toSafeSmartAccount.d.ts +33 -6
- package/_types/accounts/safe/toSafeSmartAccount.d.ts.map +1 -1
- package/accounts/safe/index.ts +22 -0
- package/accounts/safe/signUserOperation.test.ts +277 -0
- package/accounts/safe/signUserOperation.ts +177 -0
- package/accounts/safe/toSafeSmartAccount.ts +177 -116
- package/actions/smartAccount/signMessage.test.ts +27 -7
- package/actions/smartAccount/signTypedData.test.ts +4 -1
- package/package.json +6 -1
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
type TypedDataDefinition,
|
|
14
14
|
type WalletClient,
|
|
15
15
|
concat,
|
|
16
|
-
concatHex,
|
|
17
16
|
encodeAbiParameters,
|
|
18
17
|
encodeFunctionData,
|
|
19
18
|
encodePacked,
|
|
@@ -36,12 +35,13 @@ import {
|
|
|
36
35
|
entryPoint07Address,
|
|
37
36
|
toSmartAccount
|
|
38
37
|
} from "viem/account-abstraction"
|
|
39
|
-
import { getChainId, readContract
|
|
38
|
+
import { getChainId, readContract } from "viem/actions"
|
|
40
39
|
import { getAction } from "viem/utils"
|
|
41
40
|
import { getAccountNonce } from "../../actions/public/getAccountNonce.js"
|
|
42
41
|
import { encode7579Calls } from "../../utils/encode7579Calls.js"
|
|
43
42
|
import { isSmartAccountDeployed } from "../../utils/isSmartAccountDeployed.js"
|
|
44
43
|
import { type EthereumProvider, toOwner } from "../../utils/toOwner.js"
|
|
44
|
+
import { signUserOperation } from "./signUserOperation.js"
|
|
45
45
|
|
|
46
46
|
export type SafeVersion = "1.4.1"
|
|
47
47
|
|
|
@@ -364,7 +364,7 @@ const executeUserOpWithErrorStringAbi = [
|
|
|
364
364
|
}
|
|
365
365
|
] as const
|
|
366
366
|
|
|
367
|
-
const EIP712_SAFE_OPERATION_TYPE_V06 = {
|
|
367
|
+
export const EIP712_SAFE_OPERATION_TYPE_V06 = {
|
|
368
368
|
SafeOp: [
|
|
369
369
|
{ type: "address", name: "safe" },
|
|
370
370
|
{ type: "uint256", name: "nonce" },
|
|
@@ -382,7 +382,7 @@ const EIP712_SAFE_OPERATION_TYPE_V06 = {
|
|
|
382
382
|
]
|
|
383
383
|
}
|
|
384
384
|
|
|
385
|
-
const EIP712_SAFE_OPERATION_TYPE_V07 = {
|
|
385
|
+
export const EIP712_SAFE_OPERATION_TYPE_V07 = {
|
|
386
386
|
SafeOp: [
|
|
387
387
|
{ type: "address", name: "safe" },
|
|
388
388
|
{ type: "uint256", name: "nonce" },
|
|
@@ -525,18 +525,19 @@ const get7579LaunchPadInitData = ({
|
|
|
525
525
|
safe4337ModuleAddress,
|
|
526
526
|
safeSingletonAddress,
|
|
527
527
|
erc7579LaunchpadAddress,
|
|
528
|
-
|
|
528
|
+
owners,
|
|
529
529
|
validators,
|
|
530
530
|
executors,
|
|
531
531
|
fallbacks,
|
|
532
532
|
hooks,
|
|
533
533
|
attesters,
|
|
534
|
+
threshold,
|
|
534
535
|
attestersThreshold
|
|
535
536
|
}: {
|
|
536
537
|
safe4337ModuleAddress: Address
|
|
537
538
|
safeSingletonAddress: Address
|
|
538
539
|
erc7579LaunchpadAddress: Address
|
|
539
|
-
|
|
540
|
+
owners: Address[]
|
|
540
541
|
executors: {
|
|
541
542
|
address: Address
|
|
542
543
|
context: Address
|
|
@@ -545,12 +546,13 @@ const get7579LaunchPadInitData = ({
|
|
|
545
546
|
fallbacks: { address: Address; context: Address }[]
|
|
546
547
|
hooks: { address: Address; context: Address }[]
|
|
547
548
|
attesters: Address[]
|
|
549
|
+
threshold: bigint
|
|
548
550
|
attestersThreshold: number
|
|
549
551
|
}) => {
|
|
550
552
|
const initData = {
|
|
551
553
|
singleton: safeSingletonAddress,
|
|
552
|
-
owners:
|
|
553
|
-
threshold:
|
|
554
|
+
owners: owners,
|
|
555
|
+
threshold: threshold,
|
|
554
556
|
setupTo: erc7579LaunchpadAddress,
|
|
555
557
|
setupData: encodeFunctionData({
|
|
556
558
|
abi: initSafe7579Abi,
|
|
@@ -581,7 +583,8 @@ const get7579LaunchPadInitData = ({
|
|
|
581
583
|
}
|
|
582
584
|
|
|
583
585
|
const getInitializerCode = async ({
|
|
584
|
-
|
|
586
|
+
owners,
|
|
587
|
+
threshold,
|
|
585
588
|
safeModuleSetupAddress,
|
|
586
589
|
safe4337ModuleAddress,
|
|
587
590
|
multiSendAddress,
|
|
@@ -599,7 +602,8 @@ const getInitializerCode = async ({
|
|
|
599
602
|
payment = BigInt(0),
|
|
600
603
|
paymentReceiver = zeroAddress
|
|
601
604
|
}: {
|
|
602
|
-
|
|
605
|
+
owners: Address[]
|
|
606
|
+
threshold: bigint
|
|
603
607
|
safeSingletonAddress: Address
|
|
604
608
|
safeModuleSetupAddress: Address
|
|
605
609
|
safe4337ModuleAddress: Address
|
|
@@ -629,10 +633,11 @@ const getInitializerCode = async ({
|
|
|
629
633
|
safe4337ModuleAddress,
|
|
630
634
|
safeSingletonAddress,
|
|
631
635
|
erc7579LaunchpadAddress,
|
|
632
|
-
|
|
636
|
+
owners,
|
|
633
637
|
validators,
|
|
634
638
|
executors,
|
|
635
639
|
fallbacks,
|
|
640
|
+
threshold,
|
|
636
641
|
hooks,
|
|
637
642
|
attesters,
|
|
638
643
|
attestersThreshold
|
|
@@ -729,7 +734,7 @@ const getInitializerCode = async ({
|
|
|
729
734
|
abi: setupAbi,
|
|
730
735
|
functionName: "setup",
|
|
731
736
|
args: [
|
|
732
|
-
|
|
737
|
+
owners,
|
|
733
738
|
BigInt(1),
|
|
734
739
|
multiSendAddress,
|
|
735
740
|
multiSendCallData,
|
|
@@ -741,7 +746,7 @@ const getInitializerCode = async ({
|
|
|
741
746
|
})
|
|
742
747
|
}
|
|
743
748
|
|
|
744
|
-
function getPaymasterAndData(unpackedUserOperation: UserOperation) {
|
|
749
|
+
export function getPaymasterAndData(unpackedUserOperation: UserOperation) {
|
|
745
750
|
return unpackedUserOperation.paymaster
|
|
746
751
|
? concat([
|
|
747
752
|
unpackedUserOperation.paymaster,
|
|
@@ -768,7 +773,8 @@ function getPaymasterAndData(unpackedUserOperation: UserOperation) {
|
|
|
768
773
|
}
|
|
769
774
|
|
|
770
775
|
const getAccountInitCode = async ({
|
|
771
|
-
|
|
776
|
+
owners,
|
|
777
|
+
threshold,
|
|
772
778
|
safeModuleSetupAddress,
|
|
773
779
|
safe4337ModuleAddress,
|
|
774
780
|
safeSingletonAddress,
|
|
@@ -787,7 +793,8 @@ const getAccountInitCode = async ({
|
|
|
787
793
|
attesters = [],
|
|
788
794
|
attestersThreshold = 0
|
|
789
795
|
}: {
|
|
790
|
-
|
|
796
|
+
owners: Address[]
|
|
797
|
+
threshold: bigint
|
|
791
798
|
safeModuleSetupAddress: Address
|
|
792
799
|
safe4337ModuleAddress: Address
|
|
793
800
|
safeSingletonAddress: Address
|
|
@@ -813,12 +820,9 @@ const getAccountInitCode = async ({
|
|
|
813
820
|
payment?: bigint
|
|
814
821
|
paymentReceiver?: Address
|
|
815
822
|
}): Promise<Hex> => {
|
|
816
|
-
if (!owner) {
|
|
817
|
-
throw new Error("Owner account not found")
|
|
818
|
-
}
|
|
819
|
-
|
|
820
823
|
const initializer = await getInitializerCode({
|
|
821
|
-
|
|
824
|
+
owners,
|
|
825
|
+
threshold,
|
|
822
826
|
safeModuleSetupAddress,
|
|
823
827
|
safe4337ModuleAddress,
|
|
824
828
|
multiSendAddress,
|
|
@@ -850,7 +854,7 @@ const getAccountInitCode = async ({
|
|
|
850
854
|
return initCodeCallData
|
|
851
855
|
}
|
|
852
856
|
|
|
853
|
-
const getDefaultAddresses = (
|
|
857
|
+
export const getDefaultAddresses = (
|
|
854
858
|
safeVersion: SafeVersion,
|
|
855
859
|
entryPointVersion: "0.6" | "0.7",
|
|
856
860
|
{
|
|
@@ -938,13 +942,8 @@ export type ToSafeSmartAccountParameters<
|
|
|
938
942
|
TErc7579 extends Address | undefined
|
|
939
943
|
> = {
|
|
940
944
|
client: Client
|
|
941
|
-
owners: [
|
|
942
|
-
|
|
943
|
-
| EthereumProvider
|
|
944
|
-
| WalletClient<Transport, Chain | undefined, Account>
|
|
945
|
-
| LocalAccount
|
|
946
|
-
>
|
|
947
|
-
]
|
|
945
|
+
owners: (Account | WalletClient<Transport, Chain | undefined, Account>)[]
|
|
946
|
+
threshold?: bigint
|
|
948
947
|
version: SafeVersion
|
|
949
948
|
entryPoint?: {
|
|
950
949
|
address: Address
|
|
@@ -988,7 +987,8 @@ const proxyCreationCodeAbi = [
|
|
|
988
987
|
|
|
989
988
|
const getAccountAddress = async ({
|
|
990
989
|
client,
|
|
991
|
-
|
|
990
|
+
owners,
|
|
991
|
+
threshold,
|
|
992
992
|
safeModuleSetupAddress,
|
|
993
993
|
safe4337ModuleAddress,
|
|
994
994
|
safeProxyFactoryAddress,
|
|
@@ -1009,7 +1009,8 @@ const getAccountAddress = async ({
|
|
|
1009
1009
|
attestersThreshold = 0
|
|
1010
1010
|
}: {
|
|
1011
1011
|
client: Client
|
|
1012
|
-
|
|
1012
|
+
owners: Address[]
|
|
1013
|
+
threshold: bigint
|
|
1013
1014
|
safeModuleSetupAddress: Address
|
|
1014
1015
|
safe4337ModuleAddress: Address
|
|
1015
1016
|
safeProxyFactoryAddress: Address
|
|
@@ -1043,7 +1044,8 @@ const getAccountAddress = async ({
|
|
|
1043
1044
|
})
|
|
1044
1045
|
|
|
1045
1046
|
const initializer = await getInitializerCode({
|
|
1046
|
-
|
|
1047
|
+
owners,
|
|
1048
|
+
threshold,
|
|
1047
1049
|
safeModuleSetupAddress,
|
|
1048
1050
|
safe4337ModuleAddress,
|
|
1049
1051
|
multiSendAddress,
|
|
@@ -1119,8 +1121,9 @@ export async function toSafeSmartAccount<
|
|
|
1119
1121
|
): Promise<ToSafeSmartAccountReturnType<entryPointVersion>> {
|
|
1120
1122
|
const {
|
|
1121
1123
|
client,
|
|
1122
|
-
owners,
|
|
1124
|
+
owners: _owners,
|
|
1123
1125
|
address,
|
|
1126
|
+
threshold = BigInt(_owners.length),
|
|
1124
1127
|
version,
|
|
1125
1128
|
safe4337ModuleAddress: _safe4337ModuleAddress,
|
|
1126
1129
|
safeProxyFactoryAddress: _safeProxyFactoryAddress,
|
|
@@ -1135,7 +1138,38 @@ export async function toSafeSmartAccount<
|
|
|
1135
1138
|
paymentReceiver
|
|
1136
1139
|
} = parameters
|
|
1137
1140
|
|
|
1138
|
-
const
|
|
1141
|
+
const owners = _owners.map((owner) =>
|
|
1142
|
+
"account" in owner ? owner.account : owner
|
|
1143
|
+
)
|
|
1144
|
+
|
|
1145
|
+
const localOwners = await Promise.all(
|
|
1146
|
+
_owners
|
|
1147
|
+
.filter((owner) => {
|
|
1148
|
+
if ("type" in owner && owner.type === "local") {
|
|
1149
|
+
return true
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
if ("request" in owner) {
|
|
1153
|
+
return true
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
if ("account" in owner) {
|
|
1157
|
+
// walletClient
|
|
1158
|
+
return true
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
return false
|
|
1162
|
+
})
|
|
1163
|
+
.map((owner) =>
|
|
1164
|
+
toOwner({
|
|
1165
|
+
owner: owner as OneOf<
|
|
1166
|
+
| LocalAccount
|
|
1167
|
+
| EthereumProvider
|
|
1168
|
+
| WalletClient<Transport, Chain | undefined, Account>
|
|
1169
|
+
>
|
|
1170
|
+
})
|
|
1171
|
+
)
|
|
1172
|
+
)
|
|
1139
1173
|
|
|
1140
1174
|
const entryPoint = {
|
|
1141
1175
|
address: parameters.entryPoint?.address ?? entryPoint07Address,
|
|
@@ -1211,7 +1245,8 @@ export async function toSafeSmartAccount<
|
|
|
1211
1245
|
return {
|
|
1212
1246
|
factory: safeProxyFactoryAddress,
|
|
1213
1247
|
factoryData: await getAccountInitCode({
|
|
1214
|
-
|
|
1248
|
+
owners: owners.map((owner) => owner.address),
|
|
1249
|
+
threshold,
|
|
1215
1250
|
safeModuleSetupAddress,
|
|
1216
1251
|
safe4337ModuleAddress,
|
|
1217
1252
|
safeSingletonAddress,
|
|
@@ -1243,7 +1278,8 @@ export async function toSafeSmartAccount<
|
|
|
1243
1278
|
// Get the sender address based on the init code
|
|
1244
1279
|
accountAddress = await getAccountAddress({
|
|
1245
1280
|
client,
|
|
1246
|
-
|
|
1281
|
+
owners: owners.map((owner) => owner.address),
|
|
1282
|
+
threshold,
|
|
1247
1283
|
safeModuleSetupAddress,
|
|
1248
1284
|
safe4337ModuleAddress,
|
|
1249
1285
|
safeProxyFactoryAddress,
|
|
@@ -1280,7 +1316,8 @@ export async function toSafeSmartAccount<
|
|
|
1280
1316
|
safe4337ModuleAddress,
|
|
1281
1317
|
safeSingletonAddress,
|
|
1282
1318
|
erc7579LaunchpadAddress,
|
|
1283
|
-
|
|
1319
|
+
owners: owners.map((owner) => owner.address),
|
|
1320
|
+
threshold,
|
|
1284
1321
|
validators,
|
|
1285
1322
|
executors,
|
|
1286
1323
|
fallbacks,
|
|
@@ -1372,12 +1409,30 @@ export async function toSafeSmartAccount<
|
|
|
1372
1409
|
})
|
|
1373
1410
|
},
|
|
1374
1411
|
async getStubSignature() {
|
|
1375
|
-
return
|
|
1412
|
+
return encodePacked(
|
|
1413
|
+
["uint48", "uint48", "bytes"],
|
|
1414
|
+
[
|
|
1415
|
+
0,
|
|
1416
|
+
0,
|
|
1417
|
+
`0x${owners
|
|
1418
|
+
.map(
|
|
1419
|
+
(_) =>
|
|
1420
|
+
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
|
1421
|
+
)
|
|
1422
|
+
.join("")}`
|
|
1423
|
+
]
|
|
1424
|
+
)
|
|
1376
1425
|
},
|
|
1377
1426
|
async sign({ hash }) {
|
|
1378
1427
|
return this.signMessage({ message: hash })
|
|
1379
1428
|
},
|
|
1380
1429
|
async signMessage({ message }) {
|
|
1430
|
+
if (localOwners.length !== owners.length) {
|
|
1431
|
+
throw new Error(
|
|
1432
|
+
"Owners length mismatch, currently not supported"
|
|
1433
|
+
)
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1381
1436
|
const messageHash = hashTypedData({
|
|
1382
1437
|
domain: {
|
|
1383
1438
|
chainId: await getMemoizedChainId(),
|
|
@@ -1392,102 +1447,108 @@ export async function toSafeSmartAccount<
|
|
|
1392
1447
|
}
|
|
1393
1448
|
})
|
|
1394
1449
|
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1450
|
+
const signatures = await Promise.all(
|
|
1451
|
+
localOwners.map(async (localOwner) => ({
|
|
1452
|
+
signer: localOwner.address,
|
|
1453
|
+
data: adjustVInSignature(
|
|
1454
|
+
"eth_sign",
|
|
1455
|
+
await localOwner.signMessage({
|
|
1456
|
+
message: {
|
|
1457
|
+
raw: toBytes(messageHash)
|
|
1458
|
+
}
|
|
1459
|
+
})
|
|
1460
|
+
)
|
|
1461
|
+
}))
|
|
1402
1462
|
)
|
|
1463
|
+
|
|
1464
|
+
signatures.sort((left, right) =>
|
|
1465
|
+
left.signer
|
|
1466
|
+
.toLowerCase()
|
|
1467
|
+
.localeCompare(right.signer.toLowerCase())
|
|
1468
|
+
)
|
|
1469
|
+
|
|
1470
|
+
const signatureBytes = concat(signatures.map((sig) => sig.data))
|
|
1471
|
+
|
|
1472
|
+
return signatureBytes
|
|
1403
1473
|
},
|
|
1404
1474
|
async signTypedData(typedData) {
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1475
|
+
if (localOwners.length !== owners.length) {
|
|
1476
|
+
throw new Error(
|
|
1477
|
+
"Owners length mismatch, currently not supported"
|
|
1478
|
+
)
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
const signatures = await Promise.all(
|
|
1482
|
+
localOwners.map(async (localOwner) => ({
|
|
1483
|
+
signer: localOwner.address,
|
|
1484
|
+
data: adjustVInSignature(
|
|
1485
|
+
"eth_signTypedData",
|
|
1486
|
+
|
|
1487
|
+
await localOwner.signTypedData({
|
|
1488
|
+
domain: {
|
|
1489
|
+
chainId: await getMemoizedChainId(),
|
|
1490
|
+
verifyingContract: await this.getAddress()
|
|
1491
|
+
},
|
|
1492
|
+
types: {
|
|
1493
|
+
SafeMessage: [
|
|
1494
|
+
{ name: "message", type: "bytes" }
|
|
1495
|
+
]
|
|
1496
|
+
},
|
|
1497
|
+
primaryType: "SafeMessage",
|
|
1498
|
+
message: {
|
|
1499
|
+
message: generateSafeMessageMessage(typedData)
|
|
1500
|
+
}
|
|
1501
|
+
})
|
|
1502
|
+
)
|
|
1503
|
+
}))
|
|
1504
|
+
)
|
|
1505
|
+
|
|
1506
|
+
signatures.sort((left, right) =>
|
|
1507
|
+
left.signer
|
|
1508
|
+
.toLowerCase()
|
|
1509
|
+
.localeCompare(right.signer.toLowerCase())
|
|
1420
1510
|
)
|
|
1511
|
+
|
|
1512
|
+
const signatureBytes = concat(signatures.map((sig) => sig.data))
|
|
1513
|
+
|
|
1514
|
+
return signatureBytes
|
|
1421
1515
|
},
|
|
1422
1516
|
async signUserOperation(parameters) {
|
|
1423
1517
|
const { chainId = await getMemoizedChainId(), ...userOperation } =
|
|
1424
1518
|
parameters
|
|
1425
1519
|
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
initCode: userOperation.initCode ?? "0x",
|
|
1431
|
-
maxFeePerGas: userOperation.maxFeePerGas,
|
|
1432
|
-
maxPriorityFeePerGas: userOperation.maxPriorityFeePerGas,
|
|
1433
|
-
preVerificationGas: userOperation.preVerificationGas,
|
|
1434
|
-
verificationGasLimit: userOperation.verificationGasLimit,
|
|
1435
|
-
callGasLimit: userOperation.callGasLimit,
|
|
1436
|
-
paymasterAndData: userOperation.paymasterAndData ?? "0x",
|
|
1437
|
-
validAfter: validAfter,
|
|
1438
|
-
validUntil: validUntil,
|
|
1439
|
-
entryPoint: entryPoint.address
|
|
1520
|
+
if (localOwners.length !== owners.length) {
|
|
1521
|
+
throw new Error(
|
|
1522
|
+
"Owners length mismatch use SafeSmartAccount.signUserOperation from `permissionless/accounts/safe`"
|
|
1523
|
+
)
|
|
1440
1524
|
}
|
|
1441
1525
|
|
|
1442
|
-
|
|
1443
|
-
message.paymasterAndData =
|
|
1444
|
-
userOperation.paymasterAndData ?? "0x"
|
|
1445
|
-
}
|
|
1526
|
+
let signatures: Hex | undefined = undefined
|
|
1446
1527
|
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
message.initCode = concatHex([
|
|
1450
|
-
userOperation.factory,
|
|
1451
|
-
userOperation.factoryData
|
|
1452
|
-
])
|
|
1453
|
-
}
|
|
1454
|
-
message.paymasterAndData = getPaymasterAndData({
|
|
1528
|
+
for (const owner of localOwners) {
|
|
1529
|
+
signatures = await signUserOperation({
|
|
1455
1530
|
...userOperation,
|
|
1456
|
-
|
|
1531
|
+
version,
|
|
1532
|
+
entryPoint,
|
|
1533
|
+
owners: localOwners,
|
|
1534
|
+
account: owner as OneOf<
|
|
1535
|
+
| EthereumProvider
|
|
1536
|
+
| WalletClient<Transport, Chain | undefined, Account>
|
|
1537
|
+
| LocalAccount
|
|
1538
|
+
>,
|
|
1539
|
+
chainId: await getMemoizedChainId(),
|
|
1540
|
+
signatures,
|
|
1541
|
+
validAfter,
|
|
1542
|
+
validUntil,
|
|
1543
|
+
safe4337ModuleAddress
|
|
1457
1544
|
})
|
|
1458
1545
|
}
|
|
1459
1546
|
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
data: await signTypedData(client, {
|
|
1464
|
-
account: localOwner,
|
|
1465
|
-
domain: {
|
|
1466
|
-
chainId,
|
|
1467
|
-
verifyingContract: safe4337ModuleAddress
|
|
1468
|
-
},
|
|
1469
|
-
types:
|
|
1470
|
-
entryPoint.version === "0.6"
|
|
1471
|
-
? EIP712_SAFE_OPERATION_TYPE_V06
|
|
1472
|
-
: EIP712_SAFE_OPERATION_TYPE_V07,
|
|
1473
|
-
primaryType: "SafeOp",
|
|
1474
|
-
message: message
|
|
1475
|
-
})
|
|
1476
|
-
}
|
|
1477
|
-
]
|
|
1478
|
-
|
|
1479
|
-
signatures.sort((left, right) =>
|
|
1480
|
-
left.signer
|
|
1481
|
-
.toLowerCase()
|
|
1482
|
-
.localeCompare(right.signer.toLowerCase())
|
|
1483
|
-
)
|
|
1484
|
-
|
|
1485
|
-
const signatureBytes = concat(signatures.map((sig) => sig.data))
|
|
1547
|
+
if (!signatures) {
|
|
1548
|
+
throw new Error("No signatures found")
|
|
1549
|
+
}
|
|
1486
1550
|
|
|
1487
|
-
return
|
|
1488
|
-
["uint48", "uint48", "bytes"],
|
|
1489
|
-
[validAfter, validUntil, signatureBytes]
|
|
1490
|
-
)
|
|
1551
|
+
return signatures
|
|
1491
1552
|
}
|
|
1492
1553
|
}) as Promise<ToSafeSmartAccountReturnType<entryPointVersion>>
|
|
1493
1554
|
}
|
|
@@ -46,8 +46,20 @@ describe.each(getCoreSmartAccounts())(
|
|
|
46
46
|
...rpc
|
|
47
47
|
})
|
|
48
48
|
|
|
49
|
+
if (!smartClient.account) {
|
|
50
|
+
throw new Error("Account not found")
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (name.includes("Safe 7579")) {
|
|
54
|
+
// Due to 7579 launchpad, we can't verify the signature before deploying the account.
|
|
55
|
+
await smartClient.sendTransaction({
|
|
56
|
+
calls: [{ to: zeroAddress, value: 0n }]
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
49
60
|
const signature = await signMessage(smartClient, {
|
|
50
|
-
message: "slowly and steadily burning the private keys"
|
|
61
|
+
message: "slowly and steadily burning the private keys",
|
|
62
|
+
account: smartClient.account
|
|
51
63
|
})
|
|
52
64
|
|
|
53
65
|
const publicClient = getPublicClient(anvilRpc)
|
|
@@ -92,18 +104,26 @@ describe.each(getCoreSmartAccounts())(
|
|
|
92
104
|
...rpc
|
|
93
105
|
})
|
|
94
106
|
|
|
107
|
+
if (name === "LightAccount 2.0.0") {
|
|
108
|
+
// LightAccount 2.0.0 doesn't support EIP-1271
|
|
109
|
+
return
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (name.includes("Safe 7579")) {
|
|
113
|
+
return
|
|
114
|
+
|
|
115
|
+
// Due to 7579 launchpad, we can't verify the signature before deploying the account.
|
|
116
|
+
// await smartClient.sendTransaction({
|
|
117
|
+
// calls: [{ to: zeroAddress, value: 0n }]
|
|
118
|
+
// })
|
|
119
|
+
}
|
|
120
|
+
|
|
95
121
|
const signature = await signMessage(smartClient, {
|
|
96
122
|
message: "slowly and steadily burning the private keys"
|
|
97
123
|
})
|
|
98
124
|
|
|
99
125
|
const publicClient = getPublicClient(anvilRpc)
|
|
100
126
|
|
|
101
|
-
if (name === "Safe 7579" || name === "LightAccount 2.0.0") {
|
|
102
|
-
// Due to 7579 launchpad, we can't verify the signature as of now.
|
|
103
|
-
// Awaiting for the fix
|
|
104
|
-
return
|
|
105
|
-
}
|
|
106
|
-
|
|
107
127
|
const isVerified = await publicClient.verifyMessage({
|
|
108
128
|
address: smartClient.account.address,
|
|
109
129
|
message: "slowly and steadily burning the private keys",
|
|
@@ -124,7 +124,10 @@ describe.each(getCoreSmartAccounts())(
|
|
|
124
124
|
|
|
125
125
|
const publicClient = getPublicClient(anvilRpc)
|
|
126
126
|
|
|
127
|
-
if (
|
|
127
|
+
if (
|
|
128
|
+
name.includes("Safe 7579") ||
|
|
129
|
+
name === "LightAccount 2.0.0"
|
|
130
|
+
) {
|
|
128
131
|
// Due to 7579 launchpad, we can't verify the signature as of now.
|
|
129
132
|
// Awaiting for the fix
|
|
130
133
|
return
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "permissionless",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.25",
|
|
4
4
|
"author": "Pimlico",
|
|
5
5
|
"homepage": "https://docs.pimlico.io/permissionless",
|
|
6
6
|
"repository": "github:pimlicolabs/permissionless.js",
|
|
@@ -30,6 +30,11 @@
|
|
|
30
30
|
"import": "./_esm/accounts/index.js",
|
|
31
31
|
"default": "./_cjs/accounts/index.js"
|
|
32
32
|
},
|
|
33
|
+
"./accounts/safe": {
|
|
34
|
+
"types": "./_types/accounts/safe/index.d.ts",
|
|
35
|
+
"import": "./_esm/accounts/safe/index.js",
|
|
36
|
+
"default": "./_cjs/accounts/safe/index.js"
|
|
37
|
+
},
|
|
33
38
|
"./actions": {
|
|
34
39
|
"types": "./_types/actions/index.d.ts",
|
|
35
40
|
"import": "./_esm/actions/index.js",
|