@shopkit/app-sdk
v0.1.3
Published
The in-iframe library merchant-app developers npm-install. Reads init payload from window.__RATIO_APP_INIT__, exposes typed Promise-returning RPC, auto-injects the session JWT on fetch() calls to whitelisted origins.
Downloads
45
Readme
@shopkit/app-sdk
The in-iframe library merchant-app developers npm install. Provides a typed Promise-returning RPC client into the merchant data layer + automatic session-JWT injection on fetch().
Quick start
import { createSdk } from "@shopkit/app-sdk";
const sdk = createSdk();
// RPC — fully typed, throws RpcError on host denial
const cart = await sdk.invoke<{ items: CartItem[] }>("cart.read");
// Plain fetch — Authorization: Bearer <sessionJwt> is auto-injected for
// any origin listed in manifest.networkOrigins[]. Apps don't author auth code.
const r = await fetch("https://api.acme.com/reviews?productId=" + pid);
const reviews = await r.json();What's in the SDK
| Export | Purpose |
| --- | --- |
| createSdk(options?) | Boots the SDK. Reads window.__RATIO_APP_INIT__, wires the postMessage RPC channel, configures the fetch interceptor, posts app:ready to the parent. |
| sdk.invoke<T>(method, args?, timeoutMs?) | Typed RPC. Resolves with the handler's return value, rejects with RpcError on host denial. |
| sdk.init | The init payload — surface, capabilities, settings, pageContext, sessionJwt, networkOrigins. |
| sdk.dispose() | Tears down listeners + restores window.fetch. |
| RpcError | Typed error class. .code: RpcErrorCode, .hint?: string (developer remediation message). |
| configureFetchInterceptor(jwt, origins) | The fetch interceptor as a standalone helper (the SDK calls it automatically). |
| readInit() | Read __RATIO_APP_INIT__ defensively; returns null outside an iframe. |
| AppInit type | TypeScript type for the init payload. |
RPC error codes (RpcErrorCode)
| Code | Meaning | Typical fix |
| --- | --- | --- |
| unknown_method | Method not in the platform's METHOD_CAPABILITIES map. | Typo? Or you're calling a method that doesn't exist yet. |
| capability_denied | Manifest doesn't declare the required scope. | Add the scope to surfaces[].capabilities[] and reinstall. RpcError.hint tells you which one. |
| capability_not_allowed_on_surface | Scope declared but not in this surface's allowlist. | Use the scope on a different surface, or it's not supported here. |
| no_handler | Host hasn't registered a handler for this method. | Merchant integration issue — file a bug with the platform team. |
| handler_failed | Host handler threw / rejected. | Inspect .message for upstream error. |
Fetch interception details
- Whitelist-only. Only origins in
manifest.networkOrigins[]receive theAuthorizationheader. All other fetches are untouched (your CDN, your 3rd-party CORS-enabled APIs, etc.). - Never overwrites. If your
initalready sets anAuthorizationheader, the SDK leaves it alone. Lets you opt out per-call. - Reversible.
sdk.dispose()restores the originalwindow.fetch. Useful for tests and for explicit teardown. - Opt-out. Pass
{ disableFetchInterceptor: true }tocreateSdk()if your app wants full control.
Lifecycle
- Sandbox shell loads (
apps.ratio.win/sandbox.html), postsiframe:readyto parent. - Parent posts
LOAD_APP_CODEwithbundleUrl,integrity,sessionJwt, etc. - Sandbox shell stamps
window.__RATIO_APP_INIT__, injects your bundle's<script>with SRI. - Your bundle runs, calls
createSdk()— SDK reads init, postsapp:ready. - Host adapter's
mount()Promise resolves onapp:ready. RPC channel open.
Cross-references
- Wire envelopes:
@shopkit/apps-capabilities(RpcRequestMessage, RpcResultMessage, IframeReadyMessage, etc.) - Manifest contract:
@shopkit/apps-manifest - Host adapter:
@shopkit/apps-platform - Architecture Reference §2.1 (sandbox runtime), §2.2 (host adapter), §2.4 (auth)
