@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.
Files changed (32) hide show
  1. package/browser/_version.d.ts +1 -1
  2. package/browser/abi/ABICoder.d.ts +1 -0
  3. package/browser/buffer/BinaryWriter.d.ts +1 -1
  4. package/browser/index.js +1 -1
  5. package/browser/transaction/browser/types/Unisat.d.ts +1 -1
  6. package/browser/transaction/interfaces/ITransactionParameters.d.ts +1 -0
  7. package/browser/transaction/shared/TweakedTransaction.d.ts +5 -1
  8. package/build/_version.d.ts +1 -1
  9. package/build/_version.js +1 -1
  10. package/build/abi/ABICoder.d.ts +1 -0
  11. package/build/abi/ABICoder.js +4 -0
  12. package/build/buffer/BinaryWriter.d.ts +1 -1
  13. package/build/buffer/BinaryWriter.js +11 -9
  14. package/build/keypair/AddressVerificator.js +3 -1
  15. package/build/keypair/EcKeyPair.js +5 -5
  16. package/build/transaction/browser/types/Unisat.d.ts +1 -1
  17. package/build/transaction/builders/DeploymentTransaction.js +4 -4
  18. package/build/transaction/builders/SharedInteractionTransaction.js +4 -4
  19. package/build/transaction/interfaces/ITransactionParameters.d.ts +1 -0
  20. package/build/transaction/shared/TweakedTransaction.d.ts +5 -1
  21. package/build/transaction/shared/TweakedTransaction.js +24 -19
  22. package/package.json +10 -10
  23. package/src/_version.ts +1 -1
  24. package/src/abi/ABICoder.ts +4 -0
  25. package/src/buffer/BinaryWriter.ts +13 -11
  26. package/src/keypair/AddressVerificator.ts +5 -1
  27. package/src/keypair/EcKeyPair.ts +5 -5
  28. package/src/transaction/browser/types/Unisat.ts +1 -1
  29. package/src/transaction/builders/DeploymentTransaction.ts +4 -4
  30. package/src/transaction/builders/SharedInteractionTransaction.ts +4 -4
  31. package/src/transaction/interfaces/ITransactionParameters.ts +1 -0
  32. 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, extra?: boolean): PsbtInputExtended;
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 +1 @@
1
- export declare const version = "1.5.2";
1
+ export declare const version = "1.5.3";
package/build/_version.js CHANGED
@@ -1 +1 @@
1
- export const version = '1.5.2';
1
+ export const version = '1.5.3';
@@ -9,6 +9,7 @@ export declare enum ABIDataTypes {
9
9
  BOOL = "BOOL",
10
10
  ADDRESS = "ADDRESS",
11
11
  STRING = "STRING",
12
+ BYTES4 = "BYTES4",
12
13
  BYTES32 = "BYTES32",
13
14
  BYTES = "BYTES",
14
15
  ADDRESS_UINT256_TUPLE = "ADDRESS_UINT256_TUPLE",
@@ -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
- this.allocSafe(value.length);
113
- for (let i = 0; i < value.length; i++) {
114
- this.writeU8(value.charCodeAt(i));
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 && decodedBech32.version === 16) {
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 { ProjectivePoint: Point, CURVE } = secp256k1;
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.toRawBytes(true).subarray(1);
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.toRawBytes(true));
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.hasEvenY() ? P : P.negate();
126
+ const P_even = P.y % 2n === 0n ? P : P.negate();
127
127
  const Q = P_even.add(T);
128
- return Q.toRawBytes(true);
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, extra?: boolean): PsbtInputExtended;
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
- for (let i = 0; i < batches.length; i++) {
220
- const batch = batches[i];
221
- const promises = [];
222
- const offset = i * batchSize;
223
- for (let j = 0; j < batch.length; j++) {
224
- const index = offset + j;
225
- const input = batch[j];
226
- try {
227
- promises.push(this.signInput(transaction, input, index, this.signer));
228
- }
229
- catch (e) {
230
- this.log(`Failed to sign input ${index}: ${e.stack}`);
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, extra = false) {
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.2",
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.3",
67
+ "@babel/core": "^7.27.4",
68
68
  "@babel/plugin-proposal-class-properties": "^7.18.6",
69
- "@babel/plugin-transform-runtime": "^7.27.3",
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.26",
74
+ "@types/node": "^22.15.29",
75
75
  "@types/sha.js": "^2.4.4",
76
- "eslint": "^9.27.0",
77
- "gulp": "^5.0.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.1.1",
92
- "@btc-vision/bitcoin": "^6.4.5",
93
- "@btc-vision/bitcoin-rpc": "^1.0.1",
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.27.0",
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.2';
1
+ export const version = '1.5.3';
@@ -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
- this.allocSafe(value.length);
149
+ const encoder = new TextEncoder();
150
+ const bytes = encoder.encode(value);
150
151
 
151
- for (let i: i32 = 0; i < value.length; i++) {
152
- this.writeU8(value.charCodeAt(i));
153
- }
152
+ this.allocSafe(bytes.length);
153
+ this.writeBytes(bytes);
154
154
  }
155
155
 
156
- public writeAddress(value: Address): void {
157
- this.verifyAddress(value);
156
+ public writeStringWithLength(value: string): void {
157
+ const encoder = new TextEncoder();
158
+ const bytes = encoder.encode(value);
158
159
 
159
- this.writeBytes(value);
160
+ this.allocSafe(U32_BYTE_LENGTH + bytes.length);
161
+ this.writeU32(bytes.length);
162
+ this.writeBytes(bytes);
160
163
  }
161
164
 
162
- public writeStringWithLength(value: string): void {
163
- this.allocSafe(U32_BYTE_LENGTH + value.length);
165
+ public writeAddress(value: Address): void {
166
+ this.verifyAddress(value);
164
167
 
165
- this.writeU32(value.length);
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 (decodedBech32.prefix === network.bech32Opnet && decodedBech32.version === 16) {
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
 
@@ -28,7 +28,7 @@ if (!BIP32factory) {
28
28
 
29
29
  secp256k1.utils.precompute(8);
30
30
 
31
- const { ProjectivePoint: Point, CURVE } = secp256k1;
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.toRawBytes(true).subarray(1);
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.toRawBytes(true));
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.hasEvenY() ? P : P.negate();
297
+ const P_even = P.y % 2n === 0n ? P : P.negate();
298
298
  const Q = P_even.add(T);
299
- return Q.toRawBytes(true);
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
  }
@@ -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;