# Wallet

> The NeuroChain wallet — 24-word recovery phrase, post-quantum ML-DSA-65 key derived in the browser, encrypted keystore, sending NRO, signed operations, transaction statuses and the test-network faucet.

Source: https://docs.nro.world/learn/wallet

A NeuroChain wallet is a **24-word recovery phrase**. Everything else — the signing key and the `.human` address — is computed from it, in your browser, and never leaves it.

## Ways to use a wallet

All of these use the same keys and the same `.human` address; they differ in where the key lives and who signs.

| Option | Where the key lives | Who signs | Good for | Page |
|--------|--------------------|-----------|----------|------|
| **Web wallet** | Your browser, encrypted with your password | You, in the app | Everyday use: send, stake, vote, register names, manage agents | This page |
| **Signer pop-up** | Your browser (the web wallet) | You, approving in a pop-up | Using a dApp on another site without giving it your phrase | [Signer SDK](/build/sdk#signer-sdk) |
| **JavaScript SDK** | Your own page or script | Your code, with the phrase you give it | Building a dApp or automation that holds its own wallet | [JavaScript SDK](/build/sdk) |
| **Session key (AI agent)** | The agent's machine — a separate, limited key | The agent, within scope, spend cap and expiry you set | Letting an AI assistant act for you through MCP | [AI agents (MCP)](/build/mcp) |
| **Paid names** (`.node`, `.vault`, `.agent`, …) | No key of their own | The `.human` wallet that owns them | Validators, shared treasuries, agent accounts | [Addresses](./addresses) |

A `.vault` is controlled together by several members: a payout needs a threshold of their signatures.

## Create or import

| | What happens |
|---|---|
| **Create** | The browser generates 24 words from 256 bits of random entropy (BIP-39 word list with checksum). Write them down; they are shown once. |
| **Import** | Enter an existing 24-word phrase. The checksum is verified before anything else happens. |

From the words, the browser derives the ML-DSA-65 keypair and the address as described in [Addresses](./addresses#your-wallet-address-human). The same phrase always gives the same address, on any device.

## Where the key is kept

| Item | Where | Protection |
|------|-------|-----------|
| Recovery phrase | Browser `localStorage`, key `nc_ks_<address>` | Encrypted with your password: PBKDF2-SHA256 (100 000 iterations, random 16-byte salt) → AES-256-GCM |
| Signing key | Memory of the open tab only | Re-derived from the phrase after you unlock |
| Password | Nowhere | Only used to encrypt and decrypt the phrase |

Several wallets can live side by side in the same browser; you switch between them in the app.

::: warning Keep the phrase, not the password
The password only unlocks the copy stored in this browser. If you lose the phrase and the browser data, the wallet is gone — nobody can restore it. If the phrase leaks, anyone can sign as you; rotate to a new key through [Identity](/ai/identity).
:::

## Sending NRO

1. The app reads your next nonce and the current base fee.
2. It sets the gas price to **1.5 × base fee** (rounded up) so the transaction stays valid if the base fee rises before inclusion.
3. The browser checks balance, nonce and fee locally (WASM) and shows any error before sending.
4. It signs `nc-tx-v2|from|to|value|nonce` with your key and sends the transaction with your public key.
5. The node verifies the signature and that your public key derives your address, then queues the transaction.

A transfer to yourself costs only the fee; the app shows it that way.

## Transaction statuses

| Status | Meaning |
|--------|---------|
| `pending` | Accepted by a node, waiting in the mempool. Dropped if not included within 60 seconds. |
| `confirmed` | In a final block and applied. |
| `failed` | In a final block, but the contract call trapped or ran out of fuel. Value and storage changes are rolled back; the fee and nonce are consumed. |
| `held` | Accepted but delayed by the [Sentinel policy layer](/ai/sentinel) <Badge type="warning" text="off by default" />: the value is released automatically after a delay, or waits for your confirmation. |
| `cancelled` | A held transaction you cancelled; the value is returned. |
| `refunded` | Value returned to you — a held transaction that expired without confirmation, or a cross-shard transfer that timed out. |

## Signed operations

Staking, registering names, voting and similar actions are not transfers, but they are signed the same way. The wallet signs `nc-tx-v2|<you>|<system target>|<value>|<nonce>`, where the target names the operation (`neuro:system.stake`, `neuro:system.node`, `neuro:system.name`, `neuro:system.governance`, …).

For these, the nonce is a millisecond timestamp, and the node accepts only a nonce higher than the last one it saw from your address — a captured request cannot be replayed.

## Faucet <Badge type="warning" text="test networks only" />

On a node started with `CHAIN_ENV=testnet`, `POST /api/v1/faucet` credits test NRO. On `CHAIN_ENV=mainnet` (the default) it is disabled.

| Setting | Default | Variable |
|---------|---------|----------|
| Amount per request | 50 NRO | request field `amount` |
| Maximum per request | 100 NRO | `NEUROCHAIN_FAUCET_MAX_NRO` |
| Cooldown per address | 24 hours | `NEUROCHAIN_FAUCET_COOLDOWN_SECS` (0 turns it off) |

```bash
curl -s -X POST "$NODE_RPC/api/v1/faucet" \
  -H 'Content-Type: application/json' \
  -d '{"address":"neuro:<your address>.human","public_key":"<your ML-DSA-65 public key, hex>"}'
```

The faucet binds the public key you send to the address when it first funds it.

## Command-line wallet

The node repository still contains an older command-line wallet, `neurowallet`. It predates the current address scheme (`NC_KDF_v3`) and does not sign with ML-DSA-65, so its addresses and transactions are not accepted by the current network. Use the web wallet or the [JavaScript SDK](/build/sdk).
