@did-btcr2/bitcoin 0.1.2 → 0.2.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 (135) hide show
  1. package/dist/cjs/{bitcoin.browser.js → bitcoin.js} +39 -16
  2. package/dist/cjs/bitcoin.js.map +1 -0
  3. package/dist/cjs/client/rest/address.js +76 -0
  4. package/dist/cjs/client/rest/address.js.map +1 -0
  5. package/dist/cjs/client/rest/block.js +50 -0
  6. package/dist/cjs/client/rest/block.js.map +1 -0
  7. package/dist/cjs/client/rest/index.js +118 -0
  8. package/dist/cjs/client/rest/index.js.map +1 -0
  9. package/dist/cjs/client/rest/transaction.js +56 -0
  10. package/dist/cjs/client/rest/transaction.js.map +1 -0
  11. package/dist/cjs/client/rpc/index.js +394 -0
  12. package/dist/cjs/client/rpc/index.js.map +1 -0
  13. package/dist/cjs/client/rpc/interface.js.map +1 -0
  14. package/dist/cjs/client/rpc/json-rpc.js +78 -0
  15. package/dist/cjs/client/rpc/json-rpc.js.map +1 -0
  16. package/dist/cjs/client/utils.js +28 -0
  17. package/dist/cjs/client/utils.js.map +1 -0
  18. package/dist/cjs/constants.js +34 -13
  19. package/dist/cjs/constants.js.map +1 -1
  20. package/dist/cjs/errors.js +8 -0
  21. package/dist/cjs/errors.js.map +1 -1
  22. package/dist/cjs/index.js +15 -0
  23. package/dist/cjs/index.js.map +1 -0
  24. package/dist/cjs/types.js +2 -2
  25. package/dist/cjs/types.js.map +1 -1
  26. package/dist/esm/{bitcoin.browser.js → bitcoin.js} +39 -16
  27. package/dist/esm/bitcoin.js.map +1 -0
  28. package/dist/esm/client/rest/address.js +76 -0
  29. package/dist/esm/client/rest/address.js.map +1 -0
  30. package/dist/esm/client/rest/block.js +50 -0
  31. package/dist/esm/client/rest/block.js.map +1 -0
  32. package/dist/esm/client/rest/index.js +118 -0
  33. package/dist/esm/client/rest/index.js.map +1 -0
  34. package/dist/esm/client/rest/transaction.js +56 -0
  35. package/dist/esm/client/rest/transaction.js.map +1 -0
  36. package/dist/esm/client/rpc/index.js +394 -0
  37. package/dist/esm/client/rpc/index.js.map +1 -0
  38. package/dist/esm/client/rpc/interface.js.map +1 -0
  39. package/dist/esm/client/rpc/json-rpc.js +78 -0
  40. package/dist/esm/client/rpc/json-rpc.js.map +1 -0
  41. package/dist/esm/client/utils.js +28 -0
  42. package/dist/esm/client/utils.js.map +1 -0
  43. package/dist/esm/constants.js +34 -13
  44. package/dist/esm/constants.js.map +1 -1
  45. package/dist/esm/errors.js +8 -0
  46. package/dist/esm/errors.js.map +1 -1
  47. package/dist/esm/index.js +15 -0
  48. package/dist/esm/index.js.map +1 -0
  49. package/dist/esm/types.js +2 -2
  50. package/dist/esm/types.js.map +1 -1
  51. package/dist/types/{bitcoin.browser.d.ts → bitcoin.d.ts} +23 -8
  52. package/dist/types/bitcoin.d.ts.map +1 -0
  53. package/dist/types/client/rest/address.d.ts +56 -0
  54. package/dist/types/client/rest/address.d.ts.map +1 -0
  55. package/dist/types/client/rest/block.d.ts +32 -0
  56. package/dist/types/client/rest/block.d.ts.map +1 -0
  57. package/dist/types/client/rest/index.d.ts +149 -0
  58. package/dist/types/client/rest/index.d.ts.map +1 -0
  59. package/dist/types/client/rest/transaction.d.ts +44 -0
  60. package/dist/types/client/rest/transaction.d.ts.map +1 -0
  61. package/dist/types/client/rpc/index.d.ts +276 -0
  62. package/dist/types/client/rpc/index.d.ts.map +1 -0
  63. package/dist/types/client/rpc/interface.d.ts +27 -0
  64. package/dist/types/client/rpc/interface.d.ts.map +1 -0
  65. package/dist/types/client/rpc/json-rpc.d.ts +24 -0
  66. package/dist/types/client/rpc/json-rpc.d.ts.map +1 -0
  67. package/dist/types/client/utils.d.ts +12 -0
  68. package/dist/types/client/utils.d.ts.map +1 -0
  69. package/dist/types/constants.d.ts +46 -13
  70. package/dist/types/constants.d.ts.map +1 -1
  71. package/dist/types/errors.d.ts +4 -0
  72. package/dist/types/errors.d.ts.map +1 -1
  73. package/dist/types/index.d.ts +14 -0
  74. package/dist/types/index.d.ts.map +1 -0
  75. package/dist/types/types.d.ts +8 -8
  76. package/dist/types/types.d.ts.map +1 -1
  77. package/package.json +9 -15
  78. package/src/{bitcoin.browser.ts → bitcoin.ts} +48 -16
  79. package/src/client/rest/address.ts +84 -0
  80. package/src/client/rest/block.ts +58 -0
  81. package/src/client/rest/index.ts +217 -0
  82. package/src/client/rest/transaction.ts +64 -0
  83. package/src/client/rpc/index.ts +479 -0
  84. package/src/client/rpc/interface.ts +58 -0
  85. package/src/client/rpc/json-rpc.ts +82 -0
  86. package/src/client/utils.ts +21 -0
  87. package/src/constants.ts +35 -14
  88. package/src/errors.ts +9 -0
  89. package/src/index.ts +14 -0
  90. package/src/types.ts +9 -9
  91. package/dist/cjs/bitcoin.browser.js.map +0 -1
  92. package/dist/cjs/bitcoin.node.js +0 -85
  93. package/dist/cjs/bitcoin.node.js.map +0 -1
  94. package/dist/cjs/index.browser.js +0 -10
  95. package/dist/cjs/index.browser.js.map +0 -1
  96. package/dist/cjs/index.node.js +0 -10
  97. package/dist/cjs/index.node.js.map +0 -1
  98. package/dist/cjs/interface.js.map +0 -1
  99. package/dist/cjs/rest-client.js +0 -294
  100. package/dist/cjs/rest-client.js.map +0 -1
  101. package/dist/cjs/rpc-client.js +0 -722
  102. package/dist/cjs/rpc-client.js.map +0 -1
  103. package/dist/esm/bitcoin.browser.js.map +0 -1
  104. package/dist/esm/bitcoin.node.js +0 -85
  105. package/dist/esm/bitcoin.node.js.map +0 -1
  106. package/dist/esm/index.browser.js +0 -10
  107. package/dist/esm/index.browser.js.map +0 -1
  108. package/dist/esm/index.node.js +0 -10
  109. package/dist/esm/index.node.js.map +0 -1
  110. package/dist/esm/interface.js.map +0 -1
  111. package/dist/esm/rest-client.js +0 -294
  112. package/dist/esm/rest-client.js.map +0 -1
  113. package/dist/esm/rpc-client.js +0 -722
  114. package/dist/esm/rpc-client.js.map +0 -1
  115. package/dist/types/bitcoin.browser.d.ts.map +0 -1
  116. package/dist/types/bitcoin.node.d.ts +0 -47
  117. package/dist/types/bitcoin.node.d.ts.map +0 -1
  118. package/dist/types/index.browser.d.ts +0 -9
  119. package/dist/types/index.browser.d.ts.map +0 -1
  120. package/dist/types/index.node.d.ts +0 -9
  121. package/dist/types/index.node.d.ts.map +0 -1
  122. package/dist/types/interface.d.ts +0 -86
  123. package/dist/types/interface.d.ts.map +0 -1
  124. package/dist/types/rest-client.d.ts +0 -273
  125. package/dist/types/rest-client.d.ts.map +0 -1
  126. package/dist/types/rpc-client.d.ts +0 -506
  127. package/dist/types/rpc-client.d.ts.map +0 -1
  128. package/src/bitcoin.node.ts +0 -121
  129. package/src/index.browser.ts +0 -9
  130. package/src/index.node.ts +0 -9
  131. package/src/interface.ts +0 -160
  132. package/src/rest-client.ts +0 -420
  133. package/src/rpc-client.ts +0 -888
  134. /package/dist/cjs/{interface.js → client/rpc/interface.js} +0 -0
  135. /package/dist/esm/{interface.js → client/rpc/interface.js} +0 -0
