灵符lingfu
L

ling-wallet

↓ 0 downloads

Ling Wallet: a post-quantum privacy-coin wallet, full node and HyperTorus miner for LNG

Windows · x86-64 ✕Linux · x86-64 ✕LingOS · x86-64LingOS · Pi 5 ARM64 ✕
Keywords wallet, cryptocurrency, lng, node, miner, ling
lingfu install ling-wallet
LicenseMIT
Authorsling-lin
READMECode / FilesVersionsDependency GraphDependentsSecurityBuildsSettings

Code / Files (116)

ling/selftest.ling
# selftest.ling — drives the real backend exactly as the UI does (no
# window): node + wallet + miner isolates, create/lock/unlock, mining to the
# new wallet, password checks.
#
#   ling run --interp selftest.ling --data-dir <empty dir> --fast-kdf 1 --listen 127.0.0.1:18795

use "api.ling"
use "real_backend.ling"

fn check(name, cond) {
    if cond {
        print("PASS ", name)
        st_add("pass", 1)
    } else {
        print("FAIL ", name)
        st_add("fail", 1)
    }
    return cond
}

fn is_ok(r) {
    return match r {
        ok(v) => true,
        bad(e) => false,
    }
}

fn pump(secs) {
    bind deadline = epoch_now() + secs
    while epoch_now() < deadline {
        real_tick()
        sleep(50)
    }
    return 0
}

bind start = do {
    shared_put("test_genesis_difficulty", "1")
    real_init()
    pump(2)
    check("fresh install shows no wallet", real_state() == "nowallet")
    check("short password rejected", is_ok(real_create("short")) == false)
    bind created = real_create("correct horse battery")
    check("wallet created", is_ok(created))
    bind words = match created {
        ok(w) => w,
        bad(e) => [],
    }
    check("24-word recovery phrase", len(words) == 24)
    pump(2)
    bind s = real_summary()
    check("summary available after create", is_ok(s))
    bind addr = s.x.short_address
    check("short address looks right", starts_with(addr, "lng1"))

    # Our own address resolves locally (published by the wallet isolate).
    bind lk = ["pending"]
    bind deadline = epoch_now() + 15
    while list_get(lk, 0) == "pending" && epoch_now() < deadline {
        bind lk = real_lookup(addr)
        pump(0.3)
    }
    check("own address resolves and verifies", list_get(lk, 0) == "verified")
    check("lngkey1 export available", starts_with(real_export_bundle(), "lngkey1"))

    # Passive mining to the new wallet.
    real_set_mining(true, 1, 100, false)
    bind deadline = epoch_now() + 120
    while epoch_now() < deadline && st_get("blocks_found", 0) < 3 {
        real_tick()
        sleep(100)
    }
    check("miner found blocks", st_get("blocks_found", 0) >= 3)
    pump(5)
    check("hashrate reported", real_mining().hashrate > 0)
    bind hist = real_history(50)
    bind mined = 0
    bind i = 0
    while i < len(hist) {
        if list_get(hist, i).direction == "mined" {
            bind mined = mined + 1
        }
        bind i = i + 1
    }
    check("mined coinbases appear in history", mined >= 1)
    bind s2 = real_summary().x
    check("young coinbases are pending, not spendable", s2.pending > 0 && s2.unlocked == 0)
    check("sending with no unlocked funds is refused", is_ok(real_prepare(addr, 100000000, "")) == false)
    real_set_mining(false, 1, 100, false)

    # Lock / unlock / passwords.
    real_lock()
    pump(1)
    check("locked", real_state() == "locked")
    check("summary hidden while locked", is_ok(real_summary()) == false)
    check("wrong password rejected", is_ok(real_unlock("wrong password!!")) == false)
    check("right password unlocks", is_ok(real_unlock("correct horse battery")))
    bind rev = real_reveal("correct horse battery")
    check("reveal returns the same phrase", is_ok(rev) && list_join(rev.x, " ") == list_join(words, " "))
    check("reveal with wrong password refused", is_ok(real_reveal("nope nope nope")) == false)
    check("change password", is_ok(real_change_password("correct horse battery", "new horse battery staple")))
    real_lock()
    pump(1)
    check("old password no longer works", is_ok(real_unlock("correct horse battery")) == false)
    check("new password works", is_ok(real_unlock("new horse battery staple")))

    print("")
    print(format("{} passed, {} failed", st_get("pass", 0), st_get("fail", 0)))
    chan_try_send(st_get("node_send", ""), ["shutdown"])
    chan_try_send(st_get("wallet_send", ""), ["shutdown"])
    quit()
}

← Back to index