@notabene/verify-proof 1.4.0 → 1.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@notabene/verify-proof",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "description": "Verify ownership proofs",
5
5
  "source": "src/index.ts",
6
6
  "type": "module",
package/src/bitcoin.ts CHANGED
@@ -21,6 +21,7 @@ interface ChainConfig {
21
21
  pubKeyHashVersion: number;
22
22
  scriptHashVersion: number;
23
23
  bech32Prefix?: string;
24
+ isTestnet?: boolean;
24
25
  }
25
26
 
26
27
  const CHAIN_CONFIGS: Record<string, ChainConfig> = {
@@ -28,28 +29,41 @@ const CHAIN_CONFIGS: Record<string, ChainConfig> = {
28
29
  messagePrefix: "\u0018Bitcoin Signed Message:\n",
29
30
  pubKeyHashVersion: 0x00, // 1...
30
31
  scriptHashVersion: 0x05, // 3...
31
- bech32Prefix: "bc"
32
+ bech32Prefix: "bc",
33
+ isTestnet: false,
32
34
  },
33
35
  bitcoincash: {
34
36
  messagePrefix: "\u0018Bitcoin Signed Message:\n",
35
37
  pubKeyHashVersion: 0x00, // 1...
36
38
  scriptHashVersion: 0x05, // 3...
39
+ bech32Prefix: "bc",
40
+ isTestnet: false,
37
41
  },
38
42
  litecoin: {
39
43
  messagePrefix: "\u0019Litecoin Signed Message:\n",
40
44
  pubKeyHashVersion: 0x30, // L... or M...
41
45
  scriptHashVersion: 0x32, // 3... or M...
42
- bech32Prefix: "ltc"
46
+ bech32Prefix: "ltc",
47
+ isTestnet: false,
43
48
  },
44
49
  dogecoin: {
45
50
  messagePrefix: "\u0019Dogecoin Signed Message:\n",
46
51
  pubKeyHashVersion: 0x1E, // D...
47
52
  scriptHashVersion: 0x16, // A...
53
+ isTestnet: false,
48
54
  },
49
55
  dash: {
50
56
  messagePrefix: "\u0019DarkCoin Signed Message:\n",
51
57
  pubKeyHashVersion: 0x4C, // X...
52
58
  scriptHashVersion: 0x10, // 7...
59
+ isTestnet: false,
60
+ },
61
+ testnet: {
62
+ messagePrefix: "\u0018Bitcoin Signed Message:\n",
63
+ pubKeyHashVersion: 0x6f, // m or n
64
+ scriptHashVersion: 0xc4, // 2
65
+ bech32Prefix: "tb",
66
+ isTestnet: true,
53
67
  },
54
68
  };
55
69
 
