Skip to content

Commit

Permalink
fix: check utxo fallback error, closes #5250
Browse files Browse the repository at this point in the history
  • Loading branch information
alter-eggo committed Apr 18, 2024
1 parent 1e02992 commit 321a00a
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 16 deletions.
4 changes: 2 additions & 2 deletions src/app/query/bitcoin/bitcoin-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ interface BestinslotInscription {
byte_size: number;
}

export interface BestinslotInscriptionByIdResponse {
interface BestinslotInscriptionByIdResponse {
data: BestinslotInscription;
block_height: number;
}

export interface BestinslotInscriptionsByTxIdResponse {
interface BestinslotInscriptionsByTxIdResponse {
data: { inscription_id: string }[];
blockHeight: number;
}
Expand Down
22 changes: 10 additions & 12 deletions src/app/query/bitcoin/transaction/use-check-utxos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { useBitcoinClient } from '@app/store/common/api-clients.hooks';
import { useCurrentNetworkState } from '@app/store/networks/networks.hooks';

import type {
BestinslotInscriptionByIdResponse,
BestinslotInscriptionsByTxIdResponse,
} from '../bitcoin-client';
import type { BitcoinClient } from '../bitcoin-client';
import { getNumberOfInscriptionOnUtxoUsingOrdinalsCom } from '../ordinals/inscriptions.query';

class PreventTransactionError extends Error {
Expand Down Expand Up @@ -45,27 +42,29 @@ export function filterOutIntentionalUtxoSpend({
interface CheckInscribedUtxosByBestinslotArgs {
inputs: btc.TransactionInput[];
txids: string[];
getInscriptionsByTransactionId(id: string): Promise<BestinslotInscriptionsByTxIdResponse>;
getInscriptionById(id: string): Promise<BestinslotInscriptionByIdResponse>;
client: BitcoinClient;
}

async function checkInscribedUtxosByBestinslot({
inputs,
txids,
getInscriptionsByTransactionId,
getInscriptionById,
client,
}: CheckInscribedUtxosByBestinslotArgs): Promise<boolean> {
/**
* @description Get the list of inscriptions moving on a transaction
* @see https://docs.bestinslot.xyz/reference/api-reference/ordinals-and-brc-20-and-bitmap-v3-api-mainnet+testnet/inscriptions
*/
const inscriptionIdsList = await Promise.all(txids.map(id => getInscriptionsByTransactionId(id)));
const inscriptionIdsList = await Promise.all(
txids.map(id => client.BestinslotApi.getInscriptionsByTransactionId(id))
);

const inscriptionIds = inscriptionIdsList.flatMap(inscription =>
inscription.data.map(data => data.inscription_id)
);

const inscriptionsList = await Promise.all(inscriptionIds.map(id => getInscriptionById(id)));
const inscriptionsList = await Promise.all(
inscriptionIds.map(id => client.BestinslotApi.getInscriptionById(id))
);

const hasInscribedUtxos = inscriptionsList.some(resp => {
return inputs.some(input => {
Expand Down Expand Up @@ -147,8 +146,7 @@ export function useCheckUnspendableUtxos(blockTxAction?: () => void) {
const hasInscribedUtxo = await checkInscribedUtxosByBestinslot({
inputs,
txids,
getInscriptionsByTransactionId: client.BestinslotApi.getInscriptionsByTransactionId,
getInscriptionById: client.BestinslotApi.getInscriptionById,
client,
});

if (hasInscribedUtxo) {
Expand Down
60 changes: 58 additions & 2 deletions tests/specs/send/send-btc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,65 @@ test.describe('send btc', () => {

await sendPage.clickInfoCardButton();

const isErrorPageVisible = await sendPage.broadcastErrorTitle.isVisible();
await test.expect(sendPage.broadcastErrorTitle).toBeVisible();
});

test('that fallbacks to other api provider if main fails', async ({ sendPage }) => {
let output = '';
let id = '';
let index = '';

await sendPage.page.route('**/ordinals-explorer.generative.xyz/**', async route => {
return route.fulfill({
status: 500,
contentType: 'text/html',
body: mockOrdinalsComApiHtmlResponse,
});
});

sendPage.page.on('request', async request => {
if (request.url().includes('ordinals-explorer.generative.xyz')) {
const url = request.url();
output = url.split('/').pop() || '';
id = output.split(':')[0];
index = output.split(':')[1];
}
});

await sendPage.page.route(
'**/leatherapi.bestinslot.xyz/v3/inscription/in_transaction**',
async route => {
return route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
data: [{ txid: id, output, index, satpoint: output }],
}),
});
}
);

await sendPage.page.route(
'**/leatherapi.bestinslot.xyz/v3/inscription/single_info_id**',
async route => {
return route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
data: { txid: id, output, index, satpoint: output },
}),
});
}
);
await sendPage.amountInput.fill('0.00006');
await sendPage.recipientInput.fill(TEST_TESTNET_ACCOUNT_2_BTC_ADDRESS);

await sendPage.previewSendTxButton.click();
await sendPage.feesListItem.filter({ hasText: BtcFeeType.High }).click();

await sendPage.clickInfoCardButton();

test.expect(isErrorPageVisible).toBeTruthy();
await test.expect(sendPage.broadcastErrorTitle).toBeVisible();
});
});
});

0 comments on commit 321a00a

Please sign in to comment.