@btc-vision/transaction 1.0.86 → 1.0.88

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.
@@ -1,244 +1,244 @@
1
- import { FetchUTXOParams, FetchUTXOParamsMultiAddress, RawUTXOResponse, UTXO } from './interfaces/IUTXO.js';
2
- import { WrappedGeneration } from '../wbtc/WrappedGenerationParameters.js';
3
- import { UnwrappedGenerationParameters, WrappedGenerationParameters } from '../wbtc/Generate.js';
4
- import { BroadcastResponse } from './interfaces/BroadcastResponse.js';
5
- import { Address } from '@btc-vision/bsi-binary';
6
- import { UnwrapGeneration } from '../wbtc/UnwrapGeneration.js';
7
- import { currentConsensusConfig } from '../consensus/ConsensusConfig.js';
8
-
9
- /**
10
- * Allows to fetch UTXO data from any OPNET node
11
- */
12
- export class OPNetLimitedProvider {
13
- private readonly utxoPath: string = 'address/utxos';
14
- private readonly rpc: string = 'json-rpc';
15
-
16
- constructor(private readonly opnetAPIUrl: string) {}
17
-
18
- /**
19
- * Fetches UTXO data from the OPNET node
20
- * @param {FetchUTXOParams} settings - The settings to fetch UTXO data
21
- * @returns {Promise<UTXO[]>} - The UTXOs fetched
22
- * @throws {Error} - If UTXOs could not be fetched
23
- */
24
- public async fetchUTXO(settings: FetchUTXOParams): Promise<UTXO[]> {
25
- const params = {
26
- method: 'GET',
27
- headers: {
28
- 'Content-Type': 'application/json',
29
- },
30
- };
31
-
32
- const url: string = `${this.opnetAPIUrl}/api/v1/${this.utxoPath}?address=${settings.address}&optimize=${settings.optimized ?? false}`;
33
- const resp: Response = await fetch(url, params);
34
-
35
- if (!resp.ok) {
36
- throw new Error(`Failed to fetch UTXO data: ${resp.statusText}`);
37
- }
38
-
39
- const fetchedData: RawUTXOResponse[] = await resp.json();
40
- if (fetchedData.length === 0) {
41
- throw new Error('No UTXO found');
42
- }
43
-
44
- const meetCriteria: RawUTXOResponse[] = fetchedData.filter((utxo: RawUTXOResponse) => {
45
- return BigInt(utxo.value) >= settings.minAmount;
46
- });
47
-
48
- if (meetCriteria.length === 0) {
49
- throw new Error('No UTXO found (minAmount)');
50
- }
51
-
52
- let finalUTXOs: UTXO[] = [];
53
- let currentAmount: bigint = 0n;
54
-
55
- const amountRequested: bigint = settings.requestedAmount;
56
- for (const utxo of meetCriteria) {
57
- const utxoValue: bigint = BigInt(utxo.value);
58
-
59
- // check if value is greater than 0
60
- if (utxoValue <= 0n) {
61
- continue;
62
- }
63
-
64
- currentAmount += utxoValue;
65
- finalUTXOs.push({
66
- transactionId: utxo.transactionId,
67
- outputIndex: utxo.outputIndex,
68
- value: utxoValue,
69
- scriptPubKey: utxo.scriptPubKey,
70
- });
71
-
72
- if (currentAmount > amountRequested) {
73
- break;
74
- }
75
- }
76
-
77
- return finalUTXOs;
78
- }
79
-
80
- /**
81
- * Fetches UTXO data from the OPNET node for multiple addresses
82
- * @param {FetchUTXOParamsMultiAddress} settings - The settings to fetch UTXO data
83
- * @returns {Promise<UTXO[]>} - The UTXOs fetched
84
- * @throws {Error} - If UTXOs could not be fetched
85
- */
86
- public async fetchUTXOMultiAddr(settings: FetchUTXOParamsMultiAddress): Promise<UTXO[]> {
87
- const promises: Promise<UTXO[]>[] = [];
88
-
89
- for (let address of settings.addresses) {
90
- const params: FetchUTXOParams = {
91
- address: address,
92
- minAmount: settings.minAmount,
93
- requestedAmount: settings.requestedAmount,
94
- optimized: settings.optimized,
95
- };
96
-
97
- const promise = this.fetchUTXO(params).catch(() => {
98
- return [];
99
- });
100
-
101
- promises.push(promise);
102
- }
103
-
104
- const utxos: UTXO[][] = await Promise.all(promises);
105
- const all = utxos.flat();
106
-
107
- const finalUTXOs: UTXO[] = [];
108
- let currentAmount = 0n;
109
- for (let i = 0; i < all.length; i++) {
110
- let utxo = all[i];
111
-
112
- if (currentAmount >= settings.requestedAmount) {
113
- break;
114
- }
115
-
116
- currentAmount += utxo.value;
117
- finalUTXOs.push(utxo);
118
- }
119
-
120
- return finalUTXOs;
121
- }
122
-
123
- /**
124
- * Broadcasts a transaction to the OPNET node
125
- * @param {string} transaction - The transaction to broadcast
126
- * @param {boolean} psbt - Whether the transaction is a PSBT
127
- * @returns {Promise<BroadcastResponse>} - The response from the OPNET node
128
- */
129
- public async broadcastTransaction(
130
- transaction: string,
131
- psbt: boolean,
132
- ): Promise<BroadcastResponse | undefined> {
133
- const params = [transaction, psbt];
134
- const result = await this.rpcMethod('btc_sendRawTransaction', params);
135
-
136
- if (!result) {
137
- return;
138
- }
139
-
140
- return result as BroadcastResponse;
141
- }
142
-
143
- /**
144
- * Fetches to the OPNET node
145
- * @param {string} method
146
- * @param {unknown[]} paramsMethod
147
- * @returns {Promise<unknown>}
148
- */
149
- public async rpcMethod(method: string, paramsMethod: unknown[]): Promise<unknown> {
150
- const params = {
151
- method: 'POST',
152
- headers: {
153
- 'Content-Type': 'application/json',
154
- },
155
- body: JSON.stringify({
156
- jsonrpc: '2.0',
157
- method: method,
158
- params: paramsMethod,
159
- id: 1,
160
- }),
161
- };
162
-
163
- const url: string = `${this.opnetAPIUrl}/api/v1/${this.rpc}`;
164
-
165
- try {
166
- const resp: Response = await fetch(url, params);
167
- if (!resp.ok) {
168
- throw new Error(`Failed to fetch to rpc: ${resp.statusText}`);
169
- }
170
-
171
- const fetchedData = await resp.json();
172
- if (!fetchedData) {
173
- throw new Error('No data fetched');
174
- }
175
-
176
- const result = fetchedData.result;
177
- if (!result) {
178
- throw new Error('No rpc parameters found');
179
- }
180
-
181
- if ('error' in result) {
182
- throw new Error(`Error in fetching to rpc ${result.error}`);
183
- }
184
-
185
- return result;
186
- } catch (e) {
187
- console.error(`Failed to fetch wrap parameters: ${(e as Error).stack}`);
188
- }
189
- }
190
-
191
- /**
192
- * Fetches the wrap parameters from the OPNET node
193
- * @param {bigint} amount - The amount to wrap
194
- * @returns {Promise<WrappedGeneration | undefined>} - The wrap parameters fetched
195
- * @throws {Error} - If wrap parameters could not be fetched
196
- */
197
- public async fetchWrapParameters(amount: bigint): Promise<WrappedGeneration | undefined> {
198
- if (amount < currentConsensusConfig.VAULT_MINIMUM_AMOUNT) {
199
- throw new Error(
200
- `Amount must be greater than the minimum consolidation amount ${currentConsensusConfig.VAULT_MINIMUM_AMOUNT}sat.`,
201
- );
202
- }
203
-
204
- const params = [0, amount.toString()];
205
- const result = await this.rpcMethod('btc_generate', params);
206
-
207
- if (!result) {
208
- return;
209
- }
210
-
211
- return new WrappedGeneration(result as WrappedGenerationParameters);
212
- }
213
-
214
- /**
215
- * Fetches the wrap parameters from the OPNET node
216
- * @param {bigint} amount - The amount to wrap
217
- * @param {Address} receiver - The receiver address
218
- * @returns {Promise<UnwrapGeneration | undefined>} - The wrap parameters fetched
219
- * @throws {Error} - If wrap parameters could not be fetched
220
- */
221
- public async fetchUnWrapParameters(
222
- amount: bigint,
223
- receiver: Address,
224
- ): Promise<UnwrapGeneration | undefined> {
225
- if (amount < 330n) {
226
- throw new Error(
227
- `Amount must be greater than the minimum consolidation amount ${currentConsensusConfig.VAULT_MINIMUM_AMOUNT}sat.`,
228
- );
229
- }
230
-
231
- if (receiver.length < 50) {
232
- throw new Error('Invalid receiver address');
233
- }
234
-
235
- const params = [1, amount.toString(), receiver];
236
- const result = await this.rpcMethod('btc_generate', params);
237
-
238
- if (!result) {
239
- return;
240
- }
241
-
242
- return new UnwrapGeneration(result as UnwrappedGenerationParameters);
243
- }
244
- }
1
+ import { FetchUTXOParams, FetchUTXOParamsMultiAddress, RawUTXOResponse, UTXO } from './interfaces/IUTXO.js';
2
+ import { WrappedGeneration } from '../wbtc/WrappedGenerationParameters.js';
3
+ import { UnwrappedGenerationParameters, WrappedGenerationParameters } from '../wbtc/Generate.js';
4
+ import { BroadcastResponse } from './interfaces/BroadcastResponse.js';
5
+ import { Address } from '@btc-vision/bsi-binary';
6
+ import { UnwrapGeneration } from '../wbtc/UnwrapGeneration.js';
7
+ import { currentConsensusConfig } from '../consensus/ConsensusConfig.js';
8
+
9
+ /**
10
+ * Allows to fetch UTXO data from any OPNET node
11
+ */
12
+ export class OPNetLimitedProvider {
13
+ private readonly utxoPath: string = 'address/utxos';
14
+ private readonly rpc: string = 'json-rpc';
15
+
16
+ constructor(private readonly opnetAPIUrl: string) {}
17
+
18
+ /**
19
+ * Fetches UTXO data from the OPNET node
20
+ * @param {FetchUTXOParams} settings - The settings to fetch UTXO data
21
+ * @returns {Promise<UTXO[]>} - The UTXOs fetched
22
+ * @throws {Error} - If UTXOs could not be fetched
23
+ */
24
+ public async fetchUTXO(settings: FetchUTXOParams): Promise<UTXO[]> {
25
+ const params = {
26
+ method: 'GET',
27
+ headers: {
28
+ 'Content-Type': 'application/json',
29
+ },
30
+ };
31
+
32
+ const url: string = `${this.opnetAPIUrl}/api/v1/${this.utxoPath}?address=${settings.address}&optimize=${settings.optimized ?? false}`;
33
+ const resp: Response = await fetch(url, params);
34
+
35
+ if (!resp.ok) {
36
+ throw new Error(`Failed to fetch UTXO data: ${resp.statusText}`);
37
+ }
38
+
39
+ const fetchedData: RawUTXOResponse[] = await resp.json();
40
+ if (fetchedData.length === 0) {
41
+ throw new Error('No UTXO found');
42
+ }
43
+
44
+ const meetCriteria: RawUTXOResponse[] = fetchedData.filter((utxo: RawUTXOResponse) => {
45
+ return BigInt(utxo.value) >= settings.minAmount;
46
+ });
47
+
48
+ if (meetCriteria.length === 0) {
49
+ throw new Error('No UTXO found (minAmount)');
50
+ }
51
+
52
+ let finalUTXOs: UTXO[] = [];
53
+ let currentAmount: bigint = 0n;
54
+
55
+ const amountRequested: bigint = settings.requestedAmount;
56
+ for (const utxo of meetCriteria) {
57
+ const utxoValue: bigint = BigInt(utxo.value);
58
+
59
+ // check if value is greater than 0
60
+ if (utxoValue <= 0n) {
61
+ continue;
62
+ }
63
+
64
+ currentAmount += utxoValue;
65
+ finalUTXOs.push({
66
+ transactionId: utxo.transactionId,
67
+ outputIndex: utxo.outputIndex,
68
+ value: utxoValue,
69
+ scriptPubKey: utxo.scriptPubKey,
70
+ });
71
+
72
+ if (currentAmount > amountRequested) {
73
+ break;
74
+ }
75
+ }
76
+
77
+ return finalUTXOs;
78
+ }
79
+
80
+ /**
81
+ * Fetches UTXO data from the OPNET node for multiple addresses
82
+ * @param {FetchUTXOParamsMultiAddress} settings - The settings to fetch UTXO data
83
+ * @returns {Promise<UTXO[]>} - The UTXOs fetched
84
+ * @throws {Error} - If UTXOs could not be fetched
85
+ */
86
+ public async fetchUTXOMultiAddr(settings: FetchUTXOParamsMultiAddress): Promise<UTXO[]> {
87
+ const promises: Promise<UTXO[]>[] = [];
88
+
89
+ for (let address of settings.addresses) {
90
+ const params: FetchUTXOParams = {
91
+ address: address,
92
+ minAmount: settings.minAmount,
93
+ requestedAmount: settings.requestedAmount,
94
+ optimized: settings.optimized,
95
+ };
96
+
97
+ const promise = this.fetchUTXO(params).catch(() => {
98
+ return [];
99
+ });
100
+
101
+ promises.push(promise);
102
+ }
103
+
104
+ const utxos: UTXO[][] = await Promise.all(promises);
105
+ const all = utxos.flat();
106
+
107
+ const finalUTXOs: UTXO[] = [];
108
+ let currentAmount = 0n;
109
+ for (let i = 0; i < all.length; i++) {
110
+ let utxo = all[i];
111
+
112
+ if (currentAmount >= settings.requestedAmount) {
113
+ break;
114
+ }
115
+
116
+ currentAmount += utxo.value;
117
+ finalUTXOs.push(utxo);
118
+ }
119
+
120
+ return finalUTXOs;
121
+ }
122
+
123
+ /**
124
+ * Broadcasts a transaction to the OPNET node
125
+ * @param {string} transaction - The transaction to broadcast
126
+ * @param {boolean} psbt - Whether the transaction is a PSBT
127
+ * @returns {Promise<BroadcastResponse>} - The response from the OPNET node
128
+ */
129
+ public async broadcastTransaction(
130
+ transaction: string,
131
+ psbt: boolean,
132
+ ): Promise<BroadcastResponse | undefined> {
133
+ const params = [transaction, psbt];
134
+ const result = await this.rpcMethod('btc_sendRawTransaction', params);
135
+
136
+ if (!result) {
137
+ return;
138
+ }
139
+
140
+ return result as BroadcastResponse;
141
+ }
142
+
143
+ /**
144
+ * Fetches to the OPNET node
145
+ * @param {string} method
146
+ * @param {unknown[]} paramsMethod
147
+ * @returns {Promise<unknown>}
148
+ */
149
+ public async rpcMethod(method: string, paramsMethod: unknown[]): Promise<unknown> {
150
+ const params = {
151
+ method: 'POST',
152
+ headers: {
153
+ 'Content-Type': 'application/json',
154
+ },
155
+ body: JSON.stringify({
156
+ jsonrpc: '2.0',
157
+ method: method,
158
+ params: paramsMethod,
159
+ id: 1,
160
+ }),
161
+ };
162
+
163
+ const url: string = `${this.opnetAPIUrl}/api/v1/${this.rpc}`;
164
+
165
+ //try {
166
+ const resp: Response = await fetch(url, params);
167
+ if (!resp.ok) {
168
+ throw new Error(`Failed to fetch to rpc: ${resp.statusText}`);
169
+ }
170
+
171
+ const fetchedData = await resp.json();
172
+ if (!fetchedData) {
173
+ throw new Error('No data fetched');
174
+ }
175
+
176
+ const result = fetchedData.result;
177
+ if (!result) {
178
+ throw new Error('No rpc parameters found');
179
+ }
180
+
181
+ if ('error' in result) {
182
+ throw new Error(`Error in fetching to rpc ${result.error}`);
183
+ }
184
+
185
+ return result;
186
+ //} catch (e) {
187
+ // throw e;
188
+ //}
189
+ }
190
+
191
+ /**
192
+ * Fetches the wrap parameters from the OPNET node
193
+ * @param {bigint} amount - The amount to wrap
194
+ * @returns {Promise<WrappedGeneration | undefined>} - The wrap parameters fetched
195
+ * @throws {Error} - If wrap parameters could not be fetched
196
+ */
197
+ public async fetchWrapParameters(amount: bigint): Promise<WrappedGeneration | undefined> {
198
+ if (amount < currentConsensusConfig.VAULT_MINIMUM_AMOUNT) {
199
+ throw new Error(
200
+ `Amount must be greater than the minimum consolidation amount ${currentConsensusConfig.VAULT_MINIMUM_AMOUNT}sat.`,
201
+ );
202
+ }
203
+
204
+ const params = [0, amount.toString()];
205
+ const result = await this.rpcMethod('btc_generate', params);
206
+
207
+ if (!result) {
208
+ return;
209
+ }
210
+
211
+ return new WrappedGeneration(result as WrappedGenerationParameters);
212
+ }
213
+
214
+ /**
215
+ * Fetches the wrap parameters from the OPNET node
216
+ * @param {bigint} amount - The amount to wrap
217
+ * @param {Address} receiver - The receiver address
218
+ * @returns {Promise<UnwrapGeneration | undefined>} - The wrap parameters fetched
219
+ * @throws {Error} - If wrap parameters could not be fetched
220
+ */
221
+ public async fetchUnWrapParameters(
222
+ amount: bigint,
223
+ receiver: Address,
224
+ ): Promise<UnwrapGeneration | undefined> {
225
+ if (amount < 330n) {
226
+ throw new Error(
227
+ `Amount must be greater than the minimum consolidation amount ${currentConsensusConfig.VAULT_MINIMUM_AMOUNT}sat.`,
228
+ );
229
+ }
230
+
231
+ if (receiver.length < 50) {
232
+ throw new Error('Invalid receiver address');
233
+ }
234
+
235
+ const params = [1, amount.toString(), receiver];
236
+ const result = await this.rpcMethod('btc_generate', params);
237
+
238
+ if (!result) {
239
+ return;
240
+ }
241
+
242
+ return new UnwrapGeneration(result as UnwrappedGenerationParameters);
243
+ }
244
+ }