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

@kova-sdk/wallet

v1.0.2

Published

A policy-constrained crypto wallet SDK for autonomous AI agents

Readme


AI agents need to transact on-chain. Without guardrails, a single hallucination or prompt injection can drain a wallet. kova sits between your agent and the blockchain, enforcing spending limits, allowlists, rate limits, time windows, and human approval gates on every transaction before it touches the network.

Agent → Intent → Policy Engine → Build Tx → Sign → Broadcast → Audit Log
                     ↓ DENY
                 Circuit Breaker

Why kova

  • Your agent says "send 100 SOL" but your policy caps it at 5 SOL per transaction — denied.
  • Your agent tries to send funds to an unknown address — denied by allowlist.
  • A prompt injection tricks your agent into rapid-fire transfers — denied by rate limit, then circuit breaker kicks in.
  • A high-value transaction needs human sign-off — held until approved via webhook or custom callback.
  • Every transaction, approved or denied, is recorded in a tamper-evident audit log.

Features

| Category | Details | |----------|---------| | Policy Engine | 5 composable rules, deny-by-default, fail-closed, two-phase evaluation | | Spending Limits | Per-transaction, daily, weekly, monthly caps (per-token and USD via Pyth oracle) | | Address Allowlist | Restrict transfers to approved addresses/programs; denylist support | | Rate Limiting | Max transactions per minute/hour with store-backed counters | | Time Windows | Restrict to business hours (timezone-aware, multiple windows) | | Approval Gates | Human-in-the-loop via webhook or custom callback for high-value transactions | | MCP Server | Agents interact via Model Context Protocol — framework-agnostic (Claude, OpenAI, LangChain, any MCP client) | | Signers | LocalSigner (dev), MpcSigner with Turnkey provider (production) | | Stores | MemoryStore (dev), SqliteStore (single server), RedisStore (multi-server) | | Solana | SOL transfers, SPL tokens with ATA creation, transaction simulation | | Oracles | Pyth on-chain price feeds, multi-oracle consensus provider | | Audit Log | SHA-256 hash-chained with HMAC per-entry integrity, checkpoint hashing | | Circuit Breaker | Auto-cooldown after consecutive denials, single-process lock enforcement | | Security | Store operation timeouts, timing side-channel resistance, error sanitization |

Important

ESM-only — kova is published as ES modules only. Use import, not require(). Your tsconfig.json should have "module": "Node16" and "moduleResolution": "Node16".

Single-instance deployment — The SDK's mutex, circuit breaker, idempotency cache, and spending counters are designed for a single Node.js process per store. Running multiple processes against the same store without external distributed locking can cause TOCTOU races, spending limit bypasses, and audit log inconsistencies. For multi-process deployments, use RedisStore with per-instance storePrefix, or implement external coordination (e.g., Redis Redlock).

Native dependencies are optionalbetter-sqlite3 (for SqliteStore) and ioredis (for RedisStore) are optional peer dependencies. Install only what you need. better-sqlite3 requires C++ build tools (see Installation). If you only need MemoryStore for development, no native dependencies are required.

Quick Start

Install

npm install @kova-sdk/wallet

For persistent storage (single server):

npm install better-sqlite3          # requires C++ build tools

For multi-server deployments:

npm install ioredis

Minimal example

import { Keypair } from "@solana/web3.js";
import {
  AgentWallet, Policy, LocalSigner, MemoryStore, SolanaAdapter,
} from "@kova-sdk/wallet";

const signer = new LocalSigner(Keypair.generate());
const store  = new MemoryStore();
const chain  = new SolanaAdapter({ rpcUrl: "https://api.devnet.solana.com", network: "devnet" });

const policy = Policy.create("demo")
  .spendingLimit({ perTransaction: { amount: "1", token: "SOL" }, daily: { amount: "5", token: "SOL" } })
  .rateLimit({ maxTransactionsPerMinute: 5 })
  .build();

const wallet = new AgentWallet({ signer, chain, policy, store });

const result = await wallet.execute({
  type: "transfer",
  chain: "solana",
  params: { to: "GsbwXfJraMomNxBcjYLcG3mxkBUiyWXAB32fGbSQQRre", amount: "0.5", token: "SOL" },
});

