Previous #4d7300 (0.3.10) was still too light against actual white backgrounds — several tint fills (rgba(214,255,61,X)) and unpatched addon panels were making the effective color feel bright green. Two fixes bundled: 1) Bump --acid in every top-level page's light-media block from #4d7300 to #3a5c00 — same hue, ~7:1 contrast on #ffffff (was ~5.5:1). 2) Add the missing light-media --acid override to the addon panels that were still resolving to #d6ff3d: bchwallet/panel.html, siawallet/panel.html, and screenshot/editor.css (was #b4e024, now #3a5c00 to match). Dark mode unchanged. Tint fills (rgba backgrounds at low alpha) still stay as-is — at 8–15% opacity the specific hue barely matters and the darker foreground now dominates.
142 lines
6.5 KiB
JavaScript
142 lines
6.5 KiB
JavaScript
// Aegis dapp bridges. Runs in the isolated world of every matching tab and
|
|
// puts up to two dapp APIs on the page's main world:
|
|
//
|
|
// window.bitcoincash Silent Mode's own BCH API (only on .x pages —
|
|
// matches the pre-multi-wallet gate).
|
|
// window.tronWeb TronLink-shaped Tron dapp bridge (on any page).
|
|
// window.tronLink TronLink shim; `tron_requestAccounts` triggers
|
|
// an approval overlay via activate().
|
|
//
|
|
// Everything crosses into the wallet's activate() context in main, which
|
|
// shows the approval overlay and enforces per-origin permissions. Nothing
|
|
// here can sign, read a balance, or read an address on its own.
|
|
//
|
|
// `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);
|
|
});
|
|
|
|
// -------- BCH bridge (window.bitcoincash), only on .x pages ------------------
|
|
const isBchOrigin = (() => { try { return /\.x$/i.test(location.hostname); } catch { return false; } })();
|
|
if (isBchOrigin) {
|
|
theseus.contextBridge.exposeInMainWorld("bitcoincash", {
|
|
isTheseus: true,
|
|
version: "0.2.0",
|
|
network: "mainnet",
|
|
getAddress: () => call("getAddress"),
|
|
signAndSend: (txSpec) => call("signAndSend", txSpec && typeof txSpec === "object" ? txSpec : {}),
|
|
signMessage: (message) => call("signMessage", { message: String(message ?? "") }),
|
|
});
|
|
}
|
|
|
|
// -------- Tron bridge (window.tronWeb, window.tronLink), everywhere ---------
|
|
//
|
|
// Matches enough of the TronLink surface for read + send flows on dapps like
|
|
// tronscan, sunswap, and justlend (mainnet or Nile). Not implemented:
|
|
// TRC20/TRC721 abstractions, address utilities beyond base58<->hex, event
|
|
// emitters beyond the "message" events TronLink documents.
|
|
|
|
let CACHED = { address: null, network: null };
|
|
const listeners = new Set();
|
|
|
|
// Public copy of tronWeb.trx.
|
|
const trx = {
|
|
// Returns the account object TronGrid gives (may be {} for never-funded).
|
|
// Deliberately mirrors tronWeb.trx.getAccount.
|
|
getAccount: async () => call("trx.getAccount"),
|
|
// Sign an assembled transaction (dapp built it via its own tronWeb).
|
|
// Returns the same object with a `signature` field populated.
|
|
sign: async (transaction) => {
|
|
if (!transaction || typeof transaction !== "object" || !transaction.raw_data_hex) {
|
|
throw new Error("tronWeb.trx.sign: expected an assembled transaction with raw_data_hex");
|
|
}
|
|
return call("trx.signTransaction", { transaction });
|
|
},
|
|
// Broadcast a signed transaction. Returns { result: true, txid } on success.
|
|
sendRawTransaction: async (signedTx) => {
|
|
const r = await call("trx.sendRawTransaction", { transaction: signedTx });
|
|
return { result: true, txid: r.txid };
|
|
},
|
|
// Convenience wrappers matching the tronWeb surface — dapps call these
|
|
// when the wallet is supposed to build the tx too. Left unimplemented
|
|
// in this build so a dapp that hits them gets a clear error instead of
|
|
// silently unassembled behavior; assemble on the dapp side.
|
|
sendTrx: async () => { throw new Error("tronWeb.trx.sendTrx not implemented — build the transaction with tronWeb.transactionBuilder and call sign+sendRawTransaction"); },
|
|
// TronLink documents signMessage (legacy, keccak of just the message) and
|
|
// signMessageV2 (adds the "\x19TRON Signed Message:\n<len>" prefix). We
|
|
// only implement V2 because that is what modern dapps use.
|
|
signMessageV2: async (message) => {
|
|
const r = await call("trx.signMessageV2", { message: String(message ?? "") });
|
|
return r.signature;
|
|
},
|
|
};
|
|
|
|
// Shallow tronWeb — enough for `tronWeb.defaultAddress.base58` / `.hex` reads
|
|
// and the trx methods. Populated once the user connects.
|
|
const tronWeb = {
|
|
ready: false,
|
|
defaultAddress: { base58: false, hex: false, name: false },
|
|
fullNode: { host: "" },
|
|
solidityNode: { host: "" },
|
|
eventServer: { host: "" },
|
|
trx,
|
|
// Utility helpers a few dapps poke at.
|
|
isConnected: () => tronWeb.ready === true && !!tronWeb.defaultAddress.base58,
|
|
address: {
|
|
fromHex: (hex) => hex, // no-op stub; dapps that need a real
|
|
toHex: (base58) => base58, // conversion should use their own copy.
|
|
},
|
|
// Some dapps read this to decide "Tron mainnet vs testnet".
|
|
get currentNetwork() { return CACHED.network || null; },
|
|
};
|
|
|
|
function nodeHost(network) {
|
|
return network === "nile" ? "https://nile.trongrid.io" : "https://api.trongrid.io";
|
|
}
|
|
function applyConnection({ address, network }) {
|
|
CACHED = { address, network };
|
|
tronWeb.defaultAddress = { base58: address || false, hex: false, name: false };
|
|
tronWeb.ready = !!address;
|
|
tronLink.ready = !!address;
|
|
const host = nodeHost(network);
|
|
tronWeb.fullNode = { host };
|
|
tronWeb.solidityNode = { host };
|
|
tronWeb.eventServer = { host };
|
|
// Broadcast on the window in the way TronLink documents.
|
|
try {
|
|
window.postMessage({ message: { action: "accountsChanged", data: { address } }, isTronLink: true }, location.origin);
|
|
window.postMessage({ message: { action: "setAccount", data: { address } }, isTronLink: true }, location.origin);
|
|
window.postMessage({ message: { action: "setNode", data: { node: { fullNode: host, solidityNode: host, eventServer: host, chain: network === "nile" ? "0xcd8690dc" : "0x2b6653dc" } } }, isTronLink: true }, location.origin);
|
|
} catch {}
|
|
for (const fn of listeners) { try { fn({ address, network }); } catch {} }
|
|
}
|
|
|
|
const tronLink = {
|
|
ready: false,
|
|
tronWeb: tronWeb,
|
|
// TronLink's canonical request router. Handles at minimum tron_requestAccounts.
|
|
request: async (opts) => {
|
|
const method = String(opts?.method || "");
|
|
if (method === "tron_requestAccounts" || method === "requestAccounts") {
|
|
const r = await call("trx.requestAccounts");
|
|
applyConnection({ address: r.address, network: r.network });
|
|
return { code: 200, message: "ok" };
|
|
}
|
|
if (method === "tron_accounts") {
|
|
const r = await call("trx.getAccount").catch(() => null);
|
|
return r ? [r.address] : [];
|
|
}
|
|
throw new Error("Aegis: unsupported tronLink method " + method);
|
|
},
|
|
// Dapps sometimes attach here to react to wallet changes.
|
|
on: (event, fn) => {
|
|
if (event === "message" || event === "accountsChanged" || event === "networkChanged") listeners.add(fn);
|
|
},
|
|
removeListener: (_event, fn) => listeners.delete(fn),
|
|
};
|
|
|
|
theseus.contextBridge.exposeInMainWorld("tronWeb", tronWeb);
|
|
theseus.contextBridge.exposeInMainWorld("tronLink", tronLink);
|