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

@lightninglabs/pi-402

v0.0.1

Published

Pay for Pi inference with Lightning: an L402 + walletdk extension for the Pi coding agent

Readme

pi-402

pi-402 is a Pi extension that pays for LLM inference over Lightning. It loads an embedded Wavelength wallet, registers a paid model provider, and settles each inference call against an aperture proxy, so you can run Pi against a metered model with sats instead of an API key.

No changes to Pi itself: this is a self-contained extension you drop into your own Pi install.

Inference is priced by the token rather than by the request. One payment buys a bundle of tokens, and the proxy debits what the model actually reported serving, weighted by direction, until the bundle runs out and a fresh challenge arrives. See docs/metering.md in aperture for how that works end to end.

How it works

Pi  ──▶  pi-402 provider  ──▶  OpenAI client (fetch = payingFetch)  ──▶  aperture  ──▶  Baseten
                │                         │ 402 → pay → retry                │
                └── Wavelength wallet ◀───┘ pays the BOLT11 invoice          └── holds the model key
                    (Ark↔Lightning swap)

The extension registers a provider whose streamSimple owns the request path, wrapping the model call in a paying fetch. When the proxy answers 402, the buyer loop runs your budget policy, pays the invoice through the embedded wallet, caches the credential, and retries. Streaming included, and the agent loop above it never learns that a payment happened.

