Table of Contents

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

IReadOnlySet<ArkadeSwapIntentStatus>

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

type ArkadeSwapIntentType

Which corridor.

status ArkadeSwapIntentStatus

Where 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

type ArkadeSwapIntentType

Which corridor.

current ArkadeSwapIntentStatus

Where the swap is now.

observation SwapObservation

What the chain says.

Returns

ArkadeSwapIntentStatus?

The status to move to, or null to 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

type ArkadeSwapIntentType

Which corridor.

current ArkadeSwapIntentStatus

Where the swap is now.

now long

Unix seconds.

refundLocktime long?

The corridor's refund locktime, if it has one.

Returns

ArkadeSwapIntentStatus?

The status to move to, or null to 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

type ArkadeSwapIntentType

Which 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