@@ -74,6 +88,11 @@ export async function verifyBTCSignature(
74
88
  const chainConfig = getChainConfig(address);
75
89
  if (!chainConfig) return { ...proof, status: ProofStatus.FAILED };
76
90
 
91
+ // Use BIP322 for testnet addresses
92
+ if (chainConfig.isTestnet) {
93
+ return verifyBIP322(address, proof);
94
+ }
95
+
77
96
  try {
78
97
  switch (proof.type) {
79
98
  case ProofTypes.BIP137:
@@ -88,7 +107,7 @@ export async function verifyBTCSignature(
88
107
  }
89
108
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
90
109
  } catch (error) {
91
- // console.error("error verifying proof", error);
110
+ console.error("error verifying proof", error);
92
111
  return {
93
112
  ...proof,
94
113
  status: ProofStatus.FAILED,
@@ -113,6 +132,9 @@ function getChainConfig(address: string): ChainConfig {
113
132
  if (address.startsWith("q")) {
114
133
  return CHAIN_CONFIGS["bitcoincash"];
115
134
  }
135
+ if (address.startsWith("tb1")) {
136
+ return CHAIN_CONFIGS["testnet"];
137
+ }
116
138
 
117
139
  return CHAIN_CONFIGS["bitcoin"];
118
140
  }
@@ -7,6 +7,16 @@ import {
7
7
  ProofTypes,
8
8
  } from "@notabene/javascript-sdk";
9
9
 
10
+ const bip322SegwitTestnetProof: SignatureProof = {
11
+ type: ProofTypes.BIP137,
12
+ address: "bip122:000000000019d6689c085ae165831e93:tb1q0apvgsh48f3rmw224na3ye5rrg37fd796cm0xf",
13
+ did: "did:pkh:bip122:000000000019d6689c085ae165831e93:tb1q0apvgsh48f3rmw224na3ye5rrg37fd796cm0xf",
14
+ attestation: "I certify that the blockchain address tb1q0apvgsh48f3rmw224na3ye5rrg37fd796cm0xf belongs to did:pkh:bip122:000000000019d6689c085ae165831e93:tb1q0apvgsh48f3rmw224na3ye5rrg37fd796cm0xf on Tue, 29 Apr 2025 15:33:26 GMT",
15
+ proof: "AkcwRAIgXzKIOGjVp8qrqpUM+e/2BkbITsbGpjTFxgfHjk/Bt+sCIGueO3l6/cvfZYSggu2F4WKj1K97p32NivFwKdOHg9cgASEDtJ0tfDgrGYO4OSuYjyiehIoY1dEUkPo8XZQJ3Yqo//8=",
16
+ status: ProofStatus.PENDING,
17
+ wallet_provider: "Manual Wallet Signature",
18
+ };
19
+
10
20
  const bip322SegwitProof: SignatureProof = {
11
21
  did: "did:pkh:bip122:000000000019d6689c085ae165831e93:bc1qcxm70pg5yk9c8pupj93uys5azw5xpt6qeu2z0u",
12
22
  status: ProofStatus.PENDING,
@@ -69,6 +79,13 @@ const dogeProof: SignatureProof = {
69
79
  };
70
80
 
71
81
  describe("verifyBTCSignature", () => {
82
+ it("handles bip322 segwit testnet addresses", async () => {
83
+ const result = await verifyBTCSignature(bip322SegwitTestnetProof);
84
+ expect(result).toEqual({
85
+ ...bip322SegwitTestnetProof,
86
+ status: ProofStatus.VERIFIED,
87
+ });
88
+ });
72
89
  it("handles bip322 segwit addresses", async () => {
73
90
  const result = await verifyBTCSignature(bip322SegwitProof);
74
91
  expect(result).toEqual({
@@ -136,6 +136,16 @@ describe("verifyProof", () => {
136
136
  });
137
137
 
138
138
  describe("bitcoin", () => {
139
+ const testnetProof: SignatureProof = {
140
+ type: ProofTypes.BIP137,
141
+ status: ProofStatus.PENDING,
142
+ did: "did:pkh:bip122:000000000019d6689c085ae165831e93:tb1q0apvgsh48f3rmw224na3ye5rrg37fd796cm0xf",
143
+ address: "bip122:000000000019d6689c085ae165831e93:tb1q0apvgsh48f3rmw224na3ye5rrg37fd796cm0xf",
144
+ proof: "AkcwRAIgZHktoWuDR5A1F8WFlm0v3dIGCVfokUWbeR7XbsH5JYECIH0AylmIg+zOeId0TXi6p++1BJSnc3n8EqnpnTd64T8EASEDtJ0tfDgrGYO4OSuYjyiehIoY1dEUkPo8XZQJ3Yqo//8=",
145
+ attestation: "I certify that the blockchain address tb1q0apvgsh48f3rmw224na3ye5rrg37fd796cm0xf belongs to did:pkh:bip122:000000000019d6689c085ae165831e93:tb1q0apvgsh48f3rmw224na3ye5rrg37fd796cm0xf on Tue, 29 Apr 2025 16:22:24 GMT",
146
+ wallet_provider: "Manual Wallet Signature",
147
+ };
148
+
139
149
  const proof: SignatureProof = {
140
150
  type: ProofTypes.BIP137,
141
151
  status: ProofStatus.PENDING,
@@ -160,6 +170,11 @@ describe("verifyProof", () => {
160
170
  wallet_provider: "Phantom (Wallet Connect)",
161
171
  type: ProofTypes.BIP322,
162
172
  };
173
+
174
+ it("should verify segwit testnet proof", async () => {
175
+ const result = await verifyProof(testnetProof);
176
+ expect(result.status).toBe(ProofStatus.VERIFIED);
177
+ });
163
178
 
164
179
  it("should verify proof", async () => {
165
180
  const result = await verifyProof(proof);
@@ -283,4 +298,31 @@ describe("verifyProof", () => {
283
298
  expect(result.status).toBe(ProofStatus.FAILED);
284
299
  });
285
300
  });
301
+
302
+ describe("SIWE", () => {
303
+ const proof: SignatureProof = {
304
+ address: "eip155:1:0xb5f28405d09746a20c7aa0399e5109f0c295b098",
305
+ attestation:
306
+ "localhost wants you to sign in with your **blockchain** account:\n0xb5f28405d09746a20c7aa0399e5109f0c295b098\n\nPlease sign this message to confirm your identity\n\nURI: http://localhost:8000\nVersion: 1\nChain ID: eip155:1\nNonce: 5389\nIssued At: 2025-05-22T09:28:38.992Z",
307
+ proof:
308
+ "0xf88efca56019b58d4523fa5b480fe549afd41d2d92a90e7b54126ca1d8a933fe4e5b3a507d1a2e9f28e6b9fab92d3fb288e946712903bbdafff4556694fc50f51b",
309
+ did: "did:pkh:eip155:1:0xb5f28405d09746a20c7aa0399e5109f0c295b098",
310
+ status: ProofStatus.PENDING,
311
+ type: ProofTypes.EIP191,
312
+ wallet_provider: "reown",
313
+ };
314
+
315
+ it("should verify proof", async () => {
316
+ const result = await verifyProof(proof);
317
+ expect(result.status).toBe(ProofStatus.VERIFIED);
318
+ });
319
+
320
+ it("should fail if not valid proof", async () => {
321
+ const result = await verifyProof({
322
+ ...proof,
323
+ proof: "0x",
324
+ } as SignatureProof);
325
+ expect(result.status).toBe(ProofStatus.FAILED);
326
+ });
327
+ });
286
328
  });