permissionless 0.2.7 → 0.2.9
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/index.js +3 -1
- package/_cjs/accounts/index.js.map +1 -1
- package/_cjs/accounts/thirdweb/toThirdwebSmartAccount.js +118 -0
- package/_cjs/accounts/thirdweb/toThirdwebSmartAccount.js.map +1 -0
- package/_cjs/accounts/thirdweb/utils/encodeCallData.js +76 -0
- package/_cjs/accounts/thirdweb/utils/encodeCallData.js.map +1 -0
- package/_cjs/accounts/thirdweb/utils/getAccountAddress.js +37 -0
- package/_cjs/accounts/thirdweb/utils/getAccountAddress.js.map +1 -0
- package/_cjs/accounts/thirdweb/utils/getFactoryData.js +37 -0
- package/_cjs/accounts/thirdweb/utils/getFactoryData.js.map +1 -0
- package/_cjs/accounts/thirdweb/utils/signMessage.js +19 -0
- package/_cjs/accounts/thirdweb/utils/signMessage.js.map +1 -0
- package/_cjs/accounts/thirdweb/utils/signTypedData.js +40 -0
- package/_cjs/accounts/thirdweb/utils/signTypedData.js.map +1 -0
- package/_cjs/actions/public/getSenderAddress.js +7 -4
- package/_cjs/actions/public/getSenderAddress.js.map +1 -1
- package/_esm/accounts/index.js +2 -1
- package/_esm/accounts/index.js.map +1 -1
- package/_esm/accounts/thirdweb/toThirdwebSmartAccount.js +122 -0
- package/_esm/accounts/thirdweb/toThirdwebSmartAccount.js.map +1 -0
- package/_esm/accounts/thirdweb/utils/encodeCallData.js +72 -0
- package/_esm/accounts/thirdweb/utils/encodeCallData.js.map +1 -0
- package/_esm/accounts/thirdweb/utils/getAccountAddress.js +33 -0
- package/_esm/accounts/thirdweb/utils/getAccountAddress.js.map +1 -0
- package/_esm/accounts/thirdweb/utils/getFactoryData.js +33 -0
- package/_esm/accounts/thirdweb/utils/getFactoryData.js.map +1 -0
- package/_esm/accounts/thirdweb/utils/signMessage.js +17 -0
- package/_esm/accounts/thirdweb/utils/signMessage.js.map +1 -0
- package/_esm/accounts/thirdweb/utils/signTypedData.js +40 -0
- package/_esm/accounts/thirdweb/utils/signTypedData.js.map +1 -0
- package/_esm/actions/public/getSenderAddress.js +8 -6
- package/_esm/actions/public/getSenderAddress.js.map +1 -1
- package/_types/accounts/index.d.ts +2 -1
- package/_types/accounts/index.d.ts.map +1 -1
- package/_types/accounts/thirdweb/toThirdwebSmartAccount.d.ts +37 -0
- package/_types/accounts/thirdweb/toThirdwebSmartAccount.d.ts.map +1 -0
- package/_types/accounts/thirdweb/utils/encodeCallData.d.ts +6 -0
- package/_types/accounts/thirdweb/utils/encodeCallData.d.ts.map +1 -0
- package/_types/accounts/thirdweb/utils/getAccountAddress.d.ts +8 -0
- package/_types/accounts/thirdweb/utils/getAccountAddress.d.ts.map +1 -0
- package/_types/accounts/thirdweb/utils/getFactoryData.d.ts +6 -0
- package/_types/accounts/thirdweb/utils/getFactoryData.d.ts.map +1 -0
- package/_types/accounts/thirdweb/utils/signMessage.d.ts +8 -0
- package/_types/accounts/thirdweb/utils/signMessage.d.ts.map +1 -0
- package/_types/accounts/thirdweb/utils/signTypedData.d.ts +7 -0
- package/_types/accounts/thirdweb/utils/signTypedData.d.ts.map +1 -0
- package/_types/actions/public/getSenderAddress.d.ts.map +1 -1
- package/accounts/index.ts +12 -1
- package/accounts/thirdweb/toThirdwebSmartAccount.ts +203 -0
- package/accounts/thirdweb/utils/encodeCallData.ts +81 -0
- package/accounts/thirdweb/utils/getAccountAddress.ts +48 -0
- package/accounts/thirdweb/utils/getFactoryData.ts +40 -0
- package/accounts/thirdweb/utils/signMessage.ts +34 -0
- package/accounts/thirdweb/utils/signTypedData.ts +67 -0
- package/actions/public/getSenderAddress.ts +11 -8
- package/package.json +2 -8
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { encodeFunctionData } from "viem"
|
|
2
|
+
|
|
3
|
+
export const encodeCallData = async (
|
|
4
|
+
calls: readonly {
|
|
5
|
+
to: `0x${string}`
|
|
6
|
+
value?: bigint | undefined
|
|
7
|
+
data?: `0x${string}` | undefined
|
|
8
|
+
}[]
|
|
9
|
+
) => {
|
|
10
|
+
if (calls.length > 1) {
|
|
11
|
+
return encodeFunctionData({
|
|
12
|
+
abi: [
|
|
13
|
+
{
|
|
14
|
+
inputs: [
|
|
15
|
+
{
|
|
16
|
+
internalType: "address[]",
|
|
17
|
+
name: "dest",
|
|
18
|
+
type: "address[]"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
internalType: "uint256[]",
|
|
22
|
+
name: "value",
|
|
23
|
+
type: "uint256[]"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
internalType: "bytes[]",
|
|
27
|
+
name: "func",
|
|
28
|
+
type: "bytes[]"
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
name: "executeBatch",
|
|
32
|
+
outputs: [],
|
|
33
|
+
stateMutability: "nonpayable",
|
|
34
|
+
type: "function"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
functionName: "executeBatch",
|
|
38
|
+
args: [
|
|
39
|
+
calls.map((a) => a.to),
|
|
40
|
+
calls.map((a) => a.value ?? 0n),
|
|
41
|
+
calls.map((a) => a.data ?? "0x")
|
|
42
|
+
]
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const call = calls.length === 0 ? undefined : calls[0]
|
|
47
|
+
|
|
48
|
+
if (!call) {
|
|
49
|
+
throw new Error("No calls to encode")
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return encodeFunctionData({
|
|
53
|
+
abi: [
|
|
54
|
+
{
|
|
55
|
+
inputs: [
|
|
56
|
+
{
|
|
57
|
+
internalType: "address",
|
|
58
|
+
name: "dest",
|
|
59
|
+
type: "address"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
internalType: "uint256",
|
|
63
|
+
name: "value",
|
|
64
|
+
type: "uint256"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
internalType: "bytes",
|
|
68
|
+
name: "func",
|
|
69
|
+
type: "bytes"
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
name: "execute",
|
|
73
|
+
outputs: [],
|
|
74
|
+
stateMutability: "nonpayable",
|
|
75
|
+
type: "function"
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
functionName: "execute",
|
|
79
|
+
args: [call.to, call.value ?? 0n, call.data ?? "0x"]
|
|
80
|
+
})
|
|
81
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Address, Client, Hex } from "viem"
|
|
2
|
+
import { readContract } from "viem/actions"
|
|
3
|
+
import { getAction } from "viem/utils"
|
|
4
|
+
|
|
5
|
+
export type GetAccountAddressParams = {
|
|
6
|
+
adminAddress: Address
|
|
7
|
+
factoryAddress: Address
|
|
8
|
+
salt: Hex
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const getAccountAddress = async (
|
|
12
|
+
client: Client,
|
|
13
|
+
args: GetAccountAddressParams
|
|
14
|
+
): Promise<Address> => {
|
|
15
|
+
const { adminAddress, factoryAddress, salt } = args
|
|
16
|
+
|
|
17
|
+
return getAction(
|
|
18
|
+
client,
|
|
19
|
+
readContract,
|
|
20
|
+
"readContract"
|
|
21
|
+
)({
|
|
22
|
+
address: factoryAddress,
|
|
23
|
+
abi: [
|
|
24
|
+
{
|
|
25
|
+
inputs: [
|
|
26
|
+
{
|
|
27
|
+
name: "_adminSigner",
|
|
28
|
+
type: "address"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: "_data",
|
|
32
|
+
type: "bytes"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
name: "getAddress",
|
|
36
|
+
outputs: [
|
|
37
|
+
{
|
|
38
|
+
type: "address"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
stateMutability: "view",
|
|
42
|
+
type: "function"
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
functionName: "getAddress",
|
|
46
|
+
args: [adminAddress, salt]
|
|
47
|
+
})
|
|
48
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Address, Hex } from "viem"
|
|
2
|
+
import { encodeFunctionData } from "viem"
|
|
3
|
+
|
|
4
|
+
export const getFactoryData = async ({
|
|
5
|
+
admin,
|
|
6
|
+
salt
|
|
7
|
+
}: {
|
|
8
|
+
admin: Address
|
|
9
|
+
salt: Hex
|
|
10
|
+
}) => {
|
|
11
|
+
return encodeFunctionData({
|
|
12
|
+
abi: [
|
|
13
|
+
{
|
|
14
|
+
inputs: [
|
|
15
|
+
{
|
|
16
|
+
internalType: "address",
|
|
17
|
+
name: "_admin",
|
|
18
|
+
type: "address"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
internalType: "bytes",
|
|
22
|
+
name: "_salt",
|
|
23
|
+
type: "bytes"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
name: "createAccount",
|
|
27
|
+
outputs: [
|
|
28
|
+
{
|
|
29
|
+
internalType: "address",
|
|
30
|
+
type: "address"
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
stateMutability: "nonpayable",
|
|
34
|
+
type: "function"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
functionName: "createAccount",
|
|
38
|
+
args: [admin, salt]
|
|
39
|
+
})
|
|
40
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Address,
|
|
3
|
+
type LocalAccount,
|
|
4
|
+
type SignMessageReturnType,
|
|
5
|
+
type SignableMessage,
|
|
6
|
+
hashMessage
|
|
7
|
+
} from "viem"
|
|
8
|
+
import { signMessage as _signMessage } from "viem/actions"
|
|
9
|
+
|
|
10
|
+
export async function signMessage({
|
|
11
|
+
message,
|
|
12
|
+
admin,
|
|
13
|
+
accountAddress,
|
|
14
|
+
chainId
|
|
15
|
+
}: {
|
|
16
|
+
chainId: number
|
|
17
|
+
message: SignableMessage
|
|
18
|
+
admin: LocalAccount
|
|
19
|
+
accountAddress: Address
|
|
20
|
+
}): Promise<SignMessageReturnType> {
|
|
21
|
+
const hashedMessage = hashMessage(message)
|
|
22
|
+
|
|
23
|
+
return admin.signTypedData({
|
|
24
|
+
domain: {
|
|
25
|
+
name: "Account",
|
|
26
|
+
version: "1",
|
|
27
|
+
chainId,
|
|
28
|
+
verifyingContract: accountAddress
|
|
29
|
+
},
|
|
30
|
+
primaryType: "AccountMessage",
|
|
31
|
+
types: { AccountMessage: [{ name: "message", type: "bytes" }] },
|
|
32
|
+
message: { message: hashedMessage }
|
|
33
|
+
})
|
|
34
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Address,
|
|
3
|
+
type LocalAccount,
|
|
4
|
+
type SignTypedDataReturnType,
|
|
5
|
+
type TypedDataDefinition,
|
|
6
|
+
type TypedDataDomain,
|
|
7
|
+
encodeAbiParameters,
|
|
8
|
+
getTypesForEIP712Domain,
|
|
9
|
+
hashTypedData,
|
|
10
|
+
validateTypedData
|
|
11
|
+
} from "viem"
|
|
12
|
+
|
|
13
|
+
export async function signTypedData(
|
|
14
|
+
parameters: TypedDataDefinition & {
|
|
15
|
+
accountAddress: Address
|
|
16
|
+
chainId: number
|
|
17
|
+
admin: LocalAccount
|
|
18
|
+
}
|
|
19
|
+
): Promise<SignTypedDataReturnType> {
|
|
20
|
+
const { admin, accountAddress, chainId, ...typedData } = parameters
|
|
21
|
+
const isSelfVerifyingContract =
|
|
22
|
+
(
|
|
23
|
+
typedData.domain as TypedDataDomain
|
|
24
|
+
)?.verifyingContract?.toLowerCase() === accountAddress
|
|
25
|
+
|
|
26
|
+
// If this is a self-verifying contract, we can use the admin's signature
|
|
27
|
+
if (isSelfVerifyingContract) {
|
|
28
|
+
return admin.signTypedData({
|
|
29
|
+
...typedData
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const { message, primaryType, types: _types, domain } = typedData
|
|
34
|
+
const types = {
|
|
35
|
+
EIP712Domain: getTypesForEIP712Domain({
|
|
36
|
+
domain: domain
|
|
37
|
+
}),
|
|
38
|
+
..._types
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Need to do a runtime validation check on addresses, byte ranges, integer ranges, etc
|
|
42
|
+
// as we can't statically check this with TypeScript.
|
|
43
|
+
validateTypedData({
|
|
44
|
+
domain,
|
|
45
|
+
message,
|
|
46
|
+
primaryType,
|
|
47
|
+
types
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
const typedHash = hashTypedData({ message, primaryType, types, domain })
|
|
51
|
+
const wrappedMessageHash = encodeAbiParameters(
|
|
52
|
+
[{ type: "bytes32" }],
|
|
53
|
+
[typedHash]
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
return admin.signTypedData({
|
|
57
|
+
domain: {
|
|
58
|
+
name: "Account",
|
|
59
|
+
version: "1",
|
|
60
|
+
chainId,
|
|
61
|
+
verifyingContract: accountAddress
|
|
62
|
+
},
|
|
63
|
+
primaryType: "AccountMessage",
|
|
64
|
+
types: { AccountMessage: [{ name: "message", type: "bytes" }] },
|
|
65
|
+
message: { message: wrappedMessageHash }
|
|
66
|
+
})
|
|
67
|
+
}
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
InvalidInputRpcError,
|
|
9
9
|
type OneOf,
|
|
10
10
|
type Prettify,
|
|
11
|
+
RawContractError,
|
|
11
12
|
RpcRequestError,
|
|
12
13
|
UnknownRpcError,
|
|
13
14
|
concat,
|
|
@@ -179,20 +180,22 @@ export const getSenderAddress = async (
|
|
|
179
180
|
}
|
|
180
181
|
|
|
181
182
|
if (revertError instanceof InvalidInputRpcError) {
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
183
|
+
const { data: data_ } = (
|
|
184
|
+
e instanceof RawContractError
|
|
185
|
+
? e
|
|
186
|
+
: e instanceof BaseError
|
|
187
|
+
? e.walk((err) => "data" in (err as Error)) || e.walk()
|
|
188
|
+
: {}
|
|
189
|
+
) as RawContractError
|
|
187
190
|
|
|
188
|
-
|
|
191
|
+
const data = typeof data_ === "string" ? data_ : data_?.data
|
|
192
|
+
|
|
193
|
+
if (data === undefined) {
|
|
189
194
|
throw new Error(
|
|
190
195
|
"Failed to parse revert bytes from RPC response"
|
|
191
196
|
)
|
|
192
197
|
}
|
|
193
198
|
|
|
194
|
-
const data: Hex = match[0]
|
|
195
|
-
|
|
196
199
|
const error = decodeErrorResult({
|
|
197
200
|
abi: [
|
|
198
201
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "permissionless",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"author": "Pimlico",
|
|
5
5
|
"homepage": "https://docs.pimlico.io/permissionless",
|
|
6
6
|
"repository": "github:pimlicolabs/permissionless.js",
|
|
@@ -11,13 +11,7 @@
|
|
|
11
11
|
"type": "module",
|
|
12
12
|
"sideEffects": false,
|
|
13
13
|
"description": "A utility library for working with ERC-4337",
|
|
14
|
-
"keywords": [
|
|
15
|
-
"ethereum",
|
|
16
|
-
"erc-4337",
|
|
17
|
-
"eip-4337",
|
|
18
|
-
"paymaster",
|
|
19
|
-
"bundler"
|
|
20
|
-
],
|
|
14
|
+
"keywords": ["ethereum", "erc-4337", "eip-4337", "paymaster", "bundler"],
|
|
21
15
|
"license": "MIT",
|
|
22
16
|
"exports": {
|
|
23
17
|
".": {
|