@neuraiproject/neurai-assets 1.6.2 → 1.7.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
@@ -46,7 +46,7 @@ Complete asset management library for Neurai blockchain. Supports creation, reis
46
46
  - ✅ **RPC queries**: Complete wrapper for all asset query methods
47
47
  - ✅ **Client-side validation**: Prevents errors before creating transactions
48
48
  - ✅ **Owner token protection**: Validation to prevent permanent loss
49
- - ✅ **Legacy + AuthScript destinations**: Supports classic `N...` / `t...` and witness-v1 `nq1...` / `tnq1...` addresses
49
+ - ✅ **Every Neurai address type**: classic `N...` / `t...`, generic AuthScript v1 `nc1p...` / `tnc1p...`, PQ v2 `pq1z...` / `tpq1z...` and ECDSA v3 `nq1r...` / `tnq1r...`
50
50
 
51
51
  ## Supported Asset Types
52
52
 
@@ -154,9 +154,9 @@ You can also initialize the library with AuthScript addresses:
154
154
  ```javascript
155
155
  const assetsPQ = new NeuraiAssets(rpc, {
156
156
  network: 'xna', // 'xna-pq' / 'xna-pq-test' remain valid aliases
157
- addresses: ['nq1yourauthscriptaddress...'],
158
- changeAddress: 'nq1yourauthscriptchange...',
159
- toAddress: 'nq1recipientauthscriptaddress...'
157
+ addresses: ['pq1zyourpqaddress...'], // or nc1p… / nq1r…
158
+ changeAddress: 'pq1zyourpqchange...',
159
+ toAddress: 'nq1rrecipientecdsaaddress...'
160
160
  });
161
161
  ```
162
162
 
