Appearance
useCoinbaseWithdrawal
Start a Coinbase withdrawal, confirm 2FA, and track status.
When to use
On the withdraw step, inside CoinbaseProvider. Always combine with useCoinbaseWithdrawalCooldown so Start cannot double-submit.
Example
tsx
import {
useCoinbaseSelection,
useCoinbaseWithdrawal,
useCoinbaseWithdrawalCooldown,
} from '@swapped/connect-sdk/react'
function WithdrawButton() {
const { canSubmit } = useCoinbaseSelection()
const {
startWithdrawal,
confirmWithdrawal,
cancelWithdrawal,
status,
requires2fa,
isStartingWithdrawal,
isConfirming,
error,
} = useCoinbaseWithdrawal()
const { isInCooldown, remainingMs } = useCoinbaseWithdrawalCooldown()
async function onWithdraw() {
// Uses token / network / amount / funding from CoinbaseProvider.
// If the amount is above the fee-reserve max, the amount input is synced
// to the adjusted value before onAmountAdjusted runs.
const result = await startWithdrawal(undefined, {
onAmountAdjusted: async ({ formatted }) =>
window.confirm(
`Withdraw ${formatted.adjustedAmount} instead (fee reserve $${formatted.feeReserveFiat})?`,
),
})
if (result.status === 'idle') {
// User declined the adjusted amount — stay on the form.
return
}
if (result.status === 'requires2fa') {
const code = window.prompt('Enter Coinbase 2FA code') // replace with your UI
if (code) {
const confirmResult = await confirmWithdrawal(code)
if (confirmResult.status === 'requires2fa') {
// Wrong code — status stays requires2fa; hook sets `is2faInvalid`.
// Show feedback and call clear2faInvalid() when the user edits the code.
}
} else {
cancelWithdrawal()
}
}
}
return (
<div>
{error && <p>{error.message}</p>}
<p>Status: {status}</p>
<button
type="button"
disabled={!canSubmit || isStartingWithdrawal || isConfirming || isInCooldown}
onClick={() => void onWithdraw()}
>
{isInCooldown
? `Wait ${Math.ceil(remainingMs / 1000)}s`
: 'Withdraw'}
</button>
{requires2fa && <p>Enter your 2FA code to continue</p>}
</div>
)
}Override individual fields when needed:
tsx
await startWithdrawal({ amount: '10' })Returns
| Field | Purpose |
|---|---|
status | idle | starting | requires2fa | confirming | completed | error |
requires2fa | Convenience flag |
startWithdrawal(overrides?, options?) | Builds the request from context; optional partial overrides + onAmountAdjusted |
confirmWithdrawal / cancelWithdrawal | 2FA actions |
isStartingWithdrawal / isConfirming | In-progress flags |
result / error | Outcome / last hard error |
is2faInvalid / clear2faInvalid | Wrong 2FA code flag (status stays requires2fa) |
When the SDK auto-adjusts an above-spendable amount, the React hook syncs the amount input via setAmountExact before your onAmountAdjusted callback runs, so the form already shows the value the user is being asked to approve. Returning false from the callback cancels — status becomes idle and no cooldown is started. See core withdrawal for the full adjustment payload.
The 2FA code can come from SMS, email, or an authenticator app and is typically 6–7 characters. Do not hardcode a 6-digit-only input in your UI.
Passkeys are not supported → COINBASE_PASSKEY_NOT_SUPPORTED.
Success UI
When status === 'completed', result holds the full CoinbaseWithdrawal. Use it (or useCoinbaseCompletedTransactionSummary) for the success screen, then call restartSession() before another payment.
Typical step branching:
tsx
const { result, requires2fa, isConfirming, status } = useCoinbaseWithdrawal()
if (result) {
// success — show amount, network fee, destination, id, …
} else if (requires2fa || isConfirming || status === 'confirming') {
// 2FA form
} else {
// withdraw form
}Full walkthrough: Example.
Errors
| Code | When | What to do |
|---|---|---|
REACT_COINBASE_PROVIDER_REQUIRED | Outside provider | Wrap with CoinbaseProvider |
COINBASE_SELECTION_INCOMPLETE | Missing token / amount / account name | Complete selection first |
SESSION_NOT_ACTIVE | Session cannot pay again | restartSession() |
COINBASE_NOT_CONNECTED | Not connected | Connect |
COINBASE_SESSION_EXPIRED | Token invalid | Reconnect |
COINBASE_COOLDOWN_ACTIVE | Start during cooldown | Use cooldown |
COINBASE_INVALID_WITHDRAWAL_AMOUNT | Amount below min, invalid, or above spendable with no viable cap | Fix amount first |
COINBASE_PASSKEY_NOT_SUPPORTED | Passkey-only confirm | SMS / authenticator |
COINBASE_NO_ACTIVE_WITHDRAWAL | Confirm with nothing pending | Start again |
See Errors.