@bsv/wallet-toolbox 1.1.31 → 1.1.33

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/wallet-toolbox",
3
- "version": "1.1.31",
3
+ "version": "1.1.33",
4
4
  "description": "BRC100 conforming wallet, wallet storage and wallet signer components",
5
5
  "main": "./out/src/index.js",
6
6
  "types": "./out/src/index.d.ts",
package/src/Wallet.ts CHANGED
@@ -116,6 +116,12 @@ export class Wallet implements WalletInterface, ProtoWallet {
116
116
  * Over time, this allows an active wallet to drastically reduce the amount of data transmitted.
117
117
  */
118
118
  beef: BeefParty
119
+ /**
120
+ * If true, signableTransactions will include sourceTransaction for each input,
121
+ * including those that do not require signature and those that were also contained
122
+ * in the inputBEEF.
123
+ */
124
+ includeAllSourceTransactions: boolean = true
119
125
  /**
120
126
  * If true, beefs returned to the user may contain txidOnly transactions.
121
127
  */
@@ -676,42 +682,19 @@ export class Wallet implements WalletInterface, ProtoWallet {
676
682
  args,
677
683
  sdk.validateCreateActionArgs
678
684
  )
685
+ vargs.includeAllSourceTransactions = this.includeAllSourceTransactions
679
686
  if (this.randomVals && this.randomVals.length > 1) {
680
687
  vargs.randomVals = [...this.randomVals]
681
688
  }
682
689
 
683
690
  const r = await createAction(this, auth, vargs)
684
691
 
685
- if (r.signableTransaction) {
686
- const st = r.signableTransaction
687
- const ab = Beef.fromBinary(st.tx)
688
- if (!ab.atomicTxid)
689
- throw new sdk.WERR_INTERNAL(
690
- 'Missing atomicTxid in signableTransaction result'
691
- )
692
- if (ab.txs.length < 1 || ab.txs[ab.txs.length - 1].txid !== ab.atomicTxid)
693
- throw new sdk.WERR_INTERNAL(
694
- 'atomicTxid does not match txid of last AtomicBEEF transaction'
695
- )
696
- // Merge the inputBEEF into the beef going back to the user for lockingScripts.
697
- if (vargs.inputBEEF) {
698
- ab.mergeBeef(vargs.inputBEEF)
699
- r.signableTransaction.tx = ab.toBinaryAtomic(ab.atomicTxid)
700
- }
701
- // Remove the new, partially constructed transaction from beef as it will never be a valid transaction.
702
- ab.txs.slice(ab.txs.length - 1)
703
- this.beef.mergeBeefFromParty(this.storageParty, ab)
704
- } else if (r.tx) {
692
+ if (r.tx) {
705
693
  this.beef.mergeBeefFromParty(this.storageParty, r.tx)
706
694
  }
707
695
 
708
696
  if (r.tx) r.tx = this.verifyReturnedTxidOnlyAtomicBEEF(r.tx)
709
697
 
710
- if (r.signableTransaction?.tx)
711
- r.signableTransaction.tx = this.verifyReturnedTxidOnlyAtomicBEEF(
712
- r.signableTransaction.tx
713
- )
714
-
715
698
  if (
716
699
  !vargs.options.acceptDelayedBroadcast &&
717
700
  r.sendWithResults &&
@@ -244,6 +244,10 @@ export interface StorageCreateTransactionSdkInput {
244
244
  sourceVout: number
245
245
  sourceSatoshis: number
246
246
  sourceLockingScript: string
247
+ /**
248
+ *
249
+ */
250
+ sourceTransaction?: number[]
247
251
  unlockingScriptLength: number
248
252
  providedBy: StorageProvidedBy
249
253
  type: string
@@ -404,6 +404,12 @@ export interface ValidCreateActionArgs extends ValidProcessActionArgs {
404
404
  // true if transaction creation completion will require a `signAction` call.
405
405
  isSignAction: boolean
406
406
  randomVals?: number[]
407
+ /**
408
+ * If true, signableTransactions will include sourceTransaction for each input,
409
+ * including those that do not require signature and those that were also contained
410
+ * in the inputBEEF.
411
+ */
412
+ includeAllSourceTransactions: boolean
407
413
  }
408
414
 
409
415
  export interface ValidSignActionArgs extends ValidProcessActionArgs {
@@ -430,7 +436,8 @@ export function validateCreateActionArgs(
430
436
  isNoSend: false,
431
437
  isNewTx: false,
432
438
  isSignAction: false,
433
- randomVals: undefined
439
+ randomVals: undefined,
440
+ includeAllSourceTransactions: false
434
441
  }
435
442
  vargs.isSendWith = vargs.options.sendWith.length > 0
436
443
  vargs.isNewTx = vargs.inputs.length > 0 || vargs.outputs.length > 0
@@ -1,4 +1,5 @@
1
1
  import {
2
+ Beef,
2
3
  CreateActionResult,
3
4
  SendWithResult,
4
5
  SignActionResult,
@@ -79,7 +80,7 @@ function makeSignableTransactionResult(
79
80
  : undefined,
80
81
  signableTransaction: {
81
82
  reference: prior.dcr.reference,
82
- tx: makeAtomicBeef(prior.tx, prior.dcr.inputBeef)
83
+ tx: makeSignableTransactionBeef(prior.tx, prior.dcr.inputBeef)
83
84
  }
84
85
  }
85
86
 
@@ -88,6 +89,21 @@ function makeSignableTransactionResult(
88
89
  return r
89
90
  }
90
91
 
92
+ function makeSignableTransactionBeef(
93
+ tx: Transaction,
94
+ inputBEEF: number[]
95
+ ): number[] {
96
+ for (const input of tx.inputs) {
97
+ if (!input.sourceTransaction)
98
+ throw new sdk.WERR_INTERNAL(
99
+ 'Every signableTransaction input must have a sourceTransaction'
100
+ )
101
+ }
102
+ const beef = new Beef()
103
+ beef.mergeTransaction(tx)
104
+ return beef.toBinaryAtomic(tx.id('hex'))
105
+ }
106
+
91
107
  /**
92
108
  * Derive a change output locking script
93
109
  */
@@ -230,6 +246,8 @@ function buildSignableTransaction(
230
246
  } {
231
247
  const changeKeys = wallet.getClientChangeKeyPair()
232
248
 
249
+ const inputBeef = args.inputBEEF ? Beef.fromBinary(args.inputBEEF) : undefined
250
+
233
251
  const { inputs: storageInputs, outputs: storageOutputs } = dctr
234
252
 
235
253
  const tx = new Transaction(args.version, [], [], args.lockTime)
@@ -313,9 +331,15 @@ function buildSignableTransaction(
313
331
  const unlock = hasUnlock
314
332
  ? asBsvSdkScript(argsInput.unlockingScript!)
315
333
  : new Script()
334
+ const sourceTransaction = args.isSignAction
335
+ ? inputBeef?.findTxid(argsInput.outpoint.txid)?.tx
336
+ : undefined
316
337
  const inputToAdd: TransactionInput = {
317
338
  sourceTXID: argsInput.outpoint.txid,
318
339
  sourceOutputIndex: argsInput.outpoint.vout,
340
+ // Include the source transaction for access to the outputs locking script and output satoshis for user side fee calculation.
341
+ // TODO: Make this conditional to improve performance when user can supply locking scripts themselves.
342
+ sourceTransaction,
319
343
  unlockingScript: unlock,
320
344
  sequence: argsInput.sequenceNumber
321
345
  }
@@ -340,6 +364,9 @@ function buildSignableTransaction(
340
364
  const inputToAdd: TransactionInput = {
341
365
  sourceTXID: storageInput.sourceTxid,
342
366
  sourceOutputIndex: storageInput.sourceVout,
367
+ sourceTransaction: storageInput.sourceTransaction
368
+ ? Transaction.fromBinary(storageInput.sourceTransaction)
369
+ : undefined,
343
370
  unlockingScript: new Script(),
344
371
  sequence: 0xffffffff
345
372
  }
@@ -362,3 +389,14 @@ function buildSignableTransaction(
362
389
  log: ''
363
390
  }
364
391
  }
392
+
393
+ function makeDummyTransactionForOutputSatoshis(
394
+ vout: number,
395
+ satoshis: number
396
+ ): Transaction {
397
+ const tx = new Transaction()
398
+ for (let i = 0; i < vout; i++)
399
+ tx.addOutput({ lockingScript: new Script(), satoshis: 0 })
400
+ tx.addOutput({ lockingScript: new Script(), satoshis })
401
+ return tx
402
+ }
@@ -268,12 +268,17 @@ async function createNewInputs(
268
268
  throw new sdk.WERR_INTERNAL(
269
269
  `vin ${vin} non-fixedInput without unlockLen`
270
270
  )
271
+ const sourceTransaction =
272
+ vargs.includeAllSourceTransactions && vargs.isSignAction
273
+ ? await storage.getRawTxOfKnownValidTransaction(o.txid!)
274
+ : undefined
271
275
  const ri: sdk.StorageCreateTransactionSdkInput = {
272
276
  vin,
273
277
  sourceTxid: o.txid!,
274
278
  sourceVout: o!.vout!,
275
279
  sourceSatoshis: o.satoshis!,
276
280
  sourceLockingScript: asString(o.lockingScript!),
281
+ sourceTransaction,
277
282
  unlockingScriptLength: unlockLen ? unlockLen : i!.unlockingScriptLength,
278
283
  providedBy:
279
284
  i && o.providedBy === 'storage'
@@ -1503,7 +1503,7 @@ export abstract class TestUtilsWalletStorage {
1503
1503
 
1504
1504
  const st = car2.signableTransaction!
1505
1505
  const stBeef = Beef.fromBinary(st.tx)
1506
- const tx = wallet.beef.findAtomicTransaction(stBeef.txs.slice(-1)[0].txid)!
1506
+ const tx = stBeef.findAtomicTransaction(stBeef.txs.slice(-1)[0].txid)!
1507
1507
  tx.inputs[0].unlockingScriptTemplate = unlock
1508
1508
  await tx.sign()
1509
1509
  const unlockingScript = tx.inputs[0].unlockingScript!.toHex()