Skip to main content

Driving

The driver moves each swap forward in passes. A pass reads the chain and the server for one swap, saves what changed, and acts on it.

In the background​

let mut updates = driver.subscribe();
tokio::spawn(driver.run());
while let Some(swap) = updates.next().await {
let record = swap.record().await?;
println!("{} {:?} {:?}", swap.swap_id(), record.status, swap.error());
}
CallEffect
runDrives every stored swap that still has something to do, until stop. A swap created or restored joins at once. A second call does nothing.
subscribeYields a handle each time a swap changes, and each time a pass on it fails.
stopEnds run after the pass in flight. Final: the driver does not run again, and its updates end once drained.
wait_stoppedResolves once nothing writes to the store.
stateIdle, Running, Stopping or Stopped.

An update is a prompt to render, not a ledger: under sustained lag the stream drops updates rather than slow the driver. A handle keeps no copy of the swap, so status, record and funds always return the store's latest, and driver.get(swap_id) returns any stored swap.

By hand​

while !swap.status().await?.is_terminal() {
match swap.advance().await {
Ok(status) => println!("{status:?}"),
Err(error) if error.retryable() => {}
Err(error) => return Err(error.into()),
}
}
CallEffect
stepOne pass now. Returns the status.
advanceWaits for a server signal or the poll interval, whichever comes first, then one pass.

Handles and run mix freely: a swap never gets two passes at once. On a SwapIn, a terminal status can still leave refunds moving.

Errors​

A failing pass sets the swap's error, and the next pass retries. A pass that works clears it and yields the swap once more.

What failserrorThen
Reading a chainsetthe swap waits for the chain
Broadcasting a claim or a refundsetthe next pass broadcasts again
Reading the servernot setthe swap moves on from the chain; server_status keeps the last label
The server taking a cancel, or a SwapIn's refund keysetthe next pass sends it again

error.retryable() is true for an outage the next pass may outlive, such as an unreachable chain or server, and false for an error that needs attention.

The driver does not report whether the server is reachable.

TypeScript

client.signals({ onConnectionChange }) reports when the server's WebSocket drops and when it is back, for a reconnecting hint.