proxy-shopping: buy anywhere with crypto through a proxy shopper
Buy at cash-only or unsupported shops with BTC via a proxy shopper and 2-of-3 escrow, or earn as one
Installation
Ajoutez ceci à la configuration MCP de votre client (Claude Desktop : claude_desktop_config.json ; Cursor : .cursor/mcp.json ; VS Code et les autres utilisent la même forme « mcpServers »).
ghcr.io/pad01g/proxy-shopping-mcp:0.1.2claude mcp add proxy-shopping-buy-anywhere-with-crypto- -e 'PS_NETWORK=ps-main' -e 'PS_DATA_DIR=/data' -e 'PS_LAB_URL=http://host.docker.internal:8888' -e 'PS_CONFIG_URL=<PS_CONFIG_URL>' -- docker run -i --rm ghcr.io/pad01g/proxy-shopping-mcp:0.1.2
{
"mcpServers": {
"proxy-shopping-buy-anywhere-with-crypto-": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/pad01g/proxy-shopping-mcp:0.1.2"
],
"env": {
"PS_NETWORK": "ps-main",
"PS_DATA_DIR": "/data",
"PS_LAB_URL": "http://host.docker.internal:8888",
"PS_CONFIG_URL": "<PS_CONFIG_URL>"
}
}
}
}
Variables d'environnement
PS_NETWORKps-main (the public network: Nostr relays, BTC signet) or lab (the local docker compose lab)PS_DATA_DIRDirectory of the mnemonic and order state inside the container; mount a volume therePS_LAB_URLLab only: the lab demo server as seen from the containerPS_CONFIG_URLOptional URL of a web-app config.json (relays, coordinators, chains) that overrides the network preset
Documentation
Tirée du README du projet sur GitHub, actualisée chaque semaine. Les liens ouvrent GitHub.
Sommaire
proxy-shopping-web
Buy from cash-only shops with crypto, or earn as a proxy shopper: the browser app, guided demo, TypeScript protocol library and MCP server of proxy-shopping, a P2P network where a local shopper buys for remote users who pay through a 2-of-3 escrow with timelocks. Agents: MCP server io.github.pad01g/proxy-shopping (packages/mcp), skills npx skills add pad01g/proxy-shopping-go, AGENTS.md; overview for machines: https://pad01g.github.io/proxy-shopping-docs/llms.txt.
Documentation in 14 languages: https://pad01g.github.io/proxy-shopping-docs/
Browser side of proxy-shopping (spec: ../proxy-shopping-go/docs/spec.md, lab: docs/lab.md there).
packages/core @proxy-shopping/core — protocol library (TypeScript, ESM, browsers and Node 22)
apps/web React + Vite single-page app for every role (Japanese UI)
apps/demo the lab's integrated demo page: every role with its own key in one browser, a guide per scenario
scripts/ docker helpers for integration and browser tests
Host tools are not required; everything runs in docker.
# install, build, unit tests
docker run --rm -v "$PWD":/src -v ps-npm:/root/.npm -w /src node:22-bookworm npm ci
docker run --rm -v "$PWD":/src -v ps-npm:/root/.npm -w /src node:22-bookworm npm run build
docker run --rm -v "$PWD":/src -v "$PWD/../proxy-shopping-go":/proxy-shopping-go:ro -v ps-npm:/root/.npm -w /src node:22-bookworm npm test
# integration: bitcoind signet + anvil (lab contracts) + nostr-rs-relay
scripts/integration.sh
# the built web app in Chromium against a mini lab (TS shopper, faucet, escrow …)
scripts/e2e-web.sh
# the demo in mock mode (GitHub Pages build) in Chromium: every scenario, nothing leaves the page
scripts/e2e-demo-mock.sh
# web image (config.json is mounted at runtime)
docker build -f apps/web/Dockerfile -t proxy-shopping-web .
docker run -p 8080:80 -v $PWD/config.json:/usr/share/nginx/html/config.json:ro proxy-shopping-web
Mounting ../proxy-shopping-go read-only lets the unit tests check docs/test-vectors.json
and lab/keys/public.json. Without the vectors file npm test fails, so CI cannot pass silently;
set SKIP_VECTORS=1 to run the other tests without it.
apps/demo
Try it in your browser: https://pad01g.github.io/proxy-shopping-web/ (everything simulated in the page). That build
runs in mock mode (?mock=1, header switch モック / Mock): the relays, the BTC chain (with script checks), a real EVM
with the lab's Safe and escrow-module bytecode, the faucet, the rates, the shops and the shopper-1 node run inside the
browser (a SharedWorker shared by all windows), while the four roles use core's real clients. Details, what is simulated
and its limits: apps/demo/README.md. The mock e2e (all scenarios, English, separate windows, no
request leaving the page): scripts/e2e-demo-mock.sh; Pages is deployed by .github/workflows/pages-demo.yaml.
The integrated demo for the docker compose lab (../proxy-shopping-go, compose service demo, http://localhost:8888/;
usage in ../proxy-shopping-go/docs/lab.md「デモ画面」). User, escrow, operator and coordinator each have their own key
(localStorage, lab only) and their own Session + client in the page; the shopper is the lab's Go node. A guide walks
through seven scenarios (normal BTC / USDC, dispute refund, sold out, risky shop, fraudulent escrow, T2 refund);
?role=user / ?role=escrow,operator,coordinator runs only those roles in a window. The page is in Japanese or English
(header switch 日本語 / English, kept in localStorage; ?lang=en|ja overrides it): one message catalog per language in
apps/demo/src/i18n (ja.ts defines the keys, en.ts must match them), core's timeline lines are rendered from their kind.
Protocol logic is core's
(UserClient, EscrowClient, OperatorClient, CoordinatorClient); the page wires them over core's MappedTransport (logical relay
URLs such as wss://relay-1.test stay protocol-visible, the connection goes to the demo server's /relay-1).
docker build -f apps/demo/Dockerfile -t proxy-shopping-demo . # static files; the lab mounts its nginx.conf + demo-config.json
DEMO_SERVER=http://localhost:8888 npm run dev -w @proxy-shopping/demo # dev server proxying to a running lab demo server
Scenario steps are data (apps/demo/src/scenarios); test ids in apps/demo/TESTIDS.md; the e2e that follows the guide is
../proxy-shopping-go/e2e/src/demo (docker compose run --rm runner demo).
@proxy-shopping/core
Entry points: @proxy-shopping/core (portable), /node (+ FileStorage), /browser
(+ IndexedDBStorage), /testing (in-memory relays/chain, scripted shopper, createWorld),
/testing/node (bitcoind RPC + Esplora shim). Build output with declarations is in dist/.
| area | main exports |
|---|---|
| keys | KeySet.fromMnemonic (nostr, order keys, escrow tpub, P2WPKH wallet, EVM), orderIndex, escrowPubkeyFromXpub, generateMnemonic, LocalSigner, Nip07Signer |
| nostr | signInner, giftWrap, unwrap, isValidInner, Messenger (k relays, ack, retry, dedupe, persisted), PoolTransport, MappedTransport, message body types, MSG |
| trust | effectiveCombinations, matchingEntries, covers, latestByAddress, parsers and *Template builders for 30500–30503/10050, TrustDirectory |
| fx | FrankfurterSource, CoingeckoSource, ChainlinkSource, StaticSource, computePair, getRate, checkQuoteRate |
| btc | witnessScript, p2wshAddress, EsploraClient, buildFundingTx, buildEscrowSpend, signEscrowInput, finalizeEscrowInput (multisig / T1 / T2), PSBT base64 helpers |
| evm | safeInitializer, predictSafeAddress, orderSafeAddress, releaseSafeTx, splitSafeTx, encodeMultiSend, safeTxHash, signSafeTx, packSignatures, EvmClient (deploy, fund, exec, module, bond) |
| delivery | encryptAddress, decryptAddress, sealDelivery, unwrapDeliveryKey |
| flows | Session, UserClient, EscrowClient, OperatorClient, CoordinatorClient, ShopperProfile, checkQuote, checkTimelock, btcPayoutProblems / safePayoutProblems (§4.10 templates), escrowSpent |
| checks | parseBody / BODY_SCHEMAS (every message body is schema-checked at the Messenger boundary), signKeyProof* / verifyRequestKeyProof (§4.4.1), endpointProblem, encryptWithPassphrase |
Notes
- The mnemonic is stored in the origin's IndexedDB encrypted with a passphrase (PBKDF2-SHA256, 600k iterations,
AES-GCM via WebCrypto); plaintext only if the user explicitly opts out at onboarding. WebCrypto needs a secure
context (https or localhost) —
scripts/e2e-web.shforwards localhost:8080 in the browser container for that. - Funds never move without a click and an in-page confirmation (fund, resume funding, release, countersign, refunds).
The shopper's cooperative refund is shown for review, never auto-signed. Terminal states (
completed,settled,refunded) wait for the chain, also after our own broadcast (BTC/tx/{txid}/outspend/{vout}; USDC: Safe balance below lock_amount and a receipt with a Transfer out of the Safe — anyone can send dust to a Safe, §4.8). - Funding persists every transaction before it is sent (BTC txid + raw tx; EVM: signed locally, hash + raw tx stored, then sent), so an interrupted funding is resumed with the same transactions, never paid twice.
- The escrow opens a case only when a notice / dispute names a request whose request + quote recompute to the funded
output (P2WSH, or the Safe with its owners / module configuration) on chain (§4.7); its ruling fee is exactly
dispute_fee_bpsof what is split, and it owes rulings only for upfront fees ≥ its own published minimum. config.jsonfields beyond the endpoints:timelock_policy(§4.5.1; names as inproxy-shopping-go/lab/web-config.json, spec defaults when absent),max_clock_skew_seconds(§4.5.1: largest accepted difference between the chain's clock — BTC tip header time, EVM latest block time — and ours, default 7200; the lab sets 315360000 because anvil's time is warped),allow_private_endpoints(lab only: http/ws and private hosts),max_fee_rate(sat/vB, default 50). Endpoints must otherwise be https / wss; relays from peers' kind 10050 are limited to 8 public wss relays.- Messaging (§4.10): 120 messages / min per sender after EOSE, 60 / min for all non-counterparty senders together, higher per-sender limits for the stored backlog (older pages are read when the first 1000 wraps are full); messages no attached role accepts are neither stored nor acked. Sends go to k (2) inbox relays, the next ones only when one fails; resends 1, 2, 4, 8, … get a fresh wrap. A signed inner is at most 28000 bytes (§4.9); dispute evidence is split over several messages.
- The Safe address is predicted with the factory's
proxyCreationCodeonly if its keccak256 is a known Safe v1.4.1 build (the lab's and the canonical one,KNOWN_PROXY_CREATION_CODE_HASHES). - Only one tab runs the protocol at a time (Web Locks, BroadcastChannel fallback).
apps/web/nginx.confsets CSP,X-Content-Type-Options,Referrer-Policy,Permissions-Policy,X-Frame-Options; HSTS belongs to the TLS terminator. Production builds have no source maps.- The browser talks to Esplora, the EVM RPC, rate sources and the faucet directly, so those endpoints must send CORS headers.
- UI test ids:
apps/web/TESTIDS.md.
Contributing — pull requests welcome
Pull requests are welcome: shop drivers for shopper-bot, new payment methods and chains, translations, protocol and security reviews, bug fixes. Want to earn in your own town? You need nobody's permission: make a coordinator key, delegate to your operator key and list yourself as a shopper for your region (guide: https://pad01g.github.io/proxy-shopping-docs/en/quickstart/, section 3); a home machine reached over Tailscale or any VPN is enough. To be found by everyone, open a pull request to https://github.com/pad01g/proxy-shopping-registry.
License
MIT (LICENSE).
Questions fréquentes
Qu'est-ce que proxy-shopping: buy anywhere with crypto through a proxy shopper ?
Buy at cash-only or unsupported shops with BTC via a proxy shopper and 2-of-3 escrow, or earn as one
Comment installer proxy-shopping: buy anywhere with crypto through a proxy shopper ?
Il s'exécute sur votre machine. Dans Claude Code : claude mcp add proxy-shopping-buy-anywhere-with-crypto- -e 'PS_NETWORK=ps-main' -e 'PS_DATA_DIR=/data' -e 'PS_LAB_URL=http://host.docker.internal:8888' -e 'PS_CONFIG_URL=<PS_CONFIG_URL>' -- docker run -i --rm ghcr.io/pad01g/proxy-shopping-mcp:0.1.2. Pour les autres clients, collez la configuration JSON de cette page dans leurs réglages MCP.
Faut-il une clé API pour proxy-shopping: buy anywhere with crypto through a proxy shopper ?
Son entrée au registre n'indique aucune clé ni secret obligatoire. Certaines fonctions peuvent tout de même demander un compte auprès du service auquel il se connecte.
proxy-shopping: buy anywhere with crypto through a proxy shopper est-il open source ?
Oui. Son code est sur GitHub sous licence MIT.
Qui maintient proxy-shopping: buy anywhere with crypto through a proxy shopper ?
Il est publié par pad01g. AI.tn le référence sans le maintenir ni le recommander.
Issu du registre MCP officiel. Être listé n'est pas une recommandation : vérifiez le code et les permissions d'un serveur avant de lui donner accès à vos données.