Skip to content

Commit

Permalink
chore: check confirmed utxo contains ordinals
Browse files Browse the repository at this point in the history
  • Loading branch information
slavastartsev committed Dec 19, 2024
1 parent 08aff7d commit d92d198
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 17 deletions.
36 changes: 21 additions & 15 deletions sdk/src/wallet/utxo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { hex, base64 } from '@scure/base';
import { AddressType, getAddressInfo, Network } from 'bitcoin-address-validation';
import { EsploraClient, UTXO } from '../esplora';
import { OrdinalsClient, OutPoint, OutputJson } from '../ordinal-api';
import { getTxInscriptions } from '../inscription';

export type BitcoinNetworkName = Exclude<Network, 'regtest'>;

Expand Down Expand Up @@ -32,42 +31,49 @@ const createUtxoNodes = (utxos: UTXO[], cardinalOutputsSet: Set<string>) =>
utxos.reduce(
(acc, utxo) => {
if (!cardinalOutputsSet.has(OutPoint.toString(utxo)))
acc.push(new TreeNode<OutputNodeData>({ ...utxo, cardinal: true }));
// mark node as containing ordinals
acc.push(new TreeNode<OutputNodeData>({ ...utxo, cardinal: false }));
else acc.push(null);

return acc;
},
[] as (TreeNode<OutputNodeData> | null)[]
);

const processNodes = async (rootNodes: (TreeNode<OutputNodeData> | null)[], esploraClient: EsploraClient) => {
const processNodes = async (
rootNodes: (TreeNode<OutputNodeData> | null)[],
cardinalOutputsSet: Set<string>,
esploraClient: EsploraClient,
ordinalsClient: OrdinalsClient
) => {
const queue = Array.from(rootNodes);

while (queue.length > 0) {
const childNode = queue.shift();

if (childNode === null) continue;

const txInscriptions = await getTxInscriptions(esploraClient, childNode.val.txid);
const transaction = await esploraClient.getTransaction(childNode.val.txid);

if (txInscriptions.length === 0) {
const transaction = await esploraClient.getTransaction(childNode.val.txid);
if (transaction.status.confirmed) {
// if confirmed check if it contains ordinals
childNode.val.cardinal = cardinalOutputsSet.has(OutPoint.toString(childNode.val));
} else {
const response = await ordinalsClient.getInscriptionsFromOutPoint(childNode.val);

// if not confirmed check inputs for current utxo
if (!transaction.status.confirmed) {
if (response.inscriptions.length === 0) {
// if not confirmed check inputs for current utxo
childNode.children = transaction.vin.map((vin) => {
return new TreeNode<OutputNodeData>({
vout: vin.vout,
txid: vin.txid,
cardinal: true,
// mark node as containing ordinals
cardinal: false,
});
});

queue.push(...childNode.children);
}
} else {
// mark node as containing ordinals
childNode.val.cardinal = false;
}
}
};
Expand Down Expand Up @@ -173,7 +179,7 @@ export async function createBitcoinPsbt(

const rootUtxoNodes = createUtxoNodes(utxos, cardinalOutputsSet);

await processNodes(rootUtxoNodes, esploraClient);
await processNodes(rootUtxoNodes, cardinalOutputsSet, esploraClient, ordinalsClient);

// To construct the spending transaction and estimate the fee, we need the transactions for the UTXOs
const possibleInputs: Input[] = [];
Expand Down Expand Up @@ -389,7 +395,7 @@ export async function estimateTxFee(

const rootUtxoNodes = createUtxoNodes(utxos, cardinalOutputsSet);

await processNodes(rootUtxoNodes, esploraClient);
await processNodes(rootUtxoNodes, cardinalOutputsSet, esploraClient, ordinalsClient);

const possibleInputs: Input[] = [];

Expand Down Expand Up @@ -505,7 +511,7 @@ export async function getBalance(address?: string) {

const rootUtxoNodes = createUtxoNodes(utxos, cardinalOutputsSet);

await processNodes(rootUtxoNodes, esploraClient);
await processNodes(rootUtxoNodes, cardinalOutputsSet, esploraClient, ordinalsClient);

const total = utxos.reduce((acc, utxo, index) => {
// there will be a match if output is confirmed and has no ordinals
Expand Down
4 changes: 2 additions & 2 deletions sdk/test/utxo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ describe('UTXO Tests', () => {
})
)
)
).not.toEqual([]);
).toEqual([]);
});

it('throws an error if insufficient balance', { timeout: 50000 }, async () => {
Expand Down Expand Up @@ -471,7 +471,7 @@ describe('UTXO Tests', () => {

const balanceData = await getBalance(taprootAddress);

expect(balanceData.total).toEqual(BigInt(total));
expect(balanceData.total).toBeLessThan(BigInt(total));
expect(balanceData.confirmed).toBeLessThan(BigInt(confirmed));
});
});

0 comments on commit d92d198

Please sign in to comment.