@btc-vision/transaction 1.6.1 → 1.6.5

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 (75) hide show
  1. package/browser/_version.d.ts +1 -1
  2. package/browser/epoch/ChallengeSolution.d.ts +3 -3
  3. package/browser/epoch/validator/EpochValidator.d.ts +5 -6
  4. package/browser/generators/builders/P2WDAGenerator.d.ts +13 -0
  5. package/browser/index.js +1 -1
  6. package/browser/keypair/Address.d.ts +3 -2
  7. package/browser/keypair/AddressVerificator.d.ts +13 -1
  8. package/browser/keypair/Wallet.d.ts +3 -0
  9. package/browser/opnet.d.ts +4 -0
  10. package/browser/p2wda/P2WDADetector.d.ts +16 -0
  11. package/browser/transaction/TransactionFactory.d.ts +3 -1
  12. package/browser/transaction/builders/DeploymentTransaction.d.ts +3 -3
  13. package/browser/transaction/builders/InteractionTransactionP2WDA.d.ts +37 -0
  14. package/browser/transaction/builders/SharedInteractionTransaction.d.ts +4 -4
  15. package/browser/transaction/builders/TransactionBuilder.d.ts +3 -0
  16. package/browser/transaction/interfaces/ITransactionParameters.d.ts +1 -0
  17. package/browser/transaction/mineable/IP2WSHAddress.d.ts +4 -0
  18. package/browser/transaction/mineable/TimelockGenerator.d.ts +2 -5
  19. package/browser/transaction/shared/TweakedTransaction.d.ts +23 -0
  20. package/build/_version.d.ts +1 -1
  21. package/build/_version.js +1 -1
  22. package/build/epoch/ChallengeSolution.d.ts +3 -3
  23. package/build/epoch/ChallengeSolution.js +3 -3
  24. package/build/epoch/validator/EpochValidator.d.ts +5 -6
  25. package/build/epoch/validator/EpochValidator.js +11 -12
  26. package/build/generators/builders/P2WDAGenerator.d.ts +13 -0
  27. package/build/generators/builders/P2WDAGenerator.js +62 -0
  28. package/build/keypair/Address.d.ts +3 -2
  29. package/build/keypair/Address.js +28 -2
  30. package/build/keypair/AddressVerificator.d.ts +13 -1
  31. package/build/keypair/AddressVerificator.js +82 -1
  32. package/build/keypair/Wallet.d.ts +3 -0
  33. package/build/keypair/Wallet.js +4 -0
  34. package/build/opnet.d.ts +4 -0
  35. package/build/opnet.js +4 -0
  36. package/build/p2wda/P2WDADetector.d.ts +16 -0
  37. package/build/p2wda/P2WDADetector.js +97 -0
  38. package/build/transaction/TransactionFactory.d.ts +3 -1
  39. package/build/transaction/TransactionFactory.js +35 -4
  40. package/build/transaction/builders/DeploymentTransaction.d.ts +3 -3
  41. package/build/transaction/builders/DeploymentTransaction.js +1 -1
  42. package/build/transaction/builders/InteractionTransactionP2WDA.d.ts +37 -0
  43. package/build/transaction/builders/InteractionTransactionP2WDA.js +205 -0
  44. package/build/transaction/builders/SharedInteractionTransaction.d.ts +4 -4
  45. package/build/transaction/builders/SharedInteractionTransaction.js +3 -3
  46. package/build/transaction/builders/TransactionBuilder.d.ts +3 -0
  47. package/build/transaction/builders/TransactionBuilder.js +18 -3
  48. package/build/transaction/interfaces/ITransactionParameters.d.ts +1 -0
  49. package/build/transaction/mineable/IP2WSHAddress.d.ts +4 -0
  50. package/build/transaction/mineable/IP2WSHAddress.js +1 -0
  51. package/build/transaction/mineable/TimelockGenerator.d.ts +2 -5
  52. package/build/transaction/shared/TweakedTransaction.d.ts +23 -0
  53. package/build/transaction/shared/TweakedTransaction.js +154 -18
  54. package/doc/README.md +0 -0
  55. package/doc/addresses/P2OP.md +1 -0
  56. package/doc/addresses/P2WDA.md +240 -0
  57. package/package.json +2 -2
  58. package/src/_version.ts +1 -1
  59. package/src/epoch/ChallengeSolution.ts +4 -4
  60. package/src/epoch/validator/EpochValidator.ts +12 -16
  61. package/src/generators/builders/P2WDAGenerator.ts +174 -0
  62. package/src/keypair/Address.ts +58 -3
  63. package/src/keypair/AddressVerificator.ts +147 -2
  64. package/src/keypair/Wallet.ts +16 -0
  65. package/src/opnet.ts +4 -0
  66. package/src/p2wda/P2WDADetector.ts +218 -0
  67. package/src/transaction/TransactionFactory.ts +79 -5
  68. package/src/transaction/builders/DeploymentTransaction.ts +4 -3
  69. package/src/transaction/builders/InteractionTransactionP2WDA.ts +376 -0
  70. package/src/transaction/builders/SharedInteractionTransaction.ts +7 -6
  71. package/src/transaction/builders/TransactionBuilder.ts +30 -3
  72. package/src/transaction/interfaces/ITransactionParameters.ts +1 -0
  73. package/src/transaction/mineable/IP2WSHAddress.ts +4 -0
  74. package/src/transaction/mineable/TimelockGenerator.ts +2 -6
  75. package/src/transaction/shared/TweakedTransaction.ts +246 -23
