theseus/bundled-addons/aegis/lib/dgb/deps.js

61 lines
2.3 KiB
JavaScript
Raw Normal View History

fix(aegis): DigiByte import failed on every OTA install Reported as "the Aegis DigiByte import error". The vendored @dgb-wallet/core modules under lib/dgb/ imported "bitcoinjs-lib", "bip32", "ecpair", "bip39" and "@bitcoinerlab/secp256k1" as bare specifiers. Node's ESM resolver walks up from the importing file, so that resolves in a dev checkout — where Theseus's node_modules sits above the add-on — and resolves nowhere once Aegis is running from <userData>/extensions/aegis/, which is every OTA install. The import threw, index.js caught it and set dgbCore = null, and any DigiByte import then died in digibyteNetwork() with "DGB adapter not available". So DigiByte worked on a fresh install and disappeared after the first update. Confirmed on this machine: the only node_modules reachable from the installed extension carries bip39 and none of the other four. lib/dgb/deps.js now holds the dependencies, injected by index.js from api.require (which resolves against the app tree) before anything under lib/dgb/ is imported — the same pattern every other lib/*.js in Aegis already uses, and the reason that pattern exists. Consumers read them through accessors rather than capturing them at module scope, so import order is no longer load-bearing: hd.js builds its bip32 on first use and the two initEccLib callers go through a once-only ensureEcc(). Using a DGB module without injection now throws a named error instead of a resolver failure swallowed into a null. Verified by loading the modules from a directory with no reachable node_modules and deriving real addresses: BIP44 D…, BIP49 S… with its legacy 3… pair, BIP84 dgb1q…, BIP86 dgb1p… taproot, plus a WIF round-trip and the non-DGB WIF rejection.
2026-10-03 13:59:01 +02:00
// Dependency injection for the vendored DGB modules.
//
// These files were vendored from @dgb-wallet/core and imported
// "bitcoinjs-lib", "bip32", "ecpair" and "@bitcoinerlab/secp256k1" as bare
// specifiers. That resolves fine in a dev checkout, where Theseus's
// node_modules sits above the add-on — and fails for every OTA install, where
// Aegis lives in <userData>/extensions/aegis/ and Node's ESM resolver has
// nowhere to find them. index.js caught the failure and set dgbCore = null,
// so DigiByte quietly stopped existing and an import died with "DGB adapter
// not available". It worked on a fresh install and broke after the first
// update, which is the worst possible shape for a bug.
//
// index.js already holds all of these via api.require (which resolves against
// the app tree), so it injects them here before importing anything under
// lib/dgb/. Every consumer reads them through the accessors below rather than
// capturing them at module scope, so nothing depends on import order and a
// missing injection fails loudly at the call instead of silently at load.
let deps = null;
export function setDgbDeps(d) {
const need = ["bitcoinjs", "ecc", "bip32Factory", "ecpairFactory", "bip39"];
for (const k of need) {
if (!d || !d[k]) throw new Error(`setDgbDeps: missing ${k}`);
}
deps = d;
}
function need() {
if (!deps) throw new Error("DGB modules used before setDgbDeps() — see lib/dgb/deps.js");
return deps;
}
export const bitcoinjs = () => need().bitcoinjs;
export const payments = () => need().bitcoinjs.payments;
export const Psbt = () => need().bitcoinjs.Psbt;
export const ecc = () => need().ecc;
export const bip39 = () => need().bip39;
// initEccLib must run before any Taproot derivation, and exactly once.
let eccInstalled = false;
export function ensureEcc() {
if (eccInstalled) return;
need().bitcoinjs.initEccLib(need().ecc);
eccInstalled = true;
}
// Built on first use rather than at module scope, so hd.js no longer forces
// the deps to exist merely by being imported.
let bip32Cached = null;
export function bip32() {
if (!bip32Cached) bip32Cached = need().bip32Factory(need().ecc);
return bip32Cached;
}
let ecpairCached = null;
export function ECPair() {
if (!ecpairCached) ecpairCached = need().ecpairFactory(need().ecc);
return ecpairCached;
}