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

@keep-coffee/sdk

v0.2.0

Published

TypeScript SDK for Keep — non-custodial, refundable onchain fundraising on Solana, built for AI builders and agents.

Readme

@keep-coffee/sdk

npm CI License: MIT

Non-custodial, refundable onchain fundraising on Solana — built for AI builders and agents.

Keep lets a builder raise USDC from their users against a fixed target. The SDK builds the transactions; your wallet or agent signs them. The SDK never holds a key and never touches funds — backers pay the contract directly.

0.1.2 — live on Solana mainnet (Keep program v2.4). Pre-1.0: the API may still evolve. Every instruction is byte-checked against the on-chain program.

Why it exists

  • Non-custodial. Backers pay the on-chain program, not a platform wallet. We never hold or move a cent.
  • Refundable on the failure paths only. If a raise doesn't fill, every backer is refunded in full. If it later fails its on-chain price check, the contract refunds them automatically — ~95% at day 7, ~85% at day 30 — funded by the protocol mechanism itself, never a balance sheet.
  • A successful raise is a normal open market afterward — not principal-protected.

Install

npm i @keep-coffee/sdk @solana/web3.js

Quickstart

import { Connection, Keypair } from '@solana/web3.js';
import { KeepClient } from '@keep-coffee/sdk';

const connection = new Connection('https://api.mainnet-beta.solana.com', 'confirmed');
const keep = new KeepClient({ network: 'mainnet', connection });
const wallet = Keypair.fromSecretKey(/* your secret key */); // or any wallet adapter / agent signer

// Read a live raise.
const raise = await keep.getRaise(0);
console.log(raise.state, raise.totalRaised, raise.raiseTarget);

// Back a raise during fundraising (fixed-price, refundable on the failure paths).
const tx = await keep.back(0, { amount: 50_000_000n, backer: wallet.publicKey }); // 50 USDC
const sig = await connection.sendTransaction(tx, [wallet]);

Every write method returns an unsigned Transaction. You add your signer — a Keypair, a browser wallet, or an agent's signer — and send it.

Core API

// Reads
keep.getRaise(projectId)                  // a raise's full on-chain state
keep.listRaises()                         // all raises (decoded; unreadable slots skipped)
keep.listRaises({ strict: true })         // ...or throw if any slot can't be read
keep.listRaisesDetailed()                 // { raises, errors[] } — why each slot was skipped
keep.getPosition(projectId, wallet)       // a backer's deposit position
keep.getClaimPool(projectId)              // the failure-path refund pool
keep.getFactory()                         // global config + next project id
keep.getRiskProfile(projectId)            // agent-friendly action/risk summary
keep.quote(projectId, { side, amountIn }) // expected swap output (to set minOut)

// Start a raise (a builder deploys a launchpad)
keep.createRaise({ owner, mint, name, symbol })  // sign with [owner, mintKeypair]
keep.setMetadata(projectId, { owner, name, symbol, uri })  // Metaplex name/logo
keep.setWhitelistRoot(projectId, { owner, root })          // Private/Hybrid allowlist

// Back, refund, claim (Keep-native, refund-protected)
keep.back(projectId, { amount, backer })        // fund a raise at the fixed price
keep.claimRefund(projectId, { backer })         // refund on a failure / cancel path
keep.claim(projectId, { backer })               // collect your tokens on success

// Trade the graduated market
keep.buy(projectId,  { usdcIn,  minTokenOut, trader })  // open-market swap (Raydium)
keep.sell(projectId, { tokenIn, minUsdcOut,  trader })  // Keep-native in hold, Raydium after

Starting a raise mints a new token, so sign the returned transaction with both the owner and the mint keypair:

import { Keypair } from '@solana/web3.js';

const mint = Keypair.generate(); // optionally vanity-ground to a *keep suffix
const { transaction, projectId } = await keep.createRaise({
  owner: owner.publicKey, mint: mint.publicKey, name: 'My Project', symbol: 'MYP',
});
await connection.sendTransaction(transaction, [owner, mint]);

Every write method returns an unsigned Transaction.

back and buy are different actions, deliberately kept distinct:

  • back happens during the raise, at a fixed price, and carries the failure-path refund protection above.
  • buy is an ordinary open-market swap after the token is trading. It has no refund protection — it's a normal market trade.

The backer's token account is created at back time (keep it)

keep.back(...) returns two instructions: a leading createAssociatedTokenAccountIdempotent for the backer's project-token account, then the deposit. Keep the ATA-create — the on-chain program does not create it (Anchor's in-instruction ATA init overflowed the SBF stack frame), and on success the keeper's automatic token distribution transfers straight into that ATA. The backer pays its rent; the create is idempotent, so it's a no-op if the account already exists.

