Every deposit that enters the settlement queue moves through a status machine. The current state is
on each /swaps item and on every
status_changed event.
Donβt hardcode status strings
Depending on the source chain, a deposit flows through one of two machines β EVM (deploy β swap)
or Solana (settle). So each item carries three fields that let you react to meaning rather than
memorizing every string:
phase β which leg of the lifecycle: deploy | swap | settle | done
category β the integrator-facing meaning, independent of chain:
waiting β queued, will be picked up automatically
active β a transaction is in flight right now
retrying β the last attempt failed or was deferred; will retry after backoff
success β terminal, funds delivered
failed β terminal, gave up
terminal β true once no further automatic transition will happen (completed or dead)
The simplest integration: watch for terminal: true β completed is success, dead is
failure. Everything else is in-progress.
Status reference
Happy paths
The error field
When a swap is in a retrying state (or dead), its error is a
structured error:
error is null on any non-failing state. A non-null error never means success β success is
always status: "completed" with error: null.
- Branch on
error.code (stable), not on message.
error.retryable reflects whether the worker will try again. A dead item always reports
retryable: false.
Retries & backoff
Failed attempts are retried automatically with exponential backoff:
After 7 attempts β or immediately for a non-retryable error such as UNSUPPORTED_DEST β the item
becomes dead. Every attempt emits a status_changed event carrying the incremented retryCount
and the current error, so you can surface retry progress in real time.
deferred (Solana) is not a failure β it means settlement is temporarily blocked (e.g. no quote
yet, or the accumulated balance is still too small) and will be retried. It shares the same
backoff and dead cap as the failing states.
Reacting to states