@btc-vision/transaction 1.1.17 → 1.2.1

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 (82) hide show
  1. package/browser/_version.d.ts +1 -1
  2. package/browser/crypto/crypto-browser.d.ts +2 -2
  3. package/browser/index.js +1 -1
  4. package/browser/index.js.LICENSE.txt +2 -0
  5. package/browser/keypair/Address.d.ts +8 -0
  6. package/browser/keypair/Secp256k1PointDeriver.d.ts +16 -0
  7. package/browser/opnet.d.ts +2 -0
  8. package/browser/signer/SignerUtils.d.ts +0 -1
  9. package/browser/transaction/ContractAddress.d.ts +6 -0
  10. package/browser/transaction/builders/CustomScriptTransaction.d.ts +1 -1
  11. package/browser/transaction/builders/InteractionTransaction.d.ts +1 -1
  12. package/browser/transaction/builders/MultiSignTransaction.d.ts +3 -4
  13. package/browser/transaction/builders/SharedInteractionTransaction.d.ts +2 -3
  14. package/browser/verification/TapscriptVerificator.d.ts +1 -2
  15. package/build/_version.d.ts +1 -1
  16. package/build/_version.js +1 -1
  17. package/build/buffer/BinaryReader.js +2 -2
  18. package/build/buffer/BinaryWriter.js +1 -1
  19. package/build/generators/AddressGenerator.js +1 -2
  20. package/build/generators/Generator.js +1 -2
  21. package/build/generators/builders/MultiSignGenerator.js +1 -2
  22. package/build/keypair/Address.d.ts +8 -0
  23. package/build/keypair/Address.js +67 -7
  24. package/build/keypair/AddressVerificator.js +5 -2
  25. package/build/keypair/EcKeyPair.js +3 -4
  26. package/build/keypair/MessageSigner.js +1 -2
  27. package/build/keypair/Secp256k1PointDeriver.d.ts +16 -0
  28. package/build/keypair/Secp256k1PointDeriver.js +80 -0
  29. package/build/keypair/Wallet.js +1 -2
  30. package/build/opnet.d.ts +2 -0
  31. package/build/opnet.js +2 -0
  32. package/build/signer/SignerUtils.d.ts +0 -1
  33. package/build/signer/SignerUtils.js +1 -17
  34. package/build/signer/TweakedSigner.js +1 -3
  35. package/build/transaction/ContractAddress.d.ts +6 -0
  36. package/build/transaction/ContractAddress.js +12 -0
  37. package/build/transaction/browser/extensions/UnisatSigner.js +1 -2
  38. package/build/transaction/browser/extensions/XverseSigner.js +1 -2
  39. package/build/transaction/builders/CustomScriptTransaction.d.ts +1 -1
  40. package/build/transaction/builders/CustomScriptTransaction.js +1 -2
  41. package/build/transaction/builders/DeploymentTransaction.js +2 -2
  42. package/build/transaction/builders/FundingTransaction.js +2 -2
  43. package/build/transaction/builders/InteractionTransaction.d.ts +1 -1
  44. package/build/transaction/builders/MultiSignTransaction.d.ts +3 -4
  45. package/build/transaction/builders/MultiSignTransaction.js +1 -2
  46. package/build/transaction/builders/SharedInteractionTransaction.d.ts +2 -3
  47. package/build/transaction/builders/SharedInteractionTransaction.js +1 -2
  48. package/build/transaction/builders/TransactionBuilder.js +11 -2
  49. package/build/transaction/shared/TweakedTransaction.js +1 -4
  50. package/build/utils/BufferHelper.js +1 -1
  51. package/build/verification/TapscriptVerificator.d.ts +1 -2
  52. package/build/verification/TapscriptVerificator.js +1 -2
  53. package/package.json +9 -9
  54. package/src/_version.ts +1 -1
  55. package/src/buffer/BinaryReader.ts +2 -2
  56. package/src/buffer/BinaryWriter.ts +1 -1
  57. package/src/generators/AddressGenerator.ts +1 -2
  58. package/src/generators/Generator.ts +1 -2
  59. package/src/generators/builders/MultiSignGenerator.ts +1 -2
  60. package/src/keypair/Address.ts +91 -10
  61. package/src/keypair/AddressVerificator.ts +6 -2
  62. package/src/keypair/EcKeyPair.ts +14 -5
  63. package/src/keypair/MessageSigner.ts +1 -2
  64. package/src/keypair/Secp256k1PointDeriver.ts +170 -0
  65. package/src/keypair/Wallet.ts +1 -2
  66. package/src/opnet.ts +2 -0
  67. package/src/signer/SignerUtils.ts +7 -19
  68. package/src/signer/TweakedSigner.ts +1 -3
  69. package/src/transaction/ContractAddress.ts +13 -0
  70. package/src/transaction/TransactionFactory.ts +4 -5
  71. package/src/transaction/browser/extensions/UnisatSigner.ts +1 -1
  72. package/src/transaction/browser/extensions/XverseSigner.ts +1 -2
  73. package/src/transaction/builders/CustomScriptTransaction.ts +10 -3
  74. package/src/transaction/builders/DeploymentTransaction.ts +13 -3
  75. package/src/transaction/builders/FundingTransaction.ts +2 -2
  76. package/src/transaction/builders/InteractionTransaction.ts +1 -1
  77. package/src/transaction/builders/MultiSignTransaction.ts +2 -2
  78. package/src/transaction/builders/SharedInteractionTransaction.ts +1 -3
  79. package/src/transaction/builders/TransactionBuilder.ts +11 -1
  80. package/src/transaction/shared/TweakedTransaction.ts +9 -93
  81. package/src/utils/BufferHelper.ts +1 -1
  82. package/src/verification/TapscriptVerificator.ts +9 -3
