L
ling-wallet
↓ 0 downloadsLing Wallet: a post-quantum privacy-coin wallet, full node and HyperTorus miner for LNG
Keywords wallet, cryptocurrency, lng, node, miner, ling
lingfu install ling-walletCode / Files (116)
README.md
<div align="center">
# 🪙 Ling Wallet
### A post-quantum privacy wallet, full node and miner for **LNG** — in one app, written entirely in [Ling](https://ling-lang.org).
`post-quantum` · `private by default` · `no accounts, no KYC` · `wallet + node + miner` · `one language`
</div>

> [!WARNING]
> **LNG is a new, unaudited, experimental coin.** The cryptography is built on
> standard primitives, but the ring signature and proof-of-work are novel, the
> network is small, and nothing here has had an external security review. Read
> [`docs/THREAT_MODEL.md`](docs/THREAT_MODEL.md) before trusting it with anything
> you can't afford to lose.
---
## ✨ What makes it different
Most coins were designed before quantum computers were a planning concern, and
most wallets are a thin client that trusts someone else's node. Ling Wallet is
built the other way around:
| | |
|---|---|
| 🔐 **Post-quantum from day one** | Identities, key exchange and the wallet file use **ML-DSA-87**, **ML-KEM-1024** and **X25519** in hybrid — an attacker who records your traffic today still can't read it after quantum computers arrive. |
| 🥷 **Private by default** | Every payment uses a **fresh one-time address**, a **ring signature** over same-value decoys, and fixed denominations. There is no "transparent mode" to forget to turn on. |
| 🧅 **Network privacy built in** | **Dandelion++** hides which node made a transaction, frames are padded with cover traffic, and all outbound traffic can go over **Tor** with no DNS leaks. |
| 🏠 **You are the node** | The app *is* a full node. It validates the whole chain itself — it never asks a server for your balance, so no one learns your addresses by watching your queries. |
| ⛏️ **Mine from the same app** | A background miner runs on spare cores, visualized as a 4-D **HyperTorus** walk. No pool, no separate software. |
| 🧬 **One language, no C** | Node, wallet, miner, UI and tests are all **Ling**. The whole thing is readable top to bottom, with no foreign-function glue. |
---
## 🆚 How it compares
An honest comparison. Ling Wallet leads on *design* — post-quantum security and
privacy that's on by default — while established coins lead on *maturity*: they
are audited, have huge anonymity sets, and have survived years of attack.
| | **Bitcoin** | **Monero** | **Zcash** | **🪙 Ling Wallet / LNG** |
|---|:---:|:---:|:---:|:---:|
| **Private by default** | ❌ transparent | ✅ always | ⚠️ opt-in (shielded) | ✅ always |
| **Post-quantum** | ❌ ECDSA | ❌ Ed25519 | ❌ | ✅ **hybrid PQ** |
| **Hidden recipient** | ❌ | ✅ stealth addrs | ✅ shielded | ✅ one-time keys |
| **Hidden sender** | ❌ | ✅ ring sigs | ✅ zk-SNARKs | ✅ **lattice ring sigs** |
| **No trusted setup** | ✅ | ✅ | ⚠️ (historically) | ✅ |
| **Built-in full node** | ⚠️ separate | ⚠️ separate | ⚠️ separate | ✅ **in the app** |
| **Built-in miner** | ❌ (pools) | ⚠️ separate | ❌ | ✅ **in the app** |
| **Tor / Dandelion++** | ⚠️ add-on | ✅ | ⚠️ partial | ✅ built in |
| **Accounts / KYC** | none | none | none | **none** |
| **Supply cap** | 21 M | ∞ (tail) | 21 M | **21 M + tail** |
| **Maturity** | 🟢 battle-tested | 🟢 audited | 🟢 audited | 🔴 **experimental, unaudited** |
| **Anonymity set** | 🟢 huge | 🟢 huge | 🟡 medium | 🔴 **small (new)** |
**The honest summary:** if you need proven, audited money today, use an
established coin. If you want to see what a wallet looks like when **post-quantum
security and default privacy are the starting point, not a retrofit** — and you
treat it as the experiment it is — that's Ling Wallet.
---
## 🛡️ The security stack
Every layer, and whether it's a vetted standard or something new:
```
┌─────────────────────────────────────────────────────────────────────┐
│ 🔑 IDENTITY & SIGNING ML-DSA-87 (FIPS 204) [standard]│
│ 🤝 KEY EXCHANGE X25519 + ML-KEM-1024 (FIPS 203)[standard]│
│ 🔒 ENCRYPTION XChaCha20-Poly1305 [standard]│
│ 🧂 PASSWORD → KEY Argon2id 256 MiB · 3 passes [standard]│
│ #️⃣ HASHING SHAKE256 (SHA-3) [standard]│
│ 🥷 SENDER PRIVACY LRS-87 lattice ring signatures [experimental]│
│ 🧅 NETWORK PRIVACY Dandelion++ · padded frames · Tor │
│ ⛏️ PROOF OF WORK HyperTorus memory-hard walk [novel] │
└─────────────────────────────────────────────────────────────────────┘
standard = NIST-standardized or widely vetted
experimental = research-grade, flagged in the UI
novel = designed here; a flaw can at worst speed up mining
```
The **About** page inside the app lists every one of these with its status, and
[`docs/THREAT_MODEL.md`](docs/THREAT_MODEL.md) spells out exactly what each does
and does **not** protect — including a known sender-tracing leak and its
mitigation.
---
## 🏗️ How the app is built
The UI never touches keys or the network. Each job runs in its own **isolate**
(a sandboxed thread) with only the capabilities it needs, and they talk over
channels:
```mermaid
graph TD
UI["🖥️ UI thread<br/>windows · input · drawing<br/><i>no capabilities to keys</i>"]
W["🔑 walletd isolate<br/>keys · scanning · signing<br/><i>caps: keys, db, fs</i>"]
N["🌐 node isolate<br/>chain · mempool · P2P<br/><i>caps: db, fs, p2p</i>"]
M["⛏️ miner isolates ×N<br/>one per core<br/><i>no capabilities</i>"]
NET(["🧅 LWP-1 network<br/>peers · Tor"])
UI <-->|"requests<br/>(wiped channel)"| W
UI <-->|status| N
W <-->|"tip · submit · bundles"| N
N <-->|templates| M
M -->|solved blocks| N
N <-->|encrypted frames| NET
```
- The **node** holds `p2p` but never `keys` — a network attacker who found a bug
in it still can't reach your spending keys.
- The **wallet** holds `keys` but never `p2p` — it never talks to the internet.
- **Miners** get **no** capabilities at all.
- The UI asks the wallet for things over a **separate, wiped channel**, so
passwords and seed words don't linger.
---
## 📸 A look inside
| | | |
|:---:|:---:|:---:|
|  **Balance & activity** |  **Send to a verified address** |  **Your address & QR** |
|  **HyperTorus miner** |  **Peers & supply audit** |  **Phrase & auto-lock** |
---
## 🚀 Quick start
Ling Wallet runs on the [Ling](https://ling-lang.org) runtime — one build gives
you both `ling` and the `lingfu` package tool.
```sh
cd ../ling && cargo build --features web # once (builds ling and lingfu)
cd ../ling-wallet
lingfu run # live node — connects to the network and syncs
lingfu run --mock # simulated backend — no network, for a look around
```
`lingfu run` reads `entry` from [`Ling.toml`](Ling.toml) and runs
`ling/main.ling`. Any flags after `run` are passed through to the wallet:
| flag | default | meaning |
|---|---|---|
| `--data-dir D` | `%APPDATA%\LingWallet\mainnet` | wallet file, chain database, peer data |
| `--listen HOST:PORT` | `0.0.0.0:18780` (`none` with `--proxy`) | where this node accepts peers; `none` = outbound only |
| `--peer HOST:PORT` | — | a peer to connect to (repeatable) |
| `--proxy 127.0.0.1:9050` | — | send **all** connections through Tor / SOCKS5 |
| `--mock` | — | simulated backend (UI development, screenshots) |
Your 24-word recovery phrase **is** your wallet — write it on paper, store it
safely, and never photograph it. Keys never leave your computer.
---
## 🌐 Running on a real network
Nodes find each other through **seeds**: always-on nodes listed in a file signed
by the seed authority (`keys/seed-authority.key`, whose public key is compiled
into every wallet). A tampered list is ignored. Once connected, nodes gossip the
other reachable nodes they know, so a wallet needs only one working seed.
**1. Run a seed node** on a machine with a public IP or DNS name (a VPS, or a
home PC with TCP 18780 forwarded), and open TCP 18780 in its firewall:
```sh
ling run ling/seednode.ling --data-dir /srv/lng --mine 2 --pay-to @payout.txt
```
It writes its identity public key to `/srv/lng/node_identity.pub`. `--pay-to` is
where block rewards go — a wallet's key bundle (**Receive → Copy bundle**, the
`lngkey1…` text) or `@file` holding it. Without one, `--mine` does nothing. The
node remembers the address, so later starts can drop `--pay-to`.
**2. Sign a seed list** naming it (on the machine holding the authority key):
```sh
ling run ling/tools/seeds.ling sign --authority keys/seed-authority.key \
--out ling/assets/seeds.lwseeds seed.example.org:18780=@node_identity.pub
ling run ling/tools/seeds.ling show ling/assets/seeds.lwseeds
```
**3. Ship it.** `ling/assets/seeds.lwseeds` goes out with the wallet, and every
wallet installs it into its data folder on start when it's newer. A wallet with
a seed list needs no `--peer`.
> 💡 A home IP can change — give the seed a **DNS name** and sign the list with
> that, so an IP change only needs a DNS update, not a new list in every wallet.
> Wallets behind a router need nothing forwarded (they connect out); forwarding
> the port only makes a node reachable so it can help relay.
---
## ⚠️ Honest limitations
This is where an experiment differs from money you'd rely on:
- **No external audit.** The code has had internal review (see
[`docs/THREAT_MODEL.md`](docs/THREAT_MODEL.md)) and nothing more.
- **Novel crypto.** The LRS-87 ring signature is research-grade and has had no
independent cryptanalysis. There is a known **sender-tracing** leak: whoever
*paid you* can tell when you later spend those exact coins — churn coins from
parties you don't trust.
- **Small anonymity set.** Ring signatures hide you among others holding the same
denomination; while few people use LNG, there are few to hide among. The wallet
flags "reduced ring" spends.
- **Visible amounts.** Each output is a public standard denomination (post-quantum
hidden amounts aren't practical yet); a payment's *total* isn't linked, though.
- **Malware is out of scope.** If someone controls your computer, they can read
keys as you type. Use a dedicated, encrypted, up-to-date machine.
---
## 📁 Layout
```
ling/
main.ling window + frame loop
backend.ling be_* contract → real_backend.ling or mock.ling
real_backend.ling spawns and talks to the isolates below
seednode.ling headless seed node for a server
isolates/node.ling chain, mempool, P2P (caps: db, fs, p2p)
isolates/walletd.ling keys, scanning, signing (caps: keys, db, fs)
isolates/miner.ling one per core (no capabilities)
core/ consensus: params, codec, money, chain, mempool, wallet
ui/ screens, widgets, theme, HyperTorus visualizer
tools/seeds.ling node identity · sign / show seed lists
tests/ crypto, threads, p2p, chain, nodes test programs
selftest.ling drives the real backend end to end
docs/ DESIGN (consensus spec), THREAT_MODEL, LING_API, LING_BACKEND
```
## 🧪 Tests
```sh
cd ling/tests/crypto && ling run --interp t_crypto.ling # 204 checks
cd ling/tests/threads && ling run --interp t_basic.ling # 72
cd ling/tests/p2p && ling run --interp t_p2p.ling # 71
cd ling/tests/chain && ling run --interp t_chain.ling # 19: mine, send, double-spend, reorg
cd ling/tests/nodes && ling run --interp t_nodes.ling # 7: two nodes sync over P2P
cd ling && ling run --interp selftest.ling --data-dir <empty dir> --fast-kdf 1 --listen 127.0.0.1:18795 # 22
```
---
<div align="center">
**Built with [Ling](https://ling-lang.org)** · MIT license · an experiment, not a bank
*Read [`docs/THREAT_MODEL.md`](docs/THREAT_MODEL.md) before you trust it.*
</div>