Protocol
Address types
Testnet has five kinds of address. You can tell them apart by how they start: the Base58 Legacy format
and three Bech32m witness families, which went live at block 10, plus the private addresses of the privacy
pools. The letter after 1 in a Bech32m address is the witness version: p = 1,
z = 2, r = 3.
At a glance
Testnet and mainnet prefixes
| Family | Testnet | Mainnet | Encoding | Signatures |
|---|---|---|---|---|
| Legacy | t… |
N… |
Base58Check, version 127 | secp256k1 ECDSA |
| ECDSA witness | tnq1r… |
nq1r… |
Bech32m, HRP tnq, witness v3 | Compressed secp256k1 ECDSA |
| Post-quantum | tpq1z… |
pq1z… |
Bech32m, HRP tpq, witness v2 | ML-DSA-44 (FIPS 204): 1,313-byte public key, 2,421-byte signature |
| AuthScript | tnc1p… |
nc1p… |
Bech32m, HRP tnc, witness v1 | None, ML-DSA-44 or ECDSA (authType 0x00 / 0x01 / 0x02), plus a witness script |
| Private | tnzk1… |
nzk1… |
Bech32m string defined by neurai-privacy (not a node address) | Keys derived from the wallet words (NeuraiZK), optional ZK passphrase |
On mainnet only Legacy is in use today; the witness families are not scheduled there yet. P2SH scripts use
Base58 version 196 on testnet (addresses starting with 2).
Base58Check, version 127
Legacy t…
Supported by every Neurai release and tool. Required for DePIN messaging and for the privacy pool's C4 profile.
- Script
P2PKH: OP_DUP OP_HASH160 <20 bytes> OP_EQUALVERIFY OP_CHECKSIG- Keys
- secp256k1 ECDSA
- Derivation
m/44'/1'/account'/change/index
Bech32m, HRP tnq, witness v3
ECDSA witness tnq1r…
Strict ECDSA AuthScript. Smaller signatures and lower fees. The default family of the testnet web wallet.
- Script
OP_3 <32-byte commitment>- Keys
- Compressed secp256k1 ECDSA
- Derivation
m/84'/1'/account'/change/index
Bech32m, HRP tpq, witness v2
Post-quantum tpq1z…
Strict post-quantum AuthScript. ML-DSA-44 signatures are designed to resist attacks by quantum computers.
- Script
OP_2 <32-byte commitment>- Keys
- ML-DSA-44 (FIPS 204): 1,313-byte public key, 2,421-byte signature
- Derivation
m_pq/100'/1'/account'/change'/index'
Bech32m, HRP tnc, witness v1
AuthScript tnc1p…
The contract family: covenants, script trees, mixed ECDSA/PQ multisig and the privacy pools live here. Wallets do not hand these out as receiving addresses.
- Script
OP_1 <32-byte tagged commitment>- Keys
- None, ML-DSA-44 or ECDSA (authType 0x00 / 0x01 / 0x02), plus a witness script
- Derivation
Built per contract
Bech32m string defined by neurai-privacy (not a node address)
Private tnzk1…
Receive private payments inside a privacy pool. The node never sees these; the wallet and the neurai-privacy library do.
- Script
None: a note inside a privacy pool- Keys
- Keys derived from the wallet words (NeuraiZK), optional ZK passphrase
- Derivation
From the wallet words, per pool and account
AuthScript
How the witness families commit
All three Bech32m families are AuthScript outputs: a version opcode followed by a 32-byte commitment. For the generic family (v1) the commitment is a tagged hash of the authentication type, the key hash and the witness script, so one output can require a post-quantum signature, an ECDSA signature, or only the script. The strict families fix the key type and the script: v2 always means an ML-DSA-44 key, v3 always a compressed ECDSA key.
commitment = TaggedHash("NeuraiAuthScript",
0x01 || authType || [HASH160(pubkey)] || SHA256(witnessScript))
authType 0x00 script only (keys checked inside the script)
authType 0x01 ML-DSA-44 public key
authType 0x02 ECDSA public key
Try it
Create each kind of address
neurai-cli -testnet getnewaddress "" # default family
neurai-cli -testnet getnewaddress "" "ecdsa" # tnq1r…
neurai-cli -testnet getnewaddress "" "pq" # tpq1z…
neurai-cli -testnet validateaddress tpq1z…
import NeuraiKey from "@neuraiproject/neurai-key";
const words = NeuraiKey.generateMnemonic();
NeuraiKey.getAddressPair("xna-legacy-test", words, 0, 0).external.address; // t…
NeuraiKey.getPQAddress("xna-pq-test", words, 0, 0).address; // tpq1z…