Appearance
Wallets example
End-to-end signature verification: create a client, list wallets, run verify(), read the result.
The address lives in a self-custodial wallet. For an address that lives on Coinbase, see Coinbase example.
This is not a Connect session. You need a public API key, not a sessionId. customerId is your id for the end user.
1. Create the client
ts
import {
createWalletVerification,
IntegrationProvider,
} from '@swapped/connect-sdk/wallet-verification'
const client = createWalletVerification({
apiKey: 'your-public-api-key',
environment: 'staging',
})See Client. Call destroy() when the page tears down.
2. List wallets
getAvailable() is the picker catalog - signature wallets this device can use. These are not connected yet. See Availability.
ts
const wallets = await client.wallets.getAvailable({ network: 'evm' })Each row has isInstalled, transports, supportsWalletConnect, isDeepLinkConnection, isPopupConnection, qrScanTarget, and icon.light / icon.dark.
3. Verify (signature)
verify() is the one-shot path. For a QR-first picker, prepareVerify() then verify({ prepared }). See Verify wallet.
QR first, then optionally the extension (one create - pick one completion, not both):
ts
const prepared = await client.wallets.prepareVerify({
network: 'evm',
customerId: 'user-1234',
provider: IntegrationProvider.MetaMask,
address: '0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B',
onUri: ({ uri, deeplinkUrl }) => {
// uri → QR / copy; deeplinkUrl → open the wallet on this device
},
})
// phone scanned
const fromQr = await prepared.wait()
// or "Verify with extension" while the QR is up
const fromExtension = await client.wallets.verify({
prepared,
transport: 'injected',
provider: IntegrationProvider.MetaMask,
network: 'evm',
customerId: 'user-1234',
})Injected one-shot:
ts
const verification = await client.wallets.verify({
network: 'evm',
customerId: 'user-1234',
provider: wallets[0].provider,
transport: 'injected',
popupIfUnavailable: true,
})WalletConnect (QR + optional mobile link):
ts
const verification = await client.wallets.verify({
network: 'evm',
customerId: 'user-1234',
provider: IntegrationProvider.Trust,
transport: 'walletconnect',
force: true,
onUri: ({ uri, deeplinkUrl }) => {
// uri → QR / copy; deeplinkUrl → open the wallet on this device
},
})Browse deeplink (address required):
ts
const abort = new AbortController()
const verification = await client.wallets.verify({
address: '0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B',
network: 'evm',
customerId: 'user-1234',
provider: IntegrationProvider.Phantom,
signal: abort.signal,
onDeeplinkUrl: ({ url }) => {
// desktop: render `url` as a camera QR
},
})Omit address on injected / WalletConnect / popup to verify the connected account. If customerId + address is already verified, verify() returns status: 'verified' without a prompt.
4. Read the result
ts
if (verification.status === 'verified') {
verification.verificationId
verification.address
verification.verifiedAt
}
if (verification.status === 'failed' || verification.status === 'expired') {
// start a new verify()
}Invalid signature: the call throws and status stays pending - call verify() again. See Result.
5. Tear down
ts
client.destroy()Deep dives: Client, Availability, Verify wallet, Result, Errors.