@neuraiproject/neurai-key 3.0.2 → 4.0.0

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/README.md CHANGED
@@ -5,7 +5,7 @@ Generate Neurai addresses from a mnemonic phrase following the standards BIP32,
5
5
  That is, use your 12 words to get addresses for Neurai mainnet and testnet.
6
6
 
7
7
  **NPM**: https://www.npmjs.com/package/@neuraiproject/neurai-key
8
- **CDN**: https://cdn.jsdelivr.net/npm/@neuraiproject/neurai-key@3.0.0/dist/NeuraiKey.global.js
8
+ **CDN**: https://cdn.jsdelivr.net/npm/@neuraiproject/neurai-key@4.0.0/dist/NeuraiKey.global.js
9
9
 
10
10
  ## Features
11
11
 
@@ -16,7 +16,22 @@ That is, use your 12 words to get addresses for Neurai mainnet and testnet.
16
16
  - ✅ Mainnet and Testnet support for Neurai (XNA)
17
17
  - ✅ Support for both XNA (BIP44: 1900) and XNA Legacy (BIP44: 0) networks
18
18
  - ✅ Convert raw public keys into Neurai mainnet or testnet addresses
19
- - ✅ PostQuantum AuthScript addresses using ML-DSA-44 (FIPS 204) with Bech32m encoding
19
+ - ✅ AuthScript witness v1 addresses with Bech32m encoding
20
+ - ✅ `authType = 0x00` NoAuth addresses from `witnessScript` only
21
+ - ✅ `authType = 0x01` PostQuantum ML-DSA-44 AuthScript addresses
22
+ - ✅ `authType = 0x02` Legacy secp256k1 AuthScript addresses
23
+
24
+ ## Compatibility Note
25
+
26
+ Starting in `4.0.0`, PQ HD derivation uses a native PQ tree (HMAC-SHA512 with `"Neurai PQ seed"`, all derivation levels hardened, path `m_pq/100'/coin'/0'/0'/index'`). The extended private key format is also updated (prefix `xpqp...` mainnet / `tpqp...` testnet, 74-byte padded layout matching BIP32 xprv length).
27
+
28
+ These are breaking changes versus `3.x`:
29
+ - PQ addresses produced from the same mnemonic will differ between `3.x` and `4.x`.
30
+ - PQ extended private keys exported by `3.x` (leading `DeG1...` / `Ck5n...`) are not readable by `4.x`.
31
+
32
+ If you have mnemonics from `3.x`, keep them — the mnemonic is the authoritative backup. Any funds on `3.x` PQ addresses should be moved before upgrading.
33
+
34
+ Since `3.1.0`, PQ AuthScript descriptors are computed as `0x01 || HASH160(0x05 || rawPublicKey)` to match `neurai-sign-transaction` and the node implementation.
20
35
 
21
36
  ## Network Types
22
37
 
@@ -24,12 +39,12 @@ This library supports three Neurai network configurations:
24
39
 
25
40
  - **`xna` / `xna-test`**: Current Neurai standard (BIP44 coin type: 1900)
26
41
  - **`xna-legacy` / `xna-legacy-test`**: Legacy Neurai addresses (BIP44 coin type: 0)
27
- - **`xna-pq` / `xna-pq-test`**: PostQuantum ML-DSA-44 AuthScript addresses (Bech32m, witness v1)
42
+ - **`xna-pq` / `xna-pq-test`**: AuthScript witness v1 addresses (Bech32m, `nq1` / `tnq1`)
28
43
 
29
44
  The main difference is the derivation path and address encoding:
30
45
  - **XNA**: mainnet `m/44'/1900'/0'/0/0`, testnet `m/44'/1'/0'/0/0` — Base58Check (recommended for new wallets)
31
46
  - **XNA Legacy**: mainnet `m/44'/0'/0'/0/0`, testnet `m/44'/1'/0'/0/0` — Base58Check (for compatibility with older wallets)
32
- - **XNA PostQuantum**: mainnet `m/100'/1900'/0'/0/0`, testnet default/external `m/100'/1'/0'/0/0` — Bech32m (`nq1` / `tnq1`)
47
+ - **XNA PostQuantum**: mainnet `m_pq/100'/1900'/0'/0'/0'`, testnet default/external `m_pq/100'/1'/0'/0'/0'` — Bech32m (`nq1` / `tnq1`), native PQ HD tree with hardened-only derivation
33
48
 
34
49
  **Note**: Using different network types will generate completely different addresses from the same mnemonic.
35
50
 
@@ -185,6 +200,14 @@ console.log(testAddress); // tPXGaMRNwZuV1UKSrD9gABPscrJWUmedQ9
185
200
 
186
201
  Generate quantum-resistant AuthScript addresses using the ML-DSA-44 signature scheme (FIPS 204). The library now follows the migrated `witness v1 = AuthScript` layout, so the Bech32m program is a 32-byte commitment instead of the old 20-byte PQ keyhash.
187
202
 
