App Session Deposit Flow
This document provides a comprehensive breakdown of the App Session Deposit flow as defined in the Nitrolite v1.0 protocol. This operation allows a user to deposit funds from their channel state (Unified Balance) into an existing App Session, locking those funds for use within the application.
Actors in the Flow
| Actor | Role |
|---|---|
| User | The human user initiating the deposit |
| SenderClient | SDK/Application managing states on behalf of the user |
| Node | The Nitronode that validates and coordinates both app session and channel states |
Prerequisites
Before the deposit flow begins:
- SenderClient is connected to the Node via WebSocket.
- Node contains user's state with Home Channel information.
- An App Session already exists (created via
create_app_session). - User is a participant in the target App Session.
:::info Application signature collection The application is responsible for collecting the app-session quorum signatures before it submits an app-state update. Nitronode validates the quorum, but it does not gather participant signatures for the app. :::
Key Data Structures
newAppState (App State Update)
app_session_id: appSessionId # Hex identifier of the app session
intent: deposit # Specifies this is a deposit operation
version: <incremented> # Next version number
allocations: # Updated fund distribution
- participant: "0xUser1..." # User making the deposit
asset: "usdc"
amount: "150.0" # Amount after deposit (+50 added)
- participant: "0xUser2..." # Another participant in the session
asset: "usdc"
amount: "50.0" # Not affected by this deposit
session_data: "{...}" # JSON stringified session data
Dual-State Coordination
Unlike a simple transfer, App Session Deposit requires updating two states simultaneously:
- App Session State -- Shows increased allocations for the depositor.
- User Channel State -- Shows funds committed (locked) via
committransition.
Phase 1: Deposit Initiation
The User calls submit_app_state on the SenderClient with:
| Parameter | Description |
|---|---|
newAppState | App state update with intent: deposit and new allocations |
sigQuorum | Array of signatures meeting the quorum requirement |
Phase 2: Fetching Current App Session State
- SenderClient requests the current App Session state from the Node using
get_app_sessionswith theapp_session_idfilter. - The Node returns
<currentAppState>containing current version, allocations for all participants, and session data.
Phase 3: Client-Side Validation and User State Preparation
Validation Step Details
The client performs ValidateSessionAppState checking:
| Check | Description |
|---|---|
intent = deposit | Confirms this is a deposit operation |
userWallet = appParticipant | User must be a participant in the session |
only participant deposits | Only the depositing participant's allocation increases |
validate quorum | Signatures meet the quorum threshold |
Building the User's New Channel State
| Step | Operation | Description |
|---|---|---|
| 1 | createNextState(currentState) | Create new state with incremented version |
| 2 | state.setID(...) | Calculate deterministic state ID |
| 3 | NewTransition(commit, ...) | Create commit transition linking to appSessionId |
| 4 | applyTransitions(...) | Apply transition, reducing user's available balance |
| 5 | signState(state) | User signs the new channel state |
The commit Transition
The commit transition is used for locking funds into an App Session:
| Field | Value |
|---|---|
type | commit |
account_id | appSessionId (the target app session) |
amount | Amount being deposited |
tx_hash | State ID reference |
The commit transition locks funds from the user's Unified Balance. The reverse operation (release) unlocks funds when withdrawing from an app session.
Phase 4: Submitting to Node
API Method: submit_deposit_state
| Parameter | Type | Description |
|---|---|---|
app_state_update | app_state_update | The app session state update |
quorum_sigs | string[] | Signatures for quorum |
user_state | state | User's new channel state with commit transition |
Node Validation Steps
| Step | Operation | Purpose |
|---|---|---|
| 1 | App session validation | Verify app state update is valid |
| 2 | GetLastState(...) | Fetch current user channel state |
| 3 | EnsureNoOngoingTransitions() | Prevent race conditions |
| 4 | ValidateStateTransition(...) | Verify state version and signatures |
| 5 | EnsureSameDepositAssetAmount(...) | Amount in app state matches commit transition |
| 6 | StoreState(state) | Persist both states |
EnsureSameDepositAssetAmount is the key validation ensuring the user's channel state (commit amount) exactly matches the increase in their app session allocation. This prevents discrepancies between the two states.
:::info Off-chain App Session Semantics From the on-chain protocol:
- App sessions are off-chain sub-channels governed by an external server.
- Funds may be locked into a session (flow to Node), or unlocked from a session (flow to User).
- Only signatures are required for persistence.
- Session effects are netted into cumulative net flows of the next enforceable state. :::
Phase 5: Confirmation and Completion
What Gets Returned
- Node signature -- Confirms Nitronode has accepted both states.
- Latest app session state -- Retrieved by query if the application wants a fresh read after submission.
- Success -- User-facing confirmation.
Complete Flow Diagram
Key Concepts Summary
Dual-State Coordination
| State | What Changes |
|---|---|
| App Session State | allocations array increases for the depositor |
| User Channel State | commit transition locks funds from Unified Balance |
Transition Types for App Sessions
| Transition | From / To | Purpose |
|---|---|---|
commit | Unified Balance to App Session | Lock funds for deposit |
release | App Session to Unified Balance | Return funds on withdraw |
Why Two States?
Having two different states (App Session State and User Channel State) creates an atomicity challenge -- if one state updates without the other, the system would be in an inconsistent state.
This is solved by:
- Single API endpoint -- Both states are submitted together via
submit_deposit_state, ensuring the Node processes them as a single atomic operation. - Verifiable accounting -- Channel state tracks fund flows, app session tracks allocations.
- Linked validation --
EnsureSameDepositAssetAmountvalidates that both states reflect the same deposit amount before either is stored.