@atom-circuit/embed-sdk 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +106 -0
- package/LICENSE +21 -0
- package/README.md +312 -0
- package/SECURITY.md +88 -0
- package/dist/atom-circuit.iife.js +2 -0
- package/dist/atom-circuit.iife.js.map +1 -0
- package/dist/index.cjs +694 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +391 -0
- package/dist/index.d.ts +391 -0
- package/dist/index.mjs +691 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react.cjs +744 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +337 -0
- package/dist/react.d.ts +337 -0
- package/dist/react.mjs +742 -0
- package/dist/react.mjs.map +1 -0
- package/package.json +125 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/protocol.ts","../src/iframe-client.ts","../src/resize.ts","../src/theme.ts","../src/mount.ts","../src/react.tsx"],"names":["isObject","isString","isFiniteNumber"],"mappings":"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","file":"react.mjs","sourcesContent":["/**\n * Atom Circuit Embed SDK - wire protocol contracts.\n *\n * Every message passed between host page and iframe must match one of the\n * discriminated unions exported here. Strict origin and shape checks rely on\n * these types both at compile time and at runtime (see assertion helpers).\n */\n\n/**\n * Wire-protocol major. SDK sends this in the URL (`?v=`) and during the\n * handshake. The iframe must honor at least the last 2 majors or 18 months\n * of SDK versions, whichever is longer. Bumped on every\n * breaking wire change; independent of the npm package version.\n */\nexport const PROTOCOL_VERSION = '1.0.0';\n\n/**\n * Origin the SDK trusts for all postMessage traffic. Equality, not prefix.\n */\nexport const WIDGET_ORIGIN = 'https://atomcircuit.net';\n\n/**\n * Path of the embedded swap page on the widget origin.\n */\nexport const WIDGET_PATH = '/embed/swap';\n\n/**\n * Capabilities advertised in the handshake. Names are stable strings; new\n * capabilities may be added without breaking older SDKs (they simply ignore\n * unknown entries).\n */\nexport type Capability =\n | 'swap.submit'\n | 'swap.status'\n | 'resize.report'\n | 'events.stream';\n\nexport type Capabilities = ReadonlyArray<Capability | string>;\n\n/**\n * Handshake payload exchanged once on connect. The iframe is expected to\n * reply with its own handshake describing its protocol version + capability\n * set; the SDK warns (does not throw) when the major versions diverge.\n */\nexport interface HandshakeMessage {\n readonly type: 'handshake';\n readonly protocolVersion: string;\n readonly capabilities: Capabilities;\n}\n\n/**\n * Iframe -> host: notify a new content height. Host clamps to `minHeight`\n * before applying. Sent on every measured change, RAF-debounced inside the\n * iframe.\n */\nexport interface ResizeMessage {\n readonly type: 'atomcircuit:resize';\n readonly height: number;\n}\n\n/**\n * Names of public events the iframe may emit. Stable additions go to the\n * end of the union to preserve exhaustive-match safety in older SDKs.\n */\nexport type WidgetEventName =\n | 'ready'\n | 'swap:submitted'\n | 'swap:success'\n | 'swap:error';\n\n/**\n * Generic event envelope. The `payload` shape is event-specific and typed\n * via the discriminated `WidgetEvent` union below.\n */\nexport interface WidgetEventMessage {\n readonly type: 'atomcircuit:event';\n readonly name: WidgetEventName;\n readonly payload?: unknown;\n}\n\n/* ------------------------------------------------------------------------- */\n/* Typed event payloads */\n/* ------------------------------------------------------------------------- */\n\nexport interface ReadyPayload {\n readonly protocolVersion: string;\n}\n\nexport interface SwapSubmittedPayload {\n readonly txHash: string;\n readonly route?: SwapRouteSummary;\n}\n\nexport interface SwapSuccessPayload {\n readonly txHash: string;\n}\n\nexport interface SwapErrorPayload {\n readonly code: string;\n readonly message: string;\n}\n\nexport interface SwapRouteSummary {\n readonly sourceChainId: string;\n readonly destChainId: string;\n readonly sourceDenom: string;\n readonly destDenom: string;\n readonly amountIn: string;\n readonly amountOut?: string;\n}\n\n/**\n * Discriminated union of all valid widget events. Use this when typing event\n * subscribers on the host side.\n */\nexport type WidgetEvent =\n | { readonly name: 'ready'; readonly payload: ReadyPayload }\n | { readonly name: 'swap:submitted'; readonly payload: SwapSubmittedPayload }\n | { readonly name: 'swap:success'; readonly payload: SwapSuccessPayload }\n | { readonly name: 'swap:error'; readonly payload: SwapErrorPayload };\n\n/**\n * Every accepted message on the wire.\n */\nexport type ProtocolMessage =\n | HandshakeMessage\n | ResizeMessage\n | WidgetEventMessage;\n\n/* ------------------------------------------------------------------------- */\n/* Theme + sizing */\n/* ------------------------------------------------------------------------- */\n\n/**\n * Optional theming contract passed from host to iframe via the `?theme=` URL\n * parameter (base64-encoded compact JSON of this object).\n *\n * Contract:\n * - The SDK validates every field against the rules documented per-field. If\n * ANY field fails validation, the entire theme is dropped and the iframe\n * falls back to its default appearance. Validation is intentionally strict\n * so a malformed theme cannot break the embed or be used as an injection\n * vector against the iframe's CSS surface.\n * - Fields are optional; the iframe must accept partial themes and apply only\n * the keys present.\n * - Color values are CSS hex strings (`#RGB` or `#RRGGBB`). Other CSS color\n * notations (rgb(), named colors) are rejected to keep the wire surface\n * trivial to validate and to avoid CSS-injection footguns via string\n * interpolation on the iframe side.\n * - `radius` and `fontSize` are plain pixel numbers in tight bounds.\n * - `fontFamily` is a CSS-safe subset: letters, digits, spaces, hyphens,\n * commas, single/double quotes, dots. Anything containing `<`, `>`, `;`,\n * `{`, `}`, `=`, `(`, `)`, newlines, or tabs is rejected. Max 200 chars.\n * - The iframe applies these as CSS custom properties on its embed root;\n * see the dapp side for the variable mapping.\n *\n * Omitting the `theme` field on MountOptions omits the `?theme=` param\n * from the iframe URL entirely.\n */\nexport interface ThemeOptions {\n /** Light/dark/auto mode hint. Auto follows the host system preference. */\n readonly mode?: 'light' | 'dark' | 'auto';\n /** Brand accent color used for primary buttons and highlights. Hex only. */\n readonly accentColor?: string;\n /** Page background color. Hex only. */\n readonly background?: string;\n /** Primary text/foreground color. Hex only. */\n readonly foreground?: string;\n /** Border color for inputs, cards, dividers. Hex only. */\n readonly border?: string;\n /** Corner radius in pixels. Range: 0-64 inclusive. */\n readonly radius?: number;\n /** Base font size in pixels. Range: 8-32 inclusive. */\n readonly fontSize?: number;\n /** CSS font-family value. CSS-safe subset only; see ThemeOptions doc. */\n readonly fontFamily?: string;\n}\n\n/* ------------------------------------------------------------------------- */\n/* Chrome options */\n/* ------------------------------------------------------------------------- */\n\n/**\n * Toggles for the visual chrome surfaces rendered by the embed page. Each\n * surface defaults to ON (true) so an embed dropped in with no chrome\n * option shows the full chrome. Setting a flag to false hides the\n * corresponding surface.\n *\n * Encoded into the iframe URL as part of the `?theme=` base64-JSON\n * payload under the `chrome` key. Validation is strict: each present field\n * must be a boolean, otherwise the entire chrome bundle is rejected.\n *\n * Omitting the `chrome` field, or omitting individual flags, leaves the\n * default-on behaviour in place.\n */\nexport interface ChromeOptions {\n /** Show the Atom Circuit logo in the top bar. Default true. */\n readonly logo?: boolean;\n /** Show the wallet connect / disconnect button in the top bar. Default true. */\n readonly wallet?: boolean;\n /** Show the \"Fees stake with <moniker>\" validator badge. Default true. */\n readonly validator?: boolean;\n /** Show the \"Powered by Atom Circuit\" footer. Default true. */\n readonly footer?: boolean;\n}\n\n/* ------------------------------------------------------------------------- */\n/* Mount options */\n/* ------------------------------------------------------------------------- */\n\n/**\n * Stable error codes surfaced via the `onError` callback. Consumers should\n * treat unknown codes as opaque diagnostics rather than control-flow\n * signals.\n */\nexport type MountErrorCode =\n | 'handshake_failed'\n | 'iframe_load_failed'\n | 'origin_mismatch'\n | 'protocol_incompatible'\n | 'unknown';\n\n/**\n * Shape of the error passed to `onError`. `cause` carries the original error\n * (if any) for diagnostic logging; it is typed as `unknown` so consumers\n * narrow it explicitly before use.\n */\nexport interface MountError {\n readonly code: MountErrorCode;\n readonly message: string;\n readonly cause?: unknown;\n}\n\n/**\n * Options accepted by both `mount(...)` (vanilla) and `<AtomCircuitSwap />`\n * (React). Required fields are kept to the absolute minimum so the embed\n * stays a one-liner for the validator.\n */\nexport interface MountOptions {\n /**\n * Validator-supplied affiliate identifier. Forwarded to the widget via the\n * iframe URL so fees route correctly.\n */\n /**\n * Validator referralId. Optional. When omitted (or empty / whitespace),\n * the SDK defaults to the literal string `'general'`, which fans the\n * affiliate fee across all participating Atom Circuit validators at\n * sweep time. Hosts that want fees to stake to a specific validator\n * pass that validator's 8-character hex referralId (or a registered\n * vanity slug).\n */\n referralId?: string;\n /**\n * Override the widget origin. Default `https://atomcircuit.net`. Used by\n * the test suite and local development only.\n */\n origin?: string;\n /**\n * Override the widget path. Default `/embed/swap`.\n */\n path?: string;\n /**\n * Minimum height applied to the iframe before any resize messages arrive.\n * Default `480px`.\n */\n minHeight?: string;\n /**\n * Optional additional CSS class applied to the iframe element.\n */\n className?: string;\n /**\n * Optional inline style merge. `height` and `width` are managed by the SDK\n * and ignored if supplied.\n */\n style?: Partial<CSSStyleDeclaration>;\n /**\n * Fires once the iframe has loaded and the handshake completes.\n */\n onReady?: (payload: ReadyPayload) => void;\n /**\n * Fires on every measured content-height change.\n */\n onResize?: (info: { height: number }) => void;\n /**\n * Fires when the user submits a swap (tx broadcast).\n */\n onSwapSubmitted?: (payload: SwapSubmittedPayload) => void;\n /**\n * Fires when a submitted swap confirms on chain.\n */\n onSwapSuccess?: (payload: SwapSuccessPayload) => void;\n /**\n * Fires when a swap fails or is rejected by the wallet.\n */\n onSwapError?: (payload: SwapErrorPayload) => void;\n /**\n * Fires on SDK-level failures (iframe load failure, handshake timeout,\n * origin mismatch, etc). When not supplied the SDK emits a single warning\n * via the injected warn sink and returns. This is distinct from\n * `onSwapError`, which reports widget-level (in-iframe) swap failures.\n */\n onError?: (error: MountError) => void;\n /**\n * Optional theme. See {@link ThemeOptions} for the validated contract.\n * Validation failure silently drops the theme; the iframe falls back to\n * defaults.\n */\n readonly theme?: ThemeOptions;\n /**\n * Optional chrome toggles. See {@link ChromeOptions} for the validated\n * contract. Validation failure silently drops the chrome bundle; the\n * iframe falls back to all-chrome-on defaults. Encoded alongside `theme`\n * in the iframe URL.\n */\n readonly chrome?: ChromeOptions;\n /**\n * CSS `width` applied to the iframe. Default `'100%'` when omitted.\n */\n readonly width?: string;\n /**\n * CSS `max-width` applied to the iframe. Default unset (no cap) when\n * omitted.\n */\n readonly maxWidth?: string;\n /**\n * CSS `padding` applied to the wrapper element around the iframe (NOT to\n * the iframe element itself, since padding on iframes does not behave\n * intuitively across browsers). Default `'0'` when omitted.\n */\n readonly padding?: string;\n}\n\n/* ------------------------------------------------------------------------- */\n/* Runtime validators (strict, no `any`) */\n/* ------------------------------------------------------------------------- */\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null;\n\nconst isString = (value: unknown): value is string => typeof value === 'string';\n\nconst isFiniteNumber = (value: unknown): value is number =>\n typeof value === 'number' && Number.isFinite(value);\n\nexport function isHandshakeMessage(value: unknown): value is HandshakeMessage {\n if (!isObject(value)) return false;\n if (value['type'] !== 'handshake') return false;\n if (!isString(value['protocolVersion'])) return false;\n if (!Array.isArray(value['capabilities'])) return false;\n return value['capabilities'].every(isString);\n}\n\nexport function isResizeMessage(value: unknown): value is ResizeMessage {\n if (!isObject(value)) return false;\n if (value['type'] !== 'atomcircuit:resize') return false;\n return isFiniteNumber(value['height']) && value['height'] >= 0;\n}\n\nconst WIDGET_EVENT_NAMES: ReadonlySet<WidgetEventName> = new Set([\n 'ready',\n 'swap:submitted',\n 'swap:success',\n 'swap:error',\n]);\n\nexport function isWidgetEventMessage(\n value: unknown\n): value is WidgetEventMessage {\n if (!isObject(value)) return false;\n if (value['type'] !== 'atomcircuit:event') return false;\n if (!isString(value['name'])) return false;\n return WIDGET_EVENT_NAMES.has(value['name'] as WidgetEventName);\n}\n\nexport function isProtocolMessage(value: unknown): value is ProtocolMessage {\n return (\n isHandshakeMessage(value) ||\n isResizeMessage(value) ||\n isWidgetEventMessage(value)\n );\n}\n\n/**\n * Returns true when two protocol versions agree on their major number. Used\n * by the SDK to decide whether to warn the host on handshake.\n */\nexport function isCompatibleProtocol(sdkVersion: string, remoteVersion: string): boolean {\n const sdkMajor = sdkVersion.split('.')[0];\n const remoteMajor = remoteVersion.split('.')[0];\n return sdkMajor !== undefined && sdkMajor === remoteMajor;\n}\n","/**\n * Host-side client that wraps Penpal v7 for typed RPC plus a custom\n * event emitter for streamed widget events (resize, ready, swap:*).\n *\n * Strict origin validation is enforced two ways:\n * 1. Penpal's `WindowMessenger({ allowedOrigins })` filters at the messenger layer.\n * 2. A second `MessageEvent` listener double-checks `event.origin` before\n * acknowledging stream events. Two-tier check is intentional: it ensures\n * we never trust a payload coming through a future Penpal change that\n * relaxes origin handling.\n */\n\nimport {\n connect,\n WindowMessenger,\n type Connection,\n type Messenger,\n type Methods,\n} from 'penpal';\n\nimport {\n PROTOCOL_VERSION,\n WIDGET_ORIGIN,\n isCompatibleProtocol,\n isProtocolMessage,\n isResizeMessage,\n isWidgetEventMessage,\n type Capabilities,\n type HandshakeMessage,\n type ReadyPayload,\n type SwapErrorPayload,\n type SwapSubmittedPayload,\n type SwapSuccessPayload,\n type WidgetEventName,\n type WidgetEventMessage,\n} from './protocol.js';\n\n/**\n * Methods the iframe can call on the host. Kept tiny: only the handshake\n * reply path is used. Stream events arrive through raw postMessage to keep\n * the iframe implementation simple.\n */\nexport interface HostMethods extends Methods {\n /**\n * Reports the iframe's handshake details. Resolves once the host has\n * recorded the capability set.\n */\n handshake(payload: HandshakeMessage): void;\n}\n\n/**\n * Methods the host may call on the iframe. The widget surface is narrow:\n * a `ping` liveness probe is the only RPC the SDK relies on; the primary\n * path is user-driven inside the widget.\n */\nexport interface RemoteMethods extends Methods {\n /**\n * Returns the protocol version the iframe is running. Used as a liveness\n * probe in tests.\n */\n ping(): string;\n}\n\n/**\n * Per-event handler signatures. Keeps the public surface free of `any`.\n */\nexport interface EventHandlers {\n ready: (payload: ReadyPayload) => void;\n resize: (info: { height: number }) => void;\n 'swap:submitted': (payload: SwapSubmittedPayload) => void;\n 'swap:success': (payload: SwapSuccessPayload) => void;\n 'swap:error': (payload: SwapErrorPayload) => void;\n}\n\nexport type EventName = keyof EventHandlers;\n\nexport interface IframeClientOptions {\n /**\n * The iframe element. Must already be appended to the DOM and have its\n * `src` set so `iframe.contentWindow` is non-null by the time `init()`\n * resolves.\n */\n iframe: HTMLIFrameElement;\n /**\n * Origin to trust for postMessage. Defaults to {@link WIDGET_ORIGIN}.\n */\n allowedOrigin?: string;\n /**\n * Connection timeout in milliseconds. Default 15000.\n */\n timeoutMs?: number;\n /**\n * Optional warning sink. Defaults to a no-op (the SDK refuses to write to\n * console.log per project policy).\n */\n warn?: (message: string) => void;\n}\n\ninterface PenpalConnectFn {\n <T extends Methods>(opts: {\n messenger: Messenger;\n methods?: Methods;\n timeout?: number;\n }): Connection<T>;\n}\n\nconst noopWarn = (_message: string): void => {\n /* silent by default */\n};\n\n/**\n * Typed Penpal RPC client + stream-event hub. One instance per iframe.\n */\nexport class IframeClient {\n private readonly iframe: HTMLIFrameElement;\n private readonly allowedOrigin: string;\n private readonly timeoutMs: number;\n private readonly warn: (message: string) => void;\n\n private connection: Connection<RemoteMethods> | null = null;\n private rawListener: ((event: MessageEvent) => void) | null = null;\n private destroyed = false;\n private handshakeReceived: HandshakeMessage | null = null;\n private handshakeResolvers: Array<(value: HandshakeMessage) => void> = [];\n\n private readonly handlers: {\n [K in EventName]: Set<EventHandlers[K]>;\n } = {\n ready: new Set(),\n resize: new Set(),\n 'swap:submitted': new Set(),\n 'swap:success': new Set(),\n 'swap:error': new Set(),\n };\n\n constructor(opts: IframeClientOptions) {\n this.iframe = opts.iframe;\n this.allowedOrigin = opts.allowedOrigin ?? WIDGET_ORIGIN;\n this.timeoutMs = opts.timeoutMs ?? 15_000;\n this.warn = opts.warn ?? noopWarn;\n }\n\n /**\n * Opens the Penpal connection and starts listening for stream events.\n * Resolves once the remote handshake has been received.\n */\n async init(): Promise<HandshakeMessage> {\n if (this.destroyed) {\n throw new Error('IframeClient: cannot init after destroy()');\n }\n if (this.connection) {\n throw new Error('IframeClient: already initialised');\n }\n\n const remoteWindow = this.iframe.contentWindow;\n if (!remoteWindow) {\n throw new Error('IframeClient: iframe.contentWindow is null');\n }\n\n this.rawListener = (event: MessageEvent): void => {\n this.handleRawMessage(event);\n };\n window.addEventListener('message', this.rawListener);\n\n const messenger = new WindowMessenger({\n remoteWindow,\n allowedOrigins: [this.allowedOrigin],\n });\n\n const hostMethods: HostMethods = {\n handshake: (payload: HandshakeMessage): void => {\n this.recordHandshake(payload);\n },\n };\n\n const typedConnect = connect as PenpalConnectFn;\n this.connection = typedConnect<RemoteMethods>({\n messenger,\n methods: hostMethods,\n timeout: this.timeoutMs,\n });\n\n // Wait for Penpal's own connection promise to resolve; this guarantees\n // both sides have exchanged Penpal's own SYN/ACK frames.\n await this.connection.promise;\n\n // If the iframe used the raw postMessage handshake path instead of the\n // RPC method, the handshake may have already arrived through\n // handleRawMessage. Either way, wait for it (bounded).\n return this.waitForHandshake();\n }\n\n /**\n * Subscribe to a named stream event. Returns an unsubscribe function.\n */\n on<K extends EventName>(name: K, handler: EventHandlers[K]): () => void {\n this.handlers[name].add(handler);\n return () => this.off(name, handler);\n }\n\n /**\n * Remove a registered handler.\n */\n off<K extends EventName>(name: K, handler: EventHandlers[K]): void {\n this.handlers[name].delete(handler);\n }\n\n /**\n * Tears down the Penpal connection, removes the raw listener, and clears\n * every event subscriber. Safe to call multiple times.\n */\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n\n if (this.rawListener) {\n window.removeEventListener('message', this.rawListener);\n this.rawListener = null;\n }\n if (this.connection) {\n this.connection.destroy();\n this.connection = null;\n }\n for (const set of Object.values(this.handlers)) {\n set.clear();\n }\n this.handshakeResolvers = [];\n }\n\n /**\n * Returns the handshake payload received from the iframe, or null if no\n * handshake has been observed yet.\n */\n getHandshake(): HandshakeMessage | null {\n return this.handshakeReceived;\n }\n\n /**\n * Returns true if the iframe advertised the given capability in its\n * handshake. Returns false when no handshake has been received yet or\n * when the capability is not present.\n *\n * Callers wrapping a method that requires a capability should gate on\n * `client.has('cap')` before invoking it. Calls to capabilities the\n * iframe does not advertise are silent no-ops at the call-site (or\n * resolve to `null`); the iframe is the source of truth for what it\n * implements.\n */\n has(capability: string): boolean {\n const list = this.handshakeReceived?.capabilities;\n if (!list) return false;\n for (const entry of list) {\n if (entry === capability) return true;\n }\n return false;\n }\n\n /**\n * Test-only seam. Allows unit tests to invoke the message handler without\n * dispatching real `MessageEvent`s through the JSDOM bus.\n */\n /* v8 ignore next 3 */\n _handleMessageForTest(event: MessageEvent): void {\n this.handleRawMessage(event);\n }\n\n /* --------------------------------------------------------------------- */\n\n private handleRawMessage(event: MessageEvent): void {\n if (event.origin !== this.allowedOrigin) {\n return;\n }\n if (event.source !== this.iframe.contentWindow) {\n return;\n }\n const data: unknown = event.data;\n if (!isProtocolMessage(data)) {\n return;\n }\n\n if (data.type === 'handshake') {\n this.recordHandshake(data);\n return;\n }\n\n if (isResizeMessage(data)) {\n this.emitResize(data.height);\n return;\n }\n\n if (isWidgetEventMessage(data)) {\n this.dispatchWidgetEvent(data);\n }\n }\n\n private recordHandshake(payload: HandshakeMessage): void {\n this.handshakeReceived = payload;\n if (!isCompatibleProtocol(PROTOCOL_VERSION, payload.protocolVersion)) {\n this.warn(\n `Atom Circuit embed: protocol mismatch (sdk=${PROTOCOL_VERSION}, iframe=${payload.protocolVersion}). Some features may be unavailable.`\n );\n }\n const resolvers = this.handshakeResolvers;\n this.handshakeResolvers = [];\n for (const resolve of resolvers) {\n resolve(payload);\n }\n }\n\n private waitForHandshake(): Promise<HandshakeMessage> {\n if (this.handshakeReceived) {\n return Promise.resolve(this.handshakeReceived);\n }\n return new Promise<HandshakeMessage>((resolve, reject) => {\n const timer = setTimeout(() => {\n const idx = this.handshakeResolvers.indexOf(wrapped);\n if (idx >= 0) this.handshakeResolvers.splice(idx, 1);\n reject(new Error('IframeClient: handshake timeout'));\n }, this.timeoutMs);\n const wrapped = (value: HandshakeMessage): void => {\n clearTimeout(timer);\n resolve(value);\n };\n this.handshakeResolvers.push(wrapped);\n });\n }\n\n private emitResize(height: number): void {\n for (const fn of this.handlers.resize) {\n fn({ height });\n }\n }\n\n private dispatchWidgetEvent(message: WidgetEventMessage): void {\n const name: WidgetEventName = message.name;\n switch (name) {\n case 'ready':\n this.emitReady((message.payload as ReadyPayload | undefined) ?? {\n protocolVersion: this.handshakeReceived?.protocolVersion ?? 'unknown',\n });\n return;\n case 'swap:submitted':\n this.emitTyped('swap:submitted', message.payload as SwapSubmittedPayload);\n return;\n case 'swap:success':\n this.emitTyped('swap:success', message.payload as SwapSuccessPayload);\n return;\n case 'swap:error':\n this.emitTyped('swap:error', message.payload as SwapErrorPayload);\n return;\n /* v8 ignore next 2 */\n default:\n return;\n }\n }\n\n private emitReady(payload: ReadyPayload): void {\n for (const fn of this.handlers.ready) {\n fn(payload);\n }\n }\n\n private emitTyped<K extends Exclude<EventName, 'ready' | 'resize'>>(\n name: K,\n payload: Parameters<EventHandlers[K]>[0]\n ): void {\n for (const fn of this.handlers[name]) {\n (fn as (p: unknown) => void)(payload);\n }\n }\n}\n\n/**\n * Exported for advanced callers that need the trusted origin without\n * importing the protocol module directly.\n */\nexport const TRUSTED_ORIGIN = WIDGET_ORIGIN;\n\n/**\n * Re-export so consumers can capability-gate calls without importing the\n * protocol module.\n */\nexport type { Capabilities };\n","/**\n * Host-side resize handler. Subscribes to `IframeClient`'s `resize` stream\n * and applies the reported height to the iframe element, RAF-debounced.\n *\n * The iframe is the source of truth for height; the SDK only clamps to\n * `minHeight` to avoid scrollbar thrash on mobile keyboard open.\n */\n\nimport type { IframeClient } from './iframe-client.js';\n\nexport interface ResizeOptions {\n iframe: HTMLIFrameElement;\n client: IframeClient;\n minHeight?: string;\n}\n\nexport interface ResizeHandle {\n destroy(): void;\n}\n\nconst DEFAULT_MIN_HEIGHT = '480px';\n\n/**\n * Parses a CSS length like \"480px\" or \"30rem\" into pixels. Falls back to 0\n * when the unit is not recognised.\n */\nfunction parsePixels(value: string): number {\n const trimmed = value.trim();\n const match = trimmed.match(/^([0-9]+(?:\\.[0-9]+)?)(px)?$/i);\n if (!match) return 0;\n const numStr = match[1];\n if (numStr === undefined) return 0;\n const num = Number.parseFloat(numStr);\n return Number.isFinite(num) ? num : 0;\n}\n\n/**\n * Wires the iframe's height to incoming resize events. Returns a handle whose\n * `destroy()` unsubscribes and cancels any in-flight RAF.\n */\nexport function attachResize(opts: ResizeOptions): ResizeHandle {\n const { iframe, client } = opts;\n const minHeight = opts.minHeight ?? DEFAULT_MIN_HEIGHT;\n const minPx = parsePixels(minHeight);\n\n // Apply min-height immediately so the iframe is not 0px before the first\n // resize message lands.\n iframe.style.minHeight = minHeight;\n if (!iframe.style.height) {\n iframe.style.height = minHeight;\n }\n\n let pending: number | null = null;\n let lastApplied = -1;\n let destroyed = false;\n\n const apply = (height: number): void => {\n if (destroyed) return;\n const clamped = Math.max(height, minPx);\n if (clamped === lastApplied) return;\n iframe.style.height = `${clamped}px`;\n lastApplied = clamped;\n };\n\n const schedule = (height: number): void => {\n if (destroyed) return;\n if (pending !== null) {\n cancelAnimationFrame(pending);\n }\n if (typeof window === 'undefined' || typeof window.requestAnimationFrame !== 'function') {\n apply(height);\n return;\n }\n pending = window.requestAnimationFrame(() => {\n pending = null;\n apply(height);\n });\n };\n\n const unsubscribe = client.on('resize', ({ height }) => {\n schedule(height);\n });\n\n return {\n destroy(): void {\n if (destroyed) return;\n destroyed = true;\n if (pending !== null && typeof window !== 'undefined' && typeof window.cancelAnimationFrame === 'function') {\n window.cancelAnimationFrame(pending);\n }\n pending = null;\n unsubscribe();\n },\n };\n}\n\nexport const RESIZE_DEFAULT_MIN_HEIGHT = DEFAULT_MIN_HEIGHT;\n","/**\n * Theme validation + encoding for the embed SDK.\n *\n * The host SDK is the trust boundary: every theme that crosses into the\n * iframe URL passes through {@link validateTheme} first, which returns a\n * deep-cloned, fully-validated object or null. The iframe receives the\n * theme as base64-encoded JSON in the `?theme=` query param (see\n * {@link encodeTheme}); the dapp on the iframe side decodes and applies\n * the validated subset as CSS custom properties.\n *\n * Validation is intentionally strict (hex colors only, character allowlist\n * on fontFamily, tight numeric ranges) so a malformed or hostile theme can\n * neither break the embed nor be used as a CSS-injection vector. Any single\n * field failing validation drops the entire theme.\n */\n\nimport type { ChromeOptions, ThemeOptions } from './protocol.js';\n\nconst HEX_COLOR_RE = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\n\n/**\n * fontFamily allowlist: letters, digits, spaces, hyphens, commas, single\n * and double quotes, dots. Anything else (including `<>;{}=()`, newlines,\n * tabs, semicolons, etc) is rejected.\n */\nconst FONT_FAMILY_RE = /^[a-zA-Z0-9 ,'\".\\-]+$/;\n\nconst FONT_FAMILY_MAX_LEN = 200;\n\nconst MODES: ReadonlySet<'light' | 'dark' | 'auto'> = new Set([\n 'light',\n 'dark',\n 'auto',\n]);\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null;\n\nconst isString = (value: unknown): value is string => typeof value === 'string';\n\nconst isFiniteNumber = (value: unknown): value is number =>\n typeof value === 'number' && Number.isFinite(value);\n\nfunction isHexColor(value: unknown): value is string {\n return isString(value) && HEX_COLOR_RE.test(value);\n}\n\nfunction isValidMode(value: unknown): value is 'light' | 'dark' | 'auto' {\n return isString(value) && MODES.has(value as 'light' | 'dark' | 'auto');\n}\n\nfunction isValidFontFamily(value: unknown): value is string {\n if (!isString(value)) return false;\n if (value.length === 0 || value.length > FONT_FAMILY_MAX_LEN) return false;\n return FONT_FAMILY_RE.test(value);\n}\n\n/**\n * Validate an unknown theme value. Returns a deep-cloned ThemeOptions object\n * containing only the present (defined) fields if every field that is\n * present passes its validator. Returns null if the input is not an object\n * or if any present field fails validation.\n *\n * Partial themes are allowed: only the keys that appear in the input are\n * validated and carried through. Undefined keys are skipped silently.\n */\nexport function validateTheme(theme: unknown): ThemeOptions | null {\n if (!isObject(theme)) return null;\n\n const out: {\n -readonly [K in keyof ThemeOptions]: ThemeOptions[K];\n } = {};\n\n if (theme['mode'] !== undefined) {\n if (!isValidMode(theme['mode'])) return null;\n out.mode = theme['mode'];\n }\n\n if (theme['accentColor'] !== undefined) {\n if (!isHexColor(theme['accentColor'])) return null;\n out.accentColor = theme['accentColor'];\n }\n\n if (theme['background'] !== undefined) {\n if (!isHexColor(theme['background'])) return null;\n out.background = theme['background'];\n }\n\n if (theme['foreground'] !== undefined) {\n if (!isHexColor(theme['foreground'])) return null;\n out.foreground = theme['foreground'];\n }\n\n if (theme['border'] !== undefined) {\n if (!isHexColor(theme['border'])) return null;\n out.border = theme['border'];\n }\n\n if (theme['radius'] !== undefined) {\n const r = theme['radius'];\n if (!isFiniteNumber(r) || r < 0 || r > 64) return null;\n out.radius = r;\n }\n\n if (theme['fontSize'] !== undefined) {\n const fs = theme['fontSize'];\n if (!isFiniteNumber(fs) || fs < 8 || fs > 32) return null;\n out.fontSize = fs;\n }\n\n if (theme['fontFamily'] !== undefined) {\n if (!isValidFontFamily(theme['fontFamily'])) return null;\n out.fontFamily = theme['fontFamily'];\n }\n\n return out;\n}\n\nconst isBoolean = (value: unknown): value is boolean => typeof value === 'boolean';\n\n/**\n * Validate an unknown chrome value. Returns a deep-cloned ChromeOptions\n * object containing only the present (defined) fields if every field that is\n * present is a boolean. Returns null if the input is not an object or if any\n * present field is non-boolean.\n *\n * Partial chrome bundles are allowed: only the keys that appear in the input\n * are validated and carried through. Undefined keys are skipped silently.\n */\nexport function validateChrome(chrome: unknown): ChromeOptions | null {\n if (!isObject(chrome)) return null;\n\n const out: {\n -readonly [K in keyof ChromeOptions]: ChromeOptions[K];\n } = {};\n\n if (chrome['logo'] !== undefined) {\n if (!isBoolean(chrome['logo'])) return null;\n out.logo = chrome['logo'];\n }\n\n if (chrome['wallet'] !== undefined) {\n if (!isBoolean(chrome['wallet'])) return null;\n out.wallet = chrome['wallet'];\n }\n\n if (chrome['validator'] !== undefined) {\n if (!isBoolean(chrome['validator'])) return null;\n out.validator = chrome['validator'];\n }\n\n if (chrome['footer'] !== undefined) {\n if (!isBoolean(chrome['footer'])) return null;\n out.footer = chrome['footer'];\n }\n\n return out;\n}\n\n/**\n * Encode a validated theme as URL-safe base64(JSON). Skips null/undefined\n * fields so the encoded payload only carries keys actually set by the host.\n *\n * An optional validated chrome bundle is attached under the reserved\n * `chrome` key inside the same JSON payload so the existing `?theme=`\n * iframe-URL parameter carries both. The dapp side decodes the combined\n * payload and applies each half independently.\n *\n * Browser path uses `btoa(JSON.stringify(payload))`. Node fallback (tests)\n * uses `Buffer.from(...).toString('base64')`. Either way the output is\n * standard base64 - the dapp side decodes with the matching primitive.\n */\nexport function encodeTheme(\n theme: ThemeOptions,\n chrome?: ChromeOptions | null\n): string {\n const compact: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(theme)) {\n if (value === null || value === undefined) continue;\n compact[key] = value;\n }\n if (chrome && Object.keys(chrome).length > 0) {\n const chromeCompact: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(chrome)) {\n if (value === null || value === undefined) continue;\n chromeCompact[key] = value;\n }\n if (Object.keys(chromeCompact).length > 0) {\n compact['chrome'] = chromeCompact;\n }\n }\n const json = JSON.stringify(compact);\n if (typeof btoa === 'function') {\n return btoa(json);\n }\n // Node fallback for unit tests / SSR contexts.\n return Buffer.from(json, 'utf-8').toString('base64');\n}\n","/**\n * Vanilla mount factory. Builds the iframe element, applies sandbox attrs,\n * wires up the IframeClient + resize handler, and returns a destroy handle.\n */\n\nimport { IframeClient } from './iframe-client.js';\nimport { attachResize, type ResizeHandle } from './resize.js';\nimport {\n PROTOCOL_VERSION,\n WIDGET_ORIGIN,\n WIDGET_PATH,\n type MountError,\n type MountErrorCode,\n type MountOptions,\n type ReadyPayload,\n type SwapErrorPayload,\n type SwapSubmittedPayload,\n type SwapSuccessPayload,\n} from './protocol.js';\nimport { encodeTheme, validateChrome, validateTheme } from './theme.js';\n\nexport type { MountOptions, MountError, MountErrorCode };\nexport type { WidgetEvent } from './protocol.js';\nexport { PROTOCOL_VERSION };\n\n/**\n * Handshake timeout enforced by `mount()` via `Promise.race`. Mirrors the\n * default Penpal timeout in `IframeClient` so the error surface is\n * predictable even if a future refactor decouples the two.\n */\nconst HANDSHAKE_TIMEOUT_MS = 15_000;\n\n/**\n * Sandbox attribute applied to the iframe. Allowed:\n * - allow-scripts: widget needs JS.\n * - allow-same-origin: required so Keplr can inject window.keplr.\n * - allow-popups + allow-popups-to-escape-sandbox: wallet popups (Keplr,\n * Leap, Cosmostation), tx success links.\n * - allow-forms: in case future widget revs add a form-based on-ramp.\n *\n * Deliberately omitted: `allow-top-navigation` (clickjacking risk).\n */\nexport const SANDBOX_ATTR =\n 'allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-forms';\n\n/**\n * Inline SVG for the pre-handshake loading spinner. Rendered inside an\n * absolute-positioned overlay on the wrapper while the iframe is still\n * loading. The rotation is driven by the Web Animations API in mount()\n * rather than inline SMIL because SMIL set via `innerHTML` does not\n * reliably start the animation during the initial-page-load phase on\n * Chromium - the exact phase where the host needs the spinner to be\n * visibly spinning. The arc is painted with a brand gradient\n * (cyan -> violet) so the loader visually matches the dapp's accent\n * palette; the background ring is a neutral grey that reads on both\n * light and dark host backgrounds. The gradient id is namespaced to\n * avoid collisions with host page `<defs>`.\n */\nconst LOADER_SVG = '<svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">'\n + '<circle cx=\"16\" cy=\"16\" r=\"13\" stroke=\"#7B61FF\" stroke-width=\"2.5\" stroke-opacity=\"0.28\"/>'\n + '<path d=\"M29 16a13 13 0 0 0-13-13\" stroke=\"#33D6FF\" stroke-width=\"2.5\" stroke-linecap=\"round\"/>'\n + '</svg>';\n\nexport interface MountResult {\n iframe: HTMLIFrameElement;\n /**\n * Wrapper div the iframe is appended to. Always present in v1.0.0 and\n * later. Hosts that previously relied on `container > iframe` should use\n * `container iframe` or `[data-atom-circuit-embed] iframe` instead. The\n * wrapper carries a position:relative anchor so the pre-handshake\n * loading overlay (the spinner) can absolutely-position over the iframe\n * without leaking into surrounding host layout. Padding (when supplied)\n * is applied to this wrapper, never to the iframe element itself.\n */\n wrapper: HTMLDivElement;\n client: IframeClient;\n destroy(): void;\n}\n\ntype BuildSrcOpts = Pick<\n MountOptions,\n 'origin' | 'path' | 'theme' | 'chrome'\n> & {\n /** Resolved referralId. mount() defaults undefined/empty to 'general'\n * before calling buildSrc, so this is always a non-empty string here. */\n readonly referralId: string;\n /** Optional warn sink used to report theme validation failures. */\n readonly warn?: (message: string) => void;\n};\n\nfunction buildSrc(opts: BuildSrcOpts): string {\n const origin = (opts.origin ?? WIDGET_ORIGIN).replace(/\\/$/, '');\n const path = opts.path ?? WIDGET_PATH;\n const params = new URLSearchParams();\n params.set('ref', opts.referralId);\n params.set('v', PROTOCOL_VERSION);\n\n // Validate theme + chrome independently; the URL param is set when EITHER\n // half validates so a host can pass chrome alone without a theme override.\n const validatedTheme =\n opts.theme !== undefined ? validateTheme(opts.theme) : null;\n if (opts.theme !== undefined && validatedTheme === null && opts.warn) {\n opts.warn(\n 'Atom Circuit embed: theme validation failed, falling back to defaults'\n );\n }\n const validatedChrome =\n opts.chrome !== undefined ? validateChrome(opts.chrome) : null;\n if (opts.chrome !== undefined && validatedChrome === null && opts.warn) {\n opts.warn(\n 'Atom Circuit embed: chrome validation failed, falling back to defaults'\n );\n }\n\n if (validatedTheme !== null || validatedChrome !== null) {\n params.set(\n 'theme',\n encodeTheme(validatedTheme ?? {}, validatedChrome ?? undefined)\n );\n }\n\n const sep = path.includes('?') ? '&' : '?';\n return `${origin}${path}${sep}${params.toString()}`;\n}\n\n/**\n * Apply caller-supplied inline style overrides to the iframe.\n *\n * `height` is ignored unconditionally (the resize handler owns it).\n * `width` is also ignored from the generic `style` bag because the\n * dedicated `width` MountOption is the supported surface; entries passing\n * `style.width` are silently filtered to keep behaviour predictable when\n * both are supplied.\n */\nfunction applyStyle(iframe: HTMLIFrameElement, style: Partial<CSSStyleDeclaration> | undefined): void {\n if (!style) return;\n for (const key of Object.keys(style) as Array<keyof CSSStyleDeclaration>) {\n if (key === 'height' || key === 'width') continue;\n const value = style[key];\n if (typeof value === 'string') {\n // CSSStyleDeclaration is a string-indexed setter; assignment is safe.\n (iframe.style as unknown as Record<string, string>)[key as string] = value;\n }\n }\n}\n\n/**\n * Apply the sizing MountOptions (`width`, `maxWidth`, `padding`) to the\n * iframe and its optional wrapper. Padding lives on the wrapper because\n * applying padding to an `<iframe>` element itself does not behave\n * intuitively across browsers (the padding sits inside the iframe's CSS\n * box but the document inside the iframe is unaffected, producing a\n * visible margin the embed page cannot control). When padding is not\n * supplied the wrapper is omitted entirely so a simple\n * `container > iframe` DOM shape is preserved for hosts using that\n * structural CSS selector.\n *\n * `height` is intentionally NOT touched here. The resize handler owns it.\n */\nfunction applySizing(\n iframe: HTMLIFrameElement,\n wrapper: HTMLDivElement,\n opts: Pick<MountOptions, 'width' | 'maxWidth' | 'padding'>\n): void {\n if (opts.width !== undefined) {\n iframe.style.width = opts.width;\n }\n if (opts.maxWidth !== undefined) {\n iframe.style.maxWidth = opts.maxWidth;\n }\n if (opts.padding !== undefined) {\n wrapper.style.padding = opts.padding;\n }\n}\n\n/**\n * Creates an iframe, appends it to the container, and connects to the widget.\n * Returns a handle for cleanup.\n */\nexport function mount(container: HTMLElement, opts: MountOptions = {}): MountResult {\n if (!container || typeof container.appendChild !== 'function') {\n throw new TypeError('mount: container must be an HTMLElement');\n }\n // referralId default: 'general'. Hosts that do not pass an explicit\n // referralId (or pass an empty/whitespace-only string) embed the\n // general-pool variant, which fans the affiliate fee across all\n // participating Atom Circuit validators at sweep time. Passing an\n // explicit validator id keeps the prior single-validator behavior.\n const referralIdRaw = typeof opts.referralId === 'string'\n ? opts.referralId.trim()\n : '';\n const resolvedReferralId = referralIdRaw.length > 0 ? referralIdRaw : 'general';\n\n const warnSink: (message: string) => void =\n typeof console !== 'undefined' && typeof console.warn === 'function'\n ? (msg: string): void => {\n console.warn(msg);\n }\n : (): void => {\n /* no console available */\n };\n\n // Loading-overlay dismisser. Bound to a no-op until the loader element\n // is created below; reportError() and the ready-event handler capture\n // this closure binding so the eventual handler is the one that fires.\n let dismissLoader: () => void = (): void => { /* not yet wired */ };\n\n const reportError = (error: MountError): void => {\n // Always clear the loader on any error path so a permanent handshake\n // failure does not leave a forever-spinning state in the host page.\n dismissLoader();\n if (opts.onError) {\n opts.onError(error);\n return;\n }\n warnSink(`Atom Circuit embed: ${error.code}: ${error.message}`);\n };\n\n // Wrap the iframe in a dedicated div. The wrapper carries\n // position:relative so the pre-handshake loading overlay can absolutely\n // position over the iframe without affecting host page layout. It also\n // hosts any caller-supplied padding (iframes ignore their own padding\n // because the inner document does its own box-model). Hosts that\n // previously relied on the `container > iframe` selector should switch\n // to `container iframe` or `[data-atom-circuit-embed] iframe`. The\n // wrapper attribute is unchanged from earlier versions.\n const wrapper: HTMLDivElement = document.createElement('div');\n wrapper.setAttribute('data-atom-circuit-embed', '');\n wrapper.style.position = 'relative';\n wrapper.style.width = '100%';\n wrapper.style.display = 'block';\n\n const iframe = document.createElement('iframe');\n iframe.src = buildSrc({\n referralId: resolvedReferralId,\n ...(opts.origin !== undefined ? { origin: opts.origin } : {}),\n ...(opts.path !== undefined ? { path: opts.path } : {}),\n ...(opts.theme !== undefined ? { theme: opts.theme } : {}),\n ...(opts.chrome !== undefined ? { chrome: opts.chrome } : {}),\n warn: warnSink,\n });\n iframe.setAttribute('sandbox', SANDBOX_ATTR);\n iframe.setAttribute('allow', 'clipboard-write; clipboard-read');\n iframe.setAttribute('title', 'Atom Circuit swap widget');\n iframe.setAttribute('loading', 'lazy');\n iframe.setAttribute('referrerpolicy', 'strict-origin-when-cross-origin');\n iframe.style.width = '100%';\n iframe.style.border = '0';\n iframe.style.display = 'block';\n iframe.style.colorScheme = 'normal';\n // Iframe sits at z-index 1 so the loader (z-index 2) overlays it during\n // handshake. Both are within the same stacking context (the wrapper).\n iframe.style.position = 'relative';\n iframe.style.zIndex = '1';\n applyStyle(iframe, opts.style);\n applySizing(iframe, wrapper, opts);\n if (opts.className) {\n iframe.className = opts.className;\n }\n\n // Pre-handshake loading overlay. Absolute-positioned within the wrapper,\n // pointer-events:none so user clicks pass straight to the iframe once\n // it's interactive. Color is a neutral mid-grey that reads on both\n // light and dark host backgrounds. Removed on the first ready event\n // OR on any onError dispatch (whichever fires first) so a permanent\n // handshake failure does not leave a spinning forever-state.\n const loader: HTMLDivElement = document.createElement('div');\n loader.setAttribute('data-atom-circuit-loader', '');\n loader.setAttribute('aria-hidden', 'true');\n loader.style.position = 'absolute';\n loader.style.inset = '0';\n loader.style.display = 'flex';\n loader.style.alignItems = 'center';\n loader.style.justifyContent = 'center';\n loader.style.pointerEvents = 'none';\n loader.style.color = '#888888';\n loader.style.transition = 'opacity 0.08s ease-out';\n loader.style.opacity = '1';\n loader.style.zIndex = '2';\n loader.innerHTML = LOADER_SVG;\n\n // Drive the spinner rotation via the Web Animations API. The SMIL\n // approach (the earlier shape of LOADER_SVG) renders a static frame\n // when the SVG is set via innerHTML during the initial page-load\n // phase on Chromium - exactly when the host needs the spinner to be\n // visibly spinning. WAAPI starts immediately and runs off the\n // browser's compositor thread without a JS rAF loop. The animation\n // is owned by the loader's SVG child, so removing the loader\n // (dismissLoader below) garbage-collects the animation too.\n const loaderSvg = loader.querySelector('svg');\n let spinAnimation: Animation | null = null;\n if (loaderSvg && typeof loaderSvg.animate === 'function') {\n // transform-origin via CSS on the SVG itself rather than inside the\n // keyframes so the rotation pivots about the SVG centre regardless\n // of how the host page sized the surrounding wrapper.\n (loaderSvg as SVGElement).style.transformOrigin = 'center';\n spinAnimation = loaderSvg.animate(\n [{ transform: 'rotate(0deg)' }, { transform: 'rotate(360deg)' }],\n { duration: 900, iterations: Infinity, easing: 'linear' },\n );\n }\n\n let loaderDismissed = false;\n dismissLoader = (): void => {\n if (loaderDismissed) return;\n loaderDismissed = true;\n loader.style.opacity = '0';\n // Cancel the spinner animation immediately so the rAF/compositor\n // work stops even before the fade-out completes.\n if (spinAnimation) {\n try { spinAnimation.cancel(); } catch { /* DOMException on detached node, safe to ignore */ }\n spinAnimation = null;\n }\n // Remove from DOM after the fade-out transition completes so it does\n // not eat pointer events or screen-reader focus.\n setTimeout(() => {\n if (loader.parentNode) loader.parentNode.removeChild(loader);\n }, 100);\n };\n\n // Forward native iframe network/load failures to onError. Browsers fire\n // `error` on the iframe element for resource failures (DNS, TLS, 5xx HTML\n // pages still fire `load`, so this only catches transport-level breakage).\n const onIframeError = (event: Event | string): void => {\n reportError({\n code: 'iframe_load_failed',\n message: 'Iframe failed to load the widget URL',\n cause: event,\n });\n };\n iframe.addEventListener('error', onIframeError);\n\n // Dismiss the loading overlay as soon as the iframe document fires\n // `load`. This is strictly earlier than the postMessage `ready`\n // handshake event because `load` only requires the iframe's HTML to\n // finish loading; the handshake additionally requires the dapp JS to\n // execute and respond. Without this listener the spinner stayed\n // visible for several hundred ms after the dapp had begun painting,\n // overlapping the swap UI. The ready-side dismissal is still wired\n // below as a backstop in case the load event is delayed by a slow\n // resource (the dismissLoader closure is idempotent).\n const onIframeLoad = (): void => {\n dismissLoader();\n };\n iframe.addEventListener('load', onIframeLoad);\n\n // If appendChild throws (e.g. the container is detached and the host's\n // custom element implementation rejects insertions), the error listener\n // would otherwise stay attached to a dangling iframe element. Detach it\n // and let the iframe go out of scope before re-throwing so callers see\n // the original DOM error without leaking the listener.\n try {\n wrapper.appendChild(iframe);\n wrapper.appendChild(loader);\n container.appendChild(wrapper);\n } catch (err) {\n iframe.removeEventListener('error', onIframeError);\n iframe.removeEventListener('load', onIframeLoad);\n throw err;\n }\n\n const client = new IframeClient({\n iframe,\n allowedOrigin: opts.origin ?? WIDGET_ORIGIN,\n });\n\n const resize: ResizeHandle = attachResize({\n iframe,\n client,\n ...(opts.minHeight !== undefined ? { minHeight: opts.minHeight } : {}),\n });\n\n // Subscribe callbacks before init() so we never miss an early event.\n const subscriptions: Array<() => void> = [];\n if (opts.onReady) {\n const fn = opts.onReady;\n subscriptions.push(client.on('ready', (p: ReadyPayload) => fn(p)));\n }\n if (opts.onResize) {\n const fn = opts.onResize;\n subscriptions.push(client.on('resize', (info) => fn(info)));\n }\n if (opts.onSwapSubmitted) {\n const fn = opts.onSwapSubmitted;\n subscriptions.push(client.on('swap:submitted', (p: SwapSubmittedPayload) => fn(p)));\n }\n if (opts.onSwapSuccess) {\n const fn = opts.onSwapSuccess;\n subscriptions.push(client.on('swap:success', (p: SwapSuccessPayload) => fn(p)));\n }\n if (opts.onSwapError) {\n const fn = opts.onSwapError;\n subscriptions.push(client.on('swap:error', (p: SwapErrorPayload) => fn(p)));\n }\n\n // Race the underlying init() against an explicit handshake-timeout so the\n // host always sees an `onError` (or warn) within 15s even if Penpal's own\n // timeout machinery is bypassed by a future refactor.\n //\n // We also treat an early `ready` event as proof the bridge is alive: if\n // the iframe emits a ready event via the raw event stream, the embed is\n // working regardless of whether Penpal's internal connection.promise\n // resolves. Some host pages trigger asymmetric Penpal handshakes (the\n // iframe sees SYN/ACK done but the host's connection.promise rejects)\n // and we do not want to surface a spurious handshake_failed in that case.\n let timeoutHandle: ReturnType<typeof setTimeout> | null = null;\n let bridgeReady = false;\n const clearTimer = (): void => {\n if (timeoutHandle !== null) {\n clearTimeout(timeoutHandle);\n timeoutHandle = null;\n }\n };\n const readySuppressUnsub = client.on('ready', () => {\n bridgeReady = true;\n clearTimer();\n dismissLoader();\n readySuppressUnsub();\n });\n const timeoutPromise = new Promise<never>((_resolve, reject) => {\n timeoutHandle = setTimeout(() => {\n reject(new Error(`Iframe handshake timed out after ${HANDSHAKE_TIMEOUT_MS}ms`));\n }, HANDSHAKE_TIMEOUT_MS);\n });\n\n Promise.race([client.init(), timeoutPromise])\n .then(() => {\n clearTimer();\n })\n .catch((err: unknown) => {\n clearTimer();\n // Suppress: the iframe already announced readiness via the event\n // stream, so the apparent init failure is a Penpal asymmetry, not a\n // real bridge failure.\n if (bridgeReady) return;\n // Suppress: the host already destroyed this mount (e.g. React\n // StrictMode double-effect in dev). The pending init() promise will\n // still reject when its underlying timeout fires, but there is no\n // consumer to surface the error to and emitting it would log a\n // spurious handshake_failed against the unmounted instance.\n if (destroyed) return;\n const message = err instanceof Error ? err.message : String(err);\n const code: MountErrorCode = classifyInitError(message);\n reportError({ code, message, cause: err });\n });\n\n let destroyed = false;\n const destroy = (): void => {\n if (destroyed) return;\n destroyed = true;\n if (timeoutHandle !== null) {\n clearTimeout(timeoutHandle);\n timeoutHandle = null;\n }\n iframe.removeEventListener('error', onIframeError);\n iframe.removeEventListener('load', onIframeLoad);\n for (const unsub of subscriptions) unsub();\n resize.destroy();\n client.destroy();\n // Clear the loader's pending fade-out timer side-effect if it has not\n // yet fired. Idempotent because dismissLoader gates on a sentinel.\n dismissLoader();\n // Remove the wrapper which carries both the iframe and the loader.\n // Fall back to removing the iframe alone if the wrapper has already\n // been detached by host code.\n if (wrapper.parentNode) {\n wrapper.parentNode.removeChild(wrapper);\n } else if (iframe.parentNode) {\n iframe.parentNode.removeChild(iframe);\n }\n };\n\n return { iframe, wrapper, client, destroy };\n}\n\n/**\n * Maps an init-time error message to a stable {@link MountErrorCode}. Kept\n * conservative: anything we cannot positively identify becomes 'unknown'\n * rather than masquerading as a more specific code.\n */\nfunction classifyInitError(message: string): MountErrorCode {\n const lower = message.toLowerCase();\n if (lower.includes('handshake') || lower.includes('timed out') || lower.includes('timeout')) {\n return 'handshake_failed';\n }\n if (lower.includes('protocol mismatch') || lower.includes('protocolversion')) {\n return 'protocol_incompatible';\n }\n // 'allowed origin' / 'origin mismatch' are our own strings; the noisier\n // 'Invalid target origin' from postMessage gets classified as 'unknown'.\n if (lower.includes('origin mismatch') || lower.includes('allowed origin')) {\n return 'origin_mismatch';\n }\n if (lower.includes('contentwindow') || lower.includes('iframe failed') || lower.includes('load')) {\n return 'iframe_load_failed';\n }\n return 'unknown';\n}\n\n/**\n * Exposed for tests and callers that want to compute the iframe URL without\n * mounting (e.g. for SSR `<link rel=\"preconnect\">` hints).\n *\n * A `theme` may be supplied; validation failures cause the theme param to\n * be silently omitted (matching `mount()` behaviour). Pass an optional\n * `warn` sink to observe validation failures during tests.\n */\nexport function buildIframeSrc(\n opts: Pick<MountOptions, 'referralId' | 'origin' | 'path' | 'theme' | 'chrome'> & {\n readonly warn?: (message: string) => void;\n }\n): string {\n // Apply the same referralId default as mount(): undefined / empty /\n // whitespace-only collapses to 'general'.\n const raw = typeof opts.referralId === 'string' ? opts.referralId.trim() : '';\n const resolvedReferralId = raw.length > 0 ? raw : 'general';\n return buildSrc({ ...opts, referralId: resolvedReferralId });\n}\n","/**\n * React wrapper. Imports are kept narrow so the bundle stays small when only\n * the `./react` subpath is consumed.\n *\n * SSR-safe: renders nothing on the server (returns null until the effect\n * runs in the browser). The host should still wrap this in a `dynamic`\n * import with `ssr: false` when using Next.js App Router to avoid pulling\n * iframe-only code into the server bundle.\n */\n\nimport {\n useEffect,\n useRef,\n type CSSProperties,\n type ReactElement,\n} from 'react';\n\nimport { mount, type MountResult } from './mount.js';\nimport type {\n ChromeOptions,\n MountError,\n MountErrorCode,\n MountOptions,\n ReadyPayload,\n SwapErrorPayload,\n SwapRouteSummary,\n SwapSubmittedPayload,\n SwapSuccessPayload,\n ThemeOptions,\n} from './protocol.js';\n\nexport type {\n ChromeOptions,\n MountError,\n MountErrorCode,\n MountResult,\n ReadyPayload,\n SwapErrorPayload,\n SwapRouteSummary,\n SwapSubmittedPayload,\n SwapSuccessPayload,\n ThemeOptions,\n};\n\nexport interface AtomCircuitSwapProps {\n /**\n * Validator-supplied affiliate identifier. Optional - defaults to\n * `'general'` when omitted. See {@link MountOptions.referralId}.\n */\n referralId?: string;\n /**\n * Override the widget origin. Defaults to `https://atomcircuit.net`.\n */\n origin?: string;\n /**\n * Override the widget path. Defaults to `/embed/swap`.\n */\n path?: string;\n /**\n * Minimum iframe height; default `480px`.\n */\n minHeight?: string;\n /**\n * CSS class applied to the wrapping `<div>`.\n */\n className?: string;\n /**\n * Inline style applied to the wrapping `<div>`.\n */\n style?: CSSProperties;\n /** Fires once the handshake completes. */\n onReady?: (payload: ReadyPayload) => void;\n /** Fires on every measured content-height change. */\n onResize?: (info: { height: number }) => void;\n /** Fires when a user submits a swap. */\n onSwapSubmitted?: (payload: SwapSubmittedPayload) => void;\n /** Fires when a submitted swap confirms on chain. */\n onSwapSuccess?: (payload: SwapSuccessPayload) => void;\n /** Fires when a swap fails or is rejected by the wallet. */\n onSwapError?: (payload: SwapErrorPayload) => void;\n /** Fires on SDK-level failures (handshake timeout, iframe load failure, origin mismatch). */\n onError?: (error: MountError) => void;\n /**\n * Optional theme. Forwarded to the iframe URL as a validated, base64-encoded\n * payload. Validation failures silently drop the theme; the iframe falls\n * back to its defaults. See {@link ThemeOptions}.\n */\n theme?: ThemeOptions;\n /**\n * Optional chrome toggles. Each flag hides the corresponding embed surface\n * (logo, wallet button, validator badge, footer) when false. Defaults are\n * all-on so an embed dropped in with no chrome configuration retains the\n * full surface. See {@link ChromeOptions}.\n */\n chrome?: ChromeOptions;\n /** CSS width for the iframe. Default `'100%'`. */\n width?: string;\n /** CSS max-width for the iframe. Default unset. */\n maxWidth?: string;\n /**\n * CSS padding applied to the wrapping div around the iframe (NOT the\n * iframe element itself). Default `'0'`.\n */\n padding?: string;\n}\n\nconst WRAPPER_STYLE: CSSProperties = {\n width: '100%',\n display: 'block',\n};\n\n/**\n * React component wrapping `mount()`. Mounts on first effect tick, unmounts\n * on cleanup. Callbacks are captured via a ref so updating them between\n * renders does not re-mount the iframe.\n */\nexport function AtomCircuitSwap(props: AtomCircuitSwapProps): ReactElement | null {\n const containerRef = useRef<HTMLDivElement | null>(null);\n const propsRef = useRef(props);\n propsRef.current = props;\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const opts: MountOptions = {\n referralId: propsRef.current.referralId,\n ...(propsRef.current.origin !== undefined ? { origin: propsRef.current.origin } : {}),\n ...(propsRef.current.path !== undefined ? { path: propsRef.current.path } : {}),\n ...(propsRef.current.minHeight !== undefined ? { minHeight: propsRef.current.minHeight } : {}),\n ...(propsRef.current.theme !== undefined ? { theme: propsRef.current.theme } : {}),\n ...(propsRef.current.chrome !== undefined ? { chrome: propsRef.current.chrome } : {}),\n ...(propsRef.current.width !== undefined ? { width: propsRef.current.width } : {}),\n ...(propsRef.current.maxWidth !== undefined ? { maxWidth: propsRef.current.maxWidth } : {}),\n ...(propsRef.current.padding !== undefined ? { padding: propsRef.current.padding } : {}),\n onReady: (payload) => propsRef.current.onReady?.(payload),\n onResize: (info) => propsRef.current.onResize?.(info),\n onSwapSubmitted: (payload) => propsRef.current.onSwapSubmitted?.(payload),\n onSwapSuccess: (payload) => propsRef.current.onSwapSuccess?.(payload),\n onSwapError: (payload) => propsRef.current.onSwapError?.(payload),\n onError: (error) => propsRef.current.onError?.(error),\n };\n\n let handle: MountResult | null = null;\n try {\n handle = mount(container, opts);\n } catch {\n handle = null;\n }\n return () => {\n handle?.destroy();\n };\n // referralId / origin / path are the only props that warrant a re-mount.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [props.referralId, props.origin, props.path]);\n\n const wrapperStyle: CSSProperties = props.style\n ? { ...WRAPPER_STYLE, ...props.style }\n : WRAPPER_STYLE;\n\n // Returning the container synchronously is safe on the server because the\n // child iframe is only created inside the effect.\n return (\n <div\n ref={containerRef}\n className={props.className}\n style={wrapperStyle}\n data-atom-circuit-embed=\"\"\n />\n );\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atom-circuit/embed-sdk",
|
|
3
|
+
"version": "1.2.1",
|
|
4
|
+
"description": "Embed the Atom Circuit swap widget on any website with one line. Carries a referralId so swap fees route to the host validator.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"main": "./dist/index.cjs",
|
|
9
|
+
"module": "./dist/index.mjs",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.mjs"
|
|
16
|
+
},
|
|
17
|
+
"require": {
|
|
18
|
+
"types": "./dist/index.d.cts",
|
|
19
|
+
"default": "./dist/index.cjs"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"./react": {
|
|
23
|
+
"import": {
|
|
24
|
+
"types": "./dist/react.d.ts",
|
|
25
|
+
"default": "./dist/react.mjs"
|
|
26
|
+
},
|
|
27
|
+
"require": {
|
|
28
|
+
"types": "./dist/react.d.cts",
|
|
29
|
+
"default": "./dist/react.cjs"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"README.md",
|
|
36
|
+
"LICENSE",
|
|
37
|
+
"SECURITY.md",
|
|
38
|
+
"CHANGELOG.md"
|
|
39
|
+
],
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsup",
|
|
42
|
+
"test": "vitest run",
|
|
43
|
+
"test:watch": "vitest",
|
|
44
|
+
"test:e2e": "playwright test",
|
|
45
|
+
"typecheck": "tsc --noEmit",
|
|
46
|
+
"size": "size-limit",
|
|
47
|
+
"prepublishOnly": "npm run build && npm test"
|
|
48
|
+
},
|
|
49
|
+
"keywords": [
|
|
50
|
+
"cosmos",
|
|
51
|
+
"atom",
|
|
52
|
+
"swap",
|
|
53
|
+
"widget",
|
|
54
|
+
"embed",
|
|
55
|
+
"skip",
|
|
56
|
+
"iframe",
|
|
57
|
+
"keplr",
|
|
58
|
+
"leap",
|
|
59
|
+
"cosmostation",
|
|
60
|
+
"validator",
|
|
61
|
+
"referral",
|
|
62
|
+
"staking",
|
|
63
|
+
"defi",
|
|
64
|
+
"cosmwasm",
|
|
65
|
+
"react-component"
|
|
66
|
+
],
|
|
67
|
+
"repository": {
|
|
68
|
+
"type": "git",
|
|
69
|
+
"url": "git+https://github.com/cosmosrescue/atom-circuit-embed-sdk.git"
|
|
70
|
+
},
|
|
71
|
+
"bugs": {
|
|
72
|
+
"url": "https://github.com/cosmosrescue/atom-circuit-embed-sdk/issues"
|
|
73
|
+
},
|
|
74
|
+
"homepage": "https://github.com/cosmosrescue/atom-circuit-embed-sdk#readme",
|
|
75
|
+
"publishConfig": {
|
|
76
|
+
"access": "public"
|
|
77
|
+
},
|
|
78
|
+
"dependencies": {
|
|
79
|
+
"penpal": "~7.0.6"
|
|
80
|
+
},
|
|
81
|
+
"peerDependencies": {
|
|
82
|
+
"react": ">=17 <20",
|
|
83
|
+
"react-dom": ">=17 <20"
|
|
84
|
+
},
|
|
85
|
+
"peerDependenciesMeta": {
|
|
86
|
+
"react": {
|
|
87
|
+
"optional": true
|
|
88
|
+
},
|
|
89
|
+
"react-dom": {
|
|
90
|
+
"optional": true
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"devDependencies": {
|
|
94
|
+
"@playwright/test": "^1.46.0",
|
|
95
|
+
"@size-limit/preset-small-lib": "^12.1.0",
|
|
96
|
+
"@testing-library/react": "^16.0.0",
|
|
97
|
+
"@types/node": "^25.9.1",
|
|
98
|
+
"@types/react": "^18.3.3",
|
|
99
|
+
"@types/react-dom": "^18.3.0",
|
|
100
|
+
"jsdom": "^29.1.1",
|
|
101
|
+
"react": "^18.3.1",
|
|
102
|
+
"react-dom": "^18.3.1",
|
|
103
|
+
"size-limit": "^12.1.0",
|
|
104
|
+
"tsup": "^8.2.4",
|
|
105
|
+
"typescript": "^6.0.3",
|
|
106
|
+
"vitest": "^4.1.7"
|
|
107
|
+
},
|
|
108
|
+
"engines": {
|
|
109
|
+
"node": ">=20"
|
|
110
|
+
},
|
|
111
|
+
"size-limit": [
|
|
112
|
+
{
|
|
113
|
+
"name": "iife (gzip)",
|
|
114
|
+
"path": "dist/atom-circuit.iife.js",
|
|
115
|
+
"limit": "25 KB",
|
|
116
|
+
"gzip": true
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"name": "esm (gzip)",
|
|
120
|
+
"path": "dist/index.mjs",
|
|
121
|
+
"limit": "25 KB",
|
|
122
|
+
"gzip": true
|
|
123
|
+
}
|
|
124
|
+
]
|
|
125
|
+
}
|