Skip to content

Commit

Permalink
feat: getting gas configuration from the bundler if paymaster only re…
Browse files Browse the repository at this point in the history
…turns paymasterAndData
  • Loading branch information
excaliborr committed Jan 5, 2024
1 parent c2e3ea9 commit 6c44097
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export const simpleAccountFactoryAddress = '0x9406Cc6185a346906296840746125a0E44976454';

export const dummySignature = '0xa15569dd8f8324dbeabf8023fdec36d4b754f53ce5901e283c6de79af177dc94557fa3c9922cd7af2a96ca94402d35c39f266925ee6407aeb32b31d76978d4ba1c';
export const dummySignature = '0xa15569dd8f8324dbeabf8073fdec36d4b754f53ce5901e283c6de79af177dc94557fa3c9922cd7af2a96ca94402d35c39f266925ee6407aeb32b31d76978d4ba1c';
36 changes: 26 additions & 10 deletions src/gasless-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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({
Expand Down Expand Up @@ -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 {
Expand Down
6 changes: 5 additions & 1 deletion src/paymasters/BasePaymaster.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SponsorUserOperationReturnType } from 'permissionless/actions/pimlico';
import { PartialUserOperation } from '../types';

export class BasePaymaster {
Expand All @@ -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,

Check warning on line 13 in src/paymasters/BasePaymaster.ts

View workflow job for this annotation

GitHub Actions / Run Linters (18.x)

'userOp' is defined but never used
entryPoint: `0x${string}`,

Check warning on line 14 in src/paymasters/BasePaymaster.ts

View workflow job for this annotation

GitHub Actions / Run Linters (18.x)

'entryPoint' is defined but never used
): Promise<`0x${string}` | SponsorUserOperationReturnType> {
throw new Error('This is a base class and should not be called directly.');
}
}
12 changes: 5 additions & 7 deletions src/paymasters/PimlicoPaymaster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
});
}
}
2 changes: 1 addition & 1 deletion src/paymasters/StackUpPaymaster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class StackUpPaymaster extends BasePaymaster {
public async sponsorUserOperation(
userOperation: PartialUserOperation,
entryPoint: `0x${string}`,
): Promise<SponsorUserOperationReturnType> {
): Promise<`0x${string}` | SponsorUserOperationReturnType> {
return await this.paymasterClient.sponsorUserOperation({
userOperation,
entryPoint,
Expand Down

0 comments on commit 6c44097

Please sign in to comment.