Skip to content

useVerifyWallet ​

useVerifyWallet() is the signature path: create a verification, connect the wallet, sign the server challenge, and wait until the record is terminal.

customerId, network, and address default to provider identity. Pass provider (and optionally walletId / transport). The hook owns WalletConnect and deeplink callbacks - read pairingUri, pairingDeeplinkUrl, and deeplinkUrl.

For a QR-first picker, call prepare() from a click (address required). Then verify({ transport: 'injected' }) reuses that pending session - you do not pass prepared yourself.

Coinbase OAuth is a different hook: useCoinbaseVerification. Walkthrough: Wallets example.

Bring your own QR component - qrcode.react in the examples is only an example. Selecting a wallet does not start verification. Call prepare() or verify() from a click.

When is address required? ​

Pathaddress (provider or in the call)
Injected / WalletConnect / popup verify()Optional - omit to verify the connected account
prepare() / browse deeplinkRequired
CoinbaseRequired - see useCoinbaseVerification

Example ​

tsx
import { useVerifyWallet } from '@swapped/connect-sdk/wallet-verification/react'

function VerifyButton({ provider }: { provider: IntegrationProvider }) {
  const { verify, isVerifying, pairingUri, deeplinkUrl, error } =
    useVerifyWallet()

  return (
    <>
      <button
        type="button"
        disabled={isVerifying}
        onClick={() => void verify({ provider })}
      >
        Verify
      </button>
      {pairingUri ? <Qr value={pairingUri} /> : null}
      {deeplinkUrl ? <Qr value={deeplinkUrl} /> : null}
      {error ? <p>{error.message}</p> : null}
    </>
  )
}

Reuse an existing connection:

tsx
await verify({
  provider: connection.provider,
  walletId: connection.walletId,
  transport: connection.transport,
})

QR first (address required on the provider or here). Do not wait() and also verify({ transport: 'injected' }) for the same completion:

tsx
const prepared = await prepare({
  provider: IntegrationProvider.Trust,
})
// render pairingUri / pairingDeeplinkUrl / deeplinkUrl
await prepared.wait()

// or switch to the extension while the QR is up
await verify({
  provider: IntegrationProvider.Trust,
  transport: 'injected',
})

Browse deeplink (address required - set it on the provider or pass it here):

tsx
await verify({
  provider: IntegrationProvider.Phantom,
})
// render result.deeplinkUrl

cancel() aborts pairing / the deeplink wait (WALLET_VERIFICATION_CANCELLED).

Returns ​

FieldMeaning
prepareShow a WalletConnect / browse QR first (address required). Resolves when the QR is ready
verifyConnect, sign, and wait until the record is verified / failed / expired. Pass transport: 'injected' to finish a live prepare() with the extension
cancelStop the current pairing or deeplink wait (WALLET_VERIFICATION_CANCELLED). Call this when the user closes the QR modal
isVerifyingtrue from the moment you call prepare() / verify() until that run finishes or cancel()
preparedThe live prepare() session (wait(), cancel(), pairing URLs), or null when none is active
verificationThe WalletVerification from the last successful prepare() / verify(), or null
errorError from the last failed prepare() / verify(), or null
pairingUriWalletConnect wc: URI - render this as the QR the wallet app scans
pairingDeeplinkUrlHTTPS link that opens the wallet app on this device (“Open in wallet”)
deeplinkUrlBrowse URL - render as a camera QR on desktop; the SDK opens the wallet on mobile

verify() accepts the same optional fields as Core VerifyWalletSignatureRequest (orderId, customerEmail, webhookUrl, chainId, force, forcePopup, popupIfUnavailable, walletId, transport, prepared, verificationId). It does not take onUri, onDeeplinkUrl, or signal. While a prepare() is live, verify({ transport: 'injected' }) reuses that session.

If that customerId + address is already verified, verify() returns status: 'verified' without prompting the wallet.

Transport details, popups, and retry rules: Core Verify wallet.