permissionless 0.0.13 → 0.0.15

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.
Files changed (77) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/_cjs/accounts/index.js +3 -1
  3. package/_cjs/accounts/index.js.map +1 -1
  4. package/_cjs/accounts/kernel/abi/KernelAccountAbi.js +84 -0
  5. package/_cjs/accounts/kernel/abi/KernelAccountAbi.js.map +1 -0
  6. package/_cjs/accounts/kernel/signerToEcdsaKernelSmartAccount.js +211 -0
  7. package/_cjs/accounts/kernel/signerToEcdsaKernelSmartAccount.js.map +1 -0
  8. package/_cjs/accounts/signerToSafeSmartAccount.js +2 -2
  9. package/_cjs/actions/pimlico/sponsorUserOperation.js +12 -4
  10. package/_cjs/actions/pimlico/sponsorUserOperation.js.map +1 -1
  11. package/_cjs/actions/pimlico/validateSponsorshipPolicies.js +16 -0
  12. package/_cjs/actions/pimlico/validateSponsorshipPolicies.js.map +1 -0
  13. package/_cjs/actions/pimlico.js +3 -1
  14. package/_cjs/actions/pimlico.js.map +1 -1
  15. package/_cjs/clients/createSmartAccountClient.js.map +1 -1
  16. package/_cjs/clients/decorators/pimlico.js +3 -1
  17. package/_cjs/clients/decorators/pimlico.js.map +1 -1
  18. package/_cjs/utils/getRequiredPrefund.js +12 -0
  19. package/_cjs/utils/getRequiredPrefund.js.map +1 -0
  20. package/_cjs/utils/index.js +3 -1
  21. package/_cjs/utils/index.js.map +1 -1
  22. package/_esm/accounts/index.js +2 -1
  23. package/_esm/accounts/index.js.map +1 -1
  24. package/_esm/accounts/kernel/abi/KernelAccountAbi.js +87 -0
  25. package/_esm/accounts/kernel/abi/KernelAccountAbi.js.map +1 -0
  26. package/_esm/accounts/kernel/signerToEcdsaKernelSmartAccount.js +262 -0
  27. package/_esm/accounts/kernel/signerToEcdsaKernelSmartAccount.js.map +1 -0
  28. package/_esm/accounts/signerToSafeSmartAccount.js +2 -2
  29. package/_esm/actions/pimlico/sponsorUserOperation.js +13 -5
  30. package/_esm/actions/pimlico/sponsorUserOperation.js.map +1 -1
  31. package/_esm/actions/pimlico/validateSponsorshipPolicies.js +47 -0
  32. package/_esm/actions/pimlico/validateSponsorshipPolicies.js.map +1 -0
  33. package/_esm/actions/pimlico.js +2 -1
  34. package/_esm/actions/pimlico.js.map +1 -1
  35. package/_esm/clients/createSmartAccountClient.js +1 -1
  36. package/_esm/clients/createSmartAccountClient.js.map +1 -1
  37. package/_esm/clients/decorators/pimlico.js +38 -1
  38. package/_esm/clients/decorators/pimlico.js.map +1 -1
  39. package/_esm/utils/getRequiredPrefund.js +22 -0
  40. package/_esm/utils/getRequiredPrefund.js.map +1 -0
  41. package/_esm/utils/index.js +2 -1
  42. package/_esm/utils/index.js.map +1 -1
  43. package/_types/accounts/index.d.ts +2 -1
  44. package/_types/accounts/index.d.ts.map +1 -1
  45. package/_types/accounts/kernel/abi/KernelAccountAbi.d.ts +68 -0
  46. package/_types/accounts/kernel/abi/KernelAccountAbi.d.ts.map +1 -0
  47. package/_types/accounts/kernel/signerToEcdsaKernelSmartAccount.d.ts +25 -0
  48. package/_types/accounts/kernel/signerToEcdsaKernelSmartAccount.d.ts.map +1 -0
  49. package/_types/actions/pimlico/sponsorUserOperation.d.ts +4 -3
  50. package/_types/actions/pimlico/sponsorUserOperation.d.ts.map +1 -1
  51. package/_types/actions/pimlico/validateSponsorshipPolicies.d.ts +54 -0
  52. package/_types/actions/pimlico/validateSponsorshipPolicies.d.ts.map +1 -0
  53. package/_types/actions/pimlico.d.ts +4 -3
  54. package/_types/actions/pimlico.d.ts.map +1 -1
  55. package/_types/clients/createSmartAccountClient.d.ts +6 -1
  56. package/_types/clients/createSmartAccountClient.d.ts.map +1 -1
  57. package/_types/clients/decorators/pimlico.d.ts +40 -3
  58. package/_types/clients/decorators/pimlico.d.ts.map +1 -1
  59. package/_types/types/pimlico.d.ts +21 -1
  60. package/_types/types/pimlico.d.ts.map +1 -1
  61. package/_types/utils/getRequiredPrefund.d.ts +20 -0
  62. package/_types/utils/getRequiredPrefund.d.ts.map +1 -0
  63. package/_types/utils/index.d.ts +2 -1
  64. package/_types/utils/index.d.ts.map +1 -1
  65. package/accounts/index.ts +8 -1
  66. package/accounts/kernel/abi/KernelAccountAbi.ts +87 -0
  67. package/accounts/kernel/signerToEcdsaKernelSmartAccount.ts +363 -0
  68. package/accounts/signerToSafeSmartAccount.ts +2 -2
  69. package/actions/pimlico/sponsorUserOperation.ts +20 -7
  70. package/actions/pimlico/validateSponsorshipPolicies.ts +76 -0
  71. package/actions/pimlico.ts +13 -4
  72. package/clients/createSmartAccountClient.ts +6 -1
  73. package/clients/decorators/pimlico.ts +52 -5
  74. package/package.json +1 -1
  75. package/types/pimlico.ts +21 -1
  76. package/utils/getRequiredPrefund.ts +31 -0
  77. package/utils/index.ts +6 -0
