@did-btcr2/bitcoin 0.3.4 → 0.4.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.
Files changed (104) hide show
  1. package/dist/cjs/bitcoin.js +83 -84
  2. package/dist/cjs/bitcoin.js.map +1 -1
  3. package/dist/cjs/client/http.js +9 -0
  4. package/dist/cjs/client/http.js.map +1 -0
  5. package/dist/cjs/client/rest/address.js +20 -28
  6. package/dist/cjs/client/rest/address.js.map +1 -1
  7. package/dist/cjs/client/rest/block.js +23 -22
  8. package/dist/cjs/client/rest/block.js.map +1 -1
  9. package/dist/cjs/client/rest/index.js +31 -84
  10. package/dist/cjs/client/rest/index.js.map +1 -1
  11. package/dist/cjs/client/rest/protocol.js +129 -0
  12. package/dist/cjs/client/rest/protocol.js.map +1 -0
  13. package/dist/cjs/client/rest/transaction.js +19 -21
  14. package/dist/cjs/client/rest/transaction.js.map +1 -1
  15. package/dist/cjs/client/rpc/index.js +75 -337
  16. package/dist/cjs/client/rpc/index.js.map +1 -1
  17. package/dist/cjs/client/rpc/interface.js +1 -6
  18. package/dist/cjs/client/rpc/interface.js.map +1 -1
  19. package/dist/cjs/client/rpc/json-rpc.js +40 -63
  20. package/dist/cjs/client/rpc/json-rpc.js.map +1 -1
  21. package/dist/cjs/client/rpc/protocol.js +134 -0
  22. package/dist/cjs/client/rpc/protocol.js.map +1 -0
  23. package/dist/cjs/constants.js +16 -5
  24. package/dist/cjs/constants.js.map +1 -1
  25. package/dist/cjs/errors.js.map +1 -1
  26. package/dist/cjs/index.js +21 -13
  27. package/dist/cjs/index.js.map +1 -1
  28. package/dist/cjs/types.js +5 -55
  29. package/dist/cjs/types.js.map +1 -1
  30. package/dist/esm/bitcoin.js +83 -84
  31. package/dist/esm/bitcoin.js.map +1 -1
  32. package/dist/esm/client/http.js +9 -0
  33. package/dist/esm/client/http.js.map +1 -0
  34. package/dist/esm/client/rest/address.js +20 -28
  35. package/dist/esm/client/rest/address.js.map +1 -1
  36. package/dist/esm/client/rest/block.js +23 -22
  37. package/dist/esm/client/rest/block.js.map +1 -1
  38. package/dist/esm/client/rest/index.js +31 -84
  39. package/dist/esm/client/rest/index.js.map +1 -1
  40. package/dist/esm/client/rest/protocol.js +129 -0
  41. package/dist/esm/client/rest/protocol.js.map +1 -0
  42. package/dist/esm/client/rest/transaction.js +19 -21
  43. package/dist/esm/client/rest/transaction.js.map +1 -1
  44. package/dist/esm/client/rpc/index.js +75 -337
  45. package/dist/esm/client/rpc/index.js.map +1 -1
  46. package/dist/esm/client/rpc/interface.js +1 -6
  47. package/dist/esm/client/rpc/interface.js.map +1 -1
  48. package/dist/esm/client/rpc/json-rpc.js +40 -63
  49. package/dist/esm/client/rpc/json-rpc.js.map +1 -1
  50. package/dist/esm/client/rpc/protocol.js +134 -0
  51. package/dist/esm/client/rpc/protocol.js.map +1 -0
  52. package/dist/esm/constants.js +16 -5
  53. package/dist/esm/constants.js.map +1 -1
  54. package/dist/esm/errors.js.map +1 -1
  55. package/dist/esm/index.js +21 -13
  56. package/dist/esm/index.js.map +1 -1
  57. package/dist/esm/types.js +5 -55
  58. package/dist/esm/types.js.map +1 -1
  59. package/dist/types/bitcoin.d.ts +66 -45
  60. package/dist/types/bitcoin.d.ts.map +1 -1
  61. package/dist/types/client/http.d.ts +21 -0
  62. package/dist/types/client/http.d.ts.map +1 -0
  63. package/dist/types/client/rest/address.d.ts +16 -19
  64. package/dist/types/client/rest/address.d.ts.map +1 -1
  65. package/dist/types/client/rest/block.d.ts +24 -16
  66. package/dist/types/client/rest/block.d.ts.map +1 -1
  67. package/dist/types/client/rest/index.d.ts +20 -51
  68. package/dist/types/client/rest/index.d.ts.map +1 -1
  69. package/dist/types/client/rest/protocol.d.ts +58 -0
  70. package/dist/types/client/rest/protocol.d.ts.map +1 -0
  71. package/dist/types/client/rest/transaction.d.ts +16 -17
  72. package/dist/types/client/rest/transaction.d.ts.map +1 -1
  73. package/dist/types/client/rpc/index.d.ts +105 -253
  74. package/dist/types/client/rpc/index.d.ts.map +1 -1
  75. package/dist/types/client/rpc/interface.d.ts +1 -4
  76. package/dist/types/client/rpc/interface.d.ts.map +1 -1
  77. package/dist/types/client/rpc/json-rpc.d.ts +20 -18
  78. package/dist/types/client/rpc/json-rpc.d.ts.map +1 -1
  79. package/dist/types/client/rpc/protocol.d.ts +82 -0
  80. package/dist/types/client/rpc/protocol.d.ts.map +1 -0
  81. package/dist/types/constants.d.ts +16 -5
  82. package/dist/types/constants.d.ts.map +1 -1
  83. package/dist/types/errors.d.ts +4 -3
  84. package/dist/types/errors.d.ts.map +1 -1
  85. package/dist/types/index.d.ts +20 -13
  86. package/dist/types/index.d.ts.map +1 -1
  87. package/dist/types/types.d.ts +98 -696
  88. package/dist/types/types.d.ts.map +1 -1
  89. package/package.json +3 -3
  90. package/src/bitcoin.ts +105 -118
  91. package/src/client/http.ts +28 -0
  92. package/src/client/rest/address.ts +24 -30
  93. package/src/client/rest/block.ts +29 -26
  94. package/src/client/rest/index.ts +38 -94
  95. package/src/client/rest/protocol.ts +153 -0
  96. package/src/client/rest/transaction.ts +23 -23
  97. package/src/client/rpc/index.ts +140 -379
  98. package/src/client/rpc/interface.ts +42 -51
  99. package/src/client/rpc/json-rpc.ts +53 -60
  100. package/src/client/rpc/protocol.ts +160 -0
  101. package/src/constants.ts +17 -5
  102. package/src/errors.ts +10 -3
  103. package/src/index.ts +81 -13
  104. package/src/types.ts +332 -972