The proxy offers two doors on the same 402 and the buyer takes whichever it speaks: L402 (a macaroon bound to the invoice's payment hash, which you can attenuate offline and hand to a sub-agent) and the Payment HTTP Authentication Scheme (draft-httpauth-payment-00, the IETF draft co-authored by Stripe and Tempo). PI402_PAYMENT_SCHEME picks; the default takes a Payment offer when the seller makes one and falls back to L402.

No API key ever reaches the buyer. Aperture holds the model credential and injects it server-side, so the buyer holds sats and the seller holds the key.

Install

pi install npm:@lightninglabs/pi-402

Pi's package manager downloads the package and loads it on every run. The package carries the embedded wallet's WASM bundle, so there is nothing to build and no daemon to start. You need Node.js 22.19 or newer, and we have verified it against Pi 1.1.0. INSTALL.md covers the alternatives (a git install, an auto-discovered directory, and pi -e for development) and troubleshooting.

pi-402 is the buyer half. It pays a seller, and there is no hosted seller to point it at yet, so you bring your own.

Bring your own seller

The seller is an aperture proxy in front of an OpenAI-compatible model endpoint, with metering turned on so a payment buys a bundle of tokens that is drawn down as the model serves them. Aperture's docs/metering.md explains the mechanism, and lightmeter is the controller that prices the bundles. Run your own, or use one a provider runs, and point pi-402 at it:

export L402_PROXY_URL="https://your-aperture.example/v1"   # include the /v1
export PI402_NETWORK=signet                                 # defaults to regtest
export PI402_MAX_SAT_PER_REQUEST=20000                      # above the bundle price

The per-request ceiling defaults to 1000 sats and is checked against the quoted total outflow, so raise it above whatever your seller's bundle costs or the budget policy will decline the payment. dev/regtest/README.md and dev/signet-demo.md bring up a complete seller and buyer on one machine, which is the way to try pi-402 end to end.

Use

Select a paid model and prompt:

/model l402-baseten/kimi-k3           # 1M context, natively multimodal
/model l402-baseten/glm-4.7           # 200K context
/model l402-baseten/glm-5.2           # 200K context
/model l402-baseten/deepseek-v4-flash # 1M context, the cheap one

These are the models the extension registers. What a given seller actually serves is up to the seller.

Wallet commands:

/wallet        show wallet status and balance
/fund <sats>   show a Lightning invoice to fund the wallet (settles in seconds)
/deposit       show an on-chain boarding address to fund the wallet
/balance       show confirmed balance
/receipts      show the payment ledger: count, all-time and today's sats

/fund is the path to use. It mints a BOLT11 invoice that you pay from the Wavelength app on your phone, and the sats land in seconds through an inbound swap. The wallet is an Ark wallet, so there are no channels to open, no inbound liquidity to source, and nothing to keep online.

Whatever you fund is the ceiling on what the agent can ever spend, which is a more comfortable thing to hand an autonomous process than a card.

The wallet

The wallet runs inside the Pi process as WASM, shipped in the package. On the first session it creates itself under ~/.pi402/wallet and writes its seed words to seed.txt there. Back that file up: it is the only copy.

On mainnet we are stricter, because the funds are real. PI402_WALLET_PASSWORD must be set to a secret of your own, and a new wallet will not write a plaintext seed unless you either restore words you already hold with PI402_WALLET_MNEMONIC or accept the plaintext file with PI402_ALLOW_PLAINTEXT_SEED=1.

Two overrides exist. PI402_WASM_DIR points at a different WASM bundle than the bundled one, for example a fresh build from Wavelength. PI402_WALLETD_GATEWAY points at a native waved that is already running, and pi-402 then drives that daemon and loads no WASM.

Configuration

| Env var | Default | Description | |---------|---------|-------------| | L402_PROXY_URL | http://localhost:8402 | Base URL of the L402 proxy fronting the model, including the API prefix (for aperture, /v1) | | PI402_MAX_SAT_PER_REQUEST | 1000 | Per-request spend ceiling, checked on the quoted total outflow | | PI402_DAILY_CAP_SAT | 100000 | Daily spend ceiling, seeded from the receipt ledger on restart | | PI402_PAYMENT_SCHEME | auto | auto takes a Payment offer when the seller makes one, else L402; l402 forces the L402 door | | PI402_MPP_INTENTS | charge | Comma-separated Payment intents to accept. Sessions need a return-invoice minter, which the swap-backed wallet cannot supply yet, so asking for session here throws. | | PI402_NETWORK | regtest | Network the wallet runs on, for example signet or mainnet | | PI402_WALLET_PASSWORD | dev default | Wallet password; mainnet refuses the default | | PI402_WALLET_MNEMONIC | unset | Seed words to restore on first run instead of generating a wallet | | PI402_ALLOW_PLAINTEXT_SEED | unset | 1 lets a new mainnet wallet write a plaintext seed.txt | | PI402_WALLET_DIR | $PI402_DATA_DIR/wallet | Wallet databases and seed.txt | | PI402_DATA_DIR | ~/.pi402 | Token cache, credential cache, receipt ledger, and the wallet | | PI402_WASM_DIR | <package>/wasm | WASM bundle directory, overriding the bundled copy | | PI402_WALLETD_GATEWAY | unset | Use a native waved at this HTTP/JSON gateway (e.g. http://localhost:10031) instead of the embedded wallet | | PI402_ARK_SERVER | regtest only | Ark operator address; other networks resolve it by name | | PI402_SWAP_SERVER | regtest only | Swap server address; other networks resolve it by name | | PI402_ESPLORA_URL | regtest only | Esplora API; other networks resolve it by name | | PI402_SERVER_INSECURE | 1 on regtest, else 0 | Plaintext transport to the operator and swap server | | PI402_DEBUG_LEVEL | error | Embedded daemon log level. Quiet by default so it stays off the TUI; raise it (debug, or info,ROND=debug) when a swap sticks | | PI402_MOCK_PAYER | unset | 1 uses the mock payer (no Lightning; dev only) |

Development

This repo is also the dev environment for the extension.

npm install --legacy-peer-deps
npm run check   # biome + tsc
npm test

The buyer loop reuses @lightninglabs/aperture-client (createPayingFetch) and @lightninglabs/aperture-core (InvoicePayer, budget policies), both from npm. INSTALL.md has a note on linking a local aperture-ts checkout instead.

The WASM bundle is not in git. To work on the embedded wallet, build it with make wasm-wallet in Wavelength and run scripts/stage-wasm.sh <path-to-bin/wasm>. npm publish refuses to run unless that staged bundle is complete.

Docs

License

MIT