Class ArkadeSwapStateMachine
- Namespace
- NArk.ArkadeIntents.Services
- Assembly
- NArk.ArkadeIntents.dll
The lifecycle of every Arkade intent swap, in one place: which states exist per corridor, what moves between them, and what we are expected to do in each.
public static class ArkadeSwapStateMachine
- Inheritance
-
ArkadeSwapStateMachine
- Inherited Members
Remarks
Transitions are guarded by the state we are IN, not only by what the chain says. That difference matters: a spend observed while we are mid-cancel is our own cancel landing, and a spend observed while waiting is the counterparty filling. A projection of chain state alone cannot tell those apart, which is why the guard used to live somewhere else as a special case.
The same status names mean different things per corridor, because the roles invert. Fulfilled on a send swap is the solver spending our lockup; on a receive swap it is us spending theirs. Encoding both here keeps that from being rediscovered at each call site.
Fields
Terminal
States a swap never leaves.
public static readonly IReadOnlySet<ArkadeSwapIntentStatus> Terminal
Field Value
Methods
ActionFor(ArkadeSwapIntentType, ArkadeSwapIntentStatus)
What we should do about a swap sitting in this state, if anything.
public static ArkadeIntentAction ActionFor(ArkadeSwapIntentType type, ArkadeSwapIntentStatus status)
Parameters
typeArkadeSwapIntentTypeWhich corridor.
statusArkadeSwapIntentStatusWhere the swap is.
Returns
- ArkadeIntentAction
The action, or None.
Remarks
Only consequences, never decisions. Claiming a funded receive swap and refunding a send swap past its locktime both follow from the state with nothing left to weigh — the money is already ours, the window is finite, and no one else is coming. Cancelling a pending asset swap is a choice: it is still waiting to be filled, which is what was asked for.
Both are also callable directly, and this is only the sweep's opinion about them. Neither needs a counterparty, which is what makes automating them safe at all — the covenant's other refund leaves need the solver's signature and the protocol has no way to ask for one, so there is nothing for a timer to attempt there even in principle.
Next(ArkadeSwapIntentType, ArkadeSwapIntentStatus, SwapObservation)
The next status for a swap, or null when nothing has changed.
public static ArkadeSwapIntentStatus? Next(ArkadeSwapIntentType type, ArkadeSwapIntentStatus current, SwapObservation observation)
Parameters
typeArkadeSwapIntentTypeWhich corridor.
currentArkadeSwapIntentStatusWhere the swap is now.
observationSwapObservationWhat the chain says.
Returns
- ArkadeSwapIntentStatus?
The status to move to, or
nullto stay put.
NextOnClock(ArkadeSwapIntentType, ArkadeSwapIntentStatus, long, long?)
The next status for a swap when only time has passed — no chain event either way.
public static ArkadeSwapIntentStatus? NextOnClock(ArkadeSwapIntentType type, ArkadeSwapIntentStatus current, long now, long? refundLocktime)
Parameters
typeArkadeSwapIntentTypeWhich corridor.
currentArkadeSwapIntentStatusWhere the swap is now.
nowlongUnix seconds.
refundLocktimelong?The corridor's refund locktime, if it has one.
Returns
- ArkadeSwapIntentStatus?
The status to move to, or
nullto stay put.
Remarks
Chain events drive Next(ArkadeSwapIntentType, ArkadeSwapIntentStatus, SwapObservation), but a locktime maturing raises no event: nothing moves on-chain when a deadline passes, so a monitor that only reacts would never notice. The advance loop calls this on every pass so time alone can open a refund and close a claim window. Deliberately narrower than Next(ArkadeSwapIntentType, ArkadeSwapIntentStatus, SwapObservation): with no lockup sighting there is nothing to promote, so only states a clock can honestly settle are moved.
Steps(ArkadeSwapIntentType)
The ordered steps of a corridor: what happens, who does it, and where it leaves the swap.
public static IReadOnlyList<SwapStep> Steps(ArkadeSwapIntentType type)
Parameters
typeArkadeSwapIntentTypeWhich corridor.
Returns
- IReadOnlyList<SwapStep>
The steps, in order.
Remarks
Not every step moves the swap — negotiating and verifying leave no trace in storage, and are listed anyway because the sequence is the thing a caller needs to reason about. The ones that do move it are checked against the transition table by test, so this cannot describe a state the machine never reache