console.log(result.status);  // "confirmed" | "denied" | "pending" | "failed"

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                         AgentWallet                             │
│                                                                 │
│  ┌──────────┐  ┌──────────────┐  ┌─────────┐  ┌────────────┐  │
│  │  Signer  │  │ Policy Engine │  │  Store  │  │   Chain    │  │
│  │          │  │              │  │         │  │  Adapter   │  │
│  │ Local    │  │ SpendingLimit│  │ Memory  │  │            │  │
│  │ MPC      │  │ Allowlist    │  │ SQLite  │  │  Solana    │  │
│  │ Turnkey  │  │ RateLimit    │  │ Redis   │  │  (more     │  │
│  │          │  │ TimeWindow   │  │ Prefixed│  │   coming)  │  │
│  │          │  │ ApprovalGate │  │         │  │            │  │
│  └──────────┘  └──────────────┘  └─────────┘  └────────────┘  │
│                                                                 │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────┐  │
│  │  Audit Log   │  │   Circuit    │  │    MCP Server        │  │
│  │  (hash-chain)│  │   Breaker    │  │  (Model Context      │  │
│  │              │  │              │  │   Protocol)           │  │
│  └──────────────┘  └──────────────┘  └──────────────────────┘  │
│                                                                 │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  Oracles: Pyth price feeds · Multi-oracle consensus     │  │
│  └──────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

Every call to wallet.execute(intent) follows this pipeline:

  1. Validate the intent structure and parameters
  2. Check audit log integrity (fail-closed if tampered)
  3. Circuit breaker check (auto-cooldown after consecutive denials)
  4. Policy engine evaluates rules sequentially — first DENY stops execution
  5. Build transaction via the chain adapter
  6. Sign via the signer (key material never touches policy or chain layers)
  7. Broadcast to the network
  8. Log the result to the hash-chained audit trail

Policy Engine

Compose rules to match your risk profile. Rules are evaluated in order — the first DENY stops execution.

const policy = Policy.create("production")
  .spendingLimit({
    perTransaction: { amount: "10", token: "SOL" },
    daily: { amount: "50", token: "SOL" },
  })
  .allowAddresses(["addr1", "addr2"])
  .rateLimit({ maxTransactionsPerMinute: 5 })
  .activeHours({
    timezone: "America/New_York",
    windows: [{ days: ["mon", "tue", "wed", "thu", "fri"], start: "09:00", end: "17:00" }],
  })
  .requireApproval({ above: { amount: "25", token: "SOL" } })
  .build();

| Rule | What it does | |------|-------------| | SpendingLimit | Per-transaction, daily, weekly, monthly caps. Rolling TTL windows with BigInt precision. USD limits via Pyth oracle. | | Allowlist | Restrict to approved addresses/programs/tokens. Separate denylist support. | | RateLimit | Max transactions per minute/hour. Store-backed counters. | | TimeWindow | Restrict to business hours. Timezone-aware, multiple windows per day. | | ApprovalGate | Require human approval above a threshold. Webhook or custom callback with intent hash binding. |

Policies use two-phase evaluation: a dry-run phase prevents counter inflation on denied transactions, so a denied spend doesn't eat into your rate limit or spending budget.

Policies are fully serializable:

const json = policy.toJSON();                                    // save as JSON
const loaded = Policy.fromJSON(json);                            // reconstruct later
const stricter = Policy.extend(policy, "strict").spendingLimit({ ... }).build();  // extend

AI Integration

Agents interact with the wallet exclusively through an MCP (Model Context Protocol) server. Any AI framework that supports MCP — Claude, OpenAI, LangChain, or custom agents — can connect. Policy enforcement happens automatically on every tool call.

import { Keypair } from "@solana/web3.js";
import {
  AgentWallet, Policy, LocalSigner, MemoryStore, SolanaAdapter,
  createMcpServer,
} from "@kova-sdk/wallet";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const wallet = new AgentWallet({ signer, chain, policy, store });

// Start the MCP server — agents connect via stdio (or any MCP transport)
const server = createMcpServer(wallet);
await server.connect(new StdioServerTransport());

Or use the convenience helper:

import { createMcpStdioServer } from "@kova-sdk/wallet";

const server = await createMcpStdioServer(wallet);
// Server is now running and accepting tool calls via stdio

Available tools

| Tool | Description | |------|-------------| | wallet_transfer | Transfer SOL, USDC, or USDT | | wallet_swap | Swap tokens (requires pre-built swap transaction) | | wallet_mint | Mint NFTs from a collection | | wallet_stake | Stake tokens with a validator | | wallet_get_balance | Query wallet balance for a token | | wallet_get_all_balances | Query all token balances in one call | | wallet_get_policy | View current policy rules and constraints | | wallet_get_spending_remaining | Check remaining budget per spending window | | wallet_get_supported_tokens | List supported tokens with mint addresses | | wallet_get_address | Get the wallet's public address | | wallet_get_token_price | Get current USD price from oracle | | wallet_estimate_fee | Estimate network fee before sending | | wallet_get_transaction_history | Query past transactions | | wallet_get_transaction_status | Check transaction confirmation status | | wallet_execute_custom | Raw on-chain instructions (opt-in, dangerous) |

