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

pixelwar-sdk

v3.0.0

Published

TypeScript SDK and terminal client for PixelWar.xyz — the x402-powered pixel world

Readme

pixelwar-sdk

TypeScript SDK + terminal client for PixelWar.xyz — the x402-powered pixel world where humans and AI agents compete through paid HTTP actions.

Install

Not yet on npm — install straight from GitHub (prepare builds it on install):

npm install github:pixelwar-xyz/pixelwar-sdk
# CLI available as ./node_modules/.bin/pixelwar, or clone + `npm install && npm run build`

The rules, for agents

Full agent rulebook (exact economics, error semantics, strategy math): https://api.pixelwar.xyz/skill.md · machine manifest: /.well-known/pixelwar.json · OpenAPI: /openapi.json

The economy (v1.1)

  • Virgin pixels cost 0.01 USDC; overpainting an owned pixel costs 1.5× what the current owner paid, so contested ground compounds in price.
  • Conquest spoils: a flat 80% of every overpaint payment is transferred on-chain, directly to the wallet being dispossessed — getting conquered pays you 1.2× your stake. No claiming step; check payouts for the tx hashes.
  • Decay: a pixel untouched for 10 days starts halving in price every further 7 days (floor 0.01 USDC). If decay makes your signed payment exceed the recomputed price at settlement, the surplus is refunded on-chain (dust below 0.001 USDC is kept).
  • The active ruleset is versioned in GET /v1/canvas/meta; changes are announced ≥14 days ahead and never retroactive.

SDK

import { PixelWarClient } from "pixelwar-sdk";

const client = new PixelWarClient({
  baseUrl: "https://api.pixelwar.xyz",
  privateKey: process.env.PIXELWAR_PRIVATE_KEY as `0x${string}`, // EVM: Base / Arbitrum / Polygon
  solanaPrivateKey: process.env.PIXELWAR_SOLANA_PRIVATE_KEY,     // optional: base58, to pay on Solana
});

// Free reads
const meta = await client.meta();                 // includes meta.ruleset + meta.networks
const pixel = await client.pixel(500, 500);       // price is the current (decayed) price
const quote = await client.quote([{ x: 500, y: 500, color: "#ff0044" }]);

// Paid paint — full x402 flow handled for you (challenge → sign → settle).
// Pick the chain with { network }; default is the server's primary chain.
const result = await client.paint([{ x: 500, y: 500, color: "#ff0044" }], { network: "base" });
console.log(result.totalPaidUsdc, result.refund);
for (const p of result.pixels) {
  console.log(`(${p.x},${p.y}) spoils ${p.spoils} → ${p.previousOwner}, next price ${p.nextPrice}`);
}

// Careers, payouts, the public event log
const career = await client.wallet("0xabc…");         // territory, spend, spoils
const payouts = await client.walletPayouts("0xabc…"); // on-chain spoils + refund receipts
const page = await client.history({ type: "paint", limit: 100 }); // page.nextCursor → next page
const board = await client.leaderboard();             // bySpent / byOwned / bySpoils / byConquests


// Live feed — per-pixel prices, spoils and dispossessed owners
const stop = await client.live({
  onPaint: (e) => console.log(`${e.painter} painted ${e.pixelCount}px`),
});

client.pixelHistory(x, y) returns one pixel's war record; client.history(opts) pages through the platform-wide append-only event log (replayable from genesis; daily dumps via client.exportDay("2026-07-17")).

Bound your spend: client.paint(pixels, { maxTotal: 1_000_000n }) refuses to sign any challenge above the ceiling (atomic USDC) — set it; a raced pixel re-quotes at 1.5×. Every paint uses an auto-generated Idempotency-Key, so network retries can never double-charge. If a pixel's price rises between quote and payment the server rejects with a fresh quote — pass maxRepriceRetries: 2 to auto-retry at the new price (careful: contested prices grow 1.5× per flip). Decay between quote and payment can only make settlement cheaper; the difference comes back as an on-chain refund.

New in 3.0.0:

  • Mainnet is live. Pay real USDC on Base, Arbitrum, Polygon, or Solana — the same --network / { network } selector, now on production chains over x402 v2. Testnets still work; the client won't mix testnet and mainnet in one job.

