Skip to content

Bridge — window.gerege, bridge_version: 1

The JSON bridge between a mini app's frontend and the host (Gerege App). A port of the OMAS bridge: the same methods, the same error codes, the same semantics; the name changes from openpay to gerege. The detailed contract a host implements (transport, origin checks, isolation): native-apps/shared/MINIAPP_BRIDGE.md.

Host Status
iOS (WKWebView) ✓
Android (WebView, addWebMessageListener) «coming soon» — the contract is ready, there is no code
Web (iframe) «coming soon»

1. Detecting and calling

The host injects the shim at document start, in the main frame only, when the document's origin is one of the app's allowed origins:

if (window.gerege?.bridgeVersion === 1) {
  const ctx = await window.gerege.getContext();
  await window.gerege.ready();
} else {
  // standalone browser (development) — fall back to your own mock
}
window.gerege = {
  bridgeVersion: 1,
  platform: "ios" | "android",
  call(method, params) → Promise<result>,   // error: Error, .code = §4
  ready(), getContext(), getLaunchCode(), requestPayment({ intentId }), …   // shorthands for call
}

Without the SDK (the level below the shim): on iOS, window.webkit.messageHandlers.gerege.postMessage({id, method, params}); the host delivers the reply through window.__geregeBridge.receive(reply). The reply envelope:

{"gerege_bridge": 1, "id": "…", "ok": true,  "result": {}}
{"gerege_bridge": 1, "id": "…", "ok": false, "error": {"code": "not_allowed", "message": "…"}}

2. Messages

  • id: a string (≤ 128) or a number, unique per request. params: an object ({} when absent).
  • Every request gets exactly one reply. The timeout is the caller's: 15 s; requestPayment and share — 10 min; getLaunchCode — 30 s.
  • A method the host does not know → unknown_method. A method missing from the app's bridge_methods (taken from the manifest's bridge.methods) → not_allowed. Exception: ready, getContext and close are always allowed.
  • safe_area.top = 0 (the host's header occupies it); bottom = the home indicator — add your own bottom padding.

3. Methods

Method params result Notes
ready {} {} The first screen is drawn — the host hides its loader. If it does not arrive within 10 s, an error screen
getContext {} {bridge_version, platform, app_version, locale, theme, safe_area:{top,bottom,left,right}, capabilities} locale: mn, en, ru, zh, fr, es, ar. capabilities = the methods allowed for this app and supported by the host
getLaunchCode {} {launch_code, expires_at} Renew the session (a new launch). Consent / maintenance → not_allowed
requestPayment {intentId} {status: "succeeded"\|"canceled"\|"failed", intentId} The host's payment sheet (payments.md §3). Do not trust succeeded — check on your backend. One at a time
openExternal {url} {} https; the host's global list or a prefix from the app's external_urls
share {text?, url?} {shared} The system share sheet. url is https
copy {text} {} ≤ 4 KB (UTF-8)
haptic {kind: "light"\|"medium"\|"success"\|"warning"\|"error"} {}
setTitle {text} {} ≤ 32 characters (longer is truncated)
close {} {} Closes the mini app
openMiniApp {slug, path?} {} Another mini app (a new launch, a new consent check)

Host → mini app events (themeChange, resume) do not exist in v1; call getContext again on visibilitychange.

4. Error codes

code Meaning
not_allowed The manifest / origin / app status does not allow it
invalid_params Bad parameters
canceled The person canceled
unknown_method The host does not know this method
unsupported Not possible on this platform
timeout No reply arrived (on the caller's side)
internal A host error

5. Security (as it concerns the mini app)

  • No secrets cross the bridge (tokens, accounts, balances). A launch_code is useless on its own — it needs the client secret, and lasts 60 s.
  • The mini app cannot reach the host's session, cookies or storage — it runs in an isolated (non-persistent) WebView.
  • Main-frame navigation outside the allowed origins → the system browser under openExternal's rules; anything else is blocked. window.open does not open a new window.
  • Asking for a password, card or PIN inside a mini app is FORBIDDEN — payment is only through requestPayment.

6. Testing

native-apps/shared/miniapp-test/index.html — a page for trying every method by tapping. In an iOS Debug build http://localhost is allowed (not in Release):

cd native-apps/shared/miniapp-test && python3 -m http.server 8765