Claude Code skill (and standalone Node scripts) for building and operating PolyPay privacy-preserving multisigs — where signers are identified by ZK commitments ("Membership IDs"), not EVM addresses.
Three operations:
- Bootstrap — generate N agent keypairs locally, register them as ZK-commitment users, deploy a multisig via the PolyPay relayer.
- Transfer — propose, co-sign with UltraHonk approval proofs, wait for the relayer to auto-execute.
- Status — query current multisig state and recent transactions.
Validated on Base Sepolia. Supports Base mainnet with explicit --allow-mainnet opt-in.
As a Claude Code skill:
git clone https://github.com/NurstarK/polypay-multisig.git ~/.claude/skills/polypay-multisig
cd ~/.claude/skills/polypay-multisig/scripts
npm installRestart Claude Code (or open a new session). The skill becomes invokable; in conversation, ask things like "create a 2-of-3 polypay multisig on base sepolia" or "send 0.001 ETH from my polypay multisig to vitalik.eth".
As standalone Node scripts (no Claude Code required):
git clone https://github.com/NurstarK/polypay-multisig.git
cd polypay-multisig/scripts
npm install
node bootstrap.mjs --signers=2 --threshold=2 --state-file=./state.jsonSee SKILL.md for the full reference (args, gotchas, state file format, known issues).
Quick reference:
cd ~/.claude/skills/polypay-multisig/scripts
# Create a 2-of-2 multisig on Base Sepolia
node bootstrap.mjs --signers=2 --threshold=2 --chain=base-sepolia \
--state-file=$HOME/my-project/polypay-state.json
# Send 0.0003 ETH from the multisig
node transfer.mjs --to=vitalik.eth --amount=0.0003 \
--state-file=$HOME/my-project/polypay-state.json
# Inspect state
node status.mjs --state-file=$HOME/my-project/polypay-state.jsonThe PolyPay relayer broadcasts execute() for free, but the multisig itself must hold the ETH (or ERC-20 balance) it's about to send. Faucets are not autonomous-agent-friendly — every Base Sepolia faucet requires CAPTCHA / login / wallet signature. Send testnet ETH from a wallet you already control directly to the multisig address; don't try to script the faucet step.
viem— wallet, public client, signing, ENScircomlibjs— Poseidon hash for commitments@noir-lang/noir_js+@aztec/bb.js— UltraHonk proof generation against the upstream PolyPay Noir circuits
State files contain plain-JSON private keys for the agent signers. Treat them as testnet-only; the bundled .gitignore excludes *.json to prevent accidental commits.
MIT — see LICENSE.