// 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 }; };