@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.
- package/browser/_version.d.ts +1 -1
- package/browser/generators/Generator.d.ts +2 -0
- package/browser/index.js +1 -1
- package/browser/keypair/AddressVerificator.d.ts +15 -3
- package/browser/keypair/EcKeyPair.d.ts +9 -4
- package/browser/keypair/Wallet.d.ts +1 -0
- package/browser/signer/TweakedSigner.d.ts +2 -2
- package/browser/transaction/builders/FundingTransaction.d.ts +2 -1
- package/browser/transaction/builders/MultiSignTransaction.d.ts +2 -1
- package/browser/transaction/builders/SharedInteractionTransaction.d.ts +1 -1
- package/browser/transaction/builders/TransactionBuilder.d.ts +3 -2
- package/browser/transaction/shared/TweakedTransaction.d.ts +8 -7
- package/browser/verification/TapscriptVerificator.d.ts +1 -1
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/generators/Generator.d.ts +2 -0
- package/build/generators/Generator.js +5 -0
- package/build/generators/builders/CalldataGenerator.js +4 -2
- package/build/generators/builders/DeploymentGenerator.js +7 -4
- package/build/keypair/AddressVerificator.d.ts +15 -3
- package/build/keypair/AddressVerificator.js +74 -3
- package/build/keypair/EcKeyPair.d.ts +9 -4
- package/build/keypair/EcKeyPair.js +69 -7
- package/build/keypair/Wallet.d.ts +1 -0
- package/build/keypair/Wallet.js +5 -4
- package/build/signer/TweakedSigner.d.ts +2 -2
- package/build/signer/TweakedSigner.js +1 -1
- package/build/transaction/builders/CustomScriptTransaction.js +3 -3
- package/build/transaction/builders/DeploymentTransaction.js +4 -4
- package/build/transaction/builders/FundingTransaction.d.ts +2 -1
- package/build/transaction/builders/FundingTransaction.js +18 -4
- package/build/transaction/builders/MultiSignTransaction.d.ts +2 -1
- package/build/transaction/builders/SharedInteractionTransaction.d.ts +1 -1
- package/build/transaction/builders/SharedInteractionTransaction.js +4 -4
- package/build/transaction/builders/TransactionBuilder.d.ts +3 -2
- package/build/transaction/builders/TransactionBuilder.js +7 -2
- package/build/transaction/builders/UnwrapTransaction.js +2 -2
- package/build/transaction/shared/TweakedTransaction.d.ts +8 -7
- package/build/transaction/shared/TweakedTransaction.js +1 -1
- package/build/verification/TapscriptVerificator.d.ts +1 -1
- package/build/verification/TapscriptVerificator.js +2 -2
- package/package.json +2 -1
- package/src/_version.ts +1 -1
- package/src/generators/Generator.ts +12 -0
- package/src/generators/builders/CalldataGenerator.ts +6 -3
- package/src/generators/builders/DeploymentGenerator.ts +9 -4
- package/src/keypair/AddressVerificator.ts +144 -5
- package/src/keypair/EcKeyPair.ts +149 -13
- package/src/keypair/Wallet.ts +11 -3
- package/src/signer/TweakedSigner.ts +3 -2
- package/src/transaction/builders/CustomScriptTransaction.ts +6 -5
- package/src/transaction/builders/DeploymentTransaction.ts +6 -5
- package/src/transaction/builders/FundingTransaction.ts +18 -5
- package/src/transaction/builders/MultiSignTransaction.ts +6 -2
- package/src/transaction/builders/SharedInteractionTransaction.ts +5 -5
- package/src/transaction/builders/TransactionBuilder.ts +36 -10
- package/src/transaction/builders/UnwrapSegwitTransaction.ts +7 -3
- package/src/transaction/builders/UnwrapTransaction.ts +2 -2
- package/src/transaction/builders/WrapTransaction.ts +1 -6
- package/src/transaction/shared/TweakedTransaction.ts +12 -12
- package/src/verification/TapscriptVerificator.ts +3 -3
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
import {
|
|
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:
|
|
5
|
-
static
|
|
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
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Network
|
|
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):
|
|
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?:
|
|
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):
|
|
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
|
|
4
|
+
readonly deployerPubKey: Buffer;
|
|
5
5
|
readonly contractSaltPubKey: Buffer;
|
|
6
6
|
readonly originalSalt: Buffer;
|
|
7
7
|
readonly bytecode: Buffer;
|
package/build/_version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "1.0.
|
|
1
|
+
export declare const version = "1.0.113";
|
package/build/_version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.0.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
22
|
-
this.
|
|
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.
|
|
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
|
-
]
|
|
46
|
+
];
|
|
47
|
+
return compiledData.flat();
|
|
45
48
|
}
|
|
46
49
|
}
|
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
import {
|
|
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:
|
|
5
|
-
static
|
|
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
|
|
25
|
+
catch { }
|
|
15
26
|
return isValidTapRootAddress;
|
|
16
27
|
}
|
|
17
|
-
static
|
|
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
|
|
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
|
-
|
|
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) {
|
package/build/keypair/Wallet.js
CHANGED
|
@@ -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.
|
|
31
|
-
throw new Error('
|
|
32
|
-
return this.
|
|
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.
|
|
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
|
|
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):
|
|
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
|
}
|