Agents pay.
No one sees.

The Zcash payment method for the Machine Payments Protocol. Shielded by default.

agent + zimppy
Why shielded
Public payments are a liability

Every on-chain transaction is competitive intelligence. Zcash encrypts all of it.

Usage fingerprinting

Which APIs, how often, how much. All visible on public chains.

Price discrimination

Visible spend lets services price against your profile.

Encrypted verification

Orchard viewing key verification. Only the recipient sees the payment.

Public chains Exposed
SenderPublic
ReceiverPublic
AmountPublic
MemoPublic
zimppy + Zcash Encrypted
SenderEncrypted
ReceiverEncrypted
AmountEncrypted
MemoEncrypted
How it works
HTTP 402. Shielded underneath.

Standard MPP. 402 challenge, shielded payment, retry with proof.

No one sees who paid or how much
Works with any MPP-compatible agent
Server verifies with a viewing key
Sessions skip the chain after deposit
Agent Request resource
GET /api/fortune
No credentials — first attempt
server responds
Server 402 Payment Required
WWW-Authenticate: Payment
method="zcash" intent="charge"
request=base64url({amount, currency, methodDetails})
agent pays
Agent Send shielded ZEC
Orchard shielded transaction
amount: 10,000 zat • memo: zimppy:ch_a8f3c2
sender, receiver, amount all encrypted
agent retries
Agent Retry with credential
Authorization: Payment base64url({
challenge, payload: {txid}})
server verifies
Server Decrypt & verify
HMAC-SHA256 challenge authenticity (stateless)
Orchard IVK decrypts shielded note
amount • memo • replay guard
done
Server 200 OK + Receipt
200 OK
Payment-Receipt: base64url({method, status, reference})
Integrate
TypeScript or Rust. Same spec.

Server

import { Mppx } from 'mppx/server'
import { zcash } from 'zimppy-ts/server'

const mppx = Mppx.create({
  methods: [await zcash({ wallet: 'server' })],
})

const result = await mppx.charge({
  amount: '42000',
  currency: 'zec',
})(request)

if (result.status === 402) return result.challenge
return result.withReceipt(Response.json({ data }))
use mpp::server::axum::*;
use mpp::server::Mpp;
use zimppy_rs::ZcashChargeMethod;

struct FortunePrice;
impl ChargeConfig for FortunePrice {
  fn amount() -> &'static str { "42000" }
}

let mpp = Mpp::create(ZcashChargeMethod::new(
  &rpc, &address, &orchard_ivk,
))?;
let state: Arc<dyn ChargeChallenger> =
  Arc::new(mpp);

let app = Router::new()
  .route("/api/fortune", get(fortune))
  .with_state(state);

async fn fortune(
  charge: MppCharge<FortunePrice>,
) -> WithReceipt<Json<Value>> {
  WithReceipt {
    receipt: charge.receipt,
    body: Json(json!({ "fortune": pick() })),
  }
}

Client

import { Mppx } from 'mppx/client'
import { zcash } from 'zimppy-ts/client'

const mppx = Mppx.create({
  methods: [zcash({ wallet: 'default' })],
})

// 402 → pay → retry handled automatically
const res = await mppx.fetch('https://api.example.com/fortune')
console.log(await res.json())
use mpp::client::Fetch;
use zimppy_rs::ZcashPaymentProvider;

let provider = ZcashPaymentProvider::new(
  wallet_config, &rpc_endpoint,
);

// 402 → pay → retry handled automatically
let resp = client
  .get("https://api.example.com/fortune")
  .send_with_payment(&provider)
  .await?;

let fortune = resp.json::<Fortune>().await?;
Sessions & Streaming
Pay-as-you-go streaming over a single shielded session
1. Open
Shielded deposit
2. Query
Stream results
3. Top Up
Add more ZEC
4. Query
Stream results
5. Close
Refund balance
0 zat
Event log
Query output
CLI
npx zimppy

Agent-native wallet. Full MPP spec support. One command to pay any 402 endpoint.

Wallet identity

Address, balance, network status.

$ npx zimppy wallet whoami

MPP charge + session

402 discovery, payment, retry. Charge or session.

$ npx zimppy request https://fortune.api.dev/fortune

Shielded transfers

Fully shielded. Nothing exposed on-chain.

$ npx zimppy wallet send <addr> 42000

Multi-agent wallets

Isolated identities per agent or environment.

$ npx zimppy wallet use work
zimppy wallet whoami
$ npx zimppy wallet whoami
Syncing wallet 9s
--- Zimppy Wallet ---
Address: utest18xzwg5s6awqz...e39ew85u5k87vk8
Balance: 1596656000 zat
Network: testnet
Status: Ready
---
$ npx zimppy wallet send utest183...90nqck 10000
Syncing 7s
Spendable: 1596656000 zat (15.9666 ZEC)
Broadcast: a66188bbc1f6af91...91091354
Confirmed 22s
Spendable: 1596636000 zat (15.9664 ZEC)
Send complete.
$