灵符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/ui/wallet.ling
# wallet.ling — WALLET: balance, own address and recent activity.

# "67.9988 LNG" with the fraction dimmed; returns the width.
fn big_amount(x, base, size, atomic, col) {
    bind s = format_lng(atomic)
    bind parts = str_split(s, ".")
    bind w = round(t_text_sp(F_HEAD, size, x, base, list_get(parts, 0), col, 1))
    if len(parts) > 1 {
        bind w = w + round(t_text_sp(F_HEAD, size * 0.72, x + w + 1, base, "." + list_get(parts, 1), shade(col, 0.35), 1)) + 1
    }
    bind w = w + 12
    bind w = w + round(t_text_sp(F_HEAD, size * 0.42, x + w, base, "LNG", C_TEXT_DIM, 2))
    return w
}

fn wallet_draw(ax, ay, aw, ah) {
    bind s = d_summary()
    if s == () { return () }
    bind top_h = 232
    bind bw = floor(aw * 55 / 100)
    bind in1 = panel(ax, ay, bw, top_h, "BALANCE", C_GREEN)
    bind x = list_get(in1, 0)
    bind y = list_get(in1, 1)
    bind iw = list_get(in1, 2)
    label(x, y + 16, "Available", C_TEXT_DIM)
    big_amount(x, y + 72, 46, s.unlocked, C_TEXT_STRONG)
    bind py = y + 104
    hline(x, py, iw, C_LINE_FAINT, 1)
    hatch(x, py + 1, 64, 3, C_GREEN, true, 3, 0.6)
    bind ry = py + 32
    disc(x + 4, ry - 5, 3.5, C_YELLOW, 1)
    label(x + 16, ry, "Pending", C_TEXT_DIM)
    bind pw = round(t_text(F_MONO, 24, x + 96, ry + 1, "+" + format_lng(s.pending), C_YELLOW))
    t_text(F_UI, 15, x + 96 + pw + 12, ry, "spendable after 10 confirmations", C_TEXT_FAINT)
    bind ty = ry + 30
    label(x + 16, ty, "Total", C_TEXT_DIM)
    t_text(F_MONO, 24, x + 96, ty + 1, format_lng(s.unlocked + s.pending), C_TEXT)
    bind bbw = 112
    bind bx = x + iw - 2 * bbw - 12
    if button(bx, y, bbw, 36, "Send", C_ORANGE, "plain", true, false, "out") { set_section(1) }
    if button(bx + bbw + 12, y, bbw, 36, "Receive", C_BLUE, "plain", true, false, "in") { set_section(2) }

    bind in2 = panel(ax + bw + 24, ay, aw - bw - 24, top_h, "MY ADDRESS", C_BLUE)
    bind x = list_get(in2, 0)
    bind y = list_get(in2, 1)
    bind iw = list_get(in2, 2)
    identicon(x, y + 4, 92, s.address_hash)
    bind tx = x + 112
    label(tx, y + 14, "Short address", C_TEXT_DIM)
    bind lines = grouped(s.short_address, sel(x + iw - tx > 230, 4, 3))
    bind i = 0
    while i < len(lines) {
        t_text(F_MONO, 22, tx, y + 40 + i * 22, list_get(lines, i), C_TEXT_STRONG)
        bind i = i + 1
    }
    bind fy = y + 4 + 92 + 34
    label(x, fy, "Fingerprint", C_TEXT_DIM)
    draw_fingerprint(x + 108, fy + 1, 24, fingerprint(s.address_hash), C_TEXT)
    bind cy = fy + 24
    if copy_btn(x + iw - copy_btn_w("Copy"), cy, "Copy", C_BLUE) { clip_copy(s.short_address, "Address") }
    t_text(F_UI, 15, x, cy + 23, "Payers check this fingerprint.", C_TEXT_FAINT)

    bind ly = ay + top_h + 32
    bind lh = ah - top_h - 32
    bind in3 = panel(ax, ly, aw, lh, "ACTIVITY", C_GREEN)
    bind x = list_get(in3, 0)
    bind y = list_get(in3, 1)
    bind iw = list_get(in3, 2)
    bind hist = st_get("d_history", [])
    bind count = len(hist)
    t_right(F_UI, 15, x + iw, y - 2, num_str(count) + sel(count == 1, " transaction", " transactions"), C_TEXT_FAINT)
    bind lx = x - 8
    bind lty = y + 8
    bind lw = iw + 16
    bind lhh = ly + lh - lty - 16
    bind row_h = 64
    bind max_scroll = max(0, count * row_h - lhh)
    bind scroll = clampf(st_get("w_scroll", 0) + u_scroll_in(lx, lty, lw, lhh), 0, max_scroll)
    st_set("w_scroll", scroll)
    clip_push(lx, lty, lw, lhh)
    if count == 0 { t_center(F_UI, 17, lx, lty, lw, lhh, "No transactions yet. Mining rewards and payments will appear here.", C_TEXT_FAINT) }
    bind j = 0
    while j < count {
        bind ry2 = lty + j * row_h - scroll
        if ry2 + row_h > lty && ry2 < lty + lhh {
            tx_row(lx, ry2, lw, row_h - 4, list_get(hist, j))
        }
        bind j = j + 1
    }
    clip_pop()
    if max_scroll > 0 {
        bind th = floor(lhh * lhh / (count * row_h))
        fill(lx + lw + 4, lty + floor((lhh - th) * scroll / max_scroll), 2, th, C_LINE)
    }
}

