Skip to content

Commit

Permalink
feat: Added sponsorUserOperationEip7677 action to ZeroDevPaymasterClient
Browse files Browse the repository at this point in the history
  • Loading branch information
SahilVasava committed Oct 23, 2024
1 parent 772b0bc commit d60fe9c
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 4 deletions.
6 changes: 6 additions & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @zerodev/sdk

## 5.3.23

### Patch Changes

- Added sponsorUserOperationEip7677 action to ZeroDevPaymasterClient

## 5.3.22

### Patch Changes
Expand Down
6 changes: 6 additions & 0 deletions packages/core/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,9 @@ export {
type EstimateGasInERC20Parameters,
type EstimateGasInERC20ReturnType
} from "./paymaster/estimateGasInERC20.js"

export {
type SponsorUserOperationEip7677Parameters,
type SponsorUserOperationEip7677ReturnType,
sponsorUserOperationEip7677
} from "./paymaster/sponsorUserOperationEip7677.js"
3 changes: 1 addition & 2 deletions packages/core/actions/paymaster/sponsorUserOperation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getEntryPointVersion } from "permissionless"
import type { PartialPick } from "permissionless/types"
import type {
ENTRYPOINT_ADDRESS_V06_TYPE,
EntryPoint
Expand Down Expand Up @@ -29,8 +30,6 @@ export type SponsorUserOperationParameters<entryPoint extends EntryPoint> = {
shouldConsume?: boolean
}

export type PartialPick<T, K extends keyof T> = Partial<Pick<T, K>>

export type SponsorUserOperationReturnType<entryPoint extends EntryPoint> =
entryPoint extends ENTRYPOINT_ADDRESS_V06_TYPE
? Pick<
Expand Down
152 changes: 152 additions & 0 deletions packages/core/actions/paymaster/sponsorUserOperationEip7677.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import {
type BundlerClient,
ENTRYPOINT_ADDRESS_V06,
type EstimateUserOperationGasParameters,
type EstimateUserOperationGasReturnType
} from "permissionless"
import {
type GetPaymasterDataParameters,
type GetPaymasterDataReturnType,
type GetPaymasterStubDataParameters,
type GetPaymasterStubDataReturnType,
paymasterActionsEip7677
} from "permissionless/experimental"
import type {
ENTRYPOINT_ADDRESS_V06_TYPE,
ENTRYPOINT_ADDRESS_V07_TYPE,
EntryPoint,
PartialPick
} from "permissionless/types"
import type { StateOverrides } from "permissionless/types/bundler"
import type { UserOperation } from "permissionless/types/userOperation.js"
import type { PartialBy } from "viem/types/utils"
import type { ZeroDevPaymasterClient } from "../../clients/paymasterClient.js"

export type SponsorUserOperationEip7677Parameters<
entryPoint extends EntryPoint
> = {
userOperation: entryPoint extends ENTRYPOINT_ADDRESS_V06_TYPE
? PartialBy<
UserOperation<"v0.6">,
"callGasLimit" | "preVerificationGas" | "verificationGasLimit"
>
: PartialBy<
UserOperation<"v0.7">,
| "callGasLimit"
| "preVerificationGas"
| "verificationGasLimit"
| "paymasterVerificationGasLimit"
| "paymasterPostOpGasLimit"
>
entryPoint: entryPoint
}

export type SponsorUserOperationEip7677ReturnType<
entryPoint extends EntryPoint
> = entryPoint extends ENTRYPOINT_ADDRESS_V06_TYPE
? Pick<
UserOperation<"v0.6">,
| "callGasLimit"
| "verificationGasLimit"
| "preVerificationGas"
| "paymasterAndData"
> &
PartialPick<
UserOperation<"v0.6">,
"maxFeePerGas" | "maxPriorityFeePerGas"
>
: Pick<
UserOperation<"v0.7">,
| "callGasLimit"
| "verificationGasLimit"
| "preVerificationGas"
| "paymaster"
| "paymasterVerificationGasLimit"
| "paymasterPostOpGasLimit"
| "paymasterData"
> &
PartialPick<
UserOperation<"v0.7">,
"maxFeePerGas" | "maxPriorityFeePerGas"
>

/**
* Returns paymasterAndData & updated gas parameters required to sponsor a userOperation.
*/
export const sponsorUserOperationEip7677 = async <
entryPoint extends EntryPoint
>(
client: ZeroDevPaymasterClient<entryPoint>,
args: SponsorUserOperationEip7677Parameters<entryPoint>,
bundlerClient: BundlerClient<entryPoint>,
stateOverrides?: StateOverrides
): Promise<SponsorUserOperationEip7677ReturnType<entryPoint>> => {
const { entryPoint: entryPointAddress, userOperation } = args
const chain = client.chain
const paymasterClient = client.extend(
paymasterActionsEip7677(entryPointAddress)
)
const stubData = await paymasterClient.getPaymasterStubData({
userOperation: userOperation as GetPaymasterStubDataParameters<
entryPoint,
typeof chain
>["userOperation"],
chain
})
const stubUserOperation = {
...userOperation,
...stubData
}

const gas = (await bundlerClient.estimateUserOperationGas(
{
userOperation:
stubUserOperation as EstimateUserOperationGasParameters<entryPoint>["userOperation"]
},
stateOverrides
)) as EstimateUserOperationGasReturnType<entryPoint>
const userOperationWithGas = {
...stubUserOperation,
callGasLimit: gas.callGasLimit,
verificationGasLimit: gas.verificationGasLimit,
preVerificationGas: gas.preVerificationGas
} as GetPaymasterDataParameters<entryPoint>["userOperation"]

const paymasterData = await paymasterClient.getPaymasterData({
userOperation: userOperationWithGas,
chain
})

if (entryPointAddress === ENTRYPOINT_ADDRESS_V06) {
const paymasterDataV06 =
paymasterData as GetPaymasterDataReturnType<ENTRYPOINT_ADDRESS_V06_TYPE>
return {
callGasLimit: BigInt(gas.callGasLimit),
verificationGasLimit: BigInt(gas.verificationGasLimit),
preVerificationGas: BigInt(gas.preVerificationGas),
paymasterAndData: paymasterDataV06?.paymasterAndData,
maxFeePerGas: BigInt(userOperation.maxFeePerGas),
maxPriorityFeePerGas: BigInt(userOperation.maxPriorityFeePerGas)
} as SponsorUserOperationEip7677ReturnType<entryPoint>
}
const stubDataV07 =
stubData as GetPaymasterStubDataReturnType<ENTRYPOINT_ADDRESS_V07_TYPE>
const paymasterDataV07 =
paymasterData as GetPaymasterDataReturnType<ENTRYPOINT_ADDRESS_V07_TYPE>

return {
callGasLimit: BigInt(gas.callGasLimit),
verificationGasLimit: BigInt(gas.verificationGasLimit),
preVerificationGas: BigInt(gas.preVerificationGas),
paymaster: paymasterDataV07.paymaster,
paymasterData: paymasterDataV07.paymasterData,
paymasterVerificationGasLimit:
stubDataV07.paymasterVerificationGasLimit &&
BigInt(stubDataV07.paymasterVerificationGasLimit),
paymasterPostOpGasLimit:
stubDataV07?.paymasterPostOpGasLimit &&
BigInt(stubDataV07.paymasterPostOpGasLimit),
maxFeePerGas: BigInt(userOperation.maxFeePerGas),
maxPriorityFeePerGas: BigInt(userOperation.maxPriorityFeePerGas)
} as SponsorUserOperationEip7677ReturnType<entryPoint>
}
26 changes: 25 additions & 1 deletion packages/core/clients/decorators/kernel.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { type SmartAccountActions, smartAccountActions } from "permissionless"
import {
type BundlerClient,
type SmartAccountActions,
smartAccountActions
} from "permissionless"
import type { Middleware } from "permissionless/actions/smartAccount"
import type { EntryPoint, Prettify } from "permissionless/types"
import type { StateOverrides } from "permissionless/types/bundler"
import type { Chain, Client, Hash, Transport } from "viem"
import type { KernelSmartAccount } from "../../accounts/index.js"
import {
Expand All @@ -19,11 +24,14 @@ import type {
ChangeSudoValidatorParameters,
SignUserOperationParameters,
SignUserOperationReturnType,
SponsorUserOperationEip7677Parameters,
SponsorUserOperationEip7677ReturnType,
UninstallPluginParameters
} from "../../actions/index.js"
import {
changeSudoValidator,
signUserOperation,
sponsorUserOperationEip7677,
uninstallPlugin
} from "../../actions/index.js"
import {
Expand All @@ -48,6 +56,11 @@ export type ZeroDevPaymasterClientActions<entryPoint extends EntryPoint> = {
estimateGasInERC20: (
args: EstimateGasInERC20Parameters
) => Promise<EstimateGasInERC20ReturnType>
sponsorUserOperationEip7677: (
args: SponsorUserOperationEip7677Parameters<entryPoint>,
bundlerClient: BundlerClient<entryPoint>,
stateOverrides?: StateOverrides
) => Promise<SponsorUserOperationEip7677ReturnType<entryPoint>>
}

export const zerodevPaymasterActions =
Expand All @@ -67,6 +80,17 @@ export const zerodevPaymasterActions =
estimateGasInERC20(
client as ZeroDevPaymasterClient<entryPoint>,
args
),
sponsorUserOperationEip7677: async (
args: SponsorUserOperationEip7677Parameters<entryPoint>,
bundlerClient: BundlerClient<entryPoint>,
stateOverrides?: StateOverrides
) =>
sponsorUserOperationEip7677(
client as ZeroDevPaymasterClient<entryPoint>,
args,
bundlerClient,
stateOverrides
)
})

Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zerodev/sdk",
"version": "5.3.22",
"version": "5.3.23",
"author": "ZeroDev",
"main": "./_cjs/index.js",
"module": "./_esm/index.js",
Expand Down

0 comments on commit d60fe9c

Please sign in to comment.