@btc-vision/transaction 1.5.1 → 1.5.3
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 +0 -1
- package/browser/transaction/interfaces/ITransactionParameters.d.ts +2 -0
- package/browser/transaction/shared/TweakedTransaction.d.ts +5 -1
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/keypair/AddressVerificator.js +3 -1
- package/build/transaction/builders/DeploymentTransaction.js +4 -4
- package/build/transaction/builders/InteractionTransaction.js +7 -1
- package/build/transaction/builders/SharedInteractionTransaction.d.ts +0 -1
- package/build/transaction/builders/SharedInteractionTransaction.js +5 -13
- package/build/transaction/interfaces/ITransactionParameters.d.ts +2 -0
- package/build/transaction/shared/TweakedTransaction.d.ts +5 -1
- package/build/transaction/shared/TweakedTransaction.js +24 -19
- package/package.json +9 -9
- package/src/_version.ts +1 -1
- package/src/keypair/AddressVerificator.ts +5 -1
- package/src/transaction/builders/DeploymentTransaction.ts +4 -4
- package/src/transaction/builders/InteractionTransaction.ts +9 -1
- package/src/transaction/builders/SharedInteractionTransaction.ts +8 -7
- package/src/transaction/interfaces/ITransactionParameters.ts +2 -0
- package/src/transaction/shared/TweakedTransaction.ts +37 -19
|
@@ -23,7 +23,6 @@ export declare abstract class SharedInteractionTransaction<T extends Transaction
|
|
|
23
23
|
getContractSecret(): Buffer;
|
|
24
24
|
getRndBytes(): Buffer;
|
|
25
25
|
getPreimage(): Buffer;
|
|
26
|
-
protected generateSecret(): Buffer;
|
|
27
26
|
protected scriptSignerXOnlyPubKey(): Buffer;
|
|
28
27
|
protected generateKeyPairFromSeed(): ECPairInterface;
|
|
29
28
|
protected buildTransaction(): Promise<void>;
|
|
@@ -14,6 +14,7 @@ export interface ITransactionParameters extends ITweakedTransactionData {
|
|
|
14
14
|
optionalInputs?: UTXO[];
|
|
15
15
|
optionalOutputs?: PsbtOutputExtended[];
|
|
16
16
|
chainId?: ChainId;
|
|
17
|
+
noSignatures?: boolean;
|
|
17
18
|
readonly feeRate: number;
|
|
18
19
|
readonly priorityFee: bigint;
|
|
19
20
|
readonly gasSatFee: bigint;
|
|
@@ -36,6 +37,7 @@ export interface SharedInteractionParameters extends ITransactionParameters {
|
|
|
36
37
|
export interface IInteractionParameters extends SharedInteractionParameters {
|
|
37
38
|
readonly calldata: Buffer;
|
|
38
39
|
readonly to: string;
|
|
40
|
+
readonly contract?: string;
|
|
39
41
|
}
|
|
40
42
|
export interface IDeploymentParameters extends Omit<ITransactionParameters, 'to'> {
|
|
41
43
|
readonly bytecode: Buffer;
|
|
@@ -10,6 +10,8 @@ export interface ITweakedTransactionData {
|
|
|
10
10
|
readonly network: Network;
|
|
11
11
|
readonly chainId?: ChainId;
|
|
12
12
|
readonly nonWitnessUtxo?: Buffer;
|
|
13
|
+
readonly noSignatures?: boolean;
|
|
14
|
+
readonly unlockScript?: Buffer[];
|
|
13
15
|
}
|
|
14
16
|
export declare enum TransactionSequence {
|
|
15
17
|
REPLACE_BY_FEE = 4294967293,
|
|
@@ -33,6 +35,8 @@ export declare abstract class TweakedTransaction extends Logger {
|
|
|
33
35
|
protected readonly isBrowser: boolean;
|
|
34
36
|
protected regenerated: boolean;
|
|
35
37
|
protected ignoreSignatureErrors: boolean;
|
|
38
|
+
protected noSignatures: boolean;
|
|
39
|
+
protected unlockScript: Buffer[] | undefined;
|
|
36
40
|
protected constructor(data: ITweakedTransactionData);
|
|
37
41
|
static readScriptWitnessToWitnessStack(Buffer: Buffer): Buffer[];
|
|
38
42
|
static preEstimateTaprootTransactionFees(feeRate: bigint, numInputs: bigint, numOutputs: bigint, numWitnessElements: bigint, witnessElementSize: bigint, emptyWitness: bigint, taprootControlWitnessSize?: bigint, taprootScriptSize?: bigint): bigint;
|
|
@@ -65,7 +69,7 @@ export declare abstract class TweakedTransaction extends Logger {
|
|
|
65
69
|
redeemScript: Buffer;
|
|
66
70
|
outputScript: Buffer;
|
|
67
71
|
} | undefined;
|
|
68
|
-
protected generatePsbtInputExtended(utxo: UTXO, i: number,
|
|
72
|
+
protected generatePsbtInputExtended(utxo: UTXO, i: number, _extra?: boolean): PsbtInputExtended;
|
|
69
73
|
protected customFinalizerP2SH: (inputIndex: number, input: PsbtInput, scriptA: Buffer, isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean) => {
|
|
70
74
|
finalScriptSig: Buffer | undefined;
|
|
71
75
|
finalScriptWitness: Buffer | undefined;
|
package/build/_version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "1.
|
|
1
|
+
export declare const version = "1.5.3";
|
package/build/_version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.
|
|
1
|
+
export const version = '1.5.3';
|
|
@@ -103,7 +103,9 @@ export class AddressVerificator {
|
|
|
103
103
|
catch { }
|
|
104
104
|
try {
|
|
105
105
|
const decodedBech32 = address.fromBech32(addy);
|
|
106
|
-
if (decodedBech32.prefix === network.bech32Opnet
|
|
106
|
+
if ((decodedBech32.prefix === network.bech32Opnet ||
|
|
107
|
+
decodedBech32.prefix === network.bech32) &&
|
|
108
|
+
decodedBech32.version === 16) {
|
|
107
109
|
return AddressTypes.P2OP;
|
|
108
110
|
}
|
|
109
111
|
if (decodedBech32.prefix === network.bech32) {
|
|
@@ -129,11 +129,11 @@ export class DeploymentTransaction extends TransactionBuilder {
|
|
|
129
129
|
await signer.multiSignPsbt([transaction]);
|
|
130
130
|
for (let i = 0; i < transaction.data.inputs.length; i++) {
|
|
131
131
|
if (i === 0) {
|
|
132
|
-
transaction.finalizeInput(i, this.customFinalizer);
|
|
132
|
+
transaction.finalizeInput(i, this.customFinalizer.bind(this));
|
|
133
133
|
}
|
|
134
134
|
else {
|
|
135
135
|
try {
|
|
136
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
136
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
137
137
|
}
|
|
138
138
|
catch (e) {
|
|
139
139
|
transaction.finalizeInput(i);
|
|
@@ -154,12 +154,12 @@ export class DeploymentTransaction extends TransactionBuilder {
|
|
|
154
154
|
if (i === 0) {
|
|
155
155
|
transaction.signInput(0, this.contractSigner);
|
|
156
156
|
transaction.signInput(0, this.getSignerKey());
|
|
157
|
-
transaction.finalizeInput(0, this.customFinalizer);
|
|
157
|
+
transaction.finalizeInput(0, this.customFinalizer.bind(this));
|
|
158
158
|
}
|
|
159
159
|
else {
|
|
160
160
|
transaction.signInput(i, this.getSignerKey());
|
|
161
161
|
try {
|
|
162
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
162
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
163
163
|
}
|
|
164
164
|
catch (e) {
|
|
165
165
|
transaction.finalizeInput(i);
|
|
@@ -6,7 +6,13 @@ export class InteractionTransaction extends SharedInteractionTransaction {
|
|
|
6
6
|
super(parameters);
|
|
7
7
|
this.type = TransactionType.INTERACTION;
|
|
8
8
|
this.tapLeafScript = null;
|
|
9
|
-
|
|
9
|
+
if (!parameters.contract) {
|
|
10
|
+
throw new Error('parameters.contract is required for interaction transaction.');
|
|
11
|
+
}
|
|
12
|
+
this.contractSecret = Buffer.from(parameters.contract.replace('0x', ''), 'hex');
|
|
13
|
+
if (this.contractSecret.length !== 32) {
|
|
14
|
+
throw new Error('Invalid contract secret length. Expected 32 bytes.');
|
|
15
|
+
}
|
|
10
16
|
this.compiledTargetScript = this.calldataGenerator.compile(this.calldata, this.contractSecret, this.preimage, this.priorityFee, this.generateFeatures(parameters));
|
|
11
17
|
this.scriptTree = this.getScriptTree();
|
|
12
18
|
this.internalInit();
|
|
@@ -23,7 +23,6 @@ export declare abstract class SharedInteractionTransaction<T extends Transaction
|
|
|
23
23
|
getContractSecret(): Buffer;
|
|
24
24
|
getRndBytes(): Buffer;
|
|
25
25
|
getPreimage(): Buffer;
|
|
26
|
-
protected generateSecret(): Buffer;
|
|
27
26
|
protected scriptSignerXOnlyPubKey(): Buffer;
|
|
28
27
|
protected generateKeyPairFromSeed(): ECPairInterface;
|
|
29
28
|
protected buildTransaction(): Promise<void>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PaymentType, toXOnly } from '@btc-vision/bitcoin';
|
|
2
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';
|
|
@@ -48,14 +48,6 @@ export class SharedInteractionTransaction extends TransactionBuilder {
|
|
|
48
48
|
getPreimage() {
|
|
49
49
|
return this.preimage;
|
|
50
50
|
}
|
|
51
|
-
generateSecret() {
|
|
52
|
-
if (!this.to)
|
|
53
|
-
throw new Error('To address is required');
|
|
54
|
-
if (this.to.startsWith('0x')) {
|
|
55
|
-
throw new Error(`Legacy not support at this time. Reserved for future use.`);
|
|
56
|
-
}
|
|
57
|
-
return address.fromBech32(this.to).data;
|
|
58
|
-
}
|
|
59
51
|
scriptSignerXOnlyPubKey() {
|
|
60
52
|
return toXOnly(Buffer.from(this.scriptSigner.publicKey));
|
|
61
53
|
}
|
|
@@ -155,11 +147,11 @@ export class SharedInteractionTransaction extends TransactionBuilder {
|
|
|
155
147
|
await signer.multiSignPsbt([transaction]);
|
|
156
148
|
for (let i = 0; i < transaction.data.inputs.length; i++) {
|
|
157
149
|
if (i === 0) {
|
|
158
|
-
transaction.finalizeInput(i, this.customFinalizer);
|
|
150
|
+
transaction.finalizeInput(i, this.customFinalizer.bind(this));
|
|
159
151
|
}
|
|
160
152
|
else {
|
|
161
153
|
try {
|
|
162
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
154
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
163
155
|
}
|
|
164
156
|
catch (e) {
|
|
165
157
|
transaction.finalizeInput(i);
|
|
@@ -172,12 +164,12 @@ export class SharedInteractionTransaction extends TransactionBuilder {
|
|
|
172
164
|
if (i === 0) {
|
|
173
165
|
await this.signInput(transaction, transaction.data.inputs[i], i, this.scriptSigner);
|
|
174
166
|
await this.signInput(transaction, transaction.data.inputs[i], i, this.getSignerKey());
|
|
175
|
-
transaction.finalizeInput(0, this.customFinalizer);
|
|
167
|
+
transaction.finalizeInput(0, this.customFinalizer.bind(this));
|
|
176
168
|
}
|
|
177
169
|
else {
|
|
178
170
|
await this.signInput(transaction, transaction.data.inputs[i], i, this.signer);
|
|
179
171
|
try {
|
|
180
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
172
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
181
173
|
}
|
|
182
174
|
catch (e) {
|
|
183
175
|
transaction.finalizeInput(i);
|
|
@@ -14,6 +14,7 @@ export interface ITransactionParameters extends ITweakedTransactionData {
|
|
|
14
14
|
optionalInputs?: UTXO[];
|
|
15
15
|
optionalOutputs?: PsbtOutputExtended[];
|
|
16
16
|
chainId?: ChainId;
|
|
17
|
+
noSignatures?: boolean;
|
|
17
18
|
readonly feeRate: number;
|
|
18
19
|
readonly priorityFee: bigint;
|
|
19
20
|
readonly gasSatFee: bigint;
|
|
@@ -36,6 +37,7 @@ export interface SharedInteractionParameters extends ITransactionParameters {
|
|
|
36
37
|
export interface IInteractionParameters extends SharedInteractionParameters {
|
|
37
38
|
readonly calldata: Buffer;
|
|
38
39
|
readonly to: string;
|
|
40
|
+
readonly contract?: string;
|
|
39
41
|
}
|
|
40
42
|
export interface IDeploymentParameters extends Omit<ITransactionParameters, 'to'> {
|
|
41
43
|
readonly bytecode: Buffer;
|
|
@@ -10,6 +10,8 @@ export interface ITweakedTransactionData {
|
|
|
10
10
|
readonly network: Network;
|
|
11
11
|
readonly chainId?: ChainId;
|
|
12
12
|
readonly nonWitnessUtxo?: Buffer;
|
|
13
|
+
readonly noSignatures?: boolean;
|
|
14
|
+
readonly unlockScript?: Buffer[];
|
|
13
15
|
}
|
|
14
16
|
export declare enum TransactionSequence {
|
|
15
17
|
REPLACE_BY_FEE = 4294967293,
|
|
@@ -33,6 +35,8 @@ export declare abstract class TweakedTransaction extends Logger {
|
|
|
33
35
|
protected readonly isBrowser: boolean;
|
|
34
36
|
protected regenerated: boolean;
|
|
35
37
|
protected ignoreSignatureErrors: boolean;
|
|
38
|
+
protected noSignatures: boolean;
|
|
39
|
+
protected unlockScript: Buffer[] | undefined;
|
|
36
40
|
protected constructor(data: ITweakedTransactionData);
|
|
37
41
|
static readScriptWitnessToWitnessStack(Buffer: Buffer): Buffer[];
|
|
38
42
|
static preEstimateTaprootTransactionFees(feeRate: bigint, numInputs: bigint, numOutputs: bigint, numWitnessElements: bigint, witnessElementSize: bigint, emptyWitness: bigint, taprootControlWitnessSize?: bigint, taprootScriptSize?: bigint): bigint;
|
|
@@ -65,7 +69,7 @@ export declare abstract class TweakedTransaction extends Logger {
|
|
|
65
69
|
redeemScript: Buffer;
|
|
66
70
|
outputScript: Buffer;
|
|
67
71
|
} | undefined;
|
|
68
|
-
protected generatePsbtInputExtended(utxo: UTXO, i: number,
|
|
72
|
+
protected generatePsbtInputExtended(utxo: UTXO, i: number, _extra?: boolean): PsbtInputExtended;
|
|
69
73
|
protected customFinalizerP2SH: (inputIndex: number, input: PsbtInput, scriptA: Buffer, isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean) => {
|
|
70
74
|
finalScriptSig: Buffer | undefined;
|
|
71
75
|
finalScriptWitness: Buffer | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Logger } from '@btc-vision/logger';
|
|
2
|
-
import { address as bitAddress, crypto as bitCrypto, getFinalScripts, isP2MS, isP2PK, isP2PKH, isP2SHScript, isP2TR, isP2WPKH, isP2WSHScript, opcodes, payments, PaymentType, script, toXOnly, varuint, } from '@btc-vision/bitcoin';
|
|
2
|
+
import { address as bitAddress, crypto as bitCrypto, getFinalScripts, isP2MS, isP2PK, isP2PKH, isP2SHScript, isP2TR, isP2WPKH, isP2WSHScript, isUnknownSegwitVersion, opcodes, payments, PaymentType, script, toXOnly, varuint, } from '@btc-vision/bitcoin';
|
|
3
3
|
import { TweakedSigner } from '../../signer/TweakedSigner.js';
|
|
4
4
|
import { canSignNonTaprootInput, isTaprootInput, pubkeyInScript, } from '../../signer/SignerUtils.js';
|
|
5
5
|
export var TransactionSequence;
|
|
@@ -21,6 +21,7 @@ export class TweakedTransaction extends Logger {
|
|
|
21
21
|
this.isBrowser = false;
|
|
22
22
|
this.regenerated = false;
|
|
23
23
|
this.ignoreSignatureErrors = false;
|
|
24
|
+
this.noSignatures = false;
|
|
24
25
|
this.customFinalizerP2SH = (inputIndex, input, scriptA, isSegwit, isP2SH, isP2WSH) => {
|
|
25
26
|
const inputDecoded = this.inputs[inputIndex];
|
|
26
27
|
if (isP2SH && input.partialSig && inputDecoded && inputDecoded.redeemScript) {
|
|
@@ -31,11 +32,13 @@ export class TweakedTransaction extends Logger {
|
|
|
31
32
|
finalScriptWitness: undefined,
|
|
32
33
|
};
|
|
33
34
|
}
|
|
34
|
-
return getFinalScripts(inputIndex, input, scriptA, isSegwit, isP2SH, isP2WSH);
|
|
35
|
+
return getFinalScripts(inputIndex, input, scriptA, isSegwit, isP2SH, isP2WSH, true, this.unlockScript);
|
|
35
36
|
};
|
|
36
37
|
this.signer = data.signer;
|
|
37
38
|
this.network = data.network;
|
|
39
|
+
this.noSignatures = data.noSignatures || false;
|
|
38
40
|
this.nonWitnessUtxo = data.nonWitnessUtxo;
|
|
41
|
+
this.unlockScript = data.unlockScript;
|
|
39
42
|
this.isBrowser = typeof window !== 'undefined';
|
|
40
43
|
}
|
|
41
44
|
static readScriptWitnessToWitnessStack(Buffer) {
|
|
@@ -216,24 +219,26 @@ export class TweakedTransaction extends Logger {
|
|
|
216
219
|
const txs = transaction.data.inputs;
|
|
217
220
|
const batchSize = 20;
|
|
218
221
|
const batches = this.splitArray(txs, batchSize);
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
222
|
+
if (!this.noSignatures) {
|
|
223
|
+
for (let i = 0; i < batches.length; i++) {
|
|
224
|
+
const batch = batches[i];
|
|
225
|
+
const promises = [];
|
|
226
|
+
const offset = i * batchSize;
|
|
227
|
+
for (let j = 0; j < batch.length; j++) {
|
|
228
|
+
const index = offset + j;
|
|
229
|
+
const input = batch[j];
|
|
230
|
+
try {
|
|
231
|
+
promises.push(this.signInput(transaction, input, index, this.signer));
|
|
232
|
+
}
|
|
233
|
+
catch (e) {
|
|
234
|
+
this.log(`Failed to sign input ${index}: ${e.stack}`);
|
|
235
|
+
}
|
|
231
236
|
}
|
|
237
|
+
await Promise.all(promises);
|
|
232
238
|
}
|
|
233
|
-
await Promise.all(promises);
|
|
234
239
|
}
|
|
235
240
|
for (let i = 0; i < transaction.data.inputs.length; i++) {
|
|
236
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
241
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
237
242
|
}
|
|
238
243
|
this.finalized = true;
|
|
239
244
|
}
|
|
@@ -329,7 +334,7 @@ export class TweakedTransaction extends Logger {
|
|
|
329
334
|
}
|
|
330
335
|
return;
|
|
331
336
|
}
|
|
332
|
-
generatePsbtInputExtended(utxo, i,
|
|
337
|
+
generatePsbtInputExtended(utxo, i, _extra = false) {
|
|
333
338
|
const script = Buffer.from(utxo.scriptPubKey.hex, 'hex');
|
|
334
339
|
const input = {
|
|
335
340
|
hash: utxo.transactionId,
|
|
@@ -350,7 +355,7 @@ export class TweakedTransaction extends Logger {
|
|
|
350
355
|
throw new Error('Missing nonWitnessUtxo for P2PKH UTXO');
|
|
351
356
|
}
|
|
352
357
|
}
|
|
353
|
-
else if (isP2WPKH(script)) {
|
|
358
|
+
else if (isP2WPKH(script) || isUnknownSegwitVersion(script)) {
|
|
354
359
|
}
|
|
355
360
|
else if (isP2WSHScript(script)) {
|
|
356
361
|
if (!utxo.witnessScript) {
|
|
@@ -440,7 +445,7 @@ export class TweakedTransaction extends Logger {
|
|
|
440
445
|
const signer = this.signer;
|
|
441
446
|
await signer.multiSignPsbt([transaction]);
|
|
442
447
|
for (let i = 0; i < transaction.data.inputs.length; i++) {
|
|
443
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
448
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
444
449
|
}
|
|
445
450
|
this.finalized = true;
|
|
446
451
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btc-vision/transaction",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.3",
|
|
5
5
|
"author": "BlobMaster41",
|
|
6
6
|
"description": "OPNet transaction library allows you to create and sign transactions for the OPNet network.",
|
|
7
7
|
"engines": {
|
|
@@ -64,17 +64,17 @@
|
|
|
64
64
|
"docs": "typedoc --out docs --exclude 'src/tests/*.ts' --tsconfig tsconfig.json --readme README.md --name OPNet --plugin typedoc-material-theme --themeColor '#cb9820' --exclude src/tests/test.ts --exclude src/index.ts src"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
-
"@babel/core": "^7.27.
|
|
67
|
+
"@babel/core": "^7.27.4",
|
|
68
68
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
69
|
-
"@babel/plugin-transform-runtime": "^7.27.
|
|
69
|
+
"@babel/plugin-transform-runtime": "^7.27.4",
|
|
70
70
|
"@babel/preset-env": "^7.27.2",
|
|
71
71
|
"@babel/preset-flow": "^7.27.1",
|
|
72
72
|
"@babel/preset-react": "^7.27.1",
|
|
73
73
|
"@babel/preset-typescript": "^7.27.1",
|
|
74
|
-
"@types/node": "^22.15.
|
|
74
|
+
"@types/node": "^22.15.29",
|
|
75
75
|
"@types/sha.js": "^2.4.4",
|
|
76
|
-
"eslint": "^9.
|
|
77
|
-
"gulp": "^5.0.
|
|
76
|
+
"eslint": "^9.28.0",
|
|
77
|
+
"gulp": "^5.0.1",
|
|
78
78
|
"gulp-cached": "^1.1.1",
|
|
79
79
|
"gulp-typescript": "^6.0.0-alpha.1",
|
|
80
80
|
"https-browserify": "^1.0.0",
|
|
@@ -88,11 +88,11 @@
|
|
|
88
88
|
},
|
|
89
89
|
"dependencies": {
|
|
90
90
|
"@babel/plugin-proposal-object-rest-spread": "^7.20.7",
|
|
91
|
-
"@bitcoinerlab/secp256k1": "^1.
|
|
92
|
-
"@btc-vision/bitcoin": "^6.4.
|
|
91
|
+
"@bitcoinerlab/secp256k1": "^1.2.0",
|
|
92
|
+
"@btc-vision/bitcoin": "^6.4.6",
|
|
93
93
|
"@btc-vision/bitcoin-rpc": "^1.0.1",
|
|
94
94
|
"@btc-vision/logger": "^1.0.6",
|
|
95
|
-
"@eslint/js": "^9.
|
|
95
|
+
"@eslint/js": "^9.28.0",
|
|
96
96
|
"@noble/secp256k1": "^2.2.3",
|
|
97
97
|
"assert": "^2.1.0",
|
|
98
98
|
"babel-loader": "^10.0.0",
|
package/src/_version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.
|
|
1
|
+
export const version = '1.5.3';
|
|
@@ -184,7 +184,11 @@ export class AddressVerificator {
|
|
|
184
184
|
try {
|
|
185
185
|
// Try to decode as a Bech32 or Bech32m address (P2WPKH or P2TR)
|
|
186
186
|
const decodedBech32 = address.fromBech32(addy);
|
|
187
|
-
if (
|
|
187
|
+
if (
|
|
188
|
+
(decodedBech32.prefix === network.bech32Opnet ||
|
|
189
|
+
decodedBech32.prefix === network.bech32) &&
|
|
190
|
+
decodedBech32.version === 16
|
|
191
|
+
) {
|
|
188
192
|
return AddressTypes.P2OP;
|
|
189
193
|
}
|
|
190
194
|
|
|
@@ -290,10 +290,10 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
|
|
|
290
290
|
// Then, we finalize every input.
|
|
291
291
|
for (let i = 0; i < transaction.data.inputs.length; i++) {
|
|
292
292
|
if (i === 0) {
|
|
293
|
-
transaction.finalizeInput(i, this.customFinalizer);
|
|
293
|
+
transaction.finalizeInput(i, this.customFinalizer.bind(this));
|
|
294
294
|
} else {
|
|
295
295
|
try {
|
|
296
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
296
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
297
297
|
} catch (e) {
|
|
298
298
|
transaction.finalizeInput(i);
|
|
299
299
|
}
|
|
@@ -324,12 +324,12 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
|
|
|
324
324
|
transaction.signInput(0, this.contractSigner);
|
|
325
325
|
transaction.signInput(0, this.getSignerKey());
|
|
326
326
|
|
|
327
|
-
transaction.finalizeInput(0, this.customFinalizer);
|
|
327
|
+
transaction.finalizeInput(0, this.customFinalizer.bind(this));
|
|
328
328
|
} else {
|
|
329
329
|
transaction.signInput(i, this.getSignerKey());
|
|
330
330
|
|
|
331
331
|
try {
|
|
332
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
332
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
333
333
|
} catch (e) {
|
|
334
334
|
transaction.finalizeInput(i);
|
|
335
335
|
}
|
|
@@ -26,7 +26,15 @@ export class InteractionTransaction extends SharedInteractionTransaction<Transac
|
|
|
26
26
|
public constructor(parameters: IInteractionParameters) {
|
|
27
27
|
super(parameters);
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
if (!parameters.contract) {
|
|
30
|
+
throw new Error('parameters.contract is required for interaction transaction.');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
this.contractSecret = Buffer.from(parameters.contract.replace('0x', ''), 'hex');
|
|
34
|
+
|
|
35
|
+
if (this.contractSecret.length !== 32) {
|
|
36
|
+
throw new Error('Invalid contract secret length. Expected 32 bytes.');
|
|
37
|
+
}
|
|
30
38
|
|
|
31
39
|
this.compiledTargetScript = this.calldataGenerator.compile(
|
|
32
40
|
this.calldata,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { P2TRPayment, PaymentType, Psbt, PsbtInput, Signer, Taptree, toXOnly } from '@btc-vision/bitcoin';
|
|
2
2
|
import { ECPairInterface } from 'ecpair';
|
|
3
3
|
import { MINIMUM_AMOUNT_CA, MINIMUM_AMOUNT_REWARD, TransactionBuilder } from './TransactionBuilder.js';
|
|
4
4
|
import { TransactionType } from '../enums/TransactionType.js';
|
|
@@ -120,7 +120,8 @@ export abstract class SharedInteractionTransaction<
|
|
|
120
120
|
* @returns {Buffer} The secret
|
|
121
121
|
* @throws {Error} If the to address is invalid
|
|
122
122
|
*/
|
|
123
|
-
|
|
123
|
+
|
|
124
|
+
/*protected generateSecret(): Buffer {
|
|
124
125
|
if (!this.to) throw new Error('To address is required');
|
|
125
126
|
|
|
126
127
|
if (this.to.startsWith('0x')) {
|
|
@@ -128,7 +129,7 @@ export abstract class SharedInteractionTransaction<
|
|
|
128
129
|
}
|
|
129
130
|
|
|
130
131
|
return address.fromBech32(this.to).data;
|
|
131
|
-
}
|
|
132
|
+
}*/
|
|
132
133
|
|
|
133
134
|
/**
|
|
134
135
|
* Get the internal pubkey as an x-only key
|
|
@@ -319,10 +320,10 @@ export abstract class SharedInteractionTransaction<
|
|
|
319
320
|
// Then, we finalize every input.
|
|
320
321
|
for (let i = 0; i < transaction.data.inputs.length; i++) {
|
|
321
322
|
if (i === 0) {
|
|
322
|
-
transaction.finalizeInput(i, this.customFinalizer);
|
|
323
|
+
transaction.finalizeInput(i, this.customFinalizer.bind(this));
|
|
323
324
|
} else {
|
|
324
325
|
try {
|
|
325
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
326
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
326
327
|
} catch (e) {
|
|
327
328
|
transaction.finalizeInput(i);
|
|
328
329
|
}
|
|
@@ -342,12 +343,12 @@ export abstract class SharedInteractionTransaction<
|
|
|
342
343
|
this.getSignerKey(),
|
|
343
344
|
);
|
|
344
345
|
|
|
345
|
-
transaction.finalizeInput(0, this.customFinalizer);
|
|
346
|
+
transaction.finalizeInput(0, this.customFinalizer.bind(this));
|
|
346
347
|
} else {
|
|
347
348
|
await this.signInput(transaction, transaction.data.inputs[i], i, this.signer);
|
|
348
349
|
|
|
349
350
|
try {
|
|
350
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
351
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
351
352
|
} catch (e) {
|
|
352
353
|
transaction.finalizeInput(i);
|
|
353
354
|
}
|
|
@@ -20,6 +20,7 @@ export interface ITransactionParameters extends ITweakedTransactionData {
|
|
|
20
20
|
optionalOutputs?: PsbtOutputExtended[];
|
|
21
21
|
|
|
22
22
|
chainId?: ChainId;
|
|
23
|
+
noSignatures?: boolean;
|
|
23
24
|
|
|
24
25
|
readonly feeRate: number;
|
|
25
26
|
readonly priorityFee: bigint;
|
|
@@ -52,6 +53,7 @@ export interface IInteractionParameters extends SharedInteractionParameters {
|
|
|
52
53
|
readonly calldata: Buffer;
|
|
53
54
|
|
|
54
55
|
readonly to: string;
|
|
56
|
+
readonly contract?: string;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
export interface IDeploymentParameters extends Omit<ITransactionParameters, 'to'> {
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
isP2TR,
|
|
11
11
|
isP2WPKH,
|
|
12
12
|
isP2WSHScript,
|
|
13
|
+
isUnknownSegwitVersion,
|
|
13
14
|
Network,
|
|
14
15
|
opcodes,
|
|
15
16
|
P2TRPayment,
|
|
@@ -43,6 +44,8 @@ export interface ITweakedTransactionData {
|
|
|
43
44
|
readonly network: Network;
|
|
44
45
|
readonly chainId?: ChainId;
|
|
45
46
|
readonly nonWitnessUtxo?: Buffer;
|
|
47
|
+
readonly noSignatures?: boolean;
|
|
48
|
+
readonly unlockScript?: Buffer[];
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
/**
|
|
@@ -126,6 +129,8 @@ export abstract class TweakedTransaction extends Logger {
|
|
|
126
129
|
|
|
127
130
|
protected regenerated: boolean = false;
|
|
128
131
|
protected ignoreSignatureErrors: boolean = false;
|
|
132
|
+
protected noSignatures: boolean = false;
|
|
133
|
+
protected unlockScript: Buffer[] | undefined;
|
|
129
134
|
|
|
130
135
|
protected constructor(data: ITweakedTransactionData) {
|
|
131
136
|
super();
|
|
@@ -133,7 +138,9 @@ export abstract class TweakedTransaction extends Logger {
|
|
|
133
138
|
this.signer = data.signer;
|
|
134
139
|
this.network = data.network;
|
|
135
140
|
|
|
141
|
+
this.noSignatures = data.noSignatures || false;
|
|
136
142
|
this.nonWitnessUtxo = data.nonWitnessUtxo;
|
|
143
|
+
this.unlockScript = data.unlockScript;
|
|
137
144
|
|
|
138
145
|
this.isBrowser = typeof window !== 'undefined';
|
|
139
146
|
}
|
|
@@ -476,27 +483,29 @@ export abstract class TweakedTransaction extends Logger {
|
|
|
476
483
|
const batchSize: number = 20;
|
|
477
484
|
const batches = this.splitArray(txs, batchSize);
|
|
478
485
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
486
|
+
if (!this.noSignatures) {
|
|
487
|
+
for (let i = 0; i < batches.length; i++) {
|
|
488
|
+
const batch = batches[i];
|
|
489
|
+
const promises: Promise<void>[] = [];
|
|
490
|
+
const offset = i * batchSize;
|
|
483
491
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
492
|
+
for (let j = 0; j < batch.length; j++) {
|
|
493
|
+
const index = offset + j;
|
|
494
|
+
const input = batch[j];
|
|
487
495
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
496
|
+
try {
|
|
497
|
+
promises.push(this.signInput(transaction, input, index, this.signer));
|
|
498
|
+
} catch (e) {
|
|
499
|
+
this.log(`Failed to sign input ${index}: ${(e as Error).stack}`);
|
|
500
|
+
}
|
|
492
501
|
}
|
|
493
|
-
}
|
|
494
502
|
|
|
495
|
-
|
|
503
|
+
await Promise.all(promises);
|
|
504
|
+
}
|
|
496
505
|
}
|
|
497
506
|
|
|
498
507
|
for (let i = 0; i < transaction.data.inputs.length; i++) {
|
|
499
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
508
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
500
509
|
}
|
|
501
510
|
|
|
502
511
|
this.finalized = true;
|
|
@@ -654,14 +663,14 @@ export abstract class TweakedTransaction extends Logger {
|
|
|
654
663
|
* Generate the PSBT input extended, supporting various script types
|
|
655
664
|
* @param {UTXO} utxo The UTXO
|
|
656
665
|
* @param {number} i The index of the input
|
|
657
|
-
* @param {UTXO}
|
|
666
|
+
* @param {UTXO} _extra Extra UTXO
|
|
658
667
|
* @protected
|
|
659
668
|
* @returns {PsbtInputExtended} The PSBT input extended
|
|
660
669
|
*/
|
|
661
670
|
protected generatePsbtInputExtended(
|
|
662
671
|
utxo: UTXO,
|
|
663
672
|
i: number,
|
|
664
|
-
|
|
673
|
+
_extra: boolean = false,
|
|
665
674
|
): PsbtInputExtended {
|
|
666
675
|
const script = Buffer.from(utxo.scriptPubKey.hex, 'hex');
|
|
667
676
|
|
|
@@ -689,7 +698,7 @@ export abstract class TweakedTransaction extends Logger {
|
|
|
689
698
|
}
|
|
690
699
|
|
|
691
700
|
// Handle P2WPKH (SegWit)
|
|
692
|
-
else if (isP2WPKH(script)) {
|
|
701
|
+
else if (isP2WPKH(script) || isUnknownSegwitVersion(script)) {
|
|
693
702
|
// No redeemScript required for pure P2WPKH
|
|
694
703
|
// witnessUtxo is enough, no nonWitnessUtxo needed.
|
|
695
704
|
}
|
|
@@ -849,7 +858,16 @@ export abstract class TweakedTransaction extends Logger {
|
|
|
849
858
|
};
|
|
850
859
|
}
|
|
851
860
|
|
|
852
|
-
return getFinalScripts(
|
|
861
|
+
return getFinalScripts(
|
|
862
|
+
inputIndex,
|
|
863
|
+
input,
|
|
864
|
+
scriptA,
|
|
865
|
+
isSegwit,
|
|
866
|
+
isP2SH,
|
|
867
|
+
isP2WSH,
|
|
868
|
+
true,
|
|
869
|
+
this.unlockScript,
|
|
870
|
+
);
|
|
853
871
|
};
|
|
854
872
|
|
|
855
873
|
protected async signInputsWalletBased(transaction: Psbt): Promise<void> {
|
|
@@ -860,7 +878,7 @@ export abstract class TweakedTransaction extends Logger {
|
|
|
860
878
|
|
|
861
879
|
// Then, we finalize every input.
|
|
862
880
|
for (let i = 0; i < transaction.data.inputs.length; i++) {
|
|
863
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
881
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
864
882
|
}
|
|
865
883
|
|
|
866
884
|
this.finalized = true;
|