Appearance
Amount & quote
Transfer amounts on the public API are human-readable source crypto (the token the user is sending) for a resolved transfer plan. Fiat (currently USD) is available from rates on the balance and from getMinAmount / getQuote.
Minimum
ts
const min = await client.wallets.transfer.getMinAmount(plan);
// min.crypto — source token units, already ceiled to display decimals
// min.fiat — USD, ceiled to cents, when rates are known| Field | Meaning |
|---|---|
crypto | Minimum in source token units (what the user enters) |
fiat? | Fiat value of that minimum when rates are known |
For swap/bridge, the destination min is converted into source units via exchange rates, then ceiled so typing the shown value cannot fall below the true minimum.
Validate
validateAmount does not throw. It checks flow, parse, and min.
ts
const validation = await client.wallets.transfer.validateAmount({
plan,
amount, // source crypto string
});
if (!validation.ok) {
validation.code; // 'BELOW_MIN' | 'INVALID_AMOUNT' | 'WRONG_FLOW'
validation.message;
validation.minAmount;
}WRONG_FLOW is returned when plan.flow === 'unavailable'.
Recommended validation stack
- Sanitize the input (
sanitizeAmountInput/parseAmountInput) so the string is parseable (no grouping). validateAmount({ plan, amount })for flow / parse / min.getQuote({ plan, amount })whenplan.flowisswaporbridge. Direct can skip the quote.- Pass the same amount (and quote, when you have one) into
submit.
These helpers live on @swapped/connect-sdk (same suite Coinbase uses). You do not need every helper on the wallets page — sanitize → validate → quote when needed is enough.
Crypto / fiat helpers
From @swapped/connect-sdk (same helpers Coinbase uses):
| Helper | Purpose |
|---|---|
convertCryptoToFiat({ amount, exchangeRate }) | Crypto → fiat string |
convertCryptoToFiatCeil({ amount, exchangeRate }) | Crypto → fiat, ceiled (used for min labels) |
convertFiatToCrypto({ amount, exchangeRate, decimals }) | Fiat → crypto |
validateAmountInput({ amount, minAmount, maxAmount, … }) | Field validation |
parseAmountInput / sanitizeAmountInput / formatAmountForInput | Input parsing |
WalletBalance.exchangeRate / fiatValue / formatted are the rate and display strings for the selected token. When min.fiat is missing, convertCryptoToFiatCeil with token.exchangeRate produces a fiat min from min.crypto.
React: useDualAmountInput keeps crypto and fiat fields in sync.
Quote
ts
const quote = await client.wallets.transfer.getQuote({
plan,
amount, // human-readable source crypto
});WalletTransferQuote:
| Field | Meaning |
|---|---|
flow | 'direct' | 'swap' | 'bridge' |
amountIn | { crypto, fiat? } — what the user sends |
amountOut? | { crypto, fiat?, network, symbol } — expected receive (swap/bridge) |
networkFee? | { amount, symbol, tokenAddress } — display fee. Swap: fiat from the route; bridge: network fee USD. symbol can be 'USD' |
protocolFeeFiat? | Protocol fee in fiat when the quote exposes one |
estimatedTimeSeconds? | Estimated completion time in seconds |
raw? | Opaque payload for swap/bridge. Pass the whole quote object into submit — do not build or edit fields |
An invalid or empty amount throws WALLET_TRANSFER_INVALID_AMOUNT. Quote fetch failures throw WALLET_TRANSFER_QUOTE_FAILED.
Direct can omit quote on submit. Swap and bridge need a current quote — if the amount changed, refetch and do not submit a stale one. See Submit.