Skip to content

Commit

Permalink
Merge branch 'feat/update-bundler-docs' into docs
Browse files Browse the repository at this point in the history
  • Loading branch information
joepegler committed Mar 13, 2024
2 parents 8ccc2d5 + 33353ff commit 9133a20
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 76 deletions.
115 changes: 98 additions & 17 deletions packages/bundler/src/Bundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { IBundler } from "./interfaces/IBundler.js";
import {
GetUserOperationReceiptResponse,
GetUserOpByHashResponse,
Bundlerconfig,
BundlerConfig,
UserOpResponse,
EstimateUserOpGasResponse,
UserOpReceipt,
Expand Down Expand Up @@ -37,18 +37,29 @@ import { sendRequest, HttpMethod, StateOverrideSet } from "@biconomy/common";
export class Bundler implements IBundler {
private bundlerConfig: BundlerConfigWithChainId;

// eslint-disable-next-line no-unused-vars
/**
* @description The polling interval per chain for the tx receipt in milliseconds. Default value is 5 seconds
*/
UserOpReceiptIntervals!: { [key in number]?: number };

Check warning on line 43 in packages/bundler/src/Bundler.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

'key' is defined but never used

/**
* @description The polling interval per chain for the tx result in milliseconds. Default value is 0.5 seconds
* */
UserOpWaitForTxHashIntervals!: { [key in number]?: number };

Check warning on line 48 in packages/bundler/src/Bundler.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

'key' is defined but never used

/**
* @description The maximum duration in milliseconds per chain to wait for the tx receipt. Default value is 30 seconds
*/
UserOpReceiptMaxDurationIntervals!: { [key in number]?: number };

Check warning on line 53 in packages/bundler/src/Bundler.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

'key' is defined but never used

/**
* @description The maximum duration in milliseconds per chain to wait for the tx hash. Default value is 20 seconds
*/
UserOpWaitForTxHashMaxDurationIntervals!: { [key in number]?: number };

Check warning on line 58 in packages/bundler/src/Bundler.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

'key' is defined but never used

private provider: PublicClient;

constructor(bundlerConfig: Bundlerconfig) {
constructor(bundlerConfig: BundlerConfig) {
const parsedChainId: number = bundlerConfig?.chainId || extractChainIdFromBundlerUrl(bundlerConfig.bundlerUrl);
this.bundlerConfig = { ...bundlerConfig, chainId: parsedChainId };

Expand Down Expand Up @@ -85,13 +96,44 @@ export class Bundler implements IBundler {
}

/**
* @param userOpHash
* @description This function will fetch gasPrices from bundler
* @returns Promise<UserOpGasPricesResponse>
*
* @description This function will estimate gasPrices from bundler
* It is expected that the userOp is already signed and the paymasterAndData is already provided by the caller
*
* @param userOpHash {@link UserOperationStruct}
* @param stateOverrideSet {@link StateOverrideSet}
* @returns Promise<UserOpGasResponse>
*
* @example
*
* import { createBundler } from "@biconomy/bundler"
* import { createSmartAccountClient } from "@biconomy/smartaccount"
*
* const bundler = await createBundler({
* bundlerUrl: "", // <-- Read about this at https://docs.biconomy.io/dashboard#bundler-url
* });
*
* const smartWallet = await createSmartAccountClient({
* signer,
* bundler
* });
*
* const tx = {
* to: "0x000000D50C68705bd6897B2d17c7de32FB519fDA",
* data: "0x"
* };
*
* const userOp = await smartWallet.buildUserOp([tx]);
* const {
* maxFeePerGas,
* maxPriorityFeePerGas,
* verificationGasLimit,
* callGasLimit,
* preVerificationGas,
* } = await bundler.estimateUserOpGas(userOp);
*
*/
async estimateUserOpGas(userOp: UserOperationStruct, stateOverrideSet?: StateOverrideSet): Promise<UserOpGasResponse> {
// expected dummySig and possibly dummmy paymasterAndData should be provided by the caller
// bundler doesn't know account and paymaster implementation
userOp = transformUserOP(userOp);
const bundlerUrl = this.getBundlerUrl();

Expand Down Expand Up @@ -123,9 +165,36 @@ export class Bundler implements IBundler {

/**
*
* @param userOp
* @description This function will send signed userOp to bundler to get mined on chain
* @returns Promise<UserOpResponse>
* Sends a user operation via the bundler
*
* @param userOp {@link UserOperationStruct}
* @param simulationParam {@link SimulationType}
* @description This function will take a user op as an input and send it to the bundler.
* @returns Promise<{@link UserOpResponse}> that you can use to track the user operation.
*
* @example
* import { createBundler } from "@biconomy/bundler"
* import { createSmartAccountClient } from "@biconomy/smartaccount"
*
* const bundler = await createBundler({
* bundlerUrl: "", // <-- Read about this at https://docs.biconomy.io/dashboard#bundler-url
* });
*
* const smartWallet = await createSmartAccountClient({
* signer,
* bundler
* });
*
* const tx = {
* to: "0x000000D50C68705bd6897B2d17c7de32FB519fDA",
* data: "0x"
* };
*
* const userOp = await smartWallet.buildUserOp([tx]);
*
* const { wait } = await bundler.sendUserOp(userOp);
* const { success, receipt } = await wait();
*
*/
async sendUserOp(userOp: UserOperationStruct, simulationParam?: SimulationType): Promise<UserOpResponse> {
const chainId = this.bundlerConfig.chainId;
Expand Down Expand Up @@ -238,7 +307,7 @@ export class Bundler implements IBundler {
*
* @param userOpHash
* @description This function will return userOpReceipt for a given userOpHash
* @returns Promise<UserOpReceipt>
* @returns Promise<{@link UserOpReceipt}>
*/
async getUserOpReceipt(userOpHash: string): Promise<UserOpReceipt> {
const bundlerUrl = this.getBundlerUrl();
Expand All @@ -260,10 +329,10 @@ export class Bundler implements IBundler {
}

/**
* @description This function will return userOp status for a given hash
*
* @param userOpHash
* @description This function will return userOpReceipt for a given userOpHash
* @returns Promise<UserOpReceipt>
* @returns Promise<{@link UserOpStatus}>
*/
async getUserOpStatus(userOpHash: string): Promise<UserOpStatus> {
const bundlerUrl = this.getBundlerUrl();
Expand All @@ -286,9 +355,20 @@ export class Bundler implements IBundler {

/**
*
* @param userOpHash
* @description this function will return UserOpByHashResponse for given UserOpHash
* @returns Promise<UserOpByHashResponse>
*
* @param userOpHash hash of the user operation
* @returns Promise<{@link UserOpByHashResponse}> that you can use to track the user operation.
*
* @example
* import { createBundler } from "@biconomy/bundler"
*
* const bundler = await createBundler({
* bundlerUrl: "", // <-- Read about this at https://docs.biconomy.io/dashboard#bundler-url
* });
*
* const { transactionHash } = await bundler.getUserOpByHash("0x...");
*
*/
async getUserOpByHash(userOpHash: string): Promise<UserOpByHashResponse> {
const bundlerUrl = this.getBundlerUrl();
Expand All @@ -311,6 +391,7 @@ export class Bundler implements IBundler {

/**
* @description This function will return the gas fee values
* @returns Promise<{@link GasFeeValues}>
*/
async getGasFeeValues(): Promise<GasFeeValues> {
const bundlerUrl = this.getBundlerUrl();
Expand All @@ -330,7 +411,7 @@ export class Bundler implements IBundler {
return response.result;
}

public static async create(config: Bundlerconfig): Promise<Bundler> {
public static async create(config: BundlerConfig): Promise<Bundler> {
return new Bundler(config);
}
}
15 changes: 12 additions & 3 deletions packages/bundler/src/utils/Constants.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
/**

Check failure on line 1 in packages/bundler/src/utils/Constants.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

Delete `·`
* @description The polling interval per chain for the tx receipt in milliseconds. Default value is 5 seconds

Check failure on line 2 in packages/bundler/src/utils/Constants.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

Delete `·`
*/

Check failure on line 3 in packages/bundler/src/utils/Constants.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

Insert `·`
export const UserOpReceiptIntervals: { [key in number]?: number } = {

Check warning on line 4 in packages/bundler/src/utils/Constants.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

'key' is defined but never used
[1]: 10000,
};

// Note: Default value is 500(0.5sec)
/**

Check failure on line 8 in packages/bundler/src/utils/Constants.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

Delete `·`
* @description The polling interval per chain for the tx hash in milliseconds. Default value is 0.5 seconds

Check failure on line 9 in packages/bundler/src/utils/Constants.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

Delete `·`
*/
export const UserOpWaitForTxHashIntervals: { [key in number]?: number } = {

Check warning on line 11 in packages/bundler/src/utils/Constants.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

'key' is defined but never used
[1]: 1000,
};

// Note: Default value is 30000 (30sec)
/**

Check failure on line 15 in packages/bundler/src/utils/Constants.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

Delete `·`
* @description The maximum duration in milliseconds per chain to wait for the tx receipt. Default value is 30 seconds
*/
export const UserOpReceiptMaxDurationIntervals: { [key in number]?: number } = {

Check warning on line 18 in packages/bundler/src/utils/Constants.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

'key' is defined but never used
[1]: 300000,
[80001]: 50000,
Expand All @@ -19,7 +26,9 @@ export const UserOpReceiptMaxDurationIntervals: { [key in number]?: number } = {
[59140]: 50000, // linea testnet
};

// Note: Default value is 20000 (20sec)
/**

Check failure on line 29 in packages/bundler/src/utils/Constants.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

Delete `·`
* @description The maximum duration in milliseconds per chain to wait for the tx hash. Default value is 20 seconds
*/
export const UserOpWaitForTxHashMaxDurationIntervals: { [key in number]?: number } = {

Check warning on line 32 in packages/bundler/src/utils/Constants.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

'key' is defined but never used
[1]: 20000,
};
Expand Down
45 changes: 39 additions & 6 deletions packages/bundler/src/utils/Types.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import { UserOperationStruct } from "@alchemy/aa-core";
import { UserOperationStruct, UserOperationReceipt } from "@alchemy/aa-core";
import { Chain, Hex } from "viem";

export type Bundlerconfig = {
export type BundlerConfig = {
/** The URL of the bundler service */
bundlerUrl: string;
/** entryPointAddress: address of the entry point */
entryPointAddress?: string;
/** the network id */
chainId?: number;
// eslint-disable-next-line no-unused-vars
/** The polling interval per chain for the tx receipt in milliseconds. Default value is 5 seconds */
userOpReceiptIntervals?: { [key in number]?: number };

Check warning on line 12 in packages/bundler/src/utils/Types.ts

View workflow job for this annotation

GitHub Actions / Lint sources (18.x)

'key' is defined but never used
/** The polling interval per chain for the tx result in milliseconds. Default value is 0.5 seconds */
userOpWaitForTxHashIntervals?: { [key in number]?: number };
/** The maximum duration in milliseconds per chain to wait for the tx receipt. Default value is 30 seconds */
userOpReceiptMaxDurationIntervals?: { [key in number]?: number };
/** The maximum duration in milliseconds per chain to wait for the tx hash. Default value is 20 seconds */
userOpWaitForTxHashMaxDurationIntervals?: { [key in number]?: number };
/** Can be used to optionally override the chain with a custom chain if it doesn't already exist in viems list of supported chains */
viemChain?: Chain;
};
export type BundlerConfigWithChainId = Bundlerconfig & { chainId: number };
export type BundlerConfigWithChainId = BundlerConfig & { chainId: number };

export type UserOpReceipt = {
/* The request hash of the UserOperation. */
Expand All @@ -31,9 +37,9 @@ export type UserOpReceipt = {
/* In case of revert, this is the revert reason. */
reason: string;
/* The logs generated by this UserOperation (not including logs of other UserOperations in the same bundle). */
logs: Array<any>; // The logs generated by this UserOperation (not including logs of other UserOperations in the same bundle)
logs: Array<any>;
/* The TransactionReceipt object for the entire bundle, not only for this UserOperation. */
receipt: any;
receipt: UserOperationReceipt["receipt"];
};

// review
Expand All @@ -43,28 +49,42 @@ export type UserOpStatus = {
userOperationReceipt?: UserOpReceipt;
};

/**
* @description SimulationType
* "validation_and_execution" is recommended during development for improved debugging & devEx, but will add some additional latency to calls.
* "validation" can be used in production mode to remove this latency after flows have been tested.
*/
export type SimulationType = "validation" | "validation_and_execution";

// Converted to JsonRpcResponse with strict type
export type GetUserOperationReceiptResponse = {
/** The JSON-RPC url */
jsonrpc: string;
/** Request id */
id: number;
result: UserOpReceipt;
/** The error if the request failed */
error?: JsonRpcError;
};

export type GetUserOperationStatusResponse = {
/** The JSON-RPC url */
jsonrpc: string;
/** Request id */
id: number;
result: UserOpStatus;
/** The error if the request failed */
error?: JsonRpcError;
};

// Converted to JsonRpcResponse with strict type
export type SendUserOpResponse = {
/** The JSON-RPC url */
jsonrpc: string;
/** Request id */
id: number;
result: string;
/** The error if the request failed */
error?: JsonRpcError;
};

Expand All @@ -77,17 +97,26 @@ export type UserOpResponse = {

// Converted to JsonRpcResponse with strict type
export type EstimateUserOpGasResponse = {
/** The JSON-RPC url */
jsonrpc: string;
/** Request id */
id: number;
/** The result of the estimate gas request */
result: UserOpGasResponse;
/** The error if the request failed */
error?: JsonRpcError;
};

export type UserOpGasResponse = {
/* The amount of gas to pay to compensate the bundler for pre-verification execution and calldata */
preVerificationGas: string;
/*The amount of gas to allocate for the verification step. */
verificationGasLimit: string;
/* The amount of gas to allocate for the main execution call */
callGasLimit: string;
/* Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas) */
maxPriorityFeePerGas: string;
/* Maximum fee per gas (similar to EIP-1559 max_fee_per_gas) */
maxFeePerGas: string;
};

Expand All @@ -100,9 +129,13 @@ export type GetUserOpByHashResponse = {
};

export type UserOpByHashResponse = UserOperationStruct & {
/** The transaction hash of the UserOperation. */
transactionHash: string;
/** The block number of the UserOperation. */
blockNumber: number;
/** The block hash of the UserOperation. */
blockHash: string;
/** The entrypoint used */
entryPoint: string;
};
/* eslint-disable @typescript-eslint/no-explicit-any */
Expand Down
Loading

0 comments on commit 9133a20

Please sign in to comment.