@btc-vision/transaction 1.8.7-beta.0 → 1.8.8

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 (36) hide show
  1. package/browser/btc-vision-bitcoin.js +832 -828
  2. package/browser/index.js +1074 -947
  3. package/browser/noble-curves.js +1183 -2156
  4. package/browser/noble-hashes.js +88 -88
  5. package/browser/rolldown-runtime.js +26 -19
  6. package/browser/src/epoch/validator/EpochValidator.d.ts +28 -6
  7. package/browser/src/transaction/builders/TransactionBuilder.d.ts +1 -0
  8. package/browser/src/transaction/offline/OfflineTransactionManager.d.ts +50 -0
  9. package/browser/src/transaction/offline/interfaces/ISerializableState.d.ts +10 -2
  10. package/browser/vendors.js +3267 -3229
  11. package/build/epoch/validator/EpochValidator.d.ts +28 -6
  12. package/build/epoch/validator/EpochValidator.js +44 -10
  13. package/build/transaction/TransactionFactory.js +1 -1
  14. package/build/transaction/builders/FundingTransaction.js +17 -13
  15. package/build/transaction/builders/TransactionBuilder.d.ts +1 -0
  16. package/build/transaction/builders/TransactionBuilder.js +32 -7
  17. package/build/transaction/offline/OfflineTransactionManager.d.ts +50 -0
  18. package/build/transaction/offline/OfflineTransactionManager.js +142 -1
  19. package/build/transaction/offline/TransactionSerializer.js +9 -0
  20. package/build/transaction/offline/interfaces/ISerializableState.d.ts +10 -2
  21. package/build/transaction/offline/interfaces/ISerializableState.js +3 -2
  22. package/build/transaction/shared/TweakedTransaction.js +27 -5
  23. package/package.json +1 -1
  24. package/src/epoch/validator/EpochValidator.ts +67 -6
  25. package/src/transaction/TransactionFactory.ts +1 -1
  26. package/src/transaction/builders/FundingTransaction.ts +21 -16
  27. package/src/transaction/builders/TransactionBuilder.ts +46 -10
  28. package/src/transaction/offline/OfflineTransactionManager.ts +191 -1
  29. package/src/transaction/offline/TransactionSerializer.ts +11 -0
  30. package/src/transaction/offline/interfaces/ISerializableState.ts +10 -2
  31. package/src/transaction/shared/TweakedTransaction.ts +33 -5
  32. package/test/add-refund-output.test.ts +96 -11
  33. package/test/csv-multisig-offline-edges.test.ts +293 -0
  34. package/test/csv-multisig-offline.test.ts +202 -0
  35. package/test/transaction-builders.test.ts +69 -3
  36. package/tsconfig.build.tsbuildinfo +1 -1
@@ -177,7 +177,7 @@ describe('Transaction Builders - End-to-End', () => {
177
177
  await expect(tx.signTransaction()).rejects.toThrow(/Insufficient funds/);
178
178
  });
179
179
 
