Skip to content

Amount & quote

Source crypto is what submit accepts — the token the user is sending, from a resolved transfer plan. Fiat (currently USD) is available from the token’s exchangeRate and from the min / quote hooks.

The demo binds two fields with useDualAmountInput and labels the min from useWalletTransferMinAmount.

useWalletTransferMinAmount

tsx
const { minAmount, min, isLoading, error, refetch } =
  useWalletTransferMinAmount(plan)

Options

OptionMeaning
planResolved plan, or null

Returns

FieldMeaning
min{ crypto, fiat? }. crypto is already ceiled to display decimals; fiat is ceiled to cents
minAmountNumber(min.crypto) when it is a positive finite number, else null (handy for useDualAmountInput)
isLoading / error / refetchFetch state

Idle when plan is null or plan.flow === 'unavailable'.

When min.fiat is missing, convertCryptoToFiatCeil({ amount: min.crypto, exchangeRate: token.exchangeRate }) produces a fiat min.

useDualAmountInput

Shared amount hook from @swapped/connect-sdk/react (also used by Coinbase). Keeps crypto and fiat in sync.

tsx
import { useDualAmountInput } from '@swapped/connect-sdk/react'

const {
  amount,
  amountDisplay,
  setAmount,
  setAmountExact,
  amountFiat,
  setAmountFiat,
  touched,
  setTouched,
  onBlur,
  error: amountError,
  isValid,
  isFiatAvailable,
  reset,
} = useDualAmountInput({
  exchangeRate: token.exchangeRate,
  token: token.symbol,
  tokenDecimals: token.decimals,
  minAmount,
  maxAmount: Number(token.displayBalance),
  balanceAmount: Number(token.displayBalance),
  maxAmountMode: 'balance',
  clampToMax: true,
  formatCryptoValue: value => `${value} ${token.symbol}`,
})

Options

OptionMeaning
exchangeRateToken → fiat rate. null disables fiat
token?Token symbol (formatting + default decimals)
maxDecimals?Max fraction digits while typing crypto
tokenDecimals?Max fraction digits when converting from fiat
minAmount?Minimum in crypto units
maxAmount?Spendable ceiling in crypto units
balanceAmount?Raw balance in crypto units
maxAmountMode?'balance' (default) or 'spendable'
clampToMax?Clamp typing to the ceiling. Default false
formatCryptoValue?Format min / max / balance in error messages
touchedDelay?ms before blur marks touched. Default 0

Returns

ResultMeaning
amountFull-precision crypto string — pass this to quote / submit
amountDisplayCrypto string for the input
setAmount / setAmountFiatEdit one side; the other updates
setAmountExactMax button (skips the typing sanitizer)
amountFiatFiat string (2 dp)
isFiatAvailableexchangeRate is usable
errorBlocking validation after touch (below_min, …)
warningSoft above_spendable in 'balance' mode
isValidNo blocking failure (ignores touched)

amountError.code === 'below_min' is what the demo uses for “Minimum amount is …” on both fields.

Core helpers convertCryptoToFiat, convertFiatToCrypto, validateAmountInput are also on @swapped/connect-sdk. See Amount & quote (Core).

useWalletTransferQuote

tsx
const { quote, isFetching, error, refetch } = useWalletTransferQuote({
  plan,
  amount,
  debounceMs: 300,
})

Idle when plan is null, plan.flow === 'unavailable', or amount is empty / invalid (including below the plan min). enabled: false skips fetching entirely.

Options

OptionMeaning
planResolved plan, or null
amountSource crypto string
enabled?Skip fetching when false. Default true
debounceMs?Default 300

Returns

ResultMeaning
quoteWalletTransferQuote or null
isFetchingQuote in flight
error / refetchFetch state

quote.amountIn, quote.amountOut, quote.networkFee, quote.protocolFeeFiat, quote.estimatedTimeSecondsAmount & quote (Core).

Pass the whole quote object into submit. Do not build or edit fields. Direct can omit the quote. Swap and bridge need a current quote — if the amount changed, refetch and do not submit a stale one.

The demo shows amountOut as “You receive ≈ …”, estimatedTimeSeconds, and networkFee (prefix $ when symbol === 'USD').