Skip to content

Commit a882ddb

Browse files
authored
Merge pull request #437 from pimlicolabs/mock-paymaster/add-exports
feat(mock-paymaster): export erc20Address and sudoMintTokens
2 parents f07ac67 + 7f51d34 commit a882ddb

6 files changed

Lines changed: 109 additions & 76 deletions

File tree

.changeset/cold-animals-say.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@pimlico/mock-paymaster": patch
3+
---
4+
5+
Export erc20Address and sudoMintTokens

packages/mock-paymaster/helpers/erc20-utils.ts

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import {
2+
http,
23
type Account,
34
type Address,
45
type Chain,
5-
type PublicClient,
66
type Transport,
77
type WalletClient,
88
concat,
9+
createTestClient,
10+
createWalletClient,
911
encodeFunctionData,
1012
getCreate2Address,
1113
hexToBigInt,
1214
pad,
1315
parseAbi,
16+
parseEther,
1417
toHex
1518
} from "viem"
16-
import { getAnvilWalletClient, getPublicClient } from "./utils.js"
19+
import { privateKeyToAccount } from "viem/accounts"
20+
import { getChain, getPublicClient } from "./utils.js"
1721

1822
const erc20Bytecode = concat([
1923
"0x60a060405234801561001057600080fd5b50604051610ff0380380610ff083398101604081905261002f9161022c565b6040518060400160405280600981526020016805465737445524332360bc1b8152506040518060400160405280600381526020016205432360ec1b815250816003908161007c919061034d565b506004610089828261034d565b5050506100a63369d3c21bcecceda10000006100b160201b60201c565b60ff166080526104a3565b6001600160a01b0382166100e457600060405163ec442f0560e01b81526004016100db9190610430565b60405180910390fd5b6100f0600083836100f4565b5050565b6001600160a01b03831661011f5780600260008282546101149190610454565b9091555061017e9050565b6001600160a01b0383166000908152602081905260409020548181101561015f5783818360405163391434e360e21b81526004016100db9392919061046d565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b03821661019a576002805482900390556101b9565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516101fc9190610495565b60405180910390a3505050565b60ff8116811461021857600080fd5b50565b805161022681610209565b92915050565b60006020828403121561024157610241600080fd5b600061024d848461021b565b949350505050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052602260045260246000fd5b60028104600182168061029557607f821691505b6020821081036102a7576102a761026b565b50919050565b60006102266102b98381565b90565b6102c5836102ad565b815460001960089490940293841b1916921b91909117905550565b60006102ed8184846102bc565b505050565b818110156100f0576103056000826102e0565b6001016102f2565b601f8211156102ed576000818152602090206020601f850104810160208510156103345750805b6103466020601f8601048301826102f2565b5050505050565b81516001600160401b0381111561036657610366610255565b6103708254610281565b61037b82828561030d565b6020601f8311600181146103af57600084156103975750858201515b600019600886021c1981166002860217865550610408565b600085815260208120601f198616915b828110156103df57888501518255602094850194600190920191016103bf565b868310156103fb5784890151600019601f89166008021c191682555b6001600288020188555050505b505050505050565b60006001600160a01b038216610226565b61042a81610410565b82525050565b602081016102268284610421565b634e487b7160e01b600052601160045260246000fd5b808201808211156102265761022661043e565b8061042a565b6060810161047b8286610421565b6104886020830185610467565b61024d6040830184610467565b602081016102268284610467565b608051610b326104be60003960006101650152610b326000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063313ce56711610081578063a9059cbb1161005b578063a9059cbb146101cf578063dd62ed3e146101e2578063fb4dcefa1461022857600080fd5b8063313ce5671461016357806370a082311461019157806395d89b41146101c757600080fd5b806318160ddd116100b257806318160ddd1461012c57806323b872dd1461013d5780632d688ca81461015057600080fd5b806305ea5c22146100d957806306fdde03146100ee578063095ea7b31461010c575b600080fd5b6100ec6100e7366004610868565b61023b565b005b6100f661024b565b604051610103919061092c565b60405180910390f35b61011f61011a366004610944565b6102dd565b604051610103919061098b565b6002545b604051610103919061099f565b61011f61014b366004610868565b6102f7565b6100ec61015e366004610944565b61031b565b7f000000000000000000000000000000000000000000000000000000000000000060405161010391906109b6565b61013061019f3660046109c4565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6100f6610329565b61011f6101dd366004610944565b610338565b6101306101f03660046109ed565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6100ec6102363660046109ed565b610346565b61024683838361037c565b505050565b60606003805461025a90610a4f565b80601f016020809104026020016040519081016040528092919081815260200182805461028690610a4f565b80156102d35780601f106102a8576101008083540402835291602001916102d3565b820191906000526020600020905b8154815290600101906020018083116102b657829003601f168201915b5050505050905090565b6000336102eb81858561037c565b60019150505b92915050565b600033610305858285610389565b610310858585610441565b506001949350505050565b61032582826104ec565b5050565b60606004805461025a90610a4f565b6000336102eb818585610441565b61032582826103778573ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b610441565b6102468383836001610548565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461043b578181101561042c578281836040517ffb8f41b200000000000000000000000000000000000000000000000000000000815260040161042393929190610a84565b60405180910390fd5b61043b84848484036000610548565b50505050565b73ffffffffffffffffffffffffffffffffffffffff83166104915760006040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016104239190610aac565b73ffffffffffffffffffffffffffffffffffffffff82166104e15760006040517fec442f050000000000000000000000000000000000000000000000000000000081526004016104239190610aac565b61024683838361068e565b73ffffffffffffffffffffffffffffffffffffffff821661053c5760006040517fec442f050000000000000000000000000000000000000000000000000000000081526004016104239190610aac565b6103256000838361068e565b73ffffffffffffffffffffffffffffffffffffffff84166105985760006040517fe602df050000000000000000000000000000000000000000000000000000000081526004016104239190610aac565b73ffffffffffffffffffffffffffffffffffffffff83166105e85760006040517f94280d620000000000000000000000000000000000000000000000000000000081526004016104239190610aac565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600160209081526040808320938716835292905220829055801561043b578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610680919061099f565b60405180910390a350505050565b73ffffffffffffffffffffffffffffffffffffffff83166106c65780600260008282546106bb9190610ae9565b909155506107589050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260409020548181101561072c578381836040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040161042393929190610a84565b73ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090209082900390555b73ffffffffffffffffffffffffffffffffffffffff8216610781576002805482900390556107ad565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090208054820190555b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161080a919061099f565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff82166102f1565b61083e81610817565b811461084957600080fd5b50565b80356102f181610835565b8061083e565b80356102f181610857565b60008060006060848603121561088057610880600080fd5b600061088c868661084c565b935050602061089d8682870161084c565b92505060406108ae8682870161085d565b9150509250925092565b60005b838110156108d35781810151838201526020016108bb565b50506000910152565b60006108e6825190565b8084526020840193506108fd8185602086016108b8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920192915050565b6020808252810161093d81846108dc565b9392505050565b6000806040838503121561095a5761095a600080fd5b6000610966858561084c565b92505060206109778582860161085d565b9150509250929050565b8015155b82525050565b602081016102f18284610981565b80610985565b602081016102f18284610999565b60ff8116610985565b602081016102f182846109ad565b6000602082840312156109d9576109d9600080fd5b60006109e5848461084c565b949350505050565b60008060408385031215610a0357610a03600080fd5b6000610a0f858561084c565b92505060206109778582860161084c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600281046001821680610a6357607f821691505b602082108103610a7557610a75610a20565b50919050565b61098581610817565b60608101610a928286610a7b565b610a9f6020830185610999565b6109e56040830184610999565b602081016102f18284610a7b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156102f1576102f1610aba56fea2646970667358221220d40f68e247510ec8b7876d327ac47b949de248d0626aaf2670151c5e84ee6b4a64736f6c634300081a0033",
@@ -23,11 +27,47 @@ const erc20Bytecode = concat([
2327
const create2Salt =
2428
"0x0000000000000000000000000000000000000000000000000000000000000000"
2529

26-
export const deployErc20Token = async (
27-
walletClient: WalletClient<Transport, Chain, Account>,
28-
publicClient: PublicClient
29-
) => {
30+
export const getPaymasterUtilityWallet = async (
31+
anvilRpc: string
32+
): Promise<WalletClient<Transport, Chain, Account>> => {
33+
const account = privateKeyToAccount(
34+
"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
35+
)
36+
37+
// Check if account has balance
38+
const publicClient = await getPublicClient(anvilRpc)
39+
const balance = await publicClient.getBalance({ address: account.address })
40+
41+
// If no balance, set it to 1000 ETH
42+
if (balance === 0n) {
43+
// Create test client for setting balance
44+
const testClient = createTestClient({
45+
mode: "anvil",
46+
transport: http(anvilRpc)
47+
})
48+
49+
await testClient.setBalance({
50+
address: account.address,
51+
value: parseEther("1000")
52+
})
53+
}
54+
55+
// Create and return wallet client
56+
const walletClient = createWalletClient({
57+
chain: await getChain(anvilRpc),
58+
account,
59+
transport: http(anvilRpc)
60+
})
61+
62+
return walletClient
63+
}
64+
65+
export const deployErc20Token = async (anvilRpc: string) => {
66+
const publicClient = await getPublicClient(anvilRpc)
67+
3068
if ((await publicClient.getCode({ address: erc20Address })) === undefined) {
69+
const walletClient = await getPaymasterUtilityWallet(anvilRpc)
70+
3171
await walletClient.sendTransaction({
3272
to: "0x4e59b44847b379578588920ca78fbf26c0b4956c",
3373
data: concat([create2Salt, erc20Bytecode])
@@ -59,10 +99,7 @@ export const sudoMintTokens = async ({
5999
to: Address
60100
anvilRpc: string
61101
}) => {
62-
const walletClient = await getAnvilWalletClient({
63-
addressIndex: 0,
64-
anvilRpc
65-
})
102+
const walletClient = await getPaymasterUtilityWallet(anvilRpc)
66103

67104
await walletClient.sendTransaction({
68105
to: erc20Address,

packages/mock-paymaster/helpers/utils.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
import {
22
http,
3-
type Account,
43
type Address,
54
type Chain,
65
type PublicClient,
76
type Transport,
8-
type WalletClient,
97
createPublicClient,
10-
createWalletClient,
118
defineChain
129
} from "viem"
13-
import { mnemonicToAccount } from "viem/accounts"
1410
import { erc20Address } from "./erc20-utils.js"
1511
import { RpcError, ValidationErrors } from "./schema.js"
1612

@@ -63,26 +59,6 @@ export const getPublicClient = async (
6359
})
6460
}
6561

66-
export const getAnvilWalletClient = async ({
67-
addressIndex,
68-
anvilRpc
69-
}: { addressIndex: number; anvilRpc: string }): Promise<
70-
WalletClient<Transport, Chain, Account>
71-
> => {
72-
const chain = await getChain(anvilRpc)
73-
74-
return createWalletClient({
75-
account: mnemonicToAccount(
76-
"test test test test test test test test test test test junk",
77-
{
78-
addressIndex
79-
}
80-
),
81-
chain,
82-
transport: http(anvilRpc)
83-
})
84-
}
85-
8662
export const isTokenSupported = async (token: Address) => {
8763
if (token !== erc20Address) {
8864
throw new RpcError(

packages/mock-paymaster/index.ts

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import cors from "@fastify/cors"
22
import Fastify from "fastify"
33
import { defineInstance } from "prool"
4-
import { http, createPublicClient } from "viem"
5-
import { createBundlerClient } from "viem/account-abstraction"
6-
import { deployErc20Token } from "./helpers/erc20-utils.js"
7-
import { getAnvilWalletClient, getChain } from "./helpers/utils.js"
4+
import { http, createWalletClient } from "viem"
5+
import { privateKeyToAccount } from "viem/accounts"
6+
import {
7+
deployErc20Token,
8+
erc20Address,
9+
sudoMintTokens
10+
} from "./helpers/erc20-utils.js"
11+
import { getChain } from "./helpers/utils.js"
812
import { createRpcHandler } from "./relay.js"
913
import { deployPaymasters } from "./singletonPaymasters.js"
1014

@@ -23,32 +27,29 @@ export const paymaster = defineInstance(
2327
port: _port,
2428
name: "mock-paymaster",
2529
start: async ({ port = _port }) => {
26-
const chain = await getChain(anvilRpc)
27-
const walletClient = await getAnvilWalletClient({
28-
anvilRpc,
29-
addressIndex: 1
30-
})
31-
const publicClient = createPublicClient({
32-
transport: http(anvilRpc),
33-
chain
34-
})
35-
const bundler = createBundlerClient({
36-
chain,
37-
transport: http(altoRpc)
30+
const paymasterSigner = createWalletClient({
31+
chain: await getChain(anvilRpc),
32+
account: privateKeyToAccount(
33+
"0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
34+
),
35+
transport: http(anvilRpc)
3836
})
3937

40-
await deployPaymasters({ walletClient, publicClient })
41-
await deployErc20Token(walletClient, publicClient)
38+
await deployPaymasters({
39+
anvilRpc,
40+
paymasterSigner: paymasterSigner.account.address
41+
})
42+
await deployErc20Token(anvilRpc)
4243

4344
app.register(cors, {
4445
origin: "*",
4546
methods: ["POST", "GET", "OPTIONS"]
4647
})
4748

4849
const rpcHandler = createRpcHandler({
49-
bundler,
50-
publicClient,
51-
paymasterSigner: walletClient
50+
altoRpc,
51+
anvilRpc,
52+
paymasterSigner
5253
})
5354
app.post("/", {}, rpcHandler)
5455

@@ -64,3 +65,5 @@ export const paymaster = defineInstance(
6465
}
6566
}
6667
)
68+
69+
export { erc20Address, sudoMintTokens }

packages/mock-paymaster/relay.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as util from "node:util"
22
import type { FastifyReply, FastifyRequest } from "fastify"
33
import {
4+
http,
45
type Account,
56
type Address,
67
BaseError,
@@ -15,6 +16,7 @@ import {
1516
import {
1617
type BundlerClient,
1718
type UserOperation,
19+
createBundlerClient,
1820
entryPoint06Address,
1921
entryPoint07Address,
2022
entryPoint08Address
@@ -40,6 +42,8 @@ import {
4042
} from "./helpers/schema.js"
4143
import {
4244
type PaymasterMode,
45+
getChain,
46+
getPublicClient,
4347
isTokenSupported,
4448
maxBigInt
4549
} from "./helpers/utils.js"
@@ -158,9 +162,9 @@ const handleMethod = async ({
158162
parsedBody,
159163
paymasterSigner,
160164
publicClient,
161-
bundler
165+
bundlerClient
162166
}: {
163-
bundler: BundlerClient
167+
bundlerClient: BundlerClient
164168
paymasterSigner: WalletClient<Transport, Chain, Account>
165169
publicClient: PublicClient
166170
parsedBody: JsonRpcSchema
@@ -196,7 +200,7 @@ const handleMethod = async ({
196200
entryPoint,
197201
userOperation,
198202
paymasterMode: { mode: "verifying" },
199-
bundler,
203+
bundler: bundlerClient,
200204
paymaster: epToPaymaster[entryPoint],
201205
publicClient,
202206
paymasterSigner,
@@ -284,7 +288,7 @@ const handleMethod = async ({
284288
}
285289

286290
if (parsedBody.method === "pimlico_getUserOperationGasPrice") {
287-
return await bundler.request({
291+
return await bundlerClient.request({
288292
// @ts-ignore
289293
method: "pimlico_getUserOperationGasPrice",
290294
// @ts-ignore
@@ -340,15 +344,21 @@ const handleMethod = async ({
340344
}
341345

342346
export const createRpcHandler = ({
343-
bundler,
344-
publicClient,
347+
altoRpc,
348+
anvilRpc,
345349
paymasterSigner
346350
}: {
347-
bundler: BundlerClient
348-
publicClient: PublicClient
351+
altoRpc: string
352+
anvilRpc: string
349353
paymasterSigner: WalletClient<Transport, Chain, Account>
350354
}) => {
351355
return async (request: FastifyRequest, _reply: FastifyReply) => {
356+
const publicClient = await getPublicClient(anvilRpc)
357+
const bundlerClient = createBundlerClient({
358+
chain: await getChain(anvilRpc),
359+
transport: http(altoRpc)
360+
})
361+
352362
const body = request.body
353363
const parsedBody = jsonRpcSchema.safeParse(body)
354364
if (!parsedBody.success) {
@@ -360,7 +370,7 @@ export const createRpcHandler = ({
360370

361371
try {
362372
const result = await handleMethod({
363-
bundler,
373+
bundlerClient,
364374
paymasterSigner,
365375
parsedBody: parsedBody.data,
366376
publicClient

packages/mock-paymaster/singletonPaymasters.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ import {
3030
singletonPaymaster07Abi,
3131
singletonPaymaster08Abi
3232
} from "./helpers/abi.js"
33-
import type { PaymasterMode } from "./helpers/utils.js"
33+
import { getPaymasterUtilityWallet } from "./helpers/erc20-utils.js"
34+
import { type PaymasterMode, getPublicClient } from "./helpers/utils.js"
3435

3536
export const getDummyPaymasterData = ({
3637
is06,
@@ -240,13 +241,14 @@ export const getSignedPaymasterData = async ({
240241
}
241242

242243
export const deployPaymasters = async ({
243-
walletClient,
244-
publicClient
244+
anvilRpc,
245+
paymasterSigner
245246
}: {
246-
walletClient: WalletClient<Transport, Chain, Account>
247-
publicClient: PublicClient<Transport, Chain>
247+
anvilRpc: string
248+
paymasterSigner: Address
248249
}) => {
249-
const owner = walletClient.account.address
250+
const walletClient = await getPaymasterUtilityWallet(anvilRpc)
251+
const publicClient = await getPublicClient(anvilRpc)
250252

251253
let nonce = await publicClient.getTransactionCount({
252254
address: walletClient.account.address
@@ -257,7 +259,7 @@ export const deployPaymasters = async ({
257259
to: constants.deterministicDeployer,
258260
data: concat([
259261
constants.create2Salt,
260-
getSingletonPaymaster06InitCode(walletClient.account.address)
262+
getSingletonPaymaster06InitCode(paymasterSigner)
261263
]),
262264
nonce: nonce++
263265
})
@@ -267,7 +269,7 @@ export const deployPaymasters = async ({
267269
to: constants.deterministicDeployer,
268270
data: concat([
269271
constants.create2Salt,
270-
getSingletonPaymaster07InitCode(walletClient.account.address)
272+
getSingletonPaymaster07InitCode(paymasterSigner)
271273
]),
272274
nonce: nonce++
273275
})
@@ -277,25 +279,25 @@ export const deployPaymasters = async ({
277279
to: constants.deterministicDeployer,
278280
data: concat([
279281
constants.create2Salt,
280-
getSingletonPaymaster08InitCode(walletClient.account.address)
282+
getSingletonPaymaster08InitCode(paymasterSigner)
281283
]),
282284
nonce: nonce++
283285
})
284286

285287
// Initialize contract instances.
286288
const [singletonPaymaster06, singletonPaymaster07, singletonPaymaster08] = [
287289
getContract({
288-
address: getSingletonPaymaster06Address(owner),
290+
address: getSingletonPaymaster06Address(paymasterSigner),
289291
abi: singletonPaymaster06Abi,
290292
client: walletClient
291293
}),
292294
getContract({
293-
address: getSingletonPaymaster07Address(owner),
295+
address: getSingletonPaymaster07Address(paymasterSigner),
294296
abi: singletonPaymaster07Abi,
295297
client: walletClient
296298
}),
297299
getContract({
298-
address: getSingletonPaymaster08Address(owner),
300+
address: getSingletonPaymaster08Address(paymasterSigner),
299301
abi: singletonPaymaster08Abi,
300302
client: walletClient
301303
})

0 commit comments

Comments
 (0)