@btc-vision/transaction 1.3.2 → 1.3.4
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/browser/_version.d.ts +1 -1
- package/browser/index.js +1 -1
- package/browser/transaction/builders/SharedInteractionTransaction.d.ts +1 -1
- package/browser/transaction/builders/TransactionBuilder.d.ts +1 -0
- package/browser/transaction/interfaces/ITransactionParameters.d.ts +1 -0
- package/browser/transaction/shared/TweakedTransaction.d.ts +2 -1
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/transaction/TransactionFactory.js +31 -4
- package/build/transaction/browser/extensions/UnisatSigner.js +2 -0
- package/build/transaction/builders/SharedInteractionTransaction.d.ts +1 -1
- package/build/transaction/builders/SharedInteractionTransaction.js +24 -14
- package/build/transaction/builders/TransactionBuilder.d.ts +1 -0
- package/build/transaction/builders/TransactionBuilder.js +20 -0
- package/build/transaction/interfaces/ITransactionParameters.d.ts +1 -0
- package/build/transaction/shared/TweakedTransaction.d.ts +2 -1
- package/build/transaction/shared/TweakedTransaction.js +18 -4
- package/package.json +1 -1
- package/src/_version.ts +1 -1
- package/src/transaction/TransactionFactory.ts +44 -4
- package/src/transaction/browser/extensions/UnisatSigner.ts +2 -0
- package/src/transaction/builders/SharedInteractionTransaction.ts +31 -28
- package/src/transaction/builders/TransactionBuilder.ts +36 -0
- package/src/transaction/interfaces/ITransactionParameters.ts +2 -1
- package/src/transaction/shared/TweakedTransaction.ts +37 -5
|
@@ -36,8 +36,8 @@ export declare abstract class SharedInteractionTransaction<T extends Transaction
|
|
|
36
36
|
finalScriptWitness: Buffer<ArrayBufferLike>;
|
|
37
37
|
};
|
|
38
38
|
protected signInputsWalletBased(transaction: Psbt): Promise<void>;
|
|
39
|
+
protected signInputsNonWalletBased(transaction: Psbt): Promise<void>;
|
|
39
40
|
private createMineableRewardOutputs;
|
|
40
|
-
private signInputsNonWalletBased;
|
|
41
41
|
private getPubKeys;
|
|
42
42
|
private generateRedeemScripts;
|
|
43
43
|
}
|
|
@@ -28,6 +28,7 @@ export declare abstract class TransactionBuilder<T extends TransactionType> exte
|
|
|
28
28
|
protected priorityFee: bigint;
|
|
29
29
|
protected gasSatFee: bigint;
|
|
30
30
|
protected utxos: UTXO[];
|
|
31
|
+
protected optionalInputs: UTXO[];
|
|
31
32
|
protected to: string | undefined;
|
|
32
33
|
protected from: string;
|
|
33
34
|
protected _maximumFeeRate: number;
|
|
@@ -8,6 +8,7 @@ export interface ITransactionParameters extends ITweakedTransactionData {
|
|
|
8
8
|
utxos: UTXO[];
|
|
9
9
|
nonWitnessUtxo?: Buffer;
|
|
10
10
|
estimatedFees?: bigint;
|
|
11
|
+
optionalInputs?: UTXO[];
|
|
11
12
|
optionalOutputs?: PsbtOutputExtended[];
|
|
12
13
|
chainId?: ChainId;
|
|
13
14
|
readonly feeRate: number;
|
|
@@ -51,6 +51,7 @@ export declare abstract class TweakedTransaction extends Logger {
|
|
|
51
51
|
protected signInput(transaction: Psbt, input: PsbtInput, i: number, signer: Signer | ECPairInterface, reverse?: boolean, errored?: boolean): Promise<void>;
|
|
52
52
|
protected splitArray<T>(arr: T[], chunkSize: number): T[][];
|
|
53
53
|
protected signInputs(transaction: Psbt): Promise<void>;
|
|
54
|
+
protected signInputsNonWalletBased(transaction: Psbt): Promise<void>;
|
|
54
55
|
protected internalPubKeyToXOnly(): Buffer;
|
|
55
56
|
protected internalInit(): void;
|
|
56
57
|
protected tweakSigner(): void;
|
|
@@ -64,7 +65,7 @@ export declare abstract class TweakedTransaction extends Logger {
|
|
|
64
65
|
redeemScript: Buffer;
|
|
65
66
|
outputScript: Buffer;
|
|
66
67
|
} | undefined;
|
|
67
|
-
protected generatePsbtInputExtended(utxo: UTXO, i: number): PsbtInputExtended;
|
|
68
|
+
protected generatePsbtInputExtended(utxo: UTXO, i: number, extra?: boolean): PsbtInputExtended;
|
|
68
69
|
protected customFinalizerP2SH: (inputIndex: number, input: PsbtInput, scriptA: Buffer, isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean) => {
|
|
69
70
|
finalScriptSig: Buffer | undefined;
|
|
70
71
|
finalScriptWitness: Buffer | undefined;
|
package/build/_version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "1.3.
|
|
1
|
+
export declare const version = "1.3.3";
|
package/build/_version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.3.
|
|
1
|
+
export const version = '1.3.3';
|
|
@@ -24,7 +24,11 @@ export class TransactionFactory {
|
|
|
24
24
|
(await preTransaction.estimateTransactionFees()) +
|
|
25
25
|
this.getPriorityFee(interactionParameters) +
|
|
26
26
|
preTransaction.getOptionalOutputValue();
|
|
27
|
-
const feeEstimationFundingTransaction = await this.createFundTransaction({
|
|
27
|
+
const feeEstimationFundingTransaction = await this.createFundTransaction({
|
|
28
|
+
...parameters,
|
|
29
|
+
optionalOutputs: [],
|
|
30
|
+
optionalInputs: [],
|
|
31
|
+
});
|
|
28
32
|
if (!feeEstimationFundingTransaction) {
|
|
29
33
|
throw new Error('Could not sign funding transaction.');
|
|
30
34
|
}
|
|
@@ -66,9 +70,22 @@ export class TransactionFactory {
|
|
|
66
70
|
if (!('signer' in interactionParameters)) {
|
|
67
71
|
throw new Error('Field "signer" not provided, OP_WALLET not detected.');
|
|
68
72
|
}
|
|
73
|
+
const inputs = (interactionParameters.optionalInputs || []).map((input) => {
|
|
74
|
+
let nonWitness = input.nonWitnessUtxo;
|
|
75
|
+
if (nonWitness &&
|
|
76
|
+
!(nonWitness instanceof Uint8Array) &&
|
|
77
|
+
typeof nonWitness === 'object') {
|
|
78
|
+
nonWitness = Buffer.from(Uint8Array.from(Object.values(input.nonWitnessUtxo)));
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
...input,
|
|
82
|
+
nonWitnessUtxo: nonWitness,
|
|
83
|
+
};
|
|
84
|
+
});
|
|
69
85
|
const preTransaction = new InteractionTransaction({
|
|
70
86
|
...interactionParameters,
|
|
71
87
|
utxos: [interactionParameters.utxos[0]],
|
|
88
|
+
optionalInputs: inputs,
|
|
72
89
|
});
|
|
73
90
|
await preTransaction.generateTransactionMinimalSignatures();
|
|
74
91
|
const parameters = await preTransaction.getFundingTransactionParameters();
|
|
@@ -80,6 +97,7 @@ export class TransactionFactory {
|
|
|
80
97
|
const feeEstimationFundingTransaction = await this.createFundTransaction({
|
|
81
98
|
...parameters,
|
|
82
99
|
optionalOutputs: [],
|
|
100
|
+
optionalInputs: [],
|
|
83
101
|
});
|
|
84
102
|
if (!feeEstimationFundingTransaction) {
|
|
85
103
|
throw new Error('Could not sign funding transaction.');
|
|
@@ -88,6 +106,7 @@ export class TransactionFactory {
|
|
|
88
106
|
const signedTransaction = await this.createFundTransaction({
|
|
89
107
|
...parameters,
|
|
90
108
|
optionalOutputs: [],
|
|
109
|
+
optionalInputs: [],
|
|
91
110
|
});
|
|
92
111
|
if (!signedTransaction) {
|
|
93
112
|
throw new Error('Could not sign funding transaction.');
|
|
@@ -95,11 +114,14 @@ export class TransactionFactory {
|
|
|
95
114
|
interactionParameters.utxos = this.getUTXOAsTransaction(signedTransaction.tx, interactionParameters.to, 0);
|
|
96
115
|
const newParams = {
|
|
97
116
|
...interactionParameters,
|
|
98
|
-
utxos:
|
|
117
|
+
utxos: [
|
|
118
|
+
...this.getUTXOAsTransaction(signedTransaction.tx, interactionParameters.to, 0),
|
|
119
|
+
],
|
|
99
120
|
randomBytes: preTransaction.getRndBytes(),
|
|
100
121
|
preimage: preTransaction.getPreimage(),
|
|
101
122
|
nonWitnessUtxo: signedTransaction.tx.toBuffer(),
|
|
102
123
|
estimatedFees: preTransaction.estimatedFees,
|
|
124
|
+
optionalInputs: inputs,
|
|
103
125
|
};
|
|
104
126
|
const finalTransaction = new InteractionTransaction(newParams);
|
|
105
127
|
const outTx = await finalTransaction.signTransaction();
|
|
@@ -119,7 +141,11 @@ export class TransactionFactory {
|
|
|
119
141
|
(await preTransaction.estimateTransactionFees()) +
|
|
120
142
|
this.getPriorityFee(deploymentParameters) +
|
|
121
143
|
preTransaction.getOptionalOutputValue();
|
|
122
|
-
const fundingTransaction = new FundingTransaction(
|
|
144
|
+
const fundingTransaction = new FundingTransaction({
|
|
145
|
+
...parameters,
|
|
146
|
+
optionalInputs: [],
|
|
147
|
+
optionalOutputs: [],
|
|
148
|
+
});
|
|
123
149
|
const signedTransaction = await fundingTransaction.signTransaction();
|
|
124
150
|
if (!signedTransaction) {
|
|
125
151
|
throw new Error('Could not sign funding transaction.');
|
|
@@ -141,6 +167,7 @@ export class TransactionFactory {
|
|
|
141
167
|
preimage: preTransaction.getPreimage(),
|
|
142
168
|
nonWitnessUtxo: signedTransaction.toBuffer(),
|
|
143
169
|
optionalOutputs: [],
|
|
170
|
+
optionalInputs: [],
|
|
144
171
|
};
|
|
145
172
|
const finalTransaction = new DeploymentTransaction(newParams);
|
|
146
173
|
const outTx = await finalTransaction.signTransaction();
|
|
@@ -204,7 +231,7 @@ export class TransactionFactory {
|
|
|
204
231
|
return utxos;
|
|
205
232
|
}
|
|
206
233
|
async detectInteractionOPWallet(interactionParameters) {
|
|
207
|
-
if (typeof window === 'undefined' || !window.opnet || !window.opnet.web3) {
|
|
234
|
+
if (typeof window === 'undefined' || !window || !window.opnet || !window.opnet.web3) {
|
|
208
235
|
return null;
|
|
209
236
|
}
|
|
210
237
|
const opnet = window.opnet.web3;
|
|
@@ -36,8 +36,8 @@ export declare abstract class SharedInteractionTransaction<T extends Transaction
|
|
|
36
36
|
finalScriptWitness: Buffer<ArrayBufferLike>;
|
|
37
37
|
};
|
|
38
38
|
protected signInputsWalletBased(transaction: Psbt): Promise<void>;
|
|
39
|
+
protected signInputsNonWalletBased(transaction: Psbt): Promise<void>;
|
|
39
40
|
private createMineableRewardOutputs;
|
|
40
|
-
private signInputsNonWalletBased;
|
|
41
41
|
private getPubKeys;
|
|
42
42
|
private generateRedeemScripts;
|
|
43
43
|
}
|
|
@@ -156,7 +156,30 @@ export class SharedInteractionTransaction extends TransactionBuilder {
|
|
|
156
156
|
transaction.finalizeInput(i, this.customFinalizer);
|
|
157
157
|
}
|
|
158
158
|
else {
|
|
159
|
-
|
|
159
|
+
try {
|
|
160
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
161
|
+
}
|
|
162
|
+
catch (e) {
|
|
163
|
+
transaction.finalizeInput(i);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async signInputsNonWalletBased(transaction) {
|
|
169
|
+
for (let i = 0; i < transaction.data.inputs.length; i++) {
|
|
170
|
+
if (i === 0) {
|
|
171
|
+
await this.signInput(transaction, transaction.data.inputs[i], i, this.scriptSigner);
|
|
172
|
+
await this.signInput(transaction, transaction.data.inputs[i], i, this.getSignerKey());
|
|
173
|
+
transaction.finalizeInput(0, this.customFinalizer);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
await this.signInput(transaction, transaction.data.inputs[i], i, this.signer);
|
|
177
|
+
try {
|
|
178
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
179
|
+
}
|
|
180
|
+
catch (e) {
|
|
181
|
+
transaction.finalizeInput(i);
|
|
182
|
+
}
|
|
160
183
|
}
|
|
161
184
|
}
|
|
162
185
|
}
|
|
@@ -187,19 +210,6 @@ export class SharedInteractionTransaction extends TransactionBuilder {
|
|
|
187
210
|
await this.addRefundOutput(amountSpent + amount);
|
|
188
211
|
}
|
|
189
212
|
}
|
|
190
|
-
async signInputsNonWalletBased(transaction) {
|
|
191
|
-
for (let i = 0; i < transaction.data.inputs.length; i++) {
|
|
192
|
-
if (i === 0) {
|
|
193
|
-
await this.signInput(transaction, transaction.data.inputs[i], i, this.scriptSigner);
|
|
194
|
-
await this.signInput(transaction, transaction.data.inputs[i], i, this.getSignerKey());
|
|
195
|
-
transaction.finalizeInput(i, this.customFinalizer);
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
await this.signInput(transaction, transaction.data.inputs[i], i, this.getSignerKey());
|
|
199
|
-
transaction.finalizeInput(i);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
213
|
getPubKeys() {
|
|
204
214
|
const pubKeys = [Buffer.from(this.signer.publicKey)];
|
|
205
215
|
if (this.scriptSigner) {
|
|
@@ -28,6 +28,7 @@ export declare abstract class TransactionBuilder<T extends TransactionType> exte
|
|
|
28
28
|
protected priorityFee: bigint;
|
|
29
29
|
protected gasSatFee: bigint;
|
|
30
30
|
protected utxos: UTXO[];
|
|
31
|
+
protected optionalInputs: UTXO[];
|
|
31
32
|
protected to: string | undefined;
|
|
32
33
|
protected from: string;
|
|
33
34
|
protected _maximumFeeRate: number;
|
|
@@ -26,6 +26,7 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
26
26
|
this.priorityFee = parameters.priorityFee ?? 0n;
|
|
27
27
|
this.gasSatFee = parameters.gasSatFee ?? 0n;
|
|
28
28
|
this.utxos = parameters.utxos;
|
|
29
|
+
this.optionalInputs = parameters.optionalInputs || [];
|
|
29
30
|
this.to = parameters.to || undefined;
|
|
30
31
|
this.isPubKeyDestination = this.to
|
|
31
32
|
? AddressVerificator.isValidPublicKey(this.to, this.network)
|
|
@@ -81,6 +82,7 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
81
82
|
from: this.from,
|
|
82
83
|
amount: this.estimatedFees,
|
|
83
84
|
optionalOutputs: this.optionalOutputs,
|
|
85
|
+
optionalInputs: this.optionalInputs,
|
|
84
86
|
};
|
|
85
87
|
}
|
|
86
88
|
setDestinationAddress(address) {
|
|
@@ -254,6 +256,9 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
254
256
|
for (const utxo of this.utxos) {
|
|
255
257
|
total += utxo.value;
|
|
256
258
|
}
|
|
259
|
+
for (const utxo of this.optionalInputs) {
|
|
260
|
+
total += utxo.value;
|
|
261
|
+
}
|
|
257
262
|
return total;
|
|
258
263
|
}
|
|
259
264
|
calculateTotalVOutAmount() {
|
|
@@ -261,6 +266,9 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
261
266
|
for (const utxo of this.utxos) {
|
|
262
267
|
total += utxo.value;
|
|
263
268
|
}
|
|
269
|
+
for (const utxo of this.optionalInputs) {
|
|
270
|
+
total += utxo.value;
|
|
271
|
+
}
|
|
264
272
|
return total;
|
|
265
273
|
}
|
|
266
274
|
addOptionalOutputsAndGetAmount() {
|
|
@@ -284,6 +292,13 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
284
292
|
this.addInput(input);
|
|
285
293
|
}
|
|
286
294
|
}
|
|
295
|
+
if (this.optionalInputs) {
|
|
296
|
+
for (let i = this.utxos.length; i < this.optionalInputs.length + this.utxos.length; i++) {
|
|
297
|
+
const utxo = this.optionalInputs[i - this.utxos.length];
|
|
298
|
+
const input = this.generatePsbtInputExtended(utxo, i, true);
|
|
299
|
+
this.addInput(input);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
287
302
|
}
|
|
288
303
|
internalInit() {
|
|
289
304
|
this.verifyUTXOValidity();
|
|
@@ -313,6 +328,11 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
313
328
|
throw new Error('Address is required');
|
|
314
329
|
}
|
|
315
330
|
}
|
|
331
|
+
for (const utxo of this.optionalInputs) {
|
|
332
|
+
if (!utxo.scriptPubKey) {
|
|
333
|
+
throw new Error('Address is required');
|
|
334
|
+
}
|
|
335
|
+
}
|
|
316
336
|
}
|
|
317
337
|
async setFeeOutput(output) {
|
|
318
338
|
const initialValue = output.value;
|
|
@@ -8,6 +8,7 @@ export interface ITransactionParameters extends ITweakedTransactionData {
|
|
|
8
8
|
utxos: UTXO[];
|
|
9
9
|
nonWitnessUtxo?: Buffer;
|
|
10
10
|
estimatedFees?: bigint;
|
|
11
|
+
optionalInputs?: UTXO[];
|
|
11
12
|
optionalOutputs?: PsbtOutputExtended[];
|
|
12
13
|
chainId?: ChainId;
|
|
13
14
|
readonly feeRate: number;
|
|
@@ -51,6 +51,7 @@ export declare abstract class TweakedTransaction extends Logger {
|
|
|
51
51
|
protected signInput(transaction: Psbt, input: PsbtInput, i: number, signer: Signer | ECPairInterface, reverse?: boolean, errored?: boolean): Promise<void>;
|
|
52
52
|
protected splitArray<T>(arr: T[], chunkSize: number): T[][];
|
|
53
53
|
protected signInputs(transaction: Psbt): Promise<void>;
|
|
54
|
+
protected signInputsNonWalletBased(transaction: Psbt): Promise<void>;
|
|
54
55
|
protected internalPubKeyToXOnly(): Buffer;
|
|
55
56
|
protected internalInit(): void;
|
|
56
57
|
protected tweakSigner(): void;
|
|
@@ -64,7 +65,7 @@ export declare abstract class TweakedTransaction extends Logger {
|
|
|
64
65
|
redeemScript: Buffer;
|
|
65
66
|
outputScript: Buffer;
|
|
66
67
|
} | undefined;
|
|
67
|
-
protected generatePsbtInputExtended(utxo: UTXO, i: number): PsbtInputExtended;
|
|
68
|
+
protected generatePsbtInputExtended(utxo: UTXO, i: number, extra?: boolean): PsbtInputExtended;
|
|
68
69
|
protected customFinalizerP2SH: (inputIndex: number, input: PsbtInput, scriptA: Buffer, isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean) => {
|
|
69
70
|
finalScriptSig: Buffer | undefined;
|
|
70
71
|
finalScriptWitness: Buffer | undefined;
|
|
@@ -208,6 +208,9 @@ export class TweakedTransaction extends Logger {
|
|
|
208
208
|
await this.signInputsWalletBased(transaction);
|
|
209
209
|
return;
|
|
210
210
|
}
|
|
211
|
+
await this.signInputsNonWalletBased(transaction);
|
|
212
|
+
}
|
|
213
|
+
async signInputsNonWalletBased(transaction) {
|
|
211
214
|
const txs = transaction.data.inputs;
|
|
212
215
|
const batchSize = 20;
|
|
213
216
|
const batches = this.splitArray(txs, batchSize);
|
|
@@ -324,7 +327,7 @@ export class TweakedTransaction extends Logger {
|
|
|
324
327
|
}
|
|
325
328
|
return;
|
|
326
329
|
}
|
|
327
|
-
generatePsbtInputExtended(utxo, i) {
|
|
330
|
+
generatePsbtInputExtended(utxo, i, extra = false) {
|
|
328
331
|
const script = Buffer.from(utxo.scriptPubKey.hex, 'hex');
|
|
329
332
|
const input = {
|
|
330
333
|
hash: utxo.transactionId,
|
|
@@ -421,8 +424,10 @@ export class TweakedTransaction extends Logger {
|
|
|
421
424
|
else {
|
|
422
425
|
this.error(`Unknown or unsupported script type for output: ${utxo.scriptPubKey.hex}`);
|
|
423
426
|
}
|
|
424
|
-
if (
|
|
425
|
-
|
|
427
|
+
if (i === 0) {
|
|
428
|
+
if (this.tapLeafScript) {
|
|
429
|
+
input.tapLeafScript = [this.tapLeafScript];
|
|
430
|
+
}
|
|
426
431
|
}
|
|
427
432
|
if (i === 0 && this.nonWitnessUtxo) {
|
|
428
433
|
input.nonWitnessUtxo = this.nonWitnessUtxo;
|
|
@@ -453,7 +458,16 @@ export class TweakedTransaction extends Logger {
|
|
|
453
458
|
tweakedSigner = this.tweakedSigner;
|
|
454
459
|
}
|
|
455
460
|
if (tweakedSigner) {
|
|
456
|
-
|
|
461
|
+
try {
|
|
462
|
+
await this.signTaprootInput(tweakedSigner, transaction, i);
|
|
463
|
+
}
|
|
464
|
+
catch (e) {
|
|
465
|
+
tweakedSigner = this.getTweakedSigner(false, this.signer);
|
|
466
|
+
if (!tweakedSigner) {
|
|
467
|
+
throw new Error(`Failed to obtain tweaked signer for input ${i}.`);
|
|
468
|
+
}
|
|
469
|
+
await this.signTaprootInput(tweakedSigner, transaction, i);
|
|
470
|
+
}
|
|
457
471
|
}
|
|
458
472
|
else {
|
|
459
473
|
this.error(`Failed to obtain tweaked signer for input ${i}.`);
|
package/package.json
CHANGED
package/src/_version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.3.
|
|
1
|
+
export const version = '1.3.3';
|
|
@@ -103,7 +103,12 @@ export class TransactionFactory {
|
|
|
103
103
|
this.getPriorityFee(interactionParameters) +
|
|
104
104
|
preTransaction.getOptionalOutputValue();
|
|
105
105
|
|
|
106
|
-
const feeEstimationFundingTransaction = await this.createFundTransaction({
|
|
106
|
+
const feeEstimationFundingTransaction = await this.createFundTransaction({
|
|
107
|
+
...parameters,
|
|
108
|
+
optionalOutputs: [],
|
|
109
|
+
optionalInputs: [],
|
|
110
|
+
});
|
|
111
|
+
|
|
107
112
|
if (!feeEstimationFundingTransaction) {
|
|
108
113
|
throw new Error('Could not sign funding transaction.');
|
|
109
114
|
}
|
|
@@ -169,9 +174,30 @@ export class TransactionFactory {
|
|
|
169
174
|
throw new Error('Field "signer" not provided, OP_WALLET not detected.');
|
|
170
175
|
}
|
|
171
176
|
|
|
177
|
+
const inputs = (interactionParameters.optionalInputs || []).map((input) => {
|
|
178
|
+
let nonWitness = input.nonWitnessUtxo;
|
|
179
|
+
if (
|
|
180
|
+
nonWitness &&
|
|
181
|
+
!(nonWitness instanceof Uint8Array) &&
|
|
182
|
+
typeof nonWitness === 'object'
|
|
183
|
+
) {
|
|
184
|
+
nonWitness = Buffer.from(
|
|
185
|
+
Uint8Array.from(
|
|
186
|
+
Object.values(input.nonWitnessUtxo as unknown as Record<number, number>),
|
|
187
|
+
),
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return {
|
|
192
|
+
...input,
|
|
193
|
+
nonWitnessUtxo: nonWitness,
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
|
|
172
197
|
const preTransaction: InteractionTransaction = new InteractionTransaction({
|
|
173
198
|
...interactionParameters,
|
|
174
199
|
utxos: [interactionParameters.utxos[0]], // we simulate one input here.
|
|
200
|
+
optionalInputs: inputs,
|
|
175
201
|
});
|
|
176
202
|
|
|
177
203
|
// we don't sign that transaction, we just need the parameters.
|
|
@@ -189,7 +215,9 @@ export class TransactionFactory {
|
|
|
189
215
|
const feeEstimationFundingTransaction = await this.createFundTransaction({
|
|
190
216
|
...parameters,
|
|
191
217
|
optionalOutputs: [],
|
|
218
|
+
optionalInputs: [],
|
|
192
219
|
});
|
|
220
|
+
|
|
193
221
|
if (!feeEstimationFundingTransaction) {
|
|
194
222
|
throw new Error('Could not sign funding transaction.');
|
|
195
223
|
}
|
|
@@ -199,7 +227,9 @@ export class TransactionFactory {
|
|
|
199
227
|
const signedTransaction = await this.createFundTransaction({
|
|
200
228
|
...parameters,
|
|
201
229
|
optionalOutputs: [],
|
|
230
|
+
optionalInputs: [],
|
|
202
231
|
});
|
|
232
|
+
|
|
203
233
|
if (!signedTransaction) {
|
|
204
234
|
throw new Error('Could not sign funding transaction.');
|
|
205
235
|
}
|
|
@@ -212,11 +242,14 @@ export class TransactionFactory {
|
|
|
212
242
|
|
|
213
243
|
const newParams: IInteractionParameters = {
|
|
214
244
|
...interactionParameters,
|
|
215
|
-
utxos:
|
|
245
|
+
utxos: [
|
|
246
|
+
...this.getUTXOAsTransaction(signedTransaction.tx, interactionParameters.to, 0),
|
|
247
|
+
], // always 0
|
|
216
248
|
randomBytes: preTransaction.getRndBytes(),
|
|
217
249
|
preimage: preTransaction.getPreimage(),
|
|
218
250
|
nonWitnessUtxo: signedTransaction.tx.toBuffer(),
|
|
219
251
|
estimatedFees: preTransaction.estimatedFees,
|
|
252
|
+
optionalInputs: inputs,
|
|
220
253
|
};
|
|
221
254
|
|
|
222
255
|
const finalTransaction: InteractionTransaction = new InteractionTransaction(newParams);
|
|
@@ -259,7 +292,12 @@ export class TransactionFactory {
|
|
|
259
292
|
this.getPriorityFee(deploymentParameters) +
|
|
260
293
|
preTransaction.getOptionalOutputValue();
|
|
261
294
|
|
|
262
|
-
const fundingTransaction: FundingTransaction = new FundingTransaction(
|
|
295
|
+
const fundingTransaction: FundingTransaction = new FundingTransaction({
|
|
296
|
+
...parameters,
|
|
297
|
+
optionalInputs: [],
|
|
298
|
+
optionalOutputs: [],
|
|
299
|
+
});
|
|
300
|
+
|
|
263
301
|
const signedTransaction: Transaction = await fundingTransaction.signTransaction();
|
|
264
302
|
if (!signedTransaction) {
|
|
265
303
|
throw new Error('Could not sign funding transaction.');
|
|
@@ -283,6 +321,7 @@ export class TransactionFactory {
|
|
|
283
321
|
preimage: preTransaction.getPreimage(),
|
|
284
322
|
nonWitnessUtxo: signedTransaction.toBuffer(),
|
|
285
323
|
optionalOutputs: [],
|
|
324
|
+
optionalInputs: [],
|
|
286
325
|
};
|
|
287
326
|
|
|
288
327
|
const finalTransaction: DeploymentTransaction = new DeploymentTransaction(newParams);
|
|
@@ -384,7 +423,7 @@ export class TransactionFactory {
|
|
|
384
423
|
private async detectInteractionOPWallet(
|
|
385
424
|
interactionParameters: IInteractionParameters | InteractionParametersWithoutSigner,
|
|
386
425
|
): Promise<InteractionResponse | null> {
|
|
387
|
-
if (typeof window === 'undefined' || !window.opnet || !window.opnet.web3) {
|
|
426
|
+
if (typeof window === 'undefined' || !window || !window.opnet || !window.opnet.web3) {
|
|
388
427
|
return null;
|
|
389
428
|
}
|
|
390
429
|
|
|
@@ -411,6 +450,7 @@ export class TransactionFactory {
|
|
|
411
450
|
const challengeTransaction: ChallengeSolutionTransaction = new ChallengeSolutionTransaction(
|
|
412
451
|
parameters,
|
|
413
452
|
);
|
|
453
|
+
|
|
414
454
|
const signedTransaction: Transaction = await challengeTransaction.signTransaction();
|
|
415
455
|
if (!signedTransaction) {
|
|
416
456
|
throw new Error('Could not sign funding transaction.');
|
|
@@ -67,7 +67,7 @@ export abstract class SharedInteractionTransaction<
|
|
|
67
67
|
throw new Error('Calldata is required');
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
if(!parameters.preimage) {
|
|
70
|
+
if (!parameters.preimage) {
|
|
71
71
|
throw new Error('Preimage is required');
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -319,7 +319,36 @@ export abstract class SharedInteractionTransaction<
|
|
|
319
319
|
if (i === 0) {
|
|
320
320
|
transaction.finalizeInput(i, this.customFinalizer);
|
|
321
321
|
} else {
|
|
322
|
-
|
|
322
|
+
try {
|
|
323
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
324
|
+
} catch (e) {
|
|
325
|
+
transaction.finalizeInput(i);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
protected override async signInputsNonWalletBased(transaction: Psbt): Promise<void> {
|
|
332
|
+
for (let i = 0; i < transaction.data.inputs.length; i++) {
|
|
333
|
+
if (i === 0) {
|
|
334
|
+
await this.signInput(transaction, transaction.data.inputs[i], i, this.scriptSigner);
|
|
335
|
+
|
|
336
|
+
await this.signInput(
|
|
337
|
+
transaction,
|
|
338
|
+
transaction.data.inputs[i],
|
|
339
|
+
i,
|
|
340
|
+
this.getSignerKey(),
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
transaction.finalizeInput(0, this.customFinalizer);
|
|
344
|
+
} else {
|
|
345
|
+
await this.signInput(transaction, transaction.data.inputs[i], i, this.signer);
|
|
346
|
+
|
|
347
|
+
try {
|
|
348
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
349
|
+
} catch (e) {
|
|
350
|
+
transaction.finalizeInput(i);
|
|
351
|
+
}
|
|
323
352
|
}
|
|
324
353
|
}
|
|
325
354
|
}
|
|
@@ -359,32 +388,6 @@ export abstract class SharedInteractionTransaction<
|
|
|
359
388
|
}
|
|
360
389
|
}
|
|
361
390
|
|
|
362
|
-
private async signInputsNonWalletBased(transaction: Psbt): Promise<void> {
|
|
363
|
-
for (let i = 0; i < transaction.data.inputs.length; i++) {
|
|
364
|
-
if (i === 0) {
|
|
365
|
-
await this.signInput(transaction, transaction.data.inputs[i], i, this.scriptSigner);
|
|
366
|
-
|
|
367
|
-
await this.signInput(
|
|
368
|
-
transaction,
|
|
369
|
-
transaction.data.inputs[i],
|
|
370
|
-
i,
|
|
371
|
-
this.getSignerKey(),
|
|
372
|
-
);
|
|
373
|
-
|
|
374
|
-
transaction.finalizeInput(i, this.customFinalizer);
|
|
375
|
-
} else {
|
|
376
|
-
await this.signInput(
|
|
377
|
-
transaction,
|
|
378
|
-
transaction.data.inputs[i],
|
|
379
|
-
i,
|
|
380
|
-
this.getSignerKey(),
|
|
381
|
-
);
|
|
382
|
-
|
|
383
|
-
transaction.finalizeInput(i);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
|
|
388
391
|
/**
|
|
389
392
|
* Get the public keys
|
|
390
393
|
* @private
|