@btc-vision/transaction 1.0.105 → 1.0.106

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,5 +1,7 @@
1
1
  import { Address } from '@btc-vision/bsi-binary';
2
+ import { Network } from 'bitcoinjs-lib';
2
3
  import { currentConsensusConfig } from '../consensus/ConsensusConfig.js';
4
+ import { IFundingTransactionParameters, TransactionFactory, Wallet } from '../opnet.js';
3
5
  import { UnwrappedGenerationParameters, WrappedGenerationParameters } from '../wbtc/Generate.js';
4
6
  import { UnwrapGeneration } from '../wbtc/UnwrapGeneration.js';
5
7
  import { WrappedGeneration } from '../wbtc/WrappedGenerationParameters.js';
@@ -11,6 +13,12 @@ import {
11
13
  UTXO,
12
14
  } from './interfaces/IUTXO.js';
13
15
 
16
+ export interface WalletUTXOs {
17
+ readonly confirmed: RawUTXOResponse[];
18
+ readonly pending: RawUTXOResponse[];
19
+ readonly spentTransactions: RawUTXOResponse[];
20
+ }
21
+
14
22
  /**
15
23
  * Allows to fetch UTXO data from any OPNET node
16
24
  */
@@ -18,7 +26,7 @@ export class OPNetLimitedProvider {
18
26
  private readonly utxoPath: string = 'address/utxos';
19
27
  private readonly rpc: string = 'json-rpc';
20
28
 
21
- constructor(private readonly opnetAPIUrl: string) {}
29
+ public constructor(private readonly opnetAPIUrl: string) {}
22
30
 
23
31
  /**
24
32
  * Fetches UTXO data from the OPNET node
@@ -27,6 +35,14 @@ export class OPNetLimitedProvider {
27
35
  * @throws {Error} - If UTXOs could not be fetched
28
36
  */
29
37
  public async fetchUTXO(settings: FetchUTXOParams): Promise<UTXO[]> {
38
+ if (settings.usePendingUTXO === undefined) {
39
+ settings.usePendingUTXO = true;
40
+ }
41
+
42
+ if (settings.optimized === undefined) {
43
+ settings.optimized = true;
44
+ }
45
+
30
46
  const params = {
31
47
  method: 'GET',
32
48
  headers: {
@@ -41,12 +57,31 @@ export class OPNetLimitedProvider {
41
57
  throw new Error(`Failed to fetch UTXO data: ${resp.statusText}`);
42
58
  }
43
59
 
44
- const fetchedData: RawUTXOResponse[] = (await resp.json()) as RawUTXOResponse[];
45
- if (fetchedData.length === 0) {
60
+ const fetchedData: WalletUTXOs = (await resp.json()) as WalletUTXOs;
61
+ const allUtxos = settings.usePendingUTXO
62
+ ? [...fetchedData.confirmed, ...fetchedData.pending]
63
+ : fetchedData.confirmed;
64
+
65
+ const unspentUTXOs: RawUTXOResponse[] = [];
66
+ for (const utxo of allUtxos) {
67
+ if (
68
+ fetchedData.spentTransactions.some(
69
+ (spent) =>
70
+ spent.transactionId === utxo.transactionId &&
71
+ spent.outputIndex === utxo.outputIndex,
72
+ )
73
+ ) {
74
+ continue;
75
+ }
76
+
77
+ unspentUTXOs.push(utxo);
78
+ }
79
+
80
+ if (unspentUTXOs.length === 0) {
46
81
  throw new Error('No UTXO found');
47
82
  }
48
83
 
49
- const meetCriteria: RawUTXOResponse[] = fetchedData.filter((utxo: RawUTXOResponse) => {
84
+ const meetCriteria: RawUTXOResponse[] = unspentUTXOs.filter((utxo: RawUTXOResponse) => {
50
85
  return BigInt(utxo.value) >= settings.minAmount;
51
86
  });
52
87
 
@@ -97,6 +132,7 @@ export class OPNetLimitedProvider {
97
132
  minAmount: settings.minAmount,
98
133
  requestedAmount: settings.requestedAmount,
99
134
  optimized: settings.optimized,
135
+ usePendingUTXO: false,
100
136
  };
101
137
 
102
138
  const promise = this.fetchUTXO(params).catch(() => {
@@ -145,6 +181,52 @@ export class OPNetLimitedProvider {
145
181
  return result as BroadcastResponse;
146
182
  }
147
183
 
184
+ /**
185
+ * Splits UTXOs into smaller UTXOs
186
+ * @param {Wallet} wallet - The wallet to split UTXOs
187
+ * @param {Network} network - The network to split UTXOs
188
+ * @param {number} splitInputsInto - The number of UTXOs to split into
189
+ * @param {bigint} amountPerUTXO - The amount per UTXO
190
+ * @returns {Promise<BroadcastResponse | { error: string }>} - The response from the OPNET node or an error
191
+ */
192
+ public async splitUTXOs(
193
+ wallet: Wallet,
194
+ network: Network,
195
+ splitInputsInto: number,
196
+ amountPerUTXO: bigint,
197
+ ): Promise<BroadcastResponse | { error: string }> {
198
+ const utxoSetting: FetchUTXOParamsMultiAddress = {
199
+ addresses: [wallet.p2wpkh, wallet.p2tr],
200
+ minAmount: 330n,
201
+ requestedAmount: 1_000_000_000_000_000n,
202
+ };
203
+
204
+ const utxos: UTXO[] = await this.fetchUTXOMultiAddr(utxoSetting);
205
+ if (!utxos || !utxos.length) return { error: 'No UTXOs found' };
206
+
207
+ const amount = BigInt(splitInputsInto) * amountPerUTXO;
208
+
209
+ const fundingTransactionParameters: IFundingTransactionParameters = {
210
+ amount: amount,
211
+ feeRate: 500,
212
+ from: wallet.p2tr,
213
+ utxos: utxos,
214
+ signer: wallet.keypair,
215
+ network,
216
+ to: wallet.p2tr,
217
+ splitInputsInto,
218
+ priorityFee: 330n,
219
+ };
220
+
221
+ const transactionFactory = new TransactionFactory();
222
+ const fundingTx = await transactionFactory.createBTCTransfer(fundingTransactionParameters);
223
+
224
+ const broadcastResponse = await this.broadcastTransaction(fundingTx.tx, false);
225
+ if (!broadcastResponse) return { error: 'Could not broadcast transaction' };
226
+
227
+ return broadcastResponse;
228
+ }
229
+
148
230
  /**
149
231
  * Fetches to the OPNET node
150
232
  * @param {string} method
@@ -11,7 +11,8 @@ export interface FetchUTXOParams {
11
11
  readonly address: string;
12
12
  readonly minAmount: bigint;
13
13
  readonly requestedAmount: bigint;
14
- readonly optimized?: boolean;
14
+ optimized?: boolean;
15
+ usePendingUTXO?: boolean;
15
16
  }
16
17
 
17
18
  export interface FetchUTXOParamsMultiAddress {