Skip to content

Commit d7e4846

Browse files
authored
fix: add retry logic (#29)
1 parent 46b9d53 commit d7e4846

File tree

5 files changed

+75
-42
lines changed

5 files changed

+75
-42
lines changed

composables/zksync/era/deposit/useFee.ts

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type { Ref } from "vue";
1010
import type { L1Signer, Provider } from "zksync-web3";
1111

1212
import { ETH_L2_ADDRESS } from "@/utils/constants";
13+
import { retry } from "@/utils/helpers";
1314
import { calculateFee } from "@/utils/helpers";
1415

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

81-
return await signer.getFullRequiredDepositFee({
82-
token: ETH_L1_ADDRESS,
83-
to: params.to,
82+
return retry(async () => {
83+
try {
84+
return await signer.getFullRequiredDepositFee({
85+
token: ETH_L1_ADDRESS,
86+
to: params.to,
87+
});
88+
} catch (err) {
89+
if (err instanceof Error && err.message.startsWith("Not enough balance for deposit.")) {
90+
const match = err.message.match(/([\d\\.]+) ETH/);
91+
if (feeToken.value && match?.length) {
92+
const ethAmount = match[1].split(" ")?.[0];
93+
recommendedBalance.value = ethAmount;
94+
return;
95+
}
96+
}
97+
throw err;
98+
}
8499
});
85100
};
86101
const getERC20TransactionFee = async () => {
@@ -89,7 +104,7 @@ export default (
89104
};
90105
};
91106
const getGasPrice = async () => {
92-
return BigNumber.from(await getPublicClient().getGasPrice())
107+
return BigNumber.from(await retry(() => getPublicClient().getGasPrice()))
93108
.mul(110)
94109
.div(100);
95110
};
@@ -105,29 +120,17 @@ export default (
105120
execute: estimateFee,
106121
} = usePromise(
107122
async () => {
108-
try {
109-
recommendedBalance.value = undefined;
110-
if (!feeToken.value) throw new Error("Fee tokens is not available");
123+
recommendedBalance.value = undefined;
124+
if (!feeToken.value) throw new Error("Fee tokens is not available");
111125

112-
if (params.tokenAddress === feeToken.value?.address) {
113-
fee.value = await getEthTransactionFee();
114-
} else {
115-
fee.value = await getERC20TransactionFee();
116-
}
117-
/* It can be either maxFeePerGas or gasPrice */
118-
if (!fee.value?.maxFeePerGas) {
119-
fee.value.gasPrice = await getGasPrice();
120-
}
121-
} catch (err) {
122-
if (err instanceof Error && err.message.startsWith("Not enough balance for deposit.")) {
123-
const match = err.message.match(/([\d\\.]+) ETH/);
124-
if (feeToken.value && match?.length) {
125-
const ethAmount = match[1].split(" ")?.[0];
126-
recommendedBalance.value = ethAmount;
127-
return;
128-
}
129-
}
130-
throw err;
126+
if (params.tokenAddress === feeToken.value?.address) {
127+
fee.value = await getEthTransactionFee();
128+
} else {
129+
fee.value = await getERC20TransactionFee();
130+
}
131+
/* It can be either maxFeePerGas or gasPrice */
132+
if (fee.value && !fee.value?.maxFeePerGas) {
133+
fee.value.gasPrice = await getGasPrice();
131134
}
132135
},
133136
{ cache: false }

composables/zksync/era/useFee.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { Ref } from "vue";
66
import type { Provider } from "zksync-web3";
77

88
import { ETH_L1_ADDRESS, ETH_L2_ADDRESS } from "@/utils/constants";
9+
import { retry } from "@/utils/helpers";
910
import { calculateFee } from "@/utils/helpers";
1011

1112
export type FeeEstimationParams = {
@@ -59,12 +60,15 @@ export default (
5960

6061
const provider = getProvider();
6162
await Promise.all([
62-
provider.getGasPrice().then((price) => (gasPrice.value = price)),
63-
provider[params.type === "transfer" ? "estimateGasTransfer" : "estimateGasWithdraw"]({
64-
from: params.from,
65-
to: params.to,
66-
token: params.tokenAddress === ETH_L2_ADDRESS ? ETH_L1_ADDRESS : params.tokenAddress,
67-
amount: "1",
63+
retry(() => provider.getGasPrice()).then((price) => (gasPrice.value = price)),
64+
retry(() => {
65+
if (!params) throw new Error("Params are not available");
66+
return provider[params.type === "transfer" ? "estimateGasTransfer" : "estimateGasWithdraw"]({
67+
from: params.from,
68+
to: params.to,
69+
token: params.tokenAddress === ETH_L2_ADDRESS ? ETH_L1_ADDRESS : params.tokenAddress,
70+
amount: "1",
71+
});
6872
}).then((limit) => (gasLimit.value = limit)),
6973
]);
7074
},

composables/zksync/lite/deposit/useFee.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type { BigNumberish } from "ethers";
1111
import type { Ref } from "vue";
1212
import type { Wallet } from "zksync";
1313

14+
import { retry } from "@/utils/helpers";
1415
import { calculateFee } from "@/utils/helpers";
1516

1617
export default (
@@ -57,15 +58,17 @@ export default (
5758

5859
const nonce = wallet.getNonce();
5960
const mainZkSyncContract = wallet.getZkSyncMainContract();
60-
const gasEstimate = await mainZkSyncContract.estimateGas
61-
.depositERC20(params.tokenAddress, "1000000000", params.from, {
62-
nonce,
63-
gasPrice: gasPrice,
64-
})
65-
.then(
66-
(estimate) => estimate,
67-
() => BigNumber.from("0")
68-
);
61+
const gasEstimate = await retry(() =>
62+
mainZkSyncContract.estimateGas
63+
.depositERC20(params.tokenAddress, "1000000000", params.from, {
64+
nonce,
65+
gasPrice: gasPrice,
66+
})
67+
.then(
68+
(estimate) => estimate,
69+
() => BigNumber.from("0")
70+
)
71+
);
6972
const recommendedGasLimit =
7073
publicClient.chain.id === 1 && ERC20_DEPOSIT_GAS_LIMIT[params.tokenAddress!]
7174
? BigNumber.from(ERC20_DEPOSIT_GAS_LIMIT[params.tokenAddress!])

store/ethereumBalance.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { useNetworkStore } from "@/store/network";
77
import { useOnboardStore } from "@/store/onboard";
88
import { ETH_L1_ADDRESS } from "@/utils/constants";
99
import { checksumAddress } from "@/utils/formatters";
10+
import { retry } from "@/utils/helpers";
1011

1112
export const useEthereumBalanceStore = defineStore("ethereumBalance", () => {
1213
const onboardStore = useOnboardStore();
@@ -42,7 +43,10 @@ export const useEthereumBalanceStore = defineStore("ethereumBalance", () => {
4243
await fetchBalances(result.pageKey);
4344
}
4445
};
45-
const [ethersBalance] = await Promise.all([alchemy.core.getBalance(account.value.address!), fetchBalances()]);
46+
const [ethersBalance] = await Promise.all([
47+
retry(() => alchemy.core.getBalance(account.value.address!)),
48+
retry(() => fetchBalances()),
49+
]);
4650
balances.push({
4751
contractAddress: ETH_L1_ADDRESS,
4852
tokenBalance: ethersBalance.toString(),

utils/helpers.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,22 @@ export const calculateTotalTokensPrice = (tokens: TokenAmount[]) => {
7272
return acc + parseFloat(parseTokenAmount(amount, decimals)) * price;
7373
}, 0);
7474
};
75+
76+
interface RetryOptions {
77+
retries?: number;
78+
}
79+
const DEFAULT_RETRY_OPTIONS: RetryOptions = {
80+
retries: 2,
81+
};
82+
export async function retry<T>(func: () => Promise<T>, options: RetryOptions = {}): Promise<T> {
83+
const { retries } = Object.assign({}, DEFAULT_RETRY_OPTIONS, options);
84+
try {
85+
return await func();
86+
} catch (error) {
87+
if (retries && retries > 0) {
88+
return retry(func, { retries: retries - 1 });
89+
} else {
90+
throw error;
91+
}
92+
}
93+
}

0 commit comments

Comments
 (0)