@did-btcr2/bitcoin 0.3.4 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/client/http.js +9 -0
- package/dist/cjs/client/http.js.map +1 -0
- package/dist/cjs/client/rest/address.js +20 -28
- package/dist/cjs/client/rest/address.js.map +1 -1
- package/dist/cjs/client/rest/block.js +23 -22
- package/dist/cjs/client/rest/block.js.map +1 -1
- package/dist/cjs/client/rest/index.js +31 -84
- package/dist/cjs/client/rest/index.js.map +1 -1
- package/dist/cjs/client/rest/protocol.js +129 -0
- package/dist/cjs/client/rest/protocol.js.map +1 -0
- package/dist/cjs/client/rest/transaction.js +19 -21
- package/dist/cjs/client/rest/transaction.js.map +1 -1
- package/dist/cjs/client/rpc/index.js +79 -337
- package/dist/cjs/client/rpc/index.js.map +1 -1
- package/dist/cjs/client/rpc/interface.js +1 -6
- package/dist/cjs/client/rpc/interface.js.map +1 -1
- package/dist/cjs/client/rpc/json-rpc.js +40 -63
- package/dist/cjs/client/rpc/json-rpc.js.map +1 -1
- package/dist/cjs/client/rpc/protocol.js +134 -0
- package/dist/cjs/client/rpc/protocol.js.map +1 -0
- package/dist/cjs/connection.js +104 -0
- package/dist/cjs/connection.js.map +1 -0
- package/dist/cjs/constants.js +16 -5
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/index.js +21 -13
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types.js +5 -55
- package/dist/cjs/types.js.map +1 -1
- package/dist/esm/client/http.js +9 -0
- package/dist/esm/client/http.js.map +1 -0
- package/dist/esm/client/rest/address.js +20 -28
- package/dist/esm/client/rest/address.js.map +1 -1
- package/dist/esm/client/rest/block.js +23 -22
- package/dist/esm/client/rest/block.js.map +1 -1
- package/dist/esm/client/rest/index.js +31 -84
- package/dist/esm/client/rest/index.js.map +1 -1
- package/dist/esm/client/rest/protocol.js +129 -0
- package/dist/esm/client/rest/protocol.js.map +1 -0
- package/dist/esm/client/rest/transaction.js +19 -21
- package/dist/esm/client/rest/transaction.js.map +1 -1
- package/dist/esm/client/rpc/index.js +79 -337
- package/dist/esm/client/rpc/index.js.map +1 -1
- package/dist/esm/client/rpc/interface.js +1 -6
- package/dist/esm/client/rpc/interface.js.map +1 -1
- package/dist/esm/client/rpc/json-rpc.js +40 -63
- package/dist/esm/client/rpc/json-rpc.js.map +1 -1
- package/dist/esm/client/rpc/protocol.js +134 -0
- package/dist/esm/client/rpc/protocol.js.map +1 -0
- package/dist/esm/connection.js +104 -0
- package/dist/esm/connection.js.map +1 -0
- package/dist/esm/constants.js +16 -5
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/index.js +21 -13
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types.js +5 -55
- package/dist/esm/types.js.map +1 -1
- package/dist/types/client/http.d.ts +22 -0
- package/dist/types/client/http.d.ts.map +1 -0
- package/dist/types/client/rest/address.d.ts +17 -19
- package/dist/types/client/rest/address.d.ts.map +1 -1
- package/dist/types/client/rest/block.d.ts +25 -16
- package/dist/types/client/rest/block.d.ts.map +1 -1
- package/dist/types/client/rest/index.d.ts +21 -51
- package/dist/types/client/rest/index.d.ts.map +1 -1
- package/dist/types/client/rest/protocol.d.ts +59 -0
- package/dist/types/client/rest/protocol.d.ts.map +1 -0
- package/dist/types/client/rest/transaction.d.ts +17 -17
- package/dist/types/client/rest/transaction.d.ts.map +1 -1
- package/dist/types/client/rpc/index.d.ts +112 -253
- package/dist/types/client/rpc/index.d.ts.map +1 -1
- package/dist/types/client/rpc/interface.d.ts +42 -6
- package/dist/types/client/rpc/interface.d.ts.map +1 -1
- package/dist/types/client/rpc/json-rpc.d.ts +21 -18
- package/dist/types/client/rpc/json-rpc.d.ts.map +1 -1
- package/dist/types/client/rpc/protocol.d.ts +83 -0
- package/dist/types/client/rpc/protocol.d.ts.map +1 -0
- package/dist/types/client/utils.d.ts +1 -0
- package/dist/types/connection.d.ts +82 -0
- package/dist/types/connection.d.ts.map +1 -0
- package/dist/types/constants.d.ts +17 -5
- package/dist/types/constants.d.ts.map +1 -1
- package/dist/types/errors.d.ts +5 -3
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/index.d.ts +21 -13
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/network.d.ts +1 -0
- package/dist/types/types.d.ts +99 -696
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/client/http.ts +28 -0
- package/src/client/rest/address.ts +24 -30
- package/src/client/rest/block.ts +29 -26
- package/src/client/rest/index.ts +38 -94
- package/src/client/rest/protocol.ts +153 -0
- package/src/client/rest/transaction.ts +23 -23
- package/src/client/rpc/index.ts +146 -379
- package/src/client/rpc/interface.ts +88 -53
- package/src/client/rpc/json-rpc.ts +53 -60
- package/src/client/rpc/protocol.ts +160 -0
- package/src/connection.ts +136 -0
- package/src/constants.ts +17 -5
- package/src/errors.ts +10 -3
- package/src/index.ts +81 -13
- package/src/types.ts +332 -972
- package/dist/cjs/bitcoin.js +0 -105
- package/dist/cjs/bitcoin.js.map +0 -1
- package/dist/esm/bitcoin.js +0 -105
- package/dist/esm/bitcoin.js.map +0 -1
- package/dist/types/bitcoin.d.ts +0 -60
- package/dist/types/bitcoin.d.ts.map +0 -1
- package/src/bitcoin.ts +0 -149
package/src/client/rpc/index.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { JSONUtils } from '@did-btcr2/common';
|
|
2
|
-
import { DEFAULT_BITCOIN_NETWORK_CONFIG } from '../../constants.js';
|
|
3
2
|
import { BitcoinRpcError } from '../../errors.js';
|
|
4
3
|
import {
|
|
5
|
-
BatchOption,
|
|
6
|
-
BitcoinRpcClientConfig,
|
|
7
4
|
BlockResponse,
|
|
8
5
|
BlockV0,
|
|
9
6
|
BlockV1,
|
|
@@ -16,505 +13,275 @@ import {
|
|
|
16
13
|
GetBlockParams,
|
|
17
14
|
ListTransactionsParams,
|
|
18
15
|
ListTransactionsResult,
|
|
19
|
-
MethodNameInLowerCase,
|
|
20
16
|
RawTransactionResponse,
|
|
21
17
|
RawTransactionV0,
|
|
22
18
|
RawTransactionV1,
|
|
23
19
|
RawTransactionV2,
|
|
24
|
-
|
|
20
|
+
RpcConfig,
|
|
25
21
|
SignedRawTx,
|
|
26
22
|
UnspentTxInfo,
|
|
27
23
|
VerbosityLevel,
|
|
28
24
|
WalletTransaction
|
|
29
25
|
} from '../../types.js';
|
|
26
|
+
import { HttpExecutor } from '../http.js';
|
|
30
27
|
import { BitcoinRpcClient } from './interface.js';
|
|
31
28
|
import { JsonRpcTransport } from './json-rpc.js';
|
|
32
29
|
|
|
30
|
+
// ── Typed RPC method map ────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Maps Bitcoin Core JSON-RPC method names to their parameter and return types.
|
|
34
|
+
* Used by {@link BitcoinCoreRpcClient.executeRpc} for compile-time safety.
|
|
35
|
+
*/
|
|
36
|
+
export interface RpcMethodMap {
|
|
37
|
+
getbestblockhash: { params: []; result: string };
|
|
38
|
+
getblock: { params: [string, number?]; result: BlockResponse };
|
|
39
|
+
getblockchaininfo: { params: []; result: ChainInfo };
|
|
40
|
+
getblockcount: { params: []; result: number };
|
|
41
|
+
getblockhash: { params: [number]; result: string };
|
|
42
|
+
getbalance: { params: []; result: number };
|
|
43
|
+
getnewaddress: { params: [string?, string?]; result: string };
|
|
44
|
+
gettransaction: { params: [string, boolean?]; result: WalletTransaction };
|
|
45
|
+
getrawtransaction: { params: [string, number?, string?]; result: RawTransactionResponse };
|
|
46
|
+
createrawtransaction: { params: [CreateRawTxInputs[], CreateRawTxOutputs[], number?, boolean?]; result: string };
|
|
47
|
+
signrawtransactionwithwallet: { params: [string]; result: SignedRawTx };
|
|
48
|
+
sendrawtransaction: { params: [string, (number | string)?, (number | string)?]; result: string };
|
|
49
|
+
listtransactions: { params: [string?, number?, number?, boolean?]; result: ListTransactionsResult };
|
|
50
|
+
listunspent: { params: [number?, number?, string[]?, boolean?]; result: UnspentTxInfo[] };
|
|
51
|
+
sendtoaddress: { params: [string, number]; result: string };
|
|
52
|
+
signmessage: { params: [string, string]; result: string };
|
|
53
|
+
verifymessage: { params: [string, string, string]; result: boolean };
|
|
54
|
+
deriveaddresses: { params: [string, number[]?]; result: DerivedAddresses[] };
|
|
55
|
+
generatetoaddress: { params: [number, string]; result: string[] };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Method names that have typed definitions in {@link RpcMethodMap}. */
|
|
59
|
+
export type TypedRpcMethod = keyof RpcMethodMap;
|
|
60
|
+
|
|
61
|
+
// ── Client ──────────────────────────────────────────────────────────
|
|
62
|
+
|
|
33
63
|
/**
|
|
34
|
-
*
|
|
35
|
-
* @class BitcoinCoreRpcClient
|
|
36
|
-
* @type {BitcoinCoreRpcClient}
|
|
64
|
+
* Bitcoin Core RPC client.
|
|
37
65
|
* @implements {BitcoinRpcClient}
|
|
38
66
|
*/
|
|
39
67
|
export class BitcoinCoreRpcClient implements BitcoinRpcClient {
|
|
40
|
-
/**
|
|
41
|
-
* The singleton instance of the BitcoinCoreRpcClient.
|
|
42
|
-
* @type {BitcoinCoreRpcClient}
|
|
43
|
-
* @private
|
|
44
|
-
*/
|
|
45
|
-
static #instance: BitcoinCoreRpcClient;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* The JSON-RPC transport layer.
|
|
49
|
-
* @type {JsonRpcTransport}
|
|
50
|
-
* @private
|
|
51
|
-
*/
|
|
52
68
|
readonly #transport: JsonRpcTransport;
|
|
69
|
+
readonly #config: RpcConfig;
|
|
53
70
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
* @private
|
|
58
|
-
*/
|
|
59
|
-
readonly #config: RpcClientConfig;
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Constructs a new {@link BitcoinCoreRpcClient} instance from a new {@link RpcClient | RpcClient}.
|
|
63
|
-
* @param {RpcClientConfig} config The bitcoin-core client instance.
|
|
64
|
-
* @example
|
|
65
|
-
* ```
|
|
66
|
-
* import BitcoinRpcClient from '@did-btcr2/method';
|
|
67
|
-
* const bob = BitcoinRpcClient.connect(); // To use default polar config, pass no args. Polar must run locally.
|
|
68
|
-
* ```
|
|
69
|
-
*/
|
|
70
|
-
constructor(config: RpcClientConfig) {
|
|
71
|
-
this.#config = new BitcoinRpcClientConfig(config);
|
|
72
|
-
this.#transport = new JsonRpcTransport(this.#config);
|
|
71
|
+
constructor(config: RpcConfig, executor?: HttpExecutor) {
|
|
72
|
+
this.#config = config;
|
|
73
|
+
this.#transport = new JsonRpcTransport(config, executor);
|
|
73
74
|
}
|
|
74
75
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
* @returns {BitcoinRpcClient} The encapsulated {@link BitcoinRpcClient} object.
|
|
78
|
-
* @example
|
|
79
|
-
* ```
|
|
80
|
-
* import BitcoinRpcClient from '@did-btcr2/method';
|
|
81
|
-
* const alice = BitcoinRpcClient.connect();
|
|
82
|
-
* const config = alice.config;
|
|
83
|
-
* ```
|
|
84
|
-
*/
|
|
85
|
-
get config(): BitcoinRpcClientConfig {
|
|
86
|
-
const config = this.#config;
|
|
87
|
-
return config;
|
|
76
|
+
get config(): RpcConfig {
|
|
77
|
+
return this.#config;
|
|
88
78
|
}
|
|
89
79
|
|
|
90
|
-
/**
|
|
91
|
-
* Get the client for the current BitcoinRpcClient object.
|
|
92
|
-
* @returns {RpcClient} The encapsulated {@link RpcClient} object.
|
|
93
|
-
* @example
|
|
94
|
-
* ```
|
|
95
|
-
* const alice = BitcoinRpcClient.connect();
|
|
96
|
-
* const config = alice.client;
|
|
97
|
-
* ```
|
|
98
|
-
*/
|
|
99
80
|
get client(): JsonRpcTransport {
|
|
100
|
-
|
|
101
|
-
return client;
|
|
81
|
+
return this.#transport;
|
|
102
82
|
}
|
|
103
83
|
|
|
104
84
|
/**
|
|
105
|
-
*
|
|
106
|
-
* The RpcClient returned by this method does not have any named methods.
|
|
107
|
-
* Use this method to create and pass a new RpcClient instance to a BitcoinCoreRpcClient constructor.
|
|
108
|
-
*
|
|
109
|
-
* @param {RpcClientConfig} config The configuration object for the client (optional).
|
|
110
|
-
* @returns {BitcoinCoreRpcClient} A new RpcClient instance.
|
|
111
|
-
* @example
|
|
112
|
-
* ```
|
|
113
|
-
* const options: RpcClientConfig = {
|
|
114
|
-
* host: 'http://localhost:18443',
|
|
115
|
-
* username: 'alice',
|
|
116
|
-
* password: 'alicepass',
|
|
117
|
-
* version: '28.1.0',
|
|
118
|
-
* }
|
|
119
|
-
* const alice = BitcoinCoreRpcClient.initialize(options); // Client config required
|
|
120
|
-
* ```
|
|
85
|
+
* Executes a typed JSON-RPC command on the bitcoind node.
|
|
121
86
|
*/
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Static method connects to a bitcoin node running the bitcoin core daemon (bitcoind).
|
|
130
|
-
* To use default polar config, do not pass a config. See {@link DEFAULT_BITCOIN_NETWORK_CONFIG} for default config.
|
|
131
|
-
* @required A locally running {@link https://github.com/jamaljsr/polar | Polar Lightning} regtest node.
|
|
132
|
-
*
|
|
133
|
-
* @param {?RpcClientConfig} config The configuration object for the client (optional).
|
|
134
|
-
* @returns A new {@link BitcoinRpcClient} instance.
|
|
135
|
-
* @example
|
|
136
|
-
* ```
|
|
137
|
-
* const alice = BitcoinRpcClient.connect();
|
|
138
|
-
* ```
|
|
139
|
-
*/
|
|
140
|
-
public static connect(config?: RpcClientConfig): BitcoinCoreRpcClient {
|
|
141
|
-
return new BitcoinCoreRpcClient(config ?? DEFAULT_BITCOIN_NETWORK_CONFIG.regtest.rpc);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Check if the given error is a JSON-RPC error.
|
|
146
|
-
* @param {unknown} e The error to check.
|
|
147
|
-
* @returns {boolean} True if the error is a JSON-RPC error, false otherwise.
|
|
148
|
-
*/
|
|
149
|
-
public isJsonRpcError(e: unknown): e is Error & { name: 'RpcError'; code?: number } {
|
|
150
|
-
return (
|
|
151
|
-
e instanceof Error &&
|
|
152
|
-
e.name === 'RpcError' &&
|
|
153
|
-
typeof (e as any).code === 'number'
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Executes a JSON-RPC command on the bitcoind node.
|
|
159
|
-
* @param {MethodNameInLowerCase} method The name of the method to call.
|
|
160
|
-
* @param {Array<any>} parameters The parameters to pass to the method.
|
|
161
|
-
* @returns {Promise<T>} A promise resolving to the result of the command.
|
|
162
|
-
*/
|
|
163
|
-
private async executeRpc<T>(method: MethodNameInLowerCase, parameters: Array<any> = []): Promise<T> {
|
|
87
|
+
private async executeRpc<M extends TypedRpcMethod>(
|
|
88
|
+
method: M,
|
|
89
|
+
parameters: RpcMethodMap[M]['params'] = [] as unknown as RpcMethodMap[M]['params']
|
|
90
|
+
): Promise<RpcMethodMap[M]['result']> {
|
|
164
91
|
try {
|
|
165
|
-
const raw = await this.
|
|
92
|
+
const raw = await this.#transport.call(method, parameters as unknown[]);
|
|
166
93
|
const normalized = JSONUtils.isUnprototyped(raw) ? JSONUtils.normalize(raw) : raw;
|
|
167
|
-
|
|
168
|
-
? normalized[normalized.length - 1]
|
|
169
|
-
: normalized;
|
|
170
|
-
return result as T;
|
|
94
|
+
return normalized as RpcMethodMap[M]['result'];
|
|
171
95
|
} catch (err: unknown) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
*
|
|
178
|
-
* Map JSON-RPC error codes to HTTP status codes.
|
|
179
|
-
* @param {number | undefined} code The JSON-RPC error code.
|
|
180
|
-
* @returns {number} The corresponding HTTP status code.
|
|
181
|
-
*
|
|
182
|
-
* | Error type | HTTP code |
|
|
183
|
-
* | -------------------------------| --------------------|
|
|
184
|
-
* | Valid JSON-RPC failure | **400 / 404 / 422** |
|
|
185
|
-
* | JSON-RPC authentication issues | **401 / 403** |
|
|
186
|
-
* | Upstream bitcoind unreachable | **502** |
|
|
187
|
-
* | Upstream timeout | **504** |
|
|
188
|
-
* | Network transient errors | **503** |
|
|
189
|
-
* | Unknown unexpected errors | **500** |
|
|
190
|
-
*/
|
|
191
|
-
private mapRpcCodeToHttp(code?: number): number {
|
|
192
|
-
switch (code) {
|
|
193
|
-
case -32700:
|
|
194
|
-
case -32600:
|
|
195
|
-
case -32602:
|
|
196
|
-
return 400;
|
|
197
|
-
|
|
198
|
-
case -32601:
|
|
199
|
-
return 404;
|
|
200
|
-
|
|
201
|
-
default:
|
|
202
|
-
return 422;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Handle errors that occur while executing commands.
|
|
208
|
-
* @param methods An array of {@link BatchOption} objects.
|
|
209
|
-
* @param error The error that was thrown.
|
|
210
|
-
* @throws Throws a {@link BitcoinRpcError} with the error message.
|
|
211
|
-
*/
|
|
212
|
-
private handleError(err: unknown, method: string, params: any[]): never {
|
|
213
|
-
if (this.isJsonRpcError(err)) {
|
|
96
|
+
if (err instanceof BitcoinRpcError) throw err;
|
|
97
|
+
const cause = err instanceof Error ? err.message : String(err);
|
|
214
98
|
throw new BitcoinRpcError(
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
`
|
|
218
|
-
{ method
|
|
99
|
+
'UNKNOWN_ERROR',
|
|
100
|
+
500,
|
|
101
|
+
`Unknown failure in ${method}: ${cause}`,
|
|
102
|
+
{ method }
|
|
219
103
|
);
|
|
220
104
|
}
|
|
221
|
-
|
|
222
|
-
throw new BitcoinRpcError(
|
|
223
|
-
'UNKNOWN_ERROR',
|
|
224
|
-
500,
|
|
225
|
-
`Unknown failure in ${method}`,
|
|
226
|
-
{ method, params, err }
|
|
227
|
-
);
|
|
228
105
|
}
|
|
229
106
|
|
|
230
107
|
/**
|
|
231
108
|
* Returns the block data associated with a `blockhash` of a valid block.
|
|
232
|
-
* @param {GetBlockParams} params See {@link GetBlockParams} for details.
|
|
233
|
-
* @param {?string} params.blockhash The blockhash of the block to query.
|
|
234
|
-
* @param {?number} params.height The block height of the block to query.
|
|
235
|
-
* @param {?VerbosityLevel} params.verbosity The verbosity level. See {@link VerbosityLevel}.
|
|
236
|
-
* @returns {BlockResponse} A promise resolving to a {@link BlockResponse} formatted depending on `verbosity` level.
|
|
237
|
-
* @throws {BitcoinRpcError} If neither `blockhash` nor `height` is provided.
|
|
238
109
|
*/
|
|
239
110
|
public async getBlock({ blockhash, height, verbosity }: GetBlockParams): Promise<BlockResponse | undefined> {
|
|
240
|
-
|
|
241
|
-
if(!blockhash && height === undefined) {
|
|
111
|
+
if (!blockhash && height === undefined) {
|
|
242
112
|
throw new BitcoinRpcError('INVALID_PARAMS_GET_BLOCK', 400, 'blockhash or height required', { blockhash, height });
|
|
243
113
|
}
|
|
244
114
|
|
|
245
|
-
// If height is provided, get the blockhash
|
|
246
115
|
blockhash ??= await this.getBlockHash(height!);
|
|
247
|
-
if(!blockhash || typeof blockhash !== 'string') {
|
|
116
|
+
if (!blockhash || typeof blockhash !== 'string') {
|
|
248
117
|
return undefined;
|
|
249
118
|
}
|
|
250
|
-
|
|
119
|
+
|
|
251
120
|
const block = await this.executeRpc('getblock', [blockhash, verbosity ?? 3]);
|
|
252
121
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
case
|
|
256
|
-
|
|
257
|
-
case
|
|
258
|
-
|
|
259
|
-
case 2:
|
|
260
|
-
return block as BlockV2;
|
|
261
|
-
case 3:
|
|
262
|
-
return block as BlockV3;
|
|
263
|
-
default:
|
|
264
|
-
return block as BlockV3;
|
|
122
|
+
switch (verbosity) {
|
|
123
|
+
case 0: return block as BlockV0;
|
|
124
|
+
case 1: return block as BlockV1;
|
|
125
|
+
case 2: return block as BlockV2;
|
|
126
|
+
case 3: return block as BlockV3;
|
|
127
|
+
default: return block as BlockV3;
|
|
265
128
|
}
|
|
266
129
|
}
|
|
267
130
|
|
|
268
|
-
/**
|
|
269
|
-
* Returns the blockheight of the most-work fully-validated chain. The genesis block has height 0.
|
|
270
|
-
* @returns {Blockheight} The number of the blockheight with the most-work of the fully-validated chain.
|
|
271
|
-
*/
|
|
131
|
+
/** Returns the blockheight of the most-work fully-validated chain. */
|
|
272
132
|
public async getBlockCount(): Promise<number> {
|
|
273
133
|
return await this.executeRpc('getblockcount');
|
|
274
134
|
}
|
|
275
135
|
|
|
276
|
-
/**
|
|
277
|
-
* Returns the blockhash of the block at the given height in the active chain.
|
|
278
|
-
*/
|
|
136
|
+
/** Returns the blockhash of the block at the given height. */
|
|
279
137
|
public async getBlockHash(height: number): Promise<string> {
|
|
280
138
|
return await this.executeRpc('getblockhash', [height]);
|
|
281
139
|
}
|
|
282
140
|
|
|
283
|
-
/**
|
|
284
|
-
* Returns an object containing various blockchain state info.
|
|
285
|
-
*/
|
|
141
|
+
/** Returns various blockchain state info. */
|
|
286
142
|
public async getBlockchainInfo(): Promise<ChainInfo> {
|
|
287
|
-
return this.executeRpc('getblockchaininfo');
|
|
143
|
+
return await this.executeRpc('getblockchaininfo');
|
|
288
144
|
}
|
|
289
145
|
|
|
290
|
-
/**
|
|
291
|
-
* Sign inputs for raw transaction (serialized, hex-encoded).
|
|
292
|
-
* The second optional argument (may be null) is an array of previous transaction outputs that
|
|
293
|
-
* this transaction depends on but may not yet be in the block chain.
|
|
294
|
-
* Requires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.
|
|
295
|
-
* @param {string} hexstring The hex-encoded transaction to send.
|
|
296
|
-
*/
|
|
146
|
+
/** Sign inputs for raw transaction (serialized, hex-encoded). */
|
|
297
147
|
public async signRawTransaction(hexstring: string): Promise<SignedRawTx> {
|
|
298
|
-
return await this.executeRpc
|
|
148
|
+
return await this.executeRpc('signrawtransactionwithwallet', [hexstring]);
|
|
299
149
|
}
|
|
300
150
|
|
|
301
|
-
/**
|
|
302
|
-
* Submit a raw transaction (serialized, hex-encoded) to local node and network.
|
|
303
|
-
*
|
|
304
|
-
* The transaction will be sent unconditionally to all peers, so using sendrawtransaction
|
|
305
|
-
* for manual rebroadcast may degrade privacy by leaking the transaction's origin, as
|
|
306
|
-
* nodes will normally not rebroadcast non-wallet transactions already in their mempool.
|
|
307
|
-
*
|
|
308
|
-
* @param {string} hexstring The hex-encoded transaction to send.
|
|
309
|
-
* @param {numbner} [maxfeerate] If not passed, default is 0.10.
|
|
310
|
-
* @returns {Promise<string>} A promise resolving to the transaction hash in hex.
|
|
311
|
-
*/
|
|
151
|
+
/** Submit a raw transaction (serialized, hex-encoded) to local node and network. */
|
|
312
152
|
public async sendRawTransaction(
|
|
313
153
|
hexstring: string,
|
|
314
154
|
maxfeerate?: number | string,
|
|
315
155
|
maxBurnAmount?: number | string
|
|
316
156
|
): Promise<string> {
|
|
317
|
-
return await this.executeRpc
|
|
157
|
+
return await this.executeRpc('sendrawtransaction', [hexstring, maxfeerate ?? 0.10, maxBurnAmount ?? 0.00]);
|
|
318
158
|
}
|
|
319
159
|
|
|
320
|
-
/**
|
|
321
|
-
* Combines calls to `signRawTransaction` and `sendRawTransaction`.
|
|
322
|
-
* @param {string} params.hexstring The hex-encoded transaction to send.
|
|
323
|
-
* @returns {Promise<string>} A promise resolving to the transaction hash in hex.
|
|
324
|
-
*/
|
|
160
|
+
/** Signs and sends a raw transaction. */
|
|
325
161
|
public async signAndSendRawTransaction(hexstring: string): Promise<string> {
|
|
326
|
-
const signedRawTx = await this.signRawTransaction(hexstring
|
|
162
|
+
const signedRawTx = await this.signRawTransaction(hexstring);
|
|
163
|
+
if (!signedRawTx.complete) {
|
|
164
|
+
throw new BitcoinRpcError(
|
|
165
|
+
'SIGNING_INCOMPLETE',
|
|
166
|
+
400,
|
|
167
|
+
'Transaction signing incomplete',
|
|
168
|
+
signedRawTx.errors
|
|
169
|
+
);
|
|
170
|
+
}
|
|
327
171
|
return await this.sendRawTransaction(signedRawTx.hex);
|
|
328
172
|
}
|
|
329
173
|
|
|
330
|
-
/**
|
|
331
|
-
* Combines calls to `createRawTransaction`, `signRawTransaction` and `sendRawTransaction`.
|
|
332
|
-
* @param {CreateRawTxInputs[]} inputs The inputs to the transaction (required).
|
|
333
|
-
* @param {CreateRawTxOutputs[]} outputs The outputs of the transaction (required).
|
|
334
|
-
* @returns {Promise<string>} A promise resolving to the transaction hash in hex.
|
|
335
|
-
*/
|
|
174
|
+
/** Creates, signs, and sends a raw transaction. */
|
|
336
175
|
public async createSignSendRawTransaction(inputs: CreateRawTxInputs[], outputs: CreateRawTxOutputs[]): Promise<string> {
|
|
337
176
|
const rawTx = await this.createRawTransaction(inputs, outputs);
|
|
338
177
|
const signedRawTx = await this.signRawTransaction(rawTx);
|
|
339
|
-
|
|
340
|
-
|
|
178
|
+
if (!signedRawTx.complete) {
|
|
179
|
+
throw new BitcoinRpcError(
|
|
180
|
+
'SIGNING_INCOMPLETE',
|
|
181
|
+
400,
|
|
182
|
+
'Transaction signing incomplete',
|
|
183
|
+
signedRawTx.errors
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
return await this.sendRawTransaction(signedRawTx.hex);
|
|
341
187
|
}
|
|
342
188
|
|
|
343
|
-
/**
|
|
344
|
-
* Returns up to 'count' most recent transactions skipping the first 'from' transactions for account 'label'.
|
|
345
|
-
* @param {ListTransactionsParams} params The parameters for the listTransactions command.
|
|
346
|
-
* @returns {Promise<ListTransactionsResult>} A promise resolving to a {@link ListTransactionsResult} object.
|
|
347
|
-
*/
|
|
189
|
+
/** Returns up to 'count' most recent transactions. */
|
|
348
190
|
public async listTransactions(params: ListTransactionsParams): Promise<ListTransactionsResult> {
|
|
349
|
-
return await this.executeRpc('listtransactions', [
|
|
191
|
+
return await this.executeRpc('listtransactions', [
|
|
192
|
+
params.account ?? '*',
|
|
193
|
+
params.count ?? 10,
|
|
194
|
+
params.skip ?? 0,
|
|
195
|
+
params.include_watchonly ?? false,
|
|
196
|
+
]);
|
|
350
197
|
}
|
|
351
198
|
|
|
352
|
-
/**
|
|
353
|
-
* Create a transaction spending the given inputs and creating new outputs.
|
|
354
|
-
* Outputs can be addresses or data.
|
|
355
|
-
* Returns hex-encoded raw transaction.
|
|
356
|
-
* Note that the transaction's inputs are not signed, and
|
|
357
|
-
* it is not stored in the wallet or transmitted to the network.
|
|
358
|
-
* @param {TxInForCreateRaw[]} inputs The inputs to the transaction (required).
|
|
359
|
-
* @param {CreateRawTxOutputs[]} outputs The outputs of the transaction (required).
|
|
360
|
-
* @param {number} [locktime] The locktime of the transaction (optional).
|
|
361
|
-
* @param {boolean} [replacable] Whether the transaction is replaceable (optional).
|
|
362
|
-
* @returns {string} The hex-encoded raw transaction.
|
|
363
|
-
*/
|
|
199
|
+
/** Create a transaction spending the given inputs and creating new outputs. */
|
|
364
200
|
public async createRawTransaction(inputs: CreateRawTxInputs[], outputs: CreateRawTxOutputs[], locktime?: number, replacable?: boolean): Promise<string> {
|
|
365
|
-
return await this.executeRpc
|
|
201
|
+
return await this.executeRpc('createrawtransaction', [inputs, outputs, locktime, replacable]);
|
|
366
202
|
}
|
|
367
203
|
|
|
368
|
-
/**
|
|
369
|
-
* Derives one or more addresses corresponding to an output descriptor.
|
|
370
|
-
* Examples of output descriptors are:
|
|
371
|
-
* pkh(<pubkey>) P2PKH outputs for the given pubkey
|
|
372
|
-
* wpkh(<pubkey>) Native segwit P2PKH outputs for the given pubkey
|
|
373
|
-
* sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig outputs for the given threshold and pubkeys
|
|
374
|
-
* raw(<hex script>) Outputs whose output script equals the specified hex-encoded bytes
|
|
375
|
-
* tr(<pubkey>,multi_a(<n>,<pubkey>,<pubkey>,...)) P2TR-multisig outputs for the given threshold and pubkeys
|
|
376
|
-
*
|
|
377
|
-
* In the above, <pubkey> either refers to a fixed public key in hexadecimal notation, or to an xpub/xprv optionally followed by one
|
|
378
|
-
* or more path elements separated by "/", where "h" represents a hardened child key.
|
|
379
|
-
*
|
|
380
|
-
* See {@link https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md | github.com/bitcoin/bitcoin/descriptors.md}
|
|
381
|
-
* for more information.
|
|
382
|
-
* @param {string} descriptor The descriptor.
|
|
383
|
-
* @param {Array<number>} range If descriptor is ranged, must specify end or [begin,end] to derive.
|
|
384
|
-
* @returns {Array<DerivedAddresses>} a list of derived addresses
|
|
385
|
-
* @example First three native segwit receive addresses
|
|
386
|
-
* ```
|
|
387
|
-
* const bitcoind = BitcoinRpcClient.connect()
|
|
388
|
-
* const addresses = bitcoind.deriveAddresses("wpkh([d34db33f/84h/0h/0h]xpub6DJ2dN.../0/*)#cjjspncu", [0,2])
|
|
389
|
-
* ```
|
|
390
|
-
*/
|
|
204
|
+
/** Derives one or more addresses corresponding to an output descriptor. */
|
|
391
205
|
public async deriveAddresses(descriptor: string, range?: Array<number>): Promise<Array<DerivedAddresses>> {
|
|
392
206
|
return await this.executeRpc('deriveaddresses', [descriptor, range]);
|
|
393
207
|
}
|
|
394
208
|
|
|
395
|
-
/**
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
209
|
+
/** Mines blocks to a given address (regtest/signet only). Returns array of block hashes. */
|
|
210
|
+
public async generateToAddress(nblocks: number, address: string): Promise<string[]> {
|
|
211
|
+
return await this.executeRpc('generatetoaddress', [nblocks, address]);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/** Returns the total available balance. */
|
|
401
215
|
public async getBalance(): Promise<number> {
|
|
402
216
|
return await this.executeRpc('getbalance');
|
|
403
217
|
}
|
|
404
218
|
|
|
405
|
-
/**
|
|
406
|
-
* Returns a new Bitcoin address for receiving payments. If 'label' is specified,
|
|
407
|
-
* it is added to the address book so payments received with the address will be associated with 'label'.
|
|
408
|
-
* The 'address_type' can be one of "legacy", "p2sh-segwit", "bech32", or "bech32m".
|
|
409
|
-
* @param {string} addressType The address type to use (required, options=["legacy", "p2sh-segwit", "bech32", "bech32m"], default="bech32").
|
|
410
|
-
* @param {string} [label] The label to associate with the new address (optional).
|
|
411
|
-
* @returns {Promise<string>} A promise resolving to the new address.
|
|
412
|
-
*/
|
|
219
|
+
/** Returns a new Bitcoin address for receiving payments. */
|
|
413
220
|
public async getNewAddress(addressType: string, label?: string): Promise<string> {
|
|
414
221
|
return await this.executeRpc('getnewaddress', [label ?? '', addressType]);
|
|
415
222
|
}
|
|
416
223
|
|
|
417
|
-
/**
|
|
418
|
-
* Returns array of unspent transaction outputs with between minconf and maxconf (inclusive) confirmations.
|
|
419
|
-
* Optionally filter to only include txouts paid to specified addresses.
|
|
420
|
-
* @param {Object} params The parameters for the listUnspent command.
|
|
421
|
-
* @param {number} [params.minconf=0] The minimum number of confirmations an output must have to be included.
|
|
422
|
-
* @param {number} [params.maxconf=9999999] The maximum number of confirmations an output can have to be included.
|
|
423
|
-
* @param {string[]} [params.address] Only include outputs paid to these addresses.
|
|
424
|
-
* @param {boolean} [params.include_unsafe=true] Whether to include outputs that are not safe to spend.
|
|
425
|
-
* @returns {Promise<UnspentTxInfo[]>} A promise resolving to an array of {@link UnspentTxInfo} objects.
|
|
426
|
-
*/
|
|
224
|
+
/** Returns array of unspent transaction outputs. */
|
|
427
225
|
public async listUnspent(params: {
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
226
|
+
minconf?: number;
|
|
227
|
+
maxconf?: number;
|
|
228
|
+
address?: string[];
|
|
229
|
+
include_unsafe?: boolean;
|
|
432
230
|
}): Promise<UnspentTxInfo[]> {
|
|
433
|
-
|
|
434
|
-
|
|
231
|
+
return await this.executeRpc('listunspent', [
|
|
232
|
+
params.minconf ?? 0,
|
|
233
|
+
params.maxconf ?? 9999999,
|
|
234
|
+
params.address ?? [],
|
|
235
|
+
params.include_unsafe ?? true,
|
|
236
|
+
]);
|
|
435
237
|
}
|
|
436
238
|
|
|
437
|
-
/**
|
|
438
|
-
* Send an amount to a given address.
|
|
439
|
-
* @param {string} address The address to send to.
|
|
440
|
-
* @param {number} amount The amount to send in BTC.
|
|
441
|
-
* @returns {Promise<SendToAddressResult>} A promise resolving to the transaction id.
|
|
442
|
-
*/
|
|
239
|
+
/** Send an amount to a given address. */
|
|
443
240
|
public async sendToAddress(address: string, amount: number): Promise<RawTransactionV2> {
|
|
444
|
-
const txid = await this.executeRpc
|
|
241
|
+
const txid = await this.executeRpc('sendtoaddress', [address, amount]);
|
|
445
242
|
return await this.getRawTransaction(txid) as RawTransactionV2;
|
|
446
243
|
}
|
|
447
244
|
|
|
448
|
-
/**
|
|
449
|
-
* Sign a message with the private key of an address.
|
|
450
|
-
* @param {string} address The address to sign the message with.
|
|
451
|
-
* @param {string} message The message to sign.
|
|
452
|
-
* @returns {Promise<string>} A promise resolving to the signature in base64.
|
|
453
|
-
*/
|
|
245
|
+
/** Sign a message with the private key of an address. */
|
|
454
246
|
public async signMessage(address: string, message: string): Promise<string> {
|
|
455
247
|
return await this.executeRpc('signmessage', [address, message]);
|
|
456
248
|
}
|
|
457
249
|
|
|
458
|
-
/**
|
|
459
|
-
* Verify a signed message.
|
|
460
|
-
* @param {string} address The address to verify the message with.
|
|
461
|
-
* @param {string} signature The signature to verify in base64.
|
|
462
|
-
* @param {string} message The message to verify.
|
|
463
|
-
* @returns {Promise<boolean>} A promise resolving to true if the signature is valid, false otherwise.
|
|
464
|
-
*/
|
|
250
|
+
/** Verify a signed message. */
|
|
465
251
|
public async verifyMessage(address: string, signature: string, message: string): Promise<boolean> {
|
|
466
252
|
return await this.executeRpc('verifymessage', [address, signature, message]);
|
|
467
253
|
}
|
|
468
254
|
|
|
469
|
-
/**
|
|
470
|
-
* Get detailed information about in-wallet transaction <txid>.
|
|
471
|
-
* @param txid: The transaction id. (string, required)
|
|
472
|
-
* @param {boolean} include_watchonly Whether to include watch-only addresses in balance calculation and details.
|
|
473
|
-
* @returns {WalletTransaction} A promise resolving to a {@link WalletTransaction} object.
|
|
474
|
-
*/
|
|
255
|
+
/** Get detailed information about in-wallet transaction. */
|
|
475
256
|
public async getTransaction(txid: string, include_watchonly?: boolean): Promise<WalletTransaction> {
|
|
476
257
|
return await this.executeRpc('gettransaction', [txid, include_watchonly]);
|
|
477
258
|
}
|
|
478
259
|
|
|
479
|
-
/**
|
|
480
|
-
* Get detailed information about a transaction.
|
|
481
|
-
* By default, this call only returns a transaction if it is in the mempool. If -txindex is enabled
|
|
482
|
-
* and no blockhash argument is passed, it will return the transaction if it is in the mempool or any block.
|
|
483
|
-
* If a blockhash argument is passed, it will return the transaction if the specified block is available and
|
|
484
|
-
* the transaction is in that block.
|
|
485
|
-
* @param {string} txid The transaction id (required).
|
|
486
|
-
* @param {?VerbosityLevel} verbosity Response format: 0 (hex), 1 (json) or 2 (jsonext).
|
|
487
|
-
* @param {?string} blockhash The block in which to look for the transaction (optional).
|
|
488
|
-
* @returns {GetRawTransaction} A promise resolving to data about a transaction in the form specified by verbosity.
|
|
489
|
-
*/
|
|
260
|
+
/** Get detailed information about a transaction. */
|
|
490
261
|
public async getRawTransaction(txid: string, verbosity?: VerbosityLevel, blockhash?: string): Promise<RawTransactionResponse> {
|
|
491
|
-
// Get the raw transaction
|
|
492
262
|
const rawTransaction = await this.executeRpc('getrawtransaction', [txid, verbosity ?? 2, blockhash]);
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
case
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
return rawTransaction as RawTransactionV1;
|
|
499
|
-
case 2:
|
|
500
|
-
return rawTransaction as RawTransactionV2;
|
|
501
|
-
default:
|
|
502
|
-
return rawTransaction as RawTransactionV2;
|
|
263
|
+
switch (verbosity) {
|
|
264
|
+
case 0: return rawTransaction as RawTransactionV0;
|
|
265
|
+
case 1: return rawTransaction as RawTransactionV1;
|
|
266
|
+
case 2: return rawTransaction as RawTransactionV2;
|
|
267
|
+
default: return rawTransaction as RawTransactionV2;
|
|
503
268
|
}
|
|
504
269
|
}
|
|
505
270
|
|
|
506
|
-
/**
|
|
507
|
-
* Get detailed information about multiple transactions. An extension of {@link getRawTransaction}.
|
|
508
|
-
* @param {Array<string>} txids An array of transaction ids.
|
|
509
|
-
* @param {?VerbosityLevel} verbosity Response format: 0 (hex), 1 (json) or 2 (jsonext).
|
|
510
|
-
* @returns {Promise<Array<RawTransactionResponse>>}
|
|
511
|
-
*/
|
|
271
|
+
/** Get detailed information about multiple transactions using JSON-RPC batching. */
|
|
512
272
|
public async getRawTransactions(txids: string[], verbosity?: VerbosityLevel): Promise<RawTransactionResponse[]> {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
)
|
|
273
|
+
const v = verbosity ?? 2;
|
|
274
|
+
const results = await this.#transport.batch(
|
|
275
|
+
txids.map(txid => ({ method: 'getrawtransaction', params: [txid, v] as unknown[] }))
|
|
517
276
|
);
|
|
277
|
+
return results.map(raw => {
|
|
278
|
+
const normalized = JSONUtils.isUnprototyped(raw) ? JSONUtils.normalize(raw) : raw;
|
|
279
|
+
switch (v) {
|
|
280
|
+
case 0: return normalized as RawTransactionV0;
|
|
281
|
+
case 1: return normalized as RawTransactionV1;
|
|
282
|
+
case 2: return normalized as RawTransactionV2;
|
|
283
|
+
default: return normalized as RawTransactionV2;
|
|
284
|
+
}
|
|
285
|
+
});
|
|
518
286
|
}
|
|
519
|
-
|
|
520
|
-
}
|
|
287
|
+
}
|