@@ -0,0 +1,217 @@
1
+ import { MethodError, UnixTimestamp } from '@did-btcr2/common';
2
+ import { TxInPrevout } from '../../types.js';
3
+ import { BitcoinAddress } from './address.js';
4
+ import { BitcoinBlock } from './block.js';
5
+ import { BitcoinTransaction } from './transaction.js';
6
+ import { DEFAULT_BITCOIN_NETWORK_CONFIG } from '../../constants.js';
7
+
8
+ export type TransactionStatus = {
9
+ confirmed: boolean;
10
+ block_height: number;
11
+ block_hash: string;
12
+ block_time: UnixTimestamp;
13
+ };
14
+
15
+ export interface Vin {
16
+ txid: string;
17
+ vout: number;
18
+ prevout?: TxInPrevout;
19
+ scriptsig: string;
20
+ scriptsig_asm: string;
21
+ witness: string[];
22
+ is_coinbase: boolean;
23
+ sequence: number;
24
+ };
25
+
26
+ export interface Vout {
27
+ scriptpubkey: string;
28
+ scriptpubkey_asm: string;
29
+ scriptpubkey_type: string;
30
+ scriptpubkey_address?: string;
31
+ value: number;
32
+ }
33
+ export interface ChainStats {
34
+ funded_txo_count: number;
35
+ funded_txo_sum: number;
36
+ spent_txo_count: number;
37
+ spent_txo_sum: number;
38
+ tx_count: number;
39
+ }
40
+
41
+ export interface MempoolStats {
42
+ funded_txo_count: number;
43
+ funded_txo_sum: number;
44
+ spent_txo_count: number;
45
+ spent_txo_sum: number;
46
+ tx_count: number;
47
+ }
48
+ export interface AddressInfo {
49
+ address: string;
50
+ chain_stats: ChainStats;
51
+ mempool_stats: MempoolStats;
52
+ }
53
+ export interface RawTransactionRest {
54
+ txid: string;
55
+ version: number;
56
+ locktime: number;
57
+ vin: Array<Vin>;
58
+ vout: Array<Vout>;
59
+ size: number;
60
+ weight: number;
61
+ fee: number;
62
+ status: TransactionStatus;
63
+ }
64
+
65
+ export interface AddressUtxo {
66
+ txid: string;
67
+ vout: number;
68
+ status: TransactionStatus;
69
+ value: number;
70
+ }
71
+ export interface RestClientConfigParams {
72
+ host: string;
73
+ headers?: { [key: string]: string };
74
+ }
75
+
76
+ export class RestClientConfig {
77
+ host: string;
78
+ headers?: { [key: string]: string };
79
+ constructor({ host, headers }: RestClientConfigParams) {
80
+ this.host = host;
81
+ this.headers = headers;
82
+ }
83
+ }
84
+
85
+ export interface RestApiCallParams {
86
+ path: string;
87
+ url?: string;
88
+ method?: string;
89
+ body?: any;
90
+ headers?: any;
91
+ };
92
+
93
+ export interface RestResponse extends Response {
94
+ [key: string]: any;
95
+ }
96
+
97
+ /**
98
+ * Implements a strongly-typed BitcoinRestClient to connect to remote bitcoin node via REST API.
99
+ * @class BitcoinRestClient
100
+ * @type {BitcoinRestClient}
101
+ */
102
+ export class BitcoinRestClient {
103
+ /**
104
+ * The encapsulated {@link RestClientConfig} object.
105
+ * @private
106
+ * @type {RestClientConfig}
107
+ */
108
+ private _config: RestClientConfig;
109
+
110
+ /**
111
+ * The api calls related to bitcoin transactions.
112
+ * @type {BitcoinTransaction}
113
+ */
114
+ public transaction: BitcoinTransaction;
115
+
116
+ /**
117
+ * The api calls related to bitcoin blocks.
118
+ * @type {BitcoinBlock}
119
+ */
120
+ public block: BitcoinBlock;
121
+
122
+ /**
123
+ * The api calls related to bitcoin addresses.
124
+ * @type {BitcoinAddress}
125
+ */
126
+ public address: BitcoinAddress;
127
+
128
+ /**
129
+ * The API call method that can be used to make requests to the REST API.
130
+ * @returns {Promise<any>} A promise resolving to the response data.
131
+ */
132
+ public api: (params: RestApiCallParams) => Promise<any> = this.call;
133
+
134
+ constructor(config: RestClientConfig){
135
+ this._config = new RestClientConfig(config);
136
+ this.api = this.call.bind(this);
137
+ this.transaction = new BitcoinTransaction(this.api);
138
+ this.block = new BitcoinBlock(this.api);
139
+ this.address = new BitcoinAddress(this.api);
140
+ }
141
+
142
+ /**
143
+ * Get the configuration object.
144
+ * @private
145
+ */
146
+ get config(): RestClientConfig {
147
+ const config = this._config;
148
+ return config;
149
+ }
150
+
151
+ /**
152
+ * Static method connects to a bitcoin node running a esplora REST API.
153
+ *
154
+ * @param {RestClientConfig} config The configuration object for the client (optional).
155
+ * @returns {BitcoinRestClient} A new {@link BitcoinRestClient} instance.
156
+ * @example
157
+ * ```
158
+ * const rest = BitcoinRestClient.connect();
159
+ * ```
160
+ */
161
+ public static connect(config?: RestClientConfig): BitcoinRestClient {
162
+ return new BitcoinRestClient(config ?? DEFAULT_BITCOIN_NETWORK_CONFIG.regtest.rest);
163
+ }
164
+
165
+ /**
166
+ * Make a REST API call to the configured Bitcoin node.
167
+ * @private
168
+ * @param {RestApiCallParams} params The parameters for the API call. See {@link RestApiCallParams} for details.
169
+ * @param {string} [params.path] The path to the API endpoint (required).
170
+ * @param {string} [params.url] The full URL to the API endpoint (optional).
171
+ * @param {string} [params.method] The HTTP method to use (default is 'GET').
172
+ * @param {any} [params.body] The body of the request (optional).
173
+ * @param {any} [params.headers] Additional headers to include in the request (optional).
174
+ * @returns {Promise<any>} A promise resolving to the response data.
175
+ */
176
+ private async call({ path, url, method, body, headers }: RestApiCallParams): Promise<any> {
177
+ // Construct the URL if not provided
178
+ url ??= `${this.config.host.replaceEnd('/')}${path}`;
179
+
180
+ // Set the method to GET if not provided
181
+ method ??= 'GET';
182
+
183
+ // Construct the request options
184
+ const requestInit = {
185
+ method,
186
+ headers : headers ?? {
187
+ 'Content-Type' : 'application/json',
188
+ ...this.config.headers,
189
+ }
190
+ } as any;
191
+
192
+ // If the method is POST or PUT, add the body to the request
193
+ if(body) {
194
+ requestInit.body = JSON.is(body) ? JSON.stringify(body) : body;
195
+ requestInit.method = 'POST';
196
+ }
197
+
198
+ // Make the request
199
+ const response = await fetch(url, requestInit) as RestResponse;
200
+
201
+ // Check if the response is a text/plain response
202
+ const data = (response.headers.get('Content-Type') ?? 'json') === 'text/plain'
203
+ ? await response.text()
204
+ : await response.json();
205
+
206
+ // Check if the response is ok (status in the range 200-299)
207
+ if (!response.ok) {
208
+ throw new MethodError(
209
+ `Request to ${url} failed: ${response.status} - ${response.statusText}`,
210
+ 'FAILED_HTTP_REQUEST',
211
+ { data, response }
212
+ );
213
+ }
214
+
215
+ return data;
216
+ }
217
+ }
@@ -0,0 +1,64 @@
1
+ import { Bytes } from '@did-btcr2/common';
2
+ import { RawTransactionRest, RestApiCallParams } from './index.js';
3
+
4
+ export class BitcoinTransaction {
5
+ private api: (params: RestApiCallParams) => Promise<any>;
6
+
7
+ constructor(api: (params: RestApiCallParams) => Promise<any>) {
8
+ this.api = api;
9
+ }
10
+
11
+ /**
12
+ * Returns the transaction in JSON format.
13
+ * See {@link https://github.com/blockstream/esplora/blob/master/API.md#get-txtxid | Esplora GET /tx/:txid } for details.
14
+ * @param {string} txid The transaction id (required).
15
+ * @returns {GetRawTransaction} A promise resolving to data about a transaction in the form specified by verbosity.
16
+ */
17
+ public async get(txid: string): Promise<RawTransactionRest> {
18
+ return await this.api({ path: `/tx/${txid}` });
19
+ }
20
+
21
+ /**
22
+ * Returns the transaction in JSON format.
23
+ * See {@link https://github.com/blockstream/esplora/blob/master/API.md#get-txtxid | Esplora GET /tx/:txid } for details.
24
+ * @param {string} txid The transaction id (required).
25
+ * @returns {GetRawTransaction} A promise resolving to data about a transaction in the form specified by verbosity.
26
+ */
27
+ public async isConfirmed(txid: string): Promise<boolean> {
28
+ const tx = await this.get(txid);
29
+ return tx.status.confirmed;
30
+ }
31
+
32
+ /**
33
+ * Returns the raw transaction in hex or as binary data.
34
+ * See {@link https://github.com/blockstream/esplora/blob/master/API.md#get-txtxidhex | Esplora GET /tx/:txid/hex } and
35
+ * {@link https://github.com/blockstream/esplora/blob/master/API.md#get-txtxidraw | Esplora GET /tx/:txid/raw } for details.
36
+ * @param {string} txid The transaction id (required).
37
+ * @returns {Promise<RawTransactionRest | string>} A promise resolving to the raw transaction in the specified format.
38
+ */
39
+ public async getHex(txid: string): Promise<string> {
40
+ return await this.api({ path: `/tx/${txid}/hex` });
41
+ }
42
+
43
+ /**
44
+ * Returns the raw transaction in hex or as binary data.
45
+ * See {@link https://github.com/blockstream/esplora/blob/master/API.md#get-txtxidhex | Esplora GET /tx/:txid/hex } and
46
+ * {@link https://github.com/blockstream/esplora/blob/master/API.md#get-txtxidraw | Esplora GET /tx/:txid/raw } for details.
47
+ * @param {string} txid The transaction id (required).
48
+ * @returns {Promise<RawTransactionRest | string>} A promise resolving to the raw transaction in the specified format.
49
+ */
50
+ public async getRaw(txid: string): Promise<Bytes> {
51
+ return await this.api({ path: `/tx/${txid}/raw` });
52
+ }
53
+
54
+ /**
55
+ * Broadcast a raw transaction to the network. The transaction should be provided as hex in the request body. The txid
56
+ * will be returned on success.
57
+ * See {@link https://github.com/blockstream/esplora/blob/master/API.md#post-tx | Esplora POST /tx } for details.
58
+ * @param {string} tx The raw transaction in hex format (required).
59
+ * @returns {Promise<string>} The transaction id of the broadcasted transaction.
60
+ */
61
+ public async send(tx: string): Promise<string> {
62
+ return await this.api({ path: '/tx', method: 'POST', body: tx, headers: { 'Content-Type': 'text/plain' } });
63
+ }
64
+ }