A quote request

getQuote, previewQuotes and prepareQuote check both accounts before any call. A recipient that cannot be an address on destChain, or a sourceAccount that cannot be one on sourceChain, throws an InteropError (invalid-input) naming the field and the chain, for example recipient must be a Solana address (base58, or 0x and 64 hex digits) on solana-localnet. An EVM account is 0x and 40 hex digits (any casing); a Solana account is base58, or 0x and 64 hex digits. Without the check the hub answers EIN0001, with the field as its reference. A common cause: an address typed for one destination, still in the form after the user switched the destination chain. toBaseUnits("0.05", 18) and formatUnits(50000000000000000n, 18) convert between readable and base-unit amounts.

The quote

getQuote returns a Quote:

How long a quote lives

A quote lives about 30 seconds. The hub also answers an identical request within that window with the same quote and its original expiry. The SDK therefore anchors the countdown on when a quoteId was first received, using the client’s own clock only:
executeQuote wants at least 15 s left before it asks the user to sign (minSigningTimeMs). With less, it fetches a fresh quote for the same request, and continues only if the new one is not worse: the same lane, no lower output, no higher cost. A worse one throws ReviewRequiredError carrying both quotes, so you can show the new terms and ask again. Pass acceptRequote(fresh, reviewed) to decide yourself.

Reverse quotes

With swapType: "exact-output", amount is what the recipient must receive, and the quote’s payAmount is the price:
A maxAmountIn under the price answers EIN0008 providerRefused: raise the cap rather than retry. The token-in lane refuses exact-output (EIN0001, reference swapType).

Preview and prepare

For a UI that shows live estimates as the user types, then commits to one provider:
An empty offers array is a normal answer: no provider takes this route or amount right now. A prepared quote is bound to a preparationId (a fresh UUID unless you pass one), so repeating the same preparation is safe. When a prepared quote runs low on time, the SDK prepares it again.

The pre-signing checks

The hub routes and prices; it does not decide what the user signs. Before any wallet prompt, executeQuote compares every field that moves money with the request and the catalog, and refuses with a VetError if one row fails. Run the same checks yourself to show them:
vetQuote also takes a context: sourceAccounts and destinationAccounts (every account the user may pay from or to, default the request’s), permit2Address, maxSlippageBps, and nowSec, a unix time from a clock you trust (a chain head), which turns on the Solana expiry check.

The catalog

await client.getCatalog() returns a CatalogIndex over one snapshot, cached for 5 minutes (the last good copy is kept when the hub is unreachable): Build pickers from it rather than hard-coding: contract addresses, keys and proxies move when the hub is redeployed.