Skip to content

Browser requirements

This SDK is browser only. createSwappedConnectClient throws BROWSER_REQUIRED on the server (Node.js, SSR, RSC). Create a sessionId on your backend, then instantiate the client in the browser.

If your site sends a Content-Security-Policy, you must allow Swapped origins. The SDK creates a hidden iframe and opens network connections from your page — the browser still applies your CSP to those cross-origin URLs. Sites with no CSP can ignore this page.

Hidden gateway iframe

createSwappedConnectClient mounts a hidden iframe at {widgetBaseUrl}/gateway (production default https://connect.swapped.com/gateway) when wallets or coinbase is enabled — the default, or an explicit modules list that includes either. Pass modules: ['exchangePay'] (and/or cashApp) to skip the iframe. The page talks to that host over postMessage. It is not the hosted widget — users never see it.

A frame-src (or child-src / default-src) that only allows 'self' blocks that frame even though your own script created it. Wallet and Coinbase connect then fail with WALLET_GATEWAY_NOT_READY.

Some wallets and Coinbase OAuth also open {gatewayUrl}?mode=popup. Allow popups for your origin; a blocked popup is WALLET_POPUP_BLOCKED or OAUTH_POPUP_BLOCKED, not a CSP miss.

Content Security Policy

Add the widget origin to frame-src and the API origin to connect-src (HTTPS plus wss: for live updates).

Production (defaults):

http
Content-Security-Policy:
  frame-src 'self' https://connect.swapped.com;
  connect-src 'self' https://connect-api.swapped.com wss://connect-api.swapped.com;

Staging (environment: 'staging'):

http
Content-Security-Policy:
  frame-src 'self' https://staging.swapped.app;
  connect-src 'self' https://staging-api.swapped.app wss://staging-api.swapped.app;
DirectiveAllowWhy
frame-srcwidgetBaseUrlHidden /gateway iframe
connect-srcapiBaseUrl (https: and wss:)REST ({apiBaseUrl}/api) and the WebSocket ({apiBaseUrl}/swapped-connect)

If you omit frame-src, the browser falls back to child-src, then default-src. A lone default-src 'self' blocks both the iframe and the API.

If you pass a custom apiBaseUrl or widgetBaseUrl, allow those origins instead. Localhost widget hosts are accepted in development — add that origin to frame-src when you use one.

Storage

React WalletsProvider keeps the active walletId in sessionStorage so the selection survives a refresh in that tab.

Errors

CodeWhenWhat to do
BROWSER_REQUIREDClient created outside the browserInstantiate in a client component / browser-only module
MODULE_NOT_ENABLEDCalled a module that was omitted from modulesInclude it in modules, or omit modules to enable all
WALLET_GATEWAY_NOT_READYHidden /gateway iframe blocked, timed out, or missingAllow widgetBaseUrl in frame-src; retry connect()
WEBSOCKET_CONNECTION_FAILEDLive session / order socket failed (error event, context: 'websocket')Allow apiBaseUrl in connect-src including wss:

WEBSOCKET_CONNECTION_FAILED is emitted on client.on('error', …), not thrown from loadSession.