ER Topology
How a NorthStar session is wired across the user, the SDK, the L1 anchor, and the Ephemeral Rollup. This page covers the components and the data path for the canonical session lifecycle: open → delegate → execute → settle.
The components
User / dApp
Browser, agent runtime, server
Initiates session lifecycle and submits transactions. Holds the owner keypair.
NorthStar SDK
Same process as the user
Wraps the Portal program and the ER RPC. Translates openSession, delegate, closeSession into the corresponding Solana ixs.
Router
Edge
Routes ER-bound traffic to the right validator instance (the (portal, owner, grid_id) tuple identifies the session).
Portal (L1)
Solana L1 program
Source of truth for session metadata, delegation records, and settle-back. Locks delegated accounts on L1 for the session's lifespan.
Validator
Operator infrastructure
A single-tenant Solana validator dedicated to the session. Spawns on SessionCreated, processes ER txs, holds the canonical session state until close.
Ephemeral Rollup (L2)
Inside the validator
The runtime where ER transactions execute. Same SVM semantics as L1 — different slot cadence, different fee policy.
The data flow
The diagram below traces a full session lifecycle. The columns are actors; time runs top to bottom.

Five message phases:
1. openSession
The owner calls sdk.openSession({ gridId, ttlSlots, feeCap, feeStructure }). The SDK assembles the Portal OpenSession ix and submits it to L1. The Portal:
Creates the session PDA at
sessionPda(portal, owner, grid_id).Creates a per-owner
fee_vaultPDA (one-time per owner).Pulls the
feeCaplamports from the owner into the fee vault.Emits a
SessionCreatedevent.
The validator subscribes to that event and spawns the ER runtime for this session. From this point until close, every account delegated to this session is exclusive to this validator instance.
2. delegateAccount
For each account the session needs to write, the owner calls sdk.delegate({ account, ownerProgram }). The Portal:
Reassigns the account's
ownerfield to the Portal program. This locks it on L1.Creates a delegation record at
delegationRecordPda(portal, account)with(grid_id, owner_program, bump).Emits an
AccountDelegatedevent.
The validator picks the event up and marks the account writable inside the ER. Reads come from L1 state at delegation time; writes accumulate locally.
3. sendTransaction
The owner — or any keypair the session-side program accepts — submits a transaction to the ER's RPC. The Router forwards it to the validator instance hosting this session. The validator:
Validates the tx against ER state and the session's delegated set.
Executes inside the SVM at the session's slot cadence.
Confirms back to the SDK over WebSocket (
signatureSubscribe).
End-to-end confirmation latency on the same machine as the validator is sub-50ms; over the public internet it floors at the network round-trip. See real-time confirmation for the breakdown.
4. closeSession
When the owner calls sdk.closeSession({ gridId }) (or the TTL expires), the Portal initiates settlement:
The validator stashes the final state of every delegated account.
The Portal walks the delegation set and applies each final state to its corresponding L1 account in a single multi-account write.
Ownership is restored to the original program.
Each delegation record is closed; rent flows back to the owner.
The settle is all-or-nothing: either every delegated account commits its final state, or none do and the session reverts to its pre-close state for retry. See settle-back guarantees for the failure modes.
5. State settled on L1
After the Portal finalizes settlement, the post-session state is the canonical L1 state. Anyone can read it; the original owners can write it again. The session is gone.
What stays on L1, what's local to the ER
Delegated accounts
Writable in ER, locked on L1
L1 receives final ER state; ownership restored
Non-delegated accounts
Read-only in ER, normal on L1
Unaffected
Session PDA, fee vault, delegation records
Live on L1 throughout
Reaped on close (rent → owner)
ER block history
Held by the validator
Discarded on close (the L1 state is the canonical artifact)
This is what makes the ER ephemeral: the canonical state lives on L1; the ER is a fast, scoped execution environment that exists only for the session's lifespan.
Per-component failure handling
User goes offline mid-session
No effect — the ER continues until close or TTL.
SDK process dies
Same — restart and reconnect to the same (owner, grid_id).
Router goes down
ER traffic queues at the edge; recovers when the route is restored.
Validator process crashes
The ER stalls. State persists in the validator's WAL. The validator restarts and resumes; if it can't, the owner force-undelegates after TTL.
Validator host fails entirely
Same as above — the operator restores; if recovery is impossible, the owner force-undelegates.
Portal or L1 down
The session's existing ER work isn't blocked — execution continues — but new opens, delegations, and closes wait for L1.
The single-tenant property limits blast radius: any failure is scoped to one session.
See also
Sessions — the session as a first-class object.
Account delegation — what makes an account writable on the ER.
Real-time confirmation — slot cadence and the ER confirmation path.
Security model — how the trust assumptions hold up under adversarial conditions.
Portal program reference — the on-chain ix surface.
Last updated
