chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
// Fiat prices for every Aegis-supported coin. Poll every enabled source in
|
|
|
|
|
// parallel and reconcile per chain: if two or more sources agree within a
|
|
|
|
|
// small band (±3% of the median), take their median as the truth; if none
|
|
|
|
|
// agree, fall back to the median of every reported value. This kills any
|
|
|
|
|
// single oracle's ability to make Aegis show a wrong number — a spoofed
|
|
|
|
|
// or wildly stale feed on one origin is outvoted by the others.
|
feat(theseus/aegis): 0.6.1 — in-panel vault setup/unlock, BCH wallet imports, opt-in fiat prices, WizardConnect
Aegis Wallet 0.4.4 → 0.6.1:
- Vault lifecycle from the wallet gate. The locked / not-yet-created states
now show a master-password form (with optional BIP39 mnemonic on setup)
instead of redirecting users to Settings › Passwords. New
api.vault.lifecycle {status, setup, unlock, lock} in addons-host, gated by
the existing "vault-derive" capability. api.openSettings(section) also
added; settings.html honours a #section hash on open.
- Imported BCH wallets (design M.1a, read-only). Paste a mnemonic + BIP44
path or a WIF; the cashaddr is derived in the add-on, the signer material
goes to a separate wallet-imports.enc via api.vault.imports {list, add,
remove, signer}. Argus password-vault gains createImports / unlockImports /
saveImports with its own KDF salt so the imports key is disjoint from the
passwords key. lib/chain-bch-imported.js is a single-address Electrum
adapter; spend support is deferred to M.1b.
- Opt-in USD prices via CoinGecko (lib/prices.js), off by default, persisted
in add-on storage. Fiat lines under balances, in the wallet picker, and a
portfolio total when 2+ wallets are open. Settings tab is now reachable
while the vault is locked so the toggle is always available.
- WizardConnect wallet-side pairing for BCH wallets (lib/wc.js, lib/wc-sign.js).
@wizardconnect/{core,wallet} are loaded dynamically via api.import to stay
on the right side of LGPL §4d. Sign requests go through approvalModal and
are restricted to P2PKH inputs with SIGHASH_ALL|FORKID|UTXOS.
- DGB adapter load is now soft-fail: when Aegis runs from userData/addons the
bundled ESM can't resolve peer deps, so DGB becomes unavailable instead of
taking the whole add-on down.
2026-09-09 10:33:21 +02:00
|
|
|
//
|
chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
// The user-facing model in 0.6.36+ is just "on / off": no source picker,
|
|
|
|
|
// no per-source config. Adding a new oracle here fans out to everyone
|
|
|
|
|
// with no UI churn.
|
feat(theseus/aegis): 0.6.1 — in-panel vault setup/unlock, BCH wallet imports, opt-in fiat prices, WizardConnect
Aegis Wallet 0.4.4 → 0.6.1:
- Vault lifecycle from the wallet gate. The locked / not-yet-created states
now show a master-password form (with optional BIP39 mnemonic on setup)
instead of redirecting users to Settings › Passwords. New
api.vault.lifecycle {status, setup, unlock, lock} in addons-host, gated by
the existing "vault-derive" capability. api.openSettings(section) also
added; settings.html honours a #section hash on open.
- Imported BCH wallets (design M.1a, read-only). Paste a mnemonic + BIP44
path or a WIF; the cashaddr is derived in the add-on, the signer material
goes to a separate wallet-imports.enc via api.vault.imports {list, add,
remove, signer}. Argus password-vault gains createImports / unlockImports /
saveImports with its own KDF salt so the imports key is disjoint from the
passwords key. lib/chain-bch-imported.js is a single-address Electrum
adapter; spend support is deferred to M.1b.
- Opt-in USD prices via CoinGecko (lib/prices.js), off by default, persisted
in add-on storage. Fiat lines under balances, in the wallet picker, and a
portfolio total when 2+ wallets are open. Settings tab is now reachable
while the vault is locked so the toggle is always available.
- WizardConnect wallet-side pairing for BCH wallets (lib/wc.js, lib/wc-sign.js).
@wizardconnect/{core,wallet} are loaded dynamically via api.import to stay
on the right side of LGPL §4d. Sign requests go through approvalModal and
are restricted to P2PKH inputs with SIGHASH_ALL|FORKID|UTXOS.
- DGB adapter load is now soft-fail: when Aegis runs from userData/addons the
bundled ESM can't resolve peer deps, so DGB becomes unavailable instead of
taking the whole add-on down.
2026-09-09 10:33:21 +02:00
|
|
|
//
|
chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
// Sources currently wired:
|
|
|
|
|
// coingecko — 1 request covers all 7 coins, best overall coverage
|
|
|
|
|
// kraken — public /Ticker; BCH/BTC/ETH/SOL/TRX pairs
|
|
|
|
|
// coinbase — public /spot; BCH/BTC/ETH/SOL pairs
|
|
|
|
|
// coinspectrum — coin-spectrum.com free /assets/<slug>.json (~10 min TTL)
|
2026-09-14 02:30:51 +02:00
|
|
|
//
|
chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
// Sources deferred (need their own protocol work first):
|
|
|
|
|
// oracles.cash / General Protocols — the /oracleMetadata endpoint returns
|
|
|
|
|
// hex-encoded signed attestations. Extracting a usable USD number
|
|
|
|
|
// requires decoding the message format (pair || timestamp || price_int
|
|
|
|
|
// || decimals) and verifying the signature against a known oracle
|
|
|
|
|
// pubkey per pair. Left as a TODO stub below so the plumbing is
|
|
|
|
|
// ready; enable once the message parser is done.
|
2026-09-14 02:30:51 +02:00
|
|
|
|
|
|
|
|
const CHAINS = ["bch", "btc", "trx", "eth", "sol", "sc", "dgb"];
|
feat(theseus/aegis): 0.6.1 — in-panel vault setup/unlock, BCH wallet imports, opt-in fiat prices, WizardConnect
Aegis Wallet 0.4.4 → 0.6.1:
- Vault lifecycle from the wallet gate. The locked / not-yet-created states
now show a master-password form (with optional BIP39 mnemonic on setup)
instead of redirecting users to Settings › Passwords. New
api.vault.lifecycle {status, setup, unlock, lock} in addons-host, gated by
the existing "vault-derive" capability. api.openSettings(section) also
added; settings.html honours a #section hash on open.
- Imported BCH wallets (design M.1a, read-only). Paste a mnemonic + BIP44
path or a WIF; the cashaddr is derived in the add-on, the signer material
goes to a separate wallet-imports.enc via api.vault.imports {list, add,
remove, signer}. Argus password-vault gains createImports / unlockImports /
saveImports with its own KDF salt so the imports key is disjoint from the
passwords key. lib/chain-bch-imported.js is a single-address Electrum
adapter; spend support is deferred to M.1b.
- Opt-in USD prices via CoinGecko (lib/prices.js), off by default, persisted
in add-on storage. Fiat lines under balances, in the wallet picker, and a
portfolio total when 2+ wallets are open. Settings tab is now reachable
while the vault is locked so the toggle is always available.
- WizardConnect wallet-side pairing for BCH wallets (lib/wc.js, lib/wc-sign.js).
@wizardconnect/{core,wallet} are loaded dynamically via api.import to stay
on the right side of LGPL §4d. Sign requests go through approvalModal and
are restricted to P2PKH inputs with SIGHASH_ALL|FORKID|UTXOS.
- DGB adapter load is now soft-fail: when Aegis runs from userData/addons the
bundled ESM can't resolve peer deps, so DGB becomes unavailable instead of
taking the whole add-on down.
2026-09-09 10:33:21 +02:00
|
|
|
|
chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
// Sources return { <chain>: usd_number } for every chain they know about.
|
|
|
|
|
// Absence just means "this source doesn't cover that chain"; reconciliation
|
|
|
|
|
// ignores it. Errors thrown here bubble to the poller which stores them
|
|
|
|
|
// per-source in the snapshot so the panel can show which oracle is down.
|
2026-09-14 02:30:51 +02:00
|
|
|
const SOURCES = {
|
|
|
|
|
coingecko: {
|
|
|
|
|
id: "coingecko",
|
|
|
|
|
label: "CoinGecko",
|
|
|
|
|
origin: "api.coingecko.com",
|
|
|
|
|
coversAll: true,
|
|
|
|
|
fetch: async () => {
|
|
|
|
|
const ids = {
|
|
|
|
|
bch: "bitcoin-cash", btc: "bitcoin", trx: "tron",
|
|
|
|
|
eth: "ethereum", sol: "solana", sc: "siacoin", dgb: "digibyte",
|
|
|
|
|
};
|
|
|
|
|
const url = `https://api.coingecko.com/api/v3/simple/price?ids=${encodeURIComponent(Object.values(ids).join(","))}&vs_currencies=usd`;
|
|
|
|
|
const r = await fetch(url);
|
|
|
|
|
if (!r.ok) throw new Error(`CoinGecko HTTP ${r.status}`);
|
|
|
|
|
const body = await r.json();
|
|
|
|
|
const out = {};
|
|
|
|
|
for (const [chain, cgId] of Object.entries(ids)) {
|
|
|
|
|
const usd = body?.[cgId]?.usd;
|
|
|
|
|
if (typeof usd === "number") out[chain] = usd;
|
|
|
|
|
}
|
|
|
|
|
return out;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
kraken: {
|
|
|
|
|
id: "kraken",
|
|
|
|
|
label: "Kraken",
|
|
|
|
|
origin: "api.kraken.com",
|
|
|
|
|
coversAll: false,
|
|
|
|
|
fetch: async () => {
|
|
|
|
|
const pairs = { bch: "BCHUSD", btc: "XBTUSD", eth: "ETHUSD", sol: "SOLUSD", trx: "TRXUSD" };
|
|
|
|
|
const url = `https://api.kraken.com/0/public/Ticker?pair=${Object.values(pairs).join(",")}`;
|
|
|
|
|
const r = await fetch(url);
|
|
|
|
|
if (!r.ok) throw new Error(`Kraken HTTP ${r.status}`);
|
|
|
|
|
const body = await r.json();
|
|
|
|
|
if (body?.error?.length) throw new Error("Kraken: " + body.error.join(";"));
|
|
|
|
|
const out = {};
|
|
|
|
|
const result = body?.result || {};
|
|
|
|
|
const entries = Object.entries(result);
|
|
|
|
|
for (const [chain, pair] of Object.entries(pairs)) {
|
|
|
|
|
const hit = entries.find(([k]) => k === pair || k.endsWith(pair) || k.endsWith(pair.replace("XBT", "BT")));
|
|
|
|
|
const last = hit && parseFloat(hit[1]?.c?.[0]);
|
|
|
|
|
if (Number.isFinite(last)) out[chain] = last;
|
|
|
|
|
}
|
|
|
|
|
return out;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
coinbase: {
|
|
|
|
|
id: "coinbase",
|
|
|
|
|
label: "Coinbase",
|
|
|
|
|
origin: "api.coinbase.com",
|
|
|
|
|
coversAll: false,
|
|
|
|
|
fetch: async () => {
|
|
|
|
|
const map = { bch: "BCH-USD", btc: "BTC-USD", eth: "ETH-USD", sol: "SOL-USD" };
|
|
|
|
|
const out = {};
|
|
|
|
|
await Promise.all(Object.entries(map).map(async ([chain, pair]) => {
|
|
|
|
|
try {
|
|
|
|
|
const r = await fetch(`https://api.coinbase.com/v2/prices/${pair}/spot`);
|
|
|
|
|
if (!r.ok) return;
|
|
|
|
|
const body = await r.json();
|
|
|
|
|
const usd = parseFloat(body?.data?.amount);
|
|
|
|
|
if (Number.isFinite(usd)) out[chain] = usd;
|
|
|
|
|
} catch { /* one pair failing shouldn't kill the others */ }
|
|
|
|
|
}));
|
|
|
|
|
return out;
|
|
|
|
|
},
|
|
|
|
|
},
|
chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
coinspectrum: {
|
|
|
|
|
id: "coinspectrum",
|
|
|
|
|
label: "Coin-Spectrum",
|
|
|
|
|
origin: "coin-spectrum.com",
|
|
|
|
|
coversAll: true,
|
|
|
|
|
fetch: async () => {
|
|
|
|
|
const slugs = {
|
|
|
|
|
bch: "bitcoin-cash", btc: "bitcoin", trx: "tron",
|
|
|
|
|
eth: "ethereum", sol: "solana", sc: "siacoin", dgb: "digibyte",
|
|
|
|
|
};
|
|
|
|
|
const out = {};
|
|
|
|
|
await Promise.all(Object.entries(slugs).map(async ([chain, slug]) => {
|
|
|
|
|
try {
|
|
|
|
|
const r = await fetch(`https://coin-spectrum.com/api/v1/assets/${slug}.json`, { cache: "no-store" });
|
|
|
|
|
if (!r.ok) return;
|
|
|
|
|
const body = await r.json();
|
|
|
|
|
const usd = Number(body?.price_usd);
|
|
|
|
|
if (Number.isFinite(usd) && usd > 0) out[chain] = usd;
|
|
|
|
|
} catch { /* one slug failing shouldn't kill the others */ }
|
|
|
|
|
}));
|
|
|
|
|
return out;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
// oracles.cash (General Protocols) is deferred until we decode their
|
|
|
|
|
// signed-attestation message format. Enable by moving this entry into
|
|
|
|
|
// SOURCES above once fetch() returns real USD numbers.
|
|
|
|
|
// _oraclescash: {
|
|
|
|
|
// id: "oraclescash",
|
|
|
|
|
// label: "oracles.cash",
|
|
|
|
|
// origin: "oracles.generalprotocols.com",
|
|
|
|
|
// coversAll: false,
|
|
|
|
|
// fetch: async () => {
|
|
|
|
|
// // TODO: pick per-pair oracle pubkey, fetch /api/v1/oracleMessages,
|
|
|
|
|
// // decode `message` = pair_ascii(2 bytes) || timestamp(u32) ||
|
|
|
|
|
// // price_int(u32-or-u64) || decimals; verify signature. See
|
|
|
|
|
// // https://oracles.generalprotocols.com/api/v1/oracleMetadata for
|
|
|
|
|
// // the list of active oracles.
|
|
|
|
|
// return {};
|
|
|
|
|
// },
|
|
|
|
|
// },
|
feat(theseus/aegis): 0.6.1 — in-panel vault setup/unlock, BCH wallet imports, opt-in fiat prices, WizardConnect
Aegis Wallet 0.4.4 → 0.6.1:
- Vault lifecycle from the wallet gate. The locked / not-yet-created states
now show a master-password form (with optional BIP39 mnemonic on setup)
instead of redirecting users to Settings › Passwords. New
api.vault.lifecycle {status, setup, unlock, lock} in addons-host, gated by
the existing "vault-derive" capability. api.openSettings(section) also
added; settings.html honours a #section hash on open.
- Imported BCH wallets (design M.1a, read-only). Paste a mnemonic + BIP44
path or a WIF; the cashaddr is derived in the add-on, the signer material
goes to a separate wallet-imports.enc via api.vault.imports {list, add,
remove, signer}. Argus password-vault gains createImports / unlockImports /
saveImports with its own KDF salt so the imports key is disjoint from the
passwords key. lib/chain-bch-imported.js is a single-address Electrum
adapter; spend support is deferred to M.1b.
- Opt-in USD prices via CoinGecko (lib/prices.js), off by default, persisted
in add-on storage. Fiat lines under balances, in the wallet picker, and a
portfolio total when 2+ wallets are open. Settings tab is now reachable
while the vault is locked so the toggle is always available.
- WizardConnect wallet-side pairing for BCH wallets (lib/wc.js, lib/wc-sign.js).
@wizardconnect/{core,wallet} are loaded dynamically via api.import to stay
on the right side of LGPL §4d. Sign requests go through approvalModal and
are restricted to P2PKH inputs with SIGHASH_ALL|FORKID|UTXOS.
- DGB adapter load is now soft-fail: when Aegis runs from userData/addons the
bundled ESM can't resolve peer deps, so DGB becomes unavailable instead of
taking the whole add-on down.
2026-09-09 10:33:21 +02:00
|
|
|
};
|
|
|
|
|
|
chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
const POLL_MS = 5 * 60 * 1000; // 5 min: gentle on free tiers, still fresh enough
|
|
|
|
|
const AGREEMENT_BAND = 0.03; // ±3% around the median counts as "agreeing"
|
|
|
|
|
|
|
|
|
|
const median = (nums) => {
|
|
|
|
|
const s = nums.slice().sort((a, b) => a - b);
|
|
|
|
|
const m = s.length;
|
|
|
|
|
if (!m) return null;
|
|
|
|
|
return m % 2 ? s[(m - 1) / 2] : (s[m / 2 - 1] + s[m / 2]) / 2;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Reconcile a per-source map for ONE chain into a single trusted USD number.
|
|
|
|
|
// perSource: { <sourceId>: usd_number }
|
|
|
|
|
// Returns { usd, method, samples: [{sourceId, usd, agrees}] }.
|
|
|
|
|
function reconcileOne(perSource) {
|
|
|
|
|
const samples = Object.entries(perSource)
|
|
|
|
|
.filter(([, v]) => Number.isFinite(v) && v > 0)
|
|
|
|
|
.map(([sourceId, usd]) => ({ sourceId, usd, agrees: false }));
|
|
|
|
|
if (!samples.length) return { usd: null, method: "none", samples };
|
|
|
|
|
if (samples.length === 1) {
|
|
|
|
|
samples[0].agrees = true;
|
|
|
|
|
return { usd: samples[0].usd, method: "single", samples };
|
|
|
|
|
}
|
|
|
|
|
// Pin agreement around the overall median so no single outlier can shift
|
|
|
|
|
// the anchor. Any two samples within ±3% of that median form a "cluster";
|
|
|
|
|
// if ≥2 exist we take their median as the truth.
|
|
|
|
|
const mid = median(samples.map((s) => s.usd));
|
|
|
|
|
const lo = mid * (1 - AGREEMENT_BAND);
|
|
|
|
|
const hi = mid * (1 + AGREEMENT_BAND);
|
|
|
|
|
const agreeing = samples.filter((s) => s.usd >= lo && s.usd <= hi);
|
|
|
|
|
if (agreeing.length >= 2) {
|
|
|
|
|
for (const a of agreeing) a.agrees = true;
|
|
|
|
|
return { usd: median(agreeing.map((s) => s.usd)), method: `majority-${agreeing.length}of${samples.length}`, samples };
|
|
|
|
|
}
|
|
|
|
|
// Nobody agrees within the band — every source disagrees. Fall back to
|
|
|
|
|
// the median of everything reported so we still show A price (biased
|
|
|
|
|
// toward the middle) rather than nothing. Panel can show a "spread"
|
|
|
|
|
// warning if callers care.
|
|
|
|
|
return { usd: mid, method: `median-${samples.length}`, samples };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fan out to every SOURCES.fetch() in parallel. Returns
|
|
|
|
|
// { perChain: { <chain>: {usd, method, samples} }, sourceStatus: { <id>: {ok, error, prices, at} } }.
|
|
|
|
|
async function pollAll(log) {
|
|
|
|
|
const sourceStatus = {};
|
|
|
|
|
const perSourcePrices = {}; // chain -> {sourceId: usd}
|
|
|
|
|
|
|
|
|
|
await Promise.all(Object.values(SOURCES).map(async (s) => {
|
|
|
|
|
const start = Date.now();
|
|
|
|
|
try {
|
|
|
|
|
const got = await s.fetch();
|
|
|
|
|
const prices = got && typeof got === "object" ? got : {};
|
|
|
|
|
sourceStatus[s.id] = { ok: true, error: null, prices, at: Date.now(), took: Date.now() - start };
|
|
|
|
|
for (const [chain, usd] of Object.entries(prices)) {
|
|
|
|
|
if (!Number.isFinite(usd) || usd <= 0) continue;
|
|
|
|
|
if (!perSourcePrices[chain]) perSourcePrices[chain] = {};
|
|
|
|
|
perSourcePrices[chain][s.id] = usd;
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
const msg = e?.message || String(e);
|
|
|
|
|
sourceStatus[s.id] = { ok: false, error: msg, prices: {}, at: Date.now(), took: Date.now() - start };
|
|
|
|
|
log(`price fetch (${s.id}) failed:`, msg);
|
|
|
|
|
}
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
const perChain = {};
|
|
|
|
|
for (const chain of CHAINS) {
|
|
|
|
|
const rec = reconcileOne(perSourcePrices[chain] || {});
|
|
|
|
|
if (rec.usd != null) perChain[chain] = rec;
|
|
|
|
|
}
|
|
|
|
|
return { perChain, sourceStatus };
|
|
|
|
|
}
|
feat(theseus/aegis): 0.6.1 — in-panel vault setup/unlock, BCH wallet imports, opt-in fiat prices, WizardConnect
Aegis Wallet 0.4.4 → 0.6.1:
- Vault lifecycle from the wallet gate. The locked / not-yet-created states
now show a master-password form (with optional BIP39 mnemonic on setup)
instead of redirecting users to Settings › Passwords. New
api.vault.lifecycle {status, setup, unlock, lock} in addons-host, gated by
the existing "vault-derive" capability. api.openSettings(section) also
added; settings.html honours a #section hash on open.
- Imported BCH wallets (design M.1a, read-only). Paste a mnemonic + BIP44
path or a WIF; the cashaddr is derived in the add-on, the signer material
goes to a separate wallet-imports.enc via api.vault.imports {list, add,
remove, signer}. Argus password-vault gains createImports / unlockImports /
saveImports with its own KDF salt so the imports key is disjoint from the
passwords key. lib/chain-bch-imported.js is a single-address Electrum
adapter; spend support is deferred to M.1b.
- Opt-in USD prices via CoinGecko (lib/prices.js), off by default, persisted
in add-on storage. Fiat lines under balances, in the wallet picker, and a
portfolio total when 2+ wallets are open. Settings tab is now reachable
while the vault is locked so the toggle is always available.
- WizardConnect wallet-side pairing for BCH wallets (lib/wc.js, lib/wc-sign.js).
@wizardconnect/{core,wallet} are loaded dynamically via api.import to stay
on the right side of LGPL §4d. Sign requests go through approvalModal and
are restricted to P2PKH inputs with SIGHASH_ALL|FORKID|UTXOS.
- DGB adapter load is now soft-fail: when Aegis runs from userData/addons the
bundled ESM can't resolve peer deps, so DGB becomes unavailable instead of
taking the whole add-on down.
2026-09-09 10:33:21 +02:00
|
|
|
|
|
|
|
|
module.exports = function makePriceFeed({ log = () => {}, onChange = () => {} } = {}) {
|
|
|
|
|
const state = {
|
|
|
|
|
enabled: false,
|
chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
prices: {}, // { <chain>: usd (number) } — backward-compat
|
|
|
|
|
reconciled: {}, // { <chain>: {usd, method, samples: [...]} }
|
|
|
|
|
sourceStatus: {}, // { <sourceId>: {ok, error, prices, at, took} }
|
feat(theseus/aegis): 0.6.1 — in-panel vault setup/unlock, BCH wallet imports, opt-in fiat prices, WizardConnect
Aegis Wallet 0.4.4 → 0.6.1:
- Vault lifecycle from the wallet gate. The locked / not-yet-created states
now show a master-password form (with optional BIP39 mnemonic on setup)
instead of redirecting users to Settings › Passwords. New
api.vault.lifecycle {status, setup, unlock, lock} in addons-host, gated by
the existing "vault-derive" capability. api.openSettings(section) also
added; settings.html honours a #section hash on open.
- Imported BCH wallets (design M.1a, read-only). Paste a mnemonic + BIP44
path or a WIF; the cashaddr is derived in the add-on, the signer material
goes to a separate wallet-imports.enc via api.vault.imports {list, add,
remove, signer}. Argus password-vault gains createImports / unlockImports /
saveImports with its own KDF salt so the imports key is disjoint from the
passwords key. lib/chain-bch-imported.js is a single-address Electrum
adapter; spend support is deferred to M.1b.
- Opt-in USD prices via CoinGecko (lib/prices.js), off by default, persisted
in add-on storage. Fiat lines under balances, in the wallet picker, and a
portfolio total when 2+ wallets are open. Settings tab is now reachable
while the vault is locked so the toggle is always available.
- WizardConnect wallet-side pairing for BCH wallets (lib/wc.js, lib/wc-sign.js).
@wizardconnect/{core,wallet} are loaded dynamically via api.import to stay
on the right side of LGPL §4d. Sign requests go through approvalModal and
are restricted to P2PKH inputs with SIGHASH_ALL|FORKID|UTXOS.
- DGB adapter load is now soft-fail: when Aegis runs from userData/addons the
bundled ESM can't resolve peer deps, so DGB becomes unavailable instead of
taking the whole add-on down.
2026-09-09 10:33:21 +02:00
|
|
|
fetchedAt: null,
|
|
|
|
|
error: null,
|
|
|
|
|
loading: false,
|
|
|
|
|
};
|
|
|
|
|
let timer = null;
|
|
|
|
|
|
|
|
|
|
async function fetchOnce() {
|
|
|
|
|
if (!state.enabled) return;
|
|
|
|
|
state.loading = true; state.error = null; onChange();
|
|
|
|
|
try {
|
chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
const { perChain, sourceStatus } = await pollAll(log);
|
|
|
|
|
const flat = {};
|
|
|
|
|
for (const [chain, rec] of Object.entries(perChain)) flat[chain] = rec.usd;
|
|
|
|
|
state.prices = flat;
|
|
|
|
|
state.reconciled = perChain;
|
|
|
|
|
state.sourceStatus = sourceStatus;
|
feat(theseus/aegis): 0.6.1 — in-panel vault setup/unlock, BCH wallet imports, opt-in fiat prices, WizardConnect
Aegis Wallet 0.4.4 → 0.6.1:
- Vault lifecycle from the wallet gate. The locked / not-yet-created states
now show a master-password form (with optional BIP39 mnemonic on setup)
instead of redirecting users to Settings › Passwords. New
api.vault.lifecycle {status, setup, unlock, lock} in addons-host, gated by
the existing "vault-derive" capability. api.openSettings(section) also
added; settings.html honours a #section hash on open.
- Imported BCH wallets (design M.1a, read-only). Paste a mnemonic + BIP44
path or a WIF; the cashaddr is derived in the add-on, the signer material
goes to a separate wallet-imports.enc via api.vault.imports {list, add,
remove, signer}. Argus password-vault gains createImports / unlockImports /
saveImports with its own KDF salt so the imports key is disjoint from the
passwords key. lib/chain-bch-imported.js is a single-address Electrum
adapter; spend support is deferred to M.1b.
- Opt-in USD prices via CoinGecko (lib/prices.js), off by default, persisted
in add-on storage. Fiat lines under balances, in the wallet picker, and a
portfolio total when 2+ wallets are open. Settings tab is now reachable
while the vault is locked so the toggle is always available.
- WizardConnect wallet-side pairing for BCH wallets (lib/wc.js, lib/wc-sign.js).
@wizardconnect/{core,wallet} are loaded dynamically via api.import to stay
on the right side of LGPL §4d. Sign requests go through approvalModal and
are restricted to P2PKH inputs with SIGHASH_ALL|FORKID|UTXOS.
- DGB adapter load is now soft-fail: when Aegis runs from userData/addons the
bundled ESM can't resolve peer deps, so DGB becomes unavailable instead of
taking the whole add-on down.
2026-09-09 10:33:21 +02:00
|
|
|
state.fetchedAt = Date.now();
|
chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
// Only escalate to a top-level error if EVERY source failed. A single
|
|
|
|
|
// oracle being unreachable is normal and doesn't need a red banner.
|
|
|
|
|
const allDown = Object.values(sourceStatus).every((s) => !s.ok);
|
|
|
|
|
state.error = allDown ? "All price sources unreachable" : null;
|
feat(theseus/aegis): 0.6.1 — in-panel vault setup/unlock, BCH wallet imports, opt-in fiat prices, WizardConnect
Aegis Wallet 0.4.4 → 0.6.1:
- Vault lifecycle from the wallet gate. The locked / not-yet-created states
now show a master-password form (with optional BIP39 mnemonic on setup)
instead of redirecting users to Settings › Passwords. New
api.vault.lifecycle {status, setup, unlock, lock} in addons-host, gated by
the existing "vault-derive" capability. api.openSettings(section) also
added; settings.html honours a #section hash on open.
- Imported BCH wallets (design M.1a, read-only). Paste a mnemonic + BIP44
path or a WIF; the cashaddr is derived in the add-on, the signer material
goes to a separate wallet-imports.enc via api.vault.imports {list, add,
remove, signer}. Argus password-vault gains createImports / unlockImports /
saveImports with its own KDF salt so the imports key is disjoint from the
passwords key. lib/chain-bch-imported.js is a single-address Electrum
adapter; spend support is deferred to M.1b.
- Opt-in USD prices via CoinGecko (lib/prices.js), off by default, persisted
in add-on storage. Fiat lines under balances, in the wallet picker, and a
portfolio total when 2+ wallets are open. Settings tab is now reachable
while the vault is locked so the toggle is always available.
- WizardConnect wallet-side pairing for BCH wallets (lib/wc.js, lib/wc-sign.js).
@wizardconnect/{core,wallet} are loaded dynamically via api.import to stay
on the right side of LGPL §4d. Sign requests go through approvalModal and
are restricted to P2PKH inputs with SIGHASH_ALL|FORKID|UTXOS.
- DGB adapter load is now soft-fail: when Aegis runs from userData/addons the
bundled ESM can't resolve peer deps, so DGB becomes unavailable instead of
taking the whole add-on down.
2026-09-09 10:33:21 +02:00
|
|
|
} catch (e) {
|
|
|
|
|
state.error = e?.message || String(e);
|
chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
log("price poll failed:", state.error);
|
feat(theseus/aegis): 0.6.1 — in-panel vault setup/unlock, BCH wallet imports, opt-in fiat prices, WizardConnect
Aegis Wallet 0.4.4 → 0.6.1:
- Vault lifecycle from the wallet gate. The locked / not-yet-created states
now show a master-password form (with optional BIP39 mnemonic on setup)
instead of redirecting users to Settings › Passwords. New
api.vault.lifecycle {status, setup, unlock, lock} in addons-host, gated by
the existing "vault-derive" capability. api.openSettings(section) also
added; settings.html honours a #section hash on open.
- Imported BCH wallets (design M.1a, read-only). Paste a mnemonic + BIP44
path or a WIF; the cashaddr is derived in the add-on, the signer material
goes to a separate wallet-imports.enc via api.vault.imports {list, add,
remove, signer}. Argus password-vault gains createImports / unlockImports /
saveImports with its own KDF salt so the imports key is disjoint from the
passwords key. lib/chain-bch-imported.js is a single-address Electrum
adapter; spend support is deferred to M.1b.
- Opt-in USD prices via CoinGecko (lib/prices.js), off by default, persisted
in add-on storage. Fiat lines under balances, in the wallet picker, and a
portfolio total when 2+ wallets are open. Settings tab is now reachable
while the vault is locked so the toggle is always available.
- WizardConnect wallet-side pairing for BCH wallets (lib/wc.js, lib/wc-sign.js).
@wizardconnect/{core,wallet} are loaded dynamically via api.import to stay
on the right side of LGPL §4d. Sign requests go through approvalModal and
are restricted to P2PKH inputs with SIGHASH_ALL|FORKID|UTXOS.
- DGB adapter load is now soft-fail: when Aegis runs from userData/addons the
bundled ESM can't resolve peer deps, so DGB becomes unavailable instead of
taking the whole add-on down.
2026-09-09 10:33:21 +02:00
|
|
|
} finally {
|
|
|
|
|
state.loading = false;
|
|
|
|
|
onChange();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function schedule() {
|
|
|
|
|
clearTimeout(timer);
|
|
|
|
|
if (!state.enabled) return;
|
chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
timer = setTimeout(async () => { await fetchOnce(); schedule(); }, POLL_MS);
|
feat(theseus/aegis): 0.6.1 — in-panel vault setup/unlock, BCH wallet imports, opt-in fiat prices, WizardConnect
Aegis Wallet 0.4.4 → 0.6.1:
- Vault lifecycle from the wallet gate. The locked / not-yet-created states
now show a master-password form (with optional BIP39 mnemonic on setup)
instead of redirecting users to Settings › Passwords. New
api.vault.lifecycle {status, setup, unlock, lock} in addons-host, gated by
the existing "vault-derive" capability. api.openSettings(section) also
added; settings.html honours a #section hash on open.
- Imported BCH wallets (design M.1a, read-only). Paste a mnemonic + BIP44
path or a WIF; the cashaddr is derived in the add-on, the signer material
goes to a separate wallet-imports.enc via api.vault.imports {list, add,
remove, signer}. Argus password-vault gains createImports / unlockImports /
saveImports with its own KDF salt so the imports key is disjoint from the
passwords key. lib/chain-bch-imported.js is a single-address Electrum
adapter; spend support is deferred to M.1b.
- Opt-in USD prices via CoinGecko (lib/prices.js), off by default, persisted
in add-on storage. Fiat lines under balances, in the wallet picker, and a
portfolio total when 2+ wallets are open. Settings tab is now reachable
while the vault is locked so the toggle is always available.
- WizardConnect wallet-side pairing for BCH wallets (lib/wc.js, lib/wc-sign.js).
@wizardconnect/{core,wallet} are loaded dynamically via api.import to stay
on the right side of LGPL §4d. Sign requests go through approvalModal and
are restricted to P2PKH inputs with SIGHASH_ALL|FORKID|UTXOS.
- DGB adapter load is now soft-fail: when Aegis runs from userData/addons the
bundled ESM can't resolve peer deps, so DGB becomes unavailable instead of
taking the whole add-on down.
2026-09-09 10:33:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
snapshot() {
|
|
|
|
|
return {
|
|
|
|
|
enabled: state.enabled,
|
|
|
|
|
prices: state.prices,
|
chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
reconciled: state.reconciled,
|
|
|
|
|
sourceStatus: state.sourceStatus,
|
feat(theseus/aegis): 0.6.1 — in-panel vault setup/unlock, BCH wallet imports, opt-in fiat prices, WizardConnect
Aegis Wallet 0.4.4 → 0.6.1:
- Vault lifecycle from the wallet gate. The locked / not-yet-created states
now show a master-password form (with optional BIP39 mnemonic on setup)
instead of redirecting users to Settings › Passwords. New
api.vault.lifecycle {status, setup, unlock, lock} in addons-host, gated by
the existing "vault-derive" capability. api.openSettings(section) also
added; settings.html honours a #section hash on open.
- Imported BCH wallets (design M.1a, read-only). Paste a mnemonic + BIP44
path or a WIF; the cashaddr is derived in the add-on, the signer material
goes to a separate wallet-imports.enc via api.vault.imports {list, add,
remove, signer}. Argus password-vault gains createImports / unlockImports /
saveImports with its own KDF salt so the imports key is disjoint from the
passwords key. lib/chain-bch-imported.js is a single-address Electrum
adapter; spend support is deferred to M.1b.
- Opt-in USD prices via CoinGecko (lib/prices.js), off by default, persisted
in add-on storage. Fiat lines under balances, in the wallet picker, and a
portfolio total when 2+ wallets are open. Settings tab is now reachable
while the vault is locked so the toggle is always available.
- WizardConnect wallet-side pairing for BCH wallets (lib/wc.js, lib/wc-sign.js).
@wizardconnect/{core,wallet} are loaded dynamically via api.import to stay
on the right side of LGPL §4d. Sign requests go through approvalModal and
are restricted to P2PKH inputs with SIGHASH_ALL|FORKID|UTXOS.
- DGB adapter load is now soft-fail: when Aegis runs from userData/addons the
bundled ESM can't resolve peer deps, so DGB becomes unavailable instead of
taking the whole add-on down.
2026-09-09 10:33:21 +02:00
|
|
|
fetchedAt: state.fetchedAt,
|
|
|
|
|
error: state.error,
|
|
|
|
|
loading: state.loading,
|
chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
// Retained so existing settings UI paths that expect a `sources`
|
|
|
|
|
// list keep rendering. `coversAll` is informational only now that
|
|
|
|
|
// the picker's gone.
|
|
|
|
|
sources: Object.values(SOURCES).map((s) => ({ id: s.id, label: s.label, origin: s.origin, coversAll: s.coversAll })),
|
feat(theseus/aegis): 0.6.1 — in-panel vault setup/unlock, BCH wallet imports, opt-in fiat prices, WizardConnect
Aegis Wallet 0.4.4 → 0.6.1:
- Vault lifecycle from the wallet gate. The locked / not-yet-created states
now show a master-password form (with optional BIP39 mnemonic on setup)
instead of redirecting users to Settings › Passwords. New
api.vault.lifecycle {status, setup, unlock, lock} in addons-host, gated by
the existing "vault-derive" capability. api.openSettings(section) also
added; settings.html honours a #section hash on open.
- Imported BCH wallets (design M.1a, read-only). Paste a mnemonic + BIP44
path or a WIF; the cashaddr is derived in the add-on, the signer material
goes to a separate wallet-imports.enc via api.vault.imports {list, add,
remove, signer}. Argus password-vault gains createImports / unlockImports /
saveImports with its own KDF salt so the imports key is disjoint from the
passwords key. lib/chain-bch-imported.js is a single-address Electrum
adapter; spend support is deferred to M.1b.
- Opt-in USD prices via CoinGecko (lib/prices.js), off by default, persisted
in add-on storage. Fiat lines under balances, in the wallet picker, and a
portfolio total when 2+ wallets are open. Settings tab is now reachable
while the vault is locked so the toggle is always available.
- WizardConnect wallet-side pairing for BCH wallets (lib/wc.js, lib/wc-sign.js).
@wizardconnect/{core,wallet} are loaded dynamically via api.import to stay
on the right side of LGPL §4d. Sign requests go through approvalModal and
are restricted to P2PKH inputs with SIGHASH_ALL|FORKID|UTXOS.
- DGB adapter load is now soft-fail: when Aegis runs from userData/addons the
bundled ESM can't resolve peer deps, so DGB becomes unavailable instead of
taking the whole add-on down.
2026-09-09 10:33:21 +02:00
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
async setEnabled(on) {
|
|
|
|
|
const changed = !!on !== state.enabled;
|
|
|
|
|
state.enabled = !!on;
|
|
|
|
|
if (!state.enabled) {
|
chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
state.prices = {}; state.reconciled = {}; state.sourceStatus = {};
|
|
|
|
|
state.fetchedAt = null; state.error = null;
|
feat(theseus/aegis): 0.6.1 — in-panel vault setup/unlock, BCH wallet imports, opt-in fiat prices, WizardConnect
Aegis Wallet 0.4.4 → 0.6.1:
- Vault lifecycle from the wallet gate. The locked / not-yet-created states
now show a master-password form (with optional BIP39 mnemonic on setup)
instead of redirecting users to Settings › Passwords. New
api.vault.lifecycle {status, setup, unlock, lock} in addons-host, gated by
the existing "vault-derive" capability. api.openSettings(section) also
added; settings.html honours a #section hash on open.
- Imported BCH wallets (design M.1a, read-only). Paste a mnemonic + BIP44
path or a WIF; the cashaddr is derived in the add-on, the signer material
goes to a separate wallet-imports.enc via api.vault.imports {list, add,
remove, signer}. Argus password-vault gains createImports / unlockImports /
saveImports with its own KDF salt so the imports key is disjoint from the
passwords key. lib/chain-bch-imported.js is a single-address Electrum
adapter; spend support is deferred to M.1b.
- Opt-in USD prices via CoinGecko (lib/prices.js), off by default, persisted
in add-on storage. Fiat lines under balances, in the wallet picker, and a
portfolio total when 2+ wallets are open. Settings tab is now reachable
while the vault is locked so the toggle is always available.
- WizardConnect wallet-side pairing for BCH wallets (lib/wc.js, lib/wc-sign.js).
@wizardconnect/{core,wallet} are loaded dynamically via api.import to stay
on the right side of LGPL §4d. Sign requests go through approvalModal and
are restricted to P2PKH inputs with SIGHASH_ALL|FORKID|UTXOS.
- DGB adapter load is now soft-fail: when Aegis runs from userData/addons the
bundled ESM can't resolve peer deps, so DGB becomes unavailable instead of
taking the whole add-on down.
2026-09-09 10:33:21 +02:00
|
|
|
clearTimeout(timer);
|
|
|
|
|
if (changed) onChange();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
onChange();
|
|
|
|
|
await fetchOnce();
|
|
|
|
|
schedule();
|
|
|
|
|
},
|
chore(aegis): 0.8.2 — sectioned Settings tab
Settings grew tall enough that the user had to scroll past a dozen
cards to reach Prices, Sites or About. Split it into six named
sections (Security, Session, Wallet, Prices, Sites, About) with a
chip nav row at the top; only one section is visible at a time and
the choice persists across restarts.
Adds an About card that names the wallet, the aegis.x front-door
site and the silentmode.st umbrella, so support triage has a
one-click way to reach either from within the panel.
Includes the accumulated 0.7.x-0.8.1 wallet work that was already
shipping on OTA (CashTokens/BCMR, imported-wallet spend, siascan
integration, consolidate, currency picker, footer update chip).
2026-09-22 20:37:28 +02:00
|
|
|
// No-op kept for API compatibility — there is no source picker anymore.
|
|
|
|
|
// Existing callers that persisted a chosen source can still call this
|
|
|
|
|
// and get a benign refresh.
|
|
|
|
|
async setSource(_id) { if (state.enabled) { await fetchOnce(); schedule(); } },
|
feat(theseus/aegis): 0.6.1 — in-panel vault setup/unlock, BCH wallet imports, opt-in fiat prices, WizardConnect
Aegis Wallet 0.4.4 → 0.6.1:
- Vault lifecycle from the wallet gate. The locked / not-yet-created states
now show a master-password form (with optional BIP39 mnemonic on setup)
instead of redirecting users to Settings › Passwords. New
api.vault.lifecycle {status, setup, unlock, lock} in addons-host, gated by
the existing "vault-derive" capability. api.openSettings(section) also
added; settings.html honours a #section hash on open.
- Imported BCH wallets (design M.1a, read-only). Paste a mnemonic + BIP44
path or a WIF; the cashaddr is derived in the add-on, the signer material
goes to a separate wallet-imports.enc via api.vault.imports {list, add,
remove, signer}. Argus password-vault gains createImports / unlockImports /
saveImports with its own KDF salt so the imports key is disjoint from the
passwords key. lib/chain-bch-imported.js is a single-address Electrum
adapter; spend support is deferred to M.1b.
- Opt-in USD prices via CoinGecko (lib/prices.js), off by default, persisted
in add-on storage. Fiat lines under balances, in the wallet picker, and a
portfolio total when 2+ wallets are open. Settings tab is now reachable
while the vault is locked so the toggle is always available.
- WizardConnect wallet-side pairing for BCH wallets (lib/wc.js, lib/wc-sign.js).
@wizardconnect/{core,wallet} are loaded dynamically via api.import to stay
on the right side of LGPL §4d. Sign requests go through approvalModal and
are restricted to P2PKH inputs with SIGHASH_ALL|FORKID|UTXOS.
- DGB adapter load is now soft-fail: when Aegis runs from userData/addons the
bundled ESM can't resolve peer deps, so DGB becomes unavailable instead of
taking the whole add-on down.
2026-09-09 10:33:21 +02:00
|
|
|
refresh() { return fetchOnce(); },
|
|
|
|
|
dispose() { clearTimeout(timer); state.enabled = false; },
|
|
|
|
|
};
|
|
|
|
|
};
|