Sessions

Prepaid channels that enable efficient multi-request transactions

What is a Session?

A Session is a prepaid channel between an agent and provider. Instead of paying for each request individually, the agent deposits funds once and can make multiple requests with automatic balance deduction.

πŸ’‘ Key Benefit
50x fewer blockchain transactions! One session creation tx + one close tx = supports 100+ requests. Traditional per-request model would need 100 transactions.

Session States

ACTIVE
Session is live, balance sufficient, can make requests
DEPLETED
Balance too low for another request, needs refill or close
EXPIRED
Time limit reached, can no longer make requests
REFUNDED
Session closed, remaining balance returned to agent
STATE TRANSITIONS
State Diagram:
─────────────

         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚ PENDING β”‚ (Initial creation)
         β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
              β”‚
         β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”
    β”Œβ”€β”€β”€β–Ί  ACTIVE  β”œβ”€β”€β”€β”
    β”‚    β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜   β”‚
    β”‚         β”‚        β”‚
    β”‚         β”‚        β”‚
Refill   β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”    β”‚ Depleted
    β”‚    β”‚DEPLETEDβ”‚β—„β”€β”€β”€β”˜
    └─────        β”‚
         β””β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
             β”‚
         β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”
         β”‚EXPIRED β”‚ (Time limit reached)
         β””β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
             β”‚
         β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”
         β”‚REFUNDEDβ”‚ (Closed & refunded)
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜

State Transitions:
──────────────────
PENDING  β†’ ACTIVE    (on successful creation)
ACTIVE   β†’ DEPLETED  (balance < pricePerRequest)
ACTIVE   β†’ EXPIRED   (current time > expiresAt)
DEPLETED β†’ REFUNDED  (on close)
EXPIRED  β†’ REFUNDED  (on close)
ACTIVE   β†’ REFUNDED  (on manual close)

Session Structure

interface Session {
  // Identity
  sessionId: string;
  offerId: string;              // Based on accepted Offer
  agentPubkey: string;
  providerPubkey: string;
  
  // Financial
  token: SupportedToken;
  depositAmount: number;         // Initially deposited
  remainingBalance: number;      // Current balance
  pricePerRequest: number;       // Cost per request
  
  // Timing
  startedAt: number;             // Creation timestamp
  expiresAt: number;             // Expiration timestamp
  
  // Guarantees
  sla: SLA;                      // SLA terms
  
  // State
  state: SessionState;           // Current state
  requestCount: number;          // Requests made
  
  // Optional On-Chain
  creationTxSignature?: string;  // Solana tx
  pdaAddress?: string;           // On-chain PDA
  
  metadata?: Record<string, any>;
}

Balance Management

How Balance Works
// Initial state
const session = {
  depositAmount: 1.0,        // Deposited 1 USDC
  remainingBalance: 1.0,     // Full balance
  pricePerRequest: 0.008,    // Each request costs 0.008
  requestCount: 0
};

// After Request #1
session.remainingBalance = 0.992;  // 1.0 - 0.008
session.requestCount = 1;

// After Request #2  
session.remainingBalance = 0.984;  // 0.992 - 0.008
session.requestCount = 2;

// ... continues ...

// After Request #125
session.remainingBalance = 0;      // Depleted!
session.requestCount = 125;
session.state = "depleted";

// Total requests possible:
Math.floor(depositAmount / pricePerRequest)
// = Math.floor(1.0 / 0.008)
// = 125 requests

Creating a Session

SESSION CREATION FLOW
1.
Agent calls createSession() and transfers funds to provider on Solana
2.
Provider waits for transaction confirmation
3.
Provider verifies correct amount and sender
4.
Provider creates Session object with balance tracking
5.
Session returned to agent - ready to make requests!
const session = await client.createSession(offer, {
  depositAmount: 1.0,      // How much to deposit
  anchorOnChain: true      // Optional: store on Solana
});

// What happens:
// 1. Agent transfers 1.0 USDC to provider on Solana
// 2. Provider waits for transaction confirmation
// 3. Provider verifies amount and sender
// 4. Provider creates Session object
// 5. Session returned to agent
// 6. Agent can now make requests!

Monitoring Sessions

// Check session status
const session = client.getSession(sessionId);

console.log('Balance:', session.remainingBalance);
console.log('Requests made:', session.requestCount);
console.log('Requests remaining:', 
  Math.floor(session.remainingBalance / session.pricePerRequest)
);
console.log('Expires:', new Date(session.expiresAt));
console.log('State:', session.state);

// Auto-refill when low
if (session.remainingBalance < 0.01) {
  console.log('Low balance, closing and creating new session...');
  await client.closeSession(sessionId);
  await createNewSession();
}

Closing Sessions

Close Session & Get Refund
const refund = await client.closeSession(sessionId);

console.log('Refunded:', refund.refundAmount, session.token);
console.log('Transaction:', refund.txSignature);

// Example calculation:
// Deposit: 1.0 USDC
// Used: 0.24 USDC (30 requests Γ— 0.008)
// Refund: 0.76 USDC

// Refund is automatic and fair!
X (Twitter)