@@ -9,57 +9,48 @@ import {
9
9
  } from '../../types.js';
10
10
 
11
11
  /**
12
- * General interface for a Bitcoin Core RPC client.\
13
- * @name BitcoinRpcClient
14
- * @type {BitcoinRpcClient}
12
+ * General interface for a Bitcoin Core RPC client.
15
13
  */
16
14
  export interface BitcoinRpcClient {
17
- /** Creates a raw transaction spending specified inputs to specified outputs. */
18
- createRawTransaction(inputs: CreateRawTxInputs[], outputs: CreateRawTxOutputs[], locktime?: number, replacable?: boolean): Promise<string>;
19
-
20
- /** Returns the number of blocks in the longest blockchain. */
21
- getBlockCount(): Promise<number>;
22
-
23
- /** Gets the hash of a block at a given height. */
24
- getBlockHash(height: number): Promise<string>;
25
-
26
- /** Gets detailed information about a specific block. */
27
- getBlock({ blockhash, height, verbosity }: GetBlockParams): Promise<BlockResponse | undefined>
28
-
29
- /** Retrieves general blockchain state info. */
30
- getBlockchainInfo(): Promise<ChainInfo>;
31
-
32
- /** Gets a new Bitcoin address for receiving payments. */
33
- getNewAddress(account?: string): Promise<string>;
34
-
35
- /** Sends raw transaction hex to the Bitcoin network. */
36
- sendRawTransaction(
37
- hexstring: string,
38
- maxfeerate?: number | string,
39
- maxBurnAmount?: number | string
40
- ): Promise<string>;
41
-
42
- /** Sends bitcoins to a specified address. */
43
- sendToAddress(
44
- address: string,
45
- amount: number,
46
- comment?: string,
47
- comment_to?: string,
48
- subtreactfeefromamount?: boolean,
49
- replaceable?: boolean,
50
- conf_target?: number,
51
- estimate_mode?: FeeEstimateMode,
52
- ): Promise<RawTransactionResponse>;
53
-
54
- /** Verifies a signed message. */
55
- verifyMessage(address: string, signature: string, message: string): Promise<boolean>;
56
-
57
- signMessage(address: string, message: string): Promise<string>;
15
+ /** Creates a raw transaction spending specified inputs to specified outputs. */
16
+ createRawTransaction(inputs: CreateRawTxInputs[], outputs: CreateRawTxOutputs[], locktime?: number, replacable?: boolean): Promise<string>;
17
+
18
+ /** Returns the number of blocks in the longest blockchain. */
19
+ getBlockCount(): Promise<number>;
20
+
21
+ /** Gets the hash of a block at a given height. */
22
+ getBlockHash(height: number): Promise<string>;
23
+
24
+ /** Gets detailed information about a specific block. */
25
+ getBlock({ blockhash, height, verbosity }: GetBlockParams): Promise<BlockResponse | undefined>
26
+
27
+ /** Retrieves general blockchain state info. */
28
+ getBlockchainInfo(): Promise<ChainInfo>;
29
+
30
+ /** Gets a new Bitcoin address for receiving payments. */
31
+ getNewAddress(account?: string): Promise<string>;
32
+
33
+ /** Sends raw transaction hex to the Bitcoin network. */
34
+ sendRawTransaction(
35
+ hexstring: string,
36
+ maxfeerate?: number | string,
37
+ maxBurnAmount?: number | string
38
+ ): Promise<string>;
39
+
40
+ /** Sends bitcoins to a specified address. */
41
+ sendToAddress(
42
+ address: string,
43
+ amount: number,
44
+ comment?: string,
45
+ comment_to?: string,
46
+ subtreactfeefromamount?: boolean,
47
+ replaceable?: boolean,
48
+ conf_target?: number,
49
+ estimate_mode?: FeeEstimateMode,
50
+ ): Promise<RawTransactionResponse>;
51
+
52
+ /** Verifies a signed message. */
53
+ verifyMessage(address: string, signature: string, message: string): Promise<boolean>;
54
+
55
+ signMessage(address: string, message: string): Promise<string>;
58
56
  }
