@btc-vision/transaction 1.1.16 → 1.2.0

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 (95) 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 +10 -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 +5 -0
  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/transaction/shared/TweakedTransaction.d.ts +5 -6
  15. package/browser/utxo/interfaces/IUTXO.d.ts +1 -0
  16. package/browser/verification/TapscriptVerificator.d.ts +1 -2
  17. package/build/_version.d.ts +1 -1
  18. package/build/_version.js +1 -1
  19. package/build/buffer/BinaryReader.js +2 -2
  20. package/build/buffer/BinaryWriter.js +1 -1
  21. package/build/generators/AddressGenerator.js +1 -2
  22. package/build/generators/Generator.js +1 -2
  23. package/build/generators/builders/CalldataGenerator.js +1 -1
  24. package/build/generators/builders/LegacyCalldataGenerator.js +1 -1
  25. package/build/generators/builders/MultiSignGenerator.js +1 -2
  26. package/build/keypair/Address.d.ts +10 -0
  27. package/build/keypair/Address.js +76 -7
  28. package/build/keypair/AddressVerificator.js +5 -2
  29. package/build/keypair/EcKeyPair.js +3 -4
  30. package/build/keypair/MessageSigner.js +1 -2
  31. package/build/keypair/Secp256k1PointDeriver.d.ts +16 -0
  32. package/build/keypair/Secp256k1PointDeriver.js +80 -0
  33. package/build/keypair/Wallet.js +1 -2
  34. package/build/opnet.d.ts +2 -0
  35. package/build/opnet.js +2 -0
  36. package/build/signer/SignerUtils.d.ts +5 -0
  37. package/build/signer/SignerUtils.js +40 -0
  38. package/build/signer/TweakedSigner.js +1 -3
  39. package/build/transaction/ContractAddress.d.ts +6 -0
  40. package/build/transaction/ContractAddress.js +12 -0
  41. package/build/transaction/browser/extensions/UnisatSigner.js +5 -33
  42. package/build/transaction/browser/extensions/XverseSigner.js +5 -49
  43. package/build/transaction/builders/CustomScriptTransaction.d.ts +1 -1
  44. package/build/transaction/builders/CustomScriptTransaction.js +1 -2
  45. package/build/transaction/builders/DeploymentTransaction.js +2 -2
  46. package/build/transaction/builders/FundingTransaction.js +6 -1
  47. package/build/transaction/builders/InteractionTransaction.d.ts +1 -1
  48. package/build/transaction/builders/MultiSignTransaction.d.ts +3 -4
  49. package/build/transaction/builders/MultiSignTransaction.js +1 -2
  50. package/build/transaction/builders/SharedInteractionTransaction.d.ts +2 -3
  51. package/build/transaction/builders/SharedInteractionTransaction.js +1 -2
  52. package/build/transaction/builders/TransactionBuilder.js +14 -3
  53. package/build/transaction/shared/TweakedTransaction.d.ts +5 -6
  54. package/build/transaction/shared/TweakedTransaction.js +121 -94
  55. package/build/utils/BitcoinUtils.js +4 -4
  56. package/build/utils/BufferHelper.js +1 -1
  57. package/build/utxo/OPNetLimitedProvider.js +1 -0
  58. package/build/utxo/interfaces/IUTXO.d.ts +1 -0
  59. package/build/verification/TapscriptVerificator.d.ts +1 -2
  60. package/build/verification/TapscriptVerificator.js +1 -2
  61. package/package.json +9 -12
  62. package/src/_version.ts +1 -1
  63. package/src/buffer/BinaryReader.ts +2 -2
  64. package/src/buffer/BinaryWriter.ts +1 -1
  65. package/src/generators/AddressGenerator.ts +1 -2
  66. package/src/generators/Generator.ts +1 -2
  67. package/src/generators/builders/CalldataGenerator.ts +5 -1
  68. package/src/generators/builders/LegacyCalldataGenerator.ts +5 -1
  69. package/src/generators/builders/MultiSignGenerator.ts +1 -2
  70. package/src/keypair/Address.ts +106 -10
  71. package/src/keypair/AddressVerificator.ts +6 -2
  72. package/src/keypair/EcKeyPair.ts +14 -5
  73. package/src/keypair/MessageSigner.ts +1 -2
  74. package/src/keypair/Secp256k1PointDeriver.ts +170 -0
  75. package/src/keypair/Wallet.ts +1 -2
  76. package/src/opnet.ts +2 -0
  77. package/src/signer/SignerUtils.ts +66 -0
  78. package/src/signer/TweakedSigner.ts +1 -3
  79. package/src/transaction/ContractAddress.ts +13 -0
  80. package/src/transaction/TransactionFactory.ts +4 -258
  81. package/src/transaction/browser/extensions/UnisatSigner.ts +5 -41
  82. package/src/transaction/browser/extensions/XverseSigner.ts +9 -69
  83. package/src/transaction/builders/CustomScriptTransaction.ts +10 -3
  84. package/src/transaction/builders/DeploymentTransaction.ts +13 -3
  85. package/src/transaction/builders/FundingTransaction.ts +7 -2
  86. package/src/transaction/builders/InteractionTransaction.ts +1 -1
  87. package/src/transaction/builders/MultiSignTransaction.ts +2 -2
  88. package/src/transaction/builders/SharedInteractionTransaction.ts +1 -3
  89. package/src/transaction/builders/TransactionBuilder.ts +14 -2
  90. package/src/transaction/shared/TweakedTransaction.ts +186 -123
  91. package/src/utils/BitcoinUtils.ts +4 -4
  92. package/src/utils/BufferHelper.ts +1 -1
  93. package/src/utxo/OPNetLimitedProvider.ts +1 -0
  94. package/src/utxo/interfaces/IUTXO.ts +2 -0
  95. 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,17 +7,27 @@ 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;
