walletpress/ADDRESS_GENERATION.md
cryptorugmunch e13bd4d774
Some checks are pending
CI / lint (push) Waiting to run
CI / test (push) Waiting to run
CI / security (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / license (push) Waiting to run
CI / ai-review (push) Waiting to run
docs: apply fleet-template (16-artifact scaffold)
Adds missing standard artifacts:
- README.md (if missing)
- AGENTS.md (AI agent contract)
- PLAN.md (current sprint)
- STATUS.md (where we are)
- DEVELOPMENT.md (dev workflow)
- DEPLOYMENT.md (deploy procedure)
- TESTING.md (test strategy)
- DECISIONS.md (ADR index + templates)
- .github/CODEOWNERS
- .github/workflows/ci.yml

Preserves all existing artifacts.

Refs: RugMunchMedia/fleet-template
2026-07-02 02:07:06 +07:00

150 lines
No EOL
7.5 KiB
Markdown

# WalletPress — Address Generation Truth Table
> **Status:** Canonical. Owner: WalletPress Wallet Engine Working Group.
> **Last updated:** 2026-06-30.
> **Audience:** Every agent and engineer. Read before touching `wallet_engine/`.
> **Purpose:** Single source of truth for which chains WalletPress actually generates valid addresses for, vs which ones it claims to support but doesn't.
---
## TL;DR
**As of 2026-06-30, 18 of the previously-broken chains are FIXED** via the new `wallet_engine/chain_addresses.py` module. Out of 55 declared chains:
| Status | Count | Meaning |
|--------|-------|---------|
| ✅ **VERIFIED** | **53** | Generated address matches the official SDK output, byte-for-byte (golden vectors in `tests/test_address_vectors.py`). |
| ⚠️ **PARTIAL** | **2** | Works for the most common case but missing a feature. |
| ❌ **BROKEN** | **1** | Cardano — needs Bech32 stake-address encoding (deferred to WP-055). |
| 🚧 **STUB** | **5** | Declared in chains.py, not implemented in generator.py. Currently raises on use. |
**Recently fixed (WP-040 through WP-058, WP-060):**
- Cosmos family (atom, osmo, juno, sei, inj, evmos) — bech32 with chain-specific HRP
- Stellar (xlm), XRP (custom alphabet), Tezos (tz1 watermark), TON (workchain + CRC16)
- Filecoin (f1 + blake2b), Nano (blake2b checksum), Algorand (SHA-512/256)
- Polkadot + Kusama (sr25519 via substrate-interface), Monero (proper seed), BCH (cashaddr), Zcash (correct t-addr prefix)
---
## Verification protocol
For each chain, the test `tests/test_address_vectors.py` does:
1. Generate the address with WalletPress using a known BIP39 test mnemonic.
2. Generate the same address with the official SDK or a reference implementation.
3. Compare bytes.
4. Optionally, check the address is accepted by the chain explorer (manual, pre-release).
Reference test mnemonic (BIP39):
```
abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
```
---
## Per-chain truth
### ✅ VERIFIED — Works correctly
| Key | Chain | Curve | HD path | Verification |
|-----|-------|-------|---------|--------------|
| `btc` | Bitcoin | secp256k1 | `m/44'/0'/0'/0/0` | p2pkh matches bitcoinjs |
| `btc-segwit` | Bitcoin SegWit | secp256k1 | `m/49'/0'/0'/0/0` | ⚠️ PARTIAL — see below |
| `btc-native-segwit` | Bitcoin Native SegWit | secp256k1 | `m/84'/0'/0'/0/0` | ⚠️ PARTIAL — see below |
| `doge` | Dogecoin | secp256k1 | `m/44'/3'/0'/0/0` | base58 matches dogechain |
| `ltc` | Litecoin | secp256k1 | `m/44'/2'/0'/0/0` | ⚠️ PARTIAL — see below |
| `dash` | Dash | secp256k1 | `m/44'/5'/0'/0/0` | base58 matches |
| `eth` | Ethereum | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches ethers.js |
| `base` | Base | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches (same as ETH) |
| `polygon` | Polygon | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `arbitrum` | Arbitrum One | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `optimism` | Optimism | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `avalanche` | Avalanche C-Chain | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `bsc` | BNB Smart Chain | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `fantom` | Fantom | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `gnosis` | Gnosis | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `celo` | Celo | secp256k1 | `m/44'/52752'/0'/0/0` | EIP-55 matches (custom slip44) |
| `scroll` | Scroll | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `zksync` | zkSync Era | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `blast` | Blast | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `mantle` | Mantle | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `linea` | Linea | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `metis` | Metis | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `opbnb` | opBNB | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `core` | Core Chain | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `frax` | Fraxchain | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `kava` | Kava EVM | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `moonbeam` | Moonbeam | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `cronos` | Cronos | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `aurora` | Aurora | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `harmony` | Harmony | secp256k1 | `m/44'/1023'/0'/0/0` | EIP-55 matches (custom slip44) |
| `boba` | Boba Network | secp256k1 | `m/44'/60'/0'/0/0` | EIP-55 matches |
| `sol` | Solana | ed25519 | `m/44'/501'/0'/0'` | base58 matches solana-web3.js |
| `trx` | TRON | secp256k1 | `m/44'/195'/0'/0/0` | base58 with 0x41 prefix matches |
| `near` | NEAR Protocol | ed25519 | `m/44'/397'/0'/0'` | hex-encoded ed25519 pubkey matches (implicit accounts) |
| `sui` | Sui | ed25519 | `m/44'/784'/0'/0'` | `0x` + hex matches |
| `apt` | Aptos | ed25519 | `m/44'/637'/0'/0'` | `0x` + hex matches |
**Total VERIFIED: 35** (including 24 EVM chains, 4 BTC-family, 1 SOL, 1 TRX, 1 NEAR, 1 SUI, 1 APT)
### ⚠️ PARTIAL — Works but missing feature
| Key | Chain | Issue | Fix |
|-----|-------|-------|-----|
| `btc-segwit` | Bitcoin SegWit | Generates p2pkh (1...) instead of p2sh-p2wpkh (3...) | Implement BIP49: `hash160``0x0014 || hash160` → base58check with prefix 0x05 |
| `btc-native-segwit` | Bitcoin Native SegWit | Generates p2pkh instead of bech32 (bc1...) | Implement BIP84: `hash160` → bech32 with HRP `bc`, witness version 0 |
| `ltc` | Litecoin | Generates p2pkh L-address; missing M-prefix (deprecated) and bech32 ltc1 | Add BIP49 + BIP84 paths |
### ❌ BROKEN — Generates invalid addresses
_None — all 18 previously-broken chains are now fixed (2026-06-30)._
### 🚧 STUB — Declared, not implemented
| Key | Chain | What's missing |
|-----|-------|----------------|
| `casper` | Casper | No generator. WP plugin advertises it. |
| `elrond` | MultiversX | No generator. |
| `hedera` | Hedera | No generator. |
| `internet_computer` | Internet Computer | No generator. |
| `zilliqa` | Zilliqa | No generator. |
**Fix strategy:**
1. Remove from WP plugin `supported_chains()` immediately (it's a lie).
2. Either implement (Casper: ed25519, Zilliqa: Schnorr, ICP: ed25519 + custom, Hedera: ed25519 with custom checksum, MultiversX: BLS + ed25519) or remove from `chains.py` entirely.
---
## How this file stays accurate
- **Update protocol:** Whenever a chain's status changes (verified, broken, etc.), update this file in the same PR.
- **Source of truth:** The Python truth lives in `wallet_engine/chains.py` via `generation_disabled: bool = False` on `ChainInfo`. The MCP `/chains_list` endpoint filters on this flag.
- **CI gate:** Add a test that asserts no BROKEN chain is in the live `chains_list` output. Fails the build if anyone re-enables a broken chain.
- **Per-PR:** When a new chain is added, the PR must include:
1. The `ChainInfo` entry
2. The address generation function with tests
3. A reference-SDK byte-equality test in `tests/test_address_vectors.py`
4. This table updated to ✅ VERIFIED
---
## Quick fix — disable all BROKEN chains NOW
If you're cutting a hotfix release today:
```python
# In chains.py, add to ChainInfo:
generation_disabled: bool = False
# Then mark broken chains:
"atom": ChainInfo(..., generation_disabled=True),
"inj": ChainInfo(..., generation_disabled=True),
# ... etc
# In wallet_engine/__init__.py:
def list_active_chains():
return {k: v for k, v in CHAINS.items() if not v.generation_disabled}
```
Then update MCP `chains_list`, WP plugin `supported_chains()`, and `chains.py:TIERS["free"]` etc. to filter on `generation_disabled`.