@btc-vision/bitcoin-rpc
Version:
The one and only fully typed Bitcoin RPC client for Node.js
1,666 lines (1,395 loc) • 55 kB
text/typescript
import { IFetchOptions, UnsuccessfulFetch } from 'rpc-request';
import { RESTClient, RESTIniOptions } from './rest.js';
import { BlockData } from '../types/BlockData.js';
import { RawTransaction } from '../types/BitcoinRawTransaction.js';
import { BitcoinVerbosity } from '../types/BitcoinVerbosity.js';
import { BlockTemplateCapability, BlockTemplateRule } from '../types/BlockTemplate.js';
export type RPCIniOptions = RESTIniOptions & {
user?: string;
pass: string;
wallet?: string;
fullResponse?: boolean;
};
export type JSONRPC = {
jsonrpc?: string | number;
id?: string | number;
method: string;
params?: object;
};
export type Verbosity = { verbosity?: 0 | 1 | 2 };
export type Verbose = { verbose?: boolean };
export type Height = { height: number };
export type Blockhash = { blockhash: string };
export type TxId = { txid: string };
export type GetBlockParams = Verbosity & Blockhash;
export type GetBlockFilterParams = Blockhash & { filtertype?: string };
export type GetBlockHeaderParams = Blockhash & Verbose;
export type GetBlockStatsParams = {
hash_or_height: string | number;
stats?: string[];
};
export type GetChainTxStatsParams = { nblocks?: number; blockhash?: string };
export type GetMemPoolParams = TxId & Verbose;
export type GetTxOutParams = TxId & { n: number; include_mempool?: boolean };
export type GetTxOutProofParams = { txids: string[]; blockhash?: string };
export type Descriptor = string | { desc: string; range: number | [number, number] };
export type ScanTxOutSetParams = {
action: 'start' | 'abort' | 'status';
scanobjects: Descriptor[];
};
export type HelpParams = { command?: string };
export type LoggingParams = {
include?: string[] | 'all' | 'none' | 0 | 1;
exclude?: string[] | 'all' | 'none' | 0 | 1;
};
export type GenerateParams = { nblocks: number; maxtries?: number };
export type GenerateToAddressParams = GenerateParams & { address: string };
export enum GetBlockTemplateMode {
TEMPLATE = 'template',
PROPOSAL = 'proposal',
}
export type GetBlockTemplateParams = {
template_request: {
mode?: GetBlockTemplateMode;
capabilities?: BlockTemplateCapability[];
rules: BlockTemplateRule[];
};
};
export type PrioritiseTransactionParams = TxId & { fee_delta: number };
export type HexData = { hexdata: string };
export type AddNodeParams = {
node: string;
command: 'add' | 'remove' | 'onetry';
};
export type DisconnectNodeParams = { address: string } | { nodeid: number };
export type SetBanParams = {
subnet: string;
command: 'add' | 'remove';
bantime?: number;
absolute?: boolean;
};
export type AddressType = 'legacy' | 'p2sh-segwit' | 'bech32';
export type CreateMultiSigParams = {
nrequired: number;
keys: string[];
address_type?: AddressType;
};
export type DeriveAddressesParams = {
descriptor: string;
range?: number | [number, number];
};
export type EstimateMode = {
estimate_mode?: 'UNSET' | 'ECONOMICAL' | 'CONSERVATIVE';
};
export type EstimateSmartFeeParams = EstimateMode & { conf_target: number };
export type SignMessageWithPrivKeyParams = { privkey: string; message: string };
export type VerifyMessageParams = {
address: string;
signature: string;
message: string;
};
export type HexString = { hexstring: string };
export type ConvertToPsbtParams = HexString & {
permitsigdata?: boolean;
iswitness?: boolean;
};
export type BaseTransactionInput = { txid: string; vout: number };
export type TransactionInput = BaseTransactionInput & { sequence?: number };
export type TransactionOutput = { [address: string]: string | number } | { data: string };
export type BaseCreateTransaction = {
inputs: TransactionInput[];
outputs: TransactionOutput[];
locktime?: number;
};
export type CreateTransactionParams = BaseCreateTransaction & {
replaceable?: boolean;
};
export type DecodeRawTransactionParams = HexString & { iswitness?: boolean };
export type FinalizePsbtParams = { psbt: string; extract?: boolean };
export type BaseFundOptions = {
options?: EstimateMode & {
changeAddress?: string;
changePosition?: number;
change_type?: string;
includeWatching?: boolean;
lockUnspents?: boolean;
feeRate?: number | string;
subtractFeeFromOutputs?: number[];
replaceable?: boolean;
conf_target?: number;
};
};
export type FundRawTransactionParams = HexString & {
options?: BaseFundOptions;
iswitness?: boolean;
};
export type GetRawTransactionParams = TxId & Verbose & { blockhash?: string };
export type SendRawTransactionParams = HexString & {
maxfeerate?: number | string;
};
export type PrevTx = {
txid: string;
vout: number;
scriptPubKey: string;
redeemScript?: string;
witnessScript?: string;
amount: number | string;
};
export type SigHashType =
| 'ALL'
| 'NONE'
| 'SINGLE'
| 'ALL|ANYONECANPAY'
| 'NONE|ANYONECANPAY'
| 'SINGLE|ANYONECANPAY';
export type SignRawTransactionWithWalletParams = HexString & {
prevtxs?: PrevTx[];
sighashtype?: SigHashType;
};
export type SignRawTransactionWithKeyParams = {
privkeys: string[];
} & SignRawTransactionWithWalletParams;
export type TestmemPoolAcceptParams = {
rawtxs: string[];
maxfeerate?: string | number;
};
export type UtxoUpdatePsbtParams = {
psbt: string;
descriptors?: (string | { desc: string; range?: number | [number, number] })[];
};
export type Label = { label?: string };
export type AddMultiSigAddressParams = CreateMultiSigParams & Label;
export type BumpFeeParams = {
txid: string;
options?: EstimateMode & { replaceable?: boolean } & (
| { confTarget?: number }
| { totalFee?: number }
);
};
export type CreateWalletParams = {
passphrase?: string;
avoid_reuse?: boolean;
wallet_name: string;
disable_private_keys?: boolean;
blank?: boolean;
};
export type GetBalanceParams = {
avoid_reuse?: boolean;
minconf?: number;
include_watchonly?: boolean;
};
export type GetNewAddressParams = { address_type?: AddressType } & Label;
export type GetReceivedByAddressParams = { address: string; minconf?: number };
export type GetReceivedByLabelParams = {
label: string;
minconf?: number;
};
export type GetTransactionParams = TxId & {
include_watchonly?: boolean;
verbose?: boolean;
};
export type ImportAddressParams = {
address: string;
label?: string;
rescan?: boolean;
p2sh?: boolean;
};
export type ImportMultiRequest = {
timestamp: number | 'now';
internal?: boolean;
watchonly?: boolean;
label?: string;
keypool?: boolean;
} & (
| { desc: string; range?: number | [number, number] }
| {
scriptPubKey: { address: string } | string;
redeemscript?: string;
witnessscript?: string;
pubkeys?: string[];
keys?: string[];
}
);
export type ImportMultiParams = {
requests: ImportMultiRequest[];
options?: { rescan?: boolean };
};
export type ImportPrivKeyParams = {
privkey: string;
label?: string;
rescan?: boolean;
};
export type ImportPrunedFundsParams = {
rawtransaction: string;
txoutproof: string;
};
export type ImportPubKeyParams = {
pubkey: string;
label?: string;
rescan?: boolean;
};
export type ListLabelsParams = { purpose: 'receive' | 'send' };
export type ListReceivedByAddressParams = ListReceivedByLabelParams & {
address_filter?: string;
};
export type ListReceivedByLabelParams = {
minconf?: number;
include_empty?: boolean;
include_watchonly?: boolean;
};
export type ListSinceBlockParams = {
blockhash?: string;
target_confirmations?: number;
include_watchonly?: boolean;
include_removed?: boolean;
};
export type ListTransactionsParams = {
label?: string;
count?: number;
skip?: number;
include_watchonly?: boolean;
};
export type ListUnspentParams = {
minconf?: number;
maxconf?: number;
addresses?: string[];
include_unsafe?: boolean;
query_options?: {
minimumAmount?: number | string;
maximumAmount?: number | string;
maximumCount?: number;
minimumSumAmount?: number | string;
};
};
export type LockUnspentParams = {
unlock: boolean;
transactions?: BaseTransactionInput[];
};
export type RescanBlockchainParams = {
start_height?: number;
stop_height?: number;
};
export type BaseSendParams = EstimateMode & {
comment?: string;
replaceable?: boolean;
conf_target?: number;
};
export type SendManyParams = BaseSendParams & {
amounts: { [address: string]: number | string };
subtractfeefrom?: string[];
};
export type SendToAddressParams = BaseSendParams & {
avoid_reuse?: boolean;
address: string;
amount: string | number;
comment_to?: string;
subtractfeefromamount?: boolean;
};
export type SetHDSeedParams = { newkeypool?: boolean; seed?: string };
export type SetLabelParams = { address: string; label: string };
export type SetWalletFlagParams = { flag: string; value?: boolean };
export type SignMessageParams = { address: string; message: string };
export type WalletCreateFundedPsbtParams = BaseCreateTransaction &
BaseFundOptions & { bip32derivs?: boolean };
export type WalletPassphraseParams = { passphrase: string; timeout: number };
export type WalletPassphraseChangeParams = {
oldpassphrase: string;
newpassphrase: string;
};
export type WalletProcessPsbtParams = {
psbt: string;
sign?: boolean;
sighashtype?: SigHashType;
bip32derivs?: boolean;
};
interface JSONRPCError {
code: number;
message: string;
}
interface JSONRPCResult {
result: object | null;
error: JSONRPCError | null;
id: string;
}
interface DefinedUnsuccessfulFetch extends UnsuccessfulFetch {
data: JSONRPCResult;
}
export type GetBestBlockHeaderParams = Verbose;
export type GetDeploymentInfoParams = { blockhash?: string };
export type GetMempoolEntryByIdParams = { wtxid: string };
export type GenerateBlockParams = {
output: string;
transactions?: string[];
submit?: boolean;
};
export type AddPeerAddressParams = {
address: string;
port: number;
tried?: boolean;
};
export type GetNodeAddressesParams = { count?: number };
export type SendMsgToPeerParams = {
peer_id: number;
msg_type: string;
data: string;
};
export type SubmitPackageParams = {
package: string[];
maxfeerate?: number | string;
maxburnamount?: number | string;
};
export type GetIndexInfoParams = { index_name?: string };
export type VerifyChainLockParams = {
blockhash: string;
signature: string;
height: number;
};
export type CreateWalletDescriptorParams = {
type: 'wpkh' | 'pkh' | 'sh' | 'tr';
internal?: boolean;
hdkey?: string;
};
export type GetHDKeysParams = {
active_only?: boolean;
private?: boolean;
};
export type ImportDescriptorRequest = {
desc: string;
timestamp: number | 'now';
active?: boolean;
range?: number | [number, number];
next_index?: number;
internal?: boolean;
label?: string;
};
export type ImportDescriptorsParams = {
requests: ImportDescriptorRequest[];
};
export type ListDescriptorsParams = { private?: boolean };
export type MigrateWalletParams = {
wallet_name?: string;
passphrase?: string;
};
export type PsbtBumpFeeParams = {
txid: string;
options?: EstimateMode & {
conf_target?: number;
fee_rate?: number | string;
replaceable?: boolean;
outputs?: Array<{ [address: string]: number | string }>;
reduce_output?: number;
};
};
export type SendParams = {
outputs: Array<{ [address: string]: number | string }>;
conf_target?: number;
estimate_mode?: 'UNSET' | 'ECONOMICAL' | 'CONSERVATIVE';
fee_rate?: number | string;
options?: {
add_inputs?: boolean;
include_unsafe?: boolean;
add_to_wallet?: boolean;
change_address?: string;
change_position?: number;
change_type?: string;
fee_rate?: number | string;
include_watching?: boolean;
inputs?: Array<{ txid: string; vout: number; weight?: number }>;
lock_unspents?: boolean;
locktime?: number;
max_tx_weight?: number;
psbt?: boolean;
subtract_fee_from_outputs?: number[];
conf_target?: number;
replaceable?: boolean;
};
};
export type SendAllParams = {
recipients: Array<{ [address: string]: number | string }> | string[];
conf_target?: number;
estimate_mode?: 'UNSET' | 'ECONOMICAL' | 'CONSERVATIVE';
fee_rate?: number | string;
options?: {
add_to_wallet?: boolean;
fee_rate?: number | string;
include_watching?: boolean;
inputs?: Array<{ txid: string; vout: number; weight?: number }>;
lock_unspents?: boolean;
locktime?: number;
max_tx_weight?: number;
minconf?: number;
maxconf?: number;
psbt?: boolean;
send_max?: boolean;
conf_target?: number;
replaceable?: boolean;
};
};
export type SimulateRawTransactionParams = {
rawtxs?: string[];
options?: {
include_watchonly?: boolean;
};
};
export type UpgradeWalletParams = { version?: number };
const voidMethods = [
'invalidateblock',
'reconsiderblock',
'preciousblock',
'abandontransaction',
'importprivkey',
'savemempool',
'walletlock',
'walletpassphrase',
'clearbanned',
'ping',
'setban',
];
export class RPCClient extends RESTClient {
wallet?: string;
fullResponse?: boolean;
constructor({ user = '', pass, wallet, fullResponse, ...options }: RPCIniOptions) {
super({ ...options, auth: { user, pass } });
this.fullResponse = !!fullResponse;
this.wallet = typeof wallet === 'string' ? wallet : undefined;
}
batch(body: JSONRPC | JSONRPC[], uri = '/'): Promise<JSONRPCResult> {
const request: IFetchOptions = {
//headers: {
// 'Content-Type': 'application/json',
//},
body: JSON.stringify(body),
};
return super.post(uri, request);
}
async rpc<T = unknown>(method: string, params = {}, wallet?: string): Promise<T> {
const uri = typeof wallet === 'undefined' ? '/' : 'wallet/' + wallet;
const body = { method, params, jsonrpc: '1.0', id: 'rpc-bitcoin' };
try {
const response = await this.batch(body, uri);
if (response.error && response.result === null) {
throw this.fullResponse ? response.error : new Error(response.error.message);
}
if (!response.result && !voidMethods.includes(method)) {
throw new Error('No result');
}
return (this.fullResponse ? response : response.result) as T;
} catch (error) {
const err: DefinedUnsuccessfulFetch = error as DefinedUnsuccessfulFetch;
if (err && err.data && err.data.error && err.data.result === null) {
throw this.fullResponse ? err.data : new Error(err.data.error.message);
}
throw error;
}
}
/**
* @description Returns the hash of the best (tip) block in the longest blockchain.
*/
getbestblockhash() {
return this.rpc('getbestblockhash');
}
/**
* @description If verbosity is 0, returns a string that is serialized, hex-encoded data for block 'hash'. If verbosity is 1, returns an Object with information about block <hash>. If verbosity is 2, returns an Object with information about block <hash> and information about each transaction.
*/
getblock({ blockhash, verbosity = 1 }: GetBlockParams) {
return this.rpc('getblock', { blockhash, verbosity });
}
async getblockBatch(blockhashes: string[], verbosity = 1) {
try {
const body = blockhashes.map((blockhash) => {
return {
method: 'getblock',
params: {
blockhash,
verbosity,
},
jsonrpc: '1.0',
id: 'rpc-bitcoin',
};
});
const response = await this.batch(body, '/');
const finalResponse: (BlockData | null)[] = [];
for (const res of response as unknown as JSONRPCResult[]) {
if (res.result) {
finalResponse.push(res.result as unknown as BlockData);
} else {
finalResponse.push(null);
}
}
return finalResponse;
} catch (error) {
const err: DefinedUnsuccessfulFetch = error as DefinedUnsuccessfulFetch;
if (err && err.data && err.data.error && err.data.result === null) {
throw this.fullResponse ? err.data : new Error(err.data.error.message);
}
throw error;
}
}
/**
* @description Returns an object containing various state info regarding blockchain processing.
*/
getblockchaininfo() {
return this.rpc('getblockchaininfo');
}
/**
* @description Returns the number of blocks in the longest blockchain.
*/
getblockcount() {
return this.rpc('getblockcount');
}
/**
* @description Retrieve a BIP 157 content filter for a particular block.
*/
getblockfilter(options: GetBlockFilterParams) {
return this.rpc('getblockfilter', options);
}
/**
* @description Returns hash of block in best-block-chain at height provided.
*/
getblockhash({ height }: Height) {
return this.rpc('getblockhash', { height });
}
/**
* @description Returns hash of block in best-block-chain at height provided.
*/
async getblockhashes(heights: Height, count: number) {
try {
const response = await this.batch(
Array.from({ length: count }, (_, i) => {
return {
method: 'getblockhash',
params: { height: heights.height + i },
jsonrpc: '1.0',
id: 'rpc-bitcoin',
};
}),
'/',
);
const finalResponse: (string | null)[] = [];
for (const res of response as unknown as JSONRPCResult[]) {
if (res.result) {
finalResponse.push(res.result as unknown as string);
} else {
finalResponse.push(null);
}
}
return finalResponse;
} catch (error) {
const err: DefinedUnsuccessfulFetch = error as DefinedUnsuccessfulFetch;
if (err && err.data && err.data.error && err.data.result === null) {
throw this.fullResponse ? err.data : new Error(err.data.error.message);
}
throw error;
}
}
/**
* @description If verbose is `false`, returns a string that is serialized, hex-encoded data for blockheader 'hash'. If verbose is `true`, returns an Object with information about blockheader <hash>.
*/
getblockheader({ blockhash, verbose = true }: GetBlockHeaderParams) {
return this.rpc('getblockheader', { blockhash, verbose });
}
/**
* @description Compute per block statistics for a given window.
*/
getblockstats({ hash_or_height, stats = [] }: GetBlockStatsParams) {
return this.rpc('getblockstats', { hash_or_height, stats });
}
/**
* @description Return information about all known tips in the block tree, including the main chain as well as orphaned branches.
*/
getchaintips() {
return this.rpc('getchaintips');
}
/**
* @description Compute statistics about the total number and rate of transactions in the chain.
*/
getchaintxstats({ nblocks, blockhash }: GetChainTxStatsParams) {
return this.rpc('getchaintxstats', { nblocks, blockhash });
}
/**
* @description Returns the proof-of-work difficulty as a multiple of the minimum difficulty.
*/
getdifficulty() {
return this.rpc('getdifficulty');
}
/**
* @description If txid is in the mempool, returns all in-mempool ancestors.
*/
getmempoolancestors({ txid, verbose = false }: GetMemPoolParams) {
return this.rpc('getmempoolancestors', { txid, verbose });
}
/**
* @description If txid is in the mempool, returns all in-mempool descendants.
*/
getmempooldescendants({ txid, verbose = false }: GetMemPoolParams) {
return this.rpc('getmempooldescendants', { txid, verbose });
}
/**
* @description Returns mempool data for given transaction
*/
getmempoolentry({ txid }: TxId) {
return this.rpc('getmempoolentry', { txid });
}
/**
* @description Returns details on the active state of the TX memory pool.
*/
getmempoolinfo() {
return this.rpc('getmempoolinfo');
}
/**
* @description Returns all transaction ids in memory pool as a json array of string transaction ids.
*/
getrawmempool({ verbose = false }: Verbose = {}) {
return this.rpc('getrawmempool', { verbose });
}
/**
* @description Returns details about an unspent transaction output.
*/
gettxout({ txid, n, include_mempool = true }: GetTxOutParams) {
return this.rpc('gettxout', { txid, n, include_mempool });
}
/**
* @description Returns a hex-encoded proof that "txid" was included in a block.
*/
gettxoutproof({ txids, blockhash }: GetTxOutProofParams) {
return this.rpc('gettxoutproof', { txids, blockhash });
}
/**
* @description Returns statistics about the unspent transaction output set.
*/
gettxoutsetinfo() {
return this.rpc('gettxoutsetinfo');
}
/**
* @description Treats a block as if it were received before others with the same work.
*/
preciousblock({ blockhash }: Blockhash) {
return this.rpc('preciousblock', { blockhash });
}
/**
* @description Prune the blockchain.
*/
pruneblockchain({ height }: Height) {
return this.rpc('pruneblockchain', { height });
}
/**
* @description Dumps the mempool to disk. It will fail until the previous dump is fully loaded.
*/
savemempool() {
return this.rpc('savemempool');
}
/**
* @description Scans the unspent transaction output set for entries that match certain output descriptors.
*/
scantxoutset({ action, scanobjects }: ScanTxOutSetParams) {
return this.rpc('scantxoutset', { action, scanobjects });
}
/**
* @description Verifies blockchain database.
*/
verifychain({ checklevel = 3, nblocks = 6 } = {}) {
return this.rpc('verifychain', { checklevel, nblocks });
}
/**
* @description Verifies that a proof points to a transaction in a block, returning the transaction it commits to and throwing an RPC error if the block is not in our best chain.
*/
verifytxoutproof({ proof }: { proof: string }) {
return this.rpc('verifytxoutproof', { proof });
}
/**
* @description Returns an object containing information about memory usage.
*/
getmemoryinfo({ mode = 'stats' } = {}) {
return this.rpc('getmemoryinfo', { mode });
}
/**
* @description Returns details of the RPC server.
*/
getrpcinfo() {
return this.rpc('getrpcinfo');
}
/**
* @description List all commands, or get help for a specified command.
*/
help({ command }: HelpParams = {}) {
return this.rpc('help', { command });
}
/**
* @description Gets and sets the logging configuration.
*/
logging({ include, exclude }: LoggingParams = {}) {
return this.rpc('logging', { include, exclude });
}
/**
* @description Stop Bitcoin server.
*/
stop() {
return this.rpc('stop');
}
/**
* @description Returns the total uptime of the server.
*/
uptime() {
return this.rpc('uptime');
}
/**
* @description Returns the header of the best (tip) block in the longest blockchain.
*/
getbestblockheader({ verbose = true }: GetBestBlockHeaderParams = {}) {
return this.rpc('getbestblockheader', { verbose });
}
/**
* @description Returns an object containing various state info regarding deployments of consensus changes.
*/
getdeploymentinfo({ blockhash }: GetDeploymentInfoParams = {}) {
return this.rpc('getdeploymentinfo', { blockhash });
}
/**
* @description Returns mempool data for given transaction by wtxid
*/
getmempoolentrybyid({ wtxid }: GetMempoolEntryByIdParams) {
return this.rpc('getmempoolentrybyid', { wtxid });
}
/**
* @description Mine up to nblocks blocks immediately (before the RPC call returns) to an address in the wallet.
* @deprecated Use generatetoaddress instead
*/
generate({ nblocks, maxtries }: GenerateParams, wallet?: string) {
return this.rpc('generate', { nblocks, maxtries }, wallet || this.wallet);
}
/**
* @description Mine a block with a set of ordered transactions immediately to a specified address.
*/
generateblock({ output, transactions = [], submit = true }: GenerateBlockParams) {
return this.rpc('generateblock', { output, transactions, submit });
}
/**
* @description Add the address of a potential peer to the address manager.
*/
addpeeraddress({ address, port, tried = false }: AddPeerAddressParams) {
return this.rpc('addpeeraddress', { address, port, tried });
}
/**
* @description Send a p2p message to a peer specified by id.
*/
sendmsgtopeer({ peer_id, msg_type, data }: SendMsgToPeerParams) {
return this.rpc('sendmsgtopeer', { peer_id, msg_type, data });
}
/**
* @description Submit a package of raw transactions to local node.
*/
submitpackage({ package: pkg, maxfeerate, maxburnamount }: SubmitPackageParams) {
return this.rpc('submitpackage', { package: pkg, maxfeerate, maxburnamount });
}
/**
* @description Mine blocks immediately to a specified address (before the RPC call returns)
*/
generatetoaddress(options: GenerateToAddressParams, wallet?: string) {
return this.rpc('generatetoaddress', options, wallet || this.wallet);
}
/**
* @description Returns the status of one or all available indices.
*/
getindexinfo({ index_name }: GetIndexInfoParams = {}) {
return this.rpc('getindexinfo', { index_name });
}
/**
* @description Verifies that a ChainLock is valid for the block.
*/
verifychainlock({ blockhash, signature, height }: VerifyChainLockParams) {
return this.rpc('verifychainlock', { blockhash, signature, height });
}
/**
* @description Create a new descriptor for the wallet.
*/
createwalletdescriptor(options: CreateWalletDescriptorParams, wallet?: string) {
return this.rpc('createwalletdescriptor', options, wallet || this.wallet);
}
/**
* @description List all BIP 32 HD keys in the wallet.
*/
gethdkeys(options: GetHDKeysParams = {}, wallet?: string) {
return this.rpc('gethdkeys', options, wallet || this.wallet);
}
/**
* @description Import descriptors to the wallet.
*/
importdescriptors({ requests }: ImportDescriptorsParams, wallet?: string) {
return this.rpc('importdescriptors', { requests }, wallet || this.wallet);
}
/**
* @description List descriptors imported into a descriptor-enabled wallet.
*/
listdescriptors({ private: priv = false }: ListDescriptorsParams = {}, wallet?: string) {
return this.rpc('listdescriptors', { private: priv }, wallet || this.wallet);
}
/**
* @description Migrate a legacy wallet to a descriptor wallet.
*/
migratewallet({ wallet_name, passphrase }: MigrateWalletParams = {}) {
return this.rpc('migratewallet', { wallet_name, passphrase });
}
/**
* @description Entirely clears and refills the keypool.
*/
newkeypool(wallet?: string) {
return this.rpc('newkeypool', undefined, wallet || this.wallet);
}
/**
* @description Bumps the fee of an opt-in-RBF transaction, replacing it with a new transaction.
*/
psbtbumpfee(options: PsbtBumpFeeParams, wallet?: string) {
return this.rpc('psbtbumpfee', options, wallet || this.wallet);
}
/**
* @description Send a transaction with advanced options.
*/
send({ outputs, conf_target, estimate_mode, fee_rate, options }: SendParams, wallet?: string) {
return this.rpc(
'send',
{ outputs, conf_target, estimate_mode, fee_rate, options },
wallet || this.wallet,
);
}
/**
* @description Send all outputs from the wallet.
*/
sendall(
{ recipients, conf_target, estimate_mode, fee_rate, options }: SendAllParams,
wallet?: string,
) {
return this.rpc(
'sendall',
{ recipients, conf_target, estimate_mode, fee_rate, options },
wallet || this.wallet,
);
}
/**
* @description Simulate raw transactions.
*/
simulaterawtransaction(
{ rawtxs = [], options = {} }: SimulateRawTransactionParams = {},
wallet?: string,
) {
return this.rpc('simulaterawtransaction', { rawtxs, options }, wallet || this.wallet);
}
/**
* @description Upgrade the wallet to a newer version.
*/
upgradewallet({ version }: UpgradeWalletParams = {}, wallet?: string) {
return this.rpc('upgradewallet', { version }, wallet || this.wallet);
}
/**
* @description It returns data needed to construct a block to work on.
*/
getblocktemplate(options: GetBlockTemplateParams) {
return this.rpc('getblocktemplate', options);
}
/**
* @description Returns a json object containing mining-related information.
*/
getmininginfo() {
return this.rpc('getmininginfo');
}
/**
* @description Returns the estimated network hashes per second based on the last `n` blocks.
*/
getnetworkhashps(options = {}) {
return this.rpc('getnetworkhashps', options);
}
/**
* @description Accepts the transaction into mined blocks at a higher (or lower) priority
*/
prioritisetransaction(options: PrioritiseTransactionParams) {
return this.rpc('prioritisetransaction', options);
}
/**
* @description Attempts to submit new block to network.
*/
submitblock(options: HexData) {
return this.rpc('submitblock', options);
}
/**
* @description Decode the given hexdata as a header and submit it as a candidate chain tip if valid.
*/
submitheader(options: HexData) {
return this.rpc('submitheader', options);
}
/**
* @description Attempts to add or remove a node from the addnode list.
*/
addnode(options: AddNodeParams) {
return this.rpc('addnode', options);
}
/**
* @description Clear all banned IPs.
*/
clearbanned() {
return this.rpc('clearbanned');
}
/**
* @description Immediately disconnects from the specified peer node.
*/
disconnectnode(params: DisconnectNodeParams) {
if ('address' in params) {
return this.rpc('disconnectnode', { address: params.address });
}
return this.rpc('disconnectnode', { nodeid: params.nodeid });
}
/**
* @description Returns information about the given added node, or all added nodes
*/
getaddednodeinfo(options: { node?: string } = {}) {
return this.rpc('getaddednodeinfo', options);
}
/**
* @description Returns the number of connections to other nodes.
*/
getconnectioncount() {
return this.rpc('getconnectioncount');
}
/**
* @description Returns information about network traffic, including bytes in, bytes out, and current time.
*/
getnettotals() {
return this.rpc('getnettotals');
}
/**
* @description Returns an object containing various state info regarding P2P networking.
*/
getnetworkinfo() {
return this.rpc('getnetworkinfo');
}
/**
* @description Return known addresses which can potentially be used to find new nodes in the network
*/
getnodeaddresses({ count }: GetNodeAddressesParams = {}) {
return this.rpc('getnodeaddresses', { count });
}
/**
* @description Returns data about each connected network node as a json array of objects.
*/
getpeerinfo() {
return this.rpc('getpeerinfo');
}
/**
* @description List all banned IPs/Subnets.
*/
listbanned() {
return this.rpc('listbanned');
}
/**
* @description Requests that a ping be sent to all other nodes, to measure ping time.
*/
ping() {
return this.rpc('ping');
}
/**
* @description Attempts to add or remove an IP/Subnet from the banned list
*/
setban(options: SetBanParams) {
return this.rpc('setban', options);
}
/**
* @description Disable/enable all p2p network activity.
*/
setnetworkactive(options: { state: boolean }) {
return this.rpc('setnetworkactive', options);
}
/**
* @description Analyzes and provides information about the current status of a PSBT and its inputs
*/
analyzepsbt(options: { psbt: string }) {
return this.rpc('analyzepsbt', options);
}
/**
* @description Combine multiple partially signed Bitcoin transactions into one transaction.
*/
combinepsbt(options: { txs: string[] }) {
return this.rpc('combinepsbt', options);
}
/**
* @description Combine multiple partially signed transactions into one transaction.
*/
combinerawtransaction(options: { txs: string[] }) {
return this.rpc('combinerawtransaction', options);
}
/**
* @description Converts a network serialized transaction to a PSBT.
*/
converttopsbt(options: ConvertToPsbtParams) {
return this.rpc('converttopsbt', options);
}
/**
* @description Creates a transaction in the Partially Signed Transaction format.
*/
createpsbt(options: CreateTransactionParams) {
return this.rpc('createpsbt', options);
}
/**
* @description Create a transaction spending the given inputs and creating new outputs.
*/
createrawtransaction(options: CreateTransactionParams) {
return this.rpc('createrawtransaction', options);
}
/**
* @description Return a JSON object representing the serialized, base64-encoded partially signed Bitcoin transaction.
*/
decodepsbt(options: { psbt: string }) {
return this.rpc('decodepsbt', options);
}
/**
* @description Return a JSON object representing the serialized, hex-encoded transaction.
*/
decoderawtransaction(options: DecodeRawTransactionParams) {
return this.rpc('decoderawtransaction', options);
}
/**
* @description Decode a hex-encoded script.
*/
decodescript(options: HexString) {
return this.rpc('decodescript', options);
}
/**
* @description Finalize the inputs of a PSBT.
*/
finalizepsbt(options: FinalizePsbtParams) {
return this.rpc('finalizepsbt', options);
}
/**
* @description Add inputs to a transaction until it has enough in value to meet its out value.
*/
fundrawtransaction(options: FundRawTransactionParams, wallet?: string) {
return this.rpc('fundrawtransaction', options, wallet || this.wallet);
}
/**
* @description Return the raw transaction data.
*/
getrawtransaction(options: GetRawTransactionParams) {
return this.rpc('getrawtransaction', options);
}
async getrawtransactionBatch<V extends BitcoinVerbosity>(txids: string[], verbose = true) {
try {
const body = txids.map((txid) => {
return {
method: 'getrawtransaction',
params: {
txid,
verbose,
},
jsonrpc: '1.0',
id: 'rpc-bitcoin',
};
});
const response = await this.batch(body, '/');
const finalResponse: (RawTransaction<V> | null)[] = [];
for (const res of response as unknown as JSONRPCResult[]) {
if (res.result) {
finalResponse.push(res.result as unknown as RawTransaction<V>);
} else {
finalResponse.push(null);
}
}
return finalResponse;
} catch (error) {
const err: DefinedUnsuccessfulFetch = error as DefinedUnsuccessfulFetch;
if (err && err.data && err.data.error && err.data.result === null) {
throw this.fullResponse ? err.data : new Error(err.data.error.message);
}
throw error;
}
}
/**
* @description Joins multiple distinct PSBTs with different inputs and outputs into one PSBT with inputs and outputs from all of the PSBTs.
*/
joinpsbts(options: { txs: string[] }) {
return this.rpc('joinpsbts', options);
}
/**
* @description Submits raw transaction (serialized, hex-encoded) to local node and network.
*/
sendrawtransaction(options: SendRawTransactionParams) {
return this.rpc('sendrawtransaction', options);
}
/**
* @description Sign inputs for raw transaction
*/
signrawtransactionwithkey(options: SignRawTransactionWithKeyParams) {
return this.rpc('signrawtransactionwithkey', options);
}
/**
* @description Returns result of mempool acceptance tests indicating if raw transaction (serialized, hex-encoded) would be accepted by mempool.
*/
testmempoolaccept(options: TestmemPoolAcceptParams) {
return this.rpc('testmempoolaccept', options);
}
/**
* @description Updates a PSBT with witness UTXOs retrieved from the UTXO set or the mempool.
*/
utxoupdatepsbt(options: UtxoUpdatePsbtParams) {
return this.rpc('utxoupdatepsbt', options);
}
/**
* @description Creates a multi-signature address with n signature of m keys required.
*/
createmultisig(options: CreateMultiSigParams) {
return this.rpc('createmultisig', options);
}
/**
* @description Derives one or more addresses corresponding to an output descriptor.
*/
deriveaddresses({ descriptor, range }: DeriveAddressesParams) {
return this.rpc('deriveaddresses', { descriptor, range });
}
/**
* @description Estimates the approximate fee per kilobyte needed for a transaction to begin confirmation within `conf_target` blocks if possible and return the number of blocks for which the estimate is valid.
*/
estimatesmartfee(options: EstimateSmartFeeParams) {
return this.rpc('estimatesmartfee', options);
}
/**
* @description Analyses a descriptor.
*/
getdescriptorinfo(options: { descriptor: string }) {
return this.rpc('getdescriptorinfo', options);
}
/**
* @description Sign a message with the private key of an address.
*/
signmessagewithprivkey(options: SignMessageWithPrivKeyParams) {
return this.rpc('signmessagewithprivkey', options);
}
/**
* @description Return information about the given bitcoin address.
*/
validateaddress(options: { address: string }) {
return this.rpc('validateaddress', options);
}
/**
* @description Verify a signed message
*/
verifymessage(options: VerifyMessageParams) {
return this.rpc('verifymessage', options);
}
/**
* @description Mark in-wallet transaction `txid` as abandoned
*/
abandontransaction(options: TxId, wallet?: string) {
return this.rpc('abandontransaction', options, wallet || this.wallet);
}
/**
* @description Stops current wallet rescan triggered by an RPC call
*/
abortrescan(wallet?: string) {
return this.rpc('abortrescan', undefined, wallet || this.wallet);
}
/**
* @description Add a nrequired-to-sign multisignature address to the wallet.
*/
addmultisigaddress(options: AddMultiSigAddressParams, wallet?: string) {
return this.rpc('addmultisigaddress', options, wallet || this.wallet);
}
/**
* @description Safely copies current wallet file to destination.
*/
backupwallet(options: { destination: string }, wallet?: string) {
return this.rpc('backupwallet', options, wallet || this.wallet);
}
/**
* @description Bumps the fee of an opt-in-RBF transaction T, replacing it with a new transaction B.
*/
bumpfee(options: BumpFeeParams, wallet?: string) {
return this.rpc('bumpfee', options, wallet || this.wallet);
}
/**
* @description Creates and loads a new wallet.
*/
createwallet(options: CreateWalletParams) {
return this.rpc('createwallet', options);
}
/**
* @description Reveals the private key corresponding to 'address'.
*/
dumpprivkey(options: { address: string }, wallet?: string) {
return this.rpc('dumpprivkey', options, wallet || this.wallet);
}
/**
* @description Dumps all wallet keys in a human-readable format to a server-side file.
*/
dumpwallet(options: { filename: string }, wallet?: string) {
return this.rpc('dumpwallet', options, wallet || this.wallet);
}
/**
* @description Encrypts the wallet with 'passphrase'.
*/
encryptwallet(options: { passphrase: string }, wallet?: string) {
return this.rpc('encryptwallet', options, wallet || this.wallet);
}
/**
* @description Returns the list of addresses assigned the specified label.
*/
getaddressesbylabel(options: { label: string }, wallet?: string) {
return this.rpc('getaddressesbylabel', options, wallet || this.wallet);
}
/**
* @description Return information about the given bitcoin address.
*/
getaddressinfo(options: { address: string }, wallet?: string) {
return this.rpc('getaddressinfo', options, wallet || this.wallet);
}
/**
* @description Returns the total available balance.
*/
getbalance(options: GetBalanceParams, wallet?: string) {
return this.rpc('getbalance', options, wallet || this.wallet);
}
/**
* @description Returns all balances in BTC.
*/
getbalances(wallet?: string) {
return this.rpc('getbalances', undefined, wallet || this.wallet);
}
/**
* @description Returns a new Bitcoin address for receiving payments.
*/
getnewaddress(options: GetNewAddressParams, wallet?: string) {
return this.rpc('getnewaddress', options, wallet || this.wallet);
}
/**
* @description Returns a new Bitcoin address, for receiving change.
*/
getrawchangeaddress(options: { address_type?: AddressType }, wallet?: string) {
return this.rpc('getrawchangeaddress', options, wallet || this.wallet);
}
/**
* @description Returns the total amount received by the given address in transactions with at least minconf confirmations.
*/
getreceivedbyaddress(options: GetReceivedByAddressParams, wallet?: string) {
return this.rpc('getreceivedbyaddress', options, wallet || this.wallet);
}
/**
* @description Returns the total amount received by addresses with `label` in transactions with at least `minconf` confirmations.
*/
getreceivedbylabel(options: GetReceivedByLabelParams, wallet?: string) {
return this.rpc('getreceivedbylabel', options, wallet || this.wallet);
}
/**
* @description Get detailed information about in-wallet transaction `txid`
*/
gettransaction(options: GetTransactionParams, wallet?: string) {
return this.rpc('gettransaction', options, wallet || this.wallet);
}
/**
* @description Returns the server's total unconfirmed balance
*/
getunconfirmedbalance(wallet?: string) {
return this.rpc('getunconfirmedbalance', undefined, wallet || this.wallet);
}
/**
* @description Returns an object containing various wallet state info.
*/
getwalletinfo(wallet?: string) {
return this.rpc('getwalletinfo', undefined, wallet || this.wallet);
}
/**
* @description Permanently marks a block as invalid, as if it violated a consensus rule.
* This will mark the block and all of its descendants as invalid.
*/
invalidateblock({ blockhash }: Blockhash) {
return this.rpc('invalidateblock', { blockhash });
}
/**
* @description Removes invalidity status of a block and its descendants, reconsider them for activation.
* This can be used to undo the effects of invalidateblock.
*/
reconsiderblock({ blockhash }: Blockhash) {
return this.rpc('reconsiderblock', { blockhash });
}
/**
* @description Adds an address or script (in hex) that can be watched as if it were in your wallet but cannot be used to spend.
*/
importaddress(options: ImportAddressParams, wallet?: string) {
return this.rpc('importaddress', options, wallet || this.wallet);
}
/**
* @description Import addresses/scripts (with private or public keys, redeem script (P2SH)), optionally rescanning the blockchain from the earliest creation time of the imported scripts.
*/
importmulti(options: ImportMultiParams, wallet?: string) {
return this.rpc('importmulti', options, wallet || this.wallet);
}
/**
* @description Adds a private key (as returned by `dumpprivkey`) to your wallet.
*/
importprivkey(options: ImportPrivKeyParams, wallet?: string) {
return this.rpc('importprivkey', options, wallet || this.wallet);
}
/**
* @description Imports funds without rescan. Corresponding address or script must previously be included in wallet.
*/
importprunedfunds(options: ImportPrunedFundsParams, wallet?: string) {
return this.rpc('importprunedfunds', options, wallet || this.wallet);
}
/**
* @description Adds a public key (in hex) that can be watched as if it were in your wallet but cannot be used to spend.
*/
importpubkey(options: ImportPubKeyParams, wallet?: string) {
return this.rpc('importpubkey', options, wallet || this.wallet);
}
/**
* @description Imports keys from a wallet dump file (see `dumpwallet`).
*/
importwallet(options: { filename: string }, wallet?: string) {
return this.rpc('importwallet', options, wallet || this.wallet);
}
/**
* @description Fills the keypool.
*/
keypoolrefill(options: { newsize?: number }, wallet?: string) {
return this.rpc('keypoolrefill', options, wallet || this.wallet);
}
/**
* @description Lists groups of addresses which have had their common ownership made public by common use as inputs or as the resulting change in past transactions
*/
listaddressgroupings(wallet?: string) {
return this.rpc('listaddressgroupings', undefined, wallet || this.wallet);
}
/**
* @description Returns the list of all labels, or labels that are assigned to addresses with a specific purpose.
*/
listlabels(options: ListLabelsParams, wallet?: string) {
return this.rpc('listlabels', options, wallet || this.wallet);
}
/**
* @description Returns list of temporarily unspendable outputs.
*/
listlockunspent(wallet?: string) {
return this.rpc('listlockunspent', undefined, wallet || this.wallet);
}
/**
* @description List balances by receiving address.
*/
listreceivedbyaddress(options: ListReceivedByAddressParams, wallet?: string) {
return this.rpc('listreceivedbyaddress', options, wallet || this.wallet);
}
/**
* @description List received transactions by label.
*/
listreceivedbylabel(options: ListReceivedByLabelParams, wallet?: string) {
return this.rpc('listreceivedbylabel', options, wallet || this.wallet);
}
/**
* @description Get all transactions in blocks since block `blockhash`, or all transactions if omitted.
*/
listsinceblock(options: ListSinceBlockParams, wallet?: string) {
return this.rpc('listsinceblock', options, wallet || this.wallet);
}
/**
* @description Returns up to `count` most recent transactions skipping the first `skip` transactions.
*/
listtransactions(options: ListTransactionsParams, wallet?: string) {
return this.rpc('listtransactions', options, wallet || this.wallet);
}
/**
* @description Returns array of unspent transaction outputs with between `minconf` and `maxconf` (inclusive) confirmations.
*/
listunsp