Skip to content

Example

End-to-end wallet deposit with client.wallets: list wallets, connect, pick a token, resolve a transfer plan, enter an amount, submit, handle requires_retry, show the summary.

Route here when the payment method has type: wallet. Session must be active before transfer.submit. After a completed payment, call restartSession() before starting again.

1. Set up the client

Create a client with the sessionId from your backend, then loadSession(). The session must be active before transfer.submit.

ts
import { createSwappedConnectClient } from '@swapped/connect-sdk';

const client = createSwappedConnectClient({
  sessionId: 'your-session-id',
});

await client.loadSession();

2. List wallets

getAvailable() is the catalog — wallets the session offers, plus how this device can reach each one. These are not connected yet. See Availability.

ts
const wallets = await client.wallets.getAvailable();

Each row has isInstalled, transports, supportsWalletConnect, isDeepLinkConnection, isPopupConnection, qrScanTarget.

3. Connect

connect opens a wallet and returns the WalletConnection (or null on browse deeplink). Multi-chain wallets are one connection — namespaces live on connection.namespaces. Use connection.walletId on later calls. See Connect wallet.

Injected:

ts
const connection = await client.wallets.connect({
  provider: wallets[0].provider,
  transport: 'injected',
  popupIfUnavailable: true,
});
const walletId = connection?.walletId;

WalletConnect (QR + optional mobile link):

ts
client.on('wallets:pairingUri', ({ uri, deeplinkUrl }) => {
  // uri → QR / copy; deeplinkUrl → open the wallet on this device
});

const connection = await client.wallets.connect({
  provider: wallets[0].provider,
  transport: 'walletconnect',
});

Open-in-wallet-app:

ts
if (client.wallets.requiresDeepLink(provider)) {
  client.wallets.openDeepLink(provider);
}

4. Connections

A connection is one approved wallet instance (one extension slot, or one WalletConnect session), keyed by walletId. The same brand can appear more than once. This is not a row from getAvailable().

getConnections lists them. getConnectionState is the live state while restore or pairing is in progress. See Connected wallets.

ts
const list = client.wallets.getConnections({ sort: 'connectedAt' });
const state = client.wallets.getConnectionState();
// state.isRestoring — previous connections still rehydrating
// state.pairingUri — WalletConnect QR / copy value
// state.connectingProviders — in-flight connect()

Wait for isRestoring === false before treating the list as complete. Sign / send still need connection.status === 'connected'.

5. Balances

getBalances() loads tokens for every connected walletId. Eligibility is supported → has balance → meets min → eligible. See Balances.

ts
const groups = await client.wallets.getBalances();
const tokens = groups.find(group => group.walletId === walletId)?.balances ?? [];

const token = tokens.find(item => item.eligible);
// token.displayBalance, token.formatted.fiatValue, token.exchangeRate

6. Transfer plan, amount, quote

A transfer plan is how this wallet + token becomes the session deposit. You pass walletId + token; the SDK picks the route — you do not. For bridge, the destination is picked automatically. See Transfer plan and Amount & quote.

plan.flowMeaning
directSession already receives this token on this network.
swapSame chain, different token. SDK swaps into the session asset.
bridgeDifferent chain. SDK bridges into the session token/network.
unavailableNo route. This token cannot complete the payment.
ts
const request = {
  walletId,
  network: token.network,
  symbol: token.symbol,
  tokenAddress: token.tokenAddress,
};

const plan =
  client.wallets.transfer.getPlanSync(request) ??
  (await client.wallets.transfer.getPlan(request));

if (plan.flow === 'unavailable') {
  // no deposit route for this token
}

const min = await client.wallets.transfer.getMinAmount(plan);
const validation = await client.wallets.transfer.validateAmount({
  plan,
  amount,
});

const quote = await client.wallets.transfer.getQuote({ plan, amount });
// quote.amountOut, quote.networkFee, quote.estimatedTimeSeconds

Crypto ↔ fiat: convertCryptoToFiat / convertFiatToCrypto with token.exchangeRate.

7. Submit

submit asks the user to confirm in the wallet. Pass the plan, amount, and quote (required for swap / bridge; optional for direct). If result.status === 'requires_retry', the wallet already sent — show Retry, do not submit again. See Submit.

ts
const result = await client.wallets.transfer.submit({
  plan,
  amount,
  quote,
  onStatus: event => {
    event.status;
    event.hash;
  },
});

if (result.status === 'requires_retry') {
  await client.wallets.transfer.retry();
}

8. Summary

getCompletedTransactionSummary() is the success-screen payload (null if this session has no completed wallet deposit). It is sync — amounts and the tx hash are ready immediately, but direct network fees and fiat often are not. Fill those, then call restartSession() before another payment — connections stay. See Summary.

ts
let summary = client.wallets.transfer.getCompletedTransactionSummary();

if (client.wallets.transfer.needsCompletedTransactionFeeEnrichment()) {
  summary = await client.wallets.transfer.ensureCompletedTransactionFees();
}

summary = await client.wallets.transfer.ensureCompletedTransactionRates();

if (summary) {
  summary.flow;
  summary.provider;
  summary.isSponsored;
  summary.send.formatted.amount;
  summary.send.formatted.fiatValue;
  summary.send.network;
  summary.receive.formatted.amount;
  summary.receive.formatted.fiatValue;
  summary.receive.network;
  summary.fees;
  summary.from.formatted;
  summary.from.explorerUrl;
  summary.to.formatted;
  summary.to.explorerUrl;
  summary.destination.formatted;
  summary.transaction.formatted;
  summary.transaction.hash;
  summary.transaction.explorerUrl;
}

await client.restartSession();

Deep dives: Availability, Connect wallet, Connected wallets, Balances, Transfer plan, Amount & quote, Submit, Summary, Events, Errors.