The extensions page could only hand out tarballs; installing meant going to Settings › Extensions › Community and finding the entry again. Pages now get window.bcnr.installExtension(id) and Theseus intercepts theseus://extensions/install/<id> links (page clicks, target=_blank and the address bar). The page only names a catalog id: Theseus fetches the catalog and package itself, asks in a native dialog the page cannot draw over, verifies the publisher signature against the name's current owner and activates the add-on — the same path a Settings install takes. One prompt at a time; an already-installed version says so instead of offering a no-op update. The site shows the button inside Theseus (feature-detected on the bridge), a "update Theseus" hint on older builds and a download hint in other browsers.
39 lines
2.6 KiB
JavaScript
39 lines
2.6 KiB
JavaScript
// bcnr-preload.js — session-wide preload that installs `window.bcnr` on every
|
|
// page (regular tabs, popups, chrome/settings/etc). Reads only — no signing,
|
|
// no wallet unlock, no permission prompts. These four methods query the same
|
|
// resolver Theseus already runs for its address bar; nothing about the local
|
|
// user leaks, so no origin gate is needed for this surface.
|
|
//
|
|
// Sequencing: registered via `session.defaultSession.setPreloads([...])` in
|
|
// main.js at whenReady, which runs BEFORE per-WebContentsView preloads (home,
|
|
// settings, popover, etc.), so those preloads still install their own bridges
|
|
// on top of `window.bcnr`. See DESIGN-integrated-wallet.md §3 for the full
|
|
// API surface.
|
|
const { contextBridge, ipcRenderer } = require("electron");
|
|
|
|
// Every method returns a Promise; a name that fails to resolve or isn't
|
|
// registered comes back as `null` (not an error) so page code can treat
|
|
// "no such name" as data, not an exception. `getBcnrTlds` always returns
|
|
// an array — even the seed ["bch"] before the on-chain list has landed.
|
|
contextBridge.exposeInMainWorld("bcnr", {
|
|
resolveName: (name) => ipcRenderer.invoke("bcnr:resolveName", name),
|
|
isRegistered: (name) => ipcRenderer.invoke("bcnr:isRegistered", name),
|
|
getBcnrTlds: () => ipcRenderer.invoke("bcnr:getBcnrTlds"),
|
|
getRecordVersion: (name) => ipcRenderer.invoke("bcnr:getRecordVersion", name),
|
|
// Owner-signed DNS records (A/AAAA/MX/TXT/CNAME/NS) published beside the
|
|
// name's Sia content and verified by the gateway against the current NFT
|
|
// holder. `{ name, dns, seq, updatedAt, owner }`, or null when the name is
|
|
// unregistered or has published no manifest. Waits ≤ 3 s for a fetch.
|
|
dnsRecords: (name) => ipcRenderer.invoke("bcnr:dnsRecords", name),
|
|
// Diagnostic — the eTLD+1 permission origin Theseus computes for THIS page.
|
|
// dApp devs use this to see how their subdomains bucket under one grant.
|
|
// Returns null for opaque origins (data:, blob:) which never hold grants.
|
|
getOrigin: () => ipcRenderer.invoke("bcnr:getOrigin"),
|
|
// One-click install of a community extension by catalog id (what
|
|
// theseus.x/extensions' Install button calls). The page names an id only;
|
|
// Theseus fetches the catalog itself, asks the user in a native dialog,
|
|
// verifies the publisher signature against the name's owner and installs.
|
|
// Resolves `{ ok, version, publisher }` or `{ ok:false, error }` (also
|
|
// "cancelled"). Pages can feature-detect it: absent on older builds.
|
|
installExtension: (id) => ipcRenderer.invoke("bcnr:installExtension", String(id || "")),
|
|
});
|