Skip to main content

Overview

In the Bluvo state machine, errors are states, not exceptions. When something goes wrong, the flow transitions to an error state (e.g., withdraw:error2FA), and the hook exposes it as a boolean (e.g., flow.requires2FA). Your UI reacts to these booleans the same way it reacts to any other state. Every error state has a defined recovery action, submit a code, retry, adjust parameters, or cancel. The hook also provides detection helpers like hasAmountError and hasAddressError that inspect error messages to help you show targeted UI.
For the full list of states, booleans, and transitions, see the State Machine Reference. This page focuses on what to do when things go wrong.

Error Quick Reference

Connection Errors

Wallet Errors

Quote Errors

Withdrawal Errors


Exchange-Specific 2FA

2FA behavior is completely different between exchanges. Your UI must account for this, do not assume all exchanges use the same 2FA pattern. The hook booleans tell you exactly which path to render.

Handling All Three in Your UI


Multi-Step 2FA Deep Dive

When requires2FAMultiStep is true, the exchange requires multiple verification steps before confirming the withdrawal. This is currently used by Binance.

Step Types

Relation Types

The multiStep2FARelation field determines how steps combine:
  • AND, All required steps must be verified. Show all step inputs simultaneously.
  • OR, Any one required step is sufficient. Show options and let user pick.

Verification Source of Truth

Use mfa.verified (available as flow.mfaVerified) as the primary source of truth for whether a step is verified, not step.status. The mfa.verified object is updated by the server and reflects the actual verification state. The step status field may lag behind.
The hook provides convenience booleans that check mfa.verified first, falling back to step.status:

Complete Flow

  1. Withdrawal execution triggers requires2FAMultiStep
  2. Check flow.multiStep2FASteps for required step types
  3. For each step, render the appropriate input:
    • GOOGLE / EMAIL / SMS, code input → submit2FAMultiStep(type, code)
    • FACE, show QR code from flow.faceQrCodeUrl → user scans → pollFaceVerification()
    • ROAMING_FIDO, prompt user → pollRoamingFidoVerification()
  4. After each submission, the server returns updated step statuses
  5. When flow.allMultiStep2FAStepsVerified becomes true, isReadyToConfirm fires
  6. Call flow.confirmWithdrawal() to finalize

FACE Verification

The FACE step requires the user to scan a QR code with their exchange mobile app and complete biometric verification:

Code Example


Recovery Actions by Error State

The exchange (typically Coinbase) requires a TOTP code.Recovery: Call flow.submit2FA(code) with the user’s authenticator code.Track: flow.invalid2FAAttempts increments on each invalid submission. Consider showing a warning after 2-3 attempts.
The exchange requires multiple verification steps.Recovery: Use flow.submit2FAMultiStep(stepType, code) for code-based steps and flow.pollFaceVerification() for biometric steps. Once flow.allMultiStep2FAStepsVerified is true, call flow.confirmWithdrawal().See the Multi-Step 2FA Deep Dive above for the complete implementation.
The exchange sent an SMS code to the user’s registered phone.Recovery: Call flow.submit2FA(code) with the SMS code the user received.
The exchange requires the user to complete identity verification before withdrawals are allowed.Recovery: This cannot be resolved via the SDK. Direct the user to complete KYC on the exchange’s website or app, then retry the withdrawal later.
The withdrawal amount exceeds the available balance.Recovery: Show the user their current balance (from flow.walletBalances), let them adjust the amount, and request a new quote.
The exchange has blocked this withdrawal. This is non-recoverable via the SDK.Recovery: Display flow.error?.message which contains the reason from the exchange. The user may need to resolve account-level restrictions.
An unrecoverable error occurred. Check requiresValid2FAMethod for a special case where the user’s 2FA method isn’t supported.Recovery:
  • If flow.requiresValid2FAMethod is true: show flow.valid2FAMethods and instruct the user to enable a supported method on the exchange.
  • Otherwise: display flow.error?.message and offer flow.cancel().
The SDK is automatically retrying the withdrawal after a transient failure.Recovery: No action needed. Show a spinner. Track progress with flow.retryAttempts / flow.maxRetryAttempts.
The quote’s TTL has elapsed and it can no longer be used for withdrawal.Recovery: Call flow.requestQuote() with the same parameters to get a fresh quote.
Enable autoRefreshQuotation: true in hook options to automatically refresh quotes before they expire.
A transient failure occurred during the OAuth flow (network timeout, temporary exchange issue).Recovery: Call startWithdrawalFlow() again with the same exchange and wallet ID.
The exchange permanently rejected the connection. This cannot be retried.Recovery: Call flow.cancel() and let the user start over, potentially with a different exchange.

Next Steps

State Machine Reference

Full list of 35 states, transitions, hook booleans, and context data

OAuth2 Integration

Step-by-step implementation guide with React and Next.js

Code Samples

Full working examples for Next.js, React, and more

Encryption & Security

How Bluvo encrypts and isolates exchange credentials