59
-
60
- export function isBitcoinRpcClient(obj: any): obj is BitcoinRpcClient {
61
- return obj &&
62
- typeof obj.getBlockCount === 'function' &&
63
- typeof obj.getBlockHash === 'function' &&
64
- typeof obj.getBlockchainInfo === 'function';
65
- }
@@ -1,81 +1,74 @@
1
- import { BatchOption, RpcClientConfig } from '../../types.js';
2
- import { safeText, toBase64 } from '../utils.js';
1
+ import { BitcoinRpcError } from '../../errors.js';
2
+ import { RpcConfig } from '../../types.js';
3
+ import { HttpExecutor, defaultHttpExecutor } from '../http.js';
4
+ import { safeText } from '../utils.js';
5
+ import { JsonRpcProtocol } from './protocol.js';
3
6
 
4
7
  export class JsonRpcTransport {
5
- private url: string;
6
- private authHeader?: string;
7
- private id = 0;
8
+ /**
9
+ * The sans-I/O protocol layer. Use this to build {@link HttpRequest}
10
+ * descriptors without performing any I/O.
11
+ */
12
+ readonly protocol: JsonRpcProtocol;
8
13
 
9
- constructor(cfg: RpcClientConfig) {
10
- this.url = (cfg.host || 'http://127.0.0.1:8332').replace(/\/+$/, '');
14
+ private readonly execute: HttpExecutor;
11
15
 
12
- if (cfg.username && cfg.password) {
13
- this.authHeader = `Basic ${toBase64(`${cfg.username}:${cfg.password}`)}`;
14
- } else {
15
- try {
16
- const u = new URL(this.url);
17
- if (u.username || u.password) {
18
- this.authHeader = `Basic ${toBase64(`${decodeURIComponent(u.username)}:${decodeURIComponent(u.password)}`)}`;
19
- u.username = ''; u.password = '';
20
- this.url = u.toString().replace(/\/+$/, '');
21
- }
22
- } catch(error: any) {
23
- console.error(`Invalid URL in Bitcoin RPC config: ${this.url}`, error);
24
- }
25
- }
16
+ constructor(cfg: RpcConfig, executor?: HttpExecutor) {
17
+ this.protocol = new JsonRpcProtocol(cfg);
18
+ this.execute = executor ?? defaultHttpExecutor;
19
+ }
20
+
21
+ /** @internal Expose URL for tests that inspect transport state. */
22
+ get url(): string {
23
+ return this.protocol.url;
26
24
  }
27
25
 
28
26
  /**
29
- * Make a JSON-RPC call or batch of calls to the Bitcoin node.
30
- * @param {BatchOption[] | { method: string; parameters?: any[] }} batch A single RPC call or an array of calls to be made.
31
- * @returns {Promise<any[] | any>} The result of the RPC call(s).
32
- * @example
27
+ * Execute a single JSON-RPC call.
33
28
  */
34
- async command(batch: BatchOption[] | { method: string; parameters?: any[] }): Promise<any[] | any> {
35
- if (Array.isArray(batch)) {
36
- const out: any[] = [];
37
- for (const item of batch) {
38
- out.push(await this.call(item.method, item.parameters ?? []));
39
- }
40
- return out;
41
- } else {
42
- return this.call(batch.method, batch.parameters ?? []);
29
+ async call(method: string, params: unknown[] = []): Promise<unknown> {
30
+ const request = this.protocol.buildRequest(method, params);
31
+ const res = await this.execute(request);
32
+
33
+ if (!res.ok) {
34
+ const text = await safeText(res);
35
+ throw new BitcoinRpcError(
36
+ 'HTTP_ERROR',
37
+ res.status,
38
+ text || `${res.status} ${res.statusText}`,
39
+ { method }
40
+ );
43
41
  }
42
+
43
+ const payload = await res.json() as { result?: unknown; error?: { code: number; message: string } };
44
+ return this.protocol.parseResponse(payload, method);
44
45
  }
45
46
 
46
47
  /**
47
- * Internal method to perform the actual JSON-RPC call.
48
- * @param {string} method The RPC method to call.
49
- * @param {any[]} params The parameters for the RPC method.
50
- * @returns {Promise<any>} The result of the RPC call.
48
+ * Execute a JSON-RPC batch in a single HTTP request.
49
+ * Returns results in the same order as the input calls.
51
50
  */
52
- private async call(method: string, params: any[]): Promise<any> {
53
- const body = { jsonrpc: '2.0', id: ++this.id, method, params };
51
+ async batch(calls: Array<{ method: string; params: unknown[] }>): Promise<unknown[]> {
52
+ if (calls.length === 0) return [];
53
+ if (calls.length === 1) {
54
+ const result = await this.call(calls[0].method, calls[0].params);
55
+ return [result];
56
+ }
54
57
 
55
- const res = await fetch(this.url, {
56
- method : 'POST',
57
- headers : {
58
- 'Content-Type' : 'application/json',
59
- ...(this.authHeader ? { Authorization: this.authHeader } : {})
60
- },
61
- body : JSON.stringify(body)
62
- });
58
+ const request = this.protocol.buildBatchRequest(calls);
59
+ const res = await this.execute(request);
63
60
 
64
61
  if (!res.ok) {
65
62
  const text = await safeText(res);
66
- const err = new Error(text || `${res.status} ${res.statusText}`);
67
- (err as any).code = res.status;
68
- (err as any).rpc = true;
69
- throw err;
63
+ throw new BitcoinRpcError(
64
+ 'HTTP_ERROR',
65
+ res.status,
66
+ text || `${res.status} ${res.statusText}`,
67
+ { methods: calls.map(c => c.method) }
68
+ );
70
69
  }
71
70
 
72
- const payload = await res.json() as { result?: any; error?: { code: number; message: string } };
73
- if (payload.error) {
74
- const err = new Error(payload.error.message);
75
- (err as any).code = payload.error.code;
76
- (err as any).rpc = true;
77
- throw err;
78
- }
79
- return payload.result;
71
+ const payloads = await res.json() as Array<{ id: number; result?: unknown; error?: { code: number; message: string } }>;
72
+ return this.protocol.parseBatchResponse(payloads, calls);
80
73
  }
81
74
  }
@@ -0,0 +1,160 @@
1
+ import { BitcoinRpcError } from '../../errors.js';
2
+ import { RpcConfig } from '../../types.js';
3
+ import { HttpRequest } from '../http.js';
4
+ import { toBase64 } from '../utils.js';
5
+
6
+ /**
7
+ * Sans-I/O JSON-RPC protocol for Bitcoin Core.
8
+ *
9
+ * Builds {@link HttpRequest} descriptors for JSON-RPC method calls and
10
+ * provides response parsing — without performing any I/O.
11
+ *
12
+ * **Security note:** Built requests include an `Authorization` header when
13
+ * credentials are configured. Do not log or persist {@link HttpRequest}
14
+ * objects without redacting the `Authorization` header.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * const protocol = new JsonRpcProtocol({
19
+ * host: 'http://localhost:18443',
20
+ * username: 'user',
21
+ * password: 'pass',
22
+ * });
23
+ *
24
+ * // Build a request descriptor (no I/O)
25
+ * const req = protocol.buildRequest('getblockcount', []);
26
+ *
27
+ * // Execute with any HTTP client
28
+ * const res = await fetch(req.url, req);
29
+ * const json = await res.json();
30
+ *
31
+ * // Parse the JSON-RPC response (throws on errors)
32
+ * const blockCount = protocol.parseResponse(json, 'getblockcount', []);
33
+ * ```
34
+ */
35
+ export class JsonRpcProtocol {
36
+ readonly url: string;
37
+
38
+ /** Whether this protocol instance has credentials configured. */
39
+ readonly hasAuth: boolean;
40
+
41
+ private readonly _headers: Record<string, string>;
42
+ private _id = 0;
43
+
44
+ constructor(cfg: RpcConfig) {
45
+ let url = (cfg.host || 'http://127.0.0.1:8332').replace(/\/+$/, '');
46
+ let authHeader: string | undefined;
47
+
48
+ if (cfg.username && cfg.password) {
49
+ authHeader = `Basic ${toBase64(`${cfg.username}:${cfg.password}`)}`;
50
+ } else {
51
+ try {
52
+ const u = new URL(url);
53
+ if (u.username || u.password) {
54
+ authHeader = `Basic ${toBase64(`${decodeURIComponent(u.username)}:${decodeURIComponent(u.password)}`)}`;
55
+ u.username = ''; u.password = '';
56
+ url = u.toString().replace(/\/+$/, '');
57
+ }
58
+ } catch (error: unknown) {
59
+ console.error(`Invalid URL in Bitcoin RPC config: ${url}`, error);
60
+ }
61
+ }
62
+
63
+ this.url = url;
64
+ this.hasAuth = authHeader !== undefined;
65
+ this._headers = {
66
+ 'Content-Type' : 'application/json',
67
+ ...(authHeader ? { Authorization: authHeader } : {}),
68
+ };
69
+ }
70
+
71
+ /**
72
+ * Build an {@link HttpRequest} for a JSON-RPC method call.
73
+ */
74
+ buildRequest(method: string, params: unknown[]): HttpRequest {
75
+ const body = { jsonrpc: '2.0', id: ++this._id, method, params };
76
+ return {
77
+ url : this.url,
78
+ method : 'POST',
79
+ headers : { ...this._headers },
80
+ body : JSON.stringify(body),
81
+ };
82
+ }
83
+
84
+ /**
85
+ * Build an {@link HttpRequest} for a JSON-RPC batch call.
86
+ * Sends all calls in a single HTTP request per the JSON-RPC 2.0 spec.
87
+ */
88
+ buildBatchRequest(calls: Array<{ method: string; params: unknown[] }>): HttpRequest {
89
+ const body = calls.map(c => ({
90
+ jsonrpc : '2.0',
91
+ id : ++this._id,
92
+ method : c.method,
93
+ params : c.params,
94
+ }));
95
+ return {
96
+ url : this.url,
97
+ method : 'POST',
98
+ headers : { ...this._headers },
99
+ body : JSON.stringify(body),
100
+ };
101
+ }
102
+
103
+ /**
104
+ * Parse a JSON-RPC response payload, throwing {@link BitcoinRpcError}
105
+ * if the response contains an error.
106
+ */
107
+ parseResponse(
108
+ payload: { result?: unknown; error?: { code: number; message: string } },
109
+ method: string,
110
+ ): unknown {
111
+ if (payload.error) {
112
+ throw new BitcoinRpcError(
113
+ 'RPC_ERROR',
114
+ payload.error.code,
115
+ payload.error.message,
116
+ { method }
117
+ );
118
+ }
119
+ return payload.result;
120
+ }
121
+
122
+ /**
123
+ * Parse a JSON-RPC batch response payload.
124
+ * Returns results in the same order as the original calls.
125
+ */
126
+ parseBatchResponse(
127
+ payloads: Array<{ id: number; result?: unknown; error?: { code: number; message: string } }>,
128
+ calls: Array<{ method: string; params: unknown[] }>,
129
+ ): unknown[] {
130
+ const byId = new Map(payloads.map(p => [p.id, p]));
131
+ // Batch responses may arrive out of order; re-sort by sequential id.
132
+ // IDs were assigned as (_id - calls.length + 1) .. _id
133
+ const startId = this._id - calls.length + 1;
134
+
135
+ return calls.map((call, i) => {
136
+ const payload = byId.get(startId + i);
137
+ if (!payload) {
138
+ throw new BitcoinRpcError(
139
+ 'RPC_ERROR',
140
+ -1,
141
+ `Missing response for batch call ${call.method} (id ${startId + i})`,
142
+ { method: call.method }
143
+ );
144
+ }
145
+ return this.parseResponse(payload, call.method);
146
+ });
147
+ }
148
+
149
+ /**
150
+ * Return a copy of the headers with the Authorization value redacted.
151
+ * Use this for logging or debugging.
152
+ */
153
+ redactedHeaders(): Record<string, string> {
154
+ const copy = { ...this._headers };
155
+ if (copy.Authorization) {
156
+ copy.Authorization = 'Basic [REDACTED]';
157
+ }
158
+ return copy;
159
+ }
160
+ }
package/src/constants.ts CHANGED
@@ -4,6 +4,23 @@ export const COINBASE_MATURITY_DELAY = 100;
4
4
  export const DEFAULT_BLOCK_CONFIRMATIONS = 7;
5
5
  export const TXIN_WITNESS_COINBASE = '0000000000000000000000000000000000000000000000000000000000000000';
6
6
  export const GENESIS_TX_ID = '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b';
7
+
8
+ /**
9
+ * Default endpoint configuration per Bitcoin network.
10
+ *
11
+ * **Regtest RPC:** Credentials are intentionally omitted — callers must
12
+ * provide `username` and `password` via overrides or explicit config.
13
+ * This prevents accidentally using hardcoded credentials in non-local
14
+ * environments.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * // Provide credentials explicitly
19
+ * BitcoinConnection.forNetwork('regtest', {
20
+ * rpc: { username: 'polaruser', password: 'polarpass' },
21
+ * });
22
+ * ```
23
+ */
7
24
  export const DEFAULT_BITCOIN_NETWORK_CONFIG = {
8
25
  bitcoin : {
9
26
  rpc : undefined,
@@ -27,13 +44,8 @@ export const DEFAULT_BITCOIN_NETWORK_CONFIG = {
27
44
  },
28
45
  regtest : {
29
46
  rpc : {
30
- network : 'regtest',
31
47
  host : 'http://localhost:18443',
32
- port : 18443,
33
- username : 'polaruser',
34
- password : 'polarpass',
35
48
  allowDefaultWallet : true,
36
- version : '28.1.0',
37
49
  },
38
50
  rest : { host: 'http://localhost:3000' }
39
51
  },
package/src/errors.ts CHANGED
@@ -1,11 +1,18 @@
1
+ export type RpcErrorType =
2
+ | 'HTTP_ERROR'
3
+ | 'RPC_ERROR'
4
+ | 'INVALID_PARAMS_GET_BLOCK'
5
+ | 'SIGNING_INCOMPLETE'
6
+ | 'UNKNOWN_ERROR';
7
+
1
8
  /**
2
9
  * Custom Error class for handling Bitcoin RPC errors.
3
10
  */
4
11
  export class BitcoinRpcError extends Error {
5
- public readonly type: string;
12
+ public readonly type: RpcErrorType;
6
13
  public readonly code: number;
7
- public readonly data?: any;
8
- constructor(type: string, code: number, message: string, data?: any) {
14
+ public readonly data?: unknown;
15
+ constructor(type: RpcErrorType, code: number, message: string, data?: unknown) {
9
16
  super(message);
10
17
  this.type = type;
11
18
  this.code = code;
package/src/index.ts CHANGED
@@ -1,13 +1,81 @@
1
- export * from './bitcoin.js';
2
- export * from './client/rest/address.js';
3
- export * from './client/rest/block.js';
4
- export * from './client/rest/index.js';
5
- export * from './client/rest/transaction.js';
6
- export * from './client/rpc/index.js';
7
- export * from './client/rpc/interface.js';
8
- export * from './client/rpc/json-rpc.js';
9
- export * from './client/utils.js';
10
- export * from './constants.js';
11
- export * from './errors.js';
12
- export * from './network.js';
13
- export * from './types.js';
1
+ // Core
2
+ export { BitcoinConnection, type BitcoinConnectionOptions } from './bitcoin.js';
3
+
4
+ // Sans-I/O protocol layer
5
+ export type { HttpRequest, HttpExecutor } from './client/http.js';
6
+ export { defaultHttpExecutor } from './client/http.js';
7
+ export { EsploraProtocol } from './client/rest/protocol.js';
8
+ export { JsonRpcProtocol } from './client/rpc/protocol.js';
9
+
10
+ // Clients (convenience wrappers around the protocol layer)
11
+ export { BitcoinRestClient } from './client/rest/index.js';
12
+ export { BitcoinCoreRpcClient } from './client/rpc/index.js';
13
+ export type { RpcMethodMap, TypedRpcMethod } from './client/rpc/index.js';
14
+ export type { BitcoinRpcClient } from './client/rpc/interface.js';
15
+
16
+ // Sub-clients (for direct construction in tests or advanced use)
17
+ export { BitcoinAddress } from './client/rest/address.js';
18
+ export { BitcoinBlock } from './client/rest/block.js';
19
+ export { BitcoinTransaction } from './client/rest/transaction.js';
20
+ export { JsonRpcTransport } from './client/rpc/json-rpc.js';
21
+
22
+ // Errors
23
+ export { BitcoinRpcError, BitcoinRestError } from './errors.js';
24
+ export type { RpcErrorType } from './errors.js';
25
+
26
+ // Helpers
27
+ export { getNetwork } from './network.js';
28
+ export { toBase64, safeText } from './client/utils.js';
29
+
30
+ // Constants
31
+ export {
32
+ DEFAULT_BITCOIN_NETWORK_CONFIG,
33
+ INITIAL_BLOCK_REWARD,
34
+ HALVING_INTERVAL,
35
+ COINBASE_MATURITY_DELAY,
36
+ DEFAULT_BLOCK_CONFIRMATIONS,
37
+ TXIN_WITNESS_COINBASE,
38
+ GENESIS_TX_ID,
39
+ } from './constants.js';
40
+
41
+ // Types
42
+ export type {
43
+ // Network
44
+ NetworkName,
45
+ // REST
46
+ RestConfig,
47
+ EsploraBlock,
48
+ TransactionStatus,
49
+ Vin,
50
+ Vout,
51
+ ChainStats,
52
+ MempoolStats,
53
+ AddressInfo,
54
+ RawTransactionRest,
55
+ AddressUtxo,
56
+ // RPC
57
+ RpcConfig,
58
+ ChainInfo,
59
+ GetBlockParams,
60
+ BlockResponse,
61
+ BlockV0,
62
+ BlockV1,
63
+ BlockV2,
64
+ BlockV3,
65
+ RawTransactionResponse,
66
+ RawTransactionV0,
67
+ RawTransactionV1,
68
+ RawTransactionV2,
69
+ CreateRawTxInputs,
70
+ CreateRawTxOutputs,
71
+ SignedRawTx,
72
+ UnspentTxInfo,
73
+ WalletTransaction,
74
+ DerivedAddresses,
75
+ ListTransactionsParams,
76
+ ListTransactionsResult,
77
+ MethodNameInLowerCase,
78
+ FeeEstimateMode,
79
+ } from './types.js';
80
+
81
+ export { VerbosityLevel } from './types.js';