ShainShain/docs
Shain/Docs/Overview
Getting started

Overview

A conceptual map of the system. Read this before diving into the Engine or SDK sections.

The three actors

Every Shain session involves three actors on-chain:

  • Holder — a Solana wallet holding at least the minimum balance of $SHAIN. Holders sign their own transactions; Shain never custodies keys.
  • Program — the deployed Anchor program. Owns two PDA types (config singleton, per-holder session) and arbitrates entry into the private route.
  • Treasury — a PDA-owned associated token account that receives session fees. Accrues balance over time; disposition rules are documented in the program itself.

The session lifecycle

  1. Holder checks that their wallet carries ≥ min_holding of $SHAIN.
  2. Holder signs start_session() — the program transfers session_feefrom the holder's token account to the treasury ATA and writes a ShainSession PDA with expires_at = now + 24h.
  3. For the next 24 hours, any dapp may gate a private call behind gated_action(tag). The program asserts the session is still live and increments the caller's action counter.
  4. After expiry, any signer may call close_session(). The session PDA is closed and its rent lamports are refunded to the session owner.

What gated_action does

gated_action(tag: u64)is the integration hook. It does exactly one thing on-chain: it asserts that the caller has a session that is not yet expired, then increments the session's action counter for instrumentation.

The tag is an opaque u64. Shain itself does not interpret it — integrating dapps use it to label call sites, the same way you'd use log keys. Use the SDK's tagFromCallsite(module, fn) helper for a stable deterministic value without managing a registry.

on-chain signaturerust
pub fn gated_action(ctx: Context<GatedAction>, tag: u64) -> Result<()>;

// Accounts:
// [signer]  user              — must match session.owner
// [writable] shain_session    — PDA [b"shain_session", user.key().as_ref()]

What the contract knows

The config PDA ShainConfig carries the global parameters the authority seeded at deployment:

FieldTypeDefaultRole
session_durationi6486400 (24h)Window length in seconds
session_feeu641_000_000Fee charged on open, in base units
min_holdingu6410_000_000Required balance to open
total_sessionsu640Lifetime counter across all holders
total_fees_collectedu640Running treasury accrual

These are all set once at initialize time and are not adjustable through any other instruction.

What Shain does not do

  • It does not mix tokens. There is no pool, no commitment tree, no relayer. Your balances stay in your wallet.
  • It does not anonymize you. Your wallet address remains attributable. What Shain attenuates is the ability of mempool watchers to correlate your actions during the session window.
  • It does not give you privacy forever. Sessions expire. This is a feature — the goal is trading without a parasite, not anonymity as an identity.

Next