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;
requestPaymentandshare— 10 min;getLaunchCode— 30 s. - A method the host does not know →
unknown_method. A method missing from the app'sbridge_methods(taken from the manifest'sbridge.methods) →not_allowed. Exception:ready,getContextandcloseare 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_codeis 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.opendoes 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):