203
+ Supported AuthScript variants:
204
+
205
+ | `authType` | Name | Description |
206
+ |------------|------|-------------|
207
+ | `0x00` | NoAuth | No signature. Spend path depends only on `witnessScript` |
208
+ | `0x01` | PQ | ML-DSA-44 post-quantum signature |
209
+ | `0x02` | Legacy | secp256k1 signature inside the AuthScript framework |
210
+
188
211
  ### Generate a PQ address
189
212
 
190
213
  ```javascript
@@ -207,12 +230,12 @@ Outputs
207
230
  {
208
231
  address: 'nq1...', // Bech32m AuthScript address
209
232
  authType: 1, // 0x01 = PQ single-key auth
210
- authDescriptor: '01...', // 0x01 || HASH160(pq_pubkey)
233
+ authDescriptor: '01...', // 0x01 || HASH160(0x05 || pq_pubkey)
211
234
  commitment: '...', // tagged_hash("NeuraiAuthScript", ...)
212
- path: "m/100'/1900'/0'/0/0", // PQ derivation path
235
+ path: "m_pq/100'/1900'/0'/0'/0'", // PQ derivation path (native PQ tree, all hardened)
213
236
  publicKey: '...', // ML-DSA-44 public key (2624 hex chars = 1312 bytes)
214
237
  privateKey: '...', // ML-DSA-44 private key (5120 hex chars = 2560 bytes)
215
- seedKey: '...', // 32-byte BIP32 seed used for ML-DSA keygen (64 hex chars)
238
+ seedKey: '...', // 32-byte native PQ seed used for ML-DSA keygen (64 hex chars)
216
239
  witnessScript: '51' // default OP_TRUE script for simple PQ auth
217
240
  }
218
241
  ```
@@ -244,16 +267,111 @@ console.log(pqAddress.witnessScript); // 5151
244
267
  console.log(pqAddress.commitment); // new 32-byte commitment
245
268
  ```
246
269
 
247
- `authType` no es configurable en la API pública. Esta librería genera únicamente direcciones PQ simples con `authType = 0x01`.
270
+ `getPQAddress()` always generates `authType = 0x01` PQ addresses. Use `getNoAuthAddress()` for `0x00` and `getLegacyAuthScriptAddress()` / `getLegacyAuthScriptAddressByWIF()` for `0x02`.
271
+
272
+ ### Generate a NoAuth address
273
+
274
+ ```javascript
275
+ import NeuraiKey from "@neuraiproject/neurai-key";
276
+
277
+ const noAuth = NeuraiKey.getNoAuthAddress("xna-pq-test");
278
+
279
+ console.log(noAuth);
280
+ ```
281
+
282
+ Outputs
283
+
284
+ ```javascript
285
+ {
286
+ address: "tnq1...",
287
+ authType: 0,
288
+ commitment: "...",
289
+ witnessScript: "51"
290
+ }
291
+ ```
292
+
293
+ You can provide a custom `witnessScript`:
294
+
295
+ ```javascript
296
+ const noAuth = NeuraiKey.getNoAuthAddress("xna-pq-test", {
297
+ witnessScript: "527551"
298
+ });
299
+ ```
300
+
301
+ ### Generate a Legacy AuthScript address from mnemonic
302
+
303
+ This derives a normal secp256k1 key using the selected legacy/current HD network, then wraps it as an AuthScript address using the PQ Bech32m network.
304
+
305
+ ```javascript
306
+ import NeuraiKey from "@neuraiproject/neurai-key";
307
+
308
+ const mnemonic = "result pact model attract result puzzle final boss private educate luggage era";
309
+
310
+ const legacyAuth = NeuraiKey.getLegacyAuthScriptAddress(
311
+ "xna-pq-test",
312
+ "xna-test",
313
+ mnemonic,
314
+ 0,
315
+ 0
316
+ );
317
+
318
+ console.log(legacyAuth);
319
+ ```
320
+
321
+ Outputs
322
+
323
+ ```javascript
324
+ {
325
+ address: "tnq1...",
326
+ path: "m/44'/1'/0'/0/0",
327
+ publicKey: "...", // compressed secp256k1 pubkey
328
+ privateKey: "...",
329
+ WIF: "...",
330
+ authType: 2,
331
+ authDescriptor: "02...",
332
+ commitment: "...",
333
+ witnessScript: "51"
334
+ }
335
+ ```
336
+
337
+ ### Generate a Legacy AuthScript address from WIF
338
+
339
+ ```javascript
340
+ import NeuraiKey from "@neuraiproject/neurai-key";
341
+
342
+ const wif = "cVP9mzcDqMzWDhekiKMWKqEy739Cp6rKDT4tbG4wXXVfopMfTiBW";
343
+ const legacyAuth = NeuraiKey.getLegacyAuthScriptAddressByWIF("xna-pq-test", wif);
344
+
345
+ console.log(legacyAuth.address);
346
+ console.log(legacyAuth.publicKey);
347
+ ```
248
348
 
249
349
  ### Advanced: derive by path with HD key reuse
250
350
 
251
351
  ```javascript
