npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

seal-wallet-sdk

v0.1.1

Published

TypeScript SDK for the Seal smart wallet on Solana

Downloads

233

Readme

seal-wallet-sdk

TypeScript SDK for the Seal Smart Wallet on Solana.

Seal enables autonomous agent capabilities with on-chain spending limits and scoped permissions. Perfect for AI agents, trading bots, and automated workflows.

Installation

npm install seal-wallet-sdk @solana/web3.js

Quick Start

import { SealClient, solToLamports } from "seal-wallet-sdk";
import { Keypair } from "@solana/web3.js";

// Initialize client
const client = new SealClient({ network: "devnet" });

// Load your owner keypair
const owner = Keypair.fromSecretKey(/* your secret key */);

// Create a smart wallet with spending limits
const wallet = await client.createWallet(owner, {
  dailyLimitSol: 10,  // Max 10 SOL per day
  perTxLimitSol: 1,   // Max 1 SOL per transaction
});

console.log("Wallet created:", wallet.address.toBase58());

Architecture Overview

flowchart TD
  W["SmartWallet PDA<br/>owner + pda_authority<br/>wallet spending limits<br/>guardian set + recovery threshold"]
  A["AgentConfig PDA<br/>agent identity<br/>program allowlist<br/>agent spending limits"]
  S["SessionKey PDA<br/>ephemeral signer<br/>expiry + budget caps<br/>revocable by owner or agent"]

  W -->|registers| A
  A -->|creates| S

Full Workflow Example

import {
  SealClient,
  solToLamports,
} from "seal-wallet-sdk";
import { Keypair, PublicKey } from "@solana/web3.js";

async function main() {
  // 1. Initialize
  const client = new SealClient({ network: "devnet" });
  const owner = Keypair.generate();
  const agent = Keypair.generate();

  // 2. Create wallet with limits
  const wallet = await client.createWallet(owner, {
    dailyLimitSol: 10,
    perTxLimitSol: 2,
  });
  console.log("Wallet:", wallet.address.toBase58());

  // 3. Register an agent with scoped permissions
  const agentConfig = await client.registerAgent(owner, agent.publicKey, {
    name: "Trading Bot",
    dailyLimitSol: 5,     // Agent limited to 5 SOL/day (less than wallet)
    perTxLimitSol: 0.5,   // Agent limited to 0.5 SOL/tx
    allowedPrograms: [    // Only allow specific programs
      new PublicKey("JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"),
    ],
    blockAllExceptAllowed: true, // Strict mode
  });
  console.log("Agent registered:", agentConfig.agent.toBase58());

  // 4. Agent creates a time/amount-limited session
  const { sessionKeypair, session } = await client.createSession(
    agent,
    owner.publicKey,
    {
      durationSecs: 3600,          // 1 hour session
      maxAmountLamports: solToLamports(1),   // Max 1 SOL total
      maxPerTxLamports: solToLamports(0.1),  // Max 0.1 SOL per tx
    }
  );
  console.log("Session created, expires:", new Date(Number(session.expiresAt) * 1000));

  // 5. Agent executes a transaction via session
  // (The session keypair signs, Seal validates and CPIs)
  const MEMO_PROGRAM = new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr");
  const signature = await client.executeViaSession(
    sessionKeypair,
    owner.publicKey,
    agent.publicKey,
    MEMO_PROGRAM,
    BigInt(0), // No SOL transfer, just a memo
    Buffer.from("Hello from autonomous agent!"),
    [], // No additional accounts needed for memo
  );
  console.log("Executed:", signature);

  // 6. Owner can revoke session at any time
  await client.revokeSession(
    owner,
    owner.publicKey,
    agent.publicKey,
    sessionKeypair.publicKey
  );
  console.log("Session revoked");

  // 7. Owner can deregister agent (returns rent)
  await client.deregisterAgent(owner, agent.publicKey);
  console.log("Agent deregistered");

  // 8. Owner can close wallet (after all agents removed)
  await client.closeWallet(owner);
  console.log("Wallet closed, rent returned");
}

main().catch(console.error);

API Reference

SealClient

const client = new SealClient({
  network?: "mainnet" | "devnet" | "localnet",  // Default: "devnet"
  rpcUrl?: string,                              // Custom RPC URL
  programId?: PublicKey,                        // Custom program ID
  commitment?: "processed" | "confirmed" | "finalized",
});

Wallet Operations

// Create a new smart wallet
const wallet = await client.createWallet(owner: Keypair, options: {
  dailyLimitSol: number,
  perTxLimitSol: number,
}): Promise<SmartWallet>;

// Get wallet by PDA
const wallet = await client.getWallet(address: PublicKey): Promise<SmartWallet>;

// Update spending limits
const wallet = await client.updateSpendingLimits(
  owner: Keypair,
  newDailyLimitSol: number,
  newPerTxLimitSol: number,
): Promise<SmartWallet>;

// Add a guardian for recovery
const wallet = await client.addGuardian(
  owner: Keypair,
  guardian: PublicKey,
): Promise<SmartWallet>;

