Skip to content

Commit 1c29556

Browse files
refactor: get userOp gas prices from bundler (#2631)
1 parent 15697ae commit 1c29556

File tree

4 files changed

+61
-13
lines changed

4 files changed

+61
-13
lines changed

.changeset/tall-socks-grin.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
Get userOp prices from bundler

packages/thirdweb/src/wallets/smart/lib/bundler.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { getClientFetch } from "../../../utils/fetch.js";
22
import { hexToBigInt, type Hex } from "../../../utils/encoding/hex.js";
33
import type {
44
EstimationResult,
5+
GasPriceResult,
56
SmartWalletOptions,
67
UserOperation,
78
} from "../types.js";
@@ -58,6 +59,24 @@ export async function estimateUserOpGas(args: {
5859
};
5960
}
6061

62+
/**
63+
* @internal
64+
*/
65+
export async function getUserOpGasPrice(args: {
66+
options: SmartWalletOptions & { client: ThirdwebClient };
67+
}): Promise<GasPriceResult> {
68+
const res = await sendBundlerRequest({
69+
...args,
70+
operation: "thirdweb_getUserOperationGasPrice",
71+
params: [],
72+
});
73+
74+
return {
75+
maxPriorityFeePerGas: hexToBigInt(res.maxPriorityFeePerGas),
76+
maxFeePerGas: hexToBigInt(res.maxFeePerGas),
77+
};
78+
}
79+
6180
/**
6281
* @internal
6382
*/
@@ -98,7 +117,8 @@ async function sendBundlerRequest(args: {
98117
operation:
99118
| "eth_estimateUserOperationGas"
100119
| "eth_sendUserOperation"
101-
| "eth_getUserOperationReceipt";
120+
| "eth_getUserOperationReceipt"
121+
| "thirdweb_getUserOperationGasPrice";
102122
params: any[];
103123
}) {
104124
const { options, operation, params } = args;

packages/thirdweb/src/wallets/smart/lib/userop.ts

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@ import { isContractDeployed } from "../../../utils/bytecode/is-contract-deployed
44
import type { ThirdwebContract } from "../../../contract/contract.js";
55
import { encode } from "../../../transaction/actions/encode.js";
66
import { getDefaultGasOverrides } from "../../../gas/fee-data.js";
7-
import { DUMMY_SIGNATURE, ENTRYPOINT_ADDRESS } from "./constants.js";
7+
import {
8+
DUMMY_SIGNATURE,
9+
ENTRYPOINT_ADDRESS,
10+
getDefaultBundlerUrl,
11+
} from "./constants.js";
812
import { getPaymasterAndData } from "./paymaster.js";
9-
import { estimateUserOpGas } from "./bundler.js";
13+
import { estimateUserOpGas, getUserOpGasPrice } from "./bundler.js";
1014
import { randomNonce } from "./utils.js";
1115
import { prepareCreateAccount } from "./calls.js";
1216
import type { Account } from "../../interfaces/wallet.js";
@@ -17,6 +21,7 @@ import { hexToBytes } from "../../../utils/encoding/to-bytes.js";
1721
import type { Hex } from "../../../utils/encoding/hex.js";
1822
import { encodeAbiParameters } from "../../../utils/abi/encodeAbiParameters.js";
1923
import type { ThirdwebClient } from "../../../client/client.js";
24+
import { isThirdwebUrl } from "../../../utils/fetch.js";
2025

2126
/**
2227
* Create an unsigned user operation
@@ -44,17 +49,30 @@ export async function createUnsignedUserOp(args: {
4449
options,
4550
});
4651
const callData = await encode(executeTx);
52+
4753
let { maxFeePerGas, maxPriorityFeePerGas } = executeTx;
48-
if (!maxFeePerGas || !maxPriorityFeePerGas) {
49-
const feeData = await getDefaultGasOverrides(
50-
factoryContract.client,
51-
factoryContract.chain,
52-
);
53-
if (!maxPriorityFeePerGas) {
54-
maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? undefined;
55-
}
56-
if (!maxFeePerGas) {
57-
maxFeePerGas = feeData.maxFeePerGas ?? undefined;
54+
const bundlerUrl =
55+
options.overrides?.bundlerUrl ?? getDefaultBundlerUrl(options.chain);
56+
if (isThirdwebUrl(bundlerUrl)) {
57+
// get gas prices from bundler
58+
const bundlerGasPrice = await getUserOpGasPrice({
59+
options,
60+
});
61+
maxFeePerGas = bundlerGasPrice.maxFeePerGas;
62+
maxPriorityFeePerGas = bundlerGasPrice.maxPriorityFeePerGas;
63+
} else {
64+
// otherwise fallback to RPC gas prices if not passed in explicitely
65+
if (!maxFeePerGas || !maxPriorityFeePerGas) {
66+
const feeData = await getDefaultGasOverrides(
67+
factoryContract.client,
68+
factoryContract.chain,
69+
);
70+
if (!maxPriorityFeePerGas) {
71+
maxPriorityFeePerGas = feeData.maxPriorityFeePerGas ?? undefined;
72+
}
73+
if (!maxFeePerGas) {
74+
maxFeePerGas = feeData.maxFeePerGas ?? undefined;
75+
}
5876
}
5977
}
6078

packages/thirdweb/src/wallets/smart/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,8 @@ export type EstimationResult = {
7676
verificationGasLimit: bigint;
7777
callGasLimit: bigint;
7878
};
79+
80+
export type GasPriceResult = {
81+
maxFeePerGas: bigint;
82+
maxPriorityFeePerGas: bigint;
83+
};

0 commit comments

Comments
 (0)