permissionless 0.1.35 → 0.1.36
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 +6 -0
- package/_cjs/actions/erc7579/supportsExecutionMode.js +4 -4
- package/_cjs/actions/erc7579/supportsExecutionMode.js.map +1 -1
- package/_cjs/utils/encode7579CallData.js +1 -1
- package/_cjs/utils/encode7579CallData.js.map +1 -1
- package/_esm/actions/erc7579/supportsExecutionMode.js +4 -4
- package/_esm/actions/erc7579/supportsExecutionMode.js.map +1 -1
- package/_esm/utils/encode7579CallData.js +1 -1
- package/_esm/utils/encode7579CallData.js.map +1 -1
- package/_types/actions/erc7579/supportsExecutionMode.d.ts +3 -3
- package/_types/actions/erc7579/supportsExecutionMode.d.ts.map +1 -1
- package/actions/erc7579/supportsExecutionMode.test.ts +53 -0
- package/actions/erc7579/supportsExecutionMode.ts +7 -7
- package/actions/smartAccount/prepareUserOperationRequest.test.ts +371 -2
- package/actions/smartAccount.test.ts +198 -0
- package/clients/createBundlerClient.test.ts +26 -0
- package/clients/createSmartAccountClient.test.ts +55 -0
- package/clients/decorators/smartAccount.test.ts +55 -0
- package/package.json +1 -1
- package/utils/deepHexlify.test.ts +57 -0
- package/utils/encode7579CallData.test.ts +68 -0
- package/utils/encode7579CallData.ts +1 -1
- package/utils/getAddressFromInitCodeOrPaymasterAndData.test.ts +31 -0
- package/utils/getEntryPointVersion.test.ts +52 -0
- package/utils/getPackedUserOperation.test.ts +204 -0
- package/utils/getRequiredPrefund.test.ts +71 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Abi,
|
|
3
|
+
Account,
|
|
4
|
+
Address,
|
|
5
|
+
Chain,
|
|
6
|
+
Client,
|
|
7
|
+
Hash,
|
|
8
|
+
Hex,
|
|
9
|
+
SignTypedDataParameters,
|
|
10
|
+
Transport,
|
|
11
|
+
TypedData
|
|
12
|
+
} from "viem"
|
|
13
|
+
import type { SignMessageParameters } from "viem"
|
|
14
|
+
import { describe, expectTypeOf, test } from "vitest"
|
|
15
|
+
import type { SmartAccount } from "../accounts"
|
|
16
|
+
import type { BundlerRpcSchema } from "../types/bundler"
|
|
17
|
+
import type {
|
|
18
|
+
ENTRYPOINT_ADDRESS_V06_TYPE,
|
|
19
|
+
EntryPoint
|
|
20
|
+
} from "../types/entrypoint"
|
|
21
|
+
import {
|
|
22
|
+
type DeployContractParametersWithPaymaster,
|
|
23
|
+
type PrepareUserOperationRequestParameters,
|
|
24
|
+
type PrepareUserOperationRequestReturnType,
|
|
25
|
+
type SendTransactionWithPaymasterParameters,
|
|
26
|
+
type SendTransactionsWithPaymasterParameters,
|
|
27
|
+
type SendUserOperationParameters,
|
|
28
|
+
type WriteContractWithPaymasterParameters,
|
|
29
|
+
deployContract,
|
|
30
|
+
prepareUserOperationRequest,
|
|
31
|
+
sendTransaction,
|
|
32
|
+
sendTransactions,
|
|
33
|
+
sendUserOperation,
|
|
34
|
+
signMessage,
|
|
35
|
+
signTypedData,
|
|
36
|
+
writeContract
|
|
37
|
+
} from "./smartAccount"
|
|
38
|
+
|
|
39
|
+
describe("index", () => {
|
|
40
|
+
test("sendUserOperation", () => {
|
|
41
|
+
expectTypeOf(deployContract).toBeFunction()
|
|
42
|
+
expectTypeOf(deployContract)
|
|
43
|
+
.parameter(0)
|
|
44
|
+
.toMatchTypeOf<
|
|
45
|
+
Client<
|
|
46
|
+
Transport,
|
|
47
|
+
Chain | undefined,
|
|
48
|
+
Account | undefined,
|
|
49
|
+
BundlerRpcSchema<EntryPoint>
|
|
50
|
+
>
|
|
51
|
+
>()
|
|
52
|
+
expectTypeOf(deployContract)
|
|
53
|
+
.parameter(1)
|
|
54
|
+
.toMatchTypeOf<DeployContractParametersWithPaymaster<EntryPoint>>()
|
|
55
|
+
expectTypeOf(deployContract).returns.toMatchTypeOf<Promise<Hash>>()
|
|
56
|
+
})
|
|
57
|
+
test("prepareUserOperationRequest", () => {
|
|
58
|
+
expectTypeOf(prepareUserOperationRequest).toBeFunction()
|
|
59
|
+
expectTypeOf(prepareUserOperationRequest)
|
|
60
|
+
.parameter(0)
|
|
61
|
+
.toMatchTypeOf<
|
|
62
|
+
Client<
|
|
63
|
+
Transport,
|
|
64
|
+
Chain | undefined,
|
|
65
|
+
Account | undefined,
|
|
66
|
+
BundlerRpcSchema<EntryPoint>
|
|
67
|
+
>
|
|
68
|
+
>()
|
|
69
|
+
expectTypeOf(prepareUserOperationRequest)
|
|
70
|
+
.parameter(1)
|
|
71
|
+
.toMatchTypeOf<PrepareUserOperationRequestParameters<EntryPoint>>()
|
|
72
|
+
expectTypeOf(prepareUserOperationRequest).returns.toMatchTypeOf<
|
|
73
|
+
Promise<PrepareUserOperationRequestReturnType<EntryPoint>>
|
|
74
|
+
>()
|
|
75
|
+
})
|
|
76
|
+
test("sendTransaction", () => {
|
|
77
|
+
expectTypeOf(sendTransaction).toBeFunction()
|
|
78
|
+
expectTypeOf(sendTransaction)
|
|
79
|
+
.parameter(0)
|
|
80
|
+
.toMatchTypeOf<
|
|
81
|
+
Client<
|
|
82
|
+
Transport,
|
|
83
|
+
Chain | undefined,
|
|
84
|
+
Account | undefined,
|
|
85
|
+
BundlerRpcSchema<EntryPoint>
|
|
86
|
+
>
|
|
87
|
+
>()
|
|
88
|
+
expectTypeOf(sendTransaction)
|
|
89
|
+
.parameter(1)
|
|
90
|
+
.toMatchTypeOf<SendTransactionWithPaymasterParameters<EntryPoint>>()
|
|
91
|
+
expectTypeOf(sendTransaction).returns.toMatchTypeOf<Promise<Hex>>()
|
|
92
|
+
})
|
|
93
|
+
test("sendTransactions", () => {
|
|
94
|
+
expectTypeOf(sendTransactions).toBeFunction()
|
|
95
|
+
expectTypeOf(sendTransactions)
|
|
96
|
+
.parameter(0)
|
|
97
|
+
.toMatchTypeOf<
|
|
98
|
+
Client<
|
|
99
|
+
Transport,
|
|
100
|
+
Chain | undefined,
|
|
101
|
+
Account | undefined,
|
|
102
|
+
BundlerRpcSchema<EntryPoint>
|
|
103
|
+
>
|
|
104
|
+
>()
|
|
105
|
+
expectTypeOf(sendTransactions)
|
|
106
|
+
.parameter(1)
|
|
107
|
+
.toMatchTypeOf<
|
|
108
|
+
SendTransactionsWithPaymasterParameters<EntryPoint>
|
|
109
|
+
>()
|
|
110
|
+
expectTypeOf(sendTransactions).returns.toMatchTypeOf<Promise<Hex>>()
|
|
111
|
+
})
|
|
112
|
+
test("writeContract", () => {
|
|
113
|
+
expectTypeOf(writeContract).toBeFunction()
|
|
114
|
+
expectTypeOf(writeContract)
|
|
115
|
+
.parameter(0)
|
|
116
|
+
.toMatchTypeOf<
|
|
117
|
+
Client<
|
|
118
|
+
Transport,
|
|
119
|
+
Chain | undefined,
|
|
120
|
+
Account | undefined,
|
|
121
|
+
BundlerRpcSchema<EntryPoint>
|
|
122
|
+
>
|
|
123
|
+
>()
|
|
124
|
+
expectTypeOf(
|
|
125
|
+
writeContract<
|
|
126
|
+
ENTRYPOINT_ADDRESS_V06_TYPE,
|
|
127
|
+
Chain,
|
|
128
|
+
SmartAccount<ENTRYPOINT_ADDRESS_V06_TYPE>,
|
|
129
|
+
Abi
|
|
130
|
+
>
|
|
131
|
+
)
|
|
132
|
+
.parameter(1)
|
|
133
|
+
.toMatchTypeOf<
|
|
134
|
+
WriteContractWithPaymasterParameters<
|
|
135
|
+
ENTRYPOINT_ADDRESS_V06_TYPE,
|
|
136
|
+
Chain,
|
|
137
|
+
SmartAccount<ENTRYPOINT_ADDRESS_V06_TYPE>,
|
|
138
|
+
Abi
|
|
139
|
+
>
|
|
140
|
+
>()
|
|
141
|
+
expectTypeOf(writeContract).returns.toMatchTypeOf<Promise<Hex>>()
|
|
142
|
+
})
|
|
143
|
+
test("sendUserOperation", () => {
|
|
144
|
+
expectTypeOf(sendUserOperation).toBeFunction()
|
|
145
|
+
expectTypeOf(sendUserOperation)
|
|
146
|
+
.parameter(0)
|
|
147
|
+
.toMatchTypeOf<
|
|
148
|
+
Client<
|
|
149
|
+
Transport,
|
|
150
|
+
Chain | undefined,
|
|
151
|
+
Account | undefined,
|
|
152
|
+
BundlerRpcSchema<EntryPoint>
|
|
153
|
+
>
|
|
154
|
+
>()
|
|
155
|
+
expectTypeOf(sendUserOperation)
|
|
156
|
+
.parameter(1)
|
|
157
|
+
.toMatchTypeOf<SendUserOperationParameters<EntryPoint>>()
|
|
158
|
+
expectTypeOf(sendUserOperation).returns.toMatchTypeOf<Promise<Hex>>()
|
|
159
|
+
})
|
|
160
|
+
test("signMessage", () => {
|
|
161
|
+
expectTypeOf(signMessage).toBeFunction()
|
|
162
|
+
expectTypeOf(signMessage)
|
|
163
|
+
.parameter(0)
|
|
164
|
+
.toMatchTypeOf<
|
|
165
|
+
Client<
|
|
166
|
+
Transport,
|
|
167
|
+
Chain | undefined,
|
|
168
|
+
Account | undefined,
|
|
169
|
+
BundlerRpcSchema<EntryPoint>
|
|
170
|
+
>
|
|
171
|
+
>()
|
|
172
|
+
expectTypeOf(signMessage)
|
|
173
|
+
.parameter(1)
|
|
174
|
+
.toMatchTypeOf<SignMessageParameters<SmartAccount<EntryPoint>>>()
|
|
175
|
+
expectTypeOf(signMessage).returns.toMatchTypeOf<Promise<Hex>>()
|
|
176
|
+
})
|
|
177
|
+
test("signTypedData", () => {
|
|
178
|
+
expectTypeOf(signTypedData).toBeFunction()
|
|
179
|
+
expectTypeOf(signTypedData)
|
|
180
|
+
.parameter(0)
|
|
181
|
+
.toMatchTypeOf<
|
|
182
|
+
Client<
|
|
183
|
+
Transport,
|
|
184
|
+
Chain | undefined,
|
|
185
|
+
Account | undefined,
|
|
186
|
+
BundlerRpcSchema<EntryPoint>
|
|
187
|
+
>
|
|
188
|
+
>()
|
|
189
|
+
expectTypeOf(
|
|
190
|
+
signTypedData<EntryPoint, TypedData, string, undefined, undefined>
|
|
191
|
+
)
|
|
192
|
+
.parameter(1)
|
|
193
|
+
.toMatchTypeOf<
|
|
194
|
+
SignTypedDataParameters<TypedData, string, undefined>
|
|
195
|
+
>()
|
|
196
|
+
expectTypeOf(signTypedData).returns.toMatchTypeOf<Promise<Hex>>()
|
|
197
|
+
})
|
|
198
|
+
})
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { http } from "viem"
|
|
2
|
+
import { describe, expect } from "vitest"
|
|
3
|
+
import { testWithRpc } from "../../permissionless-test/src/testWithRpc"
|
|
4
|
+
import { ENTRYPOINT_ADDRESS_V06, ENTRYPOINT_ADDRESS_V07 } from "../utils"
|
|
5
|
+
import { createBundlerClient } from "./createBundlerClient"
|
|
6
|
+
|
|
7
|
+
describe("createBundlerClient", () => {
|
|
8
|
+
testWithRpc("createBundlerClient_V06", async ({ rpc }) => {
|
|
9
|
+
const bundlerClientV06 = createBundlerClient({
|
|
10
|
+
transport: http(rpc.altoRpc),
|
|
11
|
+
entryPoint: ENTRYPOINT_ADDRESS_V06
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
const entryPoints = await bundlerClientV06.supportedEntryPoints()
|
|
15
|
+
expect(entryPoints).contain(ENTRYPOINT_ADDRESS_V06)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
testWithRpc("createBundlerClient_V07", async ({ rpc }) => {
|
|
19
|
+
const bundlerClientV07 = createBundlerClient({
|
|
20
|
+
transport: http(rpc.altoRpc),
|
|
21
|
+
entryPoint: ENTRYPOINT_ADDRESS_V07
|
|
22
|
+
})
|
|
23
|
+
const entryPoints = await bundlerClientV07.supportedEntryPoints()
|
|
24
|
+
expect(entryPoints).contain(ENTRYPOINT_ADDRESS_V07)
|
|
25
|
+
})
|
|
26
|
+
})
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { http } from "viem"
|
|
2
|
+
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"
|
|
3
|
+
import { foundry } from "viem/chains"
|
|
4
|
+
import { describe, expect } from "vitest"
|
|
5
|
+
import { testWithRpc } from "../../permissionless-test/src/testWithRpc"
|
|
6
|
+
import { getPublicClient } from "../../permissionless-test/src/utils"
|
|
7
|
+
import { signerToSimpleSmartAccount } from "../accounts"
|
|
8
|
+
import { ENTRYPOINT_ADDRESS_V06, ENTRYPOINT_ADDRESS_V07 } from "../utils"
|
|
9
|
+
import { createSmartAccountClient } from "./createSmartAccountClient"
|
|
10
|
+
|
|
11
|
+
describe("createSmartAccountClient", () => {
|
|
12
|
+
testWithRpc("createSmartAccountClient_V06", async ({ rpc }) => {
|
|
13
|
+
const publicClient = getPublicClient(rpc.anvilRpc)
|
|
14
|
+
|
|
15
|
+
const simpleSmartAccount = await signerToSimpleSmartAccount(
|
|
16
|
+
publicClient,
|
|
17
|
+
{
|
|
18
|
+
entryPoint: ENTRYPOINT_ADDRESS_V06,
|
|
19
|
+
signer: privateKeyToAccount(generatePrivateKey())
|
|
20
|
+
}
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
const smartAccountClient = createSmartAccountClient({
|
|
24
|
+
chain: foundry,
|
|
25
|
+
account: simpleSmartAccount,
|
|
26
|
+
bundlerTransport: http(rpc.altoRpc)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
expect(smartAccountClient.account.address).toBe(
|
|
30
|
+
simpleSmartAccount.address
|
|
31
|
+
)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
testWithRpc("createSmartAccountClient_V07", async ({ rpc }) => {
|
|
35
|
+
const publicClient = getPublicClient(rpc.anvilRpc)
|
|
36
|
+
|
|
37
|
+
const simpleSmartAccount = await signerToSimpleSmartAccount(
|
|
38
|
+
publicClient,
|
|
39
|
+
{
|
|
40
|
+
entryPoint: ENTRYPOINT_ADDRESS_V07,
|
|
41
|
+
signer: privateKeyToAccount(generatePrivateKey())
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
const smartAccountClient = createSmartAccountClient({
|
|
46
|
+
chain: foundry,
|
|
47
|
+
account: simpleSmartAccount,
|
|
48
|
+
bundlerTransport: http(rpc.altoRpc)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
expect(smartAccountClient.account.address).toBe(
|
|
52
|
+
simpleSmartAccount.address
|
|
53
|
+
)
|
|
54
|
+
})
|
|
55
|
+
})
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { http } from "viem"
|
|
2
|
+
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"
|
|
3
|
+
import { foundry } from "viem/chains"
|
|
4
|
+
import { describe, expect } from "vitest"
|
|
5
|
+
import { testWithRpc } from "../../../permissionless-test/src/testWithRpc"
|
|
6
|
+
import { getPublicClient } from "../../../permissionless-test/src/utils"
|
|
7
|
+
import { signerToSimpleSmartAccount } from "../../accounts"
|
|
8
|
+
import { ENTRYPOINT_ADDRESS_V06, ENTRYPOINT_ADDRESS_V07 } from "../../utils"
|
|
9
|
+
import { createSmartAccountClient } from "../createSmartAccountClient"
|
|
10
|
+
|
|
11
|
+
describe("createSmartAccountClient", () => {
|
|
12
|
+
testWithRpc("createSmartAccountClient_V06", async ({ rpc }) => {
|
|
13
|
+
const publicClient = getPublicClient(rpc.anvilRpc)
|
|
14
|
+
|
|
15
|
+
const simpleSmartAccount = await signerToSimpleSmartAccount(
|
|
16
|
+
publicClient,
|
|
17
|
+
{
|
|
18
|
+
entryPoint: ENTRYPOINT_ADDRESS_V06,
|
|
19
|
+
signer: privateKeyToAccount(generatePrivateKey())
|
|
20
|
+
}
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
const smartAccountClient = createSmartAccountClient({
|
|
24
|
+
chain: foundry,
|
|
25
|
+
account: simpleSmartAccount,
|
|
26
|
+
bundlerTransport: http(rpc.altoRpc)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
expect(smartAccountClient.account.address).toBe(
|
|
30
|
+
simpleSmartAccount.address
|
|
31
|
+
)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
testWithRpc("createSmartAccountClient_V07", async ({ rpc }) => {
|
|
35
|
+
const publicClient = getPublicClient(rpc.anvilRpc)
|
|
36
|
+
|
|
37
|
+
const simpleSmartAccount = await signerToSimpleSmartAccount(
|
|
38
|
+
publicClient,
|
|
39
|
+
{
|
|
40
|
+
entryPoint: ENTRYPOINT_ADDRESS_V07,
|
|
41
|
+
signer: privateKeyToAccount(generatePrivateKey())
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
const smartAccountClient = createSmartAccountClient({
|
|
46
|
+
chain: foundry,
|
|
47
|
+
account: simpleSmartAccount,
|
|
48
|
+
bundlerTransport: http(rpc.altoRpc)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
expect(smartAccountClient.account.address).toBe(
|
|
52
|
+
simpleSmartAccount.address
|
|
53
|
+
)
|
|
54
|
+
})
|
|
55
|
+
})
|
package/package.json
CHANGED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { toHex } from "viem"
|
|
2
|
+
import { describe, expect, test } from "vitest"
|
|
3
|
+
import { deepHexlify } from "../utils"
|
|
4
|
+
|
|
5
|
+
describe("deepHexlify", () => {
|
|
6
|
+
test("should return undefined for function input", async () => {
|
|
7
|
+
const func = () => {}
|
|
8
|
+
expect(deepHexlify(func)).toBeUndefined()
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
test("should return null for null input", () => {
|
|
12
|
+
expect(deepHexlify(null)).toBeNull()
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
test("should return the same string for string input", () => {
|
|
16
|
+
const str = "test"
|
|
17
|
+
expect(deepHexlify(str)).toBe(str)
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test("should return the same boolean for boolean input", () => {
|
|
21
|
+
const bool = true
|
|
22
|
+
expect(deepHexlify(bool)).toBe(bool)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
test("should return hex string for bigint input", () => {
|
|
26
|
+
const bigint = BigInt(12345)
|
|
27
|
+
expect(deepHexlify(bigint)).toBe(toHex(bigint))
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
test("should return hex string for number input", () => {
|
|
31
|
+
const number = 12345
|
|
32
|
+
expect(deepHexlify(number)).toBe(toHex(number).replace(/^0x0/, "0x"))
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
test("should return array with hex values for array input", () => {
|
|
36
|
+
const array = [12345, BigInt(67890)]
|
|
37
|
+
expect(deepHexlify(array)).toEqual([
|
|
38
|
+
toHex(12345).replace(/^0x0/, "0x"),
|
|
39
|
+
toHex(BigInt(67890))
|
|
40
|
+
])
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test("should return object with hex values for object input", () => {
|
|
44
|
+
const obj = {
|
|
45
|
+
a: 12345,
|
|
46
|
+
b: BigInt(67890),
|
|
47
|
+
c: "string",
|
|
48
|
+
d: true
|
|
49
|
+
}
|
|
50
|
+
expect(deepHexlify(obj)).toEqual({
|
|
51
|
+
a: toHex(12345).replace(/^0x0/, "0x"),
|
|
52
|
+
b: toHex(BigInt(67890)),
|
|
53
|
+
c: "string",
|
|
54
|
+
d: true
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
})
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest"
|
|
2
|
+
import { encode7579CallData } from "./encode7579CallData"
|
|
3
|
+
|
|
4
|
+
describe("encode7579CallData", () => {
|
|
5
|
+
test("single call", async () => {
|
|
6
|
+
const callData = encode7579CallData({
|
|
7
|
+
mode: {
|
|
8
|
+
type: "call"
|
|
9
|
+
},
|
|
10
|
+
callData: {
|
|
11
|
+
to: "0x1234567890123456789012345678901234567890",
|
|
12
|
+
value: BigInt(12345),
|
|
13
|
+
data: "0x1234567890123456789012345678901234567890"
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
expect(callData).toBe(
|
|
18
|
+
"0xe9ae5c53000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000048123456789012345678901234567890123456789000000000000000000000000000000000000000000000000000000000000030391234567890123456789012345678901234567890000000000000000000000000000000000000000000000000"
|
|
19
|
+
)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test("batch call", async () => {
|
|
23
|
+
const callData = encode7579CallData({
|
|
24
|
+
mode: {
|
|
25
|
+
type: "batchcall"
|
|
26
|
+
},
|
|
27
|
+
callData: [
|
|
28
|
+
{
|
|
29
|
+
to: "0x1234567890123456789012345678901234567890",
|
|
30
|
+
value: BigInt(12345),
|
|
31
|
+
data: "0x1234567890123456789012345678901234567890"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
to: "0x1234567890123456789012345678901234567890",
|
|
35
|
+
value: BigInt(12345),
|
|
36
|
+
data: "0x1234567890123456789012345678901234567890"
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
expect(callData).toBe(
|
|
42
|
+
"0xe9ae5c53ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000001234567890123456789012345678901234567890000000000000000000000000000000000000000000000000000000000000303900000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000014123456789012345678901234567890123456789000000000000000000000000000000000000000000000000012345678901234567890123456789012345678900000000000000000000000000000000000000000000000000000000000003039000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000141234567890123456789012345678901234567890000000000000000000000000"
|
|
43
|
+
)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test("should throw error for batch call with different mode", async () => {
|
|
47
|
+
expect(() => {
|
|
48
|
+
encode7579CallData({
|
|
49
|
+
mode: {
|
|
50
|
+
type: "call"
|
|
51
|
+
},
|
|
52
|
+
// @ts-expect-error
|
|
53
|
+
callData: [
|
|
54
|
+
{
|
|
55
|
+
to: "0x1234567890123456789012345678901234567890",
|
|
56
|
+
value: BigInt(12345),
|
|
57
|
+
data: "0x1234567890123456789012345678901234567890"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
to: "0x1234567890123456789012345678901234567890",
|
|
61
|
+
value: BigInt(12345),
|
|
62
|
+
data: "0x1234567890123456789012345678901234567890"
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
})
|
|
66
|
+
}).toThrowError("batchcall calldata")
|
|
67
|
+
})
|
|
68
|
+
})
|
|
@@ -33,7 +33,7 @@ export function encode7579CallData<callType extends CallType>({
|
|
|
33
33
|
}: EncodeCallDataParams<callType>): Hex {
|
|
34
34
|
if (Array.isArray(callData) && mode?.type !== "batchcall") {
|
|
35
35
|
throw new Error(
|
|
36
|
-
`mode ${mode} does not supported for batchcall calldata`
|
|
36
|
+
`mode ${JSON.stringify(mode)} does not supported for batchcall calldata`
|
|
37
37
|
)
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest"
|
|
2
|
+
import { getAddressFromInitCodeOrPaymasterAndData } from "./getAddressFromInitCodeOrPaymasterAndData"
|
|
3
|
+
|
|
4
|
+
describe("getAddressFromInitCodeOrPaymasterAndData", () => {
|
|
5
|
+
test("should return undefined for undefined data", () => {
|
|
6
|
+
expect(
|
|
7
|
+
// @ts-expect-error
|
|
8
|
+
getAddressFromInitCodeOrPaymasterAndData(undefined)
|
|
9
|
+
).toBeUndefined()
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
test("should return undefined for empty string data", () => {
|
|
13
|
+
// @ts-expect-error
|
|
14
|
+
expect(getAddressFromInitCodeOrPaymasterAndData("")).toBeUndefined()
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
test("should return undefined for data shorter than 42 characters", () => {
|
|
18
|
+
const shortData = "0x123456789"
|
|
19
|
+
expect(
|
|
20
|
+
getAddressFromInitCodeOrPaymasterAndData(shortData)
|
|
21
|
+
).toBeUndefined()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test("should return the correct address for data exactly 42 characters", () => {
|
|
25
|
+
const expectedAddress = "0x1234567890123456789012345678901234567890"
|
|
26
|
+
const exactData = `${expectedAddress}_mocked_address_for`
|
|
27
|
+
expect(getAddressFromInitCodeOrPaymasterAndData(exactData)).toBe(
|
|
28
|
+
expectedAddress
|
|
29
|
+
)
|
|
30
|
+
})
|
|
31
|
+
})
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest"
|
|
2
|
+
import {
|
|
3
|
+
ENTRYPOINT_ADDRESS_V06,
|
|
4
|
+
ENTRYPOINT_ADDRESS_V07,
|
|
5
|
+
getEntryPointVersion,
|
|
6
|
+
isUserOperationVersion06,
|
|
7
|
+
isUserOperationVersion07
|
|
8
|
+
} from "./getEntryPointVersion"
|
|
9
|
+
|
|
10
|
+
describe("getEntryPointVersion", () => {
|
|
11
|
+
describe("getEntryPointVersion", () => {
|
|
12
|
+
test('should return "v0.6" for ENTRYPOINT_ADDRESS_V06', () => {
|
|
13
|
+
expect(getEntryPointVersion(ENTRYPOINT_ADDRESS_V06)).toBe("v0.6")
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('should return "v0.7" for ENTRYPOINT_ADDRESS_V07', () => {
|
|
17
|
+
expect(getEntryPointVersion(ENTRYPOINT_ADDRESS_V07)).toBe("v0.7")
|
|
18
|
+
})
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
describe("isUserOperationVersion06", () => {
|
|
22
|
+
test('should return true for ENTRYPOINT_ADDRESS_V06 and UserOperation<"v0.6">', () => {
|
|
23
|
+
const userOperation = {} as any // mock UserOperation<"v0.6">
|
|
24
|
+
expect(
|
|
25
|
+
isUserOperationVersion06(ENTRYPOINT_ADDRESS_V06, userOperation)
|
|
26
|
+
).toBe(true)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
test('should return false for ENTRYPOINT_ADDRESS_V07 and UserOperation<"v0.6">', () => {
|
|
30
|
+
const userOperation = {} as any // mock UserOperation<"v0.6">
|
|
31
|
+
expect(
|
|
32
|
+
isUserOperationVersion06(ENTRYPOINT_ADDRESS_V07, userOperation)
|
|
33
|
+
).toBe(false)
|
|
34
|
+
})
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
describe("isUserOperationVersion07", () => {
|
|
38
|
+
test('should return false for ENTRYPOINT_ADDRESS_V06 and UserOperation<"v0.6">', () => {
|
|
39
|
+
const userOperation = {} as any // mock UserOperation<"v0.6">
|
|
40
|
+
expect(
|
|
41
|
+
isUserOperationVersion07(ENTRYPOINT_ADDRESS_V06, userOperation)
|
|
42
|
+
).toBe(false)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test('should return true for ENTRYPOINT_ADDRESS_V07 and UserOperation<"v0.7">', () => {
|
|
46
|
+
const userOperation = {} as any // mock UserOperation<"v0.7">
|
|
47
|
+
expect(
|
|
48
|
+
isUserOperationVersion07(ENTRYPOINT_ADDRESS_V07, userOperation)
|
|
49
|
+
).toBe(true)
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
})
|