@finamx/bridge-protocol
Shared TypeScript types, constants, and validators for the postMessage bridge protocol between extension iframes and the FinamX host application.
Both the host-side (@finamx/host-bridge) and the extension-side (@finamx/extension-sdk) depend on this package to guarantee a single source of truth for message shapes, version strings, and scope definitions.
Installation
Within the monorepo, reference it as a file: dependency:
"dependencies": {
"@finamx/bridge-protocol": "file:../bridge-protocol"
}
For a published extension SDK that ships to npm, use the semver range:
"dependencies": {
"@finamx/bridge-protocol": "^1.0.0"
}
Usage
import {
parseEnvelope,
serializeEnvelope,
isMethodAllowed,
DEFAULT_GRANTED_SCOPES,
type BridgeEnvelope,
type BridgeHelloPayload,
} from '@finamx/bridge-protocol';
// Parse an incoming postMessage data value
const envelope = parseEnvelope(event.data); // throws BridgeProtocolError on invalid input
// Check whether a platform invoke is permitted
if (!isMethodAllowed('market.quote', session.grantedScopes)) {
throw new Error('Scope not granted');
}
Exported API
Constants
| Export | Value | Description |
|---|---|---|
BRIDGE_VERSION | '1.0' | Current wire-protocol version; validated on every message. |
EMBED_TO_HOST_TYPES | array | All message types an extension iframe may send. |
HOST_TO_EMBED_TYPES | array | All message types the host may send back. |
METHOD_SCOPE_MAP | object | Maps platform method names to required capability scopes. |
DEFAULT_GRANTED_SCOPES | array | Scopes granted by default (market.read, ui.toast, user.profile.read). |
Types / Interfaces
| Type | Description |
|---|---|
BridgeEnvelope<T> | Wire envelope (v, type, id?, sessionId?, payload?). |
BridgeMessageType | Union of all valid message type strings. |
BridgeHelloPayload | Payload for bridge:hello — extension identifies itself to the host. |
BridgeReadyPayload | Payload for bridge:ready — host confirms session and granted scopes. |
BridgeErrorPayload | Payload for bridge:error — structured error with code and message. |
HostContext | Theme, locale, platform (web/ios/android), and app version. |
UiResizePayload | Payload for ui:resize — desired iframe height in pixels. |
UiSizePreferencePayload | Payload for ui:sizePreference — aspect ratio XOR named breakpoint; not ui:resize. Size is a UI surface preference (D-80-04), not a new extension kind. |
UiWallPayload | Payload for ui:wall — visible plus reason auth | payment; payment is type-only, no billing fields. |
UiToastPayload | Payload for ui:toast — message and optional variant. |
PlatformInvokePayload | Payload for platform:invoke — method and optional params. |
PlatformResultPayload | Payload for platform:result — ok, optional data or error. |
PlatformEventPayload | Payload for platform:event — event name and optional data. |
PlatformRevokePayload | Payload for platform:revoke — revocation reason. |
BridgeSessionConfig | Internal session record held by the host for a live iframe session. |
LaunchResponse | Shape returned by POST /embed/launch before an iframe is opened. |
InvokeRequest | Internal type for host-side method dispatch. |
AuditEntry | Audit log record written on every platform invoke. |
Validators / Utilities
| Export | Description |
|---|---|
parseEnvelope(data) | Parses and validates a raw postMessage data value; throws BridgeProtocolError. |
serializeEnvelope(envelope) | JSON-serializes an envelope for postMessage. |
parseInvokePayload(payload) | Validates a platform:invoke payload. |
parseResizePayload(payload, maxHeight) | Validates a ui:resize payload and clamps height. |
parseSizePreferencePayload(payload) | Validates a ui:sizePreference payload (exactly one of ratio or breakpoint). |
resolveSizePreference(pref, bounds) | Shared host layout math: preference → clamped pixel height. |
parseWallPayload(payload) | Validates a ui:wall payload (visible + closed reason auth | payment). |
assertSessionMatch(envelope, session) | Throws if the envelope sessionId does not match the active session. |
assertExternalEmbedPolicy(props) | Throws if an external extension tries to supply a raw embedUrl. |
requiredScopeForMethod(method) | Returns the scope string required for a given platform method. |
isMethodAllowed(method, grantedScopes) | Returns true when the method's required scope is in grantedScopes. |
BridgeProtocolError | Error class with a code string for structured error handling. |
Identity grant (3.0.0)
widget.identity.grant keeps its wire name, but 3.0.0 removed the HMAC identity helpers and the ./identity-context subpath. The grant now parses a profile: identity carries identityToken, a host-signed ES256 JWT (typ: platform.identity.v1); exchange carries exchangeCode + redeemUrl. A grant that mixes the two is rejected. This package only defines and validates shapes; it never signs. sessionJwt and Core/Gateway tokens must not be placed in the iframe or in the identity grant.
Build
npm run build
Compiles TypeScript to dist/ (ESM). The prepare script runs automatically on npm install within the monorepo.
Test
npm test
Builds first, then runs dist/validators.test.js using Node's built-in test runner (node --test).