// Close wallet (returns rent)
await client.closeWallet(owner: Keypair): Promise<void>;

Agent Operations

// Register an agent
const agentConfig = await client.registerAgent(
  owner: Keypair,
  agent: PublicKey,
  options: {
    name: string,
    dailyLimitSol: number,
    perTxLimitSol: number,
    allowedPrograms?: PublicKey[],
    blockAllExceptAllowed?: boolean,
  },
): Promise<AgentConfig>;

// Get agent config
const agentConfig = await client.getAgentConfig(address: PublicKey): Promise<AgentConfig>;

// Deregister agent (returns rent)
await client.deregisterAgent(owner: Keypair, agent: PublicKey): Promise<void>;

Session Operations

// Create a session (agent creates)
const { sessionKeypair, session } = await client.createSession(
  agent: Keypair,
  walletOwner: PublicKey,
  options: {
    durationSecs?: number,           // Default: 24 hours
    maxAmountLamports?: bigint,      // Total session budget
    maxPerTxLamports?: bigint,       // Per-transaction limit
  },
): Promise<{ sessionKeypair: Keypair; session: SessionKey }>;

// Get session
const session = await client.getSession(address: PublicKey): Promise<SessionKey>;

// Revoke session (owner or agent)
await client.revokeSession(
  authority: Keypair,
  walletOwner: PublicKey,
  agent: PublicKey,
  sessionPubkey: PublicKey,
): Promise<void>;

Execute Operations

// Execute via session (the core agent operation)
const signature = await client.executeViaSession(
  sessionKeypair: Keypair,
  walletOwner: PublicKey,
  agent: PublicKey,
  targetProgram: PublicKey,
  amountLamports: bigint,
  innerInstructionData: Buffer,
  remainingAccounts: { pubkey: PublicKey; isSigner: boolean; isWritable: boolean }[],
): Promise<string>;

Recovery Operations

// Recover wallet (guardian quorum rotates owner)
const wallet = await client.recoverWallet(
  guardians: Keypair[],
  walletOwner: PublicKey,
  newOwner: PublicKey,
): Promise<SmartWallet>;

Low-Level Instruction Builders

For advanced usage, you can build instructions directly:

import {
  createWalletInstruction,
  registerAgentInstruction,
  createSessionInstruction,
  executeViaSessionInstruction,
  revokeSessionInstruction,
  updateSpendingLimitInstruction,
  addGuardianInstruction,
  deregisterAgentInstruction,
  recoverWalletInstruction,
  closeWalletInstruction,
  solToLamports,
} from "seal-wallet-sdk";

PDA Derivation

import { deriveWalletPda, deriveAgentPda, deriveSessionPda } from "seal-wallet-sdk";

const [walletPda, walletBump] = deriveWalletPda(ownerPubkey);
const [agentPda, agentBump] = deriveAgentPda(walletPda, agentPubkey);
const [sessionPda, sessionBump] = deriveSessionPda(walletPda, agentPubkey, sessionPubkey);

Types

interface SmartWallet {
  address: PublicKey;
  owner: PublicKey;
  bump: number;
  isLocked: boolean;
  isClosed: boolean;
  guardians: PublicKey[];
  guardianCount: number;
  dailyLimitLamports: bigint;
  perTxLimitLamports: bigint;
  todaySpentLamports: bigint;
  lastResetTimestamp: bigint;
  agentCount: number;
}

interface AgentConfig {
  address: PublicKey;
  wallet: PublicKey;
  agent: PublicKey;
  name: string;
  bump: number;
  isActive: boolean;
  blockAllExceptAllowed: boolean;
  allowedPrograms: PublicKey[];
  dailyLimitLamports: bigint;
  perTxLimitLamports: bigint;
  txCount: bigint;
  totalSpent: bigint;
  createdAt: bigint;
}

interface SessionKey {
  address: PublicKey;
  wallet: PublicKey;
  agent: PublicKey;
  sessionPubkey: PublicKey;
  bump: number;
  isRevoked: boolean;
  expiresAt: bigint;
  maxAmountLamports: bigint;
  maxPerTxLamports: bigint;
  amountSpent: bigint;
}

Security Considerations

Guardian Recovery

Seal supports guardian-based recovery with a configurable recovery_threshold. New wallets start with recovery_threshold = 1, so if you add multiple guardians and want multi-party approval, set the threshold explicitly after setup.

See SECURITY.md for full details.

Spending Limits

Limits are enforced at three levels (most restrictive wins):

  1. Wallet-level: Set by owner
  2. Agent-level: Set by owner when registering agent
  3. Session-level: Set by agent when creating session

Session Security

  • Sessions have an expiry timestamp
  • Sessions have a total budget and per-tx limit
  • Owner or agent can revoke sessions instantly
  • Session keys are ephemeral keypairs

Testing

# Run SDK tests
npm test

# Run with coverage
npm run test:coverage

License

Apache-2.0