Skip to main content

Why sessions

Reading a confidential balance means decrypting it, and decryption needs the account’s authorization. Without sessions that is a wallet popup on every read. With a session the user signs one voucher, and a throwaway key held in memory decrypts on their behalf until it expires. The SDK handles this for you. The first read asks for a signature, everything after is silent:

Scoping

The voucher names a verifier contract that decides what the session can reach. CTokenSessionVerifier, the SDK default, narrows a session to cToken balances. A leaked session key exposes those and nothing else. A generic SessionVerifier also exists and covers everything the signer can read; prefer the scoped one for anything user-facing. The SDK handles all of this. It only matters if you drive @inco/lightning-js yourself:
Omit requesterArgData against this verifier and the covalidator answers PermissionDenied: advanced acl disallowed. The session is valid, but nothing is in scope.

Safe and smart accounts

Sessions work for ERC-1271 accounts. The voucher signature is checked on-chain, so a Safe signs it through its normal signed-message flow and everything downstream just works. Verified end to end on Base Sepolia. One rule: smart-account users must go through sessions. Direct decrypts without a voucher only accept EOA signatures.

Timing

Ciphertexts are processed asynchronously after a transaction lands. A decrypt right after a transfer can briefly answer “not found, try again”. The SDK retries this automatically, and balancesSettled marks such tokens pending instead of failing, so show a spinner and read again shortly.