@exodus/bip322-js 3.2.1 → 3.2.2
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/CHANGELOG.md +6 -0
- package/dist/Address.d.ts +1 -1
- package/dist/BIP322.d.ts +1 -1
- package/dist/Signer.d.ts +2 -3
- package/dist/Signer.js +2 -2
- package/dist/Verifier.d.ts +1 -4
- package/dist/Verifier.js +10 -11
- package/dist/bitcoinjs-message-verify.d.ts +1 -1
- package/dist/helpers/BIP137.d.ts +2 -2
- package/dist/helpers/BIP137.js +3 -3
- package/package.json +9 -8
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [3.2.2](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/bip322-js@3.2.1...@exodus/bip322-js@3.2.2) (2026-06-29)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **bip322-js:** BIP137 segwit-flag signature verification ([#16085](https://github.com/ExodusMovement/exodus-hydra/issues/16085)) ([9363135](https://github.com/ExodusMovement/exodus-hydra/commit/9363135c13cef1a7b632d133adddb4fde8a28f04))
|
|
11
|
+
|
|
6
12
|
## [3.2.1](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/bip322-js@3.2.0...@exodus/bip322-js@3.2.1) (2026-04-22)
|
|
7
13
|
|
|
8
14
|
### Bug Fixes
|
package/dist/Address.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ declare class Address {
|
|
|
5
5
|
static isP2TR(address: string): boolean;
|
|
6
6
|
static isP2WPKHWitness(witness: Buffer[]): boolean;
|
|
7
7
|
static isSingleKeyP2TRWitness(witness: Buffer[]): boolean;
|
|
8
|
-
static convertAdressToScriptPubkey(address: string): Buffer
|
|
8
|
+
static convertAdressToScriptPubkey(address: string): Buffer<ArrayBufferLike>;
|
|
9
9
|
static convertPubKeyIntoAddress(publicKey: Buffer, addressType: 'p2pkh' | 'p2sh-p2wpkh' | 'p2wpkh' | 'p2tr'): {
|
|
10
10
|
mainnet: string | undefined;
|
|
11
11
|
testnet: string | undefined;
|
package/dist/BIP322.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as bitcoin from '@exodus/bitcoinjs';
|
|
2
2
|
declare class BIP322 {
|
|
3
|
-
static TAG: Buffer
|
|
3
|
+
static TAG: Buffer<ArrayBuffer>;
|
|
4
4
|
static hashMessage(message: string): any;
|
|
5
5
|
static buildToSpendTx(message: string, scriptPublicKey: Buffer): bitcoin.Transaction;
|
|
6
6
|
static buildToSignTx(toSpendTxId: string, witnessScript: Buffer, isRedeemScript?: boolean, tapInternalKey?: Buffer): bitcoin.Psbt;
|
package/dist/Signer.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as bitcoin from '@exodus/bitcoinjs';
|
|
2
|
-
import type { Signer as AssetSigner } from '@exodus/asset-types
|
|
2
|
+
import type { Signer as AssetSigner } from '@exodus/asset-types';
|
|
3
3
|
export declare const createSigner: (encodedKey: string | Buffer, network: bitcoin.Network) => {
|
|
4
4
|
signer: {
|
|
5
5
|
getPublicKey: () => Promise<any>;
|
|
@@ -15,7 +15,6 @@ export declare const createSigner: (encodedKey: string | Buffer, network: bitcoi
|
|
|
15
15
|
};
|
|
16
16
|
declare class Signer {
|
|
17
17
|
#private;
|
|
18
|
-
static signAsync(signerOrKey: string | Buffer | AssetSigner, address: string, message: string, network?: bitcoin.Network): Promise<
|
|
19
|
-
private static checkPubKeyCorrespondToAddress;
|
|
18
|
+
static signAsync(signerOrKey: string | Buffer | AssetSigner, address: string, message: string, network?: bitcoin.Network): Promise<string | Buffer<ArrayBufferLike>>;
|
|
20
19
|
}
|
|
21
20
|
export default Signer;
|
package/dist/Signer.js
CHANGED
|
@@ -63,7 +63,7 @@ class Signer {
|
|
|
63
63
|
}
|
|
64
64
|
static async #signAsyncInternal(signer, address, message, network = bitcoin.networks.bitcoin, compressed) {
|
|
65
65
|
const publicKey = await signer.getPublicKey();
|
|
66
|
-
assert(this
|
|
66
|
+
assert(this.#checkPubKeyCorrespondToAddress(publicKey, address), `Invalid signer for address "${address}".`);
|
|
67
67
|
if (Address.isP2PKH(address)) {
|
|
68
68
|
const asyncSigner = {
|
|
69
69
|
sign(hash, extraEntropy) {
|
|
@@ -103,7 +103,7 @@ class Signer {
|
|
|
103
103
|
]);
|
|
104
104
|
return BIP322.encodeWitness(toSignTx.finalizeAllInputs());
|
|
105
105
|
}
|
|
106
|
-
static checkPubKeyCorrespondToAddress(publicKey, claimedAddress) {
|
|
106
|
+
static #checkPubKeyCorrespondToAddress(publicKey, claimedAddress) {
|
|
107
107
|
let derivedAddresses;
|
|
108
108
|
if (Address.isP2PKH(claimedAddress)) {
|
|
109
109
|
derivedAddresses = Address.convertPubKeyIntoAddress(publicKey, 'p2pkh');
|
package/dist/Verifier.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
declare class Verifier {
|
|
2
|
+
#private;
|
|
2
3
|
static verifySignature(signerAddress: string, message: string, signature: Buffer): Promise<boolean>;
|
|
3
|
-
private static verifyBIP137Signature;
|
|
4
|
-
private static getHashForSigP2WPKH;
|
|
5
|
-
private static getHashForSigP2SHInP2WPKH;
|
|
6
|
-
private static getHashForSigP2TR;
|
|
7
4
|
}
|
|
8
5
|
export default Verifier;
|
package/dist/Verifier.js
CHANGED
|
@@ -11,7 +11,7 @@ class Verifier {
|
|
|
11
11
|
throw new TypeError('signature must be a Buffer');
|
|
12
12
|
}
|
|
13
13
|
if (Address.isP2PKH(signerAddress) || BIP137.isBIP137Signature(signature)) {
|
|
14
|
-
return this
|
|
14
|
+
return this.#verifyBIP137Signature(signerAddress, message, signature);
|
|
15
15
|
}
|
|
16
16
|
const scriptPubKey = Address.convertAdressToScriptPubkey(signerAddress);
|
|
17
17
|
const toSpendTx = BIP322.buildToSpendTx(message, scriptPubKey);
|
|
@@ -27,7 +27,7 @@ class Verifier {
|
|
|
27
27
|
const hashedPubkey = bitcoin.crypto.hash160(publicKey);
|
|
28
28
|
let hashToSign;
|
|
29
29
|
if (Address.isP2SH(signerAddress)) {
|
|
30
|
-
hashToSign = this
|
|
30
|
+
hashToSign = this.#getHashForSigP2SHInP2WPKH(toSignTx, hashedPubkey);
|
|
31
31
|
const lockingScript = Buffer.concat([Buffer.from([0x00, 0x14]), hashedPubkey]);
|
|
32
32
|
const hashedLockingScript = bitcoin.crypto.hash160(lockingScript);
|
|
33
33
|
const hashedLockingScriptInScriptPubKey = scriptPubKey.subarray(2, -1);
|
|
@@ -36,7 +36,7 @@ class Verifier {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
else {
|
|
39
|
-
hashToSign = this
|
|
39
|
+
hashToSign = this.#getHashForSigP2WPKH(toSignTx);
|
|
40
40
|
const hashedPubkeyInScriptPubkey = scriptPubKey.subarray(2);
|
|
41
41
|
if (Buffer.compare(hashedPubkey, hashedPubkeyInScriptPubkey) !== 0) {
|
|
42
42
|
return false;
|
|
@@ -52,11 +52,11 @@ class Verifier {
|
|
|
52
52
|
let hashToSign;
|
|
53
53
|
let signature;
|
|
54
54
|
if (encodedSignature.byteLength === 64) {
|
|
55
|
-
hashToSign = this
|
|
55
|
+
hashToSign = this.#getHashForSigP2TR(toSignTx, 0x00);
|
|
56
56
|
signature = encodedSignature;
|
|
57
57
|
}
|
|
58
58
|
else if (encodedSignature.byteLength === 65) {
|
|
59
|
-
hashToSign = this
|
|
59
|
+
hashToSign = this.#getHashForSigP2TR(toSignTx, encodedSignature[64]);
|
|
60
60
|
signature = encodedSignature.subarray(0, -1);
|
|
61
61
|
}
|
|
62
62
|
else {
|
|
@@ -66,12 +66,11 @@ class Verifier {
|
|
|
66
66
|
}
|
|
67
67
|
throw new Error('Only P2WPKH, P2SH-P2WPKH, and single-key-spend P2TR BIP-322 verification is supported. Unsupported address is provided.');
|
|
68
68
|
}
|
|
69
|
-
static verifyBIP137Signature(signerAddress, message, signature) {
|
|
69
|
+
static #verifyBIP137Signature(signerAddress, message, signature) {
|
|
70
70
|
if (Address.isP2PKH(signerAddress)) {
|
|
71
71
|
return bitcoinMessage.verify(message, signerAddress, signature);
|
|
72
72
|
}
|
|
73
73
|
const publicKeySigned = BIP137.derivePubKey(message, signature);
|
|
74
|
-
const legacySigningAddress = Address.convertPubKeyIntoAddress(publicKeySigned, 'p2pkh').mainnet;
|
|
75
74
|
if (Address.isP2SH(signerAddress)) {
|
|
76
75
|
const p2shAddressDerived = Address.convertPubKeyIntoAddress(publicKeySigned, 'p2sh-p2wpkh');
|
|
77
76
|
if (p2shAddressDerived.mainnet !== signerAddress &&
|
|
@@ -96,9 +95,9 @@ class Verifier {
|
|
|
96
95
|
else {
|
|
97
96
|
return false;
|
|
98
97
|
}
|
|
99
|
-
return
|
|
98
|
+
return true;
|
|
100
99
|
}
|
|
101
|
-
static getHashForSigP2WPKH(toSignTx) {
|
|
100
|
+
static #getHashForSigP2WPKH(toSignTx) {
|
|
102
101
|
const signingScript = bitcoin.payments.p2pkh({
|
|
103
102
|
hash: toSignTx.data.inputs[0].witnessUtxo.script.subarray(2),
|
|
104
103
|
}).output;
|
|
@@ -106,7 +105,7 @@ class Verifier {
|
|
|
106
105
|
.extractTransaction()
|
|
107
106
|
.hashForWitnessV0(0, signingScript, 0, bitcoin.Transaction.SIGHASH_ALL);
|
|
108
107
|
}
|
|
109
|
-
static getHashForSigP2SHInP2WPKH(toSignTx, hashedPubkey) {
|
|
108
|
+
static #getHashForSigP2SHInP2WPKH(toSignTx, hashedPubkey) {
|
|
110
109
|
const signingScript = bitcoin.payments.p2pkh({
|
|
111
110
|
hash: hashedPubkey,
|
|
112
111
|
}).output;
|
|
@@ -114,7 +113,7 @@ class Verifier {
|
|
|
114
113
|
.extractTransaction()
|
|
115
114
|
.hashForWitnessV0(0, signingScript, 0, bitcoin.Transaction.SIGHASH_ALL);
|
|
116
115
|
}
|
|
117
|
-
static getHashForSigP2TR(toSignTx, hashType) {
|
|
116
|
+
static #getHashForSigP2TR(toSignTx, hashType) {
|
|
118
117
|
if (hashType !== bitcoin.Transaction.SIGHASH_DEFAULT &&
|
|
119
118
|
hashType !== bitcoin.Transaction.SIGHASH_ALL) {
|
|
120
119
|
throw new Error('Invalid SIGHASH used in signature. Must be either SIGHASH_ALL or SIGHASH_DEFAULT.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function verify(message: string, address: string, signature: Buffer, messagePrefix?: string, checkSegwitAlways?: boolean): boolean;
|
|
1
|
+
export declare function verify(message: string, address: string, signature: Buffer | string, messagePrefix?: string, checkSegwitAlways?: boolean): boolean;
|
package/dist/helpers/BIP137.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
declare class BIP137 {
|
|
2
|
+
#private;
|
|
2
3
|
static isBIP137Signature(signature: Buffer): boolean;
|
|
3
|
-
static derivePubKey(message: string, signature: Buffer): Buffer
|
|
4
|
-
private static decodeSignature;
|
|
4
|
+
static derivePubKey(message: string, signature: Buffer): Buffer<ArrayBuffer>;
|
|
5
5
|
}
|
|
6
6
|
export default BIP137;
|
package/dist/helpers/BIP137.js
CHANGED
|
@@ -6,15 +6,15 @@ class BIP137 {
|
|
|
6
6
|
}
|
|
7
7
|
static derivePubKey(message, signature) {
|
|
8
8
|
const messageHash = bitcoinMessage.magicHash(message);
|
|
9
|
-
const signatureDecoded = this
|
|
9
|
+
const signatureDecoded = this.#decodeSignature(signature);
|
|
10
10
|
const recoveredPublicKey = recoverPublicKey(messageHash, signatureDecoded.signature, signatureDecoded.recovery, signatureDecoded.compressed);
|
|
11
11
|
return Buffer.from(recoveredPublicKey);
|
|
12
12
|
}
|
|
13
|
-
static decodeSignature(signature) {
|
|
13
|
+
static #decodeSignature(signature) {
|
|
14
14
|
if (signature.length !== 65)
|
|
15
15
|
throw new Error('Invalid signature length');
|
|
16
16
|
const flagByte = signature.readUInt8(0) - 27;
|
|
17
|
-
if (flagByte >
|
|
17
|
+
if (flagByte > 15 || flagByte < 0) {
|
|
18
18
|
throw new Error('Invalid signature parameter');
|
|
19
19
|
}
|
|
20
20
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/bip322-js",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.2",
|
|
4
4
|
"description": "A Javascript library that provides utility functions related to the BIP-322 signature scheme",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -15,12 +15,13 @@
|
|
|
15
15
|
"!**/__tests__/**"
|
|
16
16
|
],
|
|
17
17
|
"scripts": {
|
|
18
|
-
"build": "
|
|
19
|
-
"lint": "
|
|
20
|
-
"lint:fix": "
|
|
18
|
+
"build": "pnpm exec tsc -p tsconfig.build.json",
|
|
19
|
+
"lint": "pnpm exec eslint",
|
|
20
|
+
"lint:fix": "pnpm run lint --fix",
|
|
21
21
|
"doc": "typedoc src/index.ts",
|
|
22
|
-
"test": "
|
|
23
|
-
"
|
|
22
|
+
"test": "pnpm exec exodus-test --jest --esbuild",
|
|
23
|
+
"typecheck": "pnpm exec tsc -p tsconfig.json --noEmit",
|
|
24
|
+
"prepublishOnly": "pnpm -w run build --scope @exodus/bip322-js"
|
|
24
25
|
},
|
|
25
26
|
"keywords": [
|
|
26
27
|
"bip322",
|
|
@@ -37,7 +38,7 @@
|
|
|
37
38
|
"license": "MIT",
|
|
38
39
|
"devDependencies": {
|
|
39
40
|
"@types/minimalistic-assert": "^1.0.1",
|
|
40
|
-
"@types/node": "^
|
|
41
|
+
"@types/node": "^22.7.4",
|
|
41
42
|
"ecpair": "^2.0.1",
|
|
42
43
|
"typedoc": "^0.24.8",
|
|
43
44
|
"typescript": "^5.1.3"
|
|
@@ -57,5 +58,5 @@
|
|
|
57
58
|
"bugs": {
|
|
58
59
|
"url": "https://github.com/ExodusMovement/exodus-hydra/issues?q=is%3Aissue+is%3Aopen+label%3Abip322-js"
|
|
59
60
|
},
|
|
60
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "8c91cf6b4dc913de523a9cc7dbb56ff871fefb14"
|
|
61
62
|
}
|