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.
Summary
Functions
Parse a session payload and apply the matching channel-state handler.
Apply a parsed session payload to the channel store.
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 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.