@btc-vision/transaction 1.0.111 → 1.0.113

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 (61) hide show
  1. package/browser/_version.d.ts +1 -1
  2. package/browser/generators/Generator.d.ts +2 -0
  3. package/browser/index.js +1 -1
  4. package/browser/keypair/AddressVerificator.d.ts +15 -3
  5. package/browser/keypair/EcKeyPair.d.ts +9 -4
  6. package/browser/keypair/Wallet.d.ts +1 -0
  7. package/browser/signer/TweakedSigner.d.ts +2 -2
  8. package/browser/transaction/builders/FundingTransaction.d.ts +2 -1
  9. package/browser/transaction/builders/MultiSignTransaction.d.ts +2 -1
  10. package/browser/transaction/builders/SharedInteractionTransaction.d.ts +1 -1
  11. package/browser/transaction/builders/TransactionBuilder.d.ts +3 -2
  12. package/browser/transaction/shared/TweakedTransaction.d.ts +8 -7
  13. package/browser/verification/TapscriptVerificator.d.ts +1 -1
  14. package/build/_version.d.ts +1 -1
  15. package/build/_version.js +1 -1
  16. package/build/generators/Generator.d.ts +2 -0
  17. package/build/generators/Generator.js +5 -0
  18. package/build/generators/builders/CalldataGenerator.js +4 -2
  19. package/build/generators/builders/DeploymentGenerator.js +7 -4
  20. package/build/keypair/AddressVerificator.d.ts +15 -3
  21. package/build/keypair/AddressVerificator.js +74 -3
  22. package/build/keypair/EcKeyPair.d.ts +9 -4
  23. package/build/keypair/EcKeyPair.js +69 -7
  24. package/build/keypair/Wallet.d.ts +1 -0
  25. package/build/keypair/Wallet.js +5 -4
  26. package/build/signer/TweakedSigner.d.ts +2 -2
  27. package/build/signer/TweakedSigner.js +1 -1
  28. package/build/transaction/builders/CustomScriptTransaction.js +3 -3
  29. package/build/transaction/builders/DeploymentTransaction.js +4 -4
  30. package/build/transaction/builders/FundingTransaction.d.ts +2 -1
  31. package/build/transaction/builders/FundingTransaction.js +18 -4
  32. package/build/transaction/builders/MultiSignTransaction.d.ts +2 -1
  33. package/build/transaction/builders/SharedInteractionTransaction.d.ts +1 -1
  34. package/build/transaction/builders/SharedInteractionTransaction.js +4 -4
  35. package/build/transaction/builders/TransactionBuilder.d.ts +3 -2
  36. package/build/transaction/builders/TransactionBuilder.js +7 -2
  37. package/build/transaction/builders/UnwrapTransaction.js +2 -2
  38. package/build/transaction/shared/TweakedTransaction.d.ts +8 -7
  39. package/build/transaction/shared/TweakedTransaction.js +1 -1
  40. package/build/verification/TapscriptVerificator.d.ts +1 -1
  41. package/build/verification/TapscriptVerificator.js +2 -2
  42. package/package.json +2 -1
  43. package/src/_version.ts +1 -1
  44. package/src/generators/Generator.ts +12 -0
  45. package/src/generators/builders/CalldataGenerator.ts +6 -3
  46. package/src/generators/builders/DeploymentGenerator.ts +9 -4
  47. package/src/keypair/AddressVerificator.ts +144 -5
  48. package/src/keypair/EcKeyPair.ts +149 -13
  49. package/src/keypair/Wallet.ts +11 -3
  50. package/src/signer/TweakedSigner.ts +3 -2
  51. package/src/transaction/builders/CustomScriptTransaction.ts +6 -5
  52. package/src/transaction/builders/DeploymentTransaction.ts +6 -5
  53. package/src/transaction/builders/FundingTransaction.ts +18 -5
  54. package/src/transaction/builders/MultiSignTransaction.ts +6 -2
  55. package/src/transaction/builders/SharedInteractionTransaction.ts +5 -5
  56. package/src/transaction/builders/TransactionBuilder.ts +36 -10
  57. package/src/transaction/builders/UnwrapSegwitTransaction.ts +7 -3
  58. package/src/transaction/builders/UnwrapTransaction.ts +2 -2
  59. package/src/transaction/builders/WrapTransaction.ts +1 -6
  60. package/src/transaction/shared/TweakedTransaction.ts +12 -12
  61. package/src/verification/TapscriptVerificator.ts +3 -3
@@ -1,6 +1,18 @@
1
- import { networks } from 'bitcoinjs-lib';
1
+ import { Network } from 'bitcoinjs-lib';
2
2
  import { Address } from '@btc-vision/bsi-binary';
