Appearance
Errors
Wallet verification failures throw ConnectSdkError with a stable code. Branch on code, not on message.
ts
import {
ConnectSdkError,
ConnectSdkErrorCode,
} from '@swapped/connect-sdk/wallet-verification'
try {
await client.wallets.verify({
network: 'evm',
customerId: 'user-1234',
provider,
})
} catch (error) {
if (!(error instanceof ConnectSdkError)) {
throw error
}
switch (error.code) {
case ConnectSdkErrorCode.WALLET_CONNECT_REJECTED:
case ConnectSdkErrorCode.WALLET_SIGNATURE_REJECTED:
case ConnectSdkErrorCode.WALLET_VERIFICATION_CANCELLED:
// user / merchant cancelled - offer retry
break
case ConnectSdkErrorCode.WALLET_POPUP_BLOCKED:
// ask to allow popups; retry from a click
break
case ConnectSdkErrorCode.WALLET_VERIFICATION_ADDRESS_MISMATCH:
// connected account ≠ claimed address - switch account or omit address
break
default:
// show a retry message; keep the user on this step while pending
break
}
}WALLET_CONNECT_REJECTED and WALLET_SIGNATURE_REJECTED are user cancels (wallet declined connect or the sign prompt). WALLET_VERIFICATION_CANCELLED is an SDK / merchant abort (cancelVerification(), deeplink signal, or the Coinbase tab closed after the grace period).
Unmapped HTTP failures surface as API_ERROR. Show a retry message and keep the user on the same step when safe (pending). After failed or expired, start a new verification.
When things fail in the flow
| Step | What goes wrong | How you see it | What to do |
|---|---|---|---|
| Create client | Not in a browser / missing key | BROWSER_REQUIRED, WALLET_VERIFICATION_API_KEY_REQUIRED | Browser-only module; pass apiKey |
| Gateway | Hidden iframe blocked or timed out | WALLET_GATEWAY_NOT_READY | Allow widgetBaseUrl in frame-src - Browser requirements |
| Picker | Provider has no SDK wallet config | WALLET_NOT_SUPPORTED | Hide it, or only offer getAvailable() rows |
| Injected | Extension missing | WALLET_NOT_INSTALLED | Offer WalletConnect or deeplink |
| Connect / sign | User declined | WALLET_CONNECT_REJECTED, WALLET_SIGNATURE_REJECTED | Offer retry |
| Verify | Claimed address ≠ connected account | WALLET_VERIFICATION_ADDRESS_MISMATCH | Ask the user to switch account, or verify the connected address |
| Deeplink / prepare | No address | WALLET_VERIFICATION_ADDRESS_REQUIRED | Collect the address before prepareVerify() / deeplink verify() |
| Deeplink / Coinbase wait | Merchant aborted | WALLET_VERIFICATION_CANCELLED | Close UI; allow start again |
| WalletConnect | Second QR while one is live | WALLET_PAIRING_IN_PROGRESS | cancelPairing() or force: true |
| Popup / Coinbase tab | Browser blocked it | WALLET_POPUP_BLOCKED | Ask to allow popups; retry from a click |
| Coinbase | openVerificationTab() too early | WALLET_VERIFICATION_NOT_STARTED | startVerification() first |
| Coinbase redirect | No id on the landing page | WALLET_VERIFICATION_NOT_FOUND | Pass verificationId or keep persist on |
| Any verify | Another run is in flight | WALLET_VERIFICATION_IN_PROGRESS | Wait, or take over with verify({ prepared }) |
| Proof | Bad signature | Thrown error; status stays pending | Call verify() again |
| Terminal | failed / expired | Returned record | New verify() / startVerification() |
Error code reference
Client
| Code | When | What to do |
|---|---|---|
BROWSER_REQUIRED | Client created outside the browser | Instantiate in a client component / browser-only module |
WALLET_VERIFICATION_API_KEY_REQUIRED | apiKey missing or blank | Pass the public session API key |
INVALID_ENVIRONMENT | environment is not production or staging | Use one of those two values |
INVALID_API_BASE_URL | apiBaseUrl is not an official host | Use the production or staging API URL, or omit it |
INVALID_WIDGET_BASE_URL | widgetBaseUrl is not official and not localhost | Use the environment default, or a localhost widget host |
CLIENT_DESTROYED | Method called after destroy() | Create a new client |
Signature
| Code | When | What to do |
|---|---|---|
WALLET_NOT_SUPPORTED | Provider has no SDK wallet config | Use a wallet from getAvailable() |
WALLET_NOT_INSTALLED | Injected path and the extension is not present | WalletConnect or deeplink |
WALLET_NOT_CONNECTED | Privileged action with no connection | verify() connects on its own; or connect() first |
WALLET_CONNECT_REJECTED | User rejected connect / pairing | Offer retry |
WALLET_SIGNATURE_REJECTED | User rejected the sign prompt | Offer retry |
WALLET_NAMESPACE_UNSUPPORTED | Requested namespace is not available | Use a wallet that supports network |
WALLET_CHAIN_UNSUPPORTED | Requested chain is not available | Pass a supported chainId or omit it |
WALLET_PAIRING_IN_PROGRESS | A WalletConnect pairing is already in flight | cancelPairing() or force: true |
WALLET_PAIRING_CANCELLED | In-flight pairing was cancelled | Expected after cancelPairing() |
WALLET_PAIRING_EXPIRED | WalletConnect QR / proposal expired | Start verify() again |
WALLET_POPUP_BLOCKED | Browser blocked the connect / Coinbase tab | Allow popups; retry from a click |
WALLET_POPUP_CLOSED | Popup closed before connect / sign finished | Offer retry |
WALLET_POPUP_IN_PROGRESS | Another popup is already open | Wait for it to finish |
WALLET_POPUP_NO_OPENER | Popup could not reach the opener | Retry; avoid noopener on your own window.open |
WALLET_GATEWAY_NOT_READY | Hidden /gateway iframe blocked, timed out, or missing | Allow widgetBaseUrl in frame-src |
WALLET_VERIFICATION_ADDRESS_REQUIRED | Deeplink verify() without address | Collect the address first |
WALLET_VERIFICATION_ADDRESS_MISMATCH | Connected account ≠ claimed address | Switch account, or omit address |
WALLET_VERIFICATION_NO_CHALLENGE | Pending record had no message / Coinbase URL | Retry start; if it persists, treat as a server error |
Coinbase and shared
| Code | When | What to do |
|---|---|---|
WALLET_VERIFICATION_REDIRECT_URL_REQUIRED | mode: 'redirect' without redirectUrl | Pass the landing-page URL |
WALLET_VERIFICATION_NOT_STARTED | openVerificationTab() with nothing pending | startVerification() first |
WALLET_VERIFICATION_NOT_FOUND | Landing page had no verification id | Pass the id or keep persistVerification |
WALLET_VERIFICATION_IN_PROGRESS | Another verify / Coinbase run is already in flight | Wait, or cancelVerification() |
WALLET_VERIFICATION_CANCELLED | Wait aborted (cancelVerification(), signal, or Coinbase tab closed) | Allow start again |
API_ERROR | Unmapped HTTP failure | Retry the same step while pending |