ShainShain/docs
Shain/Docs/Session helpers
SDK

Session helpers

Pure functions that operate on session snapshots. No network calls, no state — safe to use anywhere in your UI or backend.

snapshotSession

Projects a ShainSession account into a plain-JS snapshot suitable for rendering.

snapshottypescript
import { snapshotSession } from "@shain/sdk";

const account = await client.fetchSession();
if (account) {
  const snap = snapshotSession(account);
  // {
  //   owner: PublicKey,
  //   startedAt: 1744924800,
  //   expiresAt: 1745011200,
  //   active: true,
  //   remainingSeconds: 83700,
  //   actionsCount: 3,
  //   lifetimeSessions: 12
  // }
}

The optional second argument is a wall-clock seconds value; pass it if you want to re-evaluate a cached snapshot against a later moment in time without fetching again.

isSessionActive

isSessionActivetypescript
import { isSessionActive } from "@shain/sdk";

if (snap && isSessionActive(snap)) {
  routePrivate();
} else {
  openSession();
}

Clock-parameterised so you can safely evaluate against a server-supplied time (useful when the client clock is skewed).

formatRemaining

Human-readable countdown. Returns "expired" when the session is over.

formatRemainingtypescript
formatRemaining(snap);
// "23h 41m"  while active
// "7m 14s"   near expiry
// "expired"  after

tagFromCallsite

Deterministic u64 tag for gated_action. Given a (module, fn) pair, always produces the same bigint. Use this when you want per-call-site labeling without maintaining a registry.

tagFromCallsitetypescript
import { tagFromCallsite } from "@shain/sdk";

const tag = tagFromCallsite("dex", "swap_exact_in");
// always the same bigint for this (module, fn)

await client.gatedAction({ tag });

estimateExpiry

Predict expires_at for a session opened right now without fetching the config:

estimateExpirytypescript
import { estimateExpiry } from "@shain/sdk";

const now = Math.floor(Date.now() / 1000);
const expiry = estimateExpiry(now, 86_400);
// now + 86400 seconds

SessionSnapshot shape

types.tstypescript
export interface SessionSnapshot {
  owner: PublicKey;
  startedAt: number;         // unix seconds
  expiresAt: number;         // unix seconds
  active: boolean;           // now < expiresAt
  remainingSeconds: number;  // max(0, expiresAt - now)
  actionsCount: number;      // gated_action fires this session
  lifetimeSessions: number;  // lifetime count for this holder
}