Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
cmd committed Oct 21, 2023
1 parent 6c81f7e commit 462b650
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 70 deletions.
86 changes: 68 additions & 18 deletions src/lib/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@ import {
ScanObject,
ScanResults,
WalletList,
CoreTx,
CoreConfig,
CmdConfig,
TxStatus,
BlockData,
BlockHeader
BlockHeader,
ScanOptions,
TxOutpoint,
TxResult,
TxStatus
} from '../types/index.js'
import { convert_value, convert_vout } from './util.js'

export class CoreClient {
readonly _core : CoreDaemon
Expand Down Expand Up @@ -82,6 +85,10 @@ export class CoreClient {
return this._opt
}

get blocks () : Promise<number> {
return this.cmd<number>('getblockcount')
}

get chain_info () {
return this.cmd<Record<string, any>>('getblockchaininfo')
}
Expand Down Expand Up @@ -167,30 +174,62 @@ export class CoreClient {
}

async get_tx (txid : string) {
let txdata : CoreTx,
status : TxStatus = { confirmed : false }
try {
txdata = await this.cmd<CoreTx>('getrawtransaction', [ txid, true ], { cache : true })
} catch (err) {
const res = await this.cmd<TxResult>('getrawtransaction', [ txid, true ], { cache : true })
res.vout = convert_vout(res.vout)
return res
} catch {
return null
}
const { hex, ...data } = txdata
const block_hash = txdata.blockhash
const block_time = txdata.blocktime
if (block_hash !== undefined && block_time !== undefined) {
const { height } = await this.get_header({ hash : block_hash })
status = { confirmed : true, block_height : height, block_hash, block_time }
}
return { data, hex, status }
}

async get_utxos (addr : string) {
return this.scan_txout('start', `addr(${addr})`).then(res => {
async get_utxos (opt : ScanOptions) {
const desc = get_scan_desc(opt)
return this.scan_txout('start', desc).then(res => {
const { success, unspents } = res
return (success) ? unspents : null
if (!success) return []
return unspents.map(e => {
return { ...e, amount : convert_value(e.amount) }
})
})
}

async get_txout (
txid : string,
vout : number
) {
const res = await this.cmd<TxOutpoint | null>('gettxout', [ txid, vout ])
if (res === null) return null
res.value = convert_value(res.value)
return res
}

async get_prevout (
txid : string,
vout : number
) {
let status : TxStatus
const tx = await this.get_tx(txid)
if (tx === null) return null
const txout = tx.vout.at(vout)
if (txout === undefined) return null

if (
tx.confirmations === undefined ||
tx.confirmations === 0
) {
status = { confirmed : false }
} else {
const block_hash = tx.blockhash as string
const block_time = tx.blocktime as number
const block_height = (await this.blocks) - tx.confirmations
status = { confirmed : true, block_height, block_hash, block_time }
}
const { value, scriptPubKey } = txout
const prevout = { value, scriptPubKey : scriptPubKey.hex }
return { prevout, status }
}

async load_wallet (name : string) {
const wallet = new CoreWallet(this, name)
await wallet.load()
Expand Down Expand Up @@ -226,3 +265,14 @@ export class CoreClient {
return txid
}
}

function get_scan_desc (opt : ScanOptions) {
if (opt.address !== undefined) {
return `addr(${opt.address})`
} else if (opt.pubkey !== undefined) {
return `combo(${opt.pubkey})`
} else if (opt.script) {
return `raw(${opt.script})`
}
throw new Error('No scan option specified!')
}
10 changes: 10 additions & 0 deletions src/lib/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { access, constants, mkdir, writeFile } from 'fs/promises'

import { TxOutput } from '../types/index.js'

export async function path_exists (filepath : string) {
try {
await access(filepath, constants.R_OK | constants.W_OK)
Expand All @@ -20,3 +22,11 @@ export async function ensure_file(filepath : string) {
await writeFile(filepath, '')
}
}

export function convert_value (value : number) {
return value * 100_000_000
}

export function convert_vout (vout : TxOutput[]) {
return vout.map(e => { return { ...e, value : convert_value(e.value) } })
}
49 changes: 0 additions & 49 deletions src/types/info.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
export type CoreTx = CoreTxConfirmed | CoreTxUnconfirmed

export interface AddressInfo {
address : string
scriptPubKey : string
Expand All @@ -19,50 +17,3 @@ export interface AddressInfo {
labels : string[]
hdmasterfingerprint : string
}

export interface CoreTxResult {
txid : string,
hash : string,
version : number,
size : number,
vsize : number,
weight : number,
locktime : number,
hex : string
vin: [{
txid : string,
vout : number,
scriptSig : { asm : string, hex : string },
txinwitness : string[],
sequence : number
}],
vout: [{
n : number
value : number,
scriptPubKey : ScriptKeyResult
}],
}

export interface CoreTxUnconfirmed extends CoreTxResult {
blockhash ?: string
confirmations ?: number
time ?: number
blocktime ?: number
}

export interface CoreTxConfirmed extends CoreTxResult {
blockhash : string
confirmations : number
time : number
blocktime : number
}



export interface ScriptKeyResult {
asm : string,
desc : string,
hex : string,
address : string,
type : string
}
6 changes: 6 additions & 0 deletions src/types/scan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ export interface ScanObject {
range : number | number[]
}

export interface ScanOptions {
address ?: string
pubkey ?: string
script ?: string
}

export interface ScanResults {
success : boolean
txouts : number
Expand Down
53 changes: 50 additions & 3 deletions src/types/tx.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,59 @@
export type TxStatus = TxStatusUnconfimed | TxStatusConfirmed
export type TxStatus = TxConfirmed | TxUnconfirmed

export interface TxStatusUnconfimed {
export interface ScriptKey {
asm : string
desc : string
hex : string
address : string
type : string
}

export interface TxInput {
txid : string,
vout : number,
scriptSig : { asm : string, hex : string },
txinwitness : string[],
sequence : number
}

export interface TxOutput {
n : number
value : number
scriptPubKey : ScriptKey
}

export interface TxResult {
txid : string
hash : string
version : number
size : number
vsize : number
weight : number
locktime : number
hex : string
vin : TxInput[]
vout : TxOutput[]
blockhash ?: string
confirmations ?: number
time ?: number
blocktime ?: number
}

export interface TxUnconfirmed {
confirmed : false
}

export interface TxStatusConfirmed {
export interface TxConfirmed {
confirmed : true
block_hash : string
block_height : number
block_time : number
}

export interface TxOutpoint {
bestblock : string
confirmations : number
value : number
scriptPubKey : ScriptKey
coinbase : boolean
}

0 comments on commit 462b650

Please sign in to comment.