session-keys 3.1.1

Gum Session Protocol (GPL Session)
Documentation
 GPL Session
==============

Manage sessions in your Solana Anchor Programs.


# Installation


```bash
cargo add session-keys --features no-entrypoint
```

# Usage

The latest version uses `SessionTokenV2`. `SessionToken` (V1) is still supported for backwards compatibility — see [V1 usage](#v1-backwards-compatible) below.

1. Import the dependencies

```rust
use session_keys::{SessionError, SessionTokenV2, session_auth_or, Session};
```

2. Derive the `Session` trait on your instruction struct. The macro auto-detects V1 vs V2 from the `session_token` field type.

```rust
#[derive(Accounts, Session)]
pub struct Instruction<'info> {
    .....
    pub user: Account<'info, User>,

    #[session(
        // The ephemeral keypair signing the transaction
        signer = signer,
        // The authority of the user account which must have created the session
        authority = user.authority.key()
    )]
    // Session Tokens are passed as optional accounts
    pub session_token: Option<Account<'info, SessionTokenV2>>,

    #[account(mut)]
    pub signer: Signer<'info>,
    .....
}
```

3. Add the `session_auth_or` macro to your instruction handler with fallback logic on who the instruction should validate the signer when sessions are not present and an appropriate ErrorCode. If you've used `require*!` macros in anchor_lang you already know how this works.

```rust
#[session_auth_or(
    ctx.accounts.user.authority.key() == ctx.accounts.authority.key(),
    ErrorCode
)]
pub fn ix_handler(ctx: Context<Instruction>,) -> Result<()> {
.....
}

```

# V1 (backwards-compatible)

To keep using `SessionToken` (V1), import `SessionToken` instead of `SessionTokenV2` and use it as the field type:

```rust
use session_keys::{SessionError, SessionToken, session_auth_or, Session};

#[derive(Accounts, Session)]
pub struct Instruction<'info> {
    ...
    pub session_token: Option<Account<'info, SessionToken>>,
    ...
}
```

`#[derive(Session)]` picks the right trait implementation based on the field type. You can also use `#[derive(SessionV2)]` to require V2 explicitly.

# Full V2 example

A complete Anchor instruction using `SessionTokenV2`:

```rust
use anchor_lang::prelude::*;
use session_keys::{session_auth_or, Session, SessionError, SessionTokenV2};

declare_id!("YourProgramID11111111111111111111111111111111");

#[program]
pub mod my_program {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        let counter = &mut ctx.accounts.counter;
        counter.authority = *ctx.accounts.user.key;
        counter.count = 0;
        Ok(())
    }

    /// Either the session signer (via SessionTokenV2) or the original authority
    /// can call this. If no session token is provided, the fallback check runs.
    #[session_auth_or(
        ctx.accounts.counter.authority.key() == ctx.accounts.signer.key(),
        SessionError::InvalidToken
    )]
    pub fn increment(ctx: Context<Increment>) -> Result<()> {
        ctx.accounts.counter.count += 1;
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub user: Signer<'info>,
    #[account(
        init,
        payer = user,
        space = 8 + 32 + 8,
        seeds = [b"counter", user.key().as_ref()],
        bump,
    )]
    pub counter: Account<'info, Counter>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts, Session)]
pub struct Increment<'info> {
    #[account(mut)]
    pub signer: Signer<'info>,

    #[account(
        mut,
        seeds = [b"counter", counter.authority.key().as_ref()],
        bump,
    )]
    pub counter: Account<'info, Counter>,

    #[session(
        signer = signer,
        authority = counter.authority.key()
    )]
    pub session_token: Option<Account<'info, SessionTokenV2>>,
}

#[account]
pub struct Counter {
    pub authority: Pubkey,
    pub count: u64,
}
```

# More examples

- [magicblock-engine-examples / session-keys]https://github.com/magicblock-labs/magicblock-engine-examples/tree/main/session-keys — Anchor counter program using `SessionTokenV2` with the ephemeral rollups SDK, plus tests and a React frontend.
- [KamikazeJoe]https://github.com/magicblock-labs/Kamikaze-Joe — a game using session-keys.