3
+ export declare enum AddressTypes {
4
+ P2PKH = "P2PKH",
5
+ P2SH = "P2SH",
6
+ P2SH_P2WPKH = "P2SH-P2WPKH",
7
+ P2SH_OR_P2SH_P2WPKH = "P2SH_OR_P2SH-P2WPKH",
8
+ P2PK = "P2PK",
9
+ P2TR = "P2TR",
10
+ P2WPKH = "P2WPKH"
11
+ }
3
12
  export declare class AddressVerificator {
4
- static isValidP2TRAddress(inAddress: Address, network: networks.Network): boolean;
5
- static validatePKHAddress(inAddress: string, network: networks.Network): boolean;
13
+ static isValidP2TRAddress(inAddress: Address, network: Network): boolean;
14
+ static isP2WPKHAddress(inAddress: string, network: Network): boolean;
15
+ static isP2PKHOrP2SH(addy: string, network: Network): boolean;
16
+ static isValidPublicKey(input: string, network: Network): boolean;
17
+ static validateBitcoinAddress(addy: string, network: Network): AddressTypes | null;
6
18
  }
@@ -1,23 +1,28 @@
1
1
  import { Address } from '@btc-vision/bsi-binary';
2
2
  import { BIP32API, BIP32Interface } from 'bip32';
3
- import { Network } from 'bitcoinjs-lib';
3
+ import { Network, Signer } from 'bitcoinjs-lib';
4
4
  import { ECPairAPI, ECPairInterface } from 'ecpair';
5
5
  import { IWallet } from './interfaces/IWallet.js';
6
6
  export declare class EcKeyPair {
7
7
  static BIP32: BIP32API;
8
8
  static ECPair: ECPairAPI;
9
9
  static fromWIF(wif: string, network?: Network): ECPairInterface;
10
- static fromPrivateKey(privateKey: Buffer, network?: Network): ECPairInterface;
11
- static fromPublicKey(publicKey: Buffer, network?: Network): ECPairInterface;
10
+ static fromPrivateKey(privateKey: Buffer | Uint8Array, network?: Network): ECPairInterface;
11
+ static fromPublicKey(publicKey: Buffer | Uint8Array, network?: Network): ECPairInterface;
12
12
  static generateMultiSigAddress(pubKeys: Buffer[], minimumSignatureRequired: number, network?: Network): Address;
13
13
  static verifyPubKeys(pubKeys: Buffer[], network?: Network): Buffer[];
14
14
  static getP2WPKHAddress(keyPair: ECPairInterface, network?: Network): Address;
15
+ static tweakedPubKeyToAddress(tweakedPubKeyHex: string, network: Network): string;
16
+ static xOnlyTweakedPubKeyToAddress(tweakedPubKeyHex: string, network: Network): string;
17
+ static tweakPublicKey(compressedPubKeyHex: string): string;
15
18
  static generateWallet(network?: Network): IWallet;
16
19
  static verifyContractAddress(contractAddress: Address, network?: Network): boolean;
20
+ static getLegacySegwitAddress(keyPair: ECPairInterface, network?: Network): Address;
17
21
  static getLegacyAddress(keyPair: ECPairInterface, network?: Network): Address;
22
+ static getP2PKAddress(keyPair: ECPairInterface, network?: Network): Address;
18
23
  static generateRandomKeyPair(network?: Network): ECPairInterface;
19
24
  static fromSeed(seed: Buffer, network?: Network): BIP32Interface;
20
- static getTaprootAddress(keyPair: ECPairInterface, network?: Network): Address;
25
+ static getTaprootAddress(keyPair: ECPairInterface | Signer, network?: Network): Address;
21
26
  static getTaprootAddressFromAddress(inAddr: Address, network?: Network): Address;
22
27
  static fromSeedKeyPair(seed: Buffer, network?: Network): ECPairInterface;
23
28
  }