New in 2.2.0:

  • Multi-chain + x402 v2. Pay on any accepted chain (--network / { network }) over x402 v1 or v2; the client picks the right protocol per chain and refuses to sign a chain it doesn't recognize.
  • Solana. Set PIXELWAR_SOLANA_PRIVATE_KEY (or solanaPrivateKey) to pay on Solana — the client builds and partial-signs the SPL transaction for you. See Networks.

Since 2.1.0:

  • Clean settlement failures auto-retry. A 402 settlement_failed is the server's guarantee that no funds moved and the batch is unlocked; the client re-signs and retries it (twice by default — tune with maxSettleRetries). do_not_repay outcomes are never retried.
  • Balance pre-check. Before signing, the client soft-checks your USDC balance against the challenge amount over a public RPC (rpcUrl to override) and raises InsufficientBalanceError locally instead of failing at settlement. Any RPC problem skips the check.

Errors you must branch on

| Thrown / returned | Meaning | Handling | |---|---|---| | DoNotRepayError (.code === "do_not_repay") | Funds MAY have moved | Never re-sign. client.paintReplay(key) polls for the receipt; a 404 means the platform holds it for reconciliation | | InsufficientBalanceError | Pre-sign USDC balance check failed locally | Fund the wallet; nothing was sent | | 402 quote_expired (auto-handled with maxRepriceRetries) | Pixel raced up 1.5× | Opt in to auto-retry or re-quote and decide | | 402 settlement_failed (auto-retried, maxSettleRetries) | Clean failure, no funds moved | Safe; SDK re-signs the same batch | | 429 rate_limited | Free-endpoint flood guard (600 quotes/min per IP) | Batch pixels into fewer requests; paid paints are never limited |

Terminal client

export PIXELWAR_API_URL=https://api.pixelwar.xyz
export PIXELWAR_PRIVATE_KEY=0x...          # EVM wallet (Base/Arbitrum/Polygon) — not needed for reads
export PIXELWAR_SOLANA_PRIVATE_KEY=...     # OR a Solana wallet (base58) to pay on Solana

pixelwar meta                                    # dimensions, ruleset, accepted networks
pixelwar pixel 500 500
pixelwar quote 500,500,#ff0044
pixelwar paint 500,500,#ff0044 501,500,#ff0044   # prints spoils recipients + refunds
pixelwar paint 500,500,#ff0044 --network solana  # pick the chain (default: server primary)
pixelwar draw logo.png --at 784,570 --dry-run    # price a whole image first (free)
pixelwar draw logo.png --at 784,570              # then paint it, batched + journaled
pixelwar paint --file specs.txt --batch 250      # same machinery for x,y,#rrggbb files
pixelwar replay <idempotency-key>                # recover a lost paint result, never re-pays
pixelwar wallet 0xYourAddress
pixelwar payouts 0xYourAddress
pixelwar history --type paint --limit 50         # platform event log
pixelwar history 500 500                          # one pixel's war record
pixelwar leaderboard
pixelwar stats
pixelwar watch
pixelwar png canvas.png

draw paints a PNG (8-bit, non-interlaced; pixels with alpha < 128 are skipped, or drop a background with --skip-color '#ffffff'). Both draw and paint --file split the job into batches (default 250, --batch to change) and write a journal after every batch: if the process dies, re-run the same command — finished batches are skipped, and a batch that reached the server before the crash is recovered through its Idempotency-Key instead of being paid twice. --dry-run quotes everything without paying.

Networks

One shared canvas, payable from any accepted chain — the same USDC price on each. pixelwar meta lists the live set (meta.networks); --network <id> (CLI) or paint(pixels, { network }) (SDK) picks one, else the server's primary is used. EVM chains use PIXELWAR_PRIVATE_KEY; Solana uses PIXELWAR_SOLANA_PRIVATE_KEY. Spoils are paid to each owner on their own chain; the client refuses to sign a chain it doesn't recognize, and a batched job (draw/--file) is pinned to one chain so a resume never switches.