@@ -0,0 +1,205 @@
1
+ import { Buffer } from 'buffer';
2
+ import { toXOnly } from '@btc-vision/bitcoin';
3
+ import { TransactionType } from '../enums/TransactionType.js';
4
+ import { MINIMUM_AMOUNT_CA, MINIMUM_AMOUNT_REWARD, TransactionBuilder, } from './TransactionBuilder.js';
5
+ import { MessageSigner } from '../../keypair/MessageSigner.js';
6
+ import { Compressor } from '../../bytecode/Compressor.js';
7
+ import { P2WDAGenerator } from '../../generators/builders/P2WDAGenerator.js';
8
+ import { Features } from '../../generators/Features.js';
9
+ import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
10
+ import { EcKeyPair } from '../../keypair/EcKeyPair.js';
11
+ import { P2WDADetector } from '../../p2wda/P2WDADetector.js';
12
+ import { TimeLockGenerator } from '../mineable/TimelockGenerator.js';
13
+ export class InteractionTransactionP2WDA extends TransactionBuilder {
14
+ constructor(parameters) {
15
+ super(parameters);
16
+ this.type = TransactionType.INTERACTION;
17
+ this.p2wdaInputIndices = new Set();
18
+ this.compiledOperationData = null;
19
+ if (!parameters.to) {
20
+ throw new Error('Contract address (to) is required');
21
+ }
22
+ if (!parameters.contract) {
23
+ throw new Error('Contract secret is required');
24
+ }
25
+ if (!parameters.calldata) {
26
+ throw new Error('Calldata is required');
27
+ }
28
+ if (!parameters.challenge) {
29
+ throw new Error('Challenge solution is required');
30
+ }
31
+ this.disableAutoRefund = parameters.disableAutoRefund || false;
32
+ this.contractAddress = parameters.to;
33
+ this.contractSecret = Buffer.from(parameters.contract.replace('0x', ''), 'hex');
34
+ this.calldata = Compressor.compress(parameters.calldata);
35
+ this.challenge = parameters.challenge;
36
+ this.randomBytes = parameters.randomBytes || BitcoinUtils.rndBytes();
37
+ this.scriptSigner = this.generateKeyPairFromSeed();
38
+ this.p2wdaGenerator = new P2WDAGenerator(Buffer.from(this.signer.publicKey), this.scriptSignerXOnlyPubKey(), this.network);
39
+ if (this.contractSecret.length !== 32) {
40
+ throw new Error('Invalid contract secret length. Expected 32 bytes.');
41
+ }
42
+ this.epochChallenge = TimeLockGenerator.generateTimeLockAddress(this.challenge.publicKey.originalPublicKeyBuffer(), this.network);
43
+ this.validateP2WDAInputs();
44
+ this.compiledOperationData = this.p2wdaGenerator.compile(this.calldata, this.contractSecret, this.challenge, this.priorityFee, this.generateFeatures(parameters));
45
+ this.validateOperationDataSize();
46
+ this.internalInit();
47
+ }
48
+ getRndBytes() {
49
+ return this.randomBytes;
50
+ }
51
+ getChallenge() {
52
+ return this.challenge;
53
+ }
54
+ getContractSecret() {
55
+ return this.contractSecret;
56
+ }
57
+ async buildTransaction() {
58
+ if (!this.regenerated) {
59
+ this.addInputsFromUTXO();
60
+ }
61
+ await this.createMineableRewardOutputs();
62
+ }
63
+ async createMineableRewardOutputs() {
64
+ if (!this.to)
65
+ throw new Error('To address is required');
66
+ const amountSpent = this.getTransactionOPNetFee();
67
+ let amountToCA;
68
+ if (amountSpent > MINIMUM_AMOUNT_REWARD + MINIMUM_AMOUNT_CA) {
69
+ amountToCA = MINIMUM_AMOUNT_CA;
70
+ }
71
+ else {
72
+ amountToCA = amountSpent;
73
+ }
74
+ this.addOutput({
75
+ value: Number(amountToCA),
76
+ address: this.to,
77
+ });
78
+ if (amountToCA === MINIMUM_AMOUNT_CA &&
79
+ amountSpent - MINIMUM_AMOUNT_CA > MINIMUM_AMOUNT_REWARD) {
80
+ this.addOutput({
81
+ value: Number(amountSpent - amountToCA),
82
+ address: this.epochChallenge.address,
83
+ });
84
+ }
85
+ const amount = this.addOptionalOutputsAndGetAmount();
86
+ if (!this.disableAutoRefund) {
87
+ await this.addRefundOutput(amountSpent + amount);
88
+ }
89
+ }
90
+ async signInputs(transaction) {
91
+ for (let i = 0; i < transaction.data.inputs.length; i++) {
92
+ await this.signInput(transaction, transaction.data.inputs[i], i, this.signer);
93
+ }
94
+ for (let i = 0; i < transaction.data.inputs.length; i++) {
95
+ if (this.p2wdaInputIndices.has(i)) {
96
+ if (i === 0) {
97
+ transaction.finalizeInput(i, this.finalizePrimaryP2WDA.bind(this));
98
+ }
99
+ else {
100
+ transaction.finalizeInput(i, this.finalizeSecondaryP2WDA.bind(this));
101
+ }
102
+ }
103
+ else {
104
+ transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
105
+ }
106
+ }
107
+ this.finalized = true;
108
+ }
109
+ generateFeatures(parameters) {
110
+ const features = [];
111
+ if (parameters.loadedStorage) {
112
+ features.push({
113
+ opcode: Features.ACCESS_LIST,
114
+ data: parameters.loadedStorage,
115
+ });
116
+ }
117
+ const submission = parameters.challenge.getSubmission();
118
+ if (submission) {
119
+ features.push({
120
+ opcode: Features.EPOCH_SUBMISSION,
121
+ data: submission,
122
+ });
123
+ }
124
+ return features;
125
+ }
126
+ generateKeyPairFromSeed() {
127
+ return EcKeyPair.fromSeedKeyPair(this.randomBytes, this.network);
128
+ }
129
+ scriptSignerXOnlyPubKey() {
130
+ return toXOnly(Buffer.from(this.scriptSigner.publicKey));
131
+ }
132
+ validateP2WDAInputs() {
133
+ if (this.utxos.length === 0 || !P2WDADetector.isP2WDAUTXO(this.utxos[0])) {
134
+ throw new Error('Input 0 must be a P2WDA UTXO');
135
+ }
136
+ for (let i = 0; i < this.utxos.length; i++) {
137
+ if (P2WDADetector.isP2WDAUTXO(this.utxos[i])) {
138
+ this.p2wdaInputIndices.add(i);
139
+ }
140
+ }
141
+ for (let i = 0; i < this.optionalInputs.length; i++) {
142
+ const actualIndex = this.utxos.length + i;
143
+ if (P2WDADetector.isP2WDAUTXO(this.optionalInputs[i])) {
144
+ this.p2wdaInputIndices.add(actualIndex);
145
+ }
146
+ }
147
+ }
148
+ validateOperationDataSize() {
149
+ if (!this.compiledOperationData) {
150
+ throw new Error('Operation data not compiled');
151
+ }
152
+ const estimatedSize = this.compiledOperationData.length;
153
+ if (!P2WDAGenerator.validateWitnessSize(estimatedSize)) {
154
+ const signatureSize = 64;
155
+ const totalSize = estimatedSize + signatureSize;
156
+ const compressedEstimate = Math.ceil(totalSize * 0.7);
157
+ const requiredFields = Math.ceil(compressedEstimate / InteractionTransactionP2WDA.MAX_BYTES_PER_WITNESS);
158
+ throw new Error(`Please dont use P2WDA for this operation. Data too large. Raw size: ${estimatedSize} bytes, ` +
159
+ `estimated compressed: ${compressedEstimate} bytes, ` +
160
+ `needs ${requiredFields} witness fields, max is ${InteractionTransactionP2WDA.MAX_WITNESS_FIELDS}`);
161
+ }
162
+ }
163
+ finalizePrimaryP2WDA(inputIndex, input) {
164
+ if (!input.partialSig || input.partialSig.length === 0) {
165
+ throw new Error(`No signature for P2WDA input #${inputIndex}`);
166
+ }
167
+ if (!input.witnessScript) {
168
+ throw new Error(`No witness script for P2WDA input #${inputIndex}`);
169
+ }
170
+ if (!this.compiledOperationData) {
171
+ throw new Error('Operation data not compiled');
172
+ }
173
+ const txSignature = input.partialSig[0].signature;
174
+ const messageToSign = Buffer.concat([txSignature, this.compiledOperationData]);
175
+ const signedMessage = MessageSigner.signMessage(this.signer, messageToSign);
176
+ const schnorrSignature = Buffer.from(signedMessage.signature);
177
+ const fullData = Buffer.concat([schnorrSignature, this.compiledOperationData]);
178
+ const compressedData = Compressor.compress(fullData);
179
+ const chunks = this.splitIntoWitnessChunks(compressedData);
180
+ if (chunks.length > InteractionTransactionP2WDA.MAX_WITNESS_FIELDS) {
181
+ throw new Error(`Compressed data needs ${chunks.length} witness fields, max is ${InteractionTransactionP2WDA.MAX_WITNESS_FIELDS}`);
182
+ }
183
+ const witnessStack = [txSignature];
184
+ for (let i = 0; i < InteractionTransactionP2WDA.MAX_WITNESS_FIELDS; i++) {
185
+ witnessStack.push(i < chunks.length ? chunks[i] : Buffer.alloc(0));
186
+ }
187
+ witnessStack.push(input.witnessScript);
188
+ return {
189
+ finalScriptSig: undefined,
190
+ finalScriptWitness: TransactionBuilder.witnessStackToScriptWitness(witnessStack),
191
+ };
192
+ }
193
+ splitIntoWitnessChunks(data) {
194
+ const chunks = [];
195
+ let offset = 0;
196
+ while (offset < data.length) {
197
+ const size = Math.min(InteractionTransactionP2WDA.MAX_BYTES_PER_WITNESS, data.length - offset);
198
+ chunks.push(data.subarray(offset, offset + size));
199
+ offset += size;
200
+ }
201
+ return chunks;
202
+ }
203
+ }
204
+ InteractionTransactionP2WDA.MAX_WITNESS_FIELDS = 10;
205
+ InteractionTransactionP2WDA.MAX_BYTES_PER_WITNESS = 80;
@@ -4,8 +4,8 @@ import { TransactionBuilder } from './TransactionBuilder.js';
4
4
  import { TransactionType } from '../enums/TransactionType.js';