@@ -868,29 +868,52 @@ const assets = new NeuraiAssets(rpc, {
868
868
  // AuthScript mainnet using the canonical network label
869
869
  const assetsPQ = new NeuraiAssets(rpc, {
870
870
  network: 'xna',
871
- addresses: ['nq1...'],
872
- changeAddress: 'nq1...',
873
- toAddress: 'nq1...'
871
+ addresses: ['pq1z...', 'nq1r...'],
872
+ changeAddress: 'pq1z...',
873
+ toAddress: 'nc1p...'
874
874
  });
875
875
 
876
876
  // AuthScript testnet using the canonical network label
877
877
  const assetsPQTest = new NeuraiAssets(rpc, {
878
878
  network: 'xna-test',
879
- addresses: ['tnq1...'],
880
- changeAddress: 'tnq1...',
881
- toAddress: 'tnq1...'
879
+ addresses: ['tpq1z...', 'tnq1r...'],
880
+ changeAddress: 'tpq1z...',
881
+ toAddress: 'tnc1p...'
882
882
  });
883
883
  ```
884
884
 
885
- The library accepts these network names:
885
+ Address types (every family is valid with the network label of its chain):
886
886
 
887
- - `xna`: mainnet chain family, valid for both legacy `N...` and AuthScript `nq1...`
888
- - `xna-test`: testnet chain family, valid for both legacy `t...` and AuthScript `tnq1...`
887
+ | Address | Type | scriptPubKey |
888
+ |---|---|---|
889
+ | `N...` / `t...` | Legacy P2PKH | `OP_DUP OP_HASH160 <20B> OP_EQUALVERIFY OP_CHECKSIG` |
890
+ | `nc1p...` / `tnc1p...` | generic AuthScript witness v1 | `OP_1 <32B>` |
891
+ | `pq1z...` / `tpq1z...` | strict PQ witness v2 | `OP_2 <32B>` |
892
+ | `nq1r...` / `tnq1r...` | strict ECDSA witness v3 | `OP_3 <32B>` |
893
+
894
+ The old `nq1p...` / `tnq1p...` encoding of generic AuthScript v1 is rejected, like
895
+ in the node (same scriptPubKey: regenerate it as `nc1p...` / `tnc1p...`). The node
896
+ only protects a witness family where it is active: today v1 on testnet and regtest,
897
+ v2 / v3 only on regtest.
898
+
899
+ The library accepts these network names. A label only selects the chain: the
900
+ address type always comes from the address itself.
901
+
902
+ - `xna`: mainnet chain family, valid for legacy and every AuthScript family
903
+ - `xna-test`: testnet chain family (also regtest), valid for legacy and every AuthScript family
889
904
  - `xna-pq`: compatibility alias for AuthScript mainnet flows
890
905
  - `xna-pq-test`: compatibility alias for AuthScript testnet flows
906
+ - `mainnet`, `testnet`, `regtest`, `mainnet-pq`, `testnet-pq`: aliases
907
+ - neurai-key 5 labels, accepted as aliases of their chain since 1.7.0:
908
+ `xna-legacy`, `xna-old-legacy`, `xna-authscript` (mainnet) and
909
+ `xna-legacy-test`, `xna-authscript-test` (testnet)
910
+
911
+ `NetworkDetector.detectFromAddress` decodes the address (it throws for anything
912
+ that is not a valid Neurai address) and reports `xna` / `xna-test` for Base58
913
+ and `xna-pq` / `xna-pq-test` for every Bech32m AuthScript family.
891
914
 
892
- If you need to derive AuthScript addresses, use `neurai-key` and pass the resulting
893
- `nq1...` or `tnq1...` addresses into this library.
915
+ If you need to derive AuthScript addresses, use `neurai-key` 5 and pass the resulting
916
+ addresses into this library.
894
917
 
895
918
  ## Update Configuration
896
919
 
@@ -1013,9 +1036,10 @@ const txid = await wallet.broadcastTransaction(signedTx);
1013
1036
  console.log('Transaction ID:', txid);
1014
1037
  ```
1015
1038
 
1016
- For AuthScript wallets, derive addresses externally with `neurai-key`, then initialize
1017
- `NeuraiAssets` with those `nq1...` / `tnq1...` addresses. The recommended network labels
1018
- are `xna` and `xna-test`; `xna-pq` and `xna-pq-test` remain available as compatibility aliases.
1039
+ For AuthScript wallets, derive addresses externally with `neurai-key` 5, then initialize
1040
+ `NeuraiAssets` with those `nc1p…` / `pq1z…` / `nq1r…` addresses (or their testnet forms).
1041
+ The recommended network labels are `xna` and `xna-test`; `xna-pq` and `xna-pq-test` remain
1042
+ available as compatibility aliases.
1019
1043
 
1020
1044
  ## Fee estimation (PQ-aware)
1021
1045
 
@@ -1025,7 +1049,7 @@ Running out of funds raises `InsufficientFundsError` rather than returning an un
1025
1049
 
1026
1050
  All estimates share a single `estimatesmartfee` lookup. The fee rate is stable for the lifetime of one build, so it is fetched on the first estimate and cached on the builder instance.
1027
1051
 
1028
- Estimates use the helpers in [`src/utils/feeSizing.js`](src/utils/feeSizing.js) and distinguish PQ AuthScript inputs/outputs from legacy P2PKH ones. PQ inputs spend ~977 vbytes vs ~148 for legacy — without this distinction, transactions built from PQ addresses fall under the node's `min relay fee` and are rejected with `code -26: min relay fee not met`.
1052
+ Estimates use the helpers in [`src/utils/feeSizing.js`](src/utils/feeSizing.js) (published as `utils.FeeSizing`) and size every input by its address type: PQ inputs (strict PQ v2, or generic AuthScript v1 with a PQ key) spend ~977 vbytes, strict ECDSA v3 inputs ~70 and legacy P2PKH ~148 — without this distinction, transactions built from PQ addresses fall under the node's `min relay fee` and are rejected with `code -26: min relay fee not met`. Before 1.7.0 a strict PQ v2 input was sized as a legacy one (148 vbytes).
1029
1053
 
1030
1054
  Outputs that carry an asset payload are sized as such, not as bare P2PKH outputs. An asset output is `<destination> OP_XNA_ASSET <pushdata payload> OP_DROP`, which adds roughly 20-60 bytes; ignoring that under-counts a transaction by a few percent, and that is enough to fall below the floor whenever the node's fee rate sits close to its minimum relay fee.
1031
1055
 
@@ -1034,24 +1058,29 @@ Since `1.5.3` those sizes are **not modelled, they are measured**: `feeSizing` a
1034
1058
  You should not need to call these helpers directly; they are wired into every builder. They are documented here so you can audit the fee math or use the same constants if you compose transactions outside the standard builder flow.
1035
1059
 
1036
1060
  ```js
1061
+ const { utils } = require('@neuraiproject/neurai-assets');
1037
1062
  const {
1038
1063
  VBYTES,
1039
1064
  estimateInputVbytes,
1040
1065
  estimateOutputBytes,
1041
1066
  estimateTransactionVbytes,
1042
- isPQAddress,
1043
- isPQScript,
1044
- } = require('@neuraiproject/neurai-assets/src/utils/feeSizing');
1045
-
1046
- VBYTES.legacyInputVbytes; // 148
1047
- VBYTES.pqInputVbytes; // 977
1048
- VBYTES.legacyOutputBytes; // 34
1049
- VBYTES.pqOutputBytes; // 43
1050
-
1067
+ getAddressKind,
1068
+ getScriptKind,
1069
+ } = utils.FeeSizing;
1070
+
1071
+ VBYTES.legacyInputVbytes; // 148
1072
+ VBYTES.pqInputVbytes; // 977
1073
+ VBYTES.ecdsaWitnessInputVbytes; // 70
1074
+ VBYTES.legacyOutputBytes; // 34
1075
+ VBYTES.witnessOutputBytes; // 43 (pqOutputBytes is a deprecated alias)
1076
+
1077
+ getAddressKind('tpq1z…'); // 'pq' ('p2pkh' | 'authscript' | 'pq' | 'ecdsa' | 'unknown')
1078
+ getScriptKind('5320…'); // 'ecdsa'
1051
1079
  estimateInputVbytes({ script: '5120…' }); // 977
1052
- estimateInputVbytes({ address: 'nq1…' }); // 977
1053
- estimateInputVbytes({ address: 'mgRYHdMq…' }); // 148
1054
- estimateOutputBytes('tnq1…'); // 43
1080
+ estimateInputVbytes({ script: '5220…' }); // 977
1081
+ estimateInputVbytes({ script: '5320…' }); // 70
1082
+ estimateInputVbytes({ address: 't7pv…' }); // 148
1083
+ estimateOutputBytes('tnq1r…'); // 43
1055
1084
 
1056
1085
  // Asset outputs declare their payload. Sizes come from the real encoder, so
1057
1086
  // they match the bytes the node will see.
@@ -1072,8 +1101,8 @@ estimateOutputBytes({ assetName: '$SEC', kind: 'globalRestriction' });
1072
1101
  estimateOutputBytes({ kind: 'verifier', verifierString: '#KYC' }); // 17
1073
1102
 
1074
1103
  const vbytes = estimateTransactionVbytes(
1075
- [{ script: '5120…' }, { address: 'mgRYHdMq…' }], // 1 PQ + 1 legacy input
1076
- ['nq1qchange…', 'mgRYHdMqburn…'], // 1 PQ + 1 legacy output
1104
+ [{ script: '5220…' }, { address: 't7pv…' }], // 1 PQ + 1 legacy input
1105
+ ['tpq1zchange…', 't7pvburn…'], // 1 witness + 1 legacy output
1077
1106
  );
1078
1107
  ```
1079
1108
 
@@ -1086,7 +1115,8 @@ The constants mirror those exported from `@neuraiproject/neurai-sign-transaction
1086
1115
  The estimator assumes the most common spend layout for every input:
1087
1116
 
1088
1117
  - legacy inputs → P2PKH `scriptSig` worst case (DER signature + compressed pubkey)
1089
- - PQ inputs → AuthScript v1 with the **default** `OP_TRUE` `witnessScript` and **no** `functionalArgs`
1118
+ - PQ inputs → strict PQ v2, or generic AuthScript v1 with the **default** `OP_TRUE` `witnessScript` and **no** `functionalArgs`
1119
+ - ECDSA inputs → strict ECDSA v3 (worst-case DER signature + compressed pubkey)
1090
1120
 
1091
1121
  That covers all standard asset operations. If you build transactions whose PQ inputs use covenant `witnessScript`s, NoAuth (`authType=0x00`) or Legacy AuthScript (`authType=0x02`) witnesses, compute the witness size yourself and add it to the result of `estimateTransactionVbytes` (or use `estimateVirtualSize` from `@neuraiproject/neurai-sign-transaction` after building the raw transaction, which fills dummy witnesses of the worst-case size and returns the exact post-signing vsize).
1092
1122
 
@@ -1102,6 +1132,33 @@ remain available as `totalSats` / raw methods; never use a rounded display value
1102
1132
  as a new transaction input.
1103
1133
 
1104
1134
 
1135
+ ## 1.7.0: address types of neurai-key 5
1136
+
1137
+ - Every Neurai address family is accepted: generic AuthScript v1 `nc1p…` /
1138
+ `tnc1p…`, strict PQ v2 `pq1z…` / `tpq1z…` and strict ECDSA v3 `nq1r…` /
1139
+ `tnq1r…`, besides legacy `N…` / `t…`. Before, `pq1…` and `nc1…` threw
1140
+ "Cannot detect network" and `nq1r…` was taken for a PQ address.
1141
+ - **Fees:** a strict PQ v2 input used to be sized as legacy (148 vbytes
1142
+ instead of ~977), which the node rejects as `min relay fee not met`. Inputs
1143
+ are now sized per type (`VBYTES.ecdsaWitnessInputVbytes` for v3), every
1144
+ witness output as 43 bytes, and the segwit marker is counted for any witness
1145
+ input. `isPQAddress` / `isPQScript` decode instead of matching a prefix
1146
+ (`nq1…` is ECDSA now); `getAddressKind` / `getScriptKind` are new.
1147
+ - `utils.FeeSizing` publishes the fee helpers (the documented
1148
+ `src/utils/feeSizing` path was never part of the package).
1149
+ - The labels of neurai-key 5 are accepted as aliases of their chain:
1150
+ `xna-legacy`, `xna-old-legacy`, `xna-authscript`, `xna-legacy-test`,
1151
+ `xna-authscript-test`.
1152
+ - `NETWORKS.*.authScriptAddressPrefix` is `nc1` / `tnc1` (was `nq1` / `tnq1`),
1153
+ `pqAddressPrefix` is `pq1` / `tpq1`, and `ecdsaAddressPrefix` (`nq1` /
1154
+ `tnq1`) is new.
1155
+ - `NetworkDetector.detectFromAddress` / `detectNetworkFromAddress` decode the
1156
+ address: strings that are not valid Neurai addresses (placeholders such as
1157
+ `NExample…`, the old `tnq1p…` encoding) now throw instead of being labelled
1158
+ by their first letter. `isMainnet` / `isTestnet` return false for unknown
1159
+ labels instead of throwing nothing useful.
1160
+ - Requires `@neuraiproject/neurai-create-transaction` `^0.9.0`.
1161
+
1105
1162
  ## Exact amounts and legacy converter migration
1106
1163
 
1107
1164
  In 1.6.2, insufficient-funds errors preserve `required` and `available` as