Skip to content

Commit

Permalink
chore: add address request
Browse files Browse the repository at this point in the history
* update types for new version of ordinal service

* update test
  • Loading branch information
slavastartsev committed Nov 9, 2024
1 parent 25a0457 commit f42b5ff
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 24 deletions.
59 changes: 47 additions & 12 deletions sdk/src/ordinal-api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export module SatPoint {
/**
* @ignore
*/
// https://github.com/ordinals/ord/blob/0.18.5/src/api.rs#L117-L121
// https://github.com/ordinals/ord/blob/0.21.2/src/api.rs#L147-L150
export interface InscriptionsJson<InscriptionId> {
/**
* An array of inscription ids.
Expand All @@ -106,7 +106,7 @@ export interface InscriptionsJson<InscriptionId> {
/**
* @ignore
*/
// https://github.com/ordinals/ord/blob/0.18.5/src/api.rs#L124-L134
// https://github.com/ordinals/ord/blob/0.21.2/src/api.rs#L154-L164
export interface OutputJson {
/**
* The address associated with the UTXO.
Expand Down Expand Up @@ -137,7 +137,7 @@ export interface OutputJson {
/**
* The SAT ranges.
*/
sat_ranges: string | null;
sat_ranges: [number, number][] | null;

/**
* The scriptPubKey associated with the UTXO.
Expand All @@ -163,7 +163,30 @@ export interface OutputJson {
/**
* @ignore
*/
// https://github.com/ordinals/ord/blob/0.18.5/src/api.rs#L165-L180
//https://github.com/ordinals/ord/blob/0.21.2/src/api.rs#L226-231
export interface AddressInfo {
/**
* An array of output ids.
*/
outputs: string[];
/**
* An array of inscription ids.
*/
inscriptions: string[];
/**
* Balance in satoshi.
*/
sat_balance: number;
/**
* A list of runes.
*/
runes_balances: [string, `${number}`, string][];
}

/**
* @ignore
*/
// https://github.com/ordinals/ord/blob/0.21.2/src/api.rs#L195-L211
export interface SatJson<InscriptionId> {
/**
* The number of the ordinal.
Expand Down Expand Up @@ -241,7 +264,7 @@ export interface SatJson<InscriptionId> {
/**
* @ignore
*/
// https://github.com/ordinals/ord/blob/0.18.5/src/api.rs#L80-L99
// https://github.com/ordinals/ord/blob/0.21.2/src/api.rs#L93-L113
export interface InscriptionJson<InscriptionId, SatPoint> {
/**
* The address associated with the inscription.
Expand All @@ -250,6 +273,8 @@ export interface InscriptionJson<InscriptionId, SatPoint> {

charms: string[];

child_count: number;

/**
* An array of child IDs.
*/
Expand Down Expand Up @@ -292,11 +317,6 @@ export interface InscriptionJson<InscriptionId, SatPoint> {
*/
number: number;

/**
* The parent inscription IDs.
*/
parent: InscriptionId | null;

/**
* The parent inscription IDs.
*/
Expand All @@ -315,7 +335,7 @@ export interface InscriptionJson<InscriptionId, SatPoint> {
/**
* The SAT associated with the inscription.
*/
sat: string | null;
sat: number | null;

/**
* The SAT point of the inscription, this is the current UTXO.
Expand Down Expand Up @@ -352,6 +372,22 @@ export class OrdinalsClient {
}
}

/**
* Retrieves address information.
* @param {string} address - The address to request information about.
* @returns {Promise<AddressInfo>} A Promise that resolves to the address information.
*
* @example
* ```typescript
* const client = new OrdinalsClient("regtest");
* const addressInfo = await client.getAssetsByAddress("enter_your_address_here");
* console.log("AddressInfo:", addressInfo);
* ```
*/
getAssetsByAddress(address: string): Promise<AddressInfo> {
return this.getJson<AddressInfo>(`${this.basePath}/address/${address}`);
}

/**
* Retrieves an inscription based on its ID.
* @param {string} id - The ID of the inscription to retrieve.
Expand All @@ -375,7 +411,6 @@ export class OrdinalsClient {
children: inscriptionJson.children.map(InscriptionId.fromString),
id: InscriptionId.fromString(inscriptionJson.id),
next: inscriptionJson.next != null ? InscriptionId.fromString(inscriptionJson.next) : null,
parent: inscriptionJson.parent != null ? InscriptionId.fromString(inscriptionJson.parent) : null,
previous: inscriptionJson.previous != null ? InscriptionId.fromString(inscriptionJson.previous) : null,
satpoint: SatPoint.fromString(inscriptionJson.satpoint),
};
Expand Down
23 changes: 14 additions & 9 deletions sdk/src/wallet/utxo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { Transaction, Script, selectUTXO, TEST_NETWORK, NETWORK, p2wpkh, p2sh, p
import { hex, base64 } from '@scure/base';
import { AddressType, getAddressInfo, Network } from 'bitcoin-address-validation';
import { EsploraClient, UTXO } from '../esplora';
import { OrdinalsClient } from '../ordinal-api';
import { SelectionStrategy } from '@scure/btc-signer/utxo';
import { AddressInfo, InscriptionId, OrdinalsClient } from '../ordinal-api';
import { SelectionStrategy } from '@scure/btc-signer/lib/utxo';

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

Expand Down Expand Up @@ -88,29 +88,33 @@ export async function createBitcoinPsbt(
const ordinalsClient = new OrdinalsClient(addressInfo.network);

let confirmedUtxos: UTXO[] = [];
let ordinalsAddressInfo: AddressInfo = {} as AddressInfo;

if (feeRate) {
confirmedUtxos = await esploraClient.getAddressUtxos(fromAddress);
[confirmedUtxos, ordinalsAddressInfo] = await Promise.all([
esploraClient.getAddressUtxos(fromAddress),
ordinalsClient.getAssetsByAddress(fromAddress),
]);
} else {
[confirmedUtxos, feeRate] = await Promise.all([
[confirmedUtxos, feeRate, ordinalsAddressInfo] = await Promise.all([
esploraClient.getAddressUtxos(fromAddress),
esploraClient.getFeeEstimate(confirmationTarget),
ordinalsClient.getAssetsByAddress(fromAddress),
]);
}

if (confirmedUtxos.length === 0) {
throw new Error('No confirmed UTXOs');
}

const inscriptionsSet = new Set(ordinalsAddressInfo.inscriptions);

// To construct the spending transaction and estimate the fee, we need the transactions for the UTXOs
const possibleInputs: Input[] = [];

await Promise.all(
confirmedUtxos.map(async (utxo) => {
const [hex, outputJson] = await Promise.all([
esploraClient.getTransactionHex(utxo.txid),
ordinalsClient.getInscriptionsFromOutPoint(utxo),
]);
const hex = await esploraClient.getTransactionHex(utxo.txid);
const transaction = Transaction.fromRaw(Buffer.from(hex, 'hex'), { allowUnknownOutputs: true });
const input = getInputFromUtxoAndTx(
addressInfo.network as BitcoinNetworkName,
Expand All @@ -120,7 +124,8 @@ export async function createBitcoinPsbt(
publicKey
);
// to support taproot addresses we want to exclude outputs which contain inscriptions
if (outputJson.inscriptions.length === 0) possibleInputs.push(input);
if (!inscriptionsSet.has(InscriptionId.toString({ txid: utxo.txid, index: utxo.vout })))
possibleInputs.push(input);
})
);

Expand Down
6 changes: 3 additions & 3 deletions sdk/test/ordinal-api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ describe('Ordinal API Tests', () => {
const expectedInscriptionJson: InscriptionJson<InscriptionId, SatPoint> = {
address: 'bc1pxaneaf3w4d27hl2y93fuft2xk6m4u3wc4rafevc6slgd7f5tq2dqyfgy06',
charms: [],
child_count: 0,
children: [],
content_length: 94,
content_type: 'text/plain;charset=utf-8',
Expand All @@ -22,11 +23,10 @@ describe('Ordinal API Tests', () => {
id: InscriptionId.fromString('b61b0172d95e266c18aea0c624db987e971a5d6d4ebc2aaed85da4642d635735i0'),
number: 348020,
next: InscriptionId.fromString('693bd98380ad6e58f83de6068c236c6eb9d629c825cc3342c2d93f24c6762c6di0'),
parent: null,
parents: [],
previous: InscriptionId.fromString('4f0ff6259efa9d56b16664e6c5c9755c148818dc6bbca98f7f9166b277e4b7c0i0'),
rune: null,
sat: null,
sat: 923155354107609,
satpoint: SatPoint.fromString('b61b0172d95e266c18aea0c624db987e971a5d6d4ebc2aaed85da4642d635735:0:0'),
timestamp: 1678248991,
value: 10000,
Expand Down Expand Up @@ -74,7 +74,7 @@ describe('Ordinal API Tests', () => {
script_pubkey: '5120e18a5367c5d11ee31d10bf4c53e743a7479c70e3336e70dbdea1fd927305c022',
address: 'bc1pux99xe796y0wx8gshax98e6r5arecu8rxdh8pk77587eyuc9cq3q2e3nng',
transaction: 'dfe942a58b7e29a3952d8d1ed6608086c66475d20bc7bdbc3d784d616f9a6a7a',
sat_ranges: null,
sat_ranges: [[670597263608598, 670597263619335]],
inscriptions: ['dfe942a58b7e29a3952d8d1ed6608086c66475d20bc7bdbc3d784d616f9a6a7ai0'],
runes: {},
indexed: true,
Expand Down

0 comments on commit f42b5ff

Please sign in to comment.