theseus/bundled-addons/bchwallet/wallet-inject.js
Local Dev c9106d4ede fix(theseus/light): darker acid (#3a5c00) + add missing overrides in addon panels
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.
2026-09-07 00:56:33 +02:00

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);