Skip to content

Commit

Permalink
Support ERC20 paymaster in presets
Browse files Browse the repository at this point in the history
  • Loading branch information
derekchiang committed Jan 29, 2024
1 parent 4791392 commit 21eb783
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 18 deletions.
2 changes: 1 addition & 1 deletion packages/presets/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zerodev/presets",
"version": "5.0.1",
"version": "5.1.0",
"author": "ZeroDev",
"main": "./_cjs/index.js",
"module": "./_esm/index.js",
Expand Down
64 changes: 47 additions & 17 deletions packages/presets/zerodev/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import type { KernelAccountClient, KernelSmartAccount } from "@zerodev/sdk"
import {
createKernelAccount,
createKernelAccountClient,
createZeroDevPaymasterClient
createZeroDevPaymasterClient,
} from "@zerodev/sdk"
import type { UserOperation } from "permissionless"
import type { SmartAccountSigner } from "permissionless/accounts"
import type { Address, Chain, HttpTransport } from "viem"
import { http, createPublicClient } from "viem"
import { http, createPublicClient, isAddress } from "viem"

export type Provider = "STACKUP" | "PIMLICO" | "ALCHEMY" | "GELATO"

Expand All @@ -34,6 +34,17 @@ const getZeroDevPaymasterRPC = (
return rpc
}

// An enum type called "PAYMASTER" with the following values:
// - "NONE"
// - "SPONSOR"
// - "ERC20", which should wrap a string
type ERC20Paymaster = Address
type PaymasterType = "NONE" | "SPONSOR" | ERC20Paymaster

function isERC20(value: PaymasterType): value is ERC20Paymaster {
return isAddress(value)
}

export async function createEcdsaKernelAccountClient<
TChain extends Chain | undefined = Chain | undefined,
TSource extends string = "custom",
Expand All @@ -44,14 +55,14 @@ export async function createEcdsaKernelAccountClient<
signer,
provider,
index,
usePaymaster = true
paymaster = 'SPONSOR',
}: {
chain: TChain
projectId: string
signer: SmartAccountSigner<TSource, TAddress>
provider?: Provider
index?: bigint
usePaymaster?: boolean
paymaster?: PaymasterType
}): Promise<
KernelAccountClient<
HttpTransport,
Expand All @@ -74,23 +85,42 @@ export async function createEcdsaKernelAccountClient<
index
})

let sponsorUserOperation: ((args: {
userOperation: UserOperation
entryPoint: Address
}) => Promise<UserOperation>) | undefined = undefined

if (paymaster !== undefined) {
const zerodevPaymaster = createZeroDevPaymasterClient({
chain: chain,
transport: http(
getZeroDevPaymasterRPC(projectId, provider)
)
})

if (isERC20(paymaster)) {
sponsorUserOperation = async ({ userOperation }): Promise<UserOperation> => {
return zerodevPaymaster.sponsorUserOperation({
userOperation,
gasToken: paymaster,
})
}
} else if (paymaster === "SPONSOR") {
sponsorUserOperation = async ({ userOperation }): Promise<UserOperation> => {
return zerodevPaymaster.sponsorUserOperation({
userOperation
})
}
} else if (paymaster !== "NONE") {
throw new Error('Invalid paymaster type')
}
}

const kernelClient = createKernelAccountClient({
account,
chain,
transport: http(getZeroDevBundlerRPC(projectId, provider)),
sponsorUserOperation: usePaymaster
? async ({ userOperation }): Promise<UserOperation> => {
const zerodevPaymaster = createZeroDevPaymasterClient({
chain: chain,
transport: http(
getZeroDevPaymasterRPC(projectId, provider)
)
})
return zerodevPaymaster.sponsorUserOperation({
userOperation
})
}
: undefined
sponsorUserOperation,
})

return kernelClient as unknown as KernelAccountClient<
Expand Down

0 comments on commit 21eb783

Please sign in to comment.