@corridor/routing) turns a request into an ordered list of legs. It is pure: no I/O, fully unit-tested, and the only place a route is decided.
The graph
Nodes are positions (venue + asset). Edges are legs Corridor can execute, each with a cost and, where relevant, the environments it exists in.
Planning
1
Validate
Payouts must be funded from the hub; collections must land on it and are always public; a shielded payout must end in a shielded venue, and a public one must not.
2
Search
Cheapest path over the edges available in the requested environment. The batch leg is excluded from search and appended explicitly.
3
Bracket
Payouts start with
ledger.reserve (move the amount into the customer’s hold); collections end with ledger.credit (credit the customer’s hub balance). Shielded payouts end with zcash.shieldedBatch.4
Scope references
Each step gets a reference scope (payout, batch or item), so a shielded batch uses one batch reference on the funding legs and an item reference per recipient output.
Resulting routes
Payouts through partners that settle on Solana, including Paj for naira, take two hops through Base, because Across has no direct Tempo ↔ Solana route. A partner that settles on Base would cut that to one hop with a config change.