Default tools: All read tools are enabled by default. Write operations (wallet_transfer, etc.) must be explicitly enabled via enabledTools. Only wallet_execute_custom requires the includeDangerous flag.

Signers

| Signer | Use case | |--------|----------| | LocalSigner | Development. In-memory Ed25519 signing. Guarded against production use. | | MpcSigner | Production. Hardware-backed signing via pluggable providers. Retry with backoff, configurable timeout, cancellation via AbortSignal. | | TurnkeyProvider | MPC provider for Turnkey. Drop-in for MpcSigner. |

The Signer interface is minimal — getAddress(), sign(), healthCheck(), destroy() — so you can implement your own provider for Fireblocks, Lit Protocol, or any other MPC backend.

Stores

| Store | Use case | |-------|----------| | MemoryStore | Development. In-memory, data lost on exit. Guarded against production. | | SqliteStore | Production (single server). Persistent, WAL mode, HMAC-protected counters. Requires better-sqlite3. | | RedisStore | Production (multi-server). AES-256-GCM encryption at rest, HMAC counter integrity, optional TLS enforcement. Requires ioredis. | | PrefixedStore | Multi-wallet. Wraps any store, namespaces keys per wallet to prevent counter collisions. |

Floating-point precision note: MemoryStore counters use IEEE 754 doubles, which can accumulate drift over many increments. For high-precision accounting, prefer SqliteStore (native numeric types) or RedisStore (INCRBYFLOAT).

Approval Channels

| Channel | How it works | |---------|-------------| | WebhookApprovalChannel | POSTs HMAC-SHA256 signed approval requests to your endpoint. SSRF protection with private IP blocking. Configurable timeout (default 5 min). | | CallbackApprovalChannel | Developer-provided callbacks for custom approval flows — Slack, Discord, email, push notifications, or any other channel. |

The ApprovalChannel interface (requestApproval()) is open for custom implementations.

Oracles

| Provider | How it works | |----------|-------------| | createPythPriceProvider | Reads Pyth on-chain price feeds directly from Solana RPC. In-memory TTL cache, staleness and confidence validation, fail-closed on error. | | createConsensusProvider | Multi-oracle aggregation with median or first-success fallback strategy. Resistant to single-source price manipulation. |

Oracles power USD-denominated spending limits in the policy engine.

Security

| Protection | Implementation | |------------|---------------| | Fail-closed | Exceptions in policy rules deny the transaction. Audit log failures block all transactions. | | Two-phase evaluation | Dry-run prevents counter inflation on denied transactions. | | Circuit breaker | Consecutive denials trigger automatic cooldown with single-process lock enforcement. | | Hash-chained audit | SHA-256 linked entries with per-entry HMAC, checkpoint hashing every 1000 entries, verifyIntegrity() tamper detection. | | Serialized execution | FIFO async mutex prevents TOCTOU race conditions. | | Approval integrity | SHA-256 intent hashing prevents TOCTOU between approval and execution. | | DNS pinning | SSRF and DNS rebinding protection for RPC endpoints. | | Store timeouts | All store operations wrapped with configurable timeout (default 5s). | | Timing resistance | Configurable minEvaluationTimeMs pads policy evaluation to mask rule count and denial source. | | Idempotency | Duplicate intent IDs return cached results. | | Error sanitization | Errors are sanitized before returning to agents — no policy reconnaissance. | | Counter integrity | HMAC-protected store counters detect tampering. |

Report vulnerabilities via GitHub Security Advisory.

Project Structure

kova/
├── src/
│   ├── core/           # AgentWallet, intents, results, circuit breaker
│   ├── policy/         # Policy builder, engine, and 5 rule implementations
│   ├── signers/        # LocalSigner, MpcSigner, TurnkeyProvider
│   ├── stores/         # MemoryStore, SqliteStore, RedisStore, PrefixedStore
│   ├── chains/solana/  # SolanaAdapter, SOL + SPL token transfers
│   ├── approval/       # WebhookApprovalChannel, CallbackApprovalChannel
│   ├── adapters/       # MCP server adapter (sole agent interface)
│   ├── oracles/        # Pyth price feeds, consensus provider
│   └── logging/        # Hash-chained audit logger
├── tests/              # 1,281 unit and integration tests
└── docs-site/          # VitePress documentation

Development

git clone https://github.com/kova-wallet/kova.git
cd kova
npm install
npm run typecheck       # type checking
npm run lint            # eslint
npx vitest run          # run all tests
npm run build           # compile to dist/

License

MIT — see LICENSE.