Skip to content

Client (React) ​

Create a core client with createSwappedConnectClient, call loadSession() once at bootstrap, then wrap your tree with SwappedConnectProvider. Hooks read that client from context.

This SDK is browser only. createSwappedConnectClient throws BROWSER_REQUIRED on the server (Node.js, SSR, RSC). In Next.js and similar frameworks, instantiate the client in a client component ('use client') or a module that only runs in the browser. Session creation stays on your backend - see Creating a session.

tsx
import { createSwappedConnectClient } from '@swapped/connect-sdk'
import { SwappedConnectProvider } from '@swapped/connect-sdk/react'

const client = createSwappedConnectClient({
  sessionId: 'your-session-id',
  environment: 'staging', // omit or 'production' for live
})

// Provider does not load the session - do it once at bootstrap
void client.loadSession()

function App() {
  return (
    <SwappedConnectProvider client={client}>
      {/* payment UI */}
    </SwappedConnectProvider>
  )
}

Create the client once and pass it into the provider. Reuse that instance for the life of the payment UI. Call restartSession() for another payment - do not create a second client unless each tree is a separate session (SESSION_ALREADY_IN_USE). Call destroy() on teardown.

Multiple clients on one page share wallet connections and Coinbase login. See Multiple clients on one page.

SwappedConnectProvider ​

Provides the client to every hook under @swapped/connect-sdk/react. Hooks throw REACT_CONTEXT_PROVIDER_REQUIRED outside this tree. One client instance may be passed to only one provider at a time (REACT_CLIENT_ALREADY_PROVIDED).

The provider does not call loadSession() or restartSession() - do those on the client instance (or via useSwappedConnectClient / useRestartSession).

PropDefaultNotes
clientrequiredInstance from createSwappedConnectClient
destroyOnUnmounttrueCall client.destroy() when this provider unmounts. Pass false if you reuse the same client after this tree unmounts. Destroy is deferred by a macrotask so React Strict Mode remounts do not tear down a reused client.

Do not wrap the tree with a module provider (WalletsProvider, ExchangePayContextProvider, CashAppProvider, CoinbaseProvider) for a module that was omitted from modules (MODULE_NOT_ENABLED).

useSwappedConnectClient ​

Returns the same SwappedConnectClient you passed to the provider. Use it for methods that do not have a dedicated hook (destroy, isModuleEnabled, module calls).

tsx
import { useSwappedConnectClient } from '@swapped/connect-sdk/react'

function TeardownButton() {
  const client = useSwappedConnectClient()

  return (
    <button type="button" onClick={() => client.destroy()}>
      Tear down
    </button>
  )
}

For another payment after completion, prefer useRestartSession so the button can show isRestarting / error.

Config ​

Same options as Client (Core).

OptionDefaultNotes
sessionId''Required before loadSession() / restartSession() (SESSION_ID_REQUIRED if missing)
environment'production''production' or 'staging'. Sets default API, WebSocket, and widget-gateway hosts
apiBaseUrlenvironment defaultOverrides the API host. Allow-listed to the official production and staging hosts (INVALID_API_BASE_URL otherwise)
widgetBaseUrlenvironment defaultGateway host that serves /gateway. Localhost is allowed for widget development (INVALID_WIDGET_BASE_URL otherwise)
modulesall fourPayment modules to construct. See Modules
wallets.balancesCacheTtlMs600000 (10 min)How long wallet balances stay cached. A manual refresh always loads fresh balances

Environments ​

The client defaults to production. Pass environment: 'staging' to point the API, WebSocket, and widget gateway at staging. A staging sessionId will not load against production.

EnvironmentSession endpointClient
Production (default)POST https://connect-api.swapped.com/api/sessionsomit environment, or environment: 'production'
StagingPOST https://staging-api.swapped.app/api/sessionsenvironment: 'staging'

If the session was created on staging and the client stays on production, loadSession() fails - and useSessionView() still reports active because no session is loaded, so payment UI can render over a session that does not exist.

Optional apiBaseUrl / widgetBaseUrl replace that environment's defaults. If you pass a custom apiBaseUrl, the client infers environment from it when environment is omitted.

Modules ​

All payment modules are enabled by default (exchangePay, cashApp, coinbase, wallets). Pass modules to construct only the ones you need - wallets and coinbase mount a hidden /gateway iframe; exchangePay and cashApp do not. Sites with a Content-Security-Policy must allow that iframe and the API WebSocket - see Browser requirements.

ts
const client = createSwappedConnectClient({
  sessionId: 'your-session-id',
  modules: ['exchangePay'],
})

Payment method lists hide methods for modules that were left out. Accessing a disabled module throws MODULE_NOT_ENABLED.

Lifecycle ​

JobHow
Load sessionclient.loadSession() once at bootstrap, outside the component tree
Which screen to showuseSessionView
Session payload / maintenanceuseSession / useMaintenance
Another paymentuseRestartSession
EventsEvent hooks
Tear downProvider unmount (default), or client.destroy() via useSwappedConnectClient

You almost never need loadSession({ forceRefetch: true }) - sockets and payment completion already refresh the session.

Errors ​

CodeWhenWhat to do
BROWSER_REQUIREDClient created outside the browserInstantiate in a client component / browser-only module
REACT_CONTEXT_PROVIDER_REQUIREDHook used outside SwappedConnectProviderWrap the tree with the provider
REACT_CLIENT_ALREADY_PROVIDEDSame client instance passed to two providersUse one provider per client
SESSION_ID_REQUIREDMissing id on load / restartPass sessionId to create or to the call
SESSION_ALREADY_IN_USEAnother live client already has this sessionIdUse one client per session, or destroy() the other first
INVALID_ENVIRONMENTenvironment is not production or stagingUse one of those two values
INVALID_API_BASE_URLapiBaseUrl is not an official hostUse the production or staging API URL, or omit it
INVALID_WIDGET_BASE_URLwidgetBaseUrl is not official and not localhostUse the environment default, or a localhost widget host
INVALID_MODULESmodules is not an array of known namesPass exchangePay, cashApp, coinbase, and/or wallets
MODULE_NOT_ENABLEDCalled a module omitted from modulesInclude it, or omit modules to enable all
CLIENT_DESTROYEDMethod called after destroy()Create a new client