Second bundled wallet, same shape as bchwallet:
- keys: api.vault.derive("siawallet/mainnet/0") as the seed for walletd's
KeyFromSeed(seed, index) (blake2b(seed||index) -> ed25519); addresses are
standard unlock hashes, so a future walletd seed import yields the same
addresses. Seed and keys live in memory only.
- lib/sia.js: Sia binary encoder, StandardUnlockHash, address checksum,
v2 InputSigHash ("sia/sig/input|" + replay byte 2 + transaction
semantics), transaction weight, walletd JSON. Address hashing and the
sighash were verified against real mainnet v2 transactions (signatures
from block 591853 verify under this implementation).
- lib/walletd.js: address-scoped walletd HTTP client (tip, fee, balance,
outputs with proofs, events, broadcast). The node URL is a user setting
with no default; hosted providers embed the access key in the path, so
only the origin is ever displayed or logged.
- lib/wallet.js: gap-limit discovery via events, mature/immature balance,
history deltas from v1/v2/foundation/miner events, largest-first
selection with change to the current address, fee = walletd rate x
weight x 1-3 multiplier, broadcast with the outputs' basis. A signed tx
built here was accepted structurally by a live walletd (rejected only
for the stub key not owning the parent).
- panel: Receive (QR), Send, History, Settings (node URL, derivation info,
seed reveal behind approval, connected sites); gates for locked vault,
no vault, no node URL.
- window.siacoin dapp bridge: getAddress (rememberable), signAndSend with
100/1,000/10,000 SC allowances, signMessage (ed25519 over blake2b-256 of
the message) — same approval and permission rules as the BCH wallet.
27 lines
1.3 KiB
JavaScript
27 lines
1.3 KiB
JavaScript
// Dapp bridge for Sia, run in the isolated world of pages matching
|
|
// addon.json "page-inject".origins. Exposes window.siacoin; every call goes
|
|
// through the wallet's activate() context in main, which shows the approval
|
|
// overlay and enforces per-origin permissions.
|
|
//
|
|
// `theseus` is provided by the host: { id, origin, contextBridge, invoke }.
|
|
const call = (msg, payload) =>
|
|
theseus.invoke(msg, payload).catch((e) => {
|
|
const text = String(e && e.message || e).replace(/^Error invoking remote method '[^']+': (Error: )?/, "");
|
|
throw new Error(text);
|
|
});
|
|
|
|
theseus.contextBridge.exposeInMainWorld("siacoin", {
|
|
isTheseus: true,
|
|
version: "0.1.0",
|
|
network: "mainnet",
|
|
// Current receiving address (76-hex). First call per origin asks the user;
|
|
// "always allow" makes later calls silent.
|
|
getAddress: () => call("getAddress"),
|
|
// txSpec: { to, amount } or { outputs: [{ to, amount }] } — amounts are
|
|
// hastings as decimal strings (1 SC = 1e24). Always approval-gated;
|
|
// resolves { txid }.
|
|
signAndSend: (txSpec) => call("signAndSend", txSpec && typeof txSpec === "object" ? txSpec : {}),
|
|
// ed25519 signature over blake2b-256(message) with the current address's
|
|
// key. Always approval-gated; resolves { address, publicKey, signature }.
|
|
signMessage: (message) => call("signMessage", { message: String(message ?? "") }),
|
|
});
|