@@ -0,0 +1,363 @@
1
+ import {
2
+ type Account,
3
+ type Address,
4
+ type Chain,
5
+ type Client,
6
+ type Hex,
7
+ type Transport,
8
+ concatHex,
9
+ encodeFunctionData,
10
+ isAddressEqual
11
+ } from "viem"
12
+ import { toAccount } from "viem/accounts"
13
+ import {
14
+ getBytecode,
15
+ getChainId,
16
+ readContract,
17
+ signMessage,
18
+ signTypedData
19
+ } from "viem/actions"
20
+ import { getAccountNonce } from "../../actions/public/getAccountNonce.js"
21
+ import { getSenderAddress } from "../../actions/public/getSenderAddress.js"
22
+ import { getUserOperationHash } from "../../utils/getUserOperationHash.js"
23
+ import type { SmartAccount } from "../types.js"
24
+ import {
25
+ SignTransactionNotSupportedBySmartAccount,
26
+ type SmartAccountSigner
27
+ } from "../types.js"
28
+ import { KernelExecuteAbi, KernelInitAbi } from "./abi/KernelAccountAbi.js"
29
+
30
+ export type KernelEcdsaSmartAccount<
31
+ transport extends Transport = Transport,
32
+ chain extends Chain | undefined = Chain | undefined
33
+ > = SmartAccount<"kernelEcdsaSmartAccount", transport, chain>
34
+
35
+ /**
36
+ * The account creation ABI for a kernel smart account (from the KernelFactory)
37
+ */
38
+ const createAccountAbi = [
39
+ {
40
+ inputs: [
41
+ {
42
+ internalType: "address",
43
+ name: "_implementation",
44
+ type: "address"
45
+ },
46
+ {
47
+ internalType: "bytes",
48
+ name: "_data",
49
+ type: "bytes"
50
+ },
51
+ {
52
+ internalType: "uint256",
53
+ name: "_index",
54
+ type: "uint256"
55
+ }
56
+ ],
57
+ name: "createAccount",
58
+ outputs: [
59
+ {
60
+ internalType: "address",
61
+ name: "proxy",
62
+ type: "address"
63
+ }
64
+ ],
65
+ stateMutability: "payable",
66
+ type: "function"
67
+ }
68
+ ] as const
69
+
70
+ /**
71
+ * Default addresses for kernel smart account
72
+ */
73
+ const KERNEL_ADDRESSES: {
74
+ ECDSA_VALIDATOR: Address
75
+ ACCOUNT_V2_2_LOGIC: Address
76
+ FACTORY_ADDRESS: Address
77
+ } = {
78
+ ECDSA_VALIDATOR: "0xd9AB5096a832b9ce79914329DAEE236f8Eea0390",
79
+ ACCOUNT_V2_2_LOGIC: "0x0DA6a956B9488eD4dd761E59f52FDc6c8068E6B5",
80
+ FACTORY_ADDRESS: "0x5de4839a76cf55d0c90e2061ef4386d962E15ae3"
81
+ }
82
+
83
+ /**
84
+ * Get the account initialization code for a kernel smart account
85
+ * @param owner
86
+ * @param index
87
+ * @param factoryAddress
88
+ * @param accountLogicAddress
89
+ * @param ecdsaValidatorAddress
90
+ */
91
+ const getAccountInitCode = async ({
92
+ owner,
93
+ index,
94
+ factoryAddress,
95
+ accountLogicAddress,
96
+ ecdsaValidatorAddress
97
+ }: {
98
+ owner: Address
99
+ index: bigint
100
+ factoryAddress: Address
101
+ accountLogicAddress: Address
102
+ ecdsaValidatorAddress: Address
103
+ }): Promise<Hex> => {
104
+ if (!owner) throw new Error("Owner account not found")
105
+
106
+ // Build the account initialization data
107
+ const initialisationData = encodeFunctionData({
108
+ abi: KernelInitAbi,
109
+ functionName: "initialize",
110
+ args: [ecdsaValidatorAddress, owner]
111
+ })
112
+
113
+ // Build the account init code
114
+ return concatHex([
115
+ factoryAddress,
116
+ encodeFunctionData({
117
+ abi: createAccountAbi,
118
+ functionName: "createAccount",
119
+ args: [accountLogicAddress, initialisationData, index]
120
+ }) as Hex
121
+ ])
122
+ }
123
+
124
+ /**
125
+ * Check the validity of an existing account address, or fetch the pre-deterministic account address for a kernel smart wallet
126
+ * @param client
127
+ * @param owner
128
+ * @param entryPoint
129
+ * @param ecdsaValidatorAddress
130
+ * @param initCodeProvider
131
+ * @param deployedAccountAddress
132
+ */
133
+ const getAccountAddress = async <
134
+ TTransport extends Transport = Transport,
135
+ TChain extends Chain | undefined = Chain | undefined
136
+ >({
137
+ client,
138
+ owner,
139
+ entryPoint,
140
+ initCodeProvider,
141
+ ecdsaValidatorAddress,
142
+ deployedAccountAddress
143
+ }: {
144
+ client: Client<TTransport, TChain>
145
+ owner: Address
146
+ initCodeProvider: () => Promise<Hex>
147
+ entryPoint: Address
148
+ ecdsaValidatorAddress: Address
149
+ deployedAccountAddress?: Address
150
+ }): Promise<Address> => {
151
+ // If we got an already deployed account, ensure it's well deployed, and the validator & signer are correct
152
+ if (deployedAccountAddress !== undefined) {
153
+ // Get the owner of the deployed account, ensure it's the same as the owner given in params
154
+ const deployedAccountOwner = await readContract(client, {
155
+ address: ecdsaValidatorAddress,
156
+ abi: [
157
+ {
158
+ inputs: [
159
+ {
160
+ internalType: "address",
161
+ name: "",
162
+ type: "address"
163
+ }
164
+ ],
165
+ name: "ecdsaValidatorStorage",
166
+ outputs: [
167
+ {
168
+ internalType: "address",
169
+ name: "owner",
170
+ type: "address"
171
+ }
172
+ ],
173
+ stateMutability: "view",
174
+ type: "function"
175
+ }
176
+ ],
177
+ functionName: "ecdsaValidatorStorage",
178
+ args: [deployedAccountAddress]
179
+ })
180
+
181
+ // Ensure the address match
182
+ if (!isAddressEqual(deployedAccountOwner, owner)) {
183
+ throw new Error("Invalid owner for the already deployed account")
184
+ }
185
+
186
+ // If ok, return the address
187
+ return deployedAccountAddress
188
+ }
189
+
190
+ // Find the init code for this account
191
+ const initCode = await initCodeProvider()
192
+
193
+ // Get the sender address based on the init code
194
+ return getSenderAddress(client, {
195
+ initCode,
196
+ entryPoint
197
+ })
198
+ }
199
+
200
+ /**
201
+ * Build a kernel smart account from a private key, that use the ECDSA signer behind the scene
202
+ * @param client
203
+ * @param privateKey
204
+ * @param entryPoint
205
+ * @param index
206
+ * @param factoryAddress
207
+ * @param accountLogicAddress
208
+ * @param ecdsaValidatorAddress
209
+ * @param deployedAccountAddress
210
+ */
211
+ export async function signerToEcdsaKernelSmartAccount<
212
+ TTransport extends Transport = Transport,
213
+ TChain extends Chain | undefined = Chain | undefined
214
+ >(
215
+ client: Client<TTransport, TChain>,
216
+ {
217
+ signer,
218
+ entryPoint,
219
+ index = 0n,
220
+ factoryAddress = KERNEL_ADDRESSES.FACTORY_ADDRESS,
221
+ accountLogicAddress = KERNEL_ADDRESSES.ACCOUNT_V2_2_LOGIC,
222
+ ecdsaValidatorAddress = KERNEL_ADDRESSES.ECDSA_VALIDATOR,
223
+ deployedAccountAddress
224
+ }: {
225
+ signer: SmartAccountSigner
226
+ entryPoint: Address
227
+ index?: bigint
228
+ factoryAddress?: Address
229
+ accountLogicAddress?: Address
230
+ ecdsaValidatorAddress?: Address
231
+ deployedAccountAddress?: Address
232
+ }
233
+ ): Promise<KernelEcdsaSmartAccount<TTransport, TChain>> {
234
+ // Get the private key related account
235
+ const viemSigner: Account =
236
+ signer.type === "local"
237
+ ? ({
238
+ ...signer,
239
+ signTransaction: (_, __) => {
240
+ throw new SignTransactionNotSupportedBySmartAccount()
241
+ }
242
+ } as Account)
243
+ : (signer as Account)
244
+
245
+ // Helper to generate the init code for the smart account
246
+ const generateInitCode = () =>
247
+ getAccountInitCode({
248
+ owner: viemSigner.address,
249
+ index,
250
+ factoryAddress,
251
+ accountLogicAddress,
252
+ ecdsaValidatorAddress
253
+ })
254
+
255
+ // Fetch account address and chain id
256
+ const [accountAddress, chainId] = await Promise.all([
257
+ getAccountAddress<TTransport, TChain>({
258
+ client,
259
+ entryPoint,
260
+ owner: viemSigner.address,
261
+ ecdsaValidatorAddress,
262
+ initCodeProvider: generateInitCode,
263
+ deployedAccountAddress
264
+ }),
265
+ getChainId(client)
266
+ ])
267
+
268
+ if (!accountAddress) throw new Error("Account address not found")
269
+
270
+ // Build the EOA Signer
271
+ const account = toAccount({
272
+ address: accountAddress,
273
+ async signMessage({ message }) {
274
+ return signMessage(client, { account: viemSigner, message })
275
+ },
276
+ async signTransaction(_, __) {
277
+ throw new SignTransactionNotSupportedBySmartAccount()
278
+ },
279
+ async signTypedData(typedData) {
280
+ return signTypedData(client, { account: viemSigner, ...typedData })
281
+ }
282
+ })
283
+
284
+ return {
285
+ ...account,
286
+ client: client,
287
+ publicKey: accountAddress,
288
+ entryPoint: entryPoint,
289
+ source: "kernelEcdsaSmartAccount",
290
+
291
+ // Get the nonce of the smart account
292
+ async getNonce() {
293
+ return getAccountNonce(client, {
294
+ sender: accountAddress,
295
+ entryPoint: entryPoint
296
+ })
297
+ },
298
+
299
+ // Sign a user operation
300
+ async signUserOperation(userOperation) {
301
+ const hash = getUserOperationHash({
302
+ userOperation: {
303
+ ...userOperation,
304
+ signature: "0x"
305
+ },
306
+ entryPoint: entryPoint,
307
+ chainId: chainId
308
+ })
309
+ const signature = await signMessage(client, {
310
+ account: viemSigner,
311
+ message: { raw: hash }
312
+ })
313
+ // Always use the sudo mode, since we will use external paymaster
314
+ return concatHex(["0x00000000", signature])
315
+ },
316
+
317
+ // Encode the init code
318
+ async getInitCode() {
319
+ const contractCode = await getBytecode(client, {
320
+ address: accountAddress
321
+ })
322
+
323
+ if ((contractCode?.length ?? 0) > 2) return "0x"
324
+
325
+ return generateInitCode()
326
+ },
327
+
328
+ // Encode the deploy call data
329
+ async encodeDeployCallData(_) {
330
+ throw new Error("Simple account doesn't support account deployment")
331
+ },
332
+
333
+ // Encode a call
334
+ async encodeCallData(_tx) {
335
+ if (Array.isArray(_tx)) {
336
+ // Encode a batched call
337
+ return encodeFunctionData({
338
+ abi: KernelExecuteAbi,
339
+ functionName: "executeBatch",
340
+ args: [
341
+ _tx.map((tx) => ({
342
+ to: tx.to,
343
+ value: tx.value,
344
+ data: tx.data
345
+ }))
346
+ ]
347
+ })
348
+ } else {
349
+ // Encode a simple call
350
+ return encodeFunctionData({
351
+ abi: KernelExecuteAbi,
352
+ functionName: "execute",
353
+ args: [_tx.to, _tx.value, _tx.data, 0]
354
+ })
355
+ }
356
+ },
357
+
358
+ // Get simple dummy signature
359
+ async getDummySignature() {
360
+ return "0x00000000fffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c"
361
+ }
362
+ }
363
+ }
@@ -61,8 +61,8 @@ const SAFE_VERSION_TO_ADDRESSES_MAP: {
61
61
  }
