@btc-vision/transaction 1.5.2 → 1.5.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/abi/ABICoder.d.ts +1 -0
- package/browser/buffer/BinaryWriter.d.ts +1 -1
- package/browser/index.js +1 -1
- package/browser/transaction/browser/types/Unisat.d.ts +1 -1
- package/browser/transaction/interfaces/ITransactionParameters.d.ts +1 -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/abi/ABICoder.d.ts +1 -0
- package/build/abi/ABICoder.js +4 -0
- package/build/buffer/BinaryWriter.d.ts +1 -1
- package/build/buffer/BinaryWriter.js +11 -9
- package/build/keypair/AddressVerificator.js +3 -1
- package/build/keypair/EcKeyPair.js +5 -5
- package/build/transaction/browser/types/Unisat.d.ts +1 -1
- package/build/transaction/builders/DeploymentTransaction.js +4 -4
- package/build/transaction/builders/SharedInteractionTransaction.js +4 -4
- package/build/transaction/interfaces/ITransactionParameters.d.ts +1 -0
- package/build/transaction/shared/TweakedTransaction.d.ts +5 -1
- package/build/transaction/shared/TweakedTransaction.js +24 -19
- package/package.json +10 -10
- package/src/_version.ts +1 -1
- package/src/abi/ABICoder.ts +4 -0
- package/src/buffer/BinaryWriter.ts +13 -11
- package/src/keypair/AddressVerificator.ts +5 -1
- package/src/keypair/EcKeyPair.ts +5 -5
- package/src/transaction/browser/types/Unisat.ts +1 -1
- package/src/transaction/builders/DeploymentTransaction.ts +4 -4
- package/src/transaction/builders/SharedInteractionTransaction.ts +4 -4
- package/src/transaction/interfaces/ITransactionParameters.ts +1 -0
- package/src/transaction/shared/TweakedTransaction.ts +37 -19
|
@@ -63,7 +63,7 @@ export interface Unisat {
|
|
|
63
63
|
switchNetwork(network: UnisatNetwork): Promise<void>;
|
|
64
64
|
getPublicKey(): Promise<string>;
|
|
65
65
|
getBalance(): Promise<Balance>;
|
|
66
|
-
signMessage(message: string, type?: MessageType): Promise<string>;
|
|
66
|
+
signMessage(message: string | Buffer, type?: MessageType): Promise<string>;
|
|
67
67
|
signData(hex: string, type?: SignatureType): Promise<string>;
|
|
68
68
|
pushTx(options: {
|
|
69
69
|
rawtx: string;
|
|
@@ -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;
|
|
@@ -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.5.
|
|
1
|
+
export declare const version = "1.5.3";
|
package/build/_version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.5.
|
|
1
|
+
export const version = '1.5.3';
|
package/build/abi/ABICoder.d.ts
CHANGED
package/build/abi/ABICoder.js
CHANGED
|
@@ -13,6 +13,7 @@ export var ABIDataTypes;
|
|
|
13
13
|
ABIDataTypes["BOOL"] = "BOOL";
|
|
14
14
|
ABIDataTypes["ADDRESS"] = "ADDRESS";
|
|
15
15
|
ABIDataTypes["STRING"] = "STRING";
|
|
16
|
+
ABIDataTypes["BYTES4"] = "BYTES4";
|
|
16
17
|
ABIDataTypes["BYTES32"] = "BYTES32";
|
|
17
18
|
ABIDataTypes["BYTES"] = "BYTES";
|
|
18
19
|
ABIDataTypes["ADDRESS_UINT256_TUPLE"] = "ADDRESS_UINT256_TUPLE";
|
|
@@ -42,6 +43,9 @@ export class ABICoder {
|
|
|
42
43
|
case ABIDataTypes.UINT32:
|
|
43
44
|
result.push(byteReader.readU32());
|
|
44
45
|
break;
|
|
46
|
+
case ABIDataTypes.BYTES4:
|
|
47
|
+
result.push(byteReader.readBytes(4));
|
|
48
|
+
break;
|
|
45
49
|
case ABIDataTypes.BYTES32:
|
|
46
50
|
result.push(byteReader.readBytes(32));
|
|
47
51
|
break;
|
|
@@ -17,8 +17,8 @@ export declare class BinaryWriter {
|
|
|
17
17
|
writeU128(bigIntValue: bigint, be?: boolean): void;
|
|
18
18
|
writeBytes(value: Uint8Array | Buffer): void;
|
|
19
19
|
writeString(value: string): void;
|
|
20
|
-
writeAddress(value: Address): void;
|
|
21
20
|
writeStringWithLength(value: string): void;
|
|
21
|
+
writeAddress(value: Address): void;
|
|
22
22
|
getBuffer(clear?: boolean): Uint8Array;
|
|
23
23
|
reset(): void;
|
|
24
24
|
toBytesReader(): BinaryReader;
|
|
@@ -109,20 +109,22 @@ export class BinaryWriter {
|
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
writeString(value) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
const encoder = new TextEncoder();
|
|
113
|
+
const bytes = encoder.encode(value);
|
|
114
|
+
this.allocSafe(bytes.length);
|
|
115
|
+
this.writeBytes(bytes);
|
|
116
|
+
}
|
|
117
|
+
writeStringWithLength(value) {
|
|
118
|
+
const encoder = new TextEncoder();
|
|
119
|
+
const bytes = encoder.encode(value);
|
|
120
|
+
this.allocSafe(U32_BYTE_LENGTH + bytes.length);
|
|
121
|
+
this.writeU32(bytes.length);
|
|
122
|
+
this.writeBytes(bytes);
|
|
116
123
|
}
|
|
117
124
|
writeAddress(value) {
|
|
118
125
|
this.verifyAddress(value);
|
|
119
126
|
this.writeBytes(value);
|
|
120
127
|
}
|
|
121
|
-
writeStringWithLength(value) {
|
|
122
|
-
this.allocSafe(U32_BYTE_LENGTH + value.length);
|
|
123
|
-
this.writeU32(value.length);
|
|
124
|
-
this.writeString(value);
|
|
125
|
-
}
|
|
126
128
|
getBuffer(clear = true) {
|
|
127
129
|
const buf = new Uint8Array(this.buffer.byteLength);
|
|
128
130
|
for (let i = 0; i < this.buffer.byteLength; i++) {
|
|
@@ -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) {
|
|
@@ -12,7 +12,7 @@ if (!BIP32factory) {
|
|
|
12
12
|
throw new Error('Failed to load BIP32 library');
|
|
13
13
|
}
|
|
14
14
|
secp256k1.utils.precompute(8);
|
|
15
|
-
const {
|
|
15
|
+
const { Point, CURVE } = secp256k1;
|
|
16
16
|
const TAP_TAG = utf8ToBytes('TapTweak');
|
|
17
17
|
const TAP_TAG_HASH = sha256(TAP_TAG);
|
|
18
18
|
function tapTweakHash(x) {
|
|
@@ -113,19 +113,19 @@ export class EcKeyPair {
|
|
|
113
113
|
pub = pub.slice(2);
|
|
114
114
|
const P = Point.fromHex(pub);
|
|
115
115
|
const Peven = (P.y & 1n) === 0n ? P : P.negate();
|
|
116
|
-
const xBytes = Peven.
|
|
116
|
+
const xBytes = Peven.toBytes(true).subarray(1);
|
|
117
117
|
const tBytes = tapTweakHash(xBytes);
|
|
118
118
|
const t = mod(bytesToNumberBE(tBytes), CURVE.n);
|
|
119
119
|
const Q = Peven.add(Point.BASE.multiply(t));
|
|
120
|
-
return Buffer.from(Q.
|
|
120
|
+
return Buffer.from(Q.toBytes(true));
|
|
121
121
|
}
|
|
122
122
|
static tweakBatchSharedT(pubkeys, tweakScalar) {
|
|
123
123
|
const T = Point.BASE.multiply(tweakScalar);
|
|
124
124
|
return pubkeys.map((bytes) => {
|
|
125
125
|
const P = Point.fromHex(bytes);
|
|
126
|
-
const P_even = P.
|
|
126
|
+
const P_even = P.y % 2n === 0n ? P : P.negate();
|
|
127
127
|
const Q = P_even.add(T);
|
|
128
|
-
return Q.
|
|
128
|
+
return Q.toBytes(true);
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
131
|
static generateWallet(network = networks.bitcoin) {
|
|
@@ -63,7 +63,7 @@ export interface Unisat {
|
|
|
63
63
|
switchNetwork(network: UnisatNetwork): Promise<void>;
|
|
64
64
|
getPublicKey(): Promise<string>;
|
|
65
65
|
getBalance(): Promise<Balance>;
|
|
66
|
-
signMessage(message: string, type?: MessageType): Promise<string>;
|
|
66
|
+
signMessage(message: string | Buffer, type?: MessageType): Promise<string>;
|
|
67
67
|
signData(hex: string, type?: SignatureType): Promise<string>;
|
|
68
68
|
pushTx(options: {
|
|
69
69
|
rawtx: string;
|
|
@@ -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);
|
|
@@ -147,11 +147,11 @@ export class SharedInteractionTransaction extends TransactionBuilder {
|
|
|
147
147
|
await signer.multiSignPsbt([transaction]);
|
|
148
148
|
for (let i = 0; i < transaction.data.inputs.length; i++) {
|
|
149
149
|
if (i === 0) {
|
|
150
|
-
transaction.finalizeInput(i, this.customFinalizer);
|
|
150
|
+
transaction.finalizeInput(i, this.customFinalizer.bind(this));
|
|
151
151
|
}
|
|
152
152
|
else {
|
|
153
153
|
try {
|
|
154
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
154
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
155
155
|
}
|
|
156
156
|
catch (e) {
|
|
157
157
|
transaction.finalizeInput(i);
|
|
@@ -164,12 +164,12 @@ export class SharedInteractionTransaction extends TransactionBuilder {
|
|
|
164
164
|
if (i === 0) {
|
|
165
165
|
await this.signInput(transaction, transaction.data.inputs[i], i, this.scriptSigner);
|
|
166
166
|
await this.signInput(transaction, transaction.data.inputs[i], i, this.getSignerKey());
|
|
167
|
-
transaction.finalizeInput(0, this.customFinalizer);
|
|
167
|
+
transaction.finalizeInput(0, this.customFinalizer.bind(this));
|
|
168
168
|
}
|
|
169
169
|
else {
|
|
170
170
|
await this.signInput(transaction, transaction.data.inputs[i], i, this.signer);
|
|
171
171
|
try {
|
|
172
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
172
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
173
173
|
}
|
|
174
174
|
catch (e) {
|
|
175
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;
|
|
@@ -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.4",
|
|
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.
|
|
93
|
-
"@btc-vision/bitcoin-rpc": "^1.0.
|
|
91
|
+
"@bitcoinerlab/secp256k1": "^1.2.0",
|
|
92
|
+
"@btc-vision/bitcoin": "^6.4.6",
|
|
93
|
+
"@btc-vision/bitcoin-rpc": "^1.0.2",
|
|
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.5.
|
|
1
|
+
export const version = '1.5.3';
|
package/src/abi/ABICoder.ts
CHANGED
|
@@ -14,6 +14,7 @@ export enum ABIDataTypes {
|
|
|
14
14
|
BOOL = 'BOOL',
|
|
15
15
|
ADDRESS = 'ADDRESS',
|
|
16
16
|
STRING = 'STRING',
|
|
17
|
+
BYTES4 = 'BYTES4',
|
|
17
18
|
BYTES32 = 'BYTES32',
|
|
18
19
|
BYTES = 'BYTES',
|
|
19
20
|
ADDRESS_UINT256_TUPLE = 'ADDRESS_UINT256_TUPLE',
|
|
@@ -45,6 +46,9 @@ export class ABICoder {
|
|
|
45
46
|
case ABIDataTypes.UINT32:
|
|
46
47
|
result.push(byteReader.readU32());
|
|
47
48
|
break;
|
|
49
|
+
case ABIDataTypes.BYTES4:
|
|
50
|
+
result.push(byteReader.readBytes(4));
|
|
51
|
+
break;
|
|
48
52
|
case ABIDataTypes.BYTES32:
|
|
49
53
|
result.push(byteReader.readBytes(32));
|
|
50
54
|
break;
|
|
@@ -146,24 +146,26 @@ export class BinaryWriter {
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
public writeString(value: string): void {
|
|
149
|
-
|
|
149
|
+
const encoder = new TextEncoder();
|
|
150
|
+
const bytes = encoder.encode(value);
|
|
150
151
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
152
|
+
this.allocSafe(bytes.length);
|
|
153
|
+
this.writeBytes(bytes);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
public
|
|
157
|
-
|
|
156
|
+
public writeStringWithLength(value: string): void {
|
|
157
|
+
const encoder = new TextEncoder();
|
|
158
|
+
const bytes = encoder.encode(value);
|
|
158
159
|
|
|
159
|
-
this.
|
|
160
|
+
this.allocSafe(U32_BYTE_LENGTH + bytes.length);
|
|
161
|
+
this.writeU32(bytes.length);
|
|
162
|
+
this.writeBytes(bytes);
|
|
160
163
|
}
|
|
161
164
|
|
|
162
|
-
public
|
|
163
|
-
this.
|
|
165
|
+
public writeAddress(value: Address): void {
|
|
166
|
+
this.verifyAddress(value);
|
|
164
167
|
|
|
165
|
-
this.
|
|
166
|
-
this.writeString(value);
|
|
168
|
+
this.writeBytes(value);
|
|
167
169
|
}
|
|
168
170
|
|
|
169
171
|
public getBuffer(clear: boolean = true): Uint8Array {
|
|
@@ -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
|
|
package/src/keypair/EcKeyPair.ts
CHANGED
|
@@ -28,7 +28,7 @@ if (!BIP32factory) {
|
|
|
28
28
|
|
|
29
29
|
secp256k1.utils.precompute(8);
|
|
30
30
|
|
|
31
|
-
const {
|
|
31
|
+
const { Point, CURVE } = secp256k1;
|
|
32
32
|
|
|
33
33
|
const TAP_TAG = utf8ToBytes('TapTweak');
|
|
34
34
|
const TAP_TAG_HASH = sha256(TAP_TAG);
|
|
@@ -272,12 +272,12 @@ export class EcKeyPair {
|
|
|
272
272
|
const P = Point.fromHex(pub);
|
|
273
273
|
const Peven = (P.y & 1n) === 0n ? P : P.negate();
|
|
274
274
|
|
|
275
|
-
const xBytes = Peven.
|
|
275
|
+
const xBytes = Peven.toBytes(true).subarray(1);
|
|
276
276
|
const tBytes = tapTweakHash(xBytes);
|
|
277
277
|
const t = mod(bytesToNumberBE(tBytes), CURVE.n);
|
|
278
278
|
|
|
279
279
|
const Q = Peven.add(Point.BASE.multiply(t));
|
|
280
|
-
return Buffer.from(Q.
|
|
280
|
+
return Buffer.from(Q.toBytes(true));
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
/**
|
|
@@ -294,9 +294,9 @@ export class EcKeyPair {
|
|
|
294
294
|
|
|
295
295
|
return pubkeys.map((bytes) => {
|
|
296
296
|
const P = Point.fromHex(bytes);
|
|
297
|
-
const P_even = P.
|
|
297
|
+
const P_even = P.y % 2n === 0n ? P : P.negate();
|
|
298
298
|
const Q = P_even.add(T);
|
|
299
|
-
return Q.
|
|
299
|
+
return Q.toBytes(true);
|
|
300
300
|
});
|
|
301
301
|
}
|
|
302
302
|
|
|
@@ -85,7 +85,7 @@ export interface Unisat {
|
|
|
85
85
|
|
|
86
86
|
getBalance(): Promise<Balance>;
|
|
87
87
|
|
|
88
|
-
signMessage(message: string, type?: MessageType): Promise<string>;
|
|
88
|
+
signMessage(message: string | Buffer, type?: MessageType): Promise<string>;
|
|
89
89
|
|
|
90
90
|
signData(hex: string, type?: SignatureType): Promise<string>;
|
|
91
91
|
|
|
@@ -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
|
}
|
|
@@ -320,10 +320,10 @@ export abstract class SharedInteractionTransaction<
|
|
|
320
320
|
// Then, we finalize every input.
|
|
321
321
|
for (let i = 0; i < transaction.data.inputs.length; i++) {
|
|
322
322
|
if (i === 0) {
|
|
323
|
-
transaction.finalizeInput(i, this.customFinalizer);
|
|
323
|
+
transaction.finalizeInput(i, this.customFinalizer.bind(this));
|
|
324
324
|
} else {
|
|
325
325
|
try {
|
|
326
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
326
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
327
327
|
} catch (e) {
|
|
328
328
|
transaction.finalizeInput(i);
|
|
329
329
|
}
|
|
@@ -343,12 +343,12 @@ export abstract class SharedInteractionTransaction<
|
|
|
343
343
|
this.getSignerKey(),
|
|
344
344
|
);
|
|
345
345
|
|
|
346
|
-
transaction.finalizeInput(0, this.customFinalizer);
|
|
346
|
+
transaction.finalizeInput(0, this.customFinalizer.bind(this));
|
|
347
347
|
} else {
|
|
348
348
|
await this.signInput(transaction, transaction.data.inputs[i], i, this.signer);
|
|
349
349
|
|
|
350
350
|
try {
|
|
351
|
-
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
351
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH.bind(this));
|
|
352
352
|
} catch (e) {
|
|
353
353
|
transaction.finalizeInput(i);
|
|
354
354
|
}
|