permissionless 0.2.44 → 0.2.46
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/biconomy/toBiconomySmartAccount.js.map +1 -1
- package/_cjs/accounts/etherspot/toEtherspotSmartAccount.js.map +1 -1
- package/_cjs/accounts/kernel/toKernelSmartAccount.js.map +1 -1
- package/_cjs/accounts/light/toLightSmartAccount.js.map +1 -1
- package/_cjs/accounts/nexus/toNexusSmartAccount.js.map +1 -1
- package/_cjs/accounts/safe/toSafeSmartAccount.js.map +1 -1
- package/_cjs/accounts/simple/toSimpleSmartAccount.js +208 -178
- package/_cjs/accounts/simple/toSimpleSmartAccount.js.map +1 -1
- package/_cjs/accounts/thirdweb/toThirdwebSmartAccount.js.map +1 -1
- package/_cjs/accounts/trust/toTrustSmartAccount.js.map +1 -1
- package/_cjs/actions/smartAccount/sendTransaction.js +1 -0
- package/_cjs/actions/smartAccount/sendTransaction.js.map +1 -1
- package/_cjs/clients/decorators/pimlico.js.map +1 -1
- package/_cjs/clients/pimlico.js.map +1 -1
- package/_cjs/experimental/pimlico/utils/prepareUserOperationForErc20Paymaster.js.map +1 -1
- package/_cjs/utils/getEstimationCallData.js +13 -0
- package/_cjs/utils/getEstimationCallData.js.map +1 -1
- package/_cjs/utils/getRequiredPrefund.js.map +1 -1
- package/_esm/accounts/biconomy/toBiconomySmartAccount.js.map +1 -1
- package/_esm/accounts/etherspot/toEtherspotSmartAccount.js.map +1 -1
- package/_esm/accounts/kernel/toKernelSmartAccount.js.map +1 -1
- package/_esm/accounts/light/toLightSmartAccount.js.map +1 -1
- package/_esm/accounts/nexus/toNexusSmartAccount.js.map +1 -1
- package/_esm/accounts/safe/toSafeSmartAccount.js.map +1 -1
- package/_esm/accounts/simple/toSimpleSmartAccount.js +211 -179
- package/_esm/accounts/simple/toSimpleSmartAccount.js.map +1 -1
- package/_esm/accounts/thirdweb/toThirdwebSmartAccount.js.map +1 -1
- package/_esm/accounts/trust/toTrustSmartAccount.js.map +1 -1
- package/_esm/actions/smartAccount/sendTransaction.js +1 -0
- package/_esm/actions/smartAccount/sendTransaction.js.map +1 -1
- package/_esm/clients/decorators/pimlico.js.map +1 -1
- package/_esm/clients/pimlico.js.map +1 -1
- package/_esm/experimental/pimlico/utils/prepareUserOperationForErc20Paymaster.js.map +1 -1
- package/_esm/utils/getEstimationCallData.js +13 -0
- package/_esm/utils/getEstimationCallData.js.map +1 -1
- package/_esm/utils/getRequiredPrefund.js.map +1 -1
- package/_types/accounts/biconomy/toBiconomySmartAccount.d.ts +2 -2
- package/_types/accounts/biconomy/toBiconomySmartAccount.d.ts.map +1 -1
- package/_types/accounts/etherspot/toEtherspotSmartAccount.d.ts +2 -2
- package/_types/accounts/etherspot/toEtherspotSmartAccount.d.ts.map +1 -1
- package/_types/accounts/kernel/toKernelSmartAccount.d.ts +2 -2
- package/_types/accounts/kernel/toKernelSmartAccount.d.ts.map +1 -1
- package/_types/accounts/light/toLightSmartAccount.d.ts +2 -2
- package/_types/accounts/light/toLightSmartAccount.d.ts.map +1 -1
- package/_types/accounts/nexus/toNexusSmartAccount.d.ts +2 -2
- package/_types/accounts/nexus/toNexusSmartAccount.d.ts.map +1 -1
- package/_types/accounts/safe/toSafeSmartAccount.d.ts +2 -2
- package/_types/accounts/safe/toSafeSmartAccount.d.ts.map +1 -1
- package/_types/accounts/simple/toSimpleSmartAccount.d.ts +2303 -7
- package/_types/accounts/simple/toSimpleSmartAccount.d.ts.map +1 -1
- package/_types/accounts/thirdweb/toThirdwebSmartAccount.d.ts +2 -2
- package/_types/accounts/thirdweb/toThirdwebSmartAccount.d.ts.map +1 -1
- package/_types/accounts/trust/toTrustSmartAccount.d.ts +2 -2
- package/_types/accounts/trust/toTrustSmartAccount.d.ts.map +1 -1
- package/_types/actions/pimlico/sponsorUserOperation.d.ts +4 -4
- package/_types/actions/pimlico/sponsorUserOperation.d.ts.map +1 -1
- package/_types/actions/smartAccount/sendTransaction.d.ts.map +1 -1
- package/_types/clients/decorators/pimlico.d.ts +3 -2
- package/_types/clients/decorators/pimlico.d.ts.map +1 -1
- package/_types/clients/pimlico.d.ts +4 -4
- package/_types/clients/pimlico.d.ts.map +1 -1
- package/_types/types/pimlico.d.ts +3 -3
- package/_types/types/pimlico.d.ts.map +1 -1
- package/_types/utils/getEstimationCallData.d.ts +3 -3
- package/_types/utils/getEstimationCallData.d.ts.map +1 -1
- package/_types/utils/getRequiredPrefund.d.ts +3 -3
- package/_types/utils/getRequiredPrefund.d.ts.map +1 -1
- package/accounts/biconomy/toBiconomySmartAccount.ts +6 -1
- package/accounts/decodeCalls.test.ts +161 -0
- package/accounts/etherspot/toEtherspotSmartAccount.ts +6 -1
- package/accounts/kernel/toKernelSmartAccount.ts +6 -1
- package/accounts/light/toLightSmartAccount.ts +6 -1
- package/accounts/nexus/toNexusSmartAccount.ts +6 -1
- package/accounts/safe/toSafeSmartAccount.ts +6 -1
- package/accounts/simple/toSimpleSmartAccount.ts +243 -197
- package/accounts/thirdweb/toThirdwebSmartAccount.ts +6 -1
- package/accounts/trust/toTrustSmartAccount.ts +6 -1
- package/actions/pimlico/getTokenQuotes.test.ts +55 -1
- package/actions/pimlico/getUserOperationGasPrice.test.ts +50 -0
- package/actions/pimlico/getUserOperationStatus.test.ts +62 -0
- package/actions/pimlico/sponsorUserOperation.test.ts +51 -0
- package/actions/pimlico/sponsorUserOperation.ts +4 -4
- package/actions/pimlico/validateSponsorshipPolicies.test.ts +98 -2
- package/actions/public/getAccountNonce.test.ts +27 -0
- package/actions/public/getSenderAddress.test.ts +37 -1
- package/actions/smartAccount/sendTransaction.test.ts +121 -1
- package/actions/smartAccount/sendTransaction.ts +1 -0
- package/actions/smartAccount/signMessage.test.ts +59 -0
- package/actions/smartAccount/signTypedData.test.ts +54 -0
- package/clients/decorators/pimlico.ts +3 -2
- package/clients/pimlico.ts +4 -3
- package/experimental/pimlico/utils/prepareUserOperationForErc20Paymaster.test.ts +208 -43
- package/experimental/pimlico/utils/prepareUserOperationForErc20Paymaster.ts +1 -1
- package/package.json +2 -2
- package/types/pimlico.ts +12 -2
- package/utils/getEstimationCallData.ts +25 -7
- package/utils/getRequiredPrefund.ts +6 -4
|
@@ -48,6 +48,7 @@ describe.each(getCoreSmartAccounts())(
|
|
|
48
48
|
isEip1271Compliant,
|
|
49
49
|
supportsEntryPointV06,
|
|
50
50
|
supportsEntryPointV07,
|
|
51
|
+
supportsEntryPointV08,
|
|
51
52
|
name
|
|
52
53
|
}) => {
|
|
53
54
|
testWithRpc.skipIf(isEip1271Compliant || !supportsEntryPointV06)(
|
|
@@ -144,5 +145,58 @@ describe.each(getCoreSmartAccounts())(
|
|
|
144
145
|
expect(isVerified).toBeTruthy()
|
|
145
146
|
}
|
|
146
147
|
)
|
|
148
|
+
|
|
149
|
+
testWithRpc.skipIf(isEip1271Compliant || !supportsEntryPointV08)(
|
|
150
|
+
"not isEip1271Compliant_v08",
|
|
151
|
+
async ({ rpc }) => {
|
|
152
|
+
const smartClient = await getSmartAccountClient({
|
|
153
|
+
entryPoint: {
|
|
154
|
+
version: "0.8"
|
|
155
|
+
},
|
|
156
|
+
...rpc
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
await expect(async () =>
|
|
160
|
+
signTypedData(smartClient, typedData)
|
|
161
|
+
).rejects.toThrow()
|
|
162
|
+
}
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
testWithRpc.skipIf(!isEip1271Compliant || !supportsEntryPointV08)(
|
|
166
|
+
"isEip1271Compliant_v08",
|
|
167
|
+
async ({ rpc }) => {
|
|
168
|
+
const { anvilRpc } = rpc
|
|
169
|
+
|
|
170
|
+
const smartClient = await getSmartAccountClient({
|
|
171
|
+
entryPoint: {
|
|
172
|
+
version: "0.8"
|
|
173
|
+
},
|
|
174
|
+
...rpc
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
const signature = await signTypedData(smartClient, typedData)
|
|
178
|
+
|
|
179
|
+
const publicClient = getPublicClient(anvilRpc)
|
|
180
|
+
|
|
181
|
+
if (name === "LightAccount 2.0.0") {
|
|
182
|
+
// LightAccount 2.0.0 doesn't support EIP-1271
|
|
183
|
+
return
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (name.includes("Safe 7579")) {
|
|
187
|
+
// Due to 7579 launchpad, we can't verify the signature before deploying the account.
|
|
188
|
+
await smartClient.sendTransaction({
|
|
189
|
+
calls: [{ to: zeroAddress, value: 0n }]
|
|
190
|
+
})
|
|
191
|
+
}
|
|
192
|
+
const isVerified = await publicClient.verifyTypedData({
|
|
193
|
+
...typedData,
|
|
194
|
+
address: smartClient.account.address,
|
|
195
|
+
signature
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
expect(isVerified).toBeTruthy()
|
|
199
|
+
}
|
|
200
|
+
)
|
|
147
201
|
}
|
|
148
202
|
)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Address, Chain, Client, Hash, Prettify, Transport } from "viem"
|
|
2
|
+
import type { EntryPointVersion } from "viem/account-abstraction"
|
|
2
3
|
import {
|
|
3
4
|
type GetTokenQuotesParameters,
|
|
4
5
|
type GetTokenQuotesReturnType,
|
|
@@ -26,7 +27,7 @@ import {
|
|
|
26
27
|
|
|
27
28
|
export type PimlicoActions<
|
|
28
29
|
TChain extends Chain | undefined,
|
|
29
|
-
entryPointVersion extends
|
|
30
|
+
entryPointVersion extends EntryPointVersion = EntryPointVersion
|
|
30
31
|
> = {
|
|
31
32
|
/**
|
|
32
33
|
* Returns the live gas prices that you can use to send a user operation.
|
|
@@ -126,7 +127,7 @@ export type PimlicoActions<
|
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
export const pimlicoActions =
|
|
129
|
-
<entryPointVersion extends
|
|
130
|
+
<entryPointVersion extends EntryPointVersion>({
|
|
130
131
|
entryPoint
|
|
131
132
|
}: {
|
|
132
133
|
entryPoint: { address: Address; version: entryPointVersion }
|
package/clients/pimlico.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
import { createClient } from "viem"
|
|
12
12
|
import {
|
|
13
13
|
type BundlerActions,
|
|
14
|
+
type EntryPointVersion,
|
|
14
15
|
type PaymasterActions,
|
|
15
16
|
type SmartAccount,
|
|
16
17
|
bundlerActions,
|
|
@@ -21,7 +22,7 @@ import type { PimlicoRpcSchema } from "../types/pimlico.js"
|
|
|
21
22
|
import { type PimlicoActions, pimlicoActions } from "./decorators/pimlico.js"
|
|
22
23
|
|
|
23
24
|
export type PimlicoClient<
|
|
24
|
-
entryPointVersion extends
|
|
25
|
+
entryPointVersion extends EntryPointVersion = EntryPointVersion,
|
|
25
26
|
transport extends Transport = Transport,
|
|
26
27
|
chain extends Chain | undefined = Chain | undefined,
|
|
27
28
|
account extends SmartAccount | undefined = SmartAccount | undefined,
|
|
@@ -47,7 +48,7 @@ export type PimlicoClient<
|
|
|
47
48
|
>
|
|
48
49
|
|
|
49
50
|
export type PimlicoClientConfig<
|
|
50
|
-
entryPointVersion extends
|
|
51
|
+
entryPointVersion extends EntryPointVersion = EntryPointVersion,
|
|
51
52
|
transport extends Transport = Transport,
|
|
52
53
|
chain extends Chain | undefined = Chain | undefined,
|
|
53
54
|
account extends SmartAccount | undefined = SmartAccount | undefined,
|
|
@@ -72,7 +73,7 @@ export type PimlicoClientConfig<
|
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
export function createPimlicoClient<
|
|
75
|
-
entryPointVersion extends
|
|
76
|
+
entryPointVersion extends EntryPointVersion = "0.7",
|
|
76
77
|
transport extends Transport = Transport,
|
|
77
78
|
chain extends Chain | undefined = undefined,
|
|
78
79
|
account extends SmartAccount | undefined = SmartAccount | undefined,
|
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import { http, parseEther, zeroAddress } from "viem"
|
|
2
2
|
import {
|
|
3
3
|
entryPoint06Address,
|
|
4
|
-
entryPoint07Address
|
|
4
|
+
entryPoint07Address,
|
|
5
|
+
entryPoint08Address
|
|
5
6
|
} from "viem/account-abstraction"
|
|
6
7
|
import { foundry } from "viem/chains"
|
|
7
8
|
import { describe, expect } from "vitest"
|
|
8
9
|
import {
|
|
9
|
-
|
|
10
|
+
erc20Address,
|
|
10
11
|
sudoMintTokens,
|
|
11
12
|
tokenBalanceOf
|
|
12
|
-
} from "../../../../mock-paymaster/helpers/erc20-utils
|
|
13
|
-
import { testWithRpc } from "../../../../permissionless-test/src/testWithRpc
|
|
13
|
+
} from "../../../../mock-paymaster/helpers/erc20-utils"
|
|
14
|
+
import { testWithRpc } from "../../../../permissionless-test/src/testWithRpc"
|
|
14
15
|
import {
|
|
15
16
|
getCoreSmartAccounts,
|
|
16
17
|
getPublicClient
|
|
17
18
|
} from "../../../../permissionless-test/src/utils"
|
|
18
|
-
import { createSmartAccountClient } from "../../../clients/createSmartAccountClient
|
|
19
|
-
import { createPimlicoClient } from "../../../clients/pimlico
|
|
20
|
-
import { prepareUserOperationForErc20Paymaster } from "./prepareUserOperationForErc20Paymaster
|
|
19
|
+
import { createSmartAccountClient } from "../../../clients/createSmartAccountClient"
|
|
20
|
+
import { createPimlicoClient } from "../../../clients/pimlico"
|
|
21
|
+
import { prepareUserOperationForErc20Paymaster } from "./prepareUserOperationForErc20Paymaster"
|
|
21
22
|
|
|
22
23
|
describe.each(getCoreSmartAccounts())(
|
|
23
24
|
"prepareUserOperationForErc20Paymaster $name",
|
|
@@ -25,9 +26,10 @@ describe.each(getCoreSmartAccounts())(
|
|
|
25
26
|
getSmartAccountClient,
|
|
26
27
|
supportsEntryPointV06,
|
|
27
28
|
supportsEntryPointV07,
|
|
29
|
+
supportsEntryPointV08,
|
|
28
30
|
name
|
|
29
31
|
}) => {
|
|
30
|
-
testWithRpc.skipIf(!supportsEntryPointV06)(
|
|
32
|
+
testWithRpc.skipIf(!supportsEntryPointV06 || name === "Kernel 0.2.1")(
|
|
31
33
|
"prepareUserOperationForErc20Paymaster_v06",
|
|
32
34
|
async ({ rpc }) => {
|
|
33
35
|
const { anvilRpc } = rpc
|
|
@@ -84,7 +86,7 @@ describe.each(getCoreSmartAccounts())(
|
|
|
84
86
|
}
|
|
85
87
|
],
|
|
86
88
|
paymasterContext: {
|
|
87
|
-
token:
|
|
89
|
+
token: erc20Address
|
|
88
90
|
}
|
|
89
91
|
})
|
|
90
92
|
|
|
@@ -96,21 +98,17 @@ describe.each(getCoreSmartAccounts())(
|
|
|
96
98
|
expect(receipt).toBeTruthy()
|
|
97
99
|
expect(receipt).toBeTruthy()
|
|
98
100
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
})
|
|
101
|
+
expect(receipt.success).toBeTruthy()
|
|
102
|
+
const FINAL_TOKEN_BALANCE = await tokenBalanceOf(
|
|
103
|
+
smartAccountClient.account.address,
|
|
104
|
+
rpc.anvilRpc
|
|
105
|
+
)
|
|
106
|
+
const FINAL_ETH_BALANCE = await publicClient.getBalance({
|
|
107
|
+
address: smartAccountClient.account.address
|
|
108
|
+
})
|
|
108
109
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
) // Token balance should be deducted
|
|
112
|
-
expect(FINAL_ETH_BALANCE).toEqual(INTIAL_ETH_BALANCE) // There should be no ETH balance change
|
|
113
|
-
}
|
|
110
|
+
expect(FINAL_TOKEN_BALANCE).toBeLessThan(INITIAL_TOKEN_BALANCE) // Token balance should be deducted
|
|
111
|
+
expect(FINAL_ETH_BALANCE).toEqual(INTIAL_ETH_BALANCE) // There should be no ETH balance change
|
|
114
112
|
}
|
|
115
113
|
)
|
|
116
114
|
|
|
@@ -171,7 +169,90 @@ describe.each(getCoreSmartAccounts())(
|
|
|
171
169
|
}
|
|
172
170
|
],
|
|
173
171
|
paymasterContext: {
|
|
174
|
-
token:
|
|
172
|
+
token: erc20Address
|
|
173
|
+
}
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
const receipt =
|
|
177
|
+
await smartAccountClient.waitForUserOperationReceipt({
|
|
178
|
+
hash: opHash
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
expect(receipt).toBeTruthy()
|
|
182
|
+
expect(receipt).toBeTruthy()
|
|
183
|
+
expect(receipt.success).toBeTruthy()
|
|
184
|
+
|
|
185
|
+
const FINAL_TOKEN_BALANCE = await tokenBalanceOf(
|
|
186
|
+
smartAccountClient.account.address,
|
|
187
|
+
rpc.anvilRpc
|
|
188
|
+
)
|
|
189
|
+
const FINAL_ETH_BALANCE = await publicClient.getBalance({
|
|
190
|
+
address: smartAccountClient.account.address
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
expect(FINAL_TOKEN_BALANCE).toBeLessThan(INITIAL_TOKEN_BALANCE) // Token balance should be deducted
|
|
194
|
+
expect(FINAL_ETH_BALANCE).toEqual(INTIAL_ETH_BALANCE) // There should be no ETH balance change
|
|
195
|
+
}
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
testWithRpc.skipIf(!supportsEntryPointV08)(
|
|
199
|
+
"prepareUserOperationForErc20Paymaster_v08",
|
|
200
|
+
async ({ rpc }) => {
|
|
201
|
+
const { anvilRpc } = rpc
|
|
202
|
+
|
|
203
|
+
const account = (
|
|
204
|
+
await getSmartAccountClient({
|
|
205
|
+
entryPoint: {
|
|
206
|
+
version: "0.8"
|
|
207
|
+
},
|
|
208
|
+
...rpc
|
|
209
|
+
})
|
|
210
|
+
).account
|
|
211
|
+
|
|
212
|
+
const publicClient = getPublicClient(anvilRpc)
|
|
213
|
+
|
|
214
|
+
const pimlicoClient = createPimlicoClient({
|
|
215
|
+
transport: http(rpc.paymasterRpc),
|
|
216
|
+
entryPoint: {
|
|
217
|
+
address: entryPoint08Address,
|
|
218
|
+
version: "0.8"
|
|
219
|
+
}
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
const smartAccountClient = createSmartAccountClient({
|
|
223
|
+
// @ts-ignore
|
|
224
|
+
client: getPublicClient(anvilRpc),
|
|
225
|
+
account,
|
|
226
|
+
paymaster: pimlicoClient,
|
|
227
|
+
chain: foundry,
|
|
228
|
+
userOperation: {
|
|
229
|
+
prepareUserOperation:
|
|
230
|
+
prepareUserOperationForErc20Paymaster(pimlicoClient)
|
|
231
|
+
},
|
|
232
|
+
bundlerTransport: http(rpc.altoRpc)
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
const INITIAL_TOKEN_BALANCE = parseEther("100")
|
|
236
|
+
const INTIAL_ETH_BALANCE = await publicClient.getBalance({
|
|
237
|
+
address: smartAccountClient.account.address
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
sudoMintTokens({
|
|
241
|
+
amount: INITIAL_TOKEN_BALANCE,
|
|
242
|
+
to: smartAccountClient.account.address,
|
|
243
|
+
anvilRpc
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
const opHash = await smartAccountClient.sendUserOperation({
|
|
247
|
+
calls: [
|
|
248
|
+
{
|
|
249
|
+
to: zeroAddress,
|
|
250
|
+
data: "0x",
|
|
251
|
+
value: 0n
|
|
252
|
+
}
|
|
253
|
+
],
|
|
254
|
+
paymasterContext: {
|
|
255
|
+
token: erc20Address
|
|
175
256
|
}
|
|
176
257
|
})
|
|
177
258
|
|
|
@@ -259,7 +340,7 @@ describe.each(getCoreSmartAccounts())(
|
|
|
259
340
|
}
|
|
260
341
|
],
|
|
261
342
|
paymasterContext: {
|
|
262
|
-
token:
|
|
343
|
+
token: erc20Address
|
|
263
344
|
}
|
|
264
345
|
})
|
|
265
346
|
|
|
@@ -285,7 +366,95 @@ describe.each(getCoreSmartAccounts())(
|
|
|
285
366
|
}
|
|
286
367
|
)
|
|
287
368
|
|
|
288
|
-
testWithRpc.skipIf(!
|
|
369
|
+
testWithRpc.skipIf(!supportsEntryPointV08)(
|
|
370
|
+
"prepareUserOperationForErc20Paymaster_v08 (balanceOverride enabled)",
|
|
371
|
+
async ({ rpc }) => {
|
|
372
|
+
const { anvilRpc } = rpc
|
|
373
|
+
|
|
374
|
+
const account = (
|
|
375
|
+
await getSmartAccountClient({
|
|
376
|
+
entryPoint: {
|
|
377
|
+
version: "0.8"
|
|
378
|
+
},
|
|
379
|
+
...rpc
|
|
380
|
+
})
|
|
381
|
+
).account
|
|
382
|
+
|
|
383
|
+
const publicClient = getPublicClient(anvilRpc)
|
|
384
|
+
|
|
385
|
+
const pimlicoClient = createPimlicoClient({
|
|
386
|
+
transport: http(rpc.paymasterRpc),
|
|
387
|
+
entryPoint: {
|
|
388
|
+
address: entryPoint08Address,
|
|
389
|
+
version: "0.8"
|
|
390
|
+
}
|
|
391
|
+
})
|
|
392
|
+
|
|
393
|
+
const smartAccountClient = createSmartAccountClient({
|
|
394
|
+
// @ts-ignore
|
|
395
|
+
client: getPublicClient(anvilRpc),
|
|
396
|
+
account,
|
|
397
|
+
paymaster: pimlicoClient,
|
|
398
|
+
chain: foundry,
|
|
399
|
+
userOperation: {
|
|
400
|
+
prepareUserOperation:
|
|
401
|
+
prepareUserOperationForErc20Paymaster(
|
|
402
|
+
pimlicoClient,
|
|
403
|
+
{
|
|
404
|
+
balanceOverride: true
|
|
405
|
+
}
|
|
406
|
+
)
|
|
407
|
+
},
|
|
408
|
+
bundlerTransport: http(rpc.altoRpc)
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
const INITIAL_TOKEN_BALANCE = parseEther("100")
|
|
412
|
+
const INTIAL_ETH_BALANCE = await publicClient.getBalance({
|
|
413
|
+
address: smartAccountClient.account.address
|
|
414
|
+
})
|
|
415
|
+
|
|
416
|
+
sudoMintTokens({
|
|
417
|
+
amount: INITIAL_TOKEN_BALANCE,
|
|
418
|
+
to: smartAccountClient.account.address,
|
|
419
|
+
anvilRpc
|
|
420
|
+
})
|
|
421
|
+
|
|
422
|
+
const opHash = await smartAccountClient.sendUserOperation({
|
|
423
|
+
calls: [
|
|
424
|
+
{
|
|
425
|
+
to: zeroAddress,
|
|
426
|
+
data: "0x",
|
|
427
|
+
value: 0n
|
|
428
|
+
}
|
|
429
|
+
],
|
|
430
|
+
paymasterContext: {
|
|
431
|
+
token: erc20Address
|
|
432
|
+
}
|
|
433
|
+
})
|
|
434
|
+
|
|
435
|
+
const receipt =
|
|
436
|
+
await smartAccountClient.waitForUserOperationReceipt({
|
|
437
|
+
hash: opHash
|
|
438
|
+
})
|
|
439
|
+
|
|
440
|
+
expect(receipt).toBeTruthy()
|
|
441
|
+
expect(receipt).toBeTruthy()
|
|
442
|
+
expect(receipt.success).toBeTruthy()
|
|
443
|
+
|
|
444
|
+
const FINAL_TOKEN_BALANCE = await tokenBalanceOf(
|
|
445
|
+
smartAccountClient.account.address,
|
|
446
|
+
rpc.anvilRpc
|
|
447
|
+
)
|
|
448
|
+
const FINAL_ETH_BALANCE = await publicClient.getBalance({
|
|
449
|
+
address: smartAccountClient.account.address
|
|
450
|
+
})
|
|
451
|
+
|
|
452
|
+
expect(FINAL_TOKEN_BALANCE).toBeLessThan(INITIAL_TOKEN_BALANCE) // Token balance should be deducted
|
|
453
|
+
expect(FINAL_ETH_BALANCE).toEqual(INTIAL_ETH_BALANCE) // There should be no ETH balance change
|
|
454
|
+
}
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
testWithRpc.skipIf(!supportsEntryPointV06 || name === "Kernel 0.2.1")(
|
|
289
458
|
"prepareUserOperationForErc20Paymaster_v06",
|
|
290
459
|
async ({ rpc }) => {
|
|
291
460
|
const { anvilRpc } = rpc
|
|
@@ -342,7 +511,7 @@ describe.each(getCoreSmartAccounts())(
|
|
|
342
511
|
}
|
|
343
512
|
]),
|
|
344
513
|
paymasterContext: {
|
|
345
|
-
token:
|
|
514
|
+
token: erc20Address
|
|
346
515
|
}
|
|
347
516
|
})
|
|
348
517
|
|
|
@@ -354,21 +523,17 @@ describe.each(getCoreSmartAccounts())(
|
|
|
354
523
|
expect(receipt).toBeTruthy()
|
|
355
524
|
expect(receipt).toBeTruthy()
|
|
356
525
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
})
|
|
526
|
+
expect(receipt.success).toBeTruthy()
|
|
527
|
+
const FINAL_TOKEN_BALANCE = await tokenBalanceOf(
|
|
528
|
+
smartAccountClient.account.address,
|
|
529
|
+
rpc.anvilRpc
|
|
530
|
+
)
|
|
531
|
+
const FINAL_ETH_BALANCE = await publicClient.getBalance({
|
|
532
|
+
address: smartAccountClient.account.address
|
|
533
|
+
})
|
|
366
534
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
) // Token balance should be deducted
|
|
370
|
-
expect(FINAL_ETH_BALANCE).toEqual(INTIAL_ETH_BALANCE) // There should be no ETH balance change
|
|
371
|
-
}
|
|
535
|
+
expect(FINAL_TOKEN_BALANCE).toBeLessThan(INITIAL_TOKEN_BALANCE) // Token balance should be deducted
|
|
536
|
+
expect(FINAL_ETH_BALANCE).toEqual(INTIAL_ETH_BALANCE) // There should be no ETH balance change
|
|
372
537
|
}
|
|
373
538
|
)
|
|
374
539
|
|
|
@@ -429,7 +594,7 @@ describe.each(getCoreSmartAccounts())(
|
|
|
429
594
|
}
|
|
430
595
|
]),
|
|
431
596
|
paymasterContext: {
|
|
432
|
-
token:
|
|
597
|
+
token: erc20Address
|
|
433
598
|
}
|
|
434
599
|
})
|
|
435
600
|
|
|
@@ -517,7 +682,7 @@ describe.each(getCoreSmartAccounts())(
|
|
|
517
682
|
}
|
|
518
683
|
]),
|
|
519
684
|
paymasterContext: {
|
|
520
|
-
token:
|
|
685
|
+
token: erc20Address
|
|
521
686
|
}
|
|
522
687
|
})
|
|
523
688
|
|
|
@@ -68,7 +68,7 @@ export const prepareUserOperationForErc20Paymaster =
|
|
|
68
68
|
const account_ = client.account
|
|
69
69
|
|
|
70
70
|
if (!account_) throw new Error("Account not found")
|
|
71
|
-
const account = parseAccount(account_)
|
|
71
|
+
const account = parseAccount<SmartAccount>(account_)
|
|
72
72
|
|
|
73
73
|
const bundlerClient = client as unknown as BundlerClient
|
|
74
74
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "permissionless",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.46",
|
|
4
4
|
"author": "Pimlico",
|
|
5
5
|
"homepage": "https://docs.pimlico.io/permissionless",
|
|
6
6
|
"repository": "github:pimlicolabs/permissionless.js",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
}
|
|
98
98
|
},
|
|
99
99
|
"peerDependencies": {
|
|
100
|
-
"viem": "^2.
|
|
100
|
+
"viem": "^2.28.1",
|
|
101
101
|
"ox": "0.6.7"
|
|
102
102
|
},
|
|
103
103
|
"peerDependenciesMeta": {
|
package/types/pimlico.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Address, Hash, Hex, OneOf, PartialBy } from "viem"
|
|
2
|
-
import type { UserOperation } from "viem/account-abstraction"
|
|
2
|
+
import type { EntryPointVersion, UserOperation } from "viem/account-abstraction"
|
|
3
3
|
|
|
4
4
|
type PimlicoUserOperationGasPriceWithBigIntAsHex = {
|
|
5
5
|
slow: {
|
|
@@ -41,7 +41,7 @@ type GetTokenQuotesWithBigIntAsHex = {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
export type PimlicoRpcSchema<
|
|
44
|
-
entryPointVersion extends
|
|
44
|
+
entryPointVersion extends EntryPointVersion = EntryPointVersion
|
|
45
45
|
> = [
|
|
46
46
|
{
|
|
47
47
|
Method: "pimlico_getUserOperationGasPrice"
|
|
@@ -84,6 +84,16 @@ export type PimlicoRpcSchema<
|
|
|
84
84
|
| "paymasterPostOpGasLimit"
|
|
85
85
|
>
|
|
86
86
|
: never)
|
|
87
|
+
| (entryPointVersion extends "0.8"
|
|
88
|
+
? PartialBy<
|
|
89
|
+
UserOperation<"0.7", Hex>,
|
|
90
|
+
| "callGasLimit"
|
|
91
|
+
| "preVerificationGas"
|
|
92
|
+
| "verificationGasLimit"
|
|
93
|
+
| "paymasterVerificationGasLimit"
|
|
94
|
+
| "paymasterPostOpGasLimit"
|
|
95
|
+
>
|
|
96
|
+
: never)
|
|
87
97
|
>,
|
|
88
98
|
entryPoint: Address,
|
|
89
99
|
metadata?: {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Address, type Hex, encodeFunctionData } from "viem"
|
|
2
2
|
import {
|
|
3
|
+
type EntryPointVersion,
|
|
3
4
|
type UserOperation,
|
|
4
5
|
entryPoint06Abi,
|
|
5
6
|
toPackedUserOperation
|
|
@@ -44,7 +45,7 @@ function getPimlicoEstimationCallData06({
|
|
|
44
45
|
function encodeSimulateHandleOpLast({
|
|
45
46
|
userOperation
|
|
46
47
|
}: {
|
|
47
|
-
userOperation: UserOperation<"0.7">
|
|
48
|
+
userOperation: UserOperation<"0.7" | "0.8">
|
|
48
49
|
}): Hex {
|
|
49
50
|
const userOperations = [userOperation]
|
|
50
51
|
const packedUserOperations = userOperations.map((uop) => ({
|
|
@@ -177,11 +178,11 @@ function getPimlicoEstimationCallData07({
|
|
|
177
178
|
estimationAddress,
|
|
178
179
|
entrypoint
|
|
179
180
|
}: {
|
|
180
|
-
userOperation: UserOperation<"0.7">
|
|
181
|
+
userOperation: UserOperation<"0.7" | "0.8">
|
|
181
182
|
estimationAddress?: Address
|
|
182
183
|
entrypoint: {
|
|
183
184
|
address: Address
|
|
184
|
-
version: "0.7"
|
|
185
|
+
version: "0.7" | "0.8"
|
|
185
186
|
}
|
|
186
187
|
}): { to: Address; data: Hex } {
|
|
187
188
|
const simulateHandleOpLast = encodeSimulateHandleOpLast({
|
|
@@ -224,7 +225,7 @@ function getPimlicoEstimationCallData07({
|
|
|
224
225
|
}
|
|
225
226
|
|
|
226
227
|
export type GetPimlicoEstimationCallDataParams<
|
|
227
|
-
entryPointVersion extends
|
|
228
|
+
entryPointVersion extends EntryPointVersion
|
|
228
229
|
> = {
|
|
229
230
|
userOperation: UserOperation<entryPointVersion>
|
|
230
231
|
entrypoint: {
|
|
@@ -238,19 +239,25 @@ export type GetPimlicoEstimationCallDataParams<
|
|
|
238
239
|
: { estimationAddress?: Address })
|
|
239
240
|
|
|
240
241
|
function isEntryPoint06(
|
|
241
|
-
args: GetPimlicoEstimationCallDataParams<
|
|
242
|
+
args: GetPimlicoEstimationCallDataParams<EntryPointVersion>
|
|
242
243
|
): args is GetPimlicoEstimationCallDataParams<"0.6"> {
|
|
243
244
|
return args.entrypoint.version === "0.6"
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
function isEntryPoint07(
|
|
247
|
-
args: GetPimlicoEstimationCallDataParams<
|
|
248
|
+
args: GetPimlicoEstimationCallDataParams<EntryPointVersion>
|
|
248
249
|
): args is GetPimlicoEstimationCallDataParams<"0.7"> {
|
|
249
250
|
return args.entrypoint.version === "0.7"
|
|
250
251
|
}
|
|
251
252
|
|
|
253
|
+
function isEntryPoint08(
|
|
254
|
+
args: GetPimlicoEstimationCallDataParams<EntryPointVersion>
|
|
255
|
+
): args is GetPimlicoEstimationCallDataParams<"0.8"> {
|
|
256
|
+
return args.entrypoint.version === "0.8"
|
|
257
|
+
}
|
|
258
|
+
|
|
252
259
|
export function getPimlicoEstimationCallData<
|
|
253
|
-
entryPointVersion extends
|
|
260
|
+
entryPointVersion extends EntryPointVersion
|
|
254
261
|
>(
|
|
255
262
|
args: GetPimlicoEstimationCallDataParams<entryPointVersion>
|
|
256
263
|
): { to: Address; data: Hex } {
|
|
@@ -275,5 +282,16 @@ export function getPimlicoEstimationCallData<
|
|
|
275
282
|
})
|
|
276
283
|
}
|
|
277
284
|
|
|
285
|
+
if (isEntryPoint08(args)) {
|
|
286
|
+
return getPimlicoEstimationCallData07({
|
|
287
|
+
userOperation: args.userOperation,
|
|
288
|
+
estimationAddress: args.estimationAddress,
|
|
289
|
+
entrypoint: {
|
|
290
|
+
address: args.entrypoint.address,
|
|
291
|
+
version: "0.8"
|
|
292
|
+
}
|
|
293
|
+
})
|
|
294
|
+
}
|
|
295
|
+
|
|
278
296
|
throw new Error("Invalid entrypoint version")
|
|
279
297
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { UserOperation } from "viem/account-abstraction"
|
|
1
|
+
import type { EntryPointVersion, UserOperation } from "viem/account-abstraction"
|
|
2
2
|
|
|
3
3
|
export type GetRequiredPrefundReturnType<
|
|
4
|
-
entryPointVersion extends
|
|
4
|
+
entryPointVersion extends EntryPointVersion = "0.7"
|
|
5
5
|
> = {
|
|
6
6
|
userOperation: UserOperation<entryPointVersion>
|
|
7
7
|
entryPointVersion: entryPointVersion
|
|
@@ -21,7 +21,9 @@ export type GetRequiredPrefundReturnType<
|
|
|
21
21
|
* userOperation
|
|
22
22
|
* })
|
|
23
23
|
*/
|
|
24
|
-
export const getRequiredPrefund = <
|
|
24
|
+
export const getRequiredPrefund = <
|
|
25
|
+
entryPointVersion extends EntryPointVersion
|
|
26
|
+
>({
|
|
25
27
|
userOperation,
|
|
26
28
|
entryPointVersion
|
|
27
29
|
}: GetRequiredPrefundReturnType<entryPointVersion>): bigint => {
|
|
@@ -41,7 +43,7 @@ export const getRequiredPrefund = <entryPointVersion extends "0.6" | "0.7">({
|
|
|
41
43
|
)
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
const userOperationV07 = userOperation as UserOperation<"0.7">
|
|
46
|
+
const userOperationV07 = userOperation as UserOperation<"0.7" | "0.8">
|
|
45
47
|
|
|
46
48
|
const requiredGas =
|
|
47
49
|
userOperationV07.verificationGasLimit +
|