Packages: core (BIP39/32/44/49/84/86 derivation, WIF), keystore (PBKDF2 + AES-GCM), psbt, p2p (BIP157/158 SPV daemon, Dandelion++ broadcast with relay-echo verification), blockbook, rpc, electrum, net, bns, web-ui (React/Vite), mobile (Expo). ops/ holds the nginx vhost, systemd unit and push.sh deploy script for digibyte.x/web.
874 lines
41 KiB
Markdown
874 lines
41 KiB
Markdown
# DigiByte Mobile Wallet — Research Report
|
||
|
||
Compiled 2026-08-02, revised 2026-08-03. Purpose: decide the shape of a
|
||
new DigiByte mobile wallet that supports **BIP39 seed phrase recovery**
|
||
and **raw private key (WIF) import**, given the ecosystem's current
|
||
state.
|
||
|
||
> **Note on Jared Tate (correction, 2026-08-03):** the "founder gone"
|
||
> phrasing in §1 below overstates the situation. Per the user, Tate has
|
||
> remained active in 2025–2026. Treat the 2020 stepdown / 2023
|
||
> disengagement quotes as historical, not current, and re-verify current
|
||
> activity before treating "founder absent" as a real ecosystem risk.
|
||
|
||
> **Architecture note (2026-08-03):** §4 and §7 recommend Blockbook as
|
||
> the default backend. **That recommendation is superseded by §10** —
|
||
> the P2P-native SPV design with user-selectable privacy modes. §4 and
|
||
> §7 are retained as history of the design evolution.
|
||
|
||
---
|
||
|
||
## 1. Is DigiByte actually dying?
|
||
|
||
Short answer: **the chain is alive, the ecosystem is thin.** Building is
|
||
feasible; you'd be one of the more active teams in it.
|
||
|
||
- **Core is maintained.** DigiByte Core `v8.26.2` released 2026-01-16 (previous
|
||
`8.26.1` Oct 2025 shipped Taproot). Dev branch is `9.26.0`.
|
||
- **Founder gone.** Jared Tate stepped down in May 2020, publicly disengaged
|
||
in July 2023 ("$500 of DGB left, no longer meaningful involvement").
|
||
- **No foundation, no funded dev org.** Everything is volunteer. DGBAT
|
||
(~20-person outreach team) does marketing/exchange liaison, not development.
|
||
- **Market cap** roughly $65–107 M — small-cap altcoin tier. Never listed on
|
||
Coinbase. Still on Binance/Kraken/KuCoin as of the search snapshot (verify
|
||
directly if load-bearing).
|
||
- **Official mobile wallet.** iOS listing `id6481703766` "DigiByte - Wallet"
|
||
by **Sigma Systems Inc.** — a *replacement* for the old official app
|
||
(the prior repo is marked `DEPRECATED---digibyteios`). Newer repo
|
||
`digibytewallet-ios` is Electrum-based; recent App Store notes mention
|
||
an "Urgent Electrum blockchain connection error fix" — reliability has
|
||
been actively patched but the whole thing rests on one small publisher.
|
||
|
||
**Implication for us:** low competition, but no external funding, small user
|
||
base to distribute to, and real bus-factor risk in the wider ecosystem.
|
||
|
||
---
|
||
|
||
## 2. Recent hardfork — what changed, what's dead
|
||
|
||
- **Last activated fork: Taproot at block 21,168,000 (2025-04-07 UTC)**,
|
||
shipped in Core `v8.22.2`, productized in `8.26.0`.
|
||
- **Next scheduled: DigiDollar / AlgoLock at block 23,869,440** (not yet
|
||
reached; defined in `chainparams.cpp`).
|
||
|
||
Consensus/protocol changes in the recent line:
|
||
- **BIP 340/341/342** Taproot / Schnorr / MAST / Tapscript, **BIP 86**
|
||
descriptors, new witness-v1 HRP `dgb1p…`.
|
||
- **BIP 157/158** compact block filters (server-side).
|
||
- **BIP 324** encrypted v2 P2P transport.
|
||
- Protocol version 70018 → 70019.
|
||
- Coinbase maturity dropped to 8 blocks after a height threshold.
|
||
- `v8.22.0` removed legacy Odocrypt pre-fork code — anything before
|
||
Odocrypt (block 9,112,320, July 2019) is on a dead fork.
|
||
|
||
Historical relevant forks: DigiShield, MultiAlgo (5 PoW algos: SHA256,
|
||
Scrypt, Skein, Qubit, Odocrypt), MultiShield, DigiSpeed, SegWit
|
||
(activated April 2017 — DGB was first major altcoin).
|
||
|
||
**Third-party wallet compatibility right now:**
|
||
- Atomic, Exodus, Coinomi, Trust, Guarda — all light/hosted, none stranded
|
||
by any recent fork.
|
||
- **None of them issue `dgb1p…` (Taproot) addresses yet.** That is a
|
||
genuine differentiation opening for a new wallet.
|
||
|
||
---
|
||
|
||
## 3. Full-node reality (why mobile can't just run one)
|
||
|
||
- **Chain height:** ~22.77 M blocks as of 2026-01-09.
|
||
- **Block time:** 15 seconds (target across 5 algos combined).
|
||
- **Full node on disk:** roughly **45–60 GB**; pruned recommended at
|
||
`prune=8192` (~8 GB).
|
||
- **Blocks/year:** ~2,102,400 — **40× Bitcoin's** rate.
|
||
- **Just the header chain is ~1.8 GB** (22.7 M × 80 bytes) vs Bitcoin's
|
||
~70 MB. Header download + per-algo PoW validation dominate any
|
||
attempted mobile sync — this is why prior "load-all-blocks" mobile
|
||
approaches failed.
|
||
|
||
---
|
||
|
||
## 4. Lightweight-wallet options
|
||
|
||
| Approach | Verdict for DGB |
|
||
|---|---|
|
||
| **BIP37 bloom-filter SPV** | Defaults are off in Core 8.x (following Bitcoin's 2019 deprecation). Not recommended. |
|
||
| **BIP157/158 Neutrino** | Server-side code is in Core, but no maintained DGB fork of `btcd`/`lnd`/`neutrino` with DGB net params. **Effectively unavailable.** |
|
||
| **Electrum-DGB servers** | `ibbtco/electrum-dgb-server` (ElectrumX fork) exists. ~5–15 usable public servers (`electrum1.cyberbits.eu:50022` etc.). Thin but usable. |
|
||
| **Blockbook / hosted indexer** | **Best option.** SatoshiLabs' Blockbook has first-class DGB config; Trezor Suite uses it in production. NOWNodes offers hosted. Self-host for reliability. |
|
||
|
||
**Recommended architecture:**
|
||
|
||
```
|
||
┌────────────────────────────────────────────────┐
|
||
│ Mobile Wallet App │
|
||
│ │
|
||
│ Key management: bitcoinjs-lib + DGB network │
|
||
│ - BIP39 seed (12/24 word) │
|
||
│ - BIP44/49/84/86 derivation (coin type 20) │
|
||
│ - PSBT construction & signing on-device │
|
||
│ - WIF import │
|
||
│ │
|
||
│ Never leaves the phone: keys, seed, xprv │
|
||
└──────────────────┬─────────────────────────────┘
|
||
│ HTTPS + WebSocket
|
||
▼
|
||
┌────────────────────────────────────────────────┐
|
||
│ Self-hosted Blockbook (DGB config) │
|
||
│ + fallback Electrum-DGB pool │
|
||
│ - address balance / UTXO / history │
|
||
│ - tx broadcast │
|
||
└──────────────────┬─────────────────────────────┘
|
||
│
|
||
▼
|
||
DigiByte Core 8.26.x
|
||
```
|
||
|
||
Optional: background SPV header verification for trust-minimization.
|
||
|
||
**Delivery estimate:** weeks (hosted-indexer), not months (Neutrino port).
|
||
|
||
---
|
||
|
||
## 5. Seed-phrase & private-key recovery — the actual problem
|
||
|
||
The user's stated pain point: existing wallets don't reliably let you
|
||
recover DGB from a seed. Findings:
|
||
|
||
### DigiByte Core (desktop) — the root of the confusion
|
||
- Uses `wallet.dat` (BDB/sqlite) + `dumpprivkey`/`dumpwallet` RPC.
|
||
- Newer builds do expose an HD seed, **but it is NOT a portable BIP39
|
||
mnemonic.** The DigiByte Wiki explicitly warns: *"DigiByte Core wallets
|
||
cannot be restored on other BIP39-compatible apps."*
|
||
- **Do not copy this design.** This non-portability is exactly the
|
||
interoperability failure users complain about.
|
||
|
||
### Third-party wallets today — the important distinction
|
||
|
||
**Having a seed phrase is not the same as being able to import one.**
|
||
Most consumer wallets generate their own seed on first launch and only
|
||
"restore" seeds they themselves issued. Verified empirically:
|
||
|
||
| Wallet | Lists DGB | Can I *import* an external DGB seed and see my coins? | Verification status |
|
||
|---|---|---|---|
|
||
| **Atomic** | Yes | **No** — restore only accepts Atomic-generated seeds; no per-coin import; derivation path not user-visible | ✅ User-verified 2026-08-03 |
|
||
| **Exodus** | Yes | **No** — restore only accepts Exodus-generated seeds; legacy P2PKH only; no bech32; no derivation-path exposure | ✅ User-verified 2026-08-03 |
|
||
| **Guarda** | **NO — does not list DGB** | n/a | ✅ User-verified 2026-08-03 (contradicts earlier research claim) |
|
||
| **Trust Wallet** | Reportedly yes | Reportedly imports a "multi-coin wallet" seed at Trust's fixed paths; no path selection | ⚠️ Needs re-verification — earlier research on this table has been wrong twice |
|
||
| **Coinomi** | Reportedly yes | Reportedly yes, but **often needs manual account-index tweak** (…/0'H vs …/1'H); recurring support ticket | ⚠️ Needs re-verification |
|
||
| **DigiByte Go / DigiWallet (official)** | Yes | Yes — BIP39 since v1.2 per README | ⚠️ Repo state should be re-verified given the ecosystem's small size |
|
||
| **Ian Coleman BIP39 tool** (offline) | n/a | Yes — the community fallback when everything else fails | ✅ Source-verified (`hdCoin: 20`) |
|
||
|
||
**Health warning on this table:** the automated research populating the
|
||
first version overstated wallet support in at least two rows. Rows marked
|
||
⚠️ should be treated as unverified until the user or a fresh, hands-on
|
||
check confirms them. In particular, "wallet lists DGB" and "wallet lets
|
||
you import an external BIP39 seed for DGB" are separate capabilities and
|
||
the earlier research conflated them.
|
||
|
||
The ecosystem summary in one sentence: **you can back up seeds from most
|
||
of these wallets, but you cannot bring an existing DGB seed *into* the
|
||
mainstream ones (Atomic, Exodus, Trust with caveats).** This is the exact
|
||
gap your v1 must fill.
|
||
|
||
The community's "Wallet Warning" article (Medium, pappawecho) describes a
|
||
past incident where a third-party DGB wallet went offline **without following
|
||
BIP44** — users' seeds couldn't be restored anywhere. That is the incident
|
||
your requirement is really guarding against.
|
||
|
||
### Chain parameters our wallet must implement
|
||
|
||
From `src/kernel/chainparams.cpp` `CMainParams`:
|
||
|
||
| Parameter | Value |
|
||
|---|---|
|
||
| PUBKEY_ADDRESS | `30` (0x1E) → `D…` |
|
||
| SCRIPT_ADDRESS | `63` (0x3F) → `S…` |
|
||
| SECRET_KEY (WIF) | `128` (0x80) → `Q`/`L`/`K` compressed, `6` uncompressed |
|
||
| EXT_PUBLIC_KEY (xpub) | `04 88 B2 1E` |
|
||
| EXT_SECRET_KEY (xprv) | `04 88 AD E4` |
|
||
| bech32 HRP | `dgb` (→ `dgb1q…` v0, `dgb1p…` v1/Taproot) |
|
||
| Magic bytes | `FA C3 B6 DA` |
|
||
| P2P port | `12024` (RPC `14022`) |
|
||
| DNS seeds | `seed.digibyte.io`, `seed.diginode.tools`, `seed.digibyte.link`, `seed.aroundtheblock.app`, `seed.tuyul.cc` |
|
||
| SLIP-0044 coin type | **20** (`0x80000014`) |
|
||
|
||
### Derivation paths to support
|
||
|
||
```
|
||
m/44'/20'/0'/0/x → D… (legacy P2PKH)
|
||
m/49'/20'/0'/0/x → S… (P2SH-wrapped SegWit)
|
||
m/84'/20'/0'/0/x → dgb1q… (native SegWit v0) ← default
|
||
m/86'/20'/0'/0/x → dgb1p… (Taproot v1) ← differentiator
|
||
```
|
||
|
||
Supporting all four keeps us interoperable with everything above **and**
|
||
Ian Coleman's BIP39 tool (which has DGB in its coin dropdown at
|
||
`hdCoin: 20` — the community's recommended fallback).
|
||
|
||
### Recovery tools users already trust (cross-check against these)
|
||
|
||
- **Ian Coleman BIP39 tool** — `iancoleman.io/bip39`, source has
|
||
`"DGB - Digibyte"` entry
|
||
- **btcrecover / seedrecover.py**
|
||
- **hd-wallet-derive** (PHP)
|
||
- **bip_utils** (Python) — `DigibyteMainNet`
|
||
|
||
---
|
||
|
||
## 6. Libraries for the build
|
||
|
||
- **JS (recommended):** upstream `bitcoinjs-lib` accepts a custom `Network`
|
||
object — pass DGB's version bytes above and you get keygen, address
|
||
derivation, and PSBT for all four descriptor classes without needing a
|
||
fork. Cleanest path.
|
||
- Fork alternatives: `DigiByte-Team/digibytejs-lib`,
|
||
`RenzoDD/digibyte-js` (Bitcore-style).
|
||
- **.NET/C++/Python:** no maintained DGB-specific forks; `NBitcoin` and
|
||
`python-bitcoinlib` both accept custom chain params.
|
||
- **Blockbook client:** SatoshiLabs ships a JS/HTTP client — WebSocket
|
||
subscriptions for real-time balance updates.
|
||
|
||
---
|
||
|
||
## 7. Proposed build shape
|
||
|
||
**Client (mobile, React Native or Flutter):**
|
||
1. Onboarding: generate BIP39 12/24-word seed OR import existing seed
|
||
OR import raw WIF.
|
||
2. Derive addresses at all four descriptor classes; default receive to
|
||
`dgb1q…`, offer `dgb1p…` (Taproot) as an opt-in per-account setting.
|
||
3. Keys/xprv encrypted with device secure enclave + PIN; seed export
|
||
available in Settings > Backup.
|
||
4. Build & sign transactions on-device with `bitcoinjs-lib` (PSBT).
|
||
|
||
**Backend (self-hosted, one small VM):**
|
||
1. DigiByte Core 8.26.x full node.
|
||
2. Blockbook (Trezor's `digibyte.json` config).
|
||
3. HTTPS + WebSocket exposed to mobile client.
|
||
4. Fallback list of public Electrum-DGB servers baked into the app.
|
||
|
||
**Explicit non-goals (v1):** no lightning, no DigiAssets, no in-app swap,
|
||
no in-app buy. Ship the recovery-first wallet first.
|
||
|
||
### 7a. Import UX requirements (first-class, not buried in settings)
|
||
|
||
Recovery is the product's reason to exist. It gets primary onboarding real
|
||
estate, not a "restore" link in a menu.
|
||
|
||
**Onboarding entry points (equal weight on first screen):**
|
||
1. Create new wallet (generate BIP39 12/24-word seed).
|
||
2. **Import from seed phrase** — accepts any BIP39 seed from any source.
|
||
3. **Import single private key (WIF)** — accepts `Q…`/`L…`/`K…` compressed
|
||
and `6…` uncompressed.
|
||
4. Import from `xprv`/`xpub` — for advanced users or watch-only.
|
||
|
||
**"Import from seed phrase" flow — must-haves:**
|
||
- Accept 12, 15, 18, 21, or 24 words (all BIP39 lengths).
|
||
- Live word-list validation and checksum verification as the user types.
|
||
- Optional BIP39 passphrase field ("25th word"), clearly labeled as
|
||
optional, with a warning that it changes the wallet.
|
||
- **Derivation-path selection is visible, not hidden:**
|
||
- Default: **"Scan all standard paths"** — derives at BIP44/49/84/86,
|
||
coin type 20, accounts 0 through 4, and shows every path where funds
|
||
are found. This is what solves the Coinomi account-index problem
|
||
without making the user diagnose it.
|
||
- Advanced: manual path entry (`m/44'/20'/0'/0/*`, etc.) for
|
||
non-standard wallets and forensic recovery.
|
||
- Show the derivation path next to each discovered address in the review
|
||
screen — no opacity. Users need to know what they're importing.
|
||
- **Detect and warn on non-portable seeds:** if the user pastes a seed
|
||
that decodes as valid BIP39 but yields no addresses at any standard
|
||
path, offer a "This may be a DigiByte Core wallet seed — Core seeds are
|
||
not BIP39-compatible. See recovery guide." link.
|
||
|
||
**"Import private key (WIF)" flow — must-haves:**
|
||
- Validate base58 checksum before accepting.
|
||
- Verify the version byte is `0x80` (DGB WIF); reject with a clear
|
||
message if it's `0x9E` (DGB testnet), `0xEF` (Bitcoin testnet), or any
|
||
other prefix. Do not silently accept the wrong network.
|
||
- Detect compressed vs uncompressed and derive both P2PKH and
|
||
P2WPKH addresses; check balances on both; show whichever has funds
|
||
(or both if both do).
|
||
- Import as **watch-with-key** by default — the imported key is stored
|
||
separately from the HD seed and clearly labeled as "Imported" in the
|
||
account list. Do not silently merge it into the HD tree.
|
||
|
||
**"Compatibility test matrix" (must pass before ship):**
|
||
- Round-trip: Ian Coleman → our wallet → Ian Coleman.
|
||
- One-way import: seed generated in DigiByte Go → our wallet → balance
|
||
and full history visible.
|
||
- One-way import: seed generated in Coinomi at *both* account-index
|
||
variants (`…/0'H` and `…/1'H`) → our wallet auto-discovers both.
|
||
- One-way import: seed generated in Trust Wallet → our wallet.
|
||
- WIF export from Core `dumpprivkey` → wallet import → balance appears.
|
||
- Legacy-only Exodus seed → our wallet → derives `D…` addresses and
|
||
finds funds without user having to guess the format.
|
||
- **Negative test:** DigiByte Core HD seed (non-BIP39) → wallet shows
|
||
the warning above, does not silently produce empty addresses.
|
||
|
||
**Copy positioning:** the app-store one-liner is literally
|
||
*"Recover any DigiByte wallet from your seed phrase or private key."*
|
||
That's the differentiator. Lead with it.
|
||
|
||
---
|
||
|
||
## 8. Browser-extension variant (MetaMask / Rabby / Xverse style)
|
||
|
||
The mobile wallet solves the recovery pain. A **browser extension** solves
|
||
the *DigiDollar* pain — because DigiDollar's whole promise is web-based
|
||
stablecoin usage, and without a signing surface in the browser it can't
|
||
have web dApps. This is exactly the position MetaMask created for
|
||
Ethereum in 2016.
|
||
|
||
### Is a UTXO-chain browser extension even a thing? Yes.
|
||
|
||
The MetaMask model was invented for account-based EVM chains, but the same
|
||
pattern has been ported to UTXO chains successfully:
|
||
|
||
| Extension | Chain | Model |
|
||
|---|---|---|
|
||
| **Xverse** | Bitcoin, Stacks, Ordinals | Chrome/Firefox extension + mobile; injects `window.XverseProviders` |
|
||
| **Unisat** | Bitcoin, BRC-20, Ordinals | Extension only; injects `window.unisat` — became de-facto for BRC-20 dApps |
|
||
| **Leather** (ex-Hiro) | Bitcoin, Stacks | Extension; PSBT signing surface |
|
||
| **OKX Wallet** | Multichain incl. BTC | Extension |
|
||
| **Sparrow** | Bitcoin (desktop, not extension) | Reference for advanced PSBT UX |
|
||
|
||
For DigiByte the space is **empty** — there is no equivalent of any of
|
||
these. That's a moat opportunity if DigiDollar picks up.
|
||
|
||
### Architecture (extension shares almost everything with mobile)
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────┐
|
||
│ Browser Extension (Manifest V3) │
|
||
│ │
|
||
│ Popup UI (React) — send/receive, DigiDollar mint/burn │
|
||
│ Options page — seed backup, imports, network settings │
|
||
│ │
|
||
│ Background service worker │
|
||
│ - key storage (encrypted with password + WebCrypto) │
|
||
│ - PSBT signing (bitcoinjs-lib) │
|
||
│ - Blockbook RPC client │
|
||
│ │
|
||
│ Content script → injects into every page: │
|
||
│ window.digibyte = { request, on, ... } │
|
||
└──────────────────────┬───────────────────────────────────┘
|
||
│ postMessage
|
||
▼
|
||
dApp page (DigiDollar web app)
|
||
calls window.digibyte.request(...)
|
||
```
|
||
|
||
**Key management:** same `bitcoinjs-lib` + DGB network params as mobile.
|
||
Keys encrypted with WebCrypto (`AES-GCM` derived via `PBKDF2` from a
|
||
password), stored in `chrome.storage.local`. Never leaves the service
|
||
worker; popup and content scripts only ever see PSBTs and signed
|
||
transactions.
|
||
|
||
**Manifest V3 constraints to be aware of:**
|
||
- No persistent background page — service worker only. Long-running
|
||
Blockbook WebSockets need reconnection logic on wake.
|
||
- `chrome.storage.local` has a 10 MB cap; fine for keys, but tx history
|
||
should stay in IndexedDB or be re-fetched from Blockbook.
|
||
- Content-script → dApp communication via `postMessage`; requests must
|
||
be origin-checked and user-approved in a popup, MetaMask-style.
|
||
|
||
### Provider API — the DigiDollar dApp contract
|
||
|
||
Define `window.digibyte` (name TBD; consider `window.digibyteWallet` to
|
||
avoid collisions) with a small, versioned interface:
|
||
|
||
```js
|
||
window.digibyte = {
|
||
isConnected(): boolean,
|
||
request({ method, params }): Promise<any>,
|
||
on(event, handler): void,
|
||
}
|
||
```
|
||
|
||
Core methods to ship for DigiDollar to be usable:
|
||
|
||
| Method | Purpose |
|
||
|---|---|
|
||
| `dgb_requestAccounts` | Connect flow; returns array of `{address, path}` after user approves in popup |
|
||
| `dgb_getAccounts` | Cached read; returns `[]` if not connected |
|
||
| `dgb_getBalance` | For a given address |
|
||
| `dgb_signPsbt` | The workhorse — dApp builds PSBT, extension signs after user approval |
|
||
| `dgb_sendPsbt` | Sign + broadcast in one call |
|
||
| `dgb_signMessage` | BIP-322 message signing for auth flows |
|
||
| `dgb_getPublicKey` | For dApps building PSBTs client-side |
|
||
| `dgb_switchNetwork` | mainnet ↔ testnet |
|
||
| Events: `accountsChanged`, `networkChanged`, `disconnect` | Match EVM conventions so dApp developers coming from MetaMask feel at home |
|
||
|
||
For **DigiDollar-specific** operations (mint, burn, transfer of the
|
||
stablecoin), add higher-level convenience wrappers *only after* the
|
||
DigiDollar spec lands — until block 23,869,440 activates the AlgoLock
|
||
fork the surface area isn't final.
|
||
|
||
### Delivery — extension after mobile, share the crypto core
|
||
|
||
Extract `keys`, `derivation`, `psbt`, `blockbook-client`, and
|
||
`network-params` into a single `@dgb-wallet/core` TypeScript package.
|
||
Mobile (React Native) and extension (React + MV3) both depend on it.
|
||
This means:
|
||
|
||
- One place to fix a signing bug.
|
||
- Compatibility matrix runs against the shared core, not per-app.
|
||
- The core can also be published standalone as an SDK for DigiDollar
|
||
dApp developers who want to build PSBTs without the extension.
|
||
|
||
### Effort estimate
|
||
|
||
- **Mobile v1** (recovery-focused, hosted-indexer): ~6–10 weeks, one
|
||
engineer.
|
||
- **Shared core extraction:** ~1 week additional if planned from day one.
|
||
- **Extension v1** (send/receive/PSBT sign + provider API): ~4–6 weeks
|
||
once the core exists.
|
||
- **DigiDollar-specific dApp integrations:** dependent on the
|
||
DigiDollar spec finalizing.
|
||
|
||
### Strategic framing given DigiDollar
|
||
|
||
The decline symptom you named — no mobile wallet, hard recovery — is
|
||
mostly a *distribution and UX* failure, not a protocol failure. Core is
|
||
being maintained and DigiDollar is being built. Without a wallet that
|
||
(a) any user can recover on their own and (b) any web dApp can sign
|
||
through, DigiDollar ships to no one. **A mobile wallet + browser
|
||
extension pair, sharing one crypto core, is the smallest set of
|
||
software that makes DigiDollar usable at all.**
|
||
|
||
That reframes the build as "critical DigiDollar infrastructure" rather
|
||
than "another altcoin wallet," which is a much stronger pitch to the
|
||
DGBAT community for adoption, listing, and any grant funding that might
|
||
appear once DigiDollar activates.
|
||
|
||
---
|
||
|
||
## 9. Open decisions for you
|
||
|
||
1. **Platform mix:** mobile-first (RN), extension-first (Chrome MV3),
|
||
or parallel from day one with a shared TypeScript core?
|
||
2. **RN vs Flutter vs native** for the mobile side. RN wins if we're
|
||
also shipping an extension — shared `bitcoinjs-lib` + core package.
|
||
3. **Backend hosting:** self-hosted Blockbook on a VPS (one-time setup,
|
||
full control) vs paid NOWNodes (zero infra, ongoing cost)?
|
||
4. **Fork vs greenfield:** ignore the existing `digibytewallet-ios`
|
||
(Sigma Systems / Electrum-based) and build fresh, or fork it?
|
||
5. **Taproot (`dgb1p…`) support at launch:** yes (differentiator, needed
|
||
for DigiDollar path) or defer?
|
||
6. **Extension provider-API naming:** `window.digibyte` (short, may
|
||
collide) or `window.digibyteWallet` (safer, longer)?
|
||
7. **DigiDollar coordination:** wait for the DigiDollar spec to
|
||
finalize before adding stablecoin surface area, or engage
|
||
DGBAT / Core devs now to co-design the provider API?
|
||
|
||
---
|
||
|
||
## 10. Revised architecture (2026-08-03) — supersedes §4 and §7
|
||
|
||
The earlier sections defaulted to "hosted-indexer (Blockbook)" for practical
|
||
reasons — fewer moving parts, faster to ship. During review the user made
|
||
a series of points that changed the default:
|
||
|
||
1. Bitcoin/DGB is a **P2P system by design**. Connecting to one node
|
||
isn't the model; connecting to many is. Any architecture that
|
||
pretends otherwise inherits centralization the base protocol doesn't
|
||
require.
|
||
2. Centralized indexers (Blockbook, public block explorers) **collect
|
||
wallet-address queries by IP** and expose full transaction histories
|
||
of every address to the world. This is a real privacy regression from
|
||
Satoshi's design, not a feature of the chain.
|
||
3. Pruned nodes are more capable than the industry narrative suggests —
|
||
`scantxoutset` answers current-balance queries against the UTXO set
|
||
directly, without any indexer, on a pruned node.
|
||
|
||
The revised default is a **P2P-native SPV wallet with user-selectable
|
||
privacy modes**. Indexers remain available as an explicit convenience
|
||
option, never as the default.
|
||
|
||
### 10.1 Reorg safety — findings
|
||
|
||
- **No documented DGB reorg deeper than a handful of blocks** in ~12
|
||
years of operation. April 2020 51%-attack speculation was investigated
|
||
and publicly refuted by Jared Tate. No chain-explorer or post-mortem
|
||
citing a deeper reorg was surfaced.
|
||
- **Peer comparison:** Vertcoin 307-block reorg (Dec 2018), Ravencoin
|
||
X16R exploit (May–June 2020, ~$5.7 M), Litecoin 13-block MWEB reorg
|
||
(25 Apr 2026). **No 5-algo multi-PoW chain has been documented as
|
||
51%-attacked.** DGB is essentially the only widely-observed 5-algo
|
||
chain, so this is weak evidence rather than proof, but empirically
|
||
the MultiShield + 5-algo defense has held.
|
||
- **DGB Core `MIN_BLOCKS_TO_KEEP` = 288**, unchanged from Bitcoin
|
||
(`src/validation.h:56`). At 15-second block time that is ~72 minutes
|
||
of chain — a much thinner wall-clock buffer than Bitcoin's ~48 hours.
|
||
Empirically fine given DGB's reorg history, but worth knowing when
|
||
sizing a pruned node.
|
||
- **`prune=` semantics:** value in **MiB**, minimum **550**. Core
|
||
always keeps at least `MIN_BLOCKS_TO_KEEP` recent blocks regardless
|
||
of the disk budget. `prune=550` therefore covers days of recent
|
||
chain in DGB terms; you cannot practically go lower.
|
||
|
||
### 10.2 Dandelion++ (BIP156) — what it protects
|
||
|
||
Standard tx relay floods to all peers immediately; a network observer
|
||
can identify the originating node from broadcast pattern. Dandelion++
|
||
splits relay into two phases:
|
||
|
||
- **Stem phase.** Tx is forwarded hop-by-hop through one random peer
|
||
at a time.
|
||
- **Fluff phase.** At a probabilistic point (~10 hops), some node in
|
||
the stem switches to normal flooding.
|
||
|
||
Effect: the fluff-origin is somewhere random along the stem, not the
|
||
true origin. Passive observers cannot link the tx back to the sender's
|
||
IP from broadcast timing.
|
||
|
||
**What Dandelion protects — and does not:**
|
||
|
||
| Concern | Protected? |
|
||
|---|---|
|
||
| Passive network observer identifying originating IP | ✅ |
|
||
| Correlating multiple txs to same wallet via broadcast timing | ✅ Partial |
|
||
| On-chain address clustering (change-address heuristics etc.) | ❌ |
|
||
| Indexer server (Blockbook / Electrum) learning your addresses | ❌ |
|
||
| Sybil attacker controlling many peers in the stem | ⚠️ Degraded |
|
||
|
||
**Architectural consequence:** Dandelion protects broadcasts that enter
|
||
the P2P network directly. **Broadcasting via a Blockbook HTTP endpoint
|
||
bypasses Dandelion's protection for you specifically** — the operator
|
||
sees your IP and the raw tx before P2P relay begins, regardless of what
|
||
Dandelion does downstream. Any privacy-conscious mode broadcasts through
|
||
a peer relationship (own local Core, or wallet-as-P2P-participant), not
|
||
through an indexer's HTTP API.
|
||
|
||
*Verification pending:* confirm activation height and default-on status
|
||
of Dandelion in DGB Core 8.26. Server-side BIP156 support is in the
|
||
Bitcoin Core lineage DGB 8.x tracks; needs source check.
|
||
|
||
### 10.3 Broadcast semantics — correction
|
||
|
||
Blockbook does expose a broadcast endpoint (`POST /api/v2/sendtx`), but
|
||
it is a **submission funnel**, not a P2P relay participant. The flow is:
|
||
|
||
```
|
||
Wallet → HTTPS → Blockbook → RPC → its Core → P2P peers
|
||
▲
|
||
operator sees raw tx + your IP + timestamp
|
||
```
|
||
|
||
Three consequences: Dandelion protection is defeated for you specifically
|
||
(operator sees pre-relay); every user's tx goes through one operator's
|
||
Core (single-point censorship risk); the operator can correlate the tx
|
||
with prior address queries in the same session.
|
||
|
||
Blockbook broadcast belongs in the "Convenience mode with explicit
|
||
warning" bucket, never as a default.
|
||
|
||
### 10.4 Architecture — default (Maximum Privacy)
|
||
|
||
```
|
||
┌────────────────────────────────────────────────────────────┐
|
||
│ Mobile Wallet / Browser Extension │
|
||
│ │
|
||
│ Key management (@dgb-wallet/core): │
|
||
│ BIP39 seed · BIP32/44/49/84/86 derivation · PSBT sign │
|
||
│ WIF import · seed import w/ multi-path scan │
|
||
│ │
|
||
│ P2P client: │
|
||
│ • Connect to ~8 DGB peers via DNS seeds │
|
||
│ • Download block headers (~1.8 GB one-time, then trickle)│
|
||
│ • Download BIP158 compact block filters per block │
|
||
│ • Probe filters LOCALLY against wallet's scripts │
|
||
│ • Request only filter-hit blocks from any NODE_NETWORK │
|
||
│ peer │
|
||
│ • Broadcast via P2P (Dandelion protects origin) │
|
||
└────────────────────────────────────────────────────────────┘
|
||
│
|
||
│ speaks native DGB P2P (BIP324 encrypted)
|
||
▼
|
||
DGB peers on the public network
|
||
```
|
||
|
||
**Properties:** no third-party server ever sees a wallet address. No
|
||
single point of failure. Broadcast benefits from Dandelion. Read privacy
|
||
is preserved by filter-probing locally.
|
||
|
||
**Cost:** 2–4 weeks of client-side work to implement P2P + BIP158 in
|
||
TypeScript. Nearest bases: `bcoin` (JS), `nakamoto`/`neutrino` (Rust/Go).
|
||
Any of them needs DGB chainparams + a light wrapper.
|
||
|
||
### 10.5 Architecture — optional (broadcast bastion)
|
||
|
||
Users who run their own hardware can add a small pruned DGB Core:
|
||
|
||
```
|
||
Wallet ──► own pruned Core (prune=550, ~600 MB)
|
||
│
|
||
└──► P2P peers (Dandelion)
|
||
```
|
||
|
||
- Broadcast privacy: only *you* see the raw tx before P2P entry.
|
||
- Wallet still uses P2P + BIP158 for reads; Core is broadcast-only.
|
||
- Fits on ~600 MB, runs on a €4/month VPS or a local desktop.
|
||
|
||
### 10.6 Privacy modes (settings)
|
||
|
||
Four modes. Shown side-by-side in first-run wizard with one-line
|
||
trade-offs. Changeable any time. Current mode surfaced as an icon in
|
||
the app bar; per-op badges when a request leaks to a third party.
|
||
|
||
**🛡️ Maximum Privacy (default, recommended)**
|
||
- Reads: P2P + BIP158
|
||
- Broadcast: P2P direct (or own Core if configured)
|
||
- No third-party server touched
|
||
- Trade-off: slower initial sync, more device work
|
||
|
||
**⚖️ Balanced**
|
||
- Reads (address-revealing): P2P + BIP158
|
||
- Reads (metadata: fee estimate, chain tip, mempool stats): Blockbook
|
||
- Broadcast: P2P or own Core
|
||
- Trade-off: Blockbook knows you're active, not which addresses
|
||
|
||
**⚡ Convenience**
|
||
- Reads: Blockbook (yours or vetted public)
|
||
- Broadcast: Blockbook or Core, user's choice
|
||
- Fastest UX
|
||
- Trade-off: Blockbook operator sees every address you query
|
||
|
||
**🔧 Custom**
|
||
- Per-op toggles: reads / fees / broadcast independently
|
||
- Optional Tor per surface
|
||
- One-line privacy note next to every toggle
|
||
|
||
### 10.7 Design principle (for future contributors)
|
||
|
||
**Default to preserving the P2P properties of the chain. Make
|
||
convenience the user's explicit trade-off, not our default.**
|
||
|
||
Any PR that moves a read or broadcast from the P2P path to a third-party
|
||
indexer must (a) be opt-in only, (b) surface the privacy consequence in
|
||
the UI at the moment of use, and (c) not change the Maximum Privacy
|
||
mode's behavior.
|
||
|
||
### 10.7a DGB has TWO version bytes per address type — recovery must handle both
|
||
|
||
Discovered 2026-08-03 during implementation cross-check against Ian
|
||
Coleman's BIP39 tool. `src/kernel/chainparams.cpp` `CMainParams` on the
|
||
DGB Core master branch defines four legacy-compatibility constants that
|
||
matter for wallet recovery:
|
||
|
||
| Constant | Value | Purpose |
|
||
|---|---|---|
|
||
| `PUBKEY_ADDRESS` | 30 (0x1e) | Current P2PKH → `D…` |
|
||
| `SCRIPT_ADDRESS` | 63 (0x3f) | Current P2SH → `S…` |
|
||
| `SCRIPT_ADDRESS_OLD` | 5 (0x05) | **Legacy** P2SH → `3…` (Bitcoin-compatible) |
|
||
| `SECRET_KEY` | 128 (0x80) | Current WIF |
|
||
| `SECRET_KEY_OLD` | 158 (0x9e) | **Legacy** WIF |
|
||
|
||
**Why this matters:** Ian Coleman's BIP39 tool (the community's gold
|
||
standard for offline recovery) uses `scriptHash = 0x05` for DGB — the
|
||
legacy prefix. Any BIP49 address it generates starts with `3…`, not
|
||
`S…`. Older Atomic/Exodus vintages, hd-wallet-derive, and various
|
||
bitcoinjs-lib forks inherited the same legacy value.
|
||
|
||
**On-chain reality:** a P2SH output on the DGB chain is
|
||
`OP_HASH160 <20-byte-script-hash> OP_EQUAL` — the version byte is not
|
||
in the output, only in the human-readable encoding. So `3XXX…` and
|
||
`SXXX…` addresses referring to the same script-hash **refer to the
|
||
same on-chain output.** But wallets that store addresses as *strings*
|
||
(and query indexers by *string*) will silently miss funds unless they
|
||
derive both variants.
|
||
|
||
**The recovery failure mode our wallet exists to prevent:**
|
||
1. User creates seed in Ian Coleman / older Atomic / etc → receives DGB
|
||
at `3XXX…` addresses.
|
||
2. Later imports that seed into a modern wallet.
|
||
3. Modern wallet only derives `SXXX…`, queries indexer for `SXXX…`,
|
||
sees nothing.
|
||
4. User believes funds are gone; they are not.
|
||
|
||
**Same problem class for WIF:** DGB Core keeps `SECRET_KEY_OLD = 0x9e`
|
||
for backward compat. Older private-key exports may have prefix `0x9e`
|
||
rather than the current `0x80`. Import must try both.
|
||
|
||
**Implemented fix in `@dgb-wallet/core`:**
|
||
- `network.ts` exports `digibyte` (current), `digibyteLegacyP2SH`
|
||
(scriptHash 0x05), and `digibyteLegacyWIF` (wif 0x9e).
|
||
- `address.ts` exports `p2shP2wpkhAddressesBoth(node)` returning
|
||
`{ modern, legacy }`.
|
||
- `wif.ts` `importWif(wif)` tries modern 0x80 first, falls back to
|
||
legacy 0x9e, returns `{ keyPair, variant }`.
|
||
- Recovery script now scans both P2SH variants explicitly.
|
||
|
||
**Consequences downstream:**
|
||
- Any indexer-facing query for a P2SH address must be issued with both
|
||
version bytes when the seed came from an unknown source.
|
||
- New receive addresses generated by our wallet always use the current
|
||
(0x3f / 0x80) bytes.
|
||
- UX must surface when a legacy variant successfully decoded a user's
|
||
import ("This is a legacy-format key from an older DGB tool") so
|
||
they aren't confused when the same key looks different in other apps.
|
||
|
||
### 10.7b Tor by default — a fourth design principle (added 2026-08-03)
|
||
|
||
**"Every outbound socket the wallet opens goes through Tor by default.
|
||
Direct connections require an explicit user opt-out with a visible
|
||
warning."**
|
||
|
||
Applies uniformly to all backends: P2P peers, Electrum servers, HTTP
|
||
explorers, broadcast targets. No exceptions.
|
||
|
||
This tightens §10.7 from "prefer P2P over indexers" to also "prefer
|
||
Tor-wrapped sockets over clear ones." Combined, they make the wallet's
|
||
default privacy posture materially better than any other DGB wallet
|
||
currently in the ecosystem.
|
||
|
||
**Architecture:**
|
||
- A single `NetProvider` abstraction handles all outbound TCP.
|
||
- Implementations: `DirectNet`, `Socks5Net` (any local proxy),
|
||
`TorNet` (embedded).
|
||
- Every package that opens sockets (`@dgb-wallet/p2p`,
|
||
`@dgb-wallet/electrum`, any HTTP client) accepts a `NetProvider` and
|
||
never calls `net.connect` / `fetch` directly.
|
||
|
||
**Mobile:** embed Tor via `libtor` (Guardian Project, Android) and
|
||
`Tor.framework` (iCepa, iOS). ~5–10 MB app size, ~5–15s bootstrap first
|
||
launch (cached after).
|
||
|
||
**Extension:** detect Tor Browser; on Firefox use per-request `browser.proxy`
|
||
API; on Chromium recommend Tor Browser (MV3 extensions can't easily
|
||
embed Tor).
|
||
|
||
**Graceful degradation:** if Tor bootstrap fails, prompt user with the
|
||
consequence and require explicit opt-in to direct: *"Tor unavailable.
|
||
Continue over direct connection? Your IP will be visible to DGB peers."*
|
||
|
||
**Cost accepted:** +5–10 MB app size, ~5–15s first-launch bootstrap,
|
||
~300–800ms per-connection latency. All acceptable for a wallet's
|
||
request profile (low-frequency reads, low-frequency broadcasts).
|
||
|
||
### 10.7c PKI via BCH BNS (added 2026-08-03) — supersedes the WebPKI assumption
|
||
|
||
Silent Mode's BCH Name Service (BNS) at `D:\Dev\SilentMode\Argus`
|
||
provides the identity layer we were about to reinvent. The wallet's
|
||
backend is a **`.dgb` BNS name** (product decision: `rpc.dgb`) whose
|
||
on-chain records include `ip` (IPv4 to dial) and `tls` (SHA-256
|
||
fingerprint over DER of the server's cert).
|
||
|
||
**Trust chain:**
|
||
```
|
||
rpc.dgb BNS name
|
||
↓ resolveEndpoint via @dgb-wallet/bns
|
||
BCH chain (CashToken cert + OP_RETURN BNS1 records)
|
||
↓
|
||
{ ip, tls fingerprint }
|
||
↓ TLS handshake, fingerprint pinned via node:tls checkServerIdentity
|
||
VPS running DigiByte Core (disablewallet=1)
|
||
```
|
||
|
||
No ICANN, no CA/Browser Forum, no Let's Encrypt. Cert rotation is a
|
||
single on-chain UPD tx — every wallet picks up the new fingerprint at
|
||
next resolve, no client update.
|
||
|
||
**`.dgb` TLD status:** already activated in the 2026-07-30 bootstrap
|
||
of `tlds.bch`. No TLD activation needed — just register individual
|
||
names (e.g. `rpc.dgb`) via the existing `silentmode.st/register.html`
|
||
flow.
|
||
|
||
**Implementation:**
|
||
- `@dgb-wallet/bns` wraps `resolver-web.js` from Argus. `resolveEndpoint(name)`
|
||
returns `{ ip, tls }` or throws if either record is missing.
|
||
- `@dgb-wallet/rpc` `RpcClient({ bnsName, username, password })` does the
|
||
lookup and pins the TLS handshake to the on-chain fingerprint.
|
||
Direct-URL mode still exists as a dev escape hatch.
|
||
- `ops/setup.sh` provisions the VPS with a **self-signed cert** (no ACME),
|
||
prints the fingerprint at the end, ready to paste into the BNS record.
|
||
- `ops/Caddyfile.bns` uses on-disk cert instead of Let's Encrypt.
|
||
|
||
**Product name commitment:** the wallet ships as **"DigiByte.X Wallet"**
|
||
under the existing `.X` BNS TLD, distinct from other DigiByte wallets.
|
||
Product-brand "Aegis" is reserved for a future multicoin wallet.
|
||
|
||
**Distribution:** NOT under `dl.silentmode.st` — Silent Mode is scoped to
|
||
web infrastructure (browsers, resolvers, protocols). DigiByte.X Wallet
|
||
is its own product using `.dgb` TLD for its own operational needs
|
||
(`rpc.dgb`, `wallet.dgb`, `docs.dgb`, and later `usd.dgb`/`digidollar.dgb`
|
||
for DigiDollar dApp surfaces).
|
||
|
||
### 10.8 Build order (revised, 2026-08-03)
|
||
|
||
Three tracks, each shippable in independent pieces.
|
||
|
||
**Track A — Chain data (client-side privacy via BIP158)**
|
||
|
||
| # | Milestone | Status |
|
||
|---|---|---|
|
||
| A1 | Peer connect + version handshake | ✅ Done, 8/8 handshakes vs. real mainnet |
|
||
| A2 | Peer discovery (DNS seeds + `getaddr`) | |
|
||
| A3 | Header sync (`getheaders`) — ~1.8 GB one-time | |
|
||
| A4 | BIP157 negotiation + BIP158 filter download | Confirmed available: several peers advertise `NODE_COMPACT_FILTERS` |
|
||
| A5 | Filter probing (scripthash → hit → fetch block) | |
|
||
| A6 | Persistent header/filter cache | |
|
||
|
||
**Track B — Broadcast**
|
||
|
||
| # | Milestone |
|
||
|---|---|
|
||
| B1 | Broadcast via P2P (`inv` / `tx`) |
|
||
| B2 | Dandelion++ stem/fluff |
|
||
|
||
**Track C — Transport privacy**
|
||
|
||
| # | Milestone |
|
||
|---|---|
|
||
| C1 | Pluggable `NetProvider` transport abstraction |
|
||
| C2 | SOCKS5 client (wallet becomes Tor-usable via external Tor) |
|
||
| C3 | Embedded Tor on mobile (Tor by default) |
|
||
| C4 | `.onion` peer discovery + onion-only mode |
|
||
| C5 | Extension Tor story (Tor Browser detection, Firefox `browser.proxy`) |
|
||
|
||
**Track D — Persistence / UX**
|
||
|
||
| # | Milestone |
|
||
|---|---|
|
||
| D1 | Encrypted keystore (WebCrypto) |
|
||
| D2 | Recovery UX from §7a (mobile + extension shells) |
|
||
| D3 | Privacy-mode toggle UI (§10.6) |
|
||
|
||
**Empirical facts confirmed during A1 (2026-08-03):**
|
||
- DGB P2P network is alive; DNS seeds resolve to 100+ IPv4 peers.
|
||
- Chain tip observed: ~23.97M (well past DigiDollar / AlgoLock at 23,869,440 — **DigiDollar has already activated on mainnet**).
|
||
- Live peer versions: DGB Core 8.26.2, 9.26.4, 9.26.5.
|
||
- Protocol version `70019` accepted.
|
||
- `NODE_COMPACT_FILTERS` advertised by real peers — the BIP158 dependency for Maximum Privacy is real, not aspirational.
|
||
- `chainparams.cpp` magic bytes `{0xFA, 0xC3, 0xB6, 0xDA}` must be stored as integer `0xDAB6C3FA` for `writeUInt32LE`. Common gotcha; comment left in `network.ts`.
|
||
|
||
### 10.9 Legacy build-order (superseded)
|
||
|
||
1. **Now → shared `@dgb-wallet/core` TypeScript package.** BIP39, BIP32
|
||
with DGB chainparams, BIP44/49/84/86 derivation, address encoders
|
||
(`D…`, `S…`, `dgb1q…`, `dgb1p…`), WIF import/export, PSBT primitives.
|
||
No node required to develop or test. Scaffolded 2026-08-03 at
|
||
`packages/core/`.
|
||
2. **Next → P2P + BIP158 client.** Adapt from `bcoin` or write from
|
||
scratch against the DGB P2P spec. Peer discovery via DNS seeds.
|
||
Header sync, filter download, filter probing, block fetching.
|
||
3. **Then → RPC adapter for a local pruned Core** (optional bastion path).
|
||
4. **Then → mobile shell (React Native) + extension shell (Chrome MV3),
|
||
both depending on `@dgb-wallet/core`.**
|
||
5. **Later → Blockbook client** as the Convenience-mode backend.
|
||
|
||
---
|
||
|
||
## Sources
|
||
|
||
Full URLs are in the four raw research outputs (project status, hardfork,
|
||
node/SPV, seed recovery). Key references:
|
||
|
||
- github.com/DigiByte-Core/digibyte (repo, releases, chainparams.cpp)
|
||
- github.com/DigiByte-Core/digibyte/releases/tag/v8.26.0 (Taproot)
|
||
- github.com/satoshilabs/slips/blob/master/slip-0044.md (coin type 20)
|
||
- github.com/trezor/blockbook/blob/master/configs/coins/digibyte.json
|
||
- iancoleman.io/bip39 (recovery cross-check)
|
||
- dgbwiki.com/index.php?title=Common_support_queries (Core non-portability)
|
||
- github.com/DigiByte-Core/digibytego (official mobile reference)
|