Server-side session credential action handlers.
Dispatches on credential.payload.action to open, voucher, top_up,
and close. Each handler updates per-channel deposit / voucher /
spend balances through MPP.Session.Store.
open and topUp require funding verifiers, passed as the :verify_open /
:verify_top_up options or the server-only "verify_open" /
"verify_top_up" method-config keys. open calls verify.(payload, opts)
and topUp calls verify.(payload, channel, opts). Without a verifier the
action is rejected.
A verifier MUST confirm on-chain, at the finality the server requires, that
the credential's transaction succeeded, that it targets the configured
escrow_contract on the configured chain_id, and that it funds the
credential's channelId with the configured payee and token. It returns
the escrow's current channel state, or {:error, %MPP.Errors{}}:
{:ok, %{
deposit: non_neg_integer(), # total escrowed deposit
settled: non_neg_integer(), # paid out of the escrow, at most deposit
close_requested: boolean(), # a close is pending on-chain
finalized: boolean(), # the channel is closed on-chain
payer: String.t(), # open only, optional
authorized_signer: String.t() # open only, optional
}}deposit, settled, close_requested, and finalized are all required;
a result missing any of them, or of any other shape, is a verification
failure. A zero deposit is rejected as an unfunded channel;
close_requested or finalized reject the action as a closed channel. The payload's additionalDeposit and any configured
or suggested deposit are never trusted as the ceiling.
Settled funds were already paid out of the escrow for earlier vouchers. At
open the voucher's cumulativeAmount must lie between settled and
deposit, the channel records settled as already spent, and only
cumulativeAmount - settled counts toward the request. At topUp the
deposit must increase, settled never decreases, and spent and cumulative
are raised to it, so settled funds are never counted twice.
At open a verified payer must match the configured payer, and a verified
signer becomes the channel signer (a descriptor must agree with it).
The voucher signer is fixed at open and stored on the channel. A zero
signer address, from any source, means the payer signs. The signer is the
descriptor's authorizedSigner once the descriptor hashes to channelId
under the configured escrow_contract and chain_id; otherwise the
verified signer, then the configured :authorized_signer, falling back to
the payer. A descriptor's payee and
token must match the configured recipient and token. A credential's
top-level authorizedSigner must equal that signer. Vouchers and closes are
verified against the stored signer only.
The highest accepted voucher signature is kept on the channel as its settlement proof.
close requires a settlement callback, passed as the :settle_close option
or the server-only "settle_close" method-config key. Once the close voucher
has been validated, close calls settle.(payload, closing_channel, opts).
The callback MUST submit the escrow close (or settle) for that voucher, wait
for the transaction to succeed at the finality the server requires, and
return {:ok, %{tx_hash: "0x" <> 64 hex}} or {:error, %MPP.Errors{}}. Only
then is the channel marked closed; the hash is recorded on its proof and
returned as the receipt reference. Before the callback runs, the channel is
reserved as closing: it accepts no vouchers, spends, top-ups or competing
closes. {:error, %MPP.Errors{}} must mean the close definitively did not
settle; it releases the reservation and the channel stays active. Any other
result (or a raise) leaves the outcome unknown, so the close is rejected and
the channel stays reserved for the operator to reconcile. Methods
that redeem closed channels themselves (MPP.Methods.XRPL.Session) pass
settle_close: :caller.
Summary
Functions
Parse a session payload and apply the matching channel-state handler.
Apply a parsed session payload to the channel store.
Return the effective minimum voucher delta for a session intent.
Dispatch a session credential payload using fields on the session intent.
Types
@type opts() :: keyword()
Functions
@spec dispatch(map(), opts()) :: {:ok, MPP.Receipt.t()} | {:error, MPP.Errors.t()}
Parse a session payload and apply the matching channel-state handler.
@spec handle(MPP.Session.Payload.t(), opts()) :: {:ok, MPP.Receipt.t()} | {:error, MPP.Errors.t()}
Apply a parsed session payload to the channel store.
@spec minimum_voucher_delta(MPP.Intents.Session.t()) :: non_neg_integer()
Return the effective minimum voucher delta for a session intent.
@spec verify(map(), MPP.Intents.Session.t()) :: {:ok, MPP.Receipt.t()} | {:error, MPP.Errors.t()}
Dispatch a session credential payload using fields on the session intent.