diff --git a/src/constants.ts b/src/constants.ts index d73f533..7075ec9 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,3 +1,3 @@ export const simpleAccountFactoryAddress = '0x9406Cc6185a346906296840746125a0E44976454'; -export const dummySignature = '0xa15569dd8f8324dbeabf8023fdec36d4b754f53ce5901e283c6de79af177dc94557fa3c9922cd7af2a96ca94402d35c39f266925ee6407aeb32b31d76978d4ba1c'; \ No newline at end of file +export const dummySignature = '0xa15569dd8f8324dbeabf8073fdec36d4b754f53ce5901e283c6de79af177dc94557fa3c9922cd7af2a96ca94402d35c39f266925ee6407aeb32b31d76978d4ba1c'; \ No newline at end of file diff --git a/src/gasless-provider.ts b/src/gasless-provider.ts index 459919b..2706f5a 100644 --- a/src/gasless-provider.ts +++ b/src/gasless-provider.ts @@ -10,6 +10,7 @@ import { getSenderAddress, signUserOperationHashWithECDSA } from 'permissionless import * as constants from '../src/constants'; import { BasePaymaster } from './paymasters'; import { PartialBy } from 'viem/types/utils'; +import { SponsorUserOperationReturnType } from 'permissionless/actions/pimlico'; const log = init('hardhat:plugin:gasless'); @@ -144,17 +145,22 @@ export class GaslessProvider extends ProviderWrapper { verificationGasLimit: 0n, // dummy value }; - const gasConfig = await this.bundlerClient.estimateUserOperationGas({ - userOperation: { - ...userOperation, - paymasterAndData: '0x', - }, - entryPoint: this._entryPoint, - }); + const paymasterAndData: `0x${string}` | SponsorUserOperationReturnType = + await this.paymasterClient.sponsorUserOperation(userOperation, this._entryPoint); + + let sponsoredUserOperation: UserOperation; + + if (typeof paymasterAndData === 'string') { + // If our paymaster only returns its paymasterAndData and not the gas parameters, we need to estimate them ourselves + const gasConfig = await this.bundlerClient.estimateUserOperationGas({ + userOperation: Object.assign(userOperation, { paymasterAndData: paymasterAndData }), + entryPoint: this._entryPoint, + }); - // REQUEST PIMLICO VERIFYING PAYMASTER SPONSORSHIP - const sponsorUserOperationResult = await this.paymasterClient.sponsorUserOperation(userOperation, this._entryPoint); - const sponsoredUserOperation: UserOperation = Object.assign(userOperation, sponsorUserOperationResult); + sponsoredUserOperation = Object.assign(userOperation, gasConfig, { paymasterAndData: paymasterAndData }); + } else { + sponsoredUserOperation = Object.assign(userOperation, paymasterAndData); + } // SIGN THE USER OPERATION const signature = await signUserOperationHashWithECDSA({ @@ -194,6 +200,16 @@ export class GaslessProvider extends ProviderWrapper { })) as string; return parseInt(rawChainId); } + + private handlePaymasterReturnType( + variable: `0x${string}` | SponsorUserOperationReturnType, + ): `0x${string}` | SponsorUserOperationReturnType { + if (typeof variable === 'string') { + return variable; + } else { + return variable as SponsorUserOperationReturnType; + } + } } function getRandomBigInt(min: bigint, max: bigint): bigint { diff --git a/src/paymasters/BasePaymaster.ts b/src/paymasters/BasePaymaster.ts index 9a16af4..6538591 100644 --- a/src/paymasters/BasePaymaster.ts +++ b/src/paymasters/BasePaymaster.ts @@ -1,3 +1,4 @@ +import { SponsorUserOperationReturnType } from 'permissionless/actions/pimlico'; import { PartialUserOperation } from '../types'; export class BasePaymaster { @@ -8,7 +9,10 @@ export class BasePaymaster { } // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async sponsorUserOperation(userOp: PartialUserOperation, entryPoint: `0x${string}`): Promise<`0x${string}`> { + public async sponsorUserOperation( + userOp: PartialUserOperation, + entryPoint: `0x${string}`, + ): Promise<`0x${string}` | SponsorUserOperationReturnType> { throw new Error('This is a base class and should not be called directly.'); } } diff --git a/src/paymasters/PimlicoPaymaster.ts b/src/paymasters/PimlicoPaymaster.ts index d42953a..d6115c1 100644 --- a/src/paymasters/PimlicoPaymaster.ts +++ b/src/paymasters/PimlicoPaymaster.ts @@ -17,12 +17,10 @@ export class PimlicoPaymaster extends BasePaymaster { public async sponsorUserOperation( userOperation: PartialUserOperation, entryPoint: `0x${string}`, - ): Promise<`0x${string}`> { - return ( - await this.paymasterClient.sponsorUserOperation({ - userOperation, - entryPoint, - }) - ).paymasterAndData; + ): Promise<`0x${string}` | SponsorUserOperationReturnType> { + return await this.paymasterClient.sponsorUserOperation({ + userOperation, + entryPoint, + }); } } diff --git a/src/paymasters/StackUpPaymaster.ts b/src/paymasters/StackUpPaymaster.ts index 77dd8dc..966bc11 100644 --- a/src/paymasters/StackUpPaymaster.ts +++ b/src/paymasters/StackUpPaymaster.ts @@ -18,7 +18,7 @@ export class StackUpPaymaster extends BasePaymaster { public async sponsorUserOperation( userOperation: PartialUserOperation, entryPoint: `0x${string}`, - ): Promise { + ): Promise<`0x${string}` | SponsorUserOperationReturnType> { return await this.paymasterClient.sponsorUserOperation({ userOperation, entryPoint,