ZecPy

ZecPy: Private ZEC for Python.

A Python SDK for shielded Zcash. Its light server sees zero requests that identify the wallet.

Read the quick start

Zero leaks, measured

A proxy between wallet and server logged every request across create, sync, receive, restart and send. These are the requests that identified the wallet.

ZecPy
0
zcash-devtool
7
zingo-cli
71
How it is measured Then on public testnet, over Tor 108 requests from the shop. None identified it outside the opt-in memo fetch, which hid the real payment among 7 real ones. Read the run

See it run

ZecPy Live replays a real run on a local chain. Every request the server receives lands in the table as it arrives.

Sixteen transaction ids requested in two shuffled fetches of eight; two are marked Ours, fourteen Decoy
Memo fetch: 2 real transactions hidden among 16.
The offline signer's summary: spends 0.01 ZEC, pays 0.002 ZEC, 0.0079 ZEC change, fee 0.0001 ZEC
Cold signer: checks change against its own key.

Read the server's log

The audit's raw record. Pick a wallet; gold rows identify it.

ScenarioRequestWhat it asks forServer learns
First syncGetAddressUtxosStreamQueries transparent address UTXOsThis wallet

zcash-devtool: 7 identifying of 24 requests.

Fixed upstream

Building ZecPy found three problems in Zcash's own code. Each is filed with a fix.

A small API

Async where it touches the network. Amounts are integer zatoshis.

invoices.create

Each invoice gets its own shielded address. Payments match on your machine: no memo, no lookup.

invoice = wallet.invoices.create(150_000, "order-77")
Full API reference

What it refuses

  • Transparent paymentsPrivacyError unless you opt in
  • Direct connectionsTor or nothing, a fresh circuit per sync and send
  • Lone txid lookupsMemos fetched among 7 decoys
  • A sync trailTree states at aligned heights only
  • Mempool watchingPayments are seen in blocks

Install to paid

pip install zecpy on Linux or macOS, Python 3.10+. Nothing to compile.

from zecpy import Wallet

wallet, mnemonic = await Wallet.create(
    "./shop", network="test",
    server="https://testnet.zec.rocks:443")
invoice = wallet.invoices.create(150_000, "order-77")
async for event in wallet.invoices.watch():
    if event.invoice_settled:
        ship(event.invoice.reference)

Install

  • pip install zecpyseconds

Receive

  • invoices.createown address
  • payment detectednext block
  • payment confirmed3 blocks

Send

  • prove and sign locallyabout 11 s
  • fee10,000 zat

Identifying requests0

Agent ready

The docs ship as plain text for models. Paste the brief, or point your agent at llms.txt.

Agent brief
You are writing Python that uses ZecPy, an SDK for shielded Zcash.
Reference: https://zecpy.pages.dev/llms-full.txt

- Network calls are async: await Wallet.create, sync, send, pay.
- Amounts are integers in zatoshis. 1 ZEC = 100_000_000.
- Never print, log or return the mnemonic.
- Take payments with wallet.invoices.create and invoices.watch.
  Match by invoice, never by memo.
- Pay links with wallet.pay(uri, max_zat=BUDGET). Never raise
  max_zat to make a payment go through.
- PrivacyError is a refusal, not a bug. Do not pass
  allow_transparent or allow_pool_crossing unless asked.
- Keep tor=True. Use network="test" until told otherwise.
Install it and take your first private payment. Start