@btc-vision/transaction 1.7.18 → 1.7.22
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/LICENSE +190 -21
- package/README.md +1 -1
- package/browser/_version.d.ts +1 -1
- package/browser/generators/builders/HashCommitmentGenerator.d.ts +49 -0
- package/browser/index.js +1 -1
- package/browser/keypair/Address.d.ts +3 -1
- package/browser/opnet.d.ts +6 -1
- package/browser/signer/AddressRotation.d.ts +12 -0
- package/browser/transaction/TransactionFactory.d.ts +14 -0
- package/browser/transaction/builders/ConsolidatedInteractionTransaction.d.ts +44 -0
- package/browser/transaction/enums/TransactionType.d.ts +3 -1
- package/browser/transaction/interfaces/IConsolidatedTransactionParameters.d.ts +31 -0
- package/browser/transaction/interfaces/ITransactionParameters.d.ts +2 -0
- package/browser/transaction/offline/OfflineTransactionManager.d.ts +69 -0
- package/browser/transaction/offline/TransactionReconstructor.d.ts +28 -0
- package/browser/transaction/offline/TransactionSerializer.d.ts +50 -0
- package/browser/transaction/offline/TransactionStateCapture.d.ts +52 -0
- package/browser/transaction/offline/index.d.ts +5 -0
- package/browser/transaction/offline/interfaces/ISerializableState.d.ts +62 -0
- package/browser/transaction/offline/interfaces/ITypeSpecificData.d.ts +62 -0
- package/browser/transaction/offline/interfaces/index.d.ts +2 -0
- package/browser/transaction/shared/TweakedTransaction.d.ts +12 -1
- package/browser/utxo/interfaces/IUTXO.d.ts +2 -0
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/generators/builders/HashCommitmentGenerator.d.ts +49 -0
- package/build/generators/builders/HashCommitmentGenerator.js +229 -0
- package/build/keypair/Address.d.ts +3 -1
- package/build/keypair/Address.js +87 -54
- package/build/opnet.d.ts +6 -1
- package/build/opnet.js +6 -1
- package/build/signer/AddressRotation.d.ts +12 -0
- package/build/signer/AddressRotation.js +16 -0
- package/build/transaction/TransactionFactory.d.ts +14 -0
- package/build/transaction/TransactionFactory.js +36 -0
- package/build/transaction/builders/ConsolidatedInteractionTransaction.d.ts +44 -0
- package/build/transaction/builders/ConsolidatedInteractionTransaction.js +259 -0
- package/build/transaction/builders/TransactionBuilder.js +2 -0
- package/build/transaction/enums/TransactionType.d.ts +3 -1
- package/build/transaction/enums/TransactionType.js +2 -0
- package/build/transaction/interfaces/IConsolidatedTransactionParameters.d.ts +31 -0
- package/build/transaction/interfaces/IConsolidatedTransactionParameters.js +1 -0
- package/build/transaction/interfaces/ITransactionParameters.d.ts +2 -0
- package/build/transaction/offline/OfflineTransactionManager.d.ts +69 -0
- package/build/transaction/offline/OfflineTransactionManager.js +255 -0
- package/build/transaction/offline/TransactionReconstructor.d.ts +28 -0
- package/build/transaction/offline/TransactionReconstructor.js +243 -0
- package/build/transaction/offline/TransactionSerializer.d.ts +50 -0
- package/build/transaction/offline/TransactionSerializer.js +700 -0
- package/build/transaction/offline/TransactionStateCapture.d.ts +52 -0
- package/build/transaction/offline/TransactionStateCapture.js +275 -0
- package/build/transaction/offline/index.d.ts +5 -0
- package/build/transaction/offline/index.js +5 -0
- package/build/transaction/offline/interfaces/ISerializableState.d.ts +62 -0
- package/build/transaction/offline/interfaces/ISerializableState.js +2 -0
- package/build/transaction/offline/interfaces/ITypeSpecificData.d.ts +62 -0
- package/build/transaction/offline/interfaces/ITypeSpecificData.js +19 -0
- package/build/transaction/offline/interfaces/index.d.ts +2 -0
- package/build/transaction/offline/interfaces/index.js +2 -0
- package/build/transaction/shared/TweakedTransaction.d.ts +12 -1
- package/build/transaction/shared/TweakedTransaction.js +75 -8
- package/build/utxo/interfaces/IUTXO.d.ts +2 -0
- package/documentation/README.md +5 -0
- package/documentation/offline-transaction-signing.md +650 -0
- package/documentation/transaction-building.md +603 -0
- package/package.json +2 -2
- package/src/_version.ts +1 -1
- package/src/generators/builders/HashCommitmentGenerator.ts +495 -0
- package/src/keypair/Address.ts +123 -70
- package/src/opnet.ts +8 -1
- package/src/signer/AddressRotation.ts +72 -0
- package/src/transaction/TransactionFactory.ts +94 -1
- package/src/transaction/builders/CancelTransaction.ts +4 -2
- package/src/transaction/builders/ConsolidatedInteractionTransaction.ts +568 -0
- package/src/transaction/builders/CustomScriptTransaction.ts +4 -2
- package/src/transaction/builders/MultiSignTransaction.ts +4 -2
- package/src/transaction/builders/TransactionBuilder.ts +8 -2
- package/src/transaction/enums/TransactionType.ts +2 -0
- package/src/transaction/interfaces/IConsolidatedTransactionParameters.ts +78 -0
- package/src/transaction/interfaces/ITransactionParameters.ts +8 -0
- package/src/transaction/offline/OfflineTransactionManager.ts +630 -0
- package/src/transaction/offline/TransactionReconstructor.ts +402 -0
- package/src/transaction/offline/TransactionSerializer.ts +920 -0
- package/src/transaction/offline/TransactionStateCapture.ts +469 -0
- package/src/transaction/offline/index.ts +8 -0
- package/src/transaction/offline/interfaces/ISerializableState.ts +141 -0
- package/src/transaction/offline/interfaces/ITypeSpecificData.ts +172 -0
- package/src/transaction/offline/interfaces/index.ts +2 -0
- package/src/transaction/shared/TweakedTransaction.ts +156 -9
- package/src/utxo/interfaces/IUTXO.ts +8 -0
- package/test/address-rotation.test.ts +553 -0
- package/test/offline-transaction.test.ts +2065 -0
|
@@ -36,6 +36,10 @@ export class TweakedTransaction extends Logger {
|
|
|
36
36
|
this.txVersion = 2;
|
|
37
37
|
this._mldsaSigner = null;
|
|
38
38
|
this._hashedPublicKey = null;
|
|
39
|
+
this.addressRotationEnabled = false;
|
|
40
|
+
this.signerMap = new Map();
|
|
41
|
+
this.inputSignerMap = new Map();
|
|
42
|
+
this.tweakedSignerCache = new Map();
|
|
39
43
|
this.customFinalizerP2SH = (inputIndex, input, scriptA, isSegwit, isP2SH, isP2WSH) => {
|
|
40
44
|
const inputDecoded = this.inputs[inputIndex];
|
|
41
45
|
if (isP2SH && input.partialSig && inputDecoded && inputDecoded.redeemScript) {
|
|
@@ -84,6 +88,10 @@ export class TweakedTransaction extends Logger {
|
|
|
84
88
|
this._mldsaSigner = data.mldsaSigner;
|
|
85
89
|
this._hashedPublicKey = MessageSigner.sha256(this._mldsaSigner.publicKey);
|
|
86
90
|
}
|
|
91
|
+
if (data.addressRotation?.enabled) {
|
|
92
|
+
this.addressRotationEnabled = true;
|
|
93
|
+
this.signerMap = data.addressRotation.signerMap;
|
|
94
|
+
}
|
|
87
95
|
}
|
|
88
96
|
get mldsaSigner() {
|
|
89
97
|
if (!this._mldsaSigner) {
|
|
@@ -153,6 +161,9 @@ export class TweakedTransaction extends Logger {
|
|
|
153
161
|
}
|
|
154
162
|
return signHash || 0;
|
|
155
163
|
}
|
|
164
|
+
isAddressRotationEnabled() {
|
|
165
|
+
return this.addressRotationEnabled;
|
|
166
|
+
}
|
|
156
167
|
ignoreSignatureError() {
|
|
157
168
|
this.ignoreSignatureErrors = true;
|
|
158
169
|
}
|
|
@@ -198,6 +209,53 @@ export class TweakedTransaction extends Logger {
|
|
|
198
209
|
const vSize = weight / 4n;
|
|
199
210
|
return vSize * feeRate;
|
|
200
211
|
}
|
|
212
|
+
getSignerForInput(inputIndex) {
|
|
213
|
+
if (this.addressRotationEnabled) {
|
|
214
|
+
const inputSigner = this.inputSignerMap.get(inputIndex);
|
|
215
|
+
if (inputSigner) {
|
|
216
|
+
return inputSigner;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return this.signer;
|
|
220
|
+
}
|
|
221
|
+
registerInputSigner(inputIndex, utxo) {
|
|
222
|
+
if (!this.addressRotationEnabled) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (utxo.signer) {
|
|
226
|
+
this.inputSignerMap.set(inputIndex, utxo.signer);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const address = utxo.scriptPubKey?.address;
|
|
230
|
+
if (address && this.signerMap.has(address)) {
|
|
231
|
+
const signer = this.signerMap.get(address);
|
|
232
|
+
if (signer) {
|
|
233
|
+
this.inputSignerMap.set(inputIndex, signer);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
internalPubKeyToXOnlyForInput(inputIndex) {
|
|
239
|
+
const signer = this.getSignerForInput(inputIndex);
|
|
240
|
+
return toXOnly(Buffer.from(signer.publicKey));
|
|
241
|
+
}
|
|
242
|
+
getTweakedSignerForInput(inputIndex, useTweakedHash = false) {
|
|
243
|
+
if (!this.addressRotationEnabled) {
|
|
244
|
+
if (useTweakedHash) {
|
|
245
|
+
this.tweakSigner();
|
|
246
|
+
return this.tweakedSigner;
|
|
247
|
+
}
|
|
248
|
+
return this.getTweakedSigner(useTweakedHash);
|
|
249
|
+
}
|
|
250
|
+
const cacheKey = inputIndex * 2 + (useTweakedHash ? 1 : 0);
|
|
251
|
+
if (this.tweakedSignerCache.has(cacheKey)) {
|
|
252
|
+
return this.tweakedSignerCache.get(cacheKey);
|
|
253
|
+
}
|
|
254
|
+
const signer = this.getSignerForInput(inputIndex);
|
|
255
|
+
const tweaked = this.getTweakedSigner(useTweakedHash, signer);
|
|
256
|
+
this.tweakedSignerCache.set(cacheKey, tweaked);
|
|
257
|
+
return tweaked;
|
|
258
|
+
}
|
|
201
259
|
generateTapData() {
|
|
202
260
|
return {
|
|
203
261
|
internalPubkey: this.internalPubKeyToXOnly(),
|
|
@@ -289,7 +347,8 @@ export class TweakedTransaction extends Logger {
|
|
|
289
347
|
const index = offset + j;
|
|
290
348
|
const input = batch[j];
|
|
291
349
|
try {
|
|
292
|
-
|
|
350
|
+
const inputSigner = this.getSignerForInput(index);
|
|
351
|
+
promises.push(this.signInput(transaction, input, index, inputSigner));
|
|
293
352
|
}
|
|
294
353
|
catch (e) {
|
|
295
354
|
this.log(`Failed to sign input ${index}: ${e.stack}`);
|
|
@@ -370,10 +429,13 @@ export class TweakedTransaction extends Logger {
|
|
|
370
429
|
}
|
|
371
430
|
return;
|
|
372
431
|
}
|
|
373
|
-
generateP2SHP2PKHRedeemScript(inputAddr) {
|
|
374
|
-
const
|
|
375
|
-
? this.
|
|
376
|
-
:
|
|
432
|
+
generateP2SHP2PKHRedeemScript(inputAddr, inputIndex) {
|
|
433
|
+
const signer = this.addressRotationEnabled && inputIndex !== undefined
|
|
434
|
+
? this.getSignerForInput(inputIndex)
|
|
435
|
+
: this.signer;
|
|
436
|
+
const pubkey = Buffer.isBuffer(signer.publicKey)
|
|
437
|
+
? signer.publicKey
|
|
438
|
+
: Buffer.from(signer.publicKey, 'hex');
|
|
377
439
|
const w = payments.p2wpkh({
|
|
378
440
|
pubkey: pubkey,
|
|
379
441
|
network: this.network,
|
|
@@ -432,7 +494,7 @@ export class TweakedTransaction extends Logger {
|
|
|
432
494
|
if (!utxo.scriptPubKey.address) {
|
|
433
495
|
throw new Error('Missing redeemScript and no address to regenerate it for P2SH UTXO');
|
|
434
496
|
}
|
|
435
|
-
const legacyScripts = this.generateP2SHP2PKHRedeemScript(utxo.scriptPubKey.address);
|
|
497
|
+
const legacyScripts = this.generateP2SHP2PKHRedeemScript(utxo.scriptPubKey.address, i);
|
|
436
498
|
if (!legacyScripts) {
|
|
437
499
|
throw new Error('Missing redeemScript for P2SH UTXO and unable to regenerate');
|
|
438
500
|
}
|
|
@@ -469,8 +531,13 @@ export class TweakedTransaction extends Logger {
|
|
|
469
531
|
if (inputSign)
|
|
470
532
|
input.sighashType = inputSign;
|
|
471
533
|
}
|
|
472
|
-
this.
|
|
473
|
-
|
|
534
|
+
if (this.addressRotationEnabled) {
|
|
535
|
+
input.tapInternalKey = this.internalPubKeyToXOnlyForInput(i);
|
|
536
|
+
}
|
|
537
|
+
else {
|
|
538
|
+
this.tweakSigner();
|
|
539
|
+
input.tapInternalKey = this.internalPubKeyToXOnly();
|
|
540
|
+
}
|
|
474
541
|
}
|
|
475
542
|
else if (isP2A(scriptPub)) {
|
|
476
543
|
this.anchorInputIndices.add(i);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ScriptPubKey } from '@btc-vision/bitcoin-rpc';
|
|
2
|
+
import { RotationSigner } from '../../signer/AddressRotation.js';
|
|
2
3
|
export interface UTXO {
|
|
3
4
|
readonly transactionId: string;
|
|
4
5
|
readonly outputIndex: number;
|
|
@@ -7,6 +8,7 @@ export interface UTXO {
|
|
|
7
8
|
redeemScript?: string | Buffer;
|
|
8
9
|
witnessScript?: string | Buffer;
|
|
9
10
|
nonWitnessUtxo?: string | Buffer;
|
|
11
|
+
signer?: RotationSigner;
|
|
10
12
|
}
|
|
11
13
|
export interface FetchUTXOParams {
|
|
12
14
|
readonly address: string;
|
package/documentation/README.md
CHANGED
|
@@ -19,6 +19,11 @@ Complete documentation for the OPNet Transaction Library - Bitcoin transaction b
|
|
|
19
19
|
- **Universal Public Key** - `address.toHex()` returns the SHA256 hash of ML-DSA public key (32 bytes)
|
|
20
20
|
- This is the user's universal identifier across the OPNet protocol
|
|
21
21
|
|
|
22
|
+
### Transaction Building
|
|
23
|
+
|
|
24
|
+
- **[Transaction Building Guide](./transaction-building.md)** - Complete guide to TransactionFactory, UTXO flow, fee calculation, signing, and all transaction types
|
|
25
|
+
- **[Offline Transaction Signing](./offline-transaction-signing.md)** - Serialize transactions for offline/air-gapped signing, fee bumping (RBF), address rotation, and MultiSig support
|
|
26
|
+
|
|
22
27
|
### Quantum Support (ML-DSA)
|
|
23
28
|
|
|
24
29
|
**[Complete Quantum Support Guide](./quantum-support/README.md)**
|