180
- it('should tolerate small fee estimation shortfalls when effective fee is still positive', async () => {
180
+ it('should tolerate small fee estimation shortfalls when amount + effective fee is near to input utxos', async () => {
181
181
  // When amount is close to totalInputAmount but leaves some sats for
182
182
  // fees, the estimated fee may exceed what's available. As long as the
183
183
  // effective fee (totalInputAmount - amountSpent) is positive, the
@@ -187,7 +187,7 @@ describe('Transaction Builders - End-to-End', () => {
187
187
 
188
188
  // Leave 200 sats for fees , less than the estimated ~77 sats/vB * ~77 vB
189
189
  // but still a positive effective fee
190
- const amount = utxoValue - 200n;
190
+ const amount = utxoValue - 1110n;
191
191
 
192
192
  const tx = new FundingTransaction({
193
193
  signer,
@@ -209,7 +209,31 @@ describe('Transaction Builders - End-to-End', () => {
209
209
 
210
210
  // Verify fee is exactly what was left over
211
211
  const totalOutputValue = signed.outs.reduce((sum, out) => sum + BigInt(out.value), 0n);
212
- expect(utxoValue - totalOutputValue).toBe(200n);
212
+ expect(utxoValue - totalOutputValue).toBe(1110n);
213
+ });
214
+
215
+ it('should throw when leftover fee would underpay feeRate (no autoAdjust)', async () => {
216
+ // When amount is close to totalInputAmount but leaves less than the
217
+ // fee implied by feeRate, the transaction must NOT broadcast with an
218
+ // underpaid fee. Callers wanting send-max behavior must opt in via
219
+ // autoAdjustAmount=true.
220
+ const utxoValue = 100_000n;
221
+ const utxo = createTaprootUtxo(taprootAddress, utxoValue);
222
+ const amount = utxoValue - 200n;
223
+
224
+ const tx = new FundingTransaction({
225
+ signer,
226
+ network,
227
+ utxos: [utxo],
228
+ to: taprootAddress,
229
+ amount,
230
+ feeRate: 10,
231
+ priorityFee: 0n,
232
+ gasSatFee: 0n,
233
+ mldsaSigner: null,
234
+ });
235
+
236
+ await expect(tx.signTransaction()).rejects.toThrow(/Insufficient funds for fee/);
213
237
  });
214
238
 
215
239
  it('should auto-adjust amount when amount equals total UTXO value with autoAdjustAmount', async () => {
@@ -248,6 +272,48 @@ describe('Transaction Builders - End-to-End', () => {
248
272
  expect(fee).toBeLessThanOrEqual(expectedFee + 10n);
249
273
  });
250
274
 
275
+ it('should auto-adjust amount when amount + fees is higher than total UTXO value with autoAdjustAmount', async () => {
276
+ const amount = 100_000n;
277
+ const utxoValue = 100_100n; // Only 100 sats available for fees
278
+ const utxo = createTaprootUtxo(taprootAddress, utxoValue);
279
+ const feeRate = 2;
280
+
281
+ const tx = new FundingTransaction({
282
+ signer,
283
+ network,
284
+ utxos: [utxo],
285
+ to: taprootAddress,
286
+ amount: amount,
287
+ autoAdjustAmount: true,
288
+ feeRate,
289
+ priorityFee: 0n,
290
+ gasSatFee: 0n,
291
+ mldsaSigner: null,
292
+ });
293
+
294
+ const signed = await tx.signTransaction();
295
+
296
+ expect(signed.ins.length).toBeGreaterThan(0);
297
+ expect(signed.outs.length).toBeGreaterThan(0);
298
+ expect(signed.toHex()).toBeTruthy();
299
+
300
+ // Calculate total ouput for following tests
301
+ const totalOutputValue = signed.outs.reduce((sum, out) => sum + BigInt(out.value), 0n);
302
+
303
+ // The fee should be roughly feeRate * virtualSize
304
+ const fee = utxoValue - totalOutputValue;
305
+ const expectedFee = BigInt(Math.ceil(feeRate * signed.virtualSize()));
306
+ // Allow small variance due to fee estimation iterations
307
+ expect(fee).toBeGreaterThan(0n);
308
+ expect(fee).toBeGreaterThanOrEqual(expectedFee - 10n);
309
+ expect(fee).toBeLessThanOrEqual(expectedFee + 10n);
310
+
311
+ // The total output value should be less than utxoValue (fees deducted)
312
+ const expectedAmount = utxoValue - expectedFee;
313
+ expect(totalOutputValue).toBeLessThan(expectedAmount + 10n);
314
+ expect(totalOutputValue).toBeGreaterThan(expectedAmount - 10n);
315
+ });
316
+
251
317
  it('should not adjust amount when autoAdjustAmount is true but amount < totalInputAmount', async () => {
252
318
  const utxoValue = 100_000n;
253
319
  const sendAmount = 50_000n;