5
5
  import { CalldataGenerator } from '../../generators/builders/CalldataGenerator.js';
6
6
  import { SharedInteractionParameters } from '../interfaces/ITransactionParameters.js';
7
- import { ITimeLockOutput } from '../mineable/TimelockGenerator.js';
8
7
  import { ChallengeSolution } from '../../epoch/ChallengeSolution.js';
8
+ import { IP2WSHAddress } from '../mineable/IP2WSHAddress.js';
9
9
  export declare abstract class SharedInteractionTransaction<T extends TransactionType> extends TransactionBuilder<T> {
10
10
  static readonly MAXIMUM_CALLDATA_SIZE: number;
11
11
  readonly randomBytes: Buffer;
@@ -14,7 +14,7 @@ export declare abstract class SharedInteractionTransaction<T extends Transaction
14
14
  protected abstract readonly compiledTargetScript: Buffer;
15
15
  protected abstract readonly scriptTree: Taptree;
16
16
  protected readonly challenge: ChallengeSolution;
17
- protected readonly epochChallenge: ITimeLockOutput;
17
+ protected readonly epochChallenge: IP2WSHAddress;
18
18
  protected calldataGenerator: CalldataGenerator;
19
19
  protected readonly calldata: Buffer;
20
20
  protected abstract readonly contractSecret: Buffer;
@@ -23,7 +23,7 @@ export declare abstract class SharedInteractionTransaction<T extends Transaction
23
23
  protected constructor(parameters: SharedInteractionParameters);
24
24
  getContractSecret(): Buffer;
25
25
  getRndBytes(): Buffer;
26
- getPreimage(): ChallengeSolution;
26
+ getChallenge(): ChallengeSolution;
27
27
  protected scriptSignerXOnlyPubKey(): Buffer;
28
28
  protected generateKeyPairFromSeed(): ECPairInterface;
29
29
  protected buildTransaction(): Promise<void>;
@@ -37,7 +37,7 @@ export declare abstract class SharedInteractionTransaction<T extends Transaction
37
37
  };
