Called when a VTXO's exit becomes observable onchain.
The seam exists because nothing else can learn the fact: delta sync filters on creation time
(GetVtxosOptions.after / before), so a status change on an older VTXO is invisible to it, and
neither exit path can reach a contract manager on its own — Unroll.Session takes no contract
layer by design, and the UnilateralExit executor is deliberately keyless and provider-only.
A plain function type, with no runtime import anywhere in this module, is what lets both keep
that independence: an exit path calls the hook, it does not import the contract layer.
Best-effort by contract. An exit is a disaster-recovery path and must never fail because a
cache write did, so every call site goes through notifyExitObserved.
Called when a VTXO's exit becomes observable onchain.
The seam exists because nothing else can learn the fact: delta sync filters on creation time (
GetVtxosOptions.after/before), so a status change on an older VTXO is invisible to it, and neither exit path can reach a contract manager on its own —Unroll.Sessiontakes no contract layer by design, and theUnilateralExitexecutor is deliberately keyless and provider-only.A plain function type, with no runtime import anywhere in this module, is what lets both keep that independence: an exit path calls the hook, it does not import the contract layer.
Best-effort by contract. An exit is a disaster-recovery path and must never fail because a cache write did, so every call site goes through notifyExitObserved.