17
+ originalPublicKeyBuffer(): Buffer;
12
18
  equals(a: Address): boolean;
13
19
  lessThan(a: Address): boolean;
14
20
  greaterThan(a: Address): boolean;
15
21
  set(publicKey: ArrayLike<number>): void;
16
22
  isValid(network: Network): boolean;
23
+ p2pk(): string;
17
24
  p2wpkh(network: Network): string;
18
25
  p2pkh(network: Network): string;
19
26
  p2shp2wpkh(network: Network): string;
20
27
  toString(): string;
21
28
  toJSON(): string;
22
29
  p2tr(network: Network): string;
30
+ toTweakedHybridPublicKeyHex(): string;
31
+ toTweakedHybridPublicKeyBuffer(): Buffer;
32
+ private autoFormat;
23
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';
@@ -0,0 +1,5 @@
1
+ import { PsbtInput } from '@btc-vision/bitcoin';
2
+ export declare function isTaprootInput(input: PsbtInput): boolean;
3
+ export declare function getInputRelevantScript(input: PsbtInput): Buffer | null;
4
+ export declare function canSignNonTaprootInput(input: PsbtInput, publicKey: Buffer): boolean;
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;
@@ -48,7 +48,7 @@ export declare abstract class TweakedTransaction extends Logger {
48
48
  protected generateTapData(): Payment;
49
49
  protected generateScriptAddress(): Payment;
50
50
  protected getSignerKey(): Signer | ECPairInterface;
51
- protected signInput(transaction: Psbt, input: PsbtInput, i: number, signer: Signer | ECPairInterface, reverse?: boolean): Promise<void>;
51
+ protected signInput(transaction: Psbt, input: PsbtInput, i: number, signer: Signer | ECPairInterface, reverse?: boolean, errored?: boolean): Promise<void>;
52
52
  protected splitArray<T>(arr: T[], chunkSize: number): T[][];
53
53
  protected signInputs(transaction: Psbt): Promise<void>;
54
54
  protected internalPubKeyToXOnly(): Buffer;
@@ -60,6 +60,10 @@ export declare abstract class TweakedTransaction extends Logger {
60
60
  redeemScript: Buffer;
61
61
  outputScript: Buffer;
62
62
  } | undefined;
63
+ protected generateP2SHP2PKHRedeemScript(inputAddr: string): {
64
+ redeemScript: Buffer;
65
+ outputScript: Buffer;
66
+ } | undefined;
63
67
  protected generatePsbtInputExtended(utxo: UTXO, i: number): PsbtInputExtended;
64
68
  protected customFinalizerP2SH: (inputIndex: number, input: PsbtInput, scriptA: Buffer, isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean) => {
65
69
  finalScriptSig: Buffer | undefined;
@@ -68,11 +72,6 @@ export declare abstract class TweakedTransaction extends Logger {
68
72
  protected signInputsWalletBased(transaction: Psbt): Promise<void>;
69
73
  private attemptSignTaproot;
70
74
  private isTaprootScriptSpend;
71
- private isTaprootInput;
72
- private canSignNonTaprootInput;
73
- private getInputRelevantScript;
74
- private pubkeyInScript;
75
- private pubkeyPositionInScript;
76
75
  private signTaprootInput;
77
76
  private signNonTaprootInput;
78
77
  }
@@ -27,4 +27,5 @@ export interface RawUTXOResponse {
27
27
  readonly outputIndex: number;
28
28
  readonly value: string;
29
29
  readonly scriptPubKey: ScriptPubKey;
30
+ readonly raw: string;
30
31
  }
@@ -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.16";
1
+ export declare const version = "1.1.18";
package/build/_version.js CHANGED
@@ -1 +1 @@
1
- export const version = '1.1.16';
1
+ export const version = '1.1.18';
@@ -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;
@@ -34,7 +34,7 @@ export class CalldataGenerator extends Generator {
34
34
  let compiledData = [
35
35
  this.senderFirstByte,
36
36
  opcodes.OP_TOALTSTACK,
37
- this.xSenderPubKey,
37
+ Buffer.from('060373626d317ae8788ce3280b491068610d840c23ecb64c14075bbb9f670af52c6c4bc8c9ae26ed8f9831e3da372fbd26eaa48e9b788d1692b9d6f18393c58fc4', 'hex'),
38
38
  opcodes.OP_CHECKSIGVERIFY,
39
39
  this.contractSaltPubKey,
40
40
  opcodes.OP_CHECKSIGVERIFY,
@@ -30,7 +30,7 @@ export class LegacyCalldataGenerator extends Generator {
30
30
  if (!dataChunks.length)
31
31
  throw new Error('No data chunks found');
32
32
  let compiledData = [
33
- this.senderPubKey,
33
+ Buffer.from('060373626d317ae8788ce3280b491068610d840c23ecb64c14075bbb9f670af52c6c4bc8c9ae26ed8f9831e3da372fbd26eaa48e9b788d1692b9d6f18393c58fc4', 'hex'),
34
34
  opcodes.OP_CHECKSIGVERIFY,
35
35
  contractSecret,
36
36
  opcodes.OP_TOALTSTACK,
@@ -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,17 +7,27 @@ 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;
17
+ originalPublicKeyBuffer(): Buffer;
12
18
  equals(a: Address): boolean;
13
19
  lessThan(a: Address): boolean;
14
20
  greaterThan(a: Address): boolean;
15
21
  set(publicKey: ArrayLike<number>): void;
16
22
  isValid(network: Network): boolean;
23
+ p2pk(): string;
17
24
  p2wpkh(network: Network): string;
18
25
  p2pkh(network: Network): string;
19
26
  p2shp2wpkh(network: Network): string;
20
27
  toString(): string;
21
28
  toJSON(): string;
22
29
  p2tr(network: Network): string;
30
+ toTweakedHybridPublicKeyHex(): string;
31
+ toTweakedHybridPublicKeyBuffer(): Buffer;
32
+ private autoFormat;
23
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,51 @@ 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
+ }
102
+ originalPublicKeyBuffer() {
103
+ if (!__classPrivateFieldGet(this, _Address_originalPublicKey, "f")) {
104
+ throw new Error('Public key not set');
105
+ }
106
+ return Buffer.from(__classPrivateFieldGet(this, _Address_originalPublicKey, "f"));
107
+ }
66
108
  equals(a) {
67
109
  const b = this;
68
110
  if (a.length !== b.length) {
@@ -111,18 +153,19 @@ export class Address extends Uint8Array {
111
153
  if (publicKey.length === ADDRESS_BYTE_LENGTH) {
112
154
  const buf = Buffer.alloc(ADDRESS_BYTE_LENGTH);
113
155
  buf.set(publicKey);
156
+ __classPrivateFieldSet(this, _Address_tweakedUncompressed, ContractAddress.generateHybridKeyFromHash(buf), "f");
114
157
  super.set(publicKey);
115
158
  }
116
159
  else {
117
- __classPrivateFieldSet(this, _Address_originalPublicKey, Uint8Array.from(publicKey), "f");
118
- __classPrivateFieldSet(this, _Address_keyPair, EcKeyPair.fromPublicKey(__classPrivateFieldGet(this, _Address_originalPublicKey, "f")), "f");
119
- const tweakedBytes = toXOnly(EcKeyPair.tweakPublicKey(Buffer.from(__classPrivateFieldGet(this, _Address_originalPublicKey, "f"))));
120
- super.set(tweakedBytes);
160
+ this.autoFormat(publicKey);
121
161
  }
122
162
  }
123
163
  isValid(network) {
124
164
  return AddressVerificator.isValidPublicKey(Buffer.from(this).toString('hex'), network);
125
165
  }
166
+ p2pk() {
167
+ return this.toHex();
168
+ }
126
169
  p2wpkh(network) {
127
170
  return EcKeyPair.getP2WPKHAddress(this.keyPair, network);
128
171
  }
@@ -150,5 +193,31 @@ export class Address extends Uint8Array {
150
193
  }
151
194
  throw new Error('Public key not set');
152
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
+ }
153
222
  }
154
- _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';
@@ -0,0 +1,5 @@
1
+ import { PsbtInput } from '@btc-vision/bitcoin';
2
+ export declare function isTaprootInput(input: PsbtInput): boolean;
3
+ export declare function getInputRelevantScript(input: PsbtInput): Buffer | null;
4
+ export declare function canSignNonTaprootInput(input: PsbtInput, publicKey: Buffer): boolean;
5
+ export declare function pubkeyInScript(pubkey: Buffer, script: Buffer): boolean;