Skip to content

Commit

Permalink
[Wallets] fix gas estimations for local and embedded wallets (#2143)
Browse files Browse the repository at this point in the history
  • Loading branch information
joaquim-verges authored Jan 10, 2024
1 parent 756d5cc commit 85e3171
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 35 deletions.
6 changes: 6 additions & 0 deletions .changeset/lucky-pianos-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@thirdweb-dev/wallets": patch
"@thirdweb-dev/sdk": patch
---

Fix gas estimations for local and embedded wallets
6 changes: 0 additions & 6 deletions packages/sdk/src/evm/common/gas-price.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ChainId } from "../constants/chains/ChainId";
import { BigNumber, utils, providers } from "ethers";
import { Mumbai, Polygon } from "@thirdweb-dev/chains";
import { isBrowser } from "./utils";

type FeeData = {
maxFeePerGas: null | BigNumber;
Expand All @@ -10,11 +9,6 @@ type FeeData = {
};

export async function getDefaultGasOverrides(provider: providers.Provider) {
// If we're running in the browser, let users configure gas price in their wallet UI
if (isBrowser()) {
return {};
}

// handle smart wallet provider
if ((provider as any).originalProvider) {
provider = (provider as any).originalProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
PermitRequestMessage,
} from "../../types";
import { RPCConnectionHandler } from "./rpc-connection-handler";
import { isBrowser } from "../../../common/utils";

/**
* @internal
Expand Down Expand Up @@ -145,6 +146,10 @@ export class ContractWrapper<
* @internal
*/
public async getCallOverrides(): Promise<CallOverrides> {
// If we're running in the browser, let users configure gas price in their wallet UI
if (isBrowser()) {
return {};
}
return getDefaultGasOverrides(this.getProvider());
}

Expand Down
18 changes: 6 additions & 12 deletions packages/sdk/src/evm/core/classes/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import type {
TransactionOptionsWithContractWrapper,
} from "../../types/transactions";
import { GaslessTransaction, TransactionResult } from "../types";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { ThirdwebStorage, isBrowser } from "@thirdweb-dev/storage";
import {
BaseContract,
CallOverrides,
Expand Down Expand Up @@ -222,19 +222,13 @@ abstract class TransactionContext {
* Get gas overrides for the transaction
*/
protected async getGasOverrides() {
// If we're running in the browser, let users configure gas price in their wallet UI
// TODO - should prob only check if its a json rpc signer (browser extension)
if (isBrowser()) {
return {};
}
return getDefaultGasOverrides(this.provider);
}

/**
* Calculates the priority fee per gas according (adding a 10% buffer)
*/
private getPreferredPriorityFee(
defaultPriorityFeePerGas: BigNumber,
): BigNumber {
const extraTip = defaultPriorityFeePerGas.div(100).mul(10); // + 10%
const txGasPrice = defaultPriorityFeePerGas.add(extraTip);
return txGasPrice;
}
}

export class Transaction<
Expand Down
28 changes: 13 additions & 15 deletions packages/sdk/src/evm/core/wallet/user-wallet.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { BlockTag } from "@ethersproject/abstract-provider";
import type { IERC20 } from "@thirdweb-dev/contracts-js";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { ThirdwebStorage, isBrowser } from "@thirdweb-dev/storage";
import {
BigNumber,
Wallet,
Expand Down Expand Up @@ -112,10 +112,14 @@ export class UserWallet {
if (isNativeToken(resolvedCurrency)) {
// native token transfer
const from = await signer.getAddress();
const gasOverrides = isBrowser()
? {}
: await getDefaultGasOverrides(this.connection.getProvider());
const tx = await signer.sendTransaction({
from,
to: resolvedTo,
value: amountInWei,
...gasOverrides,
});
return {
receipt: await tx.wait(),
Expand Down Expand Up @@ -294,20 +298,14 @@ export class UserWallet {
transactionRequest: providers.TransactionRequest,
): Promise<providers.TransactionResponse> {
const signer = this.requireWallet();
const hasGasPrice = !!transactionRequest.gasPrice;
const hasFeeData =
!!transactionRequest.maxFeePerGas &&
!!transactionRequest.maxPriorityFeePerGas;
const hasGasData = hasGasPrice || hasFeeData;
if (!hasGasData) {
// set default gas values
const defaultGas = await getDefaultGasOverrides(
this.connection.getProvider(),
);
transactionRequest.maxFeePerGas = defaultGas.maxFeePerGas;
transactionRequest.maxPriorityFeePerGas = defaultGas.maxPriorityFeePerGas;
transactionRequest.gasPrice = defaultGas.gasPrice;
}
// set default gas values
const gasOverrides = isBrowser()
? {}
: await getDefaultGasOverrides(this.connection.getProvider());
transactionRequest = {
...gasOverrides,
...transactionRequest,
};
return signer.sendTransaction(transactionRequest);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {

import Provider from "ethereum-provider";
import type { EmbeddedWalletIframeCommunicator } from "../../utils/iFrameCommunication/EmbeddedWalletIframeCommunicator";
import { getDefaultGasOverrides } from "@thirdweb-dev/sdk";

export type SignerProcedureTypes = {
getAddress: void;
Expand Down Expand Up @@ -98,6 +99,20 @@ export class EthersSigner extends Signer {
return signedTransaction;
}

override async sendTransaction(
transaction: Deferrable<providers.TransactionRequest>,
): Promise<providers.TransactionResponse> {
if (!this.provider) {
throw new Error("Provider not found");
}
const gas = await getDefaultGasOverrides(this.provider);
const txWithGas = {
...gas,
...transaction,
};
return super.sendTransaction(txWithGas);
}

async _signTypedData(
domain: SignerProcedureTypes["signTypedDataV4"]["domain"],
types: SignerProcedureTypes["signTypedDataV4"]["types"],
Expand Down
6 changes: 4 additions & 2 deletions packages/wallets/src/evm/connectors/local-wallet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { Signer } from "ethers";
import { providers } from "ethers";
import type { Wallet } from "ethers";
import { getChainProvider } from "@thirdweb-dev/sdk";
import { WrappedSigner } from "./wrapped-signer";

export type LocalWalletConnectorOptions = {
chain: Chain;
Expand Down Expand Up @@ -119,8 +120,9 @@ function getSignerFromEthersWallet(
ethersWallet: Wallet,
provider?: providers.Provider,
) {
let signer = ethersWallet;
if (provider) {
return ethersWallet.connect(provider);
signer = ethersWallet.connect(provider);
}
return ethersWallet;
return new WrappedSigner(signer);
}
42 changes: 42 additions & 0 deletions packages/wallets/src/evm/connectors/local-wallet/wrapped-signer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { getDefaultGasOverrides } from "@thirdweb-dev/sdk";
import { Bytes, Signer, providers } from "ethers";
import { Deferrable, defineReadOnly } from "ethers/lib/utils";

export class WrappedSigner extends Signer {
constructor(private signer: Signer) {
super();
defineReadOnly(this, "provider", signer.provider);
}

override async getAddress(): Promise<string> {
return await this.signer.getAddress();
}

override async signMessage(message: Bytes | string): Promise<string> {
return await this.signer.signMessage(message);
}

override async signTransaction(
transaction: Deferrable<providers.TransactionRequest>,
): Promise<string> {
return await this.signer.signTransaction(transaction);
}

override connect(provider: providers.Provider): Signer {
return new WrappedSigner(this.signer.connect(provider));
}

override async sendTransaction(
transaction: Deferrable<providers.TransactionRequest>,
): Promise<providers.TransactionResponse> {
if (!this.provider) {
throw new Error("Provider not found");
}
const gas = await getDefaultGasOverrides(this.provider);
const txWithGas = {
...gas,
...transaction,
};
return await this.signer.sendTransaction(txWithGas);
}
}
3 changes: 3 additions & 0 deletions packages/wallets/src/evm/wallets/abstract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
Price,
TransactionResult,
fetchCurrencyValue,
getDefaultGasOverrides,
isNativeToken,
normalizePriceValue,
} from "@thirdweb-dev/sdk";
Expand Down Expand Up @@ -148,10 +149,12 @@ export abstract class AbstractWallet
);

if (isNativeToken(currencyAddress)) {
const gas = getDefaultGasOverrides(signer.provider);
const tx = await signer.sendTransaction({
from,
to,
value,
...gas,
});
return { receipt: await tx.wait() };
} else {
Expand Down

0 comments on commit 85e3171

Please sign in to comment.