From e43580a009f595aa9c0038c0e8b00c85de269b07 Mon Sep 17 00:00:00 2001
From: MattClabs <139958714+MattClabs@users.noreply.github.com>
Date: Thu, 24 Oct 2024 17:01:47 +0200
Subject: [PATCH 01/10] Update messages.json
Updating the AO process outage copy
---
assets/_locales/en/messages.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/assets/_locales/en/messages.json b/assets/_locales/en/messages.json
index a3309f0d..de800224 100644
--- a/assets/_locales/en/messages.json
+++ b/assets/_locales/en/messages.json
@@ -1564,7 +1564,7 @@
"description": "Not connected indicator"
},
"not_connected_text": {
- "message": "\"Connect / Disconnect\" is an indicator for when your ArConnect wallet is connected to an Arweave or AO application. For regular use like sending, receiving, checking balances, etc., ArConnect will always show disconnected.",
+ "message": "\"Connect / Disconnect\" is a label for when your ArConnect wallet is connected to an Arweave or AO dapp. For regular use like sending, receiving, checking balances, etc., ArConnect will always show disconnected.",
"description": "Not connected indicator explainer"
},
"disconnect": {
@@ -2009,11 +2009,11 @@
"description": "Popup description about ao token transfer learn more"
},
"ao_degraded": {
- "message": "Unable to connect to AO Token Process",
+ "message": "Token balance error",
"description": "ao degraded title text"
},
"ao_degraded_description": {
- "message": "AO balance will be available when
network issues are resolved.",
+ "message": "Ops, we are unable to fetch your token balance. This is just an UI issue. Please try again later.",
"description": "ao degraded description text"
},
"network_issue": {
From 71f15acedbc99279c0033f5320c2c21f29778467 Mon Sep 17 00:00:00 2001
From: MattClabs <139958714+MattClabs@users.noreply.github.com>
Date: Thu, 24 Oct 2024 17:04:31 +0200
Subject: [PATCH 02/10] Update messages.json
Updating the Chinese copy
---
assets/_locales/zh_CN/messages.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/assets/_locales/zh_CN/messages.json b/assets/_locales/zh_CN/messages.json
index 199c4db1..0bfc4df4 100644
--- a/assets/_locales/zh_CN/messages.json
+++ b/assets/_locales/zh_CN/messages.json
@@ -1999,11 +1999,11 @@
"description": "Popup description about ao token transfer learn more"
},
"ao_degraded": {
- "message": "无法连接到 AO 令牌进程",
+ "message": "代币余额错误",
"description": "ao degraded title text"
},
"ao_degraded_description": {
- "message": "网络问题解决后,AO 余额将可用。",
+ "message": "ArConnect 无法获取您的代币余额。这只是一个用户界面问题。请稍后重试。",
"description": "ao degraded description text"
},
"network_issue": {
From bb3d7c3c99a42f217677a84dd99ed38d3391cc39 Mon Sep 17 00:00:00 2001
From: MattClabs <139958714+MattClabs@users.noreply.github.com>
Date: Thu, 24 Oct 2024 17:05:41 +0200
Subject: [PATCH 03/10] Updating AO Process outage copy - English.json
---
assets/_locales/en/messages.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/assets/_locales/en/messages.json b/assets/_locales/en/messages.json
index de800224..2b3c1106 100644
--- a/assets/_locales/en/messages.json
+++ b/assets/_locales/en/messages.json
@@ -2013,7 +2013,7 @@
"description": "ao degraded title text"
},
"ao_degraded_description": {
- "message": "Ops, we are unable to fetch your token balance. This is just an UI issue. Please try again later.",
+ "message": "Ops, ArConnect is unable to fetch your token balance. This is just an UI issue. Please try again later.",
"description": "ao degraded description text"
},
"network_issue": {
From 34d3854a85cf05a8212311e76920f1aa08a4a4e6 Mon Sep 17 00:00:00 2001
From: MattClabs <139958714+MattClabs@users.noreply.github.com>
Date: Thu, 24 Oct 2024 17:19:07 +0200
Subject: [PATCH 04/10] Updating AO Token process outage copy - english.json
---
assets/_locales/en/messages.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/assets/_locales/en/messages.json b/assets/_locales/en/messages.json
index 2b3c1106..6e667d67 100644
--- a/assets/_locales/en/messages.json
+++ b/assets/_locales/en/messages.json
@@ -2013,7 +2013,7 @@
"description": "ao degraded title text"
},
"ao_degraded_description": {
- "message": "Ops, ArConnect is unable to fetch your token balance. This is just an UI issue. Please try again later.",
+ "message": "Ops, ArConnect is unable to fetch your token balance. Please try again later.",
"description": "ao degraded description text"
},
"network_issue": {
From 801b713ee3f3ae12e5521416345ac14b97fbe19e Mon Sep 17 00:00:00 2001
From: 7i7o
Date: Thu, 24 Oct 2024 17:30:28 +0200
Subject: [PATCH 05/10] Use Narrow tootlip for messages
---
src/components/popup/Token.tsx | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/components/popup/Token.tsx b/src/components/popup/Token.tsx
index f23afbe2..af3ca72b 100644
--- a/src/components/popup/Token.tsx
+++ b/src/components/popup/Token.tsx
@@ -166,13 +166,13 @@ export default function Token({ onClick, ...props }: Props) {
{props?.loading ? (
) : props?.error ? (
-
+
-
+
) : props?.networkError ? (
-
+
-
+
) : (
<>
{showTooltip ? (
@@ -373,6 +373,10 @@ const BalanceTooltip = styled(TooltipV2)`
margin-right: 1rem;
`;
+const MessageTooltip = styled(TooltipV2)`
+ max-width: 290px;
+`;
+
const Image = styled.img`
width: 16px;
padding: 0 8px;
From 30dc2ee4ffa42e56f593f177ed2f1b3fbc910415 Mon Sep 17 00:00:00 2001
From: MattClabs <139958714+MattClabs@users.noreply.github.com>
Date: Thu, 24 Oct 2024 18:07:33 +0200
Subject: [PATCH 06/10] Oops update.json
---
assets/_locales/en/messages.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/assets/_locales/en/messages.json b/assets/_locales/en/messages.json
index 6e667d67..608509bc 100644
--- a/assets/_locales/en/messages.json
+++ b/assets/_locales/en/messages.json
@@ -2013,7 +2013,7 @@
"description": "ao degraded title text"
},
"ao_degraded_description": {
- "message": "Ops, ArConnect is unable to fetch your token balance. Please try again later.",
+ "message": "Oops, ArConnect is unable to fetch your token balance. Please try again later.",
"description": "ao degraded description text"
},
"network_issue": {
From a0a231334490fd945fa535e5c9c120aaebc13178 Mon Sep 17 00:00:00 2001
From: Pawan Paudel
Date: Tue, 29 Oct 2024 14:10:45 +0545
Subject: [PATCH 07/10] refactor: add timeout retry to ar balance fetch
---
src/components/popup/Token.tsx | 25 ++++--------------
src/components/popup/home/Balance.tsx | 38 ++++++++++++++++-----------
src/utils/retry.ts | 38 +++++++++++++++++++++++++++
src/wallets/hooks.ts | 37 +++++++++++++++++---------
4 files changed, 91 insertions(+), 47 deletions(-)
diff --git a/src/components/popup/Token.tsx b/src/components/popup/Token.tsx
index af3ca72b..fd0d6a73 100644
--- a/src/components/popup/Token.tsx
+++ b/src/components/popup/Token.tsx
@@ -1,8 +1,4 @@
-import {
- formatFiatBalance,
- formatTokenBalance,
- balanceToFractioned
-} from "~tokens/currency";
+import { formatFiatBalance, balanceToFractioned } from "~tokens/currency";
import {
type MouseEventHandler,
useEffect,
@@ -23,8 +19,6 @@ import * as viewblock from "~lib/viewblock";
import Squircle from "~components/Squircle";
import useSetting from "~settings/hook";
import styled from "styled-components";
-import Arweave from "arweave";
-import { useGateway } from "~gateways/wayfinder";
import aoLogo from "url:/assets/ecosystem/ao-logo.svg";
import { getUserAvatar } from "~lib/avatar";
import { formatBalance } from "~utils/format";
@@ -34,6 +28,7 @@ import BigNumber from "bignumber.js";
import JSConfetti from "js-confetti";
import browser from "webextension-polyfill";
import { AO_NATIVE_TOKEN } from "~utils/ao_import";
+import { useBalance } from "~wallets/hooks";
export default function Token({ onClick, ...props }: Props) {
const ref = useRef(null);
@@ -490,33 +485,23 @@ export function ArToken({ onClick }: ArTokenProps) {
});
// load ar balance
- const [balance, setBalance] = useState(BigNumber("0"));
const [fiatBalance, setFiatBalance] = useState(BigNumber("0"));
const [displayBalance, setDisplayBalance] = useState("0");
const [totalBalance, setTotalBalance] = useState("");
const [showTooltip, setShowTooltip] = useState(false);
- // memoized requirements to ensure stability
- const requirements = useMemo(() => ({ ensureStake: true }), []);
- const gateway = useGateway(requirements);
+ const balance = useBalance();
useEffect(() => {
(async () => {
if (!activeAddress) return;
- const arweave = new Arweave(gateway);
-
- // fetch balance
- const winstonBalance = await arweave.wallets.getBalance(activeAddress);
- const arBalance = BigNumber(arweave.ar.winstonToAr(winstonBalance));
- setBalance(arBalance);
-
- const formattedBalance = formatBalance(arBalance);
+ const formattedBalance = formatBalance(balance);
setTotalBalance(formattedBalance.tooltipBalance);
setShowTooltip(formattedBalance.showTooltip);
setDisplayBalance(formattedBalance.displayBalance);
})();
- }, [activeAddress, gateway]);
+ }, [activeAddress, balance]);
useEffect(() => {
setFiatBalance(balance.multipliedBy(price));
diff --git a/src/components/popup/home/Balance.tsx b/src/components/popup/home/Balance.tsx
index e8194427..714d7f44 100644
--- a/src/components/popup/home/Balance.tsx
+++ b/src/components/popup/home/Balance.tsx
@@ -6,7 +6,6 @@ import { Loading, TooltipV2 } from "@arconnect/components";
import { useEffect, useMemo, useState, type HTMLProps } from "react";
import { useStorage } from "@plasmohq/storage/hook";
import { ExtensionStorage } from "~utils/storage";
-import { useHistory } from "~utils/hash_router";
import { useBalance } from "~wallets/hooks";
import { getArPrice } from "~lib/coingecko";
import { getAppURL } from "~utils/format";
@@ -25,8 +24,8 @@ import styled from "styled-components";
import Arweave from "arweave";
import { removeDecryptionKey } from "~wallets/auth";
import { findGateway } from "~gateways/wayfinder";
-import type { Gateway } from "~gateways/gateway";
import BigNumber from "bignumber.js";
+import { retryWithDelay, retryWithDelayAndTimeout } from "~utils/retry";
export default function Balance() {
const [loading, setLoading] = useState(false);
@@ -103,8 +102,7 @@ export default function Balance() {
(async () => {
if (!activeAddress) return;
setLoading(true);
- const gateway = await findGateway({ graphql: true });
- const history = await balanceHistory(activeAddress, gateway);
+ const history = await balanceHistory(activeAddress);
setHistoricalBalance(history);
setLoading(false);
@@ -192,8 +190,9 @@ export default function Balance() {
);
}
-async function balanceHistory(address: string, gateway: Gateway) {
- const arweave = new Arweave(gateway);
+async function balanceHistory(address: string) {
+ const gateway = await findGateway({ graphql: true });
+ let arweave = new Arweave(gateway);
let minHeight = 0;
try {
const { height } = await arweave.network.getInfo();
@@ -203,8 +202,9 @@ async function balanceHistory(address: string, gateway: Gateway) {
// find txs coming in and going out
const inTxs = (
- await gql(
- `
+ await retryWithDelay(() =>
+ gql(
+ `
query($recipient: String!, $minHeight: Int!) {
transactions(recipients: [$recipient], first: 100, bundledIn: null, block: {min: $minHeight}) {
edges {
@@ -226,13 +226,15 @@ async function balanceHistory(address: string, gateway: Gateway) {
}
}
`,
- { recipient: address, minHeight }
+ { recipient: address, minHeight }
+ )
)
).data.transactions.edges;
const outTxs = (
- await gql(
- `
+ await retryWithDelay(() =>
+ gql(
+ `
query($owner: String!, $minHeight: Int!) {
transactions(owners: [$owner], first: 100, bundledIn: null, block: {min: $minHeight}) {
edges {
@@ -254,7 +256,8 @@ async function balanceHistory(address: string, gateway: Gateway) {
}
}
`,
- { owner: address, minHeight }
+ { owner: address, minHeight }
+ )
)
).data.transactions.edges;
@@ -266,9 +269,14 @@ async function balanceHistory(address: string, gateway: Gateway) {
.sort((a, b) => b.block.timestamp - a.block.timestamp); // Sort by newest to oldest
// Get the current balance
- let balance = BigNumber(
- arweave.ar.winstonToAr(await arweave.wallets.getBalance(address))
- );
+ const winstonBalance = await retryWithDelayAndTimeout(async () => {
+ const gateway = await findGateway({ ensureStake: true });
+ arweave = new Arweave(gateway);
+ const balance = await arweave.wallets.getBalance(address);
+ if (isNaN(+balance)) throw new Error("Balance is invalid");
+ return balance;
+ });
+ let balance = BigNumber(arweave.ar.winstonToAr(winstonBalance));
// Initialize the result array with the current balance
const res = [balance.toNumber()];
diff --git a/src/utils/retry.ts b/src/utils/retry.ts
index 4c7e48b0..09f190f4 100644
--- a/src/utils/retry.ts
+++ b/src/utils/retry.ts
@@ -30,3 +30,41 @@ export async function retryWithDelay(
return attempt();
}
+
+/**
+ * Retries a given asynchronous function up to a maximum number of attempts with a timeout for each attempt.
+ * @param fn - The asynchronous function to retry, which should return a Promise.
+ * @param maxAttempts - The maximum number of attempts to make.
+ * @param delay - The delay between attempts in milliseconds.
+ * @param timeout - The maximum time to wait for each attempt in milliseconds.
+ * @return A Promise that resolves with the result of the function or rejects after all attempts fail.
+ */
+export async function retryWithDelayAndTimeout(
+ fn: () => Promise,
+ maxAttempts: number = 3,
+ delay: number = 1000,
+ timeout: number = 10000
+): Promise {
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
+ try {
+ // Create a race between the function and the timeout
+ const result = await Promise.race([
+ fn(),
+ new Promise((_, reject) =>
+ setTimeout(() => reject(new Error("Request timed out")), timeout)
+ )
+ ]);
+ return result;
+ } catch (error) {
+ if (attempt < maxAttempts) {
+ // console.log(`Attempt ${attempt} failed: ${error.message}. Retrying in ${delay}ms...`);
+ await new Promise((resolve) => setTimeout(resolve, delay));
+ } else {
+ throw error;
+ }
+ }
+ }
+
+ // Final fallback error
+ throw new Error("Max attempts reached without success.");
+}
diff --git a/src/wallets/hooks.ts b/src/wallets/hooks.ts
index 6bafbcd5..08874d6b 100644
--- a/src/wallets/hooks.ts
+++ b/src/wallets/hooks.ts
@@ -1,7 +1,7 @@
import type { WalletInterface } from "~components/welcome/load/Migrate";
import type { JWKInterface } from "arweave/web/lib/wallet";
import { type AnsUser, getAnsProfile } from "~lib/ans";
-import { useEffect, useMemo, useRef, useState } from "react";
+import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useStorage } from "@plasmohq/storage/hook";
import { defaultGateway } from "~gateways/gateway";
import { ExtensionStorage } from "~utils/storage";
@@ -10,6 +10,7 @@ import type { HardwareApi } from "./hardware";
import type { StoredWallet } from "~wallets";
import Arweave from "arweave";
import BigNumber from "bignumber.js";
+import { retryWithDelayAndTimeout } from "~utils/retry";
/**
* Wallets with details hook
@@ -113,19 +114,31 @@ export function useBalance() {
// balance in AR
const [balance, setBalance] = useState(BigNumber("0"));
- useEffect(() => {
- (async () => {
- if (!activeAddress) return;
-
- const gateway = await findGateway({});
- const arweave = new Arweave(gateway);
+ const fetchBalance = useCallback(async () => {
+ if (!activeAddress) {
+ setBalance(BigNumber("0"));
+ return;
+ }
+
+ const gateway = await findGateway({ ensureStake: true });
+ const arweave = new Arweave(gateway);
+
+ // fetch balance
+ const winstonBalance = await arweave.wallets.getBalance(activeAddress);
+ if (isNaN(+winstonBalance)) {
+ throw new Error("Invalid balance returned");
+ }
+ const arBalance = BigNumber(arweave.ar.winstonToAr(winstonBalance));
+ setBalance(arBalance);
+ }, [activeAddress]);
- // fetch balance
- const winstonBalance = await arweave.wallets.getBalance(activeAddress);
+ useEffect(() => {
+ if (!activeAddress) return;
- setBalance(BigNumber(arweave.ar.winstonToAr(winstonBalance)));
- })();
- }, [activeAddress]);
+ retryWithDelayAndTimeout(fetchBalance).catch((error) => {
+ console.log(`Error fetching balance: ${error}`);
+ });
+ }, [activeAddress, fetchBalance]);
return balance;
}
From 5a7e8de0e27947293dcc93fab65a026f1bda0760 Mon Sep 17 00:00:00 2001
From: Pawan Paudel
Date: Tue, 29 Oct 2024 18:31:01 +0545
Subject: [PATCH 08/10] refactor: Show Print Arweave tx description & network
fee in tx history
---
src/components/popup/home/Transactions.tsx | 15 +++++++--------
src/lib/transactions.ts | 15 ++++++++++++++-
src/notifications/api.ts | 3 +++
src/notifications/utils.ts | 1 +
src/routes/popup/transaction/[id].tsx | 6 ++++++
5 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/src/components/popup/home/Transactions.tsx b/src/components/popup/home/Transactions.tsx
index 6d55b533..8e24e4d7 100644
--- a/src/components/popup/home/Transactions.tsx
+++ b/src/components/popup/home/Transactions.tsx
@@ -166,14 +166,13 @@ export default function Transactions() {
: "Pending"}
- {transaction.transactionType !== "printArchive" && (
-
- {getFormattedAmount(transaction)}
-
- {getFormattedFiatAmount(transaction, arPrice, currency)}
-
-
- )}
+
+
+ {getFormattedAmount(transaction)}
+
+ {getFormattedFiatAmount(transaction, arPrice, currency)}
+
+
))
diff --git a/src/lib/transactions.ts b/src/lib/transactions.ts
index 698a9ad6..7e747f05 100644
--- a/src/lib/transactions.ts
+++ b/src/lib/transactions.ts
@@ -143,6 +143,8 @@ export const getFormattedAmount = (transaction: ExtendedTransaction) => {
}).toFixed()} ${transaction.aoInfo.tickerName}`;
}
return "";
+ case "printArchive":
+ return `${parseFloat(transaction.node.fee.ar).toFixed(3)} AR`;
default:
return "";
}
@@ -154,11 +156,22 @@ export const getFormattedFiatAmount = (
currency: string
) => {
try {
- if (transaction.node.quantity) {
+ if (
+ transaction.node.quantity &&
+ transaction.transactionType !== "printArchive"
+ ) {
const fiatBalance = BigNumber(transaction.node.quantity.ar).multipliedBy(
arPrice
);
return formatFiatBalance(fiatBalance, currency);
+ } else if (
+ transaction.node.fee &&
+ transaction.transactionType === "printArchive"
+ ) {
+ const fiatBalance = BigNumber(transaction.node.fee.ar).multipliedBy(
+ arPrice
+ );
+ return formatFiatBalance(fiatBalance, currency);
}
} catch {}
return "";
diff --git a/src/notifications/api.ts b/src/notifications/api.ts
index 5600b72c..81021229 100644
--- a/src/notifications/api.ts
+++ b/src/notifications/api.ts
@@ -26,6 +26,9 @@ export type RawTransaction = {
quantity: {
ar: string;
};
+ fee: {
+ ar: string;
+ };
block: {
timestamp: number;
height: number;
diff --git a/src/notifications/utils.ts b/src/notifications/utils.ts
index 0a09f4b4..f306a99d 100644
--- a/src/notifications/utils.ts
+++ b/src/notifications/utils.ts
@@ -258,6 +258,7 @@ query ($address: String!) {
recipient
owner { address }
quantity { ar }
+ fee { ar }
block { timestamp, height }
tags {
name
diff --git a/src/routes/popup/transaction/[id].tsx b/src/routes/popup/transaction/[id].tsx
index 9a1e8c25..f70c9c64 100644
--- a/src/routes/popup/transaction/[id].tsx
+++ b/src/routes/popup/transaction/[id].tsx
@@ -475,6 +475,12 @@ export default function Transaction({ id: rawId, gw, message }: Props) {
+
+
+ {browser.i18n.getMessage("transaction_fee")}
+
+ {transaction.fee.ar} AR
+
{!message && (
From 9d4b87d3980bb839c8d49f4aa24c8e49c5f66435 Mon Sep 17 00:00:00 2001
From: Pawan Paudel
Date: Tue, 29 Oct 2024 21:29:26 +0545
Subject: [PATCH 09/10] refactor: make sure we get random gateway
---
src/components/popup/home/Balance.tsx | 2 +-
src/utils/retry.ts | 2 +-
src/wallets/hooks.ts | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/components/popup/home/Balance.tsx b/src/components/popup/home/Balance.tsx
index 714d7f44..b27543f9 100644
--- a/src/components/popup/home/Balance.tsx
+++ b/src/components/popup/home/Balance.tsx
@@ -270,7 +270,7 @@ async function balanceHistory(address: string) {
// Get the current balance
const winstonBalance = await retryWithDelayAndTimeout(async () => {
- const gateway = await findGateway({ ensureStake: true });
+ const gateway = await findGateway({});
arweave = new Arweave(gateway);
const balance = await arweave.wallets.getBalance(address);
if (isNaN(+balance)) throw new Error("Balance is invalid");
diff --git a/src/utils/retry.ts b/src/utils/retry.ts
index 09f190f4..8d7e4a92 100644
--- a/src/utils/retry.ts
+++ b/src/utils/retry.ts
@@ -45,7 +45,7 @@ export async function retryWithDelayAndTimeout(
delay: number = 1000,
timeout: number = 10000
): Promise {
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
+ for (let attempt = 0; attempt <= maxAttempts; attempt++) {
try {
// Create a race between the function and the timeout
const result = await Promise.race([
diff --git a/src/wallets/hooks.ts b/src/wallets/hooks.ts
index 08874d6b..67ee3ade 100644
--- a/src/wallets/hooks.ts
+++ b/src/wallets/hooks.ts
@@ -120,7 +120,7 @@ export function useBalance() {
return;
}
- const gateway = await findGateway({ ensureStake: true });
+ const gateway = await findGateway({});
const arweave = new Arweave(gateway);
// fetch balance
From fb8dc898cd0c67de8731f3ab003c67a0602651ae Mon Sep 17 00:00:00 2001
From: nicholas ma
Date: Wed, 30 Oct 2024 12:49:47 -0700
Subject: [PATCH 10/10] refactor: moved withRetry to retry.ts
---
src/tokens/aoTokens/sync.ts | 39 +------------------------------------
src/utils/retry.ts | 38 ++++++++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+), 38 deletions(-)
diff --git a/src/tokens/aoTokens/sync.ts b/src/tokens/aoTokens/sync.ts
index 2607fe4e..11d0a5dc 100644
--- a/src/tokens/aoTokens/sync.ts
+++ b/src/tokens/aoTokens/sync.ts
@@ -17,6 +17,7 @@ import {
Id,
Owner
} from "./ao";
+import { withRetry } from "~utils/retry";
/** Tokens storage name */
const AO_TOKENS = "ao_tokens";
@@ -36,44 +37,6 @@ const gateway = {
protocol: "https"
};
-/**
- * Generic retry function for any async operation.
- * @param fn - The async function to be retried.
- * @param maxRetries - Maximum retry attempts.
- * @param retryDelay - Delay between retries in milliseconds.
- * @returns A promise of the type that the async function returns.
- */
-async function withRetry(
- fn: () => Promise,
- maxRetries: number = 3,
- retryDelay: number = 100
-): Promise {
- let lastError: any;
-
- const delay = (ms: number) =>
- new Promise((resolve) => setTimeout(resolve, ms));
-
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
- try {
- return await fn();
- } catch (error) {
- lastError = error;
- if (attempt < maxRetries) {
- const waitTime = Math.pow(2, attempt - 1) * retryDelay;
- console.log(`Attempt ${attempt} failed, retrying in ${waitTime}ms...`);
- await delay(waitTime);
- } else {
- console.error(
- `All ${maxRetries} attempts failed. Last error:`,
- lastError
- );
- }
- }
- }
-
- throw lastError;
-}
-
async function getTokenInfo(id: string): Promise {
const body = {
Id,
diff --git a/src/utils/retry.ts b/src/utils/retry.ts
index 8d7e4a92..e487e40b 100644
--- a/src/utils/retry.ts
+++ b/src/utils/retry.ts
@@ -68,3 +68,41 @@ export async function retryWithDelayAndTimeout(
// Final fallback error
throw new Error("Max attempts reached without success.");
}
+
+/**
+ * Generic retry function for any async operation.
+ * @param fn - The async function to be retried.
+ * @param maxRetries - Maximum retry attempts.
+ * @param retryDelay - Delay between retries in milliseconds.
+ * @returns A promise of the type that the async function returns.
+ */
+export async function withRetry(
+ fn: () => Promise,
+ maxRetries: number = 3,
+ retryDelay: number = 100
+): Promise {
+ let lastError: any;
+
+ const delay = (ms: number) =>
+ new Promise((resolve) => setTimeout(resolve, ms));
+
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
+ try {
+ return await fn();
+ } catch (error) {
+ lastError = error;
+ if (attempt < maxRetries) {
+ const waitTime = Math.pow(2, attempt - 1) * retryDelay;
+ console.log(`Attempt ${attempt} failed, retrying in ${waitTime}ms...`);
+ await delay(waitTime);
+ } else {
+ console.error(
+ `All ${maxRetries} attempts failed. Last error:`,
+ lastError
+ );
+ }
+ }
+ }
+
+ throw lastError;
+}