38
38
  protected signInputsWalletBased(transaction: Psbt): Promise<void>;
39
39
  protected signInputsNonWalletBased(transaction: Psbt): Promise<void>;
40
- private createMineableRewardOutputs;
40
+ protected createMineableRewardOutputs(): Promise<void>;
41
41
  private getPubKeys;
42
42
  private generateRedeemScripts;
43
43
  }
@@ -1,5 +1,5 @@
1
- import { PaymentType, toXOnly } from '@btc-vision/bitcoin';
2
- import { MINIMUM_AMOUNT_CA, MINIMUM_AMOUNT_REWARD, TransactionBuilder } from './TransactionBuilder.js';
1
+ import { PaymentType, toXOnly, } from '@btc-vision/bitcoin';
2
+ import { MINIMUM_AMOUNT_CA, MINIMUM_AMOUNT_REWARD, TransactionBuilder, } from './TransactionBuilder.js';
3
3
  import { CalldataGenerator } from '../../generators/builders/CalldataGenerator.js';
4
4
  import { Compressor } from '../../bytecode/Compressor.js';
5
5
  import { EcKeyPair } from '../../keypair/EcKeyPair.js';
@@ -45,7 +45,7 @@ export class SharedInteractionTransaction extends TransactionBuilder {
45
45
  getRndBytes() {
46
46
  return this.randomBytes;
47
47
  }
48
- getPreimage() {
48
+ getChallenge() {
49
49
  return this.challenge;
50
50
  }
51
51
  scriptSignerXOnlyPubKey() {
@@ -8,6 +8,7 @@ import { TweakedTransaction } from '../shared/TweakedTransaction.js';
8
8
  import { UnisatSigner } from '../browser/extensions/UnisatSigner.js';
9
9
  export declare const MINIMUM_AMOUNT_REWARD: bigint;
10
10
  export declare const MINIMUM_AMOUNT_CA: bigint;
11
+ export declare const ANCHOR_SCRIPT: Buffer<ArrayBuffer>;
11
12
  export declare abstract class TransactionBuilder<T extends TransactionType> extends TweakedTransaction {
12
13
  static readonly LOCK_LEAF_SCRIPT: Buffer;
13
14
  static readonly MINIMUM_DUST: bigint;
@@ -33,11 +34,13 @@ export declare abstract class TransactionBuilder<T extends TransactionType> exte
33
34
  protected from: string;
34
35
  protected _maximumFeeRate: number;
35
36
  protected isPubKeyDestination: boolean;
37
+ protected anchor: boolean;
36
38
  protected note?: Buffer;
37
39
  protected constructor(parameters: ITransactionParameters);
38
40
  static getFrom(from: string | undefined, keypair: ECPairInterface | Signer, network: Network): string;
39
41
  static witnessStackToScriptWitness(witness: Buffer[]): Buffer;
40
42
  addOPReturn(buffer: Buffer): void;
43
+ addAnchor(): void;
41
44
  getFundingTransactionParameters(): Promise<IFundingTransactionParameters>;
42
45
  setDestinationAddress(address: string): void;
43
46
  setMaximumFeeRate(feeRate: number): void;
@@ -6,6 +6,7 @@ import { TweakedTransaction } from '../shared/TweakedTransaction.js';
6
6
  initEccLib(ecc);
7
7
  export const MINIMUM_AMOUNT_REWARD = 540n;
8
8
  export const MINIMUM_AMOUNT_CA = 297n;
9
+ export const ANCHOR_SCRIPT = Buffer.from('51024e73', 'hex');
9
10
  export class TransactionBuilder extends TweakedTransaction {
10
11
  constructor(parameters) {
11
12
  super(parameters);
@@ -36,6 +37,7 @@ export class TransactionBuilder extends TweakedTransaction {
36
37
  this.note = parameters.note;
37
38
  }
38
39
  }
40
+ this.anchor = parameters.anchor ?? false;
39
41
  this.isPubKeyDestination = this.to
40
42
  ? AddressVerificator.isValidPublicKey(this.to, this.network)
41
43
  : false;
@@ -48,6 +50,7 @@ export class TransactionBuilder extends TweakedTransaction {
48
50
  }
49
51
  this.transaction = new Psbt({
50
52
  network: this.network,
53
+ version: this.txVersion,
51
54
  });
52
55
  }
53
56
  static getFrom(from, keypair, network) {
@@ -82,6 +85,12 @@ export class TransactionBuilder extends TweakedTransaction {
82
85
  script: compileScript,
83
86
  });
84
87
  }
88
+ addAnchor() {
89
+ this.addOutput({
90
+ value: 0,
91
+ script: ANCHOR_SCRIPT,
92
+ });
93
+ }
85
94
  async getFundingTransactionParameters() {
86
95
  if (!this.estimatedFees) {
87
96
  this.estimatedFees = await this.estimateTransactionFees();
@@ -164,8 +173,8 @@ export class TransactionBuilder extends TweakedTransaction {
164
173
  if (script.script.length < 2) {
165
174
  throw new Error('Output script is too short');
166
175
  }
167
- if (script.script[0] !== opcodes.OP_RETURN) {
168
- throw new Error('Output script must start with OP_RETURN when value is 0');
176
+ if (script.script[0] !== opcodes.OP_RETURN && !script.script.equals(ANCHOR_SCRIPT)) {
177
+ throw new Error('Output script must start with OP_RETURN or be an ANCHOR when value is 0');
169
178
  }
170
179
  }
171
180
  else if (output.value < TransactionBuilder.MINIMUM_DUST) {
@@ -201,7 +210,10 @@ export class TransactionBuilder extends TweakedTransaction {
201
210
  }
202
211
  }
203
212
  async rebuildFromBase64(base64) {
204
- this.transaction = Psbt.fromBase64(base64, { network: this.network });
213
+ this.transaction = Psbt.fromBase64(base64, {
214
+ network: this.network,
215
+ version: this.txVersion,
216
+ });
205
217
  this.signed = false;
206
218
  this.sighashTypes = [Transaction.SIGHASH_ANYONECANPAY, Transaction.SIGHASH_ALL];
207
219
  return await this.signPSBT();
@@ -231,6 +243,9 @@ export class TransactionBuilder extends TweakedTransaction {
231
243
  if (this.note) {
232
244
  this.addOPReturn(this.note);
233
245
  }
246
+ if (this.anchor) {
247
+ this.addAnchor();
248
+ }
234
249
  const sendBackAmount = this.totalInputAmount - amountSpent;
235
250
  if (sendBackAmount >= TransactionBuilder.MINIMUM_DUST) {
236
251
  if (AddressVerificator.isValidP2TRAddress(this.from, this.network)) {
@@ -17,6 +17,7 @@ export interface ITransactionParameters extends ITweakedTransactionData {
17
17
  chainId?: ChainId;
18
18
  noSignatures?: boolean;
19
19
  readonly note?: string | Buffer;
20
+ readonly anchor?: boolean;
20
21
  readonly feeRate: number;
21
22
  readonly priorityFee: bigint;
22
23
  readonly gasSatFee: bigint;
@@ -0,0 +1,4 @@
1
+ export interface IP2WSHAddress {
2
+ address: string;
3
+ witnessScript: Buffer;
4
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,9 +1,6 @@
1
1
  import { Network } from '@btc-vision/bitcoin';
2
- export interface ITimeLockOutput {
3
- address: string;
4
- witnessScript: Buffer;
5
- }
2
+ import { IP2WSHAddress } from './IP2WSHAddress.js';
6
3
  export declare class TimeLockGenerator {
7
4
  private static readonly CSV_BLOCKS;
8
- static generateTimeLockAddress(publicKey: Buffer, network?: Network, csvBlocks?: number): ITimeLockOutput;
5
+ static generateTimeLockAddress(publicKey: Buffer, network?: Network, csvBlocks?: number): IP2WSHAddress;
9
6
  }
@@ -5,6 +5,8 @@ import { UTXO } from '../../utxo/interfaces/IUTXO.js';
5
5
  import { TapLeafScript } from '../interfaces/Tap.js';
6
6
  import { ChainId } from '../../network/ChainId.js';
7
7
  import { UnisatSigner } from '../browser/extensions/UnisatSigner.js';
8
+ import { Buffer } from 'buffer';
9
+ export type SupportedTransactionVersion = 1 | 2 | 3;
8
10
  export interface ITweakedTransactionData {
9
11
  readonly signer: Signer | ECPairInterface | UnisatSigner;
10
12
  readonly network: Network;
@@ -12,11 +14,16 @@ export interface ITweakedTransactionData {
12
14
  readonly nonWitnessUtxo?: Buffer;
13
15
  readonly noSignatures?: boolean;
14
16
  readonly unlockScript?: Buffer[];
17
+ readonly txVersion?: SupportedTransactionVersion;
15
18
  }
16
19
  export declare enum TransactionSequence {
17
20
  REPLACE_BY_FEE = 4294967293,
18
21
  FINAL = 4294967295
19
22
  }
23
+ export declare enum CSVModes {
24
+ BLOCKS = 0,
25
+ TIMESTAMPS = 1
26
+ }
20
27
  export declare abstract class TweakedTransaction extends Logger {
21
28
  readonly logColor: string;
22
29
  finalized: boolean;
@@ -33,10 +40,13 @@ export declare abstract class TweakedTransaction extends Logger {
33
40
  protected tapLeafScript: TapLeafScript | null;
34
41
  protected nonWitnessUtxo?: Buffer;
35
42
  protected readonly isBrowser: boolean;
43
+ protected csvInputIndices: Set<number>;
44
+ protected anchorInputIndices: Set<number>;
36
45
  protected regenerated: boolean;
37
46
  protected ignoreSignatureErrors: boolean;
38
47
  protected noSignatures: boolean;
39
48
  protected unlockScript: Buffer[] | undefined;
49
+ protected txVersion: SupportedTransactionVersion;
40
50
  protected constructor(data: ITweakedTransactionData);
41
51
  static readScriptWitnessToWitnessStack(Buffer: Buffer): Buffer[];
42
52
  static preEstimateTaprootTransactionFees(feeRate: bigint, numInputs: bigint, numOutputs: bigint, numWitnessElements: bigint, witnessElementSize: bigint, emptyWitness: bigint, taprootControlWitnessSize?: bigint, taprootScriptSize?: bigint): bigint;
@@ -70,11 +80,24 @@ export declare abstract class TweakedTransaction extends Logger {
70
80
  outputScript: Buffer;
71
81
  } | undefined;
72
82
  protected generatePsbtInputExtended(utxo: UTXO, i: number, _extra?: boolean): PsbtInputExtended;
83
+ protected processP2WSHInput(utxo: UTXO, input: PsbtInputExtended, i: number): void;
84
+ protected secondsToCSVTimeUnits(seconds: number): number;
85
+ protected createTimeBasedCSV(seconds: number): number;
86
+ protected isCSVEnabled(sequence: number): boolean;
87
+ protected extractCSVValue(sequence: number): number;
73
88
  protected customFinalizerP2SH: (inputIndex: number, input: PsbtInput, scriptA: Buffer, isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean) => {
74
89
  finalScriptSig: Buffer | undefined;
75
90
  finalScriptWitness: Buffer | undefined;
76
91
  };
92
+ protected finalizeSecondaryP2WDA(inputIndex: number, input: PsbtInput): {
93
+ finalScriptWitness: Buffer | undefined;
94
+ finalScriptSig: Buffer | undefined;
95
+ };
77
96
  protected signInputsWalletBased(transaction: Psbt): Promise<void>;
97
+ protected isCSVScript(decompiled: (number | Buffer)[]): boolean;
98
+ protected setCSVSequence(csvBlocks: number, currentSequence: number): number;
99
+ protected getCSVType(csvValue: number): CSVModes;
100
+ private extractCSVBlocks;
78
101
  private attemptSignTaproot;
79
102
  private isTaprootScriptSpend;
80
103
  private signTaprootInput;