Aegis now covers four coins across two-step coin+network picks: BCH (mainnet + chipnet), TRX (mainnet + Nile), SC (mainnet), DGB (mainnet). - Sia (SC): pulled the standalone siawallet's lib into bundled-addons/bchwallet/lib/sia/ and wrote lib/chain-sia.js exposing the common adapter shape. The very first SC wallet the user adds in Aegis reuses purpose "siawallet/mainnet/0" so pre-Aegis funds carry over automatically; subsequent SC sub-accounts start at "bchwallet/sc/mainnet/1". Per-wallet walletd URL setting; empty URL shows a "Point Aegis at a walletd node" gate in the panel. - Vault-derive gate now honors a manifest-declared `absorbs` list, so Aegis's addon.json can list `absorbs: ["siawallet"]` and the derive() guard accepts paths under either the current id or the absorbed one — the mechanism a superseding add-on uses to inherit an older add-on's keyspace without orphaning funds. - DigiByte (DGB): lib/chain-dgb.js ports the relevant bits of the SilentCode Digibyte design — SLIP-44 coin type 20, BIP84 native SegWit (m/84'/20'/0'/0/x → dgb1q…) via ripemd160(sha256(pubkey)) + bech32. ElectrumX-DGB backend reuses lib/electrum.js (public wss:50022 pool). BIP143 P2WPKH sighash + witness-tx serialize implemented inline (no FORKID — DGB uses standard Bitcoin sighash). Derivation cross-checked against a known BIP39 vector in scratchpad/verify-dgb.mjs — the address for "abandon×11 about, m/84'/20'/0'/0/0" is dgb1q9gmf0pv8jdymcly6lz6fl7lf6mhslsd72e2jq8, matching iancoleman.io/bip39. - Panel: SVG coin logos for SC (green disc with S) and DGB (blue octagon with D) alongside the BCH/TRX marks. Chain-specific settings block per coin (walletd URL for SC; derivation path for DGB). Balance render uses BigInt-safe arithmetic so 24-decimal SC amounts don't lose precision on the way through the panel; amount input on SC returns a hastings string. - Every chain adapter's snapshot fits the panel's shared shape (address/balance/history/etc.), so future chains only need a new chain-<x>.js file, a COINS registry entry, a matching case in mountWallet, and an SVG logo. Standalone siawallet addon stays as-is on disk; users can delete it once they've confirmed Aegis shows the same balance. Nothing here disables it.
42 lines
2.3 KiB
JavaScript
42 lines
2.3 KiB
JavaScript
// Thin client for the walletd HTTP API (go.sia.tech/walletd, index mode
|
|
// "full"). Only address-scoped reads plus txpool fee/broadcast are used, so
|
|
// any public or self-hosted walletd works; the URL is a user setting.
|
|
module.exports = function makeWalletd({ log = () => {} }) {
|
|
class Client {
|
|
constructor(baseUrl) { this.setBase(baseUrl); }
|
|
setBase(baseUrl) {
|
|
const u = String(baseUrl || "").trim().replace(/\/+$/, "");
|
|
this.base = u ? (u.endsWith("/api") ? u : u + "/api") : "";
|
|
}
|
|
// Everything after the host is the node's business; only the origin is
|
|
// ever logged or shown, since hosted providers key access on the path.
|
|
get displayUrl() { try { return new URL(this.base).origin; } catch { return this.base; } }
|
|
async _req(method, path, body) {
|
|
if (!this.base) throw new Error("no walletd URL configured");
|
|
const ctrl = new AbortController();
|
|
const timer = setTimeout(() => ctrl.abort(), 25000);
|
|
try {
|
|
const res = await fetch(this.base + path, {
|
|
method, signal: ctrl.signal,
|
|
headers: body !== undefined ? { "content-type": "application/json" } : {},
|
|
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
});
|
|
const text = await res.text();
|
|
if (!res.ok) throw new Error(`walletd ${res.status}: ${text.slice(0, 200).trim()}`);
|
|
try { return JSON.parse(text); } catch { return text; }
|
|
} finally { clearTimeout(timer); }
|
|
}
|
|
get(path) { return this._req("GET", path); }
|
|
post(path, body) { return this._req("POST", path, body); }
|
|
|
|
tip() { return this.get("/consensus/tip"); }
|
|
// Recommended fee in hastings per byte (JSON string).
|
|
async feePerByte() { return BigInt(String(await this.get("/txpool/fee")).replace(/"/g, "")); }
|
|
balance(addr) { return this.get(`/addresses/${addr}/balance`); }
|
|
// { basis, outputs: [SiacoinElement] } — proofs are valid at `basis`.
|
|
outputs(addr, limit = 100, offset = 0) { return this.get(`/addresses/${addr}/outputs/siacoin?limit=${limit}&offset=${offset}`); }
|
|
events(addr, limit = 25, offset = 0) { return this.get(`/addresses/${addr}/events?limit=${limit}&offset=${offset}`); }
|
|
broadcast(basis, v2tx) { return this.post("/txpool/broadcast", { basis, transactions: [], v2transactions: [v2tx] }); }
|
|
}
|
|
return { Client };
|
|
};
|