If you assemble the deposit transaction yourself and drop the ATA-create (or the backer later closes the empty account), that backer is simply skipped by the automatic push and must call keep.claim(projectId, { backer }) themselves — claim recreates the ATA (backer-funded) and pulls their tokens. Funds are never lost, but automatic, zero-click delivery only happens when the ATA exists at distribution time. The keeper never creates ATAs on your behalf.

Networks & versioning

Mainnet only. This SDK targets the Keep program v2.4 and follows semantic versioning — a breaking program upgrade ships as a new SDK major. Reads stay forward-compatible with append-only account growth. For advanced or internal testing against another deployment, pass a custom config to KeepClient.

Use it from an agent

The SDK builds transactions; your agent's signer sends them — so it drops into any agent framework. Full LangChain tools are in examples/langchain-tools.ts:

import { DynamicStructuredTool } from '@langchain/core/tools';
import { Connection, PublicKey } from '@solana/web3.js';
import { KeepClient } from '@keep-coffee/sdk';
import { z } from 'zod';

const keep = new KeepClient({ network: 'mainnet', connection: new Connection(RPC) });

const backTool = new DynamicStructuredTool({
  name: 'keep_back',
  description: 'Build an unsigned transaction to back a Keep raise with USDC.',
  schema: z.object({ projectId: z.number(), usdc: z.string(), backer: z.string() }),
  func: async ({ projectId, usdc, backer }) =>
    (await keep.back(projectId, { amount: BigInt(usdc), backer: new PublicKey(backer) }))
      .serialize({ requireAllSignatures: false }).toString('base64'),
});

For plain-Node usage, see examples/read-and-back.ts.

Agent-launched raises

An agent can create a raise on keep.coffee from a wallet it controls. The protocol does not need a separate "agent identity" path: the wallet that signs is the creator wallet.

The SDK builds the transaction; the agent signs with:

  • the creator wallet keypair
  • a fresh mint keypair for the new project token

Plain Node example:

KEYPAIR=./agent-wallet.json \
PROJECT_NAME="My Agent Project" \
PROJECT_SYMBOL=AGT \
npx tsx examples/agent-create-raise.ts

The example dry-runs by default. To submit the transaction:

SEND=1 \
KEYPAIR=./agent-wallet.json \
PROJECT_NAME="My Agent Project" \
PROJECT_SYMBOL=AGT \
npx tsx examples/agent-create-raise.ts

For tool-calling agents, examples/langchain-tools.ts exports keep_create_raise. It returns a base64 unsigned transaction plus the assigned project id and launchpad address. The caller must sign with both the owner wallet and the mint keypair before sending.

Agent action map

Agents should call getRiskProfile(projectId) before choosing a money action. It returns structured fields such as phase, canBack, canClaimRefund, canClaim, refundPath, refundBpsNow, and marketTradeRefundProtected.

Recommended flow:

const profile = await keep.getRiskProfile(projectId);

if (profile?.canBack) {
  // Fixed-price funding during the raise; failure-path refund protection applies.
  const tx = await keep.back(projectId, { amount, backer });
}

if (profile?.canClaimRefund) {
  // Cancelled, expired, Failed1, or Failed2 path.
  const tx = await keep.claimRefund(projectId, { backer });
}

if (profile?.canClaim) {
  // Successful/trading path: claim tokens, or quote + buy/sell on the market.
  const quote = await keep.quote(projectId, { side: 'buy', amountIn: usdcIn });
  const tx = await keep.buy(projectId, { usdcIn, minTokenOut, trader });
}

The bundled LangChain example exposes these tools:

  • keep_get_raise
  • keep_get_risk_profile
  • keep_quote
  • keep_back
  • keep_claim_refund
  • keep_claim
  • keep_buy
  • keep_sell
  • keep_create_raise

All write tools return unsigned base64 transactions. Your wallet, backend signer, or authorized agent signer remains responsible for signing and sending.

Reusable agent test dashboard

To avoid one-off test scripts, the SDK includes a local dashboard for repeatable agent checks:

npm run agent:dashboard

Open the printed local URL and click Run tests. The dashboard checks:

  • SDK build
  • TypeScript typecheck
  • structural tests
  • live mainnet read decode
  • getRiskProfile(0) read path
  • local agent wallet readiness across Solana devnet, RH testnet, and Arc testnet

Reports are written to .keep-test-runs/latest.json and .keep-test-runs/latest.html, so every run leaves a local artifact that can be reviewed later or compared across conversations.

For a terminal-only run:

npm run test:agent

Use KEEP_RPC=... to override the Solana RPC and KEEP_AGENT_WALLET_DIR=... to point the wallet check at another local test-wallet directory. The dashboard reads wallet files only to derive public keys and balances; it does not submit transactions.

Resources

License

MIT — see LICENSE.