@@ -8,6 +8,7 @@ export declare class Wallet {
8
8
  private readonly _p2wpkh;
9
9
  private readonly _p2tr;
10
10
  private readonly _legacy;
11
+ private readonly _bufferPubKey;
11
12
  constructor(wallet: IWallet, network?: Network);
12
13
  get keypair(): ECPairInterface;
13
14
  get p2wpkh(): Address;
@@ -1,9 +1,9 @@
1
- import { Network, Signer } from 'bitcoinjs-lib';
1
+ import { Network } from 'bitcoinjs-lib';
2
2
  import { ECPairInterface } from 'ecpair';
3
3
  export interface TweakSettings {
4
4
  readonly network?: Network;
5
5
  tweakHash?: Buffer;
6
6
  }
7
7
  export declare class TweakedSigner {
8
- static tweakSigner(signer: ECPairInterface, opts?: TweakSettings): Signer;
8
+ static tweakSigner(signer: ECPairInterface, opts?: TweakSettings): ECPairInterface;
9
9
  }
@@ -2,6 +2,7 @@ import { TransactionType } from '../enums/TransactionType.js';
2
2
  import { IFundingTransactionParameters } from '../interfaces/ITransactionParameters.js';
3
3
  import { Signer } from 'bitcoinjs-lib';
4
4
  import { TransactionBuilder } from './TransactionBuilder.js';
5
+ import { ECPairInterface } from 'ecpair';
5
6
  export declare class FundingTransaction extends TransactionBuilder<TransactionType.FUNDING> {
6
7
  readonly type: TransactionType.FUNDING;
7
8
  protected amount: bigint;
@@ -9,5 +10,5 @@ export declare class FundingTransaction extends TransactionBuilder<TransactionTy
9
10
  constructor(parameters: IFundingTransactionParameters);
10
11
  protected buildTransaction(): Promise<void>;
11
12
  protected splitInputs(amountSpent: bigint): void;
12
- protected getSignerKey(): Signer;
13
+ protected getSignerKey(): Signer | ECPairInterface;
13
14
  }
@@ -5,6 +5,7 @@ import { TransactionBuilder } from './TransactionBuilder.js';
5
5
  import { TransactionType } from '../enums/TransactionType.js';
6
6
  import { ITransactionParameters } from '../interfaces/ITransactionParameters.js';
7
7
  import { Address } from '@btc-vision/bsi-binary';
8
+ import { ECPairInterface } from 'ecpair';
8
9
  export interface MultiSignParameters extends Omit<ITransactionParameters, 'priorityFee' | 'signer'> {
9
10
  readonly pubkeys: Buffer[];
10
11
  readonly minimumSignatures: number;
@@ -37,7 +38,7 @@ export declare class MultiSignTransaction extends TransactionBuilder<Transaction
37
38
  constructor(parameters: MultiSignParameters);
38
39
  static fromBase64(params: MultiSignFromBase64Params): MultiSignTransaction;
39
40
  static verifyIfSigned(psbt: Psbt, signerPubKey: Buffer): boolean;
40
- static signPartial(psbt: Psbt, signer: Signer, originalInputCount: number, minimums: number[]): {
41
+ static signPartial(psbt: Psbt, signer: Signer | ECPairInterface, originalInputCount: number, minimums: number[]): {
41
42
  final: boolean;
42
43
  signed: boolean;
43
44
  };
@@ -16,7 +16,7 @@ export declare abstract class SharedInteractionTransaction<T extends Transaction
16
16
  protected calldataGenerator: CalldataGenerator;
17
17
  protected readonly calldata: Buffer;
18
18
  protected abstract readonly contractSecret: Buffer;
19
- protected readonly scriptSigner: Signer;
19
+ protected readonly scriptSigner: Signer | ECPairInterface;
20
20
  protected readonly disableAutoRefund: boolean;
21
21
  protected constructor(parameters: SharedInteractionParameters);
22
22
  getContractSecret(): Buffer;
@@ -20,7 +20,7 @@ export declare abstract class TransactionBuilder<T extends TransactionType> exte
20
20
  protected readonly outputs: PsbtOutputExtended[];
21
21
  protected feeOutput: PsbtOutputExtended | null;
22
22
  protected totalInputAmount: bigint;
23
- protected readonly signer: Signer;
23
+ protected readonly signer: Signer | ECPairInterface;
24
24
  protected readonly network: Network;
25
25
  protected readonly feeRate: number;
26
26
  protected priorityFee: bigint;
@@ -28,8 +28,9 @@ export declare abstract class TransactionBuilder<T extends TransactionType> exte
28
28
  protected to: Address | undefined;
29
29
  protected from: Address;
30
30
  protected _maximumFeeRate: number;
31
+ protected isPubKeyDestination: boolean;
31
32
  protected constructor(parameters: ITransactionParameters);
32
- static getFrom(from: string | undefined, keypair: ECPairInterface, network: Network): Address;
33
+ static getFrom(from: string | undefined, keypair: ECPairInterface | Signer, network: Network): Address;
33
34
  static witnessStackToScriptWitness(witness: Buffer[]): Buffer;
34
35
  getFundingTransactionParameters(): Promise<IFundingTransactionParameters>;
35
36
  setDestinationAddress(address: Address): void;
@@ -1,11 +1,12 @@
1
1
  import { Logger } from '@btc-vision/logger';
2
2
  import { Network, Payment, Psbt, Signer, Transaction } from 'bitcoinjs-lib';
3
+ import { ECPairInterface } from 'ecpair';
3
4
  import { PsbtInput } from 'bip174/src/lib/interfaces.js';
4
5
  import { UTXO } from '../../utxo/interfaces/IUTXO.js';
5
6
  import { PsbtInputExtended, TapLeafScript } from '../interfaces/Tap.js';
6
7
  import { ChainId } from '../../network/ChainId.js';
7
8
  export interface ITweakedTransactionData {
8
- readonly signer: Signer;
9
+ readonly signer: Signer | ECPairInterface;
9
10
  readonly network: Network;
10
11
  readonly chainId?: ChainId;
11
12
  readonly nonWitnessUtxo?: Buffer;
@@ -17,8 +18,8 @@ export declare enum TransactionSequence {
17
18
  export declare abstract class TweakedTransaction extends Logger {
18
19
  readonly logColor: string;
19
20
  finalized: boolean;
20
- protected signer: Signer;
21
- protected tweakedSigner?: Signer;
21
+ protected signer: Signer | ECPairInterface;
22
+ protected tweakedSigner?: ECPairInterface;
22
23
  protected network: Network;
23
24
  protected signed: boolean;
24
25
  protected abstract readonly transaction: Psbt;
@@ -35,7 +36,7 @@ export declare abstract class TweakedTransaction extends Logger {
35
36
  protected constructor(data: ITweakedTransactionData);
36
37
  static readScriptWitnessToWitnessStack(Buffer: Buffer): Buffer[];
37
38
  static preEstimateTaprootTransactionFees(feeRate: bigint, numInputs: bigint, numOutputs: bigint, numWitnessElements: bigint, witnessElementSize: bigint, emptyWitness: bigint, taprootControlWitnessSize?: bigint, taprootScriptSize?: bigint): bigint;
38
- protected static signInput(transaction: Psbt, input: PsbtInput, i: number, signer: Signer, sighashTypes: number[]): void;
39
+ protected static signInput(transaction: Psbt, input: PsbtInput, i: number, signer: Signer | ECPairInterface, sighashTypes: number[]): void;
39
40
  protected static calculateSignHash(sighashTypes: number[]): number;
40
41
  ignoreSignatureError(): void;
41
42
  getScriptAddress(): string;
@@ -46,13 +47,13 @@ export declare abstract class TweakedTransaction extends Logger {
46
47
  preEstimateTransactionFees(feeRate: bigint, numInputs: bigint, numOutputs: bigint, numSignatures: bigint, numPubkeys: bigint): bigint;
47
48
  protected generateTapData(): Payment;
48
49
  protected generateScriptAddress(): Payment;
49
- protected getSignerKey(): Signer;
50
- protected signInput(transaction: Psbt, input: PsbtInput, i: number, signer?: Signer): Promise<void>;
50
+ protected getSignerKey(): Signer | ECPairInterface;
51
+ protected signInput(transaction: Psbt, input: PsbtInput, i: number, signer?: Signer | ECPairInterface): Promise<void>;
51
52
  protected splitArray<T>(arr: T[], chunkSize: number): T[][];
52
53
  protected signInputs(transaction: Psbt): Promise<void>;
53
54
  protected internalPubKeyToXOnly(): Buffer;
54
55
  protected internalInit(): void;
55
56
  protected tweakSigner(): void;
56
- protected getTweakedSigner(useTweakedHash?: boolean, signer?: Signer): Signer | undefined;
57
+ protected getTweakedSigner(useTweakedHash?: boolean, signer?: Signer | ECPairInterface): ECPairInterface | undefined;
57
58
  protected generatePsbtInputExtended(utxo: UTXO, i: number): PsbtInputExtended;
58
59
  }
@@ -1,7 +1,7 @@
1
1
  import { Network } from 'bitcoinjs-lib';
2
2
  import { Taptree } from 'bitcoinjs-lib/src/types.js';
3
3
  export interface ContractAddressVerificationParams {
4
- readonly deployerPubKeyXOnly: Buffer;
4
+ readonly deployerPubKey: Buffer;
5
5
  readonly contractSaltPubKey: Buffer;
6
6
  readonly originalSalt: Buffer;
7
7
  readonly bytecode: Buffer;
@@ -1 +1 @@
1
- export declare const version = "1.0.111";
1
+ export declare const version = "1.0.113";
package/build/_version.js CHANGED
@@ -1 +1 @@
1
- export const version = '1.0.111';
1
+ export const version = '1.0.113';
@@ -3,9 +3,11 @@ export declare abstract class Generator {
3
3
  static readonly DATA_CHUNK_SIZE: number;
4
4
  static readonly MAGIC: Buffer;
5
5
  protected readonly senderPubKey: Buffer;
6
+ protected readonly xSenderPubKey: Buffer;
6
7
  protected readonly contractSaltPubKey?: Buffer;
7
8
  protected readonly network: Network;
8
9
  protected constructor(senderPubKey: Buffer, contractSaltPubKey?: Buffer, network?: Network);
10
+ get senderFirstByte(): Buffer;
9
11
  abstract compile(...args: unknown[]): Buffer;
10
12
  protected splitBufferIntoChunks(buffer: Buffer, chunkSize?: number): Array<Buffer[]>;
11
13
  }
@@ -1,10 +1,15 @@
1
1
  import { networks } from 'bitcoinjs-lib';
2
+ import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
2
3
  export class Generator {
3
4
  constructor(senderPubKey, contractSaltPubKey, network = networks.bitcoin) {
4
5
  this.network = networks.bitcoin;
5
6
  this.senderPubKey = senderPubKey;
6
7
  this.contractSaltPubKey = contractSaltPubKey;
7
8
  this.network = network;
9
+ this.xSenderPubKey = toXOnly(senderPubKey);
10
+ }
11
+ get senderFirstByte() {
12
+ return Buffer.from([this.senderPubKey[0], 0, 0, 0]);
8
13
  }
9
14
  splitBufferIntoChunks(buffer, chunkSize = Generator.DATA_CHUNK_SIZE) {
10
15
  const chunks = [];
@@ -32,12 +32,14 @@ export class CalldataGenerator extends Generator {
32
32
  if (!dataChunks.length)
33
33
  throw new Error('No data chunks found');
34
34
  let compiledData = [
35
- this.senderPubKey,
35
+ this.senderFirstByte,
36
+ opcodes.OP_TOALTSTACK,
37
+ this.xSenderPubKey,
36
38
  opcodes.OP_CHECKSIGVERIFY,
37
39
  this.contractSaltPubKey,
38
40
  opcodes.OP_CHECKSIGVERIFY,
39
41
  opcodes.OP_HASH160,
40
- crypto.hash160(this.senderPubKey),
42
+ crypto.hash160(this.xSenderPubKey),
41
43
  opcodes.OP_EQUALVERIFY,
42
44
  opcodes.OP_HASH160,
43
45
  crypto.hash160(contractSecret),
@@ -18,13 +18,15 @@ export class DeploymentGenerator extends Generator {
18
18
  throw new Error('Contract salt public key not set');
19
19
  const dataChunks = this.splitBufferIntoChunks(contractBytecode);
20
20
  const calldataChunks = calldata ? this.splitBufferIntoChunks(calldata) : [];
21
- return [
22
- this.senderPubKey,
21
+ const compiledData = [
22
+ this.senderFirstByte,
23
+ opcodes.OP_TOALTSTACK,
24
+ this.xSenderPubKey,
23
25
  opcodes.OP_CHECKSIGVERIFY,
24
26
  this.contractSaltPubKey,
25
27
  opcodes.OP_CHECKSIGVERIFY,
26
28
  opcodes.OP_HASH160,
27
- crypto.hash160(this.senderPubKey),
29
+ crypto.hash160(this.xSenderPubKey),
28
30
  opcodes.OP_EQUALVERIFY,
29
31
  opcodes.OP_HASH256,
30
32
  crypto.hash256(contractSalt),
@@ -41,6 +43,7 @@ export class DeploymentGenerator extends Generator {
41
43
  opcodes.OP_ELSE,
42
44
  opcodes.OP_1,
43
45
  opcodes.OP_ENDIF,
44
- ].flat();
46
+ ];
47
+ return compiledData.flat();
45
48
  }
46
49
  }
@@ -1,6 +1,18 @@
1
- import { networks } from 'bitcoinjs-lib';
1
+ import { Network } from 'bitcoinjs-lib';
2
2
  import { Address } from '@btc-vision/bsi-binary';
3
+ export declare enum AddressTypes {
4
+ P2PKH = "P2PKH",
5
+ P2SH = "P2SH",
6
+ P2SH_P2WPKH = "P2SH-P2WPKH",
7
+ P2SH_OR_P2SH_P2WPKH = "P2SH_OR_P2SH-P2WPKH",
8
+ P2PK = "P2PK",
9
+ P2TR = "P2TR",
10
+ P2WPKH = "P2WPKH"
11
+ }
3
12
  export declare class AddressVerificator {
4
- static isValidP2TRAddress(inAddress: Address, network: networks.Network): boolean;
5
- static validatePKHAddress(inAddress: string, network: networks.Network): boolean;
13
+ static isValidP2TRAddress(inAddress: Address, network: Network): boolean;
14
+ static isP2WPKHAddress(inAddress: string, network: Network): boolean;
15
+ static isP2PKHOrP2SH(addy: string, network: Network): boolean;
16
+ static isValidPublicKey(input: string, network: Network): boolean;
17
+ static validateBitcoinAddress(addy: string, network: Network): AddressTypes | null;
6
18
  }
@@ -1,6 +1,17 @@
1
1
  import { address, initEccLib } from 'bitcoinjs-lib';
2
2
  import * as ecc from '@bitcoinerlab/secp256k1';
3
+ import { EcKeyPair } from './EcKeyPair.js';
3
4
  initEccLib(ecc);
5
+ export var AddressTypes;
6
+ (function (AddressTypes) {
7
+ AddressTypes["P2PKH"] = "P2PKH";
8
+ AddressTypes["P2SH"] = "P2SH";
9
+ AddressTypes["P2SH_P2WPKH"] = "P2SH-P2WPKH";
10
+ AddressTypes["P2SH_OR_P2SH_P2WPKH"] = "P2SH_OR_P2SH-P2WPKH";
11
+ AddressTypes["P2PK"] = "P2PK";
12
+ AddressTypes["P2TR"] = "P2TR";
13
+ AddressTypes["P2WPKH"] = "P2WPKH";
14
+ })(AddressTypes || (AddressTypes = {}));
4
15
  export class AddressVerificator {
5
16
  static isValidP2TRAddress(inAddress, network) {
6
17
  if (!inAddress || inAddress.length < 50)
@@ -11,10 +22,10 @@ export class AddressVerificator {
11
22
  const decodedAddress = address.fromBech32(inAddress);
12
23
  isValidTapRootAddress = decodedAddress.version === 1;
13
24
  }
14
- catch (e) { }
25
+ catch { }
15
26
  return isValidTapRootAddress;
16
27
  }
17
- static validatePKHAddress(inAddress, network) {
28
+ static isP2WPKHAddress(inAddress, network) {
18
29
  if (!inAddress || inAddress.length < 20 || inAddress.length > 50)
19
30
  return false;
20
31
  let isValidSegWitAddress = false;
@@ -24,7 +35,67 @@ export class AddressVerificator {
24
35
  isValidSegWitAddress =
25
36
  decodedAddress.version === 0 && decodedAddress.data.length === 20;
26
37
  }
27
- catch (e) { }
38
+ catch { }
28
39
  return isValidSegWitAddress;
29
40
  }
41
+ static isP2PKHOrP2SH(addy, network) {
42
+ try {
43
+ const decodedBase58 = address.fromBase58Check(addy);
44
+ if (decodedBase58.version === network.pubKeyHash) {
45
+ return true;
46
+ }
47
+ return decodedBase58.version === network.scriptHash;
48
+ }
49
+ catch (error) {
50
+ return false;
51
+ }
52
+ }
53
+ static isValidPublicKey(input, network) {
54
+ try {
55
+ if (input.startsWith('0x')) {
56
+ input = input.slice(2);
57
+ }
58
+ const hexRegex = /^[0-9a-fA-F]+$/;
59
+ if ((input.length === 66 || input.length === 130) && hexRegex.test(input)) {
60
+ const pubKeyBuffer = Buffer.from(input, 'hex');
61
+ EcKeyPair.fromPublicKey(pubKeyBuffer, network);
62
+ return true;
63
+ }
64
+ }
65
+ catch (error) {
66
+ console.log(error);
67
+ return false;
68
+ }
69
+ return false;
70
+ }
71
+ static validateBitcoinAddress(addy, network) {
72
+ if (AddressVerificator.isValidPublicKey(addy, network)) {
73
+ return AddressTypes.P2PK;
74
+ }
75
+ try {
76
+ const decodedBase58 = address.fromBase58Check(addy);
77
+ if (decodedBase58.version === network.pubKeyHash) {
78
+ return AddressTypes.P2PKH;
79
+ }
80
+ if (decodedBase58.version === network.scriptHash) {
81
+ return AddressTypes.P2SH_OR_P2SH_P2WPKH;
82
+ }
83
+ }
84
+ catch (error) {
85
+ }
86
+ try {
87
+ const decodedBech32 = address.fromBech32(addy);
88
+ if (decodedBech32.prefix === network.bech32) {
89
+ if (decodedBech32.version === 0 && decodedBech32.data.length === 20) {
90
+ return AddressTypes.P2WPKH;
91
+ }
92
+ if (decodedBech32.version === 1 && decodedBech32.data.length === 32) {
93
+ return AddressTypes.P2TR;
94
+ }
95
+ }
96
+ }
97
+ catch (error) {
98
+ }
99
+ return null;
100
+ }
30
101
  }
@@ -1,23 +1,28 @@
1
1
  import { Address } from '@btc-vision/bsi-binary';
2
2
  import { BIP32API, BIP32Interface } from 'bip32';
3
- import { Network } from 'bitcoinjs-lib';
3
+ import { Network, Signer } from 'bitcoinjs-lib';
4
4
  import { ECPairAPI, ECPairInterface } from 'ecpair';
5
5
  import { IWallet } from './interfaces/IWallet.js';
6
6
  export declare class EcKeyPair {
7
7
  static BIP32: BIP32API;
8
8
  static ECPair: ECPairAPI;
9
9
  static fromWIF(wif: string, network?: Network): ECPairInterface;
10
- static fromPrivateKey(privateKey: Buffer, network?: Network): ECPairInterface;
11
- static fromPublicKey(publicKey: Buffer, network?: Network): ECPairInterface;
10
+ static fromPrivateKey(privateKey: Buffer | Uint8Array, network?: Network): ECPairInterface;
11
+ static fromPublicKey(publicKey: Buffer | Uint8Array, network?: Network): ECPairInterface;
12
12
  static generateMultiSigAddress(pubKeys: Buffer[], minimumSignatureRequired: number, network?: Network): Address;
13
13
  static verifyPubKeys(pubKeys: Buffer[], network?: Network): Buffer[];
14
14
  static getP2WPKHAddress(keyPair: ECPairInterface, network?: Network): Address;
15
+ static tweakedPubKeyToAddress(tweakedPubKeyHex: string, network: Network): string;
16
+ static xOnlyTweakedPubKeyToAddress(tweakedPubKeyHex: string, network: Network): string;
17
+ static tweakPublicKey(compressedPubKeyHex: string): string;
15
18
  static generateWallet(network?: Network): IWallet;
16
19
  static verifyContractAddress(contractAddress: Address, network?: Network): boolean;
20
+ static getLegacySegwitAddress(keyPair: ECPairInterface, network?: Network): Address;
17
21
  static getLegacyAddress(keyPair: ECPairInterface, network?: Network): Address;
22
+ static getP2PKAddress(keyPair: ECPairInterface, network?: Network): Address;
18
23
  static generateRandomKeyPair(network?: Network): ECPairInterface;
19
24
  static fromSeed(seed: Buffer, network?: Network): BIP32Interface;
20
- static getTaprootAddress(keyPair: ECPairInterface, network?: Network): Address;
25
+ static getTaprootAddress(keyPair: ECPairInterface | Signer, network?: Network): Address;
21
26
  static getTaprootAddressFromAddress(inAddr: Address, network?: Network): Address;
22
27
  static fromSeedKeyPair(seed: Buffer, network?: Network): ECPairInterface;
23
28
  }
@@ -3,6 +3,8 @@ import bip32, { BIP32Factory } from 'bip32';
3
3
  import { address, initEccLib, networks, payments } from 'bitcoinjs-lib';
4
4
  import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
5
5
  import { ECPairFactory } from 'ecpair';
6
+ import { CURVE, Point, utils } from '@noble/secp256k1';
7
+ import { taggedHash } from 'bitcoinjs-lib/src/crypto.js';
6
8
  initEccLib(ecc);
7
9
  const BIP32factory = typeof bip32 === 'function' ? bip32 : BIP32Factory;
8
10
  if (!BIP32factory) {
@@ -13,10 +15,11 @@ export class EcKeyPair {
13
15
  return this.ECPair.fromWIF(wif, network);
14
16
  }
15
17
  static fromPrivateKey(privateKey, network = networks.bitcoin) {
16
- return this.ECPair.fromPrivateKey(privateKey, { network });
18
+ return this.ECPair.fromPrivateKey(!Buffer.isBuffer(privateKey) ? Buffer.from(privateKey) : privateKey, { network });
17
19
  }
18
20
  static fromPublicKey(publicKey, network = networks.bitcoin) {
19
- return this.ECPair.fromPublicKey(publicKey, { network });
21
+ const buf = !Buffer.isBuffer(publicKey) ? Buffer.from(publicKey) : publicKey;
22
+ return this.ECPair.fromPublicKey(buf, { network });
20
23
  }
21
24
  static generateMultiSigAddress(pubKeys, minimumSignatureRequired, network = networks.bitcoin) {
22
25
  const publicKeys = this.verifyPubKeys(pubKeys, network);
@@ -40,16 +43,58 @@ export class EcKeyPair {
40
43
  if (!key) {
41
44
  throw new Error('Failed to regenerate key');
42
45
  }
43
- return key.publicKey;
46
+ return Buffer.from(key.publicKey);
44
47
  });
45
48
  }
46
49
  static getP2WPKHAddress(keyPair, network = networks.bitcoin) {
47
- const res = payments.p2wpkh({ pubkey: keyPair.publicKey, network: network });
50
+ const res = payments.p2wpkh({ pubkey: Buffer.from(keyPair.publicKey), network: network });
48
51
  if (!res.address) {
49
52
  throw new Error('Failed to generate wallet');
50
53
  }
51
54
  return res.address;
52
55
  }
56
+ static tweakedPubKeyToAddress(tweakedPubKeyHex, network) {
57
+ if (tweakedPubKeyHex.startsWith('0x')) {
58
+ tweakedPubKeyHex = tweakedPubKeyHex.slice(2);
59
+ }
60
+ const tweakedPubKeyBuffer = Buffer.from(tweakedPubKeyHex, 'hex');
61
+ const { address } = payments.p2tr({
62
+ pubkey: toXOnly(tweakedPubKeyBuffer),
63
+ network: network,
64
+ });
65
+ if (!address) {
66
+ throw new Error('Failed to generate Taproot address');
67
+ }
68
+ return address;
69
+ }
70
+ static xOnlyTweakedPubKeyToAddress(tweakedPubKeyHex, network) {
71
+ if (tweakedPubKeyHex.startsWith('0x')) {
72
+ tweakedPubKeyHex = tweakedPubKeyHex.slice(2);
73
+ }
74
+ const tweakedPubKeyBuffer = Buffer.from(tweakedPubKeyHex, 'hex');
75
+ const { address } = payments.p2tr({
76
+ pubkey: tweakedPubKeyBuffer,
77
+ network: network,
78
+ });
79
+ if (!address) {
80
+ throw new Error('Failed to generate Taproot address');
81
+ }
82
+ return address;
83
+ }
84
+ static tweakPublicKey(compressedPubKeyHex) {
85
+ if (compressedPubKeyHex.startsWith('0x')) {
86
+ compressedPubKeyHex = compressedPubKeyHex.slice(2);
87
+ }
88
+ let P = Point.fromHex(compressedPubKeyHex);
89
+ if (!P.hasEvenY()) {
90
+ P = P.negate();
91
+ }
92
+ const x = P.toRawBytes(true).slice(1);
93
+ const tHash = taggedHash('TapTweak', Buffer.from(x));
94
+ const t = utils.mod(BigInt('0x' + Buffer.from(tHash).toString('hex')), CURVE.n);
95
+ const Q = P.add(Point.BASE.multiply(t));
96
+ return Q.toHex(true);
97
+ }
53
98
  static generateWallet(network = networks.bitcoin) {
54
99
  const keyPair = this.ECPair.makeRandom({
55
100
  network: network,
@@ -61,19 +106,36 @@ export class EcKeyPair {
61
106
  return {
62
107
  address: wallet,
63
108
  privateKey: keyPair.toWIF(),
64
- publicKey: keyPair.publicKey.toString('hex'),
109
+ publicKey: Buffer.from(keyPair.publicKey).toString('hex'),
65
110
  };
66
111
  }
67
112
  static verifyContractAddress(contractAddress, network = networks.bitcoin) {
68
113
  return !!address.toOutputScript(contractAddress, network);
69
114
  }
115
+ static getLegacySegwitAddress(keyPair, network = networks.bitcoin) {
116
+ const wallet = payments.p2sh({
117
+ redeem: payments.p2wpkh({ pubkey: Buffer.from(keyPair.publicKey), network: network }),
118
+ network: network,
119
+ });
120
+ if (!wallet.address) {
121
+ throw new Error('Failed to generate wallet');
122
+ }
123
+ return wallet.address;
124
+ }
70
125
  static getLegacyAddress(keyPair, network = networks.bitcoin) {
71
- const wallet = payments.p2pkh({ pubkey: keyPair.publicKey, network: network });
126
+ const wallet = payments.p2pkh({ pubkey: Buffer.from(keyPair.publicKey), network: network });
72
127
  if (!wallet.address) {
73
128
  throw new Error('Failed to generate wallet');
74
129
  }
75
130
  return wallet.address;
76
131
  }
132
+ static getP2PKAddress(keyPair, network = networks.bitcoin) {
133
+ const wallet = payments.p2pk({ pubkey: Buffer.from(keyPair.publicKey), network: network });
134
+ if (!wallet.output) {
135
+ throw new Error('Failed to generate wallet');
136
+ }
137
+ return '0x' + wallet.output.toString('hex');
138
+ }
77
139
  static generateRandomKeyPair(network = networks.bitcoin) {
78
140
  return this.ECPair.makeRandom({
79
141
  network: network,
@@ -84,7 +146,7 @@ export class EcKeyPair {
84
146
  }
85
147
  static getTaprootAddress(keyPair, network = networks.bitcoin) {
86
148
  const { address } = payments.p2tr({
87
- internalPubkey: toXOnly(keyPair.publicKey),
149
+ internalPubkey: toXOnly(Buffer.from(keyPair.publicKey)),
88
150
  network: network,
89
151
  });
90
152
  if (!address) {
@@ -8,6 +8,7 @@ export declare class Wallet {
8
8
  private readonly _p2wpkh;
9
9
  private readonly _p2tr;
10
10
  private readonly _legacy;
11
+ private readonly _bufferPubKey;
11
12
  constructor(wallet: IWallet, network?: Network);
12
13
  get keypair(): ECPairInterface;
13
14
  get p2wpkh(): Address;
@@ -8,6 +8,7 @@ export class Wallet {
8
8
  this._p2wpkh = EcKeyPair.getP2WPKHAddress(this._keypair, this.network);
9
9
  this._p2tr = EcKeyPair.getTaprootAddress(this._keypair, this.network);
10
10
  this._legacy = EcKeyPair.getLegacyAddress(this._keypair, this.network);
11
+ this._bufferPubKey = Buffer.from(wallet.publicKey, 'hex');
11
12
  }
12
13
  get keypair() {
13
14
  if (!this._keypair)
@@ -27,14 +28,14 @@ export class Wallet {
27
28
  return [this.p2wpkh, this.p2tr, this.legacy];
28
29
  }
29
30
  get publicKey() {
30
- if (!this.keypair)
31
- throw new Error('Keypair not set');
32
- return this.keypair.publicKey;
31
+ if (!this._bufferPubKey)
32
+ throw new Error('Public key not set');
33
+ return this._bufferPubKey;
33
34
  }
34
35
  get xOnly() {
35
36
  if (!this.keypair)
36
37
  throw new Error('Keypair not set');
37
- return toXOnly(this.keypair.publicKey);
38
+ return toXOnly(this._bufferPubKey);
38
39
  }
39
40
  static fromWif(wif, network = networks.bitcoin) {
40
41
  return new Wallet({ privateKey: wif, address: '', publicKey: '' }, network);
@@ -1,9 +1,9 @@
1
- import { Network, Signer } from 'bitcoinjs-lib';
1
+ import { Network } from 'bitcoinjs-lib';
2
2
  import { ECPairInterface } from 'ecpair';
3
3
  export interface TweakSettings {
4
4
  readonly network?: Network;
5
5
  tweakHash?: Buffer;
6
6
  }
7
7
  export declare class TweakedSigner {
8
- static tweakSigner(signer: ECPairInterface, opts?: TweakSettings): Signer;
8
+ static tweakSigner(signer: ECPairInterface, opts?: TweakSettings): ECPairInterface;
9
9
  }
@@ -13,7 +13,7 @@ export class TweakedSigner {
13
13
  if (signer.publicKey[0] === 3) {
14
14
  privateKey = ecc.privateNegate(privateKey);
15
15
  }
16
- const tweakedPrivateKey = ecc.privateAdd(privateKey, tapTweakHash(toXOnly(signer.publicKey), opts.tweakHash));
16
+ const tweakedPrivateKey = ecc.privateAdd(privateKey, tapTweakHash(toXOnly(Buffer.from(signer.publicKey)), opts.tweakHash));
17
17
  if (!tweakedPrivateKey) {
18
18
  throw new Error('Invalid tweaked private key!');
19
19
  }