import { IEsploraApi } from './api/bitcoin/esplora-api.interface'; import { OrphanedBlock } from './api/chain-tips'; import { HeapNode } from './utils/pairing-heap'; export interface PoolTag { id: number; uniqueId: number; name: string; link: string; regexes: string; // JSON array addresses: string; // JSON array slug: string; } export interface PoolInfo { poolId: number; // mysql row id name: string; link: string; blockCount: number; slug: string; avgMatchRate: number | null; avgFeeDelta: number | null; poolUniqueId: number; } export interface PoolStats extends PoolInfo { rank: number; emptyBlocks: number; } export interface BlockAudit { version: number, time: number, height: number, hash: string, unseenTxs: string[], missingTxs: string[], freshTxs: string[], sigopTxs: string[], fullrbfTxs: string[], addedTxs: string[], prioritizedTxs: string[], acceleratedTxs: string[], matchRate: number, expectedFees?: number, expectedWeight?: number, template?: any[]; } export interface TransactionAudit { seen?: boolean; expected?: boolean; added?: boolean; prioritized?: boolean; delayed?: number; accelerated?: boolean; conflict?: boolean; coinbase?: boolean; firstSeen?: number; } export interface AuditScore { hash: string, matchRate?: number, expectedFees?: number expectedWeight?: number } export interface MempoolBlock { blockSize: number; blockVSize: number; nTx: number; medianFee: number; totalFees: number; feeRange: number[]; } export interface MempoolBlockWithTransactions extends MempoolBlock { transactionIds: string[]; transactions: TransactionClassified[]; } export interface MempoolBlockDelta { added: TransactionCompressed[]; removed: string[]; changed: MempoolDeltaChange[]; } export interface MempoolDeltaTxids { sequence: number, added: string[]; removed: string[]; mined: string[]; replaced: { replaced: string, by: string }[]; } export interface MempoolDelta { sequence: number, added: MempoolTransactionExtended[]; removed: string[]; mined: string[]; replaced: { replaced: string, by: TransactionExtended }[]; } interface VinStrippedToScriptsig { scriptsig: string; } interface VoutStrippedToScriptPubkey { scriptpubkey_address: string | undefined; scriptpubkey_asm: string | undefined; value: number; } export interface TransactionExtended extends IEsploraApi.Transaction { vsize: number; feePerVsize: number; firstSeen?: number; effectiveFeePerVsize: number; ancestors?: Ancestor[]; descendants?: Ancestor[]; bestDescendant?: BestDescendant | null; cpfpChecked?: boolean; position?: { block: number, vsize: number, }; acceleration?: boolean; acceleratedBy?: number[]; acceleratedAt?: number; feeDelta?: number; replacement?: boolean; uid?: number; flags?: number; } export interface MempoolTransactionExtended extends TransactionExtended { order: number; sigops: number; adjustedVsize: number; adjustedFeePerVsize: number; inputs?: number[]; lastBoosted?: number; cpfpDirty?: boolean; cpfpUpdated?: number; } export interface AuditTransaction { uid: number; fee: number; weight: number; feePerVsize: number; effectiveFeePerVsize: number; sigops: number; inputs: number[]; relativesSet: boolean; ancestorMap: Map; children: Set; ancestorFee: number; ancestorWeight: number; ancestorSigops: number; score: number; used: boolean; modified: boolean; modifiedNode: HeapNode; dependencyRate?: number; } export interface CompactThreadTransaction { uid: number; fee: number; weight: number; sigops: number; feePerVsize: number; effectiveFeePerVsize: number; inputs: number[]; cpfpRoot?: number; cpfpChecked?: boolean; dirty?: boolean; } export interface GbtCandidates { txs: { [txid: string ]: boolean }, added: MempoolTransactionExtended[]; removed: MempoolTransactionExtended[]; } export interface ThreadTransaction { txid: string; fee: number; weight: number; feePerVsize: number; effectiveFeePerVsize?: number; inputs: number[]; cpfpRoot?: string; cpfpChecked?: boolean; } export interface Ancestor { txid: string; weight: number; fee: number; } export interface TransactionSet { fee: number; weight: number; score: number; children?: Set; available?: boolean; modified?: boolean; modifiedNode?: HeapNode; } interface BestDescendant { txid: string; weight: number; fee: number; } export interface CpfpInfo { ancestors: Ancestor[]; bestDescendant?: BestDescendant | null; descendants?: Ancestor[]; effectiveFeePerVsize?: number; sigops?: number; adjustedVsize?: number, acceleration?: boolean, fee?: number; } export interface TransactionStripped { txid: string; fee: number; vsize: number; value: number; acc?: boolean; rate?: number; // effective fee rate time?: number; } export interface TransactionClassified extends TransactionStripped { flags: number; } // [txid, fee, vsize, value, rate, flags, acceleration?] export type TransactionCompressed = [string, number, number, number, number, number, number, 1?]; // [txid, rate, flags, acceleration?] export type MempoolDeltaChange = [string, number, number, (1|0)]; // binary flags for transaction classification export const TransactionFlags = { // features rbf: 0b00000001n, no_rbf: 0b00000010n, v1: 0b00000100n, v2: 0b00001000n, v3: 0b00010000n, nonstandard: 0b00100000n, // address types p2pk: 0b00000001_00000000n, p2ms: 0b00000010_00000000n, p2pkh: 0b00000100_00000000n, p2sh: 0b00001000_00000000n, p2wpkh: 0b00010000_00000000n, p2wsh: 0b00100000_00000000n, p2tr: 0b01000000_00000000n, // behavior cpfp_parent: 0b00000001_00000000_00000000n, cpfp_child: 0b00000010_00000000_00000000n, replacement: 0b00000100_00000000_00000000n, // data op_return: 0b00000001_00000000_00000000_00000000n, fake_pubkey: 0b00000010_00000000_00000000_00000000n, inscription: 0b00000100_00000000_00000000_00000000n, fake_scripthash: 0b00001000_00000000_00000000_00000000n, // heuristics coinjoin: 0b00000001_00000000_00000000_00000000_00000000n, consolidation: 0b00000010_00000000_00000000_00000000_00000000n, batch_payout: 0b00000100_00000000_00000000_00000000_00000000n, // sighash sighash_all: 0b00000001_00000000_00000000_00000000_00000000_00000000n, sighash_none: 0b00000010_00000000_00000000_00000000_00000000_00000000n, sighash_single: 0b00000100_00000000_00000000_00000000_00000000_00000000n, sighash_default:0b00001000_00000000_00000000_00000000_00000000_00000000n, sighash_acp: 0b00010000_00000000_00000000_00000000_00000000_00000000n, }; export interface BlockExtension { totalFees: number; medianFee: number; // median fee rate feeRange: number[]; // fee rate percentiles reward: number; matchRate: number | null; expectedFees: number | null; expectedWeight: number | null; similarity?: number; pool: { id: number; // Note - This is the `unique_id`, not to mix with the auto increment `id` name: string; slug: string; minerNames: string[] | null; }; avgFee: number; avgFeeRate: number; coinbaseRaw: string; orphans: OrphanedBlock[] | null; coinbaseAddress: string | null; coinbaseAddresses: string[] | null; coinbaseSignature: string | null; coinbaseSignatureAscii: string | null; virtualSize: number; avgTxSize: number; totalInputs: number; totalOutputs: number; totalOutputAmt: number; medianFeeAmt: number | null; // median fee in sats feePercentiles: number[] | null, // fee percentiles in sats segwitTotalTxs: number; segwitTotalSize: number; segwitTotalWeight: number; header: string; firstSeen: number | null; utxoSetChange: number; // Requires coinstatsindex, will be set to NULL otherwise utxoSetSize: number | null; totalInputAmt: number | null; } /** * Note: Everything that is added in here will be automatically returned through * /api/v1/block and /api/v1/blocks APIs */ export interface BlockExtended extends IEsploraApi.Block { extras: BlockExtension; canonical?: string; } export interface BlockSummary { id: string; transactions: TransactionClassified[]; version?: number; } export interface AuditSummary extends BlockAudit { timestamp?: number, size?: number, weight?: number, tx_count?: number, transactions: TransactionClassified[]; template?: TransactionClassified[]; } export interface BlockPrice { height: number; priceId: number; } export interface TransactionMinerInfo { vin: VinStrippedToScriptsig[]; vout: VoutStrippedToScriptPubkey[]; } export interface MempoolStats { funded_txo_count: number; funded_txo_sum: number; spent_txo_count: number; spent_txo_sum: number; tx_count: number; } export interface EffectiveFeeStats { medianFee: number; // median effective fee rate feeRange: number[]; // 2nd, 10th, 25th, 50th, 75th, 90th, 98th percentiles } export interface WorkingEffectiveFeeStats extends EffectiveFeeStats { minFee: number; maxFee: number; } export interface CpfpCluster { root: string, height: number, txs: Ancestor[], effectiveFeePerVsize: number, } export interface CpfpSummary { transactions: MempoolTransactionExtended[]; clusters: CpfpCluster[]; version: number; } export interface Statistic { id?: number; added: string; unconfirmed_transactions: number; tx_per_second: number; vbytes_per_second: number; total_fee: number; mempool_byte_weight: number; fee_data: string; min_fee: number; vsize_1: number; vsize_2: number; vsize_3: number; vsize_4: number; vsize_5: number; vsize_6: number; vsize_8: number; vsize_10: number; vsize_12: number; vsize_15: number; vsize_20: number; vsize_30: number; vsize_40: number; vsize_50: number; vsize_60: number; vsize_70: number; vsize_80: number; vsize_90: number; vsize_100: number; vsize_125: number; vsize_150: number; vsize_175: number; vsize_200: number; vsize_250: number; vsize_300: number; vsize_350: number; vsize_400: number; vsize_500: number; vsize_600: number; vsize_700: number; vsize_800: number; vsize_900: number; vsize_1000: number; vsize_1200: number; vsize_1400: number; vsize_1600: number; vsize_1800: number; vsize_2000: number; } export interface OptimizedStatistic { added: string; count: number; vbytes_per_second: number; total_fee: number; mempool_byte_weight: number; min_fee: number; vsizes: number[]; } export interface TxTrackingInfo { replacedBy?: string, position?: { block: number, vsize: number, accelerated?: boolean, acceleratedBy?: number[], acceleratedAt?: number, feeDelta?: number }, cpfp?: { ancestors?: Ancestor[], bestDescendant?: Ancestor | null, descendants?: Ancestor[] | null, effectiveFeePerVsize?: number | null, sigops: number, adjustedVsize: number, }, utxoSpent?: { [vout: number]: { vin: number, txid: string } }, accelerated?: boolean, acceleratedBy?: number[], acceleratedAt?: number, feeDelta?: number, confirmed?: boolean } export interface WebsocketResponse { action: string; data: string[]; 'track-tx': string; 'track-address': string; 'watch-mempool': boolean; } export interface VbytesPerSecond { unixTime: number; vSize: number; } export interface RequiredSpec { [name: string]: RequiredParams; } interface RequiredParams { required: boolean; types: ('@string' | '@number' | '@boolean' | string)[]; } export interface ILoadingIndicators { [name: string]: number; } export interface IBackendInfo { hostname: string; gitCommit: string; version: string; lightning: boolean; backend: 'esplora' | 'electrum' | 'none'; } export interface IDifficultyAdjustment { progressPercent: number; difficultyChange: number; estimatedRetargetDate: number; remainingBlocks: number; remainingTime: number; previousRetarget: number; previousTime: number; nextRetargetHeight: number; timeAvg: number; timeOffset: number; expectedBlocks: number; } export interface IndexedDifficultyAdjustment { time: number; // UNIX timestamp height: number; // Block height difficulty: number; adjustment: number; } export interface RewardStats { totalReward: number; totalFee: number; totalTx: number; } export interface ITopNodesPerChannels { publicKey: string, alias: string, channels?: number, capacity: number, firstSeen?: number, updatedAt?: number, city?: any, country?: any, } export interface ITopNodesPerCapacity { publicKey: string, alias: string, capacity: number, channels?: number, firstSeen?: number, updatedAt?: number, city?: any, country?: any, } export interface INodesRanking { topByCapacity: ITopNodesPerCapacity[]; topByChannels: ITopNodesPerChannels[]; } export interface IOldestNodes { publicKey: string, alias: string, firstSeen: number, channels?: number, capacity: number, updatedAt?: number, city?: any, country?: any, }