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

@infofi/sdk

v0.1.1

Published

TypeScript agent SDK for InfoFi micro prediction markets on HyperEVM (read API + LMSR trading + strategy harness).

Readme

@infofi/sdk

TypeScript agent SDK for InfoFi — AI-powered micro prediction markets on HyperEVM. Read the public indexer, quote and trade against the LMSR market maker, derive your CTF positions, and run a simple polling strategy.

  • Read API — typed wrappers over the public indexer (https://api.infofi.trade).
  • Trading — viem-based: faucet, approve, quote, buy/sell (with slippage), positions, redeem. Quotes come from the on-chain costOfBuy/proceedsOfSell views, so slippage math is exact.
  • Strategy harnesspollMarkets + onMarket, per-market/total budget guard, dry-run mode.
  • CTF helpers — derive ERC-1155 YES/NO position ids off-chain.

Requires Node 22.

Install

Published on npm as @infofi/sdk:

npm install @infofi/sdk
# or
pnpm add @infofi/sdk

Inside this monorepo it is also available as a pnpm workspace package. To build the workspace copy locally:

fnm exec --using=22 pnpm install
fnm exec --using=22 pnpm --filter @infofi/sdk build

The fastest way to try it is the runnable demo app in sdk/ts/examples/agent-demo.ts — see Run the demo app.

Quickstart — read a market, place your first trade

import { ReadClient, TradingClient, shares } from "@infofi/sdk";

// 1. Read the public indexer (no key required).
const read = new ReadClient(); // defaults to https://api.infofi.trade
const { markets } = await read.markets({ status: "open", sort: "active" });
const market = markets[0];
if (!market) throw new Error("no open markets");
console.log(market.code, "· YES", market.yesPrice, "·", market.question ?? "(untitled)");

// 2. Trade on HyperEVM testnet (defaults to the live testnet deployment).
const trader = new TradingClient({ privateKey: process.env.PRIVATE_KEY! });
await trader.faucet();                                   // claim testnet tUSDC (once/day)

const cost = await trader.quoteBuy(market.id, "YES", shares(5));
console.log("5 YES shares ≈", Number(cost) / 1e6, "USDC");

const { hash } = await trader.buy(market.id, "YES", shares(5), { slippageBps: 100 });
console.log("bought:", hash);

// 3. After the market finalizes, redeem your winnings:
//    await trader.redeem(market.id);

Environment for trading:

| Var | Meaning | | ------------- | -------------------------------------------------- | | PRIVATE_KEY | Your signer key (0x…). Fund with testnet HYPE for gas. | | API_URL | Indexer base URL (default https://api.infofi.trade). | | RPC_URL | JSON-RPC (default HyperEVM testnet https://rpc.hyperliquid-testnet.xyz/evm). |

Read API

const read = new ReadClient({ baseUrl: "https://api.infofi.trade" });
await read.health();
await read.markets({ category: "ship-date", status: "open", sort: "closing", limit: 20 });
await read.market("MKT-0004");             // address, MKT-#### code, or offchain code
await read.trades("MKT-0004", { limit: 50 });
await read.series("MKT-0004", { range: "7d", samples: 48 });
await read.positions("MKT-0004");
await read.leaderboard({ limit: 25 });
await read.sources();

Return types mirror the indexer DTOs (MarketSummary, MarketDetail, Trade, Position, LeaderboardEntry, Series, Source, Health). USDC fields are whole-USDC numbers; exact big integers (b, bond amounts) are strings. Integer fields the indexer serializes as strings (seq, tradingDeadline, createdAt, createdBlock, resolution timestamps) are normalized back to numbers.

Trading client

const trader = new TradingClient({
  privateKey: process.env.PRIVATE_KEY!,
  // rpcUrl, chainId, addresses all optional; default to the testnet deployment.
});

await trader.usdcBalanceFormatted();               // collateral balance
await trader.faucet();                             // testnet tUSDC (TestUSDC only)
await trader.approveMarket(market);                // one-time USDC approval (buy() auto-approves)

await trader.quoteBuy(market, "YES", shares(5));   // exact on-chain LMSR cost (base units)
await trader.quoteSell(market, "NO", shares(5));   // exact on-chain LMSR proceeds
await trader.price(market, "YES");                 // spot probability [0,1]

await trader.buy(market, "YES", shares(5), { slippageBps: 100 });
await trader.sell(market, "NO", shares(5), { slippageBps: 100 }); // auto CTF operator-approve
await trader.positionBalances(market);             // { yes, no } ERC-1155 balances
await trader.redeem(market);                       // after FINALIZED

Amounts are 6-decimal base-unit bigints; use usdc() / shares() to build them and fromUsdc() / fromShares() to read them. Outcomes accept "YES", "NO", or the numeric index (0 = YES, 1 = NO).

buy() ensures the USDC allowance; sell() ensures the market is a CTF operator (required — selling merges the outcome pair via the market pulling your tokens). Both apply pool-favorable rounding to the slippage bound.

Fees (09-creator-economics)

Markets can charge a trading fee (genesis 150bps = 120 creator + 30 protocol): the buyer pays LMSR cost + fee, the seller receives LMSR proceeds − fee.

await trader.feeConfig(market);         // { feeBps, creatorFeeBps, protocolFeeBps, source }
await trader.quoteBuyWithFee(market, "YES", shares(5));  // { lmsrCost, fee, total, ... }
await trader.quoteSellWithFee(market, "NO", shares(5));  // { lmsrProceeds, fee, net, ... }

feeConfig() reads the market's on-chain creatorFeeBps/protocolFeeBps views; the currently-live markets are fee-less and don't expose them, so it returns the configured fallback (genesis by default — pass feeConfig: ZERO_FEE_BPS to the client to quote the live markets exactly) tagged source: "fallback". buy()/sell() fold the fee into their slippage bound only when it is really charged on-chain (source: "chain"), so against the live fee-less markets the execution path is unchanged. buy()/sell() results now include fee and total/net. Bake round-trip fees into your edge (docs/09-E3: fee drag eats thin edges) — see the house-trader example.

Strategy harness

import { ReadClient, TradingClient, StrategyHarness, Outcome } from "@infofi/sdk";

const harness = new StrategyHarness({
  read: new ReadClient(),
  trader: new TradingClient({ privateKey: process.env.PRIVATE_KEY! }),
  dryRun: false,                                   // omit trader (or set true) for a dry-run
  intervalMs: 30_000,
  budget: { maxPerMarketUsdc: 10, maxTotalUsdc: 50 },
  marketQuery: { status: "open", sort: "newest", limit: 50 },
});

harness.onMarket(async (ctx) => {
  const { market } = ctx;
  if (Math.abs(market.yesPrice - 0.5) > 0.4) return;
  await ctx.buyUsdc(Outcome.YES, 3);               // budget-guarded; respects dryRun
});

const stop = harness.start();                       // polls now, then every intervalMs
// stop();

The budget guard (ctx.budget) tracks committed cost basis per market and in aggregate and refuses spends beyond either cap. In dry-run it records the same exposure so trade cadence matches a live run.

Demo app

examples/agent-demo.ts is a complete agent example. It polls open markets, asks OpenAI for a calibrated YES probability, compares that probability to the market price, sizes by confidence, then places a budget-guarded trade. It defaults to a one-shot dry-run and will not broadcast unless you provide PRIVATE_KEY and set DRY_RUN=false.

# Install the published package in your agent app.
npm install @infofi/sdk

# Dry-run with no model key: uses DEMO_BIAS around the live market price.
node node_modules/@infofi/sdk/dist/examples/agent-demo.js

# Full OpenAI-backed dry-run.
OPENAI_API_KEY=sk-... \
  node node_modules/@infofi/sdk/dist/examples/agent-demo.js

# Wire in your own model endpoint. It receives { market } and returns { probability }.
MODEL_ENDPOINT=http://localhost:8787/estimate \
  node node_modules/@infofi/sdk/dist/examples/agent-demo.js

# Live testnet trading: fund the key with testnet HYPE for gas first.
OPENAI_API_KEY=sk-... PRIVATE_KEY=0x... DRY_RUN=false RUN_ONCE=false \
  node node_modules/@infofi/sdk/dist/examples/agent-demo.js

From this repo, the same demo can run from source:

fnm exec --using=22 pnpm --filter @infofi/sdk demo-agent

Useful env: OPENAI_API_KEY, OPENAI_MODEL (default gpt-4o-mini), OPENAI_BASE_URL, OPENAI_TEMPERATURE, MODEL_ENDPOINT, PRIVATE_KEY, DRY_RUN, RUN_ONCE, MIN_EDGE (default 0.05), TRADE_USDC (5), BUDGET_USDC (100), MAX_PER_MARKET_USDC (25), API_URL, RPC_URL, CHAIN_ID, INTERVAL_MS, SLIPPAGE_BPS, MARKET_LIMIT, DEMO_BIAS.

Position-id derivation

The YES/NO ERC-1155 position ids are derived off-chain from the Gnosis CTF algorithm (ported from the vendored CTHelpers.sol, including the alt_bn128 collection-id point math). Verified against the live testnet deployment — the derivation reproduces the demo market's on-chain yesPositionId/noPositionId exactly (test/ctf.test.ts golden vectors; test/integration.test.ts checks the on-chain getCollectionId/getPositionId views when a chain is reachable).

import { derivePositionIds } from "@infofi/sdk";
const { yes, no } = derivePositionIds(collateralAddress, conditionId);
// or, straight from a market (reads the stored ids):
await trader.positionIds(market);
await trader.verifyPositionIds(market); // derived === on-chain stored

House-trader bot

examples/house-trader.ts is the transparently-labeled house liquidity agent (docs/00-decisions.md D12): for each open market not already near an edge, it buys a small ($2–5) random-side position, capped by budget and a trades/hour limit, honoring DRY_RUN. It does no forecasting — it is the activity floor.

Config is entirely via env: PRIVATE_KEY, API_URL, RPC_URL, CHAIN_ID, DRY_RUN (default true), BUDGET_USDC (50), MAX_PER_MARKET_USDC (10), TRADE_MIN_USDC (2), TRADE_MAX_USDC (5), MAX_TRADES_PER_HOUR (12), INTERVAL_MS (30000), SLIPPAGE_BPS (100), EDGE_SKIP (0.45), FAUCET_ON_START (false). With no PRIVATE_KEY, it forces DRY_RUN.

Run an agent

# Dry-run (no key, no transactions) — safe to run anywhere:
fnm exec --using=22 pnpm --filter @infofi/sdk build
DRY_RUN=true node sdk/ts/dist/examples/house-trader.js

# …or without building, via tsx:
fnm exec --using=22 pnpm --filter @infofi/sdk exec tsx examples/house-trader.ts

# Live on testnet (fund the key with testnet HYPE for gas first):
PRIVATE_KEY=0x… DRY_RUN=false FAUCET_ON_START=true \
  node sdk/ts/dist/examples/house-trader.js

A Kubernetes Deployment is provided at infra/k8s/house-trader.yaml (1 replica, DRY_RUN=true by default, env from a referenced secret you create).

Addresses

Defaults target the immutable HyperEVM testnet deployment (chain 998; see deployments/testnet.md), exported as TESTNET_ADDRESSES and overridable via the addresses option. TESTNET_DEMO_MARKET is a seeded demo market.

Development

fnm exec --using=22 pnpm --filter @infofi/sdk typecheck
fnm exec --using=22 pnpm --filter @infofi/sdk build
fnm exec --using=22 pnpm --filter @infofi/sdk test        # unit + integration

The integration test verifies position derivation against a live chain and skips cleanly when none is reachable. Point it at a local anvil deployment with INFOFI_RPC_URL / INFOFI_MARKET / INFOFI_CHAIN_ID.

License: BUSL-1.1.