252
352
  const hdKey = NeuraiKey.getPQHDKey("xna-pq", mnemonic);
253
- const addr0 = NeuraiKey.getPQAddressByPath("xna-pq", hdKey, "m/100'/1900'/0'/0/0");
254
- const addr1 = NeuraiKey.getPQAddressByPath("xna-pq", hdKey, "m/100'/1900'/0'/0/1");
353
+ const addr0 = NeuraiKey.getPQAddressByPath("xna-pq", hdKey, "m_pq/100'/1900'/0'/0'/0'");
354
+ const addr1 = NeuraiKey.getPQAddressByPath("xna-pq", hdKey, "m_pq/100'/1900'/0'/0'/1'");
255
355
  ```
256
356
 
357
+ All PQ derivation levels are hardened; a non-hardened segment (`.../0/0`) throws.
358
+
359
+ ### Export / import a PQ extended private key
360
+
361
+ ```javascript
362
+ const hdKey = NeuraiKey.getPQHDKey("xna-pq", mnemonic);
363
+
364
+ // Serialize master (or any subtree) as xpqpriv / tpqpriv
365
+ const xpqpriv = NeuraiKey.pqExtendedPrivateKey("xna-pq", hdKey);
366
+ // xpqpriv starts with "xpqp..." (mainnet) or "tpqp..." (testnet), 111 chars
367
+
368
+ // Restore from the serialized form and keep deriving
369
+ const restored = NeuraiKey.pqHDKeyFromExtended("xna-pq", xpqpriv);
370
+ const addr = NeuraiKey.getPQAddressByPath("xna-pq", restored, "m_pq/100'/1900'/0'/0'/0'");
371
+ ```
372
+
373
+ The binary layout (74 bytes: `depth + fingerprint + child + chainCode + 0x00 + pq_seed`) and version bytes (`0x0488AC24` mainnet, `0x043581D5` testnet) match the Neurai node's `CNeuraiExtKeyPQ` serialization.
374
+
257
375
  ### PQ AuthScript Details
258
376
 
259
377
  | Property | Value |
@@ -263,13 +381,15 @@ const addr1 = NeuraiKey.getPQAddressByPath("xna-pq", hdKey, "m/100'/1900'/0'/0/1
263
381
  | Mainnet HRP / prefix | `nq` / `nq1...` |
264
382
  | Testnet HRP / prefix | `tnq` / `tnq1...` |
265
383
  | Public key size | 1312 bytes |
266
- | Derivation path (mainnet) | `m/100'/1900'/0'/0/index` |
267
- | Derivation path (testnet default/external) | `m/100'/1'/account'/0/index` |
268
- | Auth descriptor | `0x01 \|\| HASH160(pq_pubkey)` |
384
+ | HD tree | Native PQ, HMAC-SHA512 with key `"Neurai PQ seed"`, hardened-only |
385
+ | Derivation path (mainnet) | `m_pq/100'/1900'/0'/0'/index'` |
386
+ | Derivation path (testnet default/external) | `m_pq/100'/1'/0'/0'/index'` |
387
+ | Extended privkey prefix | `xpqp...` (mainnet) / `tpqp...` (testnet), 111 base58 chars |
388
+ | Auth descriptor | `0x01 \|\| HASH160(0x05 \|\| pq_pubkey)` |
269
389
  | Commitment | `tagged_hash("NeuraiAuthScript", 0x01 \|\| auth_descriptor \|\| SHA256(witnessScript))` |
270
390
  | Default witnessScript | `OP_TRUE` (`51` in hex) |
271
391
 
272
- **Note**: PQ AuthScript addresses do not have a WIF (Wallet Import Format) field since WIF is specific to secp256k1 keys. The `seedKey` field contains the 32-byte BIP32-derived seed used for deterministic ML-DSA-44 key generation, useful for cross-implementation verification.
392
+ **Note**: PQ AuthScript addresses do not have a WIF (Wallet Import Format) field since WIF is specific to secp256k1 keys. The `seedKey` field contains the 32-byte native PQ seed used for deterministic ML-DSA-44 key generation, useful for cross-implementation verification.
273
393
 
274
394
  ## Get public key from WIF
275
395
 
@@ -318,7 +438,7 @@ const NeuraiKey = require("@neuraiproject/neurai-key");
318
438
  </html>
319
439
  ```
320
440
 
321
- ## Package layout in `3.0.0`
441
+ ## Package layout in `4.0.0`
322
442
 
323
443
  - `dist/index.js`: ESM main entry
324
444
  - `dist/index.cjs`: CommonJS entry
@@ -338,7 +458,7 @@ const NeuraiKey = require("@neuraiproject/neurai-key");
338
458
 
339
459
  `npm test`
340
460
 
341
- The test script already builds the package before running Jest.
461
+ The test script already builds the package before running Vitest.
342
462
 
343
463
  ## BIP32
344
464