fn tx_row(x, y, w, h, tx) {
    bind hot = u_hover(x, y, w, h)
    fill(x, y, w, h, sel(hot, C_ROW_HOVER, C_BG_DEEP))
    outline(x, y, w, h, C_LINE_FAINT, 1)
    bind col = C_GREEN
    bind icon = "in"
    bind title = "Received"
    if tx.direction == "out" {
        bind col = C_ORANGE
        bind icon = "out"
        bind title = "Sent"
    }
    if tx.direction == "mined" {
        bind col = C_YELLOW
        bind icon = "mined"
        bind title = sel(tx.height >= 0, "Mined block " + num_str(tx.height), "Mined")
    }
    fill(x, y, 3, h, col)
    bind ty = y + floor((h - 40) / 2)
    outline(x + 16, ty, 40, 40, shade(col, 0.4), 1)
    brackets(x + 16, ty, 40, 40, 6, col, 1)
    icon_draw(icon, x + 28, ty + 20, col)
    bind tx0 = x + 72
    bind tw = round(t_text(F_UI, 19, tx0, y + 26, title, C_TEXT_STRONG))
    bind bx = tx0 + tw + 12
    if tx.counterparty != "" {
        bind bx = bx + round(t_text(F_MONO, 20, bx, y + 26, "to " + short_mid(tx.counterparty, 8, 4), C_TEXT_DIM)) + 12
    }
    if tx.reduced { badge(bx, y + 20, "Reduced ring", C_RED, true) }
    if tx.memo != "" {
        t_text(F_UI, 16, tx0, y + 48, "\"" + tx.memo + "\"", C_TEXT)
    } else if tx.height < 0 {
        t_text(F_MONO, 18, tx0, y + 48, "in mempool", C_TEXT_FAINT)
    } else {
        t_text(F_MONO, 18, tx0, y + 48, "txid " + substr(tx.txid, 0, 12) + "…", C_TEXT_FAINT)
    }
    bind sign = sel(tx.direction == "out", "-", "+")
    bind acol = sel(tx.direction == "out", lift(C_ORANGE, 0.1), lift(C_GREEN, 0.1))
    t_right(F_MONO, 26, x + w - 20, y + 27, sign + format_lng(tx.amount) + " LNG", acol)
    bind aw = round(t_right(F_UI, 15, x + w - 20, y + 48, ago(tx.timestamp), C_TEXT_FAINT))
    bind conf = tx.confirmations
    bind mx = x + w - 20 - aw - 16 - 50
    bind k = 0
    while k < 10 {
        bind lit = k < min(conf, 10)
        fill(mx + k * 5, y + 39, 3, 9, sel(lit, sel(conf >= 10, C_METER_G, C_METER_Y), C_LINE_SOFT))
        bind k = k + 1
    }
    bind ct = sel(conf == 0, "unconfirmed", num_str(conf) + " conf")
    bind cw = round(t_right(F_UI, 15, mx - 8, y + 48, ct, C_TEXT_DIM))
    if tx.fee > 0 { t_right(F_UI, 15, mx - 8 - cw - 14, y + 48, "fee " + format_lng(tx.fee), C_TEXT_FAINT) }
}

← Back to index