-
-
Notifications
You must be signed in to change notification settings - Fork 3
ipc contract
Version 1.7. The Rust shell (src-tauri/) and the UI (src/ui/) build against this page.
Change it in a PR that changes both sides, or keep the old form working as a shim.
- v1: first contract.
- v1.1: argument names,
chrome_set_height,platform,router_stats,bookmarks_export_file, history cursors,link-hover,fullscreen-changed,toast. - v1.3:
chrome_insets,chrome-insets-changed,window_fullscreen,status-size,status-side; the bubble shows after 100 ms and hides at once. - v1.4:
TabInfo.icon,Bookmark.icon,HistoryEntry.icon,icons-changed. See Site icons. #53 - v1.2:
connection_pause,connection_resume,router_control,RouterStatus.pausedand.managed,RouterStats.history. Theoutproxystate is gone: VERIFY no longer asks for a clearnet host. - v1.3:
report_preview,report_open,diag_crash_status,diag_crash_dismiss,diag_logs_delete(internal webview only); theeepview://reportpage;EEPVIEW_LOGis gone. See Diagnostics and bug reports. Added in #56. - Shipped in #29.
- v1.4: the
popupwebview,popup_open,popup_size,popup_close,popup-show,popup-closed,popup-select.chrome_set_heightreports the find bar only; the toolbar never grows for a popup — #55. - v1.5:
console_status,console_detect,console_open,console-changed,ConsoleInfo, theconsolewebview (#54). - v1.6: the console tab.
TabInfo.kindadds"console".console_open()takes no argument and opens the console home page in the console tab.ConsoleInfo.pages,ConsolePageand theno-pagereason are gone (#76). - v1.7:
RouterStats.uptimeResolutionMs,.floodfills,.tunnels.client,.tunnels.exploratory,.tunnelBuildSuccessPercent.total.router_statsreads the detected router console when there is no router helper. The UI reads this shape (src/ui/contract.ts). See Router console. - v1.8: no new command or event. The keyboard shortcuts follow the K1 table of Links, menus and shortcuts: new window N, and on Windows and Linux Ctrl+F4, Alt+D, F6, F5, Ctrl+F5, Ctrl+PageUp, Ctrl+PageDown and Alt+Home; Cmd+. and Cmd+Shift+[ ] on macOS. Alt+Left and Alt+Right are Back and Forward on Windows and Linux only. Esc stops a load only from a page (K4). The engines report link clicks, context menus and mouse buttons to the shell, never to a page (#77).
One OS window with several webviews (Tauri unstable multi-webview).
| Webview label | Loads | IPC | Notes |
|---|---|---|---|
toolbar |
src/ui/toolbar.html (bundled) |
yes | Top strip, 84 px: tab row (44 px) and nav row. 124 px with the find bar open. It sits above the content in z-order. |
internal |
src/ui/<page>.html (bundled) |
yes | Shown when the active tab is an internal page. |
status |
src/ui/status.html (bundled) |
events only | The link-hover bubble, bottom left, over the content. |
popup |
src/ui/popup.html (bundled) |
popup commands | The toolbar popups (suggestions, menu, router panel, router hint). Transparent, hidden until a popup opens, then sized and placed to the popup's own rectangle, on top of every other webview. |
tab-<id>-<n> |
remote http(s)://*.i2p/
|
NO | One per web tab. Only the active one is visible. |
console |
the router console, http://127.0.0.1:<port>
|
NO | Shown when the active tab is the console tab. There is at most one. Built only from a verified console. See Router console. |
On macOS the window has an overlay title bar with a hidden title. The traffic lights sit in the tab row. Windows and Linux keep the native decorations.
Internal pages: eepview://home, bookmarks, history, stats, settings, setup, blocked, router-down.
eepview://<page>?<query> loads src/ui/<page>.html?<query> in the internal webview.
| Page | Parameters |
|---|---|
blocked |
url: the refused address |
router-down |
url: the page to load when the router is back; state: RouterStatus.state; reason=paused while the connection is paused |
history |
q: the search text from the address bar |
Only toolbar and internal may call them (src-tauri/capabilities/). Arguments are camelCase in JS.
-
tab_new(url?: string) -> TabInfo. Defaulteepview://home. The new tab becomes active. -
tab_close(id). Closing the last tab opens a new home tab. -
tab_select(id),tab_move(id, index),tab_list() -> TabInfo[].
-
navigate(input) -> NavResult.- Blank or whitespace-only input is ignored.
-
foo.i2pbecomeshttp://foo.i2p/. The host is lower-cased and one trailing dot is dropped. - An
http(s)URL on a.i2por.b32.i2phost loads, with or without an explicit port 1–65535. -
eepview://xopens an internal page. - One word with no dot, no colon and no scheme searches history and bookmarks (
eepview://history?q=…). - Anything else that parses is refused with
{ok: false, reason: "not-i2p"}and showseepview://blocked?url=…(localhost:8080isnot-i2p). Input that does not parse isinvalid.
-
go_back(),go_forward(),reload(hard?),stop(),home(). They work with page JavaScript off: they call the engine's native API.
-
find(query, forward, matchCase)emitsfind-result.find_close(). Works with page JavaScript off. -
zoom_in(),zoom_out(),zoom_reset(): remembered per host; emittab-updated.TabInfo.zoomis a factor (1.0 = 100 %). -
site_js_set(host, on): rebuilds the tab webview at the same URL.
bookmarks_list() -> Bookmark[]-
bookmark_add({bookmark: {url, title, folder?}}) -> Bookmark. A non-I2P URL is refused with the errornot-i2p. -
bookmark_update({bookmark: Bookmark}),bookmark_remove(id),bookmark_find(url) -> Bookmark | null -
bookmarks_export() -> string(JSON),bookmarks_import(json) -> number -
bookmarks_export_file() -> string: writeseepview-bookmarks-<YYYYMMDD>.jsonto the Downloads folder and returns its path. - First run seeds
stats.i2p,i2p-projekt.i2p,reg.i2p,notbob.i2p.
At most 10 000 entries. Nothing is recorded while history.enabled is false.
-
history_query({query: {q?, before?, limit?}}) -> HistoryEntry[], newest first, ordered by (visiteddesc,iddesc).beforeis a cursor{visited, id}(a bare number of Unix ms also works). -
history_remove(id),history_clear(range: "hour" | "day" | "week" | "all") -
suggest(input) -> Suggestion[]: at most 8, from bookmarks and history.
settings_get() -> Settings, settings_set({patch: Partial<Settings>}) -> Settings.
router_status() -> RouterStatus-
router_stats() -> RouterStats. Every field may benull. The source is the router helper when it answers, else the detected router console (read only, one loopbackGET), else none: see Router console, R31–R46. -
connection_pause(): closes the gatekeeper, destroys everytab-*webview and showseepview://router-down?reason=paused. -
connection_resume(): runs VERIFY again. The gatekeeper opens and the active tab reloads only when VERIFY passes. If it fails, everything stays closed. -
router_control({action: "stop" | "start" | "restart"}) -> {ok: boolean, reason?: string}. It answers{ok: false, reason: "external"}until eepview runs its own router (Phase 3).
eepview shows router information and never changes the router configuration; these open the router's own console. See Router console.
-
console_status() -> ConsoleInfo: the stored detection result. It never probes. -
console_detect() -> ConsoleInfo: probes now, off the main thread. The UI calls it when the router panel opens, when the home page or Settings loads as the active tab, and whenrouter-statusturnsokwhile such a page shows. -
console_open() -> {ok: boolean, reason?: "no-console"}: opens the console home page in the console tab. It selects the console tab if one is open, and makes one if none is.
-
chrome_set_height(px): the toolbar reports its find bar: 124 or more while it shows, 84 when it is hidden. The toolbar is 124 px when the core has the find bar open (find, the Find shortcut) or the last report is 124 or more, else 84 px. It never takes another height. -
popup_open({kind, anchor: {x, y, width, height}, data?}) -> number(toolbaronly): opens a popup underanchor(window points) and returns its id.kindis"suggestions" | "menu" | "router" | "hint".datagoes to the page unchanged:{items: Suggestion[], index: number}for the suggestions,{title, text}for the hint. The shell sendspopup-showtopopup; the popup shows once the page reports its size. Opening another kind closes the open one; the same kind updates in place. -
popup_size({id, width, height})(popuponly): the natural size of the popup's card. The shell clamps it to the window (8 px margin), places thepopupwebview 4 px under the anchor and shows it, above every other webview (popupis raised last when a tab webview is added). The menu and the router panel take the focus. The size is the content size of the card with no width or height limit (scrollWidth/scrollHeightof an unconstrained card), never the size of the webview. -
popup_close({id, refocus?})(toolbarandpopup): closes the popupid. A stale id does nothing. Only the shell closes any popup (on a window resize).refocus: truegives the focus back to the toolbar. The shell hidespopupand sendspopup-closed. platform() -> "macos" | "windows" | "linux"window_fullscreen() -> boolean-
chrome_insets() -> {left: number}: the space the tab strip leaves on the left for the macOS window buttons. The shell centers the buttons on the tab row (y = 22), measures their frames, and answers their right edge plus their left margin, so the gap after the buttons equals the margin before them. 0 in full screen, and 0 on Windows and Linux (native title bar; the UI picks its own margin).
Only the internal webview may call these (capabilities/report.json). toolbar, status and tab-* cannot.
-
report_preview({kind, description, includeLog}) -> string: exactly the text that goes out, scrubbed. -
report_open({kind, description, includeLog}) -> {file: string, trimmed: boolean}: saves the report in Downloads, shows it in the file manager, and opens the prefilled GitHub issue in the system browser.fileis the file name, no folder. -
diag_crash_status() -> boolean: the last run crashed and the banner was not dismissed. diag_crash_dismiss()-
diag_logs_delete(): deletes the diagnostics log and the crash marker.
Rust sends them to toolbar, internal, status and popup.
-
tabs-changed: TabInfo[]: open, close, move, select. -
tab-updated: TabInfo: URL, title, loading, history, zoom. -
find-result: {query, matches: number | null, active: number | null} -
router-status: RouterStatus: every 5 s and on change. -
bookmarks-changed,history-changed,settings-changed: Settings -
shortcut: {action}: actions the UI handles (focus-address,open-find, …). -
toast: {kind: "info" | "warn", text}: refused downloads, new windows and in-page navigations. -
link-hover: {text, blocked}: the link under the mouse, already decoded and shortened to about 80 characters.blocked: truefor a link that would be refused (text=Blocked: <host>).textisLoading <host>…while a page loads, and empty when there is nothing to show. It shows after 100 ms of hovering (at once when the bubble is already up) and hides at once. -
fullscreen-changed: boolean -
console-changed: ConsoleInfo: when the detected console appears, goes away, moves or changes version. -
status-side: "left" | "right"(tostatusonly): the corner the bubble sits in. It moves to the bottom right while the mouse is over the bottom-left spot. -
chrome-insets-changed: {left: number}: on full screen enter and exit, and when the scale factor or the button frames change. -
icons-changed: null: a site icon was stored or deleted.tabs-changedfollows. Read the lists again for the newiconvalues. -
popup-show: {id, kind, anchorWidth, data}(topopuponly): render this popup, measure it, callpopup_size. -
popup-closed: {id, kind, refocus}(totoolbarandpopup): the popup closed (Esc, a click outside, a resize, or another popup).
-
popup-select: {index}(fromtoolbar, topopup): the arrow keys moved the highlight of the open suggestions. The page moves it; no new id, no new size. -
status-size: {width, height}(fromstatusonly): the natural size of the pill. The shell fits the transparentstatuswebview to it, at most half the content width; longer text ends in an ellipsis. The webview never sits under the mouse.
type TabInfo = { id: number; url: string; title: string; kind: "internal" | "web" | "console";
loading: boolean; canBack: boolean; canForward: boolean; active: boolean;
zoom: number; jsOn: boolean; bookmarked: boolean;
icon: string | null }; // 32 px site icon, data:image/png;base64,…; null for internal and console tabs
type NavResult = { ok: boolean; reason?: "not-i2p" | "router-down" | "invalid" };
type Bookmark = { id: string; url: string; title: string; folder: string | null; created: number;
icon: string | null }; // 64 px site icon
type HistoryEntry = { id: string; url: string; title: string; visited: number; visits: number;
icon: string | null }; // 32 px site icon
type Suggestion = { url: string; title: string; source: "bookmark" | "history" };
type Settings = { homepage: string; theme: "system" | "light" | "dark"; jsDefault: boolean;
history: { enabled: boolean }; keepCookies: boolean; zoomDefault: number };
type RouterStatus = { state: "verifying" | "ok" | "building" | "down" | "not-i2p";
proxy: string; version: string | null; detail: string | null;
paused: boolean; managed: boolean };
type RouterStats = { version: string | null; uptimeMs: number | null;
uptimeResolutionMs: number | null; // uptimeMs is rounded down to a multiple of this
networkStatus: string | null;
knownRouters: number | null; floodfills: number | null; activePeers: number | null;
tunnels: { in: number | null; out: number | null; participating: number | null;
client: number | null; exploratory: number | null }; // client, exploratory: in + out
bandwidthBytesPerSecond: { in1s: number | null; out1s: number | null; // the shortest window: "now"
in5m: number | null; out5m: number | null };
tunnelBuildSuccessPercent: { exploratory: number | null; client: number | null;
total: number | null };
history: { t: number; in: number; out: number }[] }; // last 10 min; the UI draws the last contiguous run (R41)
type ConsoleInfo = { found: boolean; kind: "java" | "i2pd" | null; origin: string | null;
version: string | null }; // origin and version: display onlyicon is a data:image/png;base64, URL that eepview drew itself, or null. bookmark_update and bookmarks_import ignore an icon they receive, and the stores never keep one. See Site icons.
jsDefault is true: JavaScript is on unless you turn it off for a site.
Rust handles them. They work wherever the keyboard focus is, also in a web page with JavaScript off. The table, with every key on each system, is in Links, menus and shortcuts (K1). Esc stops a load only from a page: in the address bar, the find field and a popup it belongs to the field (K4).
See ADR 0001.
- The
consolewebview gets no IPC, no proxy and an engine rule list for its one origin. An.i2plink in it opens a new normal tab. A console URL never loads in atab-*webview. -
tab-*webviews get no IPC, use the gatekeeper as proxy, run incognito unlesskeepCookies, and have WebRTC off. - No
tab-*webview exists before VERIFY passes. When the router goes down, or you pause, everytab-*is destroyed. - New-window requests open as a new tab through the same guard. Downloads are refused with a toast.
| Variable | Effect |
|---|---|
EEPVIEW_PROXY |
The router HTTP proxy, 127.0.0.1:<port> (default 127.0.0.1:4444). It must still pass VERIFY. |
EEPVIEW_START_URL |
Opens this URL in the first tab and skips the first-run setup. |
EEPVIEW_EXIT_AFTER |
Quits with exit code 0 after this many seconds. |
EEPVIEW_JS |
off turns page JavaScript off for every site. |
EEPVIEW_ROUTER_STATUS, EEPVIEW_ROUTER_STATUS_TOKEN
|
The router helper address and the file with its token, for router_stats. |
They exist in the release binary, for the leak test. None of them can weaken a layer.
eepview <url>… opens each argument through the rules of navigate, one tab each.
Generated from docs/wiki in the repository. Edit there, not here.