62
62
  } = {
63
63
  "1.4.1": {
64
- ADD_MODULES_LIB_ADDRESS: "0x191EFDC03615B575922289DC339F4c70aC5C30Af",
65
- SAFE_4337_MODULE_ADDRESS: "0x39E54Bb2b3Aa444b4B39DEe15De3b7809c36Fc38",
64
+ ADD_MODULES_LIB_ADDRESS: "0x8EcD4ec46D4D2a6B64fE960B3D64e8B94B2234eb",
65
+ SAFE_4337_MODULE_ADDRESS: "0xa581c4A4DB7175302464fF3C06380BC3270b4037",
66
66
  SAFE_PROXY_FACTORY_ADDRESS:
67
67
  "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67",
68
68
  SAFE_SINGLETON_ADDRESS: "0x41675C099F32341bf84BFc5382aF534df5C7461a",
@@ -7,7 +7,7 @@ import type {
7
7
  } from "../../types/userOperation.js"
8
8
  import { deepHexlify } from "../../utils/deepHexlify.js"
9
9
 
10
- export type SponsorUserOperationParameters = {
10
+ export type PimlocoSponsorUserOperationParameters = {
11
11
  userOperation: PartialBy<
12
12
  UserOperation,
13
13
  | "callGasLimit"
@@ -16,6 +16,7 @@ export type SponsorUserOperationParameters = {
16
16
  | "paymasterAndData"
17
17
  >
18
18
  entryPoint: Address
19
+ sponsorshipPolicyId?: string
19
20
  }
20
21
 
21
22
  export type SponsorUserOperationReturnType = {
@@ -31,7 +32,7 @@ export type SponsorUserOperationReturnType = {
31
32
  * - Docs: https://docs.pimlico.io/permissionless/reference/pimlico-paymaster-actions/sponsorUserOperation
32
33
  *
33
34
  * @param client {@link PimlicoBundlerClient} that you created using viem's createClient whose transport url is pointing to the Pimlico's bundler.
34
- * @param args {@link sponsorUserOperationParameters} UserOperation you want to sponsor & entryPoint.
35
+ * @param args {@link PimlocoSponsorUserOperationParameters} UserOperation you want to sponsor & entryPoint.
35
36
  * @returns paymasterAndData & updated gas parameters, see {@link SponsorUserOperationReturnType}
36
37
  *
37
38
  *
@@ -56,14 +57,26 @@ export const sponsorUserOperation = async <
56
57
  TAccount extends Account | undefined = Account | undefined
57
58
  >(
58
59
  client: Client<TTransport, TChain, TAccount, PimlicoPaymasterRpcSchema>,
59
- args: SponsorUserOperationParameters
60
+ args: PimlocoSponsorUserOperationParameters
60
61
  ): Promise<SponsorUserOperationReturnType> => {
61
62
  const response = await client.request({
62
63
  method: "pm_sponsorUserOperation",
63
- params: [
64
- deepHexlify(args.userOperation) as UserOperationWithBigIntAsHex,
65
- args.entryPoint
66
- ]
64
+ params: args.sponsorshipPolicyId
65
+ ? [
66
+ deepHexlify(
67
+ args.userOperation
68
+ ) as UserOperationWithBigIntAsHex,
69
+ args.entryPoint,
70
+ {
71
+ sponsorshipPolicyId: args.sponsorshipPolicyId
72
+ }
73
+ ]
74
+ : [
75
+ deepHexlify(
76
+ args.userOperation
77
+ ) as UserOperationWithBigIntAsHex,
78
+ args.entryPoint
79
+ ]
67
80
  })
68
81
 
69
82
  return {
@@ -0,0 +1,76 @@
1
+ import type { Account, Address, Chain, Client, Transport } from "viem"
2
+ import type { PimlicoPaymasterRpcSchema } from "../../types/pimlico.js"
3
+ import type {
4
+ UserOperation,
5
+ UserOperationWithBigIntAsHex
6
+ } from "../../types/userOperation.js"
7
+ import { deepHexlify } from "../../utils/deepHexlify.js"
8
+
9
+ export type ValidateSponsorshipPoliciesParameters = {
10
+ userOperation: UserOperation
11
+ entryPoint: Address
12
+ sponsorshipPolicyIds: string[]
13
+ }
14
+
15
+ export type ValidateSponsorshipPoliciesReturnType = {
16
+ sponsorshipPolicyId: string
17
+ data: {
18
+ name: string | null
19
+ author: string | null
20
+ icon: string | null
21
+ description: string | null
22
+ }
23
+ }[]
24
+
25
+ /**
26
+ * Returns valid sponsorship policies for a userOperation from the list of ids passed
27
+ * - Docs: https://docs.pimlico.io/permissionless/reference/pimlico-paymaster-actions/ValidateSponsorshipPolicies
28
+ *
29
+ * @param client {@link PimlicoBundlerClient} that you created using viem's createClient whose transport url is pointing to the Pimlico's bundler.
30
+ * @param args {@link ValidateSponsorshipPoliciesParameters} UserOperation you want to sponsor & entryPoint.
31
+ * @returns valid sponsorship policies, see {@link ValidateSponsorshipPoliciesReturnType}
32
+ *
33
+ * @example
34
+ * import { createClient } from "viem"
35
+ * import { validateSponsorshipPolicies } from "permissionless/actions/pimlico"
36
+ *
37
+ * const bundlerClient = createClient({
38
+ * chain: goerli,
39
+ * transport: http("https://api.pimlico.io/v2/goerli/rpc?apikey=YOUR_API_KEY_HERE")
40
+ * })
41
+ *
42
+ * await validateSponsorshipPolicies(bundlerClient, {
43
+ * userOperation: userOperationWithDummySignature,
44
+ * entryPoint: entryPoint,
45
+ * sponsorshipPolicyIds: ["sp_shiny_puma"]
46
+ * })
47
+ * Returns
48
+ * [
49
+ * {
50
+ * sponsorshipPolicyId: "sp_shiny_puma",
51
+ * data: {
52
+ * name: "Shiny Puma",
53
+ * author: "Pimlico",
54
+ * icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4...",
55
+ * description: "This policy is for testing purposes only"
56
+ * }
57
+ * }
58
+ * ]
59
+ */
60
+ export const validateSponsorshipPolicies = async <
61
+ TTransport extends Transport = Transport,
62
+ TChain extends Chain | undefined = Chain | undefined,
63
+ TAccount extends Account | undefined = Account | undefined
64
+ >(
65
+ client: Client<TTransport, TChain, TAccount, PimlicoPaymasterRpcSchema>,
66
+ args: ValidateSponsorshipPoliciesParameters
67
+ ): Promise<ValidateSponsorshipPoliciesReturnType> => {
68
+ return await client.request({
69
+ method: "pm_validateSponsorshipPolicies",
70
+ params: [
71
+ deepHexlify(args.userOperation) as UserOperationWithBigIntAsHex,
72
+ args.entryPoint,
73
+ args.sponsorshipPolicyIds
74
+ ]
75
+ })
76
+ }
@@ -8,7 +8,7 @@ import {
8
8
  getUserOperationStatus
9
9
  } from "./pimlico/getUserOperationStatus.js"
10
10
  import {
11
- type SponsorUserOperationParameters,
11
+ type PimlocoSponsorUserOperationParameters,
12
12
  type SponsorUserOperationReturnType,
13
13
  sponsorUserOperation
14
14
  } from "./pimlico/sponsorUserOperation.js"
@@ -22,14 +22,22 @@ import {
22
22
  pimlicoPaymasterActions
23
23
  } from "../clients/decorators/pimlico.js"
24
24
 
25
+ import {
26
+ type ValidateSponsorshipPoliciesParameters,
27
+ type ValidateSponsorshipPoliciesReturnType,
28
+ validateSponsorshipPolicies
29
+ } from "./pimlico/validateSponsorshipPolicies.js"
30
+
25
31
  export type {
26
32
  GetUserOperationGasPriceReturnType,
27
33
  GetUserOperationStatusParameters,
28
34
  GetUserOperationStatusReturnType,
29
- SponsorUserOperationParameters,
35
+ PimlocoSponsorUserOperationParameters,
30
36
  SponsorUserOperationReturnType,
31
37
  PimlicoBundlerActions,
32
- PimlicoPaymasterClientActions
38
+ PimlicoPaymasterClientActions,
39
+ ValidateSponsorshipPoliciesParameters,
40
+ ValidateSponsorshipPoliciesReturnType
33
41
  }
34
42
 
35
43
  export {
@@ -37,5 +45,6 @@ export {
37
45
  getUserOperationStatus,
38
46
  sponsorUserOperation,
39
47
  pimlicoBundlerActions,
40
- pimlicoPaymasterActions
48
+ pimlicoPaymasterActions,
49
+ validateSponsorshipPolicies
41
50
  }
@@ -16,6 +16,11 @@ import {
16
16
  smartAccountActions
17
17
  } from "./decorators/smartAccount.js"
18
18
 
19
+ /**
20
+ * TODO:
21
+ * - Add docs
22
+ * - Fix typing, 'accounts' is required to signMessage, signTypedData, signTransaction, but not needed here, since account is embedded in the client
23
+ */
19
24
  export type SmartAccountClient<
20
25
  transport extends Transport = Transport,
21
26
  chain extends Chain | undefined = Chain | undefined,
@@ -54,7 +59,7 @@ export type SmartAccountClientConfig<
54
59
  *
55
60
  * A Bundler Client is an interface to "erc 4337" [JSON-RPC API](https://eips.ethereum.org/EIPS/eip-4337#rpc-methods-eth-namespace) methods such as sending user operation, estimating gas for a user operation, get user operation receipt, etc through Bundler Actions.
56
61
  *
57
- * @param config - {@link WalletClientConfig}
62
+ * @param parameters - {@link WalletClientConfig}
58
63
  * @returns A Bundler Client. {@link SmartAccountClient}
59
64
  *
60
65
  * @example
@@ -1,4 +1,9 @@
1
1
  import type { Client, Hash } from "viem"
2
+ import {
3
+ type ValidateSponsorshipPoliciesParameters,
4
+ type ValidateSponsorshipPoliciesReturnType,
5
+ validateSponsorshipPolicies
6
+ } from "../../actions/pimlico.js"
2
7
  import {
3
8
  type GetUserOperationGasPriceReturnType,
4
9
  getUserOperationGasPrice
@@ -9,7 +14,7 @@ import {
9
14
  getUserOperationStatus
10
15
  } from "../../actions/pimlico/getUserOperationStatus.js"
11
16
  import {
12
- type SponsorUserOperationParameters,
17
+ type PimlocoSponsorUserOperationParameters,
13
18
  type SponsorUserOperationReturnType,
14
19
  sponsorUserOperation
15
20
  } from "../../actions/pimlico/sponsorUserOperation.js"
@@ -78,7 +83,7 @@ export type PimlicoPaymasterClientActions = {
78
83
  *
79
84
  * https://docs.pimlico.io/permissionless/reference/pimlico-paymaster-actions/sponsorUserOperation
80
85
  *
81
- * @param args {@link SponsorUserOperationParameters} UserOperation you want to sponsor & entryPoint.
86
+ * @param args {@link PimlocoSponsorUserOperationParameters} UserOperation you want to sponsor & entryPoint.
82
87
  * @returns paymasterAndData & updated gas parameters, see {@link SponsorUserOperationReturnType}
83
88
  *
84
89
  * @example
@@ -97,15 +102,57 @@ export type PimlicoPaymasterClientActions = {
97
102
  *
98
103
  */
99
104
  sponsorUserOperation: (
100
- args: SponsorUserOperationParameters
105
+ args: PimlocoSponsorUserOperationParameters
101
106
  ) => Promise<SponsorUserOperationReturnType>
107
+
108
+ validateSponsorshipPolicies: (
109
+ args: ValidateSponsorshipPoliciesParameters
110
+ ) => Promise<ValidateSponsorshipPoliciesReturnType>
102
111
  }
103
112
 
113
+ /**
114
+ * Returns valid sponsorship policies for a userOperation from the list of ids passed
115
+ * - Docs: https://docs.pimlico.io/permissionless/reference/pimlico-paymaster-actions/ValidateSponsorshipPolicies
116
+ *
117
+ * @param args {@link ValidateSponsorshipPoliciesParameters} UserOperation you want to sponsor & entryPoint.
118
+ * @returns valid sponsorship policies, see {@link ValidateSponsorshipPoliciesReturnType}
119
+ *
120
+ * @example
121
+ * import { createClient } from "viem"
122
+ * import { validateSponsorshipPolicies } from "permissionless/actions/pimlico"
123
+ *
124
+ * const bundlerClient = createClient({
125
+ * chain: goerli,
126
+ * transport: http("https://api.pimlico.io/v2/goerli/rpc?apikey=YOUR_API_KEY_HERE")
127
+ * }).extend(pimlicoPaymasterActions)
128
+
129
+ *
130
+ * await bundlerClient.validateSponsorshipPolicies({
131
+ * userOperation: userOperationWithDummySignature,
132
+ * entryPoint: entryPoint,
133
+ * sponsorshipPolicyIds: ["sp_shiny_puma"]
134
+ * })
135
+ * Returns
136
+ * [
137
+ * {
138
+ * sponsorshipPolicyId: "sp_shiny_puma",
139
+ * data: {
140
+ * name: "Shiny Puma",
141
+ * author: "Pimlico",
142
+ * icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4...",
143
+ * description: "This policy is for testing purposes only"
144
+ * }
145
+ * }
146
+ * ]
147
+ */
104
148
  export const pimlicoPaymasterActions = (
105
149
  client: Client
106
150
  ): PimlicoPaymasterClientActions => ({
107
- sponsorUserOperation: async (args: SponsorUserOperationParameters) =>
108
- sponsorUserOperation(client as PimlicoPaymasterClient, args)
151
+ sponsorUserOperation: async (args: PimlocoSponsorUserOperationParameters) =>
152
+ sponsorUserOperation(client as PimlicoPaymasterClient, args),
153
+ validateSponsorshipPolicies: async (
154
+ args: ValidateSponsorshipPoliciesParameters
155
+ ) => validateSponsorshipPolicies(client as PimlicoPaymasterClient, args)
109
156
  })
110
157
 
111
158
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "permissionless",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "author": "Pimlico",
5
5
  "main": "./_cjs/index.js",
6
6
  "module": "./_esm/index.js",