@highnoteplatform/protocol
v2.0.0-alpha.0
Published
Typed message protocol for Highnote SDK-iframe communication
Downloads
55
Keywords
Readme
@highnoteplatform/protocol
Typed message protocol for Highnote SDK-iframe communication. This package is the single source of truth for all message shapes exchanged between host-side SDKs and their iframe counterparts.
Installation
npm install @highnoteplatform/protocolOverview
Every message between an SDK and its iframe flows through a versioned envelope:
SDK iframe
| |
|-- Envelope(HANDSHAKE_INIT) -->
|<-- Envelope(HANDSHAKE_ACK) --|
|-- Envelope(CONFIGURE) ------>|
|<-- Envelope(READY) ----------|
| |The envelope carries metadata (protocol version, instance ID, timestamp) and a typed payload validated at runtime with Valibot.
Usage
Creating and parsing envelopes
import { createEnvelope, parseEnvelope, PROTOCOL_VERSION } from "@highnoteplatform/protocol";
// Create (validates UUID instanceId)
const envelope = createEnvelope(
crypto.randomUUID(),
{ type: "READY" }
);
// Parse incoming data (rejects wrong protocol version)
const parsed = parseEnvelope(event.data);
if (!parsed) return; // invalid or version mismatchValidating messages
import { parseSdkMessage, parseIframeMessage } from "@highnoteplatform/protocol";
// SDK side — validate messages from iframe
const message = parseIframeMessage(envelope.payload);
if (!message) return; // unknown or malformed
switch (message.type) {
case "READY":
// iframe is ready
break;
case "ERROR":
console.error(message.code, message.message);
break;
}
// iframe side — validate messages from SDK
const sdkMsg = parseSdkMessage(envelope.payload);
if (sdkMsg?.type === "CONFIGURE") {
// sdkMsg.clientToken, sdkMsg.environment, sdkMsg.options
}Using schemas directly
import * as v from "valibot";
import { HandshakeInitSchema, type HandshakeInit } from "@highnoteplatform/protocol";
// Validate a specific message type
const result = v.safeParse(HandshakeInitSchema, data);
if (result.success) {
const init: HandshakeInit = result.output;
}Message Types
Common (all SDKs)
| Direction | Type | Description |
|-----------|------|-------------|
| SDK → iframe | HANDSHAKE_INIT | Initiates handshake with protocol version and SDK origin |
| iframe → SDK | HANDSHAKE_ACK | Acknowledges handshake with iframe protocol version and build hash |
| SDK → iframe | CONFIGURE | Sends credentials and SDK-specific options |
| iframe → SDK | READY | Iframe is initialized and ready |
| iframe → SDK | ERROR | Error with code, message, and optional context |
| SDK → iframe | DESTROY | Tear down the iframe |
| iframe → SDK | FOCUS_REQUEST | Request focus transfer to adjacent field |
| SDK → iframe | FOCUS_GRANT | Grant focus to a specific field |
| SDK → iframe | STYLE_UPDATE | Update iframe styles |
Card Viewer
| Direction | Type | Description |
|-----------|------|-------------|
| SDK → iframe | SET_MASK | Set mask state for a field (idempotent) |
| iframe → SDK | CARD_DATA_READY | Card data loaded for a field |
| iframe → SDK | CLIPBOARD_SUCCESS | Copy to clipboard succeeded |
| iframe → SDK | CLIPBOARD_ERROR | Copy to clipboard failed |
Secure Inputs
| Direction | Type | Description |
|-----------|------|-------------|
| SDK → iframe | TOKENIZE | Request card tokenization |
| SDK → iframe | CHANGE_PIN | Request PIN change |
| iframe → SDK | TOKENIZE_SUCCESS | Tokenization succeeded with payment method token |
| iframe → SDK | TOKENIZE_ERROR | Tokenization failed |
| iframe → SDK | PIN_CHANGE_SUCCESS | PIN change succeeded |
| iframe → SDK | PIN_CHANGE_ERROR | PIN change failed |
| iframe → SDK | VALIDITY_CHANGE | Field validation state changed |
| iframe → SDK | CARD_BRAND_CHANGE | Detected card brand changed |
Checkout
| Direction | Type | Description |
|-----------|------|-------------|
| iframe → SDK | CHECKOUT_SUCCESS | Checkout completed with payment method token |
| iframe → SDK | CHECKOUT_ERROR | Checkout failed |
| iframe → SDK | CHECKOUT_RESIZE | Iframe requests height change |
Security
- All messages are validated at runtime with Valibot schemas
- Unknown properties are stripped (prevents property injection)
clientTokenrejects empty strings at the protocol boundaryinstanceIdmust be a valid UUID- Protocol version is checked on every envelope parse
- Both SDK and iframe declare their protocol version during handshake
