Skip to content

Commit

Permalink
fix: add retry logic (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
JackHamer09 authored Jul 5, 2023
1 parent 46b9d53 commit d7e4846
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 42 deletions.
55 changes: 29 additions & 26 deletions composables/zksync/era/deposit/useFee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { Ref } from "vue";
import type { L1Signer, Provider } from "zksync-web3";

import { ETH_L2_ADDRESS } from "@/utils/constants";
import { retry } from "@/utils/helpers";
import { calculateFee } from "@/utils/helpers";

export type DepositFeeValues = {
Expand Down Expand Up @@ -78,9 +79,23 @@ export default (
const signer = getVoidL1Signer();
if (!signer) throw new Error("Signer is not available");

return await signer.getFullRequiredDepositFee({
token: ETH_L1_ADDRESS,
to: params.to,
return retry(async () => {
try {
return await signer.getFullRequiredDepositFee({
token: ETH_L1_ADDRESS,
to: params.to,
});
} catch (err) {
if (err instanceof Error && err.message.startsWith("Not enough balance for deposit.")) {
const match = err.message.match(/([\d\\.]+) ETH/);
if (feeToken.value && match?.length) {
const ethAmount = match[1].split(" ")?.[0];
recommendedBalance.value = ethAmount;
return;
}
}
throw err;
}
});
};
const getERC20TransactionFee = async () => {
Expand All @@ -89,7 +104,7 @@ export default (
};
};
const getGasPrice = async () => {
return BigNumber.from(await getPublicClient().getGasPrice())
return BigNumber.from(await retry(() => getPublicClient().getGasPrice()))
.mul(110)
.div(100);
};
Expand All @@ -105,29 +120,17 @@ export default (
execute: estimateFee,
} = usePromise(
async () => {
try {
recommendedBalance.value = undefined;
if (!feeToken.value) throw new Error("Fee tokens is not available");
recommendedBalance.value = undefined;
if (!feeToken.value) throw new Error("Fee tokens is not available");

if (params.tokenAddress === feeToken.value?.address) {
fee.value = await getEthTransactionFee();
} else {
fee.value = await getERC20TransactionFee();
}
/* It can be either maxFeePerGas or gasPrice */
if (!fee.value?.maxFeePerGas) {
fee.value.gasPrice = await getGasPrice();
}
} catch (err) {
if (err instanceof Error && err.message.startsWith("Not enough balance for deposit.")) {
const match = err.message.match(/([\d\\.]+) ETH/);
if (feeToken.value && match?.length) {
const ethAmount = match[1].split(" ")?.[0];
recommendedBalance.value = ethAmount;
return;
}
}
throw err;
if (params.tokenAddress === feeToken.value?.address) {
fee.value = await getEthTransactionFee();
} else {
fee.value = await getERC20TransactionFee();
}
/* It can be either maxFeePerGas or gasPrice */
if (fee.value && !fee.value?.maxFeePerGas) {
fee.value.gasPrice = await getGasPrice();
}
},
{ cache: false }
Expand Down
16 changes: 10 additions & 6 deletions composables/zksync/era/useFee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { Ref } from "vue";
import type { Provider } from "zksync-web3";

import { ETH_L1_ADDRESS, ETH_L2_ADDRESS } from "@/utils/constants";
import { retry } from "@/utils/helpers";
import { calculateFee } from "@/utils/helpers";

export type FeeEstimationParams = {
Expand Down Expand Up @@ -59,12 +60,15 @@ export default (

const provider = getProvider();
await Promise.all([
provider.getGasPrice().then((price) => (gasPrice.value = price)),
provider[params.type === "transfer" ? "estimateGasTransfer" : "estimateGasWithdraw"]({
from: params.from,
to: params.to,
token: params.tokenAddress === ETH_L2_ADDRESS ? ETH_L1_ADDRESS : params.tokenAddress,
amount: "1",
retry(() => provider.getGasPrice()).then((price) => (gasPrice.value = price)),
retry(() => {
if (!params) throw new Error("Params are not available");
return provider[params.type === "transfer" ? "estimateGasTransfer" : "estimateGasWithdraw"]({
from: params.from,
to: params.to,
token: params.tokenAddress === ETH_L2_ADDRESS ? ETH_L1_ADDRESS : params.tokenAddress,
amount: "1",
});
}).then((limit) => (gasLimit.value = limit)),
]);
},
Expand Down
21 changes: 12 additions & 9 deletions composables/zksync/lite/deposit/useFee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type { BigNumberish } from "ethers";
import type { Ref } from "vue";
import type { Wallet } from "zksync";

import { retry } from "@/utils/helpers";
import { calculateFee } from "@/utils/helpers";

export default (
Expand Down Expand Up @@ -57,15 +58,17 @@ export default (

const nonce = wallet.getNonce();
const mainZkSyncContract = wallet.getZkSyncMainContract();
const gasEstimate = await mainZkSyncContract.estimateGas
.depositERC20(params.tokenAddress, "1000000000", params.from, {
nonce,
gasPrice: gasPrice,
})
.then(
(estimate) => estimate,
() => BigNumber.from("0")
);
const gasEstimate = await retry(() =>
mainZkSyncContract.estimateGas
.depositERC20(params.tokenAddress, "1000000000", params.from, {
nonce,
gasPrice: gasPrice,
})
.then(
(estimate) => estimate,
() => BigNumber.from("0")
)
);
const recommendedGasLimit =
publicClient.chain.id === 1 && ERC20_DEPOSIT_GAS_LIMIT[params.tokenAddress!]
? BigNumber.from(ERC20_DEPOSIT_GAS_LIMIT[params.tokenAddress!])
Expand Down
6 changes: 5 additions & 1 deletion store/ethereumBalance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useNetworkStore } from "@/store/network";
import { useOnboardStore } from "@/store/onboard";
import { ETH_L1_ADDRESS } from "@/utils/constants";
import { checksumAddress } from "@/utils/formatters";
import { retry } from "@/utils/helpers";

export const useEthereumBalanceStore = defineStore("ethereumBalance", () => {
const onboardStore = useOnboardStore();
Expand Down Expand Up @@ -42,7 +43,10 @@ export const useEthereumBalanceStore = defineStore("ethereumBalance", () => {
await fetchBalances(result.pageKey);
}
};
const [ethersBalance] = await Promise.all([alchemy.core.getBalance(account.value.address!), fetchBalances()]);
const [ethersBalance] = await Promise.all([
retry(() => alchemy.core.getBalance(account.value.address!)),
retry(() => fetchBalances()),
]);
balances.push({
contractAddress: ETH_L1_ADDRESS,
tokenBalance: ethersBalance.toString(),
Expand Down
19 changes: 19 additions & 0 deletions utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,22 @@ export const calculateTotalTokensPrice = (tokens: TokenAmount[]) => {
return acc + parseFloat(parseTokenAmount(amount, decimals)) * price;
}, 0);
};

interface RetryOptions {
retries?: number;
}
const DEFAULT_RETRY_OPTIONS: RetryOptions = {
retries: 2,
};
export async function retry<T>(func: () => Promise<T>, options: RetryOptions = {}): Promise<T> {
const { retries } = Object.assign({}, DEFAULT_RETRY_OPTIONS, options);
try {
return await func();
} catch (error) {
if (retries && retries > 0) {
return retry(func, { retries: retries - 1 });
} else {
throw error;
}
}
}

0 comments on commit d7e4846

Please sign in to comment.