leak-cli
v2026.2.17
Published
Self-hosted pop-up stores for creators -- with agent-friendly automation built in
Maintainers
Readme
leak
there is no platform\n<beautiful_milady.jpg>\ni love you- cutting-edge architecture with dial-up sensibilities
- "For a limited time only."
Leak is a content creator tool that can set up a time-boxed online store hosted straight from your computer. It leverages open source tools, the x402 protocol, and AI assistants (like OpenClaw) to make selling digital goods as easy as asking your agent about the weather. Leak is for fans too; buying content is easy as giving your agent the promo or download link shared by your favorite creators and funding your agent with USDC -- installing the leak skill makes all of this a breeze.
Quick Start
Install
npm i -g leak-cliPackage name: leak-cli
Command: leak
Check installed CLI version:
leak version
# or: leak --versionStart interactive publish wizard:
leak publishOpenClaw skill docs live in this repo at:
Config
leak configConfigure defaults to avoid managing multiple flags when using leak subcommands.
Once leak is configured, commands become very simple to use:
Selling:
leak publishor direct flags:
leak --file ./your-file.bin --publicBuying:
leak buy <promo_or_download_link> [--download-code <code>] [--buyer-private-key-file <path>]Hosting multiple files on one machine (path prefixes):
leak host --config ./examples/multi-host.example.jsonSeller Quickstart 1: Local testnet sale (fastest path)
Goal: run a local sale and verify the x402 flow end to end.
Interactive wizard path:
leak publish --file ./your-file.binDirect flags path:
Prereqs: fund a buyer test wallet on Base Sepolia (Circle Faucet); no CDP mainnet setup is needed.
leak --file ./your-file.bin --pay-to 0xYOUR_ADDRESS --price 0.01 --window 15m --network eip155:84532Expected output:
- server URLs for
/,/health, and/download /downloadis x402-protected
Verification:
curl -i http://127.0.0.1:4021/downloadExpected result: 402 plus a PAYMENT-REQUIRED header.
Seller Quickstart 2: Public testnet sale (shareable link)
Goal: create a public share link for social posting.
brew install cloudflaredleak --file ./your-file.bin --pay-to 0xYOUR_ADDRESS --price 0.01 --window 30m --network eip155:84532 --public --og-title "Your Release Title" --og-description "Limited release. Agent-assisted purchase."Use the output URLs like this:
- share
https://<tunnel>/as your promo URL (optimized for OpenGraph metadata on feeds and chats) - agents will use
https://<tunnel>/downloadto buy (x402-protected link) - open the promo URL in a browser and confirm title, description, and image render correctly for social cards
- while the tunnel is still running, run the Buyer section below to validate payment + download end-to-end
Seller Quickstart 3: Multi-file hosting with one domain + path prefixes
Goal: run multiple leak endpoints on one machine and expose them as:
https://<host>/leak/lolboy/+/downloadhttps://<host>/leak/peter/+/download
Use the built-in multi-host runner:
leak host --config ./examples/multi-host.example.jsonWhat this command does:
- starts one leak worker per route (one local port per artifact)
- starts one reverse proxy that maps
/<prefix>/*to the right worker - sets
PUBLIC_BASE_URLper worker to<resolvedOrigin><prefix>so promo/download URLs are prefix-aware
Dry-run before launching:
leak host --config ./examples/multi-host.example.json --dry-runLocal validation with the default example:
curl -i http://127.0.0.1:4080/leak/lolboy/
curl -i http://127.0.0.1:4080/leak/lolboy/download
curl -i http://127.0.0.1:4080/leak/peter/
curl -i http://127.0.0.1:4080/healthPublic origin modes:
- local-only (default): no tunnel, origin is
http://127.0.0.1:<proxy-port> - quick tunnel: add
--publicand leak host will start one Cloudflare quick tunnel for the shared proxy - configured origin: set optional
publicOriginin config for named/manual ingress
Quick tunnel run (non-interactive):
leak host --config ./examples/multi-host.example.json --public --public-confirm I_UNDERSTAND_PUBLIC_EXPOSUREConfigured-origin run (named/manual tunnel):
{
"publicOrigin": "https://your-hostname.example",
"proxy": { "host": "127.0.0.1", "port": 4080 },
"routes": [ ... ]
}Precedence note:
- if
--publicis used andpublicOriginexists in config, leak host uses configuredpublicOriginand does not start a quick tunnel
Capacity baseline (M1 Mac mini, 8 GB RAM, up to 10 concurrent downloads):
| Total hosted content | RAM working set | Disk free target | Practical uplink target |
| --- | --- | --- | --- |
| 5 MB | ~4-5 GB | >=20 GB | 10-20 Mbps |
| 50 MB | ~4-5 GB | >=20 GB | 20-50 Mbps |
| 500 MB | ~4.5-5.5 GB | >=22-25 GB | 50-150 Mbps |
| 5 GB | ~5-6 GB | >=30-40 GB | 200+ Mbps |
These numbers assume streamed downloads (no whole-file memory loading), one route per worker, and one local reverse proxy.
Buyer Skeleton (direct CLI)
Use the direct CLI buy flow:
leak buy "https://xxxx.trycloudflare.com/" --buyer-private-key-file ./buyer.keyFor download-code modes, add:
leak buy "https://xxxx.trycloudflare.com/" --download-code "friends-only"leak buy accepts either the promo URL (/) or direct /download URL.
By default, the file is saved to your current directory using the server-provided filename; use --out or --basename to control naming.
When settlement metadata is returned, leak buy also prints a receipt block with network + transaction hash (and Basescan link on Base networks).
If the sale access mode includes payment, pass a buyer key (--buyer-private-key-file or --buyer-private-key-stdin).
If the sale access mode includes download-code, pass --download-code <code> (or --download-code-stdin).
Security note: use a dedicated buyer key with limited funds.
Buyer Skeleton (Clawhub skill flow)
- install the
leak-buyskill from Clawhub - give your agent the promo URL (
/) from the post (or/download) - provide a funded buyer key when prompted
- let the agent complete payment + download through the skill
The hardened skills require a preinstalled leak binary on PATH.
Recommended first-time agent UX for unknown URLs:
- ask only for skill-install approval (
clawhub install leak-buy) - ask for an existing buyer key file path when payment is required
- ask for download code when download-code is required
- run:
bash skills/leak-buy/scripts/buy.sh "<promo_or_download_url>" --buyer-private-key-file <buyer_key_file_path>(append--download-code <code>when needed) - avoid protocol deep-dives unless the user explicitly asks for x402 internals
Next: Mainnet checklist (optional)
Warning: switching only CHAIN_ID to mainnet is not sufficient.
Required:
FACILITATOR_MODE=cdp_mainnetCHAIN_ID=eip155:8453CDP_API_KEY_IDandCDP_API_KEY_SECRET- recommended:
CONFIRMATION_POLICY=confirmed
Reference: see Testnet vs Mainnet facilitator setup below.
User Archetypes
Seller:
- publish payment-gated content straight from your computer
- set your own price 💸
- set available window 🪟
- tell your agent what you b leakin' 🤤
💦 on-demand + one-shot + ephemeral ✨ -- store for your digital goods- yes, install
leak-publish(seller) andleak-buy(buyer) OpenClaw skills and let your agent run those flows 🪬
Buyer:
- download cool sh!t straight to your device
- skip the bad 🤓 guys 😤
- NO MORE SUBSCRIPTIONS PLEASE (hehe)
- platform resi-. there is not platform, i love you.
U MAD?:
- Spotify
- OnlyFans
- BandCamp
- SoundCloud
Leak CLI (recommended)
The easiest way to run the server is the leak CLI, which prompts for missing info (price + duration) and auto-stops after the sale window (or window + ended-window, if configured).
Recommended for humans: use leak publish for a guided interactive wizard.
Recommended for scripts/automation: use leak --file ... direct flags.
leak publishWizard behavior:
- Basic step always asks core publish inputs (file, access mode, price/window, network, public tunnel).
- Advanced step is optional and includes facilitator, port, OG metadata, and ended-window fields.
- Final summary always requires explicit confirmation before launch.
- Wizard offers (optional) saving values to
~/.leak/config.json. - Publish runs are always supervised: if the worker crashes, leak restarts it automatically with the remaining sale time.
- Sale deadlines are fixed at first launch; restarts do not extend total availability.
- Run-state is persisted at
~/.leak/runs/<run_id>.json(plus~/.leak/runs/latest.jsonpointer). - In
--publicmode, tunnel URLs may rotate after a restart; leak reprints new links and persists latest URLs in run-state.
cd ~/leak
npm run leak -- --file /path/to/vape.jpgIf you install this package globally / as a dependency, you can run:
leak --file /path/to/vape.jpgBackward-compatible form still supported:
leak leak --file /path/to/vape.jpgIt will ask:
- How much (USDC)? (e.g.
0.01) - How long? (e.g.
15m,1h)
Optional flags:
--access-mode <mode>where mode is one of:no-download-code-no-paymentdownload-code-only-no-paymentpayment-only-no-download-code(default)download-code-and-payment
--download-code "friends-only"(required for download-code modes)--download-code-stdin(read download code from stdin)--price 0.01(USDC)--window 1h(or seconds)--confirmed(settle on-chain before issuing token)--public(start a temporary Cloudflare Tunnel and print a public URL; requirescloudflared)--og-title "My Drop"--og-description "Agent-assisted purchase"--og-image-url https://...(absolutehttp(s)URL) or--og-image-url ./cover.png(local image path)--ended-window-seconds 86400(keep ended promo page online before auto-stop)--network eip155:84532--pay-to 0x...(required only for payment modes; must be a valid Ethereum address)--port 4021
Persistent config (leak config)
To avoid passing the same seller/facilitator flags every run, configure defaults once:
leak configInspect saved values (secrets redacted):
leak config showOptionally scaffold a project .env from saved defaults:
leak config --write-envConfig file location:
~/.leak/config.json
Precedence for launch values:
- CLI flags
- environment variables
~/.leak/config.json- built-in defaults
Manual editing is supported. Keep CDP_API_KEY_SECRET private and avoid committing generated .env files.
Install cloudflared for --public
--public needs the Cloudflare Tunnel binary on your PATH.
# macOS (Homebrew)
brew install cloudflared
# Windows (winget)
winget install --id Cloudflare.cloudflaredLinux packages/docs:
https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/
If you don't need a public URL, run without --public for local-only mode.
For now, Cloudflare quick tunnel (--public) is supported for both dev and early production rollout.
Custom-domain ingress can be added later.
Tweeting/sharing a release
When using --public, share the promo URL (/) in your tweet/chat message.
https://<tunnel>/→ promo page with OG/Twitter card metadatahttps://<tunnel>/download→ x402 endpoint for agents
Example:
npm run leak -- --file ./song.mp3 --pay-to 0x... --price 1 --window 1h --public \
--og-title "New Single: Nightwire" \
--og-description "Limited release. Agent-assisted purchase." \
--og-image-url ./nightwire-cover.jpgWhen a local image path is used for --og-image-url, leak serves it from /og-image and points OG/Twitter metadata at that endpoint.
Without --og-image-url, leak serves a generated raster OG card from /og.png (and keeps /og.svg for debug/backward compatibility).
Payment-mode behavior (payment-only-no-download-code / download-code-and-payment):
GET /downloadwithout payment → 402 withPAYMENT-REQUIREDheaderGET /downloadwith valid payment headers → returns a time-limited token JSONGET /download?token=...→ streams the artifact
Download-code behavior (download-code-* modes):
- send
X-LEAK-DOWNLOAD-CODE: <code>onGET /download - missing/invalid code returns 401
Testnet vs Mainnet facilitator setup
CHAIN_ID=eip155:8453 by itself is not enough for production.
Base Sepolia / testnet:
FACILITATOR_MODE=testnet
FACILITATOR_URL=https://x402.org/facilitator
CHAIN_ID=eip155:84532Base mainnet (CDP facilitator auth required):
FACILITATOR_MODE=cdp_mainnet
FACILITATOR_URL=https://api.cdp.coinbase.com/platform/v2/x402
CHAIN_ID=eip155:8453
CDP_API_KEY_ID=...
CDP_API_KEY_SECRET=...Recommended for production-like behavior:
CONFIRMATION_POLICY=confirmedQuickstart (local)
1) Install
cd ~/leak
npm install2) Configure
cp .env.example .env
# edit .envMinimum you must set:
SELLER_PAY_TO(the address that receives USDC; must be a valid Ethereum address)ARTIFACT_PATH(the file you want to serve)
Example artifact:
mkdir -p protected
printf "hello" > protected/asset.bin
# then set ARTIFACT_PATH=./protected/asset.bin3) Run
Dev (auto-reload):
npm run devProd:
npm startServer will print:
http://localhost:4021/(promo page)http://localhost:4021/info(machine-readable info)http://localhost:4021/healthhttp://localhost:4021/download(protection depends onACCESS_MODE)
How the flow works
A) Unpaid request
curl -i http://localhost:4021/downloadYou should get mode-specific behavior:
- payment mode:
402+PAYMENT-REQUIRED - download-code mode without header:
401 - no-payment/no-download-code mode: direct file response
B) Paid request → token
A buyer/agent should retry with a payment header:
- v2:
PAYMENT-SIGNATURE: <base64-json> - legacy:
X-PAYMENT: <base64-json>(accepted by this server)
If valid, the server responds 200 JSON:
{
"ok": true,
"token": "...",
"expires_in": 3600,
"download_url": "/download?token=...",
"filename": "myfile.mp3",
"mime_type": "audio/mpeg"
}Node buyer test script
There’s a Node buyer test script that does the whole 3-step flow (402 → pay → token → download).
Buyer CLI (new)
There is now a proper buyer CLI that takes the link directly (no BASE_URL env):
leak buy "https://xxxx.trycloudflare.com/" --buyer-private-key-file ./buyer.keyWhen available, it prints payment receipt metadata including transaction hash and network before saving the file.
Optional save naming:
--out ./some/path.ext--basename myname(keeps the server file extension)
cd ~/leak
# buyer envs (REQUIRED)
export BASE_URL=https://xxxx.trycloudflare.com # or http://127.0.0.1:4021 in dev
export BUYER_PRIVATE_KEY=0x...
# optional
export OUTPUT_PATH=./downloaded.bin
export OUTPUT_BASENAME=myfilename
npm run buyerDev convenience (optional):
export LEAK_DEV=1 # allows BASE_URL to default to http://127.0.0.1:4021What it does:
- if payment is required, first
GET /downloadgets 402 +PAYMENT-REQUIRED - if download-code is required, sends
X-LEAK-DOWNLOAD-CODE - handles payment/token flow when required
- saves the downloaded artifact
C) Use token → download
curl -L -o out.bin "http://localhost:4021/download?token=..."Routes
GET /promo HTML page with OG/Twitter tags200while sale is active200once sale has ended (ended state is shown in page content/metadata)
GET|HEAD /.well-known/skills/index.jsonRFC skill discovery indexGET|HEAD /.well-known/skills/leak-buy/SKILL.mdRFC skill metadata markdownGET|HEAD /.well-known/skills/leak-buy/resource.jsonRFC sale/resource metadata (200live,410ended)GET /.well-known/leaklegacy discovery endpoint (backward-compatible)GET /infomachine-readable JSON status (compat endpoint)GET|HEAD /og-imageconfigured OG image file (when using local--og-image-urlpath)GET|HEAD /og.pnggenerated default OG image (used when--og-image-urlis not set)GET|HEAD /og.svgdebug/backward-compatible OG SVGGET /healthfree health checkGET /downloadaccess-controlled download endpoint- active sale: behavior depends on
ACCESS_MODE - ended sale:
410
- active sale: behavior depends on
Troubleshooting
Invalid seller payout address→ set--pay-to/SELLER_PAY_TOto a valid Ethereum address (0x+ 40 hex chars).- Farcaster/Warpcast preview missing OG image → prefer PNG/JPG (
--og-image-urlor default/og.png), ensure OG URLs are absolutehttps://(setPUBLIC_BASE_URLif needed), and re-share with a fresh URL variant (example:/?v=2) to bypass crawler cache.
Env vars
PORT(default4021)FACILITATOR_MODEtestnet(default)cdp_mainnet(required for Base mainnet path in this project)
FACILITATOR_URL- default with
FACILITATOR_MODE=testnet:https://x402.org/facilitator - default with
FACILITATOR_MODE=cdp_mainnet:https://api.cdp.coinbase.com/platform/v2/x402
- default with
SELLER_PAY_TOreceiving address (required only for payment modes; valid Ethereum address,0x+ 40 hex chars)PRICE_USD(string like1.00)ACCESS_MODE:no-download-code-no-paymentdownload-code-only-no-paymentpayment-only-no-download-code(default)download-code-and-payment
DOWNLOAD_CODE_HASH(required for download-code modes; hash only, not raw code)CHAIN_ID- default:
eip155:84532(Base Sepolia) forx402.org/facilitator - Base mainnet:
eip155:8453(requiresFACILITATOR_MODE=cdp_mainnetplus CDP keys)
- default:
CDP_API_KEY_ID(required withFACILITATOR_MODE=cdp_mainnet)CDP_API_KEY_SECRET(required withFACILITATOR_MODE=cdp_mainnet)WINDOW_SECONDSaccess token lifetimeSALE_START_TSsale start (unix seconds; usually set by launcher)SALE_END_TSsale end (unix seconds; usually set by launcher)ENDED_WINDOW_SECONDS--publicdefault in launcher:86400(24h)- local-only default in launcher:
0
CONFIRMATION_POLICYconfirmed(default): settles via facilitator before issuing token (you should be able to see a tx on Basescan)optimistic: verifies payment + issues token, but may not settle on-chain
CONFIRMATIONS_REQUIRED(currently informational; parity with Python scaffold)ARTIFACT_PATHlocal file pathPROTECTED_MIMEcontent type (defaultapplication/octet-stream)OG_TITLEoptional card/page title (or use--og-title)OG_DESCRIPTIONoptional card/page description (or use--og-description)OG_IMAGE_URLoptional absolutehttp(s)card image URL (or use--og-image-url)OG_IMAGE_PATHoptional local card image file path (set automatically by launcher when using local--og-image-url)PUBLIC_BASE_URLoptional absolute base URL for metadata canonicalization
Versioning
This package uses CalVer in YYYY.M.P format (example: 2026.2.11).
Release rules:
YYYY= yearM= monthP= release number within that month- Pre-release builds use semver-compatible tags, for example
2026.2.11-rc.1.
Maintainer Release Process
- Run local release preflight:
npm run check:release
- Use
betadist-tag before promoting tolatest:npm publish --tag betanpm dist-tag add leak-cli@<version> latest
- Keep versions synchronized:
package.jsonskills/leak/SKILL.mdskills/leak-buy/SKILL.mdskills/leak-publish/SKILL.md
- Ensure
CHANGELOG.mdhas a section for the stable release version before tagging. - Use tag format
v<version>for stable GitHub releases.
Maintainer references:
RELEASE.md(weekly lifecycle + release checklist)CONTRIBUTING.md(PR/release expectations).github/workflows/ci.yml.github/workflows/release.yml
Notes
Legacy header support
This server accepts legacy X-PAYMENT by aliasing it to PAYMENT-SIGNATURE.
Running under OpenClaw / timeouts
If you see a SIGKILL after “listening …”, it usually means the command was run with a short timeout during automated testing. Running via npm run dev in your own terminal will keep it alive.
Facilitator troubleshooting
Startup error mentions
does not support schemeor network mismatch:- your
CHAIN_IDand facilitator mode/url are misaligned. - verify testnet vs mainnet settings above.
- your
Startup or runtime error mentions
401,403,authorization, orjwt:- facilitator auth is missing/invalid.
- for mainnet, ensure
FACILITATOR_MODE=cdp_mainnetplus validCDP_API_KEY_IDandCDP_API_KEY_SECRET.
