diff --git a/src/utils/utxo/index.ts b/src/utils/utxo/index.ts index 7b6cf84a..18fae80b 100644 --- a/src/utils/utxo/index.ts +++ b/src/utils/utxo/index.ts @@ -2,7 +2,8 @@ import { postVerifyUtxoOrdinals, UtxoInfo } from "@/app/api/postFilterOrdinals"; import { InscriptionIdentifier, UTXO } from "../wallet/wallet_provider"; -const LOW_VALUE_UTXO_THRESHOLD = 10000; +export const LOW_VALUE_UTXO_THRESHOLD = 10000; +export const WALLET_FETCH_INSRIPTIONS_TIMEOUT = 3000; // 3 seconds /** * Filters out UTXOs that contain ordinals. @@ -34,7 +35,20 @@ export const filterOrdinals = async ( // try to get the ordinals from the wallet first, if the wallet supports it // otherwise fallback to the Babylon API try { - const inscriptions = await getInscriptionsFromWalletCb(); + const inscriptions = await Promise.race([ + getInscriptionsFromWalletCb(), + new Promise((_, reject) => + setTimeout( + () => + reject( + new Error( + "Request timed out when fetching inscriptions from wallet", + ), + ), + WALLET_FETCH_INSRIPTIONS_TIMEOUT, + ), + ), + ]); // filter out the utxos that contains ordinals return utxos.filter( (utxo) => diff --git a/tests/utils/utox/utxo.test.ts b/tests/utils/utox/utxo.test.ts index 04c0f950..174c4398 100644 --- a/tests/utils/utox/utxo.test.ts +++ b/tests/utils/utox/utxo.test.ts @@ -1,5 +1,5 @@ import { postVerifyUtxoOrdinals } from "@/app/api/postFilterOrdinals"; -import { filterOrdinals } from "@/utils/utxo"; +import { filterOrdinals, WALLET_FETCH_INSRIPTIONS_TIMEOUT } from "@/utils/utxo"; import { InscriptionIdentifier, UTXO } from "@/utils/wallet/wallet_provider"; // Mock the dependencies @@ -109,4 +109,29 @@ describe("filterOrdinals", () => { expect(result).toEqual(mockUtxos); }); + + it("should filter UTXOs using the API fallback when wallet callback times out", async () => { + const mockApiResponse = [ + { txid: "txid1", vout: 0, inscription: true }, + { txid: "txid2", vout: 1, inscription: false }, + { txid: "txid3", vout: 2, inscription: false }, + ]; + const getInscriptionsFromWalletCb = jest.fn().mockImplementation(() => { + return new Promise((resolve) => + setTimeout(resolve, WALLET_FETCH_INSRIPTIONS_TIMEOUT + 1000), + ); + }); + + (postVerifyUtxoOrdinals as jest.Mock).mockResolvedValue(mockApiResponse); + + const result = await filterOrdinals( + mockUtxos, + address, + getInscriptionsFromWalletCb, + ); + + expect(getInscriptionsFromWalletCb).toHaveBeenCalledTimes(1); + expect(postVerifyUtxoOrdinals).toHaveBeenCalledWith(mockUtxos, address); + expect(result).toEqual([mockUtxos[1], mockUtxos[2]]); + }); });