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.
29 lines
1,008 B
JavaScript
29 lines
1,008 B
JavaScript
// Key tree for the Sia wallet: index i -> ed25519 key via walletd's
|
|
// KeyFromSeed(root, i), address = standard unlock hash of the public key.
|
|
// Private keys stay inside this module; sign() is the only way out.
|
|
module.exports = function makeKeys({ sia }) {
|
|
class WalletKeys {
|
|
constructor(root32) {
|
|
this._root = Uint8Array.from(root32);
|
|
this._cache = new Map();
|
|
}
|
|
entry(index) {
|
|
let e = this._cache.get(index);
|
|
if (!e) {
|
|
const k = sia.keyFromSeed(this._root, index);
|
|
e = { index, pub: k.pub, address32: k.address32, address: k.address, _priv: k.priv };
|
|
this._cache.set(index, e);
|
|
}
|
|
return e;
|
|
}
|
|
sign(entry, msg) { return sia.sign(entry._priv, msg); }
|
|
// Revealed only on explicit user action in Settings.
|
|
get seedHex() { return sia.toHex(this._root); }
|
|
wipe() {
|
|
for (const e of this._cache.values()) e._priv.fill(0);
|
|
this._cache.clear();
|
|
this._root.fill(0);
|
|
}
|
|
}
|
|
return { WalletKeys };
|
|
};
|