@@ -12,6 +12,8 @@
12
12
  * @license MIT
13
13
  */
14
14
 
15
+ /*! For license information please see index.js.LICENSE.txt */
16
+
15
17
  /*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
16
18
 
17
19
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
@@ -7,8 +7,13 @@ export declare class Address extends Uint8Array {
7
7
  static dead(): Address;
8
8
  static fromString(pubKey: string): Address;
9
9
  static wrap(bytes: ArrayLike<number>): Address;
10
+ static uncompressedToCompressed(publicKey: ArrayLike<number>): Buffer;
10
11
  toHex(): string;
11
12
  toBuffer(): Buffer;
13
+ toUncompressedHex(): string;
14
+ toUncompressedBuffer(): Buffer;
15
+ toHybridPublicKeyHex(): string;
16
+ toHybridPublicKeyBuffer(): Buffer;
12
17
  originalPublicKeyBuffer(): Buffer;
13
18
  equals(a: Address): boolean;
14
19
  lessThan(a: Address): boolean;
@@ -22,4 +27,7 @@ export declare class Address extends Uint8Array {
22
27
  toString(): string;
23
28
  toJSON(): string;
24
29
  p2tr(network: Network): string;
30
+ toTweakedHybridPublicKeyHex(): string;
31
+ toTweakedHybridPublicKeyBuffer(): Buffer;
32
+ private autoFormat;
25
33
  }
@@ -0,0 +1,16 @@
1
+ export declare class Secp256k1PointDeriver {
2
+ private maxTries;
3
+ constructor(maxTries?: number);
4
+ findOrDeriveValidPoint(xBytes: Uint8Array, failOnInvalidX?: boolean, maxTries?: number): {
5
+ x: bigint;
6
+ y1: bigint;
7
+ y2: bigint;
8
+ };
9
+ getCanonicalY(y: bigint, y2: bigint): bigint;
10
+ getHybridPublicKey(x: bigint, y: bigint): Uint8Array;
11
+ private isValidX;
12
+ private modPow;
13
+ private sqrtModP;
14
+ private bytesToBigInt;
15
+ private bigIntTo32Bytes;
16
+ }
@@ -58,3 +58,5 @@ export * from './transaction/browser/types/Unisat.js';
58
58
  export * from './transaction/browser/types/Xverse.js';
59
59
  export * from './metadata/tokens.js';
60
60
  export * from './transaction/browser/Web3Provider.js';
61
+ export * from './transaction/ContractAddress.js';
62
+ export * from './keypair/Secp256k1PointDeriver.js';
@@ -2,5 +2,4 @@ import { PsbtInput } from '@btc-vision/bitcoin';
2
2
  export declare function isTaprootInput(input: PsbtInput): boolean;
3
3
  export declare function getInputRelevantScript(input: PsbtInput): Buffer | null;
4
4
  export declare function canSignNonTaprootInput(input: PsbtInput, publicKey: Buffer): boolean;
5
- export declare function pubkeyPositionInScript(pubkey: Buffer, script: Buffer): number;
6
5
  export declare function pubkeyInScript(pubkey: Buffer, script: Buffer): boolean;
@@ -0,0 +1,6 @@
1
+ declare class ContractAddressBase {
2
+ private readonly deriver;
3
+ generateHybridKeyFromHash(input: Buffer): Buffer;
4
+ }
5
+ export declare const ContractAddress: ContractAddressBase;
6
+ export {};
@@ -1,7 +1,7 @@
1
+ import { Payment, Psbt, Stack } from '@btc-vision/bitcoin';
1
2
  import { TransactionType } from '../enums/TransactionType.js';
2
3
  import { TapLeafScript } from '../interfaces/Tap.js';
3
4
  import { SharedInteractionParameters } from '../interfaces/ITransactionParameters.js';
4
- import { Payment, Psbt, Stack } from '@btc-vision/bitcoin';
5
5
  import { TransactionBuilder } from './TransactionBuilder.js';
6
6
  export interface ICustomTransactionParameters extends SharedInteractionParameters {
7
7
  readonly script: (Buffer | Stack)[];
@@ -1,4 +1,4 @@
1
- import { Taptree } from '@btc-vision/bitcoin/src/types.js';
1
+ import { Taptree } from '@btc-vision/bitcoin';
2
2
  import { TransactionType } from '../enums/TransactionType.js';
3
3
  import { TapLeafScript } from '../interfaces/Tap.js';
4
4
  import { IInteractionParameters } from '../interfaces/ITransactionParameters.js';
@@ -1,5 +1,4 @@
1
- import { Payment, Psbt, PsbtInput, Signer, TapScriptSig } from '@btc-vision/bitcoin';
2
- import { Taptree } from '@btc-vision/bitcoin/src/types.js';
1
+ import { Payment, Psbt, PsbtInput, Signer, TapScriptSig, Taptree } from '@btc-vision/bitcoin';
3
2
  import { TransactionBuilder } from './TransactionBuilder.js';
4
3
  import { TransactionType } from '../enums/TransactionType.js';
5
4
  import { ITransactionParameters } from '../interfaces/ITransactionParameters.js';
@@ -20,7 +19,7 @@ export interface MultiSignFromBase64Params extends Omit<MultiSignParameters, 'ps
20
19
  export declare class MultiSignTransaction extends TransactionBuilder<TransactionType.MULTI_SIG> {
21
20
  static readonly LOCK_LEAF_SCRIPT: Buffer;
22
21
  static readonly signHashTypesArray: number[];
23
- static readonly numsPoint: Buffer;
22
+ static readonly numsPoint: Buffer<ArrayBuffer>;
24
23
  type: TransactionType.MULTI_SIG;
25
24
  protected targetScriptRedeem: Payment | null;
26
25
  protected leftOverFundsScriptRedeem: Payment | null;
@@ -41,7 +40,7 @@ export declare class MultiSignTransaction extends TransactionBuilder<Transaction
41
40
  signed: boolean;
42
41
  };
43
42
  static partialFinalizer: (inputIndex: number, input: PsbtInput, partialSignatures: Buffer[], orderedPubKeys: Buffer[], isFinal: boolean) => {
44
- finalScriptWitness: Buffer;
43
+ finalScriptWitness: Buffer<ArrayBufferLike>;
45
44
  };
46
45
  static dedupeSignatures(original: TapScriptSig[], partial: TapScriptSig[]): TapScriptSig[];
47
46
  static attemptFinalizeInputs(psbt: Psbt, startIndex: number, orderedPubKeys: Buffer[][], isFinal: boolean): boolean;
@@ -1,5 +1,4 @@
1
- import { Payment, Psbt, PsbtInput, Signer } from '@btc-vision/bitcoin';
2
- import { Taptree } from '@btc-vision/bitcoin/src/types.js';
1
+ import { Payment, Psbt, PsbtInput, Signer, Taptree } from '@btc-vision/bitcoin';
3
2
  import { ECPairInterface } from 'ecpair';
4
3
  import { TransactionBuilder } from './TransactionBuilder.js';
5
4
  import { TransactionType } from '../enums/TransactionType.js';
@@ -30,7 +29,7 @@ export declare abstract class SharedInteractionTransaction<T extends Transaction
30
29
  protected getScriptSolution(input: PsbtInput): Buffer[];
31
30
  protected getScriptTree(): Taptree;
32
31
  protected customFinalizer: (_inputIndex: number, input: PsbtInput) => {
33
- finalScriptWitness: Buffer;
32
+ finalScriptWitness: Buffer<ArrayBufferLike>;
34
33
  };
35
34
  protected signInputsWalletBased(transaction: Psbt): Promise<void>;
36
35
  private signInputsNonWalletBased;
@@ -1,5 +1,4 @@
1
- import { Network } from '@btc-vision/bitcoin';
2
- import { Taptree } from '@btc-vision/bitcoin/src/types.js';
1
+ import { Network, Taptree } from '@btc-vision/bitcoin';
3
2
  export interface ContractAddressVerificationParams {
4
3
  readonly deployerPubKey: Buffer;
5
4
  readonly contractSaltPubKey: Buffer;
@@ -1 +1 @@
1
- export declare const version = "1.1.17";
1
+ export declare const version = "1.2.1";
package/build/_version.js CHANGED
@@ -1 +1 @@
1
- export const version = '1.1.17';
1
+ export const version = '1.2.1';
@@ -4,7 +4,7 @@ import { ADDRESS_BYTE_LENGTH, U128_BYTE_LENGTH, U16_BYTE_LENGTH, U256_BYTE_LENGT
4
4
  export class BinaryReader {
5
5
  constructor(bytes) {
6
6
  this.currentOffset = 0;
7
- this.buffer = new DataView(bytes.buffer);
7
+ this.buffer = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
8
8
  }
9
9
  static stringCompare(a, b) {
10
10
  return a.localeCompare(b);
@@ -24,7 +24,7 @@ export class BinaryReader {
24
24
  return 0;
25
25
  }
26
26
  setBuffer(bytes) {
27
- this.buffer = new DataView(bytes.buffer);
27
+ this.buffer = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
28
28
  this.currentOffset = 0;
29
29
  }
30
30
  readAddressArray() {
@@ -269,7 +269,7 @@ export class BinaryWriter {
269
269
  for (let i = 0; i < this.buffer.byteLength; i++) {
270
270
  buf[i] = this.buffer.getUint8(i);
271
271
  }
272
- this.buffer = new DataView(buf.buffer);
272
+ this.buffer = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
273
273
  }
274
274
  getDefaultBuffer(length = 0) {
275
275
  return new DataView(new ArrayBuffer(length));
@@ -1,7 +1,6 @@
1
1
  import { bech32, bech32m } from 'bech32';
2
- import { initEccLib } from '@btc-vision/bitcoin';
2
+ import { initEccLib, ripemd160 } from '@btc-vision/bitcoin';
3
3
  import * as ecc from '@bitcoinerlab/secp256k1';
4
- import { ripemd160 } from '@btc-vision/bitcoin/src/crypto.js';
5
4
  initEccLib(ecc);
6
5
  export class AddressGenerator {
7
6
  static generatePKSH(sha256Hash, network) {
@@ -1,5 +1,4 @@
1
- import { networks } from '@btc-vision/bitcoin';
2
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
1
+ import { networks, toXOnly } from '@btc-vision/bitcoin';
3
2
  export class Generator {
4
3
  constructor(senderPubKey, contractSaltPubKey, network = networks.bitcoin) {
5
4
  this.network = networks.bitcoin;
@@ -1,5 +1,4 @@
1
- import { opcodes, script } from '@btc-vision/bitcoin';
2
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
1
+ import { opcodes, script, toXOnly } from '@btc-vision/bitcoin';
3
2
  export class MultiSignGenerator {
4
3
  static compile(vaultPublicKeys, minimumSignatures = 0, internal) {
5
4
  if (minimumSignatures < 2) {
@@ -7,8 +7,13 @@ export declare class Address extends Uint8Array {
7
7
  static dead(): Address;
8
8
  static fromString(pubKey: string): Address;
9
9
  static wrap(bytes: ArrayLike<number>): Address;
10
+ static uncompressedToCompressed(publicKey: ArrayLike<number>): Buffer;
10
11
  toHex(): string;
11
12
  toBuffer(): Buffer;
13
+ toUncompressedHex(): string;
14
+ toUncompressedBuffer(): Buffer;
15
+ toHybridPublicKeyHex(): string;
16
+ toHybridPublicKeyBuffer(): Buffer;
12
17
  originalPublicKeyBuffer(): Buffer;
13
18
  equals(a: Address): boolean;
14
19
  lessThan(a: Address): boolean;
@@ -22,4 +27,7 @@ export declare class Address extends Uint8Array {
22
27
  toString(): string;
23
28
  toJSON(): string;
24
29
  p2tr(network: Network): string;
30
+ toTweakedHybridPublicKeyHex(): string;
31
+ toTweakedHybridPublicKeyBuffer(): Buffer;
32
+ private autoFormat;
25
33
  }
@@ -9,11 +9,12 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
10
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
11
  };
12
- var _Address_p2tr, _Address_network, _Address_originalPublicKey, _Address_keyPair;
13
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
12
+ var _Address_p2tr, _Address_network, _Address_originalPublicKey, _Address_keyPair, _Address_uncompressed, _Address_tweakedUncompressed;
13
+ import { decompressPublicKey, toXOnly } from '@btc-vision/bitcoin';
14
14
  import { ADDRESS_BYTE_LENGTH } from '../utils/lengths.js';
15
15
  import { AddressVerificator } from './AddressVerificator.js';
16
16
  import { EcKeyPair } from './EcKeyPair.js';
17
+ import { ContractAddress } from '../transaction/ContractAddress.js';
17
18
  const hexPattern = /^[0-9a-fA-F]+$/;
18
19
  const isHexadecimal = (input) => {
19
20
  return hexPattern.test(input);
@@ -25,6 +26,8 @@ export class Address extends Uint8Array {
25
26
  _Address_network.set(this, void 0);
26
27
  _Address_originalPublicKey.set(this, void 0);
27
28
  _Address_keyPair.set(this, void 0);
29
+ _Address_uncompressed.set(this, void 0);
30
+ _Address_tweakedUncompressed.set(this, void 0);
28
31
  if (!bytes) {
29
32
  return;
30
33
  }
@@ -57,12 +60,45 @@ export class Address extends Uint8Array {
57
60
  static wrap(bytes) {
58
61
  return new Address(bytes);
59
62
  }
63
+ static uncompressedToCompressed(publicKey) {
64
+ const buffer = Uint8Array.from(publicKey);
65
+ const x = buffer.slice(1, 33);
66
+ const y = buffer.slice(33);
67
+ const compressed = Buffer.alloc(33);
68
+ compressed[0] = 0x02 + (y[y.length - 1] & 0x01);
69
+ compressed.set(x, 1);
70
+ return compressed;
71
+ }
60
72
  toHex() {
61
73
  return '0x' + Buffer.from(this).toString('hex');
62
74
  }
63
75
  toBuffer() {
64
76
  return Buffer.from(this);
65
77
  }
78
+ toUncompressedHex() {
79
+ if (!__classPrivateFieldGet(this, _Address_uncompressed, "f")) {
80
+ throw new Error('Public key not set');
81
+ }
82
+ return '0x' + __classPrivateFieldGet(this, _Address_uncompressed, "f").uncompressed.toString('hex');
83
+ }
84
+ toUncompressedBuffer() {
85
+ if (!__classPrivateFieldGet(this, _Address_uncompressed, "f")) {
86
+ throw new Error('Public key not set');
87
+ }
88
+ return __classPrivateFieldGet(this, _Address_uncompressed, "f").uncompressed;
89
+ }
90
+ toHybridPublicKeyHex() {
91
+ if (!__classPrivateFieldGet(this, _Address_uncompressed, "f")) {
92
+ throw new Error('Public key not set');
93
+ }
94
+ return '0x' + __classPrivateFieldGet(this, _Address_uncompressed, "f").hybrid.toString('hex');
95
+ }
96
+ toHybridPublicKeyBuffer() {
97
+ if (!__classPrivateFieldGet(this, _Address_uncompressed, "f")) {
98
+ throw new Error('Public key not set');
99
+ }
100
+ return __classPrivateFieldGet(this, _Address_uncompressed, "f").hybrid;
101
+ }
66
102
  originalPublicKeyBuffer() {
67
103
  if (!__classPrivateFieldGet(this, _Address_originalPublicKey, "f")) {
68
104
  throw new Error('Public key not set');
@@ -117,13 +153,11 @@ export class Address extends Uint8Array {
117
153
  if (publicKey.length === ADDRESS_BYTE_LENGTH) {
118
154
  const buf = Buffer.alloc(ADDRESS_BYTE_LENGTH);
119
155
  buf.set(publicKey);
156
+ __classPrivateFieldSet(this, _Address_tweakedUncompressed, ContractAddress.generateHybridKeyFromHash(buf), "f");
120
157
  super.set(publicKey);
121
158
  }
122
159
  else {
123
- __classPrivateFieldSet(this, _Address_originalPublicKey, Uint8Array.from(publicKey), "f");
124
- __classPrivateFieldSet(this, _Address_keyPair, EcKeyPair.fromPublicKey(__classPrivateFieldGet(this, _Address_originalPublicKey, "f")), "f");
125
- const tweakedBytes = toXOnly(EcKeyPair.tweakPublicKey(Buffer.from(__classPrivateFieldGet(this, _Address_originalPublicKey, "f"))));
126
- super.set(tweakedBytes);
160
+ this.autoFormat(publicKey);
127
161
  }
128
162
  }
129
163
  isValid(network) {
@@ -159,5 +193,31 @@ export class Address extends Uint8Array {
159
193
  }
160
194
  throw new Error('Public key not set');
161
195
  }
196
+ toTweakedHybridPublicKeyHex() {
197
+ if (!__classPrivateFieldGet(this, _Address_tweakedUncompressed, "f")) {
198
+ throw new Error('Public key not set');
199
+ }
200
+ return '0x' + __classPrivateFieldGet(this, _Address_tweakedUncompressed, "f").toString('hex');
201
+ }
202
+ toTweakedHybridPublicKeyBuffer() {
203
+ if (!__classPrivateFieldGet(this, _Address_tweakedUncompressed, "f")) {
204
+ throw new Error('Public key not set');
205
+ }
206
+ return __classPrivateFieldGet(this, _Address_tweakedUncompressed, "f");
207
+ }
208
+ autoFormat(publicKey) {
209
+ const firstByte = publicKey[0];
210
+ if (firstByte === 0x03 || firstByte === 0x02) {
211
+ }
212
+ else if (firstByte === 0x04 || firstByte === 0x06 || firstByte === 0x07) {
213
+ publicKey = Address.uncompressedToCompressed(publicKey);
214
+ }
215
+ __classPrivateFieldSet(this, _Address_originalPublicKey, Uint8Array.from(publicKey), "f");
216
+ __classPrivateFieldSet(this, _Address_keyPair, EcKeyPair.fromPublicKey(__classPrivateFieldGet(this, _Address_originalPublicKey, "f")), "f");
217
+ __classPrivateFieldSet(this, _Address_uncompressed, decompressPublicKey(__classPrivateFieldGet(this, _Address_originalPublicKey, "f")), "f");
218
+ const tweakedBytes = toXOnly(EcKeyPair.tweakPublicKey(Buffer.from(__classPrivateFieldGet(this, _Address_originalPublicKey, "f"))));
219
+ __classPrivateFieldSet(this, _Address_tweakedUncompressed, ContractAddress.generateHybridKeyFromHash(tweakedBytes), "f");
220
+ super.set(tweakedBytes);
221
+ }
162
222
  }
163
- _Address_p2tr = new WeakMap(), _Address_network = new WeakMap(), _Address_originalPublicKey = new WeakMap(), _Address_keyPair = new WeakMap();
223
+ _Address_p2tr = new WeakMap(), _Address_network = new WeakMap(), _Address_originalPublicKey = new WeakMap(), _Address_keyPair = new WeakMap(), _Address_uncompressed = new WeakMap(), _Address_tweakedUncompressed = new WeakMap();
@@ -60,13 +60,16 @@ export class AddressVerificator {
60
60
  if (input.length === 64) {
61
61
  return true;
62
62
  }
63
+ const pubKeyBuffer = Buffer.from(input, 'hex');
64
+ if ((input.length === 130 && pubKeyBuffer[0] === 0x06) || pubKeyBuffer[0] === 0x07) {
65
+ return true;
66
+ }
63
67
  if (input.length === 66 || input.length === 130) {
64
- const pubKeyBuffer = Buffer.from(input, 'hex');
65
68
  EcKeyPair.fromPublicKey(pubKeyBuffer, network);
66
69
  return true;
67
70
  }
68
71
  }
69
- catch {
72
+ catch (e) {
70
73
  return false;
71
74
  }
72
75
  return false;
@@ -1,10 +1,8 @@
1
1
  import * as ecc from '@bitcoinerlab/secp256k1';
2
2
  import bip32, { BIP32Factory } from 'bip32';
3
- import { address, initEccLib, networks, payments } from '@btc-vision/bitcoin';
3
+ import { address, initEccLib, networks, payments, taggedHash, toXOnly, } from '@btc-vision/bitcoin';
4
4
  import { ECPairFactory } from 'ecpair';
5
5
  import { CURVE, ProjectivePoint as Point } from '@noble/secp256k1';
6
- import { taggedHash } from '@btc-vision/bitcoin/src/crypto.js';
7
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
8
6
  initEccLib(ecc);
9
7
  const BIP32factory = typeof bip32 === 'function' ? bip32 : BIP32Factory;
10
8
  if (!BIP32factory) {
@@ -62,8 +60,9 @@ export class EcKeyPair {
62
60
  tweakedPubKeyHex = tweakedPubKeyHex.slice(2);
63
61
  }
64
62
  let tweakedPubKeyBuffer = Buffer.from(tweakedPubKeyHex, 'hex');
65
- if (tweakedPubKeyBuffer.length !== 32)
63
+ if (tweakedPubKeyBuffer.length !== 32) {
66
64
  tweakedPubKeyBuffer = toXOnly(tweakedPubKeyBuffer);
65
+ }
67
66
  return EcKeyPair.tweakedPubKeyBufferToAddress(tweakedPubKeyBuffer, network);
68
67
  }
69
68
  static tweakedPubKeyBufferToAddress(tweakedPubKeyBuffer, network) {
@@ -1,8 +1,7 @@
1
1
  import * as ecc from '@bitcoinerlab/secp256k1';
2
- import { crypto } from '@btc-vision/bitcoin';
2
+ import { crypto, toXOnly } from '@btc-vision/bitcoin';
3
3
  import { TweakedSigner } from '../signer/TweakedSigner.js';
4
4
  import { EcKeyPair } from './EcKeyPair.js';
5
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
6
5
  class MessageSignerBase {
7
6
  sha256(message) {
8
7
  return crypto.sha256(Buffer.from(message));
@@ -0,0 +1,16 @@
1
+ export declare class Secp256k1PointDeriver {
2
+ private maxTries;
3
+ constructor(maxTries?: number);
4
+ findOrDeriveValidPoint(xBytes: Uint8Array, failOnInvalidX?: boolean, maxTries?: number): {
5
+ x: bigint;
6
+ y1: bigint;
7
+ y2: bigint;
8
+ };
9
+ getCanonicalY(y: bigint, y2: bigint): bigint;
10
+ getHybridPublicKey(x: bigint, y: bigint): Uint8Array;
11
+ private isValidX;
12
+ private modPow;
13
+ private sqrtModP;
14
+ private bytesToBigInt;
15
+ private bigIntTo32Bytes;
16
+ }
@@ -0,0 +1,80 @@
1
+ const P = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn;
2
+ export class Secp256k1PointDeriver {
3
+ constructor(maxTries = 10000) {
4
+ this.maxTries = maxTries;
5
+ }
6
+ findOrDeriveValidPoint(xBytes, failOnInvalidX = true, maxTries = this.maxTries) {
7
+ if (xBytes.length !== 32) {
8
+ throw new Error('xBytes must be exactly 32 bytes.');
9
+ }
10
+ let xCandidate = this.bytesToBigInt(xBytes) % P;
11
+ let sqrtVal = this.isValidX(xCandidate);
12
+ if (failOnInvalidX && sqrtVal === null) {
13
+ throw new Error(`The given x is not a valid curve point.`);
14
+ }
15
+ let tries = 0;
16
+ while (sqrtVal === null) {
17
+ xCandidate = (xCandidate + 1n) % P;
18
+ sqrtVal = this.isValidX(xCandidate);
19
+ tries++;
20
+ if (tries > maxTries) {
21
+ throw new Error(`Could not find a valid X point within ${maxTries} increments.`);
22
+ }
23
+ }
24
+ const y1 = sqrtVal;
25
+ const y2 = (P - y1) % P;
26
+ return { x: xCandidate, y1, y2 };
27
+ }
28
+ getCanonicalY(y, y2) {
29
+ return y < y2 ? y : y2;
30
+ }
31
+ getHybridPublicKey(x, y) {
32
+ const prefix = y % 2n === 0n ? 0x06 : 0x07;
33
+ const xBytes = this.bigIntTo32Bytes(x);
34
+ const yBytes = this.bigIntTo32Bytes(y);
35
+ const hybrid = new Uint8Array(65);
36
+ hybrid[0] = prefix;
37
+ hybrid.set(xBytes, 1);
38
+ hybrid.set(yBytes, 33);
39
+ return hybrid;
40
+ }
41
+ isValidX(x) {
42
+ const alpha = (this.modPow(x, 3n, P) + 7n) % P;
43
+ return this.sqrtModP(alpha, P);
44
+ }
45
+ modPow(base, exp, m) {
46
+ let result = 1n;
47
+ let cur = base % m;
48
+ let e = exp;
49
+ while (e > 0) {
50
+ if ((e & 1n) === 1n) {
51
+ result = (result * cur) % m;
52
+ }
53
+ cur = (cur * cur) % m;
54
+ e >>= 1n;
55
+ }
56
+ return result;
57
+ }
58
+ sqrtModP(a, prime) {
59
+ const root = this.modPow(a, (prime + 1n) >> 2n, prime);
60
+ if ((root * root) % prime !== a % prime) {
61
+ return null;
62
+ }
63
+ return root;
64
+ }
65
+ bytesToBigInt(bytes) {
66
+ let b = 0n;
67
+ for (const byte of bytes) {
68
+ b = (b << 8n) | BigInt(byte);
69
+ }
70
+ return b;
71
+ }
72
+ bigIntTo32Bytes(value) {
73
+ const bytes = new Uint8Array(32);
74
+ for (let i = 31; i >= 0; i--) {
75
+ bytes[i] = Number(value & 0xffn);
76
+ value >>= 8n;
77
+ }
78
+ return bytes;
79
+ }
80
+ }
@@ -1,6 +1,5 @@
1
1
  import { EcKeyPair } from './EcKeyPair.js';
2
- import { networks } from '@btc-vision/bitcoin';
3
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
2
+ import { networks, toXOnly } from '@btc-vision/bitcoin';
4
3
  import { Address } from './Address.js';
5
4
  export class Wallet {
6
5
  constructor(wallet, network = networks.bitcoin) {
package/build/opnet.d.ts CHANGED
@@ -58,3 +58,5 @@ export * from './transaction/browser/types/Unisat.js';
58
58
  export * from './transaction/browser/types/Xverse.js';
59
59
  export * from './metadata/tokens.js';
60
60
  export * from './transaction/browser/Web3Provider.js';
61
+ export * from './transaction/ContractAddress.js';
62
+ export * from './keypair/Secp256k1PointDeriver.js';
package/build/opnet.js CHANGED
@@ -58,3 +58,5 @@ export * from './transaction/browser/types/Unisat.js';
58
58
  export * from './transaction/browser/types/Xverse.js';
59
59
  export * from './metadata/tokens.js';
60
60
  export * from './transaction/browser/Web3Provider.js';
61
+ export * from './transaction/ContractAddress.js';
62
+ export * from './keypair/Secp256k1PointDeriver.js';
@@ -2,5 +2,4 @@ import { PsbtInput } from '@btc-vision/bitcoin';
2
2
  export declare function isTaprootInput(input: PsbtInput): boolean;
3
3
  export declare function getInputRelevantScript(input: PsbtInput): Buffer | null;
4
4
  export declare function canSignNonTaprootInput(input: PsbtInput, publicKey: Buffer): boolean;
5
- export declare function pubkeyPositionInScript(pubkey: Buffer, script: Buffer): number;
6
5
  export declare function pubkeyInScript(pubkey: Buffer, script: Buffer): boolean;
@@ -1,7 +1,4 @@
1
- import { crypto as bitCrypto } from '@btc-vision/bitcoin';
2
- import { isP2TR } from '@btc-vision/bitcoin/src/psbt/psbtutils.js';
3
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
4
- import * as bscript from '@btc-vision/bitcoin/src/script.js';
1
+ import { isP2TR, pubkeyPositionInScript } from '@btc-vision/bitcoin';
5
2
  export function isTaprootInput(input) {
6
3
  return (input &&
7
4
  !!(input.tapInternalKey ||
@@ -38,19 +35,6 @@ export function canSignNonTaprootInput(input, publicKey) {
38
35
  }
39
36
  return false;
40
37
  }
41
- export function pubkeyPositionInScript(pubkey, script) {
42
- const pubkeyHash = bitCrypto.hash160(pubkey);
43
- const pubkeyXOnly = toXOnly(pubkey);
44
- const decompiled = bscript.decompile(script);
45
- if (decompiled === null)
46
- throw new Error('Unknown script error');
47
- const a = decompiled.findIndex((element) => {
48
- if (typeof element === 'number')
49
- return false;
50
- return element.equals(pubkey) || element.equals(pubkeyHash) || element.equals(pubkeyXOnly);
51
- });
52
- return a;
53
- }
54
38
  export function pubkeyInScript(pubkey, script) {
55
39
  return pubkeyPositionInScript(pubkey, script) !== -1;
56
40
  }
@@ -1,7 +1,5 @@
1
1
  import * as ecc from '@bitcoinerlab/secp256k1';
2
- import { initEccLib } from '@btc-vision/bitcoin';
3
- import { tapTweakHash } from '@btc-vision/bitcoin/src/payments/bip341.js';
4
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
2
+ import { initEccLib, tapTweakHash, toXOnly } from '@btc-vision/bitcoin';
5
3
  import { EcKeyPair } from '../keypair/EcKeyPair.js';
6
4
  initEccLib(ecc);
7
5
  export class TweakedSigner {
@@ -0,0 +1,6 @@
1
+ declare class ContractAddressBase {
2
+ private readonly deriver;
3
+ generateHybridKeyFromHash(input: Buffer): Buffer;
4
+ }
5
+ export declare const ContractAddress: ContractAddressBase;
6
+ export {};
@@ -0,0 +1,12 @@
1
+ import { Secp256k1PointDeriver } from '../keypair/Secp256k1PointDeriver.js';
2
+ class ContractAddressBase {
3
+ constructor() {
4
+ this.deriver = new Secp256k1PointDeriver();
5
+ }
6
+ generateHybridKeyFromHash(input) {
7
+ const p = this.deriver.findOrDeriveValidPoint(Buffer.copyBytesFrom(input), false);
8
+ const y = this.deriver.getCanonicalY(p.y1, p.y2);
9
+ return Buffer.from(this.deriver.getHybridPublicKey(p.x, y));
10
+ }
11
+ }
12
+ export const ContractAddress = new ContractAddressBase();
@@ -1,8 +1,7 @@
1
- import { crypto as bitCrypto, networks, Psbt, script as bitScript, } from '@btc-vision/bitcoin';
1
+ import { crypto as bitCrypto, networks, Psbt, script as bitScript, toXOnly, } from '@btc-vision/bitcoin';
2
2
  import { EcKeyPair } from '../../../keypair/EcKeyPair.js';
3
3
  import { CustomKeypair } from '../BrowserSignerBase.js';
4
4
  import { UnisatNetwork } from '../types/Unisat.js';
5
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
6
5
  import { canSignNonTaprootInput, isTaprootInput } from '../../../signer/SignerUtils.js';
7
6
  export class UnisatSigner extends CustomKeypair {
8
7
  constructor() {
@@ -1,5 +1,4 @@
1
- import { networks, Psbt } from '@btc-vision/bitcoin';
2
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
1
+ import { networks, Psbt, toXOnly } from '@btc-vision/bitcoin';
3
2
  import { EcKeyPair } from '../../../keypair/EcKeyPair.js';
4
3
  import { CustomKeypair } from '../BrowserSignerBase.js';
5
4
  import { canSignNonTaprootInput, isTaprootInput, pubkeyInScript, } from '../../../signer/SignerUtils.js';
@@ -1,7 +1,7 @@
1
+ import { Payment, Psbt, Stack } from '@btc-vision/bitcoin';
1
2
  import { TransactionType } from '../enums/TransactionType.js';
2
3
  import { TapLeafScript } from '../interfaces/Tap.js';
3
4
  import { SharedInteractionParameters } from '../interfaces/ITransactionParameters.js';
4
- import { Payment, Psbt, Stack } from '@btc-vision/bitcoin';
5
5
  import { TransactionBuilder } from './TransactionBuilder.js';
6
6
  export interface ICustomTransactionParameters extends SharedInteractionParameters {
7
7
  readonly script: (Buffer | Stack)[];
@@ -1,11 +1,10 @@
1
+ import { crypto as bitCrypto, toXOnly, } from '@btc-vision/bitcoin';
1
2
  import { TransactionType } from '../enums/TransactionType.js';
2
- import { crypto as bitCrypto } from '@btc-vision/bitcoin';
3
3
  import { TransactionBuilder } from './TransactionBuilder.js';
4
4
  import { CustomGenerator } from '../../generators/builders/CustomGenerator.js';
5
5
  import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
6
6
  import { EcKeyPair } from '../../keypair/EcKeyPair.js';
7
7
  import { AddressGenerator } from '../../generators/AddressGenerator.js';
8
- import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
9
8
  export class CustomScriptTransaction extends TransactionBuilder {
10
9
  constructor(parameters) {
11
10
  super(parameters);