@notabene/verify-proof 1.8.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +1 -1
- package/dist/index.modern.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/bitcoin.ts +30 -6
- package/src/tests/bitcoin.test.ts +30 -0
package/package.json
CHANGED
package/src/bitcoin.ts
CHANGED
@@ -117,7 +117,6 @@ export async function verifyBTCSignature(
|
|
117
117
|
status: ProofStatus.FAILED,
|
118
118
|
};
|
119
119
|
}
|
120
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
121
120
|
} catch (error) {
|
122
121
|
console.error("error verifying proof", error);
|
123
122
|
return {
|
@@ -169,10 +168,16 @@ function verifyBIP322(address: string, proof: SignatureProof) {
|
|
169
168
|
}
|
170
169
|
|
171
170
|
function verifyBIP137(address: string, proof: SignatureProof, chainConfig: ChainConfig) {
|
172
|
-
const
|
173
|
-
|
174
|
-
)
|
175
|
-
|
171
|
+
const derivationMode = getDerivationMode(address);
|
172
|
+
|
173
|
+
// For legacy addresses (starting with "1"), never use SegWit encoding
|
174
|
+
// For P2SH addresses (starting with "3"), use SegWit encoding if they have bech32 support
|
175
|
+
// For native SegWit addresses (bc1, tb1, ltc1), always use SegWit encoding
|
176
|
+
const useSegwitEncoding = Boolean(chainConfig.bech32Prefix &&
|
177
|
+
(derivationMode === DerivationMode.NATIVE ||
|
178
|
+
(derivationMode === DerivationMode.SEGWIT && !address.startsWith("1"))));
|
179
|
+
|
180
|
+
const verified = verify(proof.attestation, address, proof.proof, useSegwitEncoding, chainConfig);
|
176
181
|
|
177
182
|
return {
|
178
183
|
...proof,
|
@@ -191,6 +196,10 @@ function getDerivationMode(address: string) {
|
|
191
196
|
return DerivationMode.DOGECOIN;
|
192
197
|
} else if (address.match("^(q).*")) {
|
193
198
|
return DerivationMode.BCH;
|
199
|
+
} else if (address.match("^(t1|t3).*")) {
|
200
|
+
return DerivationMode.LEGACY; // Zcash addresses
|
201
|
+
} else if (address.match("^[X7].*")) {
|
202
|
+
return DerivationMode.LEGACY; // Dash addresses
|
194
203
|
} else {
|
195
204
|
throw new Error(
|
196
205
|
"INVALID ADDRESS: "
|
@@ -271,7 +280,22 @@ function verify(
|
|
271
280
|
}
|
272
281
|
}
|
273
282
|
} else {
|
274
|
-
|
283
|
+
// For addresses starting with "3" (P2SH), try both P2SH-P2WPKH and legacy P2SH encodings if segwitType is undefined
|
284
|
+
if (address.startsWith("3") && !segwitType) {
|
285
|
+
// P2SH-P2WPKH: script hash of the redeem script (OP_0 <pubkeyhash>)
|
286
|
+
const redeemScript = new Uint8Array(22);
|
287
|
+
redeemScript[0] = 0x00; // OP_0
|
288
|
+
redeemScript[1] = 0x14; // push 20 bytes
|
289
|
+
redeemScript.set(publicKeyHash, 2);
|
290
|
+
const redeemScriptHash = hash160(redeemScript);
|
291
|
+
const p2shP2wpkh = encodeBase58AddressFormat(chainConfig.scriptHashVersion, redeemScriptHash);
|
292
|
+
// Legacy P2SH: script hash of the public key
|
293
|
+
const legacyP2sh = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);
|
294
|
+
if (address === p2shP2wpkh || address === legacyP2sh) {
|
295
|
+
return true;
|
296
|
+
}
|
297
|
+
actual = legacyP2sh; // fallback for error reporting
|
298
|
+
} else if (checkSegwitAlways && chainConfig.bech32Prefix) {
|
275
299
|
try {
|
276
300
|
actual = encodeBech32Address(publicKeyHash, chainConfig.bech32Prefix);
|
277
301
|
// if address is bech32 it is not p2sh
|
@@ -7,6 +7,26 @@ import {
|
|
7
7
|
ProofTypes,
|
8
8
|
} from "@notabene/javascript-sdk";
|
9
9
|
|
10
|
+
const bitcoinP2WPKHProof: SignatureProof = {
|
11
|
+
type: ProofTypes.BIP137,
|
12
|
+
wallet_provider: "Manual Wallet Signature",
|
13
|
+
status: ProofStatus.PENDING,
|
14
|
+
address: "bip122:000000000019d6689c085ae165831e93:3Q9jfjfbMDuatto7wZ6Tz2aKaDCRHqWWys",
|
15
|
+
did: "did:pkh:bip122:000000000019d6689c085ae165831e93:3Q9jfjfbMDuatto7wZ6Tz2aKaDCRHqWWys",
|
16
|
+
attestation: "I certify that the blockchain address 3Q9jfjfbMDuatto7wZ6Tz2aKaDCRHqWWys belongs to did:pkh:bip122:000000000019d6689c085ae165831e93:3Q9jfjfbMDuatto7wZ6Tz2aKaDCRHqWWys on Wed, 09 Jul 2025 20:17:12 GMT",
|
17
|
+
proof: "HxPmbzvEnvgu0RYIPYl5bWySkFNXwOF/Jegq3NvzjFZ/Ik/koTdV9rh2A7osXefhzTlniUw8YbZNmCeXB9V9qC8=",
|
18
|
+
}
|
19
|
+
|
20
|
+
const bitcoinP2shProof: SignatureProof = {
|
21
|
+
type: ProofTypes.BIP137,
|
22
|
+
wallet_provider: "Manual Wallet Signature",
|
23
|
+
status: ProofStatus.PENDING,
|
24
|
+
address: "bip122:000000000019d6689c085ae165831e93:1ANiqVALaKwadxA9nvmCUHpBhaopVniuVS",
|
25
|
+
did: "did:pkh:bip122:000000000019d6689c085ae165831e93:1ANiqVALaKwadxA9nvmCUHpBhaopVniuVS",
|
26
|
+
attestation: "I certify that the blockchain address 1ANiqVALaKwadxA9nvmCUHpBhaopVniuVS belongs to did:pkh:bip122:000000000019d6689c085ae165831e93:1ANiqVALaKwadxA9nvmCUHpBhaopVniuVS on Wed, 02 Jul 2025 16:01:44 GMT",
|
27
|
+
proof: "IBo2Im6O5NyuXzBJ+coiTMqmUsqG9bv8NzM3+B5e+5XMB2Xp1n/sIsE/73Jy0EdSvcb334t49+3tdjE/X+sXjFw="
|
28
|
+
}
|
29
|
+
|
10
30
|
const bip322SegwitTestnetProof: SignatureProof = {
|
11
31
|
type: ProofTypes.BIP137,
|
12
32
|
address: "bip122:000000000019d6689c085ae165831e93:tb1q0apvgsh48f3rmw224na3ye5rrg37fd796cm0xf",
|
@@ -89,6 +109,16 @@ const zcashProof: SignatureProof = {
|
|
89
109
|
};
|
90
110
|
|
91
111
|
describe("verifyBTCSignature", () => {
|
112
|
+
it("handles bitcoin p2sh addresses", async () => {
|
113
|
+
const result = await verifyBTCSignature(bitcoinP2shProof);
|
114
|
+
expect(result).toEqual({ ...bitcoinP2shProof, status: ProofStatus.VERIFIED });
|
115
|
+
});
|
116
|
+
|
117
|
+
it("handles bitcoin p2wpkh addresses", async () => {
|
118
|
+
const result = await verifyBTCSignature(bitcoinP2WPKHProof);
|
119
|
+
expect(result).toEqual({ ...bitcoinP2WPKHProof, status: ProofStatus.VERIFIED });
|
120
|
+
});
|
121
|
+
|
92
122
|
it("handles bip322 segwit testnet addresses", async () => {
|
93
123
|
const result = await verifyBTCSignature(bip322SegwitTestnetProof);
|
94
124
|
expect(result).toEqual({
|