From 2d8f33646fdf7d1502dbeb35f6a23b8d9a4ef13e Mon Sep 17 00:00:00 2001 From: Gregory Hill Date: Wed, 28 Aug 2024 16:49:01 +0100 Subject: [PATCH] refactor: remove unnecessary client interfaces Signed-off-by: Gregory Hill --- sdk/src/esplora.ts | 232 ++++++++++++------------------ sdk/src/ordinal-api/index.ts | 149 ++++++++----------- sdk/src/relay.ts | 6 +- sdk/src/scripts/relay-genesis.ts | 6 +- sdk/src/scripts/relay-retarget.ts | 6 +- sdk/src/wallet/inscriptions.ts | 4 +- sdk/src/wallet/utxo.ts | 4 +- sdk/test/esplora.test.ts | 20 +-- sdk/test/inscription.test.ts | 6 +- sdk/test/ordinal-api.test.ts | 14 +- sdk/test/relay.test.ts | 6 +- 11 files changed, 183 insertions(+), 270 deletions(-) diff --git a/sdk/src/esplora.ts b/sdk/src/esplora.ts index dc95f9d2..05a2793e 100644 --- a/sdk/src/esplora.ts +++ b/sdk/src/esplora.ts @@ -97,18 +97,61 @@ export interface Block { } /** - * +* @ignore +*/ +function encodeEsploraMerkleProof(merkle: string[]): string { + // convert to little-endian + return merkle.map(item => Buffer.from(item, "hex").reverse().toString("hex")).join(''); +} + +/** * The `EsploraClient` interface provides a set of methods for interacting with an Esplora API * for Bitcoin network data retrieval. * See https://github.com/blockstream/esplora/blob/master/API.md for more information. */ -export interface EsploraClient { +export class EsploraClient { + private basePath: string; + + /** + * Create an instance of the `EsploraClient` with the specified network or URL. + * If the `networkOrUrl` parameter is omitted, it defaults to "mainnet." + * + * @param networkOrUrl The Bitcoin network (e.g., "mainnet," "testnet," "regtest") + * + * @returns An instance of the `EsploraClient` configured for the specified network or URL. + * + * @example + * const BITCOIN_NETWORK = "regtest"; + * const esploraClient = new EsploraClient(BITCOIN_NETWORK); + * + * @example + * // Create a client for the mainnet using the default URL. + * const esploraClientMainnet = new EsploraClient(); + */ + constructor(networkOrUrl: string = "mainnet") { + switch (networkOrUrl) { + case "mainnet": + this.basePath = MAINNET_ESPLORA_BASE_PATH; + break; + case "testnet": + this.basePath = TESTNET_ESPLORA_BASE_PATH; + break; + case "regtest": + this.basePath = REGTEST_ESPLORA_BASE_PATH; + break; + default: + this.basePath = networkOrUrl; + } + } + /** * Get the latest block height of the Bitcoin chain. * * @returns {Promise} A promise that resolves to the latest block number. */ - getLatestHeight(): Promise; + async getLatestHeight(): Promise { + return parseInt(await this.getText(`${this.basePath}/blocks/tip/height`), 10); + } /** * Get the complete block data for a Bitcoin block with a given hash. @@ -119,7 +162,7 @@ export interface EsploraClient { * @example * ```typescript * const BITCOIN_NETWORK = "regtest"; - * const esploraClient = new DefaultEsploraClient(BITCOIN_NETWORK); + * const esploraClient = new EsploraClient(BITCOIN_NETWORK); * const blockHash = 'your_block_hash_here'; * esploraClient.getBlock(blockHash) * .then((block) => { @@ -130,7 +173,9 @@ export interface EsploraClient { * }); * ``` */ - getBlock(hash: string): Promise; + async getBlock(blockHash: string): Promise { + return this.getJson(`${this.basePath}/block/${blockHash}`); + } /** * Get the block hash of the Bitcoin block at a specific height. @@ -143,7 +188,7 @@ export interface EsploraClient { * @example * ```typescript * const BITCOIN_NETWORK = "regtest"; - * const esploraClient = new DefaultEsploraClient(BITCOIN_NETWORK); + * const esploraClient = new EsploraClient(BITCOIN_NETWORK); * const blockHeight = 123456; * esploraClient.getBlockHash(blockHeight) * .then((blockHash) => { @@ -154,7 +199,9 @@ export interface EsploraClient { * }); * ``` */ - getBlockHash(height: number): Promise; + async getBlockHash(height: number): Promise { + return this.getText(`${this.basePath}/block-height/${height}`); + } /** * Get the raw block header, represented as a hex string, for a Bitcoin block with a given hash. @@ -165,7 +212,7 @@ export interface EsploraClient { * @example * ```typescript * const BITCOIN_NETWORK = "regtest"; - * const esploraClient = new DefaultEsploraClient(BITCOIN_NETWORK); + * const esploraClient = new EsploraClient(BITCOIN_NETWORK); * const blockHash = 'your_block_hash_here'; * esploraClient.getBlockHeader(blockHash) * .then((blockHeader) => { @@ -176,7 +223,17 @@ export interface EsploraClient { * }); * ``` */ - getBlockHeader(hash: string): Promise; + async getBlockHeader(hash: string): Promise { + return this.getText(`${this.basePath}/block/${hash}/header`); + } + + /** + * @ignore + */ + async getBlockHeaderAt(height: number): Promise { + const blockHash = await this.getBlockHash(height); + return await this.getBlockHeader(blockHash); + } /** * Get the complete transaction data for a Bitcoin transaction with a given ID (txId). @@ -187,7 +244,7 @@ export interface EsploraClient { * @example * ```typescript * const BITCOIN_NETWORK = "regtest"; - * const esploraClient = new DefaultEsploraClient(BITCOIN_NETWORK); + * const esploraClient = new EsploraClient(BITCOIN_NETWORK); * const transactionId = 'your_transaction_id_here'; * esploraClient.getTransaction(transactionId) * .then((transaction) => { @@ -198,7 +255,9 @@ export interface EsploraClient { * }); * ``` */ - getTransaction(txId: string): Promise; + async getTransaction(txId: string): Promise { + return this.getJson(`${this.basePath}/tx/${txId}`); + } /** * Get the transaction data, represented as a hex string, for a Bitcoin transaction with a given ID (txId). @@ -209,7 +268,7 @@ export interface EsploraClient { * @example * ```typescript * const BITCOIN_NETWORK = "regtest"; - * const esploraClient = new DefaultEsploraClient(BITCOIN_NETWORK); + * const esploraClient = new EsploraClient(BITCOIN_NETWORK); * const transactionId = 'your_transaction_id_here'; * esploraClient.getTransactionHex(transactionId) * .then((transactionHex) => { @@ -220,7 +279,9 @@ export interface EsploraClient { * }); * ``` */ - getTransactionHex(txId: string): Promise; + async getTransactionHex(txId: string): Promise { + return this.getText(`${this.basePath}/tx/${txId}/hex`); + } /** * Get the encoded merkle inclusion proof for a Bitcoin transaction with a given ID (txId). @@ -231,7 +292,7 @@ export interface EsploraClient { * @example * ```typescript * const BITCOIN_NETWORK = "regtest"; - * const esploraClient = new DefaultEsploraClient(BITCOIN_NETWORK); + * const esploraClient = new EsploraClient(BITCOIN_NETWORK); * const transactionId = 'your_transaction_id_here'; * esploraClient.getMerkleProof(transactionId) * .then((merkleProof) => { @@ -242,130 +303,6 @@ export interface EsploraClient { * }); * ``` */ - getMerkleProof(txId: string): Promise; - - /** - * Get the fee estimate (in sat/vB) for the given confirmation target. - * - * @param {number} confirmationTarget - The number of blocks to be included in. - * @returns {Promise} A promise that resolves to the fee rate. - */ - getFeeEstimate(confirmationTarget: number): Promise; - - /** - * Get the Unspent Transaction Outputs (UTXOs) for an address. - * - * @param {string} address - The Bitcoin address to check. - * @returns {Promise>} A promise that resolves to an array of UTXOs. - */ - getAddressUtxos(address: string): Promise>; - - /** - * Broadcast a raw transaction to the network. - * - * @param {string} txHex - The hex encoded transaction. - * @returns {Promise} A promise that resolves to the txid. - */ - broadcastTx(txHex: string): Promise; -} - -/** -* @ignore -*/ -function encodeEsploraMerkleProof(merkle: string[]): string { - // convert to little-endian - return merkle.map(item => Buffer.from(item, "hex").reverse().toString("hex")).join(''); -} - -/** - * The `DefaultEsploraClient` class provides a client for interacting with an Esplora API - * for Bitcoin network data retrieval. - */ -export class DefaultEsploraClient implements EsploraClient { - private basePath: string; - - /** - * Create an instance of the `DefaultEsploraClient` with the specified network or URL. - * If the `networkOrUrl` parameter is omitted, it defaults to "mainnet." - * - * @param networkOrUrl The Bitcoin network (e.g., "mainnet," "testnet," "regtest") - * - * @returns An instance of the `DefaultEsploraClient` configured for the specified network or URL. - * - * @example - * const BITCOIN_NETWORK = "regtest"; - * const esploraClient = new DefaultEsploraClient(BITCOIN_NETWORK); - * - * @example - * // Create a client for the mainnet using the default URL. - * const esploraClientMainnet = new DefaultEsploraClient(); - */ - constructor(networkOrUrl: string = "mainnet") { - switch (networkOrUrl) { - case "mainnet": - this.basePath = MAINNET_ESPLORA_BASE_PATH; - break; - case "testnet": - this.basePath = TESTNET_ESPLORA_BASE_PATH; - break; - case "regtest": - this.basePath = REGTEST_ESPLORA_BASE_PATH; - break; - default: - this.basePath = networkOrUrl; - } - } - - async getLatestHeight(): Promise { - return parseInt(await this.getText(`${this.basePath}/blocks/tip/height`), 10); - } - - /** - * @ignore - */ - async getBlock(blockHash: string): Promise { - return this.getJson(`${this.basePath}/block/${blockHash}`); - } - - /** - * @ignore - */ - async getBlockHash(height: number): Promise { - return this.getText(`${this.basePath}/block-height/${height}`); - } - - /** - * @ignore - */ - async getBlockHeader(hash: string): Promise { - return this.getText(`${this.basePath}/block/${hash}/header`); - } - - /** - * @ignore - */ - async getBlockHeaderAt(height: number): Promise { - const blockHash = await this.getBlockHash(height); - return await this.getBlockHeader(blockHash); - } - - /** - * @ignore - */ - async getTransaction(txId: string): Promise { - return this.getJson(`${this.basePath}/tx/${txId}`); - } - - /** - * @ignore - */ - async getTransactionHex(txId: string): Promise { - return this.getText(`${this.basePath}/tx/${txId}/hex`); - } - - /** - * @ignore - */ async getMerkleProof(txId: string): Promise { const response = await this.getJson<{ "block_height": number, @@ -380,7 +317,10 @@ export class DefaultEsploraClient implements EsploraClient { } /** - * @ignore + * Get the fee estimate (in sat/vB) for the given confirmation target. + * + * @param {number} confirmationTarget - The number of blocks to be included in. + * @returns {Promise} A promise that resolves to the fee rate. */ async getFeeEstimate(confirmationTarget: number): Promise { const response = await this.getJson(`${this.basePath}/fee-estimates`); @@ -388,7 +328,10 @@ export class DefaultEsploraClient implements EsploraClient { } /** - * @ignore + * Get the Unspent Transaction Outputs (UTXOs) for an address. + * + * @param {string} address - The Bitcoin address to check. + * @returns {Promise>} A promise that resolves to an array of UTXOs. */ async getAddressUtxos(address: string, confirmed?: boolean): Promise> { const response = await this.getJson} A promise that resolves to the txid. */ async broadcastTx(txHex: string): Promise { const res = await fetch(`${this.basePath}/tx`, { @@ -429,7 +375,7 @@ export class DefaultEsploraClient implements EsploraClient { /** * @ignore */ - async getJson(url: string): Promise { + private async getJson(url: string): Promise { const response = await fetch(url); if (!response.ok) { throw new Error(response.statusText); @@ -440,7 +386,7 @@ export class DefaultEsploraClient implements EsploraClient { /** * @ignore */ - async getText(url: string): Promise { + private async getText(url: string): Promise { const response = await fetch(url); if (!response.ok) { throw new Error(response.statusText); diff --git a/sdk/src/ordinal-api/index.ts b/sdk/src/ordinal-api/index.ts index d60d2fc4..332d020c 100644 --- a/sdk/src/ordinal-api/index.ts +++ b/sdk/src/ordinal-api/index.ts @@ -333,8 +333,25 @@ export interface InscriptionJson { value: number | null; } +export class OrdinalsClient { + private basePath: string; + + constructor(networkOrUrl: string = "mainnet") { + switch (networkOrUrl) { + case "mainnet": + this.basePath = MAINNET_ORD_BASE_PATH; + break; + case "testnet": + this.basePath = TESTNET_ORD_BASE_PATH; + break; + case "regtest": + this.basePath = REGTEST_ORD_BASE_PATH; + break; + default: + this.basePath = networkOrUrl; + } + } -export interface OrdinalsClient { /** * Retrieves an inscription based on its ID. * @param {string} id - The ID of the inscription to retrieve. @@ -342,13 +359,25 @@ export interface OrdinalsClient { * * @example * ```typescript - * const client = new DefaultOrdinalsClient("regtest"); + * const client = new OrdinalsClient("regtest"); * let inscriptionId = InscriptionId.fromString("enter_your_inscription_id_here"); * const inscription = await client.getInscriptionFromId(inscriptionId); * console.log("Inscription:", inscription); * ``` */ - getInscriptionFromId(id: InscriptionId): Promise>; + async getInscriptionFromId(id: InscriptionId): Promise> { + console.log(`${this.basePath}/inscription/${InscriptionId.toString(id)}`) + const inscriptionJson = await this.getJson>(`${this.basePath}/inscription/${InscriptionId.toString(id)}`); + return { + ...inscriptionJson, + 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), + }; + } /** * Retrieves a list of inscriptions. @@ -356,12 +385,16 @@ export interface OrdinalsClient { * * @example * ```typescript - * const client = new DefaultOrdinalsClient("regtest"); + * const client = new OrdinalsClient("regtest"); * const inscriptions = await client.getInscriptions(); * console.log("Inscriptions:", inscriptions); * ``` */ - getInscriptions(): Promise>; + async getInscriptions(): Promise> { + // TODO: add filtering, sorting and pagination based on different parameters + const inscriptionsJson = await this.getJson>(`${this.basePath}/inscriptions`); + return this.parseInscriptionsJson(inscriptionsJson); + } /** * Retrieves an inscription based on its block height. @@ -370,13 +403,16 @@ export interface OrdinalsClient { * * @example * ```typescript - * const client = new DefaultOrdinalsClient("regtest"); + * const client = new OrdinalsClient("regtest"); * let block: number = "enter_your_block_number_here"; * const inscriptions = await client.getInscriptionsFromBlock(block); * console.log("Inscriptions:", inscriptions); * ``` */ - getInscriptionsFromBlock(height: number): Promise>; + async getInscriptionsFromBlock(height: number): Promise> { + const inscriptionsJson = await this.getJson>(`${this.basePath}/inscriptions/block/${height}`); + return this.parseInscriptionsJson(inscriptionsJson); + } /** * Retrieves inscriptions based on the UTXO (Unspent Transaction Output). @@ -385,14 +421,16 @@ export interface OrdinalsClient { * * @example * ```typescript - * const client = new DefaultOrdinalsClient("regtest"); + * const client = new OrdinalsClient("regtest"); * let txid: string = "enter_your_utxo_txid_here"; * let vout = 0; // enter the UTXO index here * const output = await client.getInscriptionsFromOutPoint({ txid, vout }); * console.log("Output:", output); * ``` */ - getInscriptionsFromOutPoint(outPoint: OutPoint): Promise; + async getInscriptionsFromOutPoint(outPoint: OutPoint): Promise { + return await this.getJson(`${this.basePath}/output/${OutPoint.toString(outPoint)}`); + } /** * Retrieves an inscription based on its sat (something specific to your use case). @@ -401,13 +439,19 @@ export interface OrdinalsClient { * * @example * ```typescript - * const client = new DefaultOrdinalsClient("regtest"); + * const client = new OrdinalsClient("regtest"); * let sat: number = 0 // enter the sat number here * const inscriptions = await client.getInscriptionsFromSat(sat); * console.log("Inscriptions:", inscriptions); * ``` */ - getInscriptionsFromSat(sat: number): Promise>; + async getInscriptionsFromSat(sat: number): Promise> { + const satJson = await this.getJson>(`${this.basePath}/sat/${sat}`); + return { + ...satJson, + inscriptions: satJson.inscriptions.map(id => InscriptionId.fromString(id)), + }; + } /** * Retrieves a list of inscriptions starting from a specified block and moving forward. @@ -416,89 +460,12 @@ export interface OrdinalsClient { * * @example * ```typescript - * const client = new DefaultOrdinalsClient("regtest"); + * const client = new OrdinalsClient("regtest"); * let startBlock: number = "enter_your_block_number_here"; * const inscriptions = await client.getInscriptionsFromStartBlock(block); * console.log("Inscriptions:", inscriptions); * ``` */ - getInscriptionsFromStartBlock(startHeight: number): Promise>; -} - -export class DefaultOrdinalsClient implements OrdinalsClient { - private basePath: string; - - constructor(networkOrUrl: string = "mainnet") { - switch (networkOrUrl) { - case "mainnet": - this.basePath = MAINNET_ORD_BASE_PATH; - break; - case "testnet": - this.basePath = TESTNET_ORD_BASE_PATH; - break; - case "regtest": - this.basePath = REGTEST_ORD_BASE_PATH; - break; - default: - this.basePath = networkOrUrl; - } - } - - /** - * @ignore - */ - async getInscriptionFromId(id: InscriptionId): Promise> { - console.log(`${this.basePath}/inscription/${InscriptionId.toString(id)}`) - const inscriptionJson = await this.getJson>(`${this.basePath}/inscription/${InscriptionId.toString(id)}`); - return { - ...inscriptionJson, - 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), - }; - } - - /** - * @ignore - */ - async getInscriptions(): Promise> { - // TODO: add filtering, sorting and pagination based on different parameters - const inscriptionsJson = await this.getJson>(`${this.basePath}/inscriptions`); - return this.parseInscriptionsJson(inscriptionsJson); - } - - /** - * @ignore - */ - async getInscriptionsFromBlock(height: number): Promise> { - const inscriptionsJson = await this.getJson>(`${this.basePath}/inscriptions/block/${height}`); - return this.parseInscriptionsJson(inscriptionsJson); - } - - /** - * @ignore - */ - async getInscriptionsFromOutPoint(outPoint: OutPoint): Promise { - return await this.getJson(`${this.basePath}/output/${OutPoint.toString(outPoint)}`); - } - - /** - * @ignore - */ - async getInscriptionsFromSat(sat: number): Promise> { - const satJson = await this.getJson>(`${this.basePath}/sat/${sat}`); - return { - ...satJson, - inscriptions: satJson.inscriptions.map(id => InscriptionId.fromString(id)), - }; - } - - /** - * @ignore - */ async getInscriptionsFromStartBlock(startHeight: number): Promise> { const inscriptionsJson = await this.getJson>(`${this.basePath}/inscriptions/${startHeight}`); return this.parseInscriptionsJson(inscriptionsJson); @@ -507,7 +474,7 @@ export class DefaultOrdinalsClient implements OrdinalsClient { /** * @ignore */ - async getJson(url: string): Promise { + private async getJson(url: string): Promise { const response = await fetch(url, { headers: { 'Accept': 'application/json', @@ -522,7 +489,7 @@ export class DefaultOrdinalsClient implements OrdinalsClient { /** * @ignore */ - parseInscriptionsJson(inscriptionsJson: InscriptionsJson): InscriptionsJson { + private parseInscriptionsJson(inscriptionsJson: InscriptionsJson): InscriptionsJson { const ids = inscriptionsJson.ids.map(id => InscriptionId.fromString(id)); return { ...inscriptionsJson, diff --git a/sdk/src/relay.ts b/sdk/src/relay.ts index 1be8c9ec..ed39fb26 100644 --- a/sdk/src/relay.ts +++ b/sdk/src/relay.ts @@ -48,7 +48,7 @@ export interface BitcoinTxInfo { * @example * ```typescript * const BITCOIN_NETWORK = "regtest"; - * const esploraClient = new DefaultEsploraClient(BITCOIN_NETWORK); + * const esploraClient = new EsploraClient(BITCOIN_NETWORK); * const txId = "279121610d9575d132c95312c032116d6b8a58a3a31f69adf9736b493de96a16"; //enter the transaction id here * const info = await getBitcoinTxInfo(esploraClient, txId); * ``` @@ -104,7 +104,7 @@ export interface BitcoinTxProof { * @example * ```typescript * const BITCOIN_NETWORK = "regtest"; - * const esploraClient = new DefaultEsploraClient(BITCOIN_NETWORK); + * const esploraClient = new EsploraClient(BITCOIN_NETWORK); * const txId = "279121610d9575d132c95312c032116d6b8a58a3a31f69adf9736b493de96a16";//enter the transaction id here * const txProofDifficultyFactor = "1";//enter the difficulty factor * const info = await getBitcoinTxProof(esploraClient, txId, txProofDifficultyFactor); @@ -137,7 +137,7 @@ export async function getBitcoinTxProof( * * @example * const BITCOIN_NETWORK = "regtest"; - * const esploraClient = new DefaultEsploraClient(BITCOIN_NETWORK); + * const esploraClient = new EsploraClient(BITCOIN_NETWORK); * const startHeight = 0; * const numBlocks = 10; * diff --git a/sdk/src/scripts/relay-genesis.ts b/sdk/src/scripts/relay-genesis.ts index 99030ae7..73e578c7 100644 --- a/sdk/src/scripts/relay-genesis.ts +++ b/sdk/src/scripts/relay-genesis.ts @@ -1,4 +1,4 @@ -import { DefaultEsploraClient } from "../esplora"; +import { EsploraClient } from "../esplora"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; import { exec } from "node:child_process"; @@ -50,14 +50,14 @@ function range(size: number, startAt = 0) { return [...Array(size).keys()].map(i => i + startAt); } -async function getRetargetHeaders(esploraClient: DefaultEsploraClient, nextRetargetHeight: number, proofLength: number) { +async function getRetargetHeaders(esploraClient: EsploraClient, nextRetargetHeight: number, proofLength: number) { const beforeRetarget = await Promise.all(range(proofLength, nextRetargetHeight - proofLength).map(height => esploraClient.getBlockHeaderAt(height))); const afterRetarget = await Promise.all(range(proofLength, nextRetargetHeight).map(height => esploraClient.getBlockHeaderAt(height))); return beforeRetarget.concat(afterRetarget).join(""); } async function main(): Promise { - const esploraClient = new DefaultEsploraClient(args["network"]); + const esploraClient = new EsploraClient(args["network"]); let initHeight = args["init-height"]; if (initHeight == "latest") { diff --git a/sdk/src/scripts/relay-retarget.ts b/sdk/src/scripts/relay-retarget.ts index 9fe681b6..6c7d825e 100644 --- a/sdk/src/scripts/relay-retarget.ts +++ b/sdk/src/scripts/relay-retarget.ts @@ -1,4 +1,4 @@ -import { DefaultEsploraClient } from "../esplora"; +import { EsploraClient } from "../esplora"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; import { exec } from "node:child_process"; @@ -39,14 +39,14 @@ function range(size: number, startAt = 0) { return [...Array(size).keys()].map(i => i + startAt); } -async function getRetargetHeaders(esploraClient: DefaultEsploraClient, nextRetargetHeight: number, proofLength: number) { +async function getRetargetHeaders(esploraClient: EsploraClient, nextRetargetHeight: number, proofLength: number) { const beforeRetarget = await Promise.all(range(proofLength, nextRetargetHeight - proofLength).map(height => esploraClient.getBlockHeaderAt(height))); const afterRetarget = await Promise.all(range(proofLength, nextRetargetHeight).map(height => esploraClient.getBlockHeaderAt(height))); return beforeRetarget.concat(afterRetarget).join(""); } async function main(): Promise { - const esploraClient = new DefaultEsploraClient(args["network"]); + const esploraClient = new EsploraClient(args["network"]); let privateKey: string; if (args["private-key"]) { diff --git a/sdk/src/wallet/inscriptions.ts b/sdk/src/wallet/inscriptions.ts index 1c789af6..80b4fe2d 100644 --- a/sdk/src/wallet/inscriptions.ts +++ b/sdk/src/wallet/inscriptions.ts @@ -1,6 +1,6 @@ import { EsploraClient, UTXO } from "../esplora"; import { getTxInscriptions } from "../inscription"; -import { DefaultOrdinalsClient, InscriptionId, OrdinalsClient } from "../ordinal-api"; +import { OrdinalsClient, InscriptionId } from "../ordinal-api"; export async function findUtxoForInscriptionId( esploraClient: EsploraClient, @@ -31,7 +31,7 @@ export async function findUtxoForInscriptionId( } export async function findUtxosWithoutInscriptions(network: string, utxos: UTXO[]): Promise { - const ordinalsClient = new DefaultOrdinalsClient(network); + const ordinalsClient = new OrdinalsClient(network); const safeUtxos: UTXO[] = []; diff --git a/sdk/src/wallet/utxo.ts b/sdk/src/wallet/utxo.ts index 40180c86..e5ac8678 100644 --- a/sdk/src/wallet/utxo.ts +++ b/sdk/src/wallet/utxo.ts @@ -1,7 +1,7 @@ import { Transaction, Script, selectUTXO, TEST_NETWORK, NETWORK, p2wpkh, p2sh } from '@scure/btc-signer'; import { hex, base64 } from "@scure/base"; import { AddressType, getAddressInfo, Network } from 'bitcoin-address-validation'; -import { DefaultEsploraClient, UTXO } from '../esplora'; +import { EsploraClient, UTXO } from '../esplora'; export type BitcoinNetworkName = Exclude; @@ -62,7 +62,7 @@ export async function createBitcoinPsbt( } } - const esploraClient = new DefaultEsploraClient(addressInfo.network); + const esploraClient = new EsploraClient(addressInfo.network); // NOTE: esplora only returns the 25 most recent UTXOs // TODO: change this to use the pagination API and return all UTXOs diff --git a/sdk/test/esplora.test.ts b/sdk/test/esplora.test.ts index ec375683..d4693390 100644 --- a/sdk/test/esplora.test.ts +++ b/sdk/test/esplora.test.ts @@ -1,15 +1,15 @@ import { assert, describe, it } from "vitest"; -import { DefaultEsploraClient, Transaction, Block } from "../src/esplora"; +import { EsploraClient, Transaction, Block } from "../src/esplora"; describe("Esplora Tests", () => { it("should get block height", async () => { - const client = new DefaultEsploraClient("testnet"); + const client = new EsploraClient("testnet"); const height = await client.getLatestHeight(); assert(height > 0); }); it("should get block", async () => { - const client = new DefaultEsploraClient("testnet"); + const client = new EsploraClient("testnet"); const block = await client.getBlock("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"); const expectedBlock: Block = { id: '000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943', @@ -33,25 +33,25 @@ describe("Esplora Tests", () => { }); it("should get block hash", async () => { - const client = new DefaultEsploraClient("testnet"); + const client = new EsploraClient("testnet"); const blockHash = await client.getBlockHash(0); assert.equal(blockHash, "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"); }); it("should get block header", async () => { - const client = new DefaultEsploraClient("testnet"); + const client = new EsploraClient("testnet"); const blockHeader = await client.getBlockHeader("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"); assert.equal(blockHeader, "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae18"); }); it("should get block header at certain height", async () => { - const client = new DefaultEsploraClient("testnet"); + const client = new EsploraClient("testnet"); const blockHeader = await client.getBlockHeaderAt(10); assert.equal(blockHeader, "010000001e93aa99c8ff9749037d74a2207f299502fa81d56a4ea2ad5330ff50000000002ec2266c3249ce2e079059e0aec01a2d8d8306a468ad3f18f06051f2c3b1645435e9494dffff001d008918cf"); }); it("should get transaction", async () => { - const client = new DefaultEsploraClient("testnet"); + const client = new EsploraClient("testnet"); const tx = await client.getTransaction("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"); const expectedTransaction: Transaction = { txid: '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b', @@ -90,14 +90,14 @@ describe("Esplora Tests", () => { }); it("should get tx hex", async () => { - const client = new DefaultEsploraClient("testnet"); + const client = new EsploraClient("testnet"); const txHex = await client.getTransactionHex("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"); assert.equal(txHex, "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"); }); it("should serialize merkle proof", async () => { - const client = new DefaultEsploraClient(); + const client = new EsploraClient(); const proof = await client.getMerkleProof("b61b0172d95e266c18aea0c624db987e971a5d6d4ebc2aaed85da4642d635735"); assert.equal(proof.merkle, "ace8423f874c95f5f9042d7cda6b9f0727251f3059ef827f373a56831cc621a371db6dfce8daed1d809275" + @@ -111,7 +111,7 @@ describe("Esplora Tests", () => { }); it("should get fee rate", async () => { - const client = new DefaultEsploraClient("testnet"); + const client = new EsploraClient("testnet"); const feeRate = await client.getFeeEstimate(1); assert.isAtLeast(feeRate, 1); }); diff --git a/sdk/test/inscription.test.ts b/sdk/test/inscription.test.ts index 81e5479a..be2bff82 100644 --- a/sdk/test/inscription.test.ts +++ b/sdk/test/inscription.test.ts @@ -1,5 +1,5 @@ import * as bitcoin from "bitcoinjs-lib"; -import { DefaultEsploraClient } from "../src/esplora"; +import { EsploraClient } from "../src/esplora"; import { Inscription, PROTOCOL_ID, parseInscriptions } from "../src/inscription"; import { assert, describe, it } from "vitest"; @@ -23,7 +23,7 @@ function createOrdinalTransaction(outputScript: Buffer) { describe("Inscription Tests", () => { it("should parse text inscription", async () => { - const esploraClient = new DefaultEsploraClient("mainnet"); + const esploraClient = new EsploraClient("mainnet"); const txHex = await esploraClient.getTransactionHex("b61b0172d95e266c18aea0c624db987e971a5d6d4ebc2aaed85da4642d635735"); const tx = bitcoin.Transaction.fromHex(txHex); @@ -48,7 +48,7 @@ describe("Inscription Tests", () => { }); it("should parse image inscription", async () => { - const esploraClient = new DefaultEsploraClient("mainnet"); + const esploraClient = new EsploraClient("mainnet"); const txHex = await esploraClient.getTransactionHex("79ddcce9b4aaa4d2c3ba512a1dfd9bf2dd1f840eab98101c41bf8b801bcb3e0c"); const tx = bitcoin.Transaction.fromHex(txHex); diff --git a/sdk/test/ordinal-api.test.ts b/sdk/test/ordinal-api.test.ts index 1b8aa152..e6d5f6c0 100644 --- a/sdk/test/ordinal-api.test.ts +++ b/sdk/test/ordinal-api.test.ts @@ -1,5 +1,5 @@ import { - DefaultOrdinalsClient, + OrdinalsClient, InscriptionJson, OutputJson, InscriptionId, @@ -9,7 +9,7 @@ import { assert, describe, it } from "vitest"; describe("Ordinal API Tests", () => { it("should get inscription from id", async () => { - const client = new DefaultOrdinalsClient("mainnet"); + const client = new OrdinalsClient("mainnet"); // Deploy ORDI - BRC20 const inscriptionJson = await client.getInscriptionFromId({ txid: "b61b0172d95e266c18aea0c624db987e971a5d6d4ebc2aaed85da4642d635735", @@ -42,7 +42,7 @@ describe("Ordinal API Tests", () => { }); it("should get inscriptions", { timeout: 10000 }, async () => { - const client = new DefaultOrdinalsClient("mainnet"); + const client = new OrdinalsClient("mainnet"); const inscriptionsJson = await client.getInscriptions(); // assert that inscriptionsJson is not null, undefined or empty assert.isNotNull(inscriptionsJson); @@ -50,7 +50,7 @@ describe("Ordinal API Tests", () => { }); it("should get inscriptions from block", { timeout: 10000 }, async () => { - const client = new DefaultOrdinalsClient("mainnet"); + const client = new OrdinalsClient("mainnet"); const block: number = 804691; const inscriptionsJson = await client.getInscriptionsFromBlock(block); const expectedInscriptionsJson = { @@ -70,7 +70,7 @@ describe("Ordinal API Tests", () => { }); it("should get inscriptions from UTXO", { timeout: 10000 }, async () => { - const client = new DefaultOrdinalsClient("mainnet"); + const client = new OrdinalsClient("mainnet"); const outputJson = await client.getInscriptionsFromOutPoint({ txid: "dfe942a58b7e29a3952d8d1ed6608086c66475d20bc7bdbc3d784d616f9a6a7a", vout: 0 @@ -90,7 +90,7 @@ describe("Ordinal API Tests", () => { }); it("should get inscriptions from Sat", { timeout: 10000 }, async () => { - const client = new DefaultOrdinalsClient("mainnet"); + const client = new OrdinalsClient("mainnet"); const sat: number = 100; const satJson = await client.getInscriptionsFromSat(sat); const expectedSatJson = { @@ -114,7 +114,7 @@ describe("Ordinal API Tests", () => { }); it("should get inscriptions from start block", { timeout: 10000 }, async () => { - const client = new DefaultOrdinalsClient("mainnet"); + const client = new OrdinalsClient("mainnet"); const startBlock: number = 2537138; const inscriptions = await client.getInscriptionsFromStartBlock(startBlock); // assert that inscriptions is not null or undefined diff --git a/sdk/test/relay.test.ts b/sdk/test/relay.test.ts index 3fb50830..4920946f 100644 --- a/sdk/test/relay.test.ts +++ b/sdk/test/relay.test.ts @@ -1,5 +1,5 @@ import { assert, describe, it } from "vitest"; -import { DefaultEsploraClient } from "../src/esplora"; +import { EsploraClient } from "../src/esplora"; import { getBitcoinTxInfo, getBitcoinTxProof } from "../src/relay"; import * as bitcoin from "bitcoinjs-lib"; import { encodeRawOutput } from "../src/utils"; @@ -19,7 +19,7 @@ describe("Relay Tests", () => { }); it("should get tx info", async () => { - const client = new DefaultEsploraClient(); + const client = new EsploraClient(); const txId = "2ef69769cc0ee81141c79552de6b91f372ff886216dbfa84e5497a16b0173e79"; const txInfo = await getBitcoinTxInfo(client, txId); assert.deepEqual(txInfo, { @@ -32,7 +32,7 @@ describe("Relay Tests", () => { }); it("should get tx proof", async () => { - const client = new DefaultEsploraClient(); + const client = new EsploraClient(); const txId = "2ef69769cc0ee81141c79552de6b91f372ff886216dbfa84e5497a16b0173e79"; const txProof = await getBitcoinTxProof(client, txId, 2); assert.equal(txProof.txIndexInBlock, 1);