One call runs the whole order for the quote’s lane: wallet checks,
approvals, re-quoting when time is short, the pre-signing checks, the signature or transaction, the
submission to the hub, and tracking until the order ends.
Options
Events
awaiting-wallet is the moment to tell the user to look at their wallet.
On the wrap-native and swap-token lanes, submit-order runs while the deposit is still
confirming: the order is registered as soon as the transaction is broadcast, and the SDK waits for
the receipt afterwards.
The result
Tracking
The aggregator’s status (GET /order/{id}/status) is advisory. It can lag, or stop at
executed, long after the order settled. The SDK therefore also reads the hub’s own chain facts
(GET /onchain/{id}/fill) on every round:
- a fill on chain emits
filled: the recipient has been paid;
- settled or refunded on chain ends the wait (
decidedBy: "chain");
- a terminal aggregator state (
settled, finalized, failed, refunded) also ends it.
Fills usually show up seconds after submission. A wait gives up after 30 minutes with a timeout
error, whose advice is to check the order’s status later; the order itself is unaffected.
To follow an order outside executeQuote (after waitForCompletion: false, or from your history):
Open-flow orders are followed on the hub’s lifecycle view instead (GET /status/{id}): done when
the recipient is paid (USER_PAID) or delivery is final, and a failure when the order goes to
recovery (RECOVERY_ONLY).
Tracking works the same with a project id (projectTransport): the chain facts and the lifecycle
view are open to it.
Lost answers
A submission can succeed while its answer is lost (a timeout, a dropped connection, or the
gateway’s EPX0050–EPX0053, among them EPX0052 when the hub took longer than the gateway’s
10 s). The gateway keeps a submission running at the hub when the caller disconnects, but not past
its own 10 s. The hub records one submission per quote and answers a repeat with the original
acknowledgement, so the SDK recovers without ever asking the user to sign again:
- it looks the order up by its derived hub order id,
hex(sha256("infinity:v1:order:" + quoteId));
- if the hub has not seen it, it re-posts the same body once;
- if every answer is still lost, it throws
OutcomeUnknownError with the hubOrderId to follow, and,
on the transaction lanes, the transactionHash already on chain.
After an OutcomeUnknownError, never quote again or ask the user to sign again: the order may exist.
Follow it with trackOrder(error.hubOrderId), or find it with
client.findOrderByTx(sourceChain, error.transactionHash).
Executing on a server for your users
A call that names no user goes under hubTransport’s own subject (default unless you set
another), so an order your backend executes for one of your users lands in that shared history like
every other, and the hub does not know which user it was for. Two ways to keep your users apart
(Authentication — your users):
-
Name the user. Get the quote with their subject, and pass the same
subject to
executeQuote, which sends it on the submission, a re-quote and the status reads. The hub then
keeps that user’s quote, order and history apart:
A client made for one user, createInteropClient({ transport, subject }), sends it on every call
that reads it. The SDK checks the subject against the hub’s rule (^[A-Za-z0-9._@+~-]{1,128}$)
before any call.
-
Record the user yourself, next to
result.orderId and result.hubOrderId.
Calls your frontend makes through createInteropProxy are kept apart for you
(Partner backend).