@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 +136 -16
- package/dist/NeuraiKey.global.js +5777 -4118
- package/dist/NeuraiKey.global.js.map +1 -1
- package/dist/browser.js +5778 -4119
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +5785 -4118
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +59 -6
- package/dist/index.js +249 -33
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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@
|
|
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
|
-
- ✅
|
|
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`**:
|
|
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 `
|
|
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: "
|
|
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
|
|
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
|
-
`
|
|
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, "
|
|
254
|
-
const addr1 = NeuraiKey.getPQAddressByPath("xna-pq", hdKey, "
|
|
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
|
-
|
|
|
267
|
-
| Derivation path (
|
|
268
|
-
|
|
|
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
|
|
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 `
|
|
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
|
|
461
|
+
The test script already builds the package before running Vitest.
|
|
342
462
|
|
|
343
463
|
## BIP32
|
|
344
464
|
|