Another faucet post, I know. This one mines its own TAZ

People have been asking where to get testnet coins on this forum for about ten years. It comes up often enough that I wanted to build one properly and keep it running.

Live: https://zcashfaucet.jinolabs.xyz
Paste a testnet address, solve a small proof-of-work in the browser, get 0.1 TAZ as a shielded z2z transaction.

Source, MIT: GitHub - jinolabs-xyz/zcash-faucet: Self-sovereign Zcash testnet faucet. Runs its own node, wallet and miner, pays shielded z2z drips, and gates claims with browser proof of work instead of a captcha vendor. · GitHub

Why I built it

I came to Zcash wanting to build application tooling and didn’t get very far, because the first thing you need is testnet coins. So I stopped and solved that first.

My view is that tooling and documentation are part of the protocol rather than something that comes afterwards. A missing RPC reference fails as quietly as a bug in the code, and it costs you more developers.

How it’s put together

The faucet runs its own stack rather than sitting in front of someone else’s:

Piece What it means
Zebra full node My own view of the chain, no trusted third party
Zallet wallet, with Zaino embedded Every send is built and broadcast by my own wallet, so nobody else can move the funds
Solo Equihash miner It mines part of its own funding
Browser proof-of-work No captcha vendor. It calls nobody and tracks nobody

It was built on the post-zcashd stack from the start, since zcashd reached end of life on 2026-07-18. It runs post-Ironwood too. NU6.3 has been active on my testnet since height 4,134,000, the wallet’s notes sit in the corrected Ironwood pool, and it was paying shielded drips on the new circuit before mainnet’s own activation on 2026-07-28.

The rule it’s built around

This is the part I’d most like people to pick at.

Zcash transactions carry an expiry height taken from the tip your node reports. If your node has fallen behind, it will happily build a transaction that is already expired by the time it’s broadcast, so it can never be mined. A faucet in that state hands you a txid and a good feeling.

Mine checks its tip against an independent reference and refuses to build the payment instead. That decision is node.canBuildTx on /api/status, and it’s kept separate from the looser “is the node behind” signal on purpose. One question is about availability. The other is about money.

Three more rules come from the same idea.

“Working”, “broken” and “cannot tell” are three different answers, and only one of them is good news. An unreachable explorer isn’t evidence of a fork, and a check that couldn’t run must never read like one that ran and found nothing.

Being ahead isn’t the same as agreeing. A node in front of every external reference looks identical to a node on its own fork. That’s safe for an expiry height, since ahead can’t be stale, but it isn’t evidence that you agree with the network. The status text says exactly that rather than reporting a comfortable “in sync”.

Nothing reports success without checking what it left behind. The deploy confirms that the wallet accepts a new credential and rejects a deliberately wrong one. A probe that only ever sees a 200 can’t tell real authentication from a server that says yes to everything.

The tests work the same way. The ops suite runs 688 assertions, and it refuses to run at all on a machine without sha256sum, because in that one case a drift check compares two empty listings, finds them equal and passes while checking nothing. A suite that answers wrongly is worse than one that admits it can’t answer.

So do the measurements. The panel reads a heartbeat the miner writes itself rather than an environment variable saying mining is on, because a config flag can’t go false when the process dies. The box publishes what’s installed, the status page turns that into a verdict, and CI fails when the two disagree. unknown counts as a failure, not a pass.

Live as I write this: node ready at height 4,230,538, 1002 TAZ in the wallet, box 29 of 29 installed and enabled, miner heartbeat 2 seconds old. It’s all on /api/status with no login, so you can check rather than take my word for it.

What’s weak

Mining is a lottery ticket, not a budget. It won blocks 4,227,889 and 4,227,915 six minutes apart on 2026-07-31, which is 2.5 TAZ and the first income this has earned. It doesn’t change the arithmetic. A dominant miner on public testnet takes most heights and extends its own chain, so a small miner’s blocks usually get orphaned.

Chain-split detection isn’t finished. Comparing a block hash at a common height is what would actually detect a split. Today node.chain reports cannot-verify rather than an answer it hasn’t earned. I’m working on it.

There’s no published API contract yet. The endpoints exist but aren’t formally described, so anything automated has to guess at them. That’s first on the list below.

It’s one box. Quick to rebuild isn’t the same as highly available, and I don’t want to suggest otherwise.

Testnet only. TAZ has no monetary value. Don’t point this at mainnet, and don’t reuse a testnet key anywhere real.

What’s next

I’ll post progress in this thread rather than starting new ones.

  1. A published HTTP contract at /.well-known/openapi.json, so CI jobs can rely on the endpoints instead of scraping them.
  2. A claim path for machines (#134). Browser proof-of-work is decent anti-abuse and poor ergonomics for a CI job that needs TAZ at 3am. This is the harder of the two problems and I’d like opinions on it: a gate that a build agent can pass honestly but a farm still can’t cheaply farm.
  3. A real drip after every merge to main (#131), verified on chain. Green CI against mocks isn’t the same as a faucet that actually paid somebody.
  4. Finishing chain-split detection, so that cannot-verify becomes a real answer.
  5. Alerting (#215). The watchdog and the smoke probe can spot a dead faucet but can’t page anyone yet.

It’s open source, and help is welcome

The whole thing is MIT and built to be run by other people, not just by me. CONTRIBUTING.md covers how to work on it, and there’s a local mock mode so you can develop against it without a node or any real coins.

Two kinds of help would make a real difference right now.

If you use it and something breaks or confuses you, please open an issue or just say so in this thread. Reports from people who aren’t me are worth more than my own testing, because I already know where the sharp edges are and I’ll route around them without noticing.

If you want to write code, the machine-friendly claim path (#134) is the most interesting open problem, and the API contract is the most immediately useful. I’ll review anything that comes in, and I’m glad to help someone get set up if the first hour is the hard part. It usually is.

And if you’d rather run your own copy than contribute to mine, that’s a good outcome too. That’s what the licence is for.

On money

I can cover the bills myself for a few months. After that I’d appreciate some help. There’s a fund page for that, and a donate page for testnet TAZ, which costs the giver nothing and goes straight back out as drips. While this is up, nobody has to run a node and mine their own TAZ just to test something. That’s the whole point of it. Keeping it that way is mostly a server bill, and if that’s covered I can put my time into the next thing in the way instead of this one.

What I’d like from the community

  1. Is 0.1 TAZ per address per day the right shape? It’s sized for someone testing a wallet flow. If you run CI, tell me what you actually need and I’ll size it against the reserve instead of guessing.
  2. If you run node infrastructure, the freshness gate and the ahead-versus-agreeing distinction are the claims I’m least sure about. If the reasoning is wrong, I’d rather find out before more things depend on it.
  3. What should a machine-friendly claim path look like? I have ideas but no strong opinion yet, and the people who’d use it are on this forum.
  4. What blocked you when you started building on Zcash? Testnet coins were the first wall I hit, so that’s the one I fixed. I’d like to hear the rest from people who aren’t me.

If you just need TAZ, it’s up, it’s shielded and there’s no signup. If it’s down when you try it, please say so here.

-- Aayush Giri · github.com/Giri-Aayush

8 Likes

Very cool! Feature request: hand out cTAZ. :slight_smile:

1 Like

Thanks @zooko for the suggestion. We are already looking into it

1 Like

@zooko following up on your cTAZ ask from when I posted this. I took it and wired cTAZ into the faucet, and that rabbit hole turned out to be the best part.

Running the real Crosslink node surfaced two actual bugs, both now fixed and up upstream. The indexer was binding its payout gRPC to 0.0.0.0 instead of loopback, a straight path to the mining wallet (#56). And the faucet RPC returned success before it built or sent anything, so you could not tell a paid request from a dropped one (#55).

Straight about where it stands, user-facing cTAZ drips are not live yet. The wallet rescans from genesis on every restart with no note persistence, so roughly a two day warm-up before it has spendable notes. Filed that as (#54) with the scan rate and root cause. Bigger change, belongs upstream. Once it lands, cTAZ follows.

TAZ drips are working and shielded in the meantime. Thanks for the nudge, it pushed this somewhere useful.

3 Likes

this is a pretty nice devex work for all of the zcash community, problem is one of these gets built every now and then but get lost in the forum threads ergo visibility dissapears then maintanance follows suite.

~ I don’t have a solution in mind so great work and thank you.

@Lucid yeah, that’s honestly the thing I worried about most before posting another one of these. You’re right that they usually show up and then quietly rot.

What I’m going for here is treating it as something to keep maintaining, not launch and forget. It’s all MIT and made to be run by anyone, so it isn’t locked to me and the whole thing rebuilds from the repo. I’m not going anywhere with it. What it really needs to stay up long term is the community behind it. The cTAZ work and the two upstream fixes yesterday are the latest, and I’m keeping every update in this one thread so it doesn’t get scattered.

The honest truth is tooling like this only lasts if the community actually adopts and values it. When work like this gets used and appreciated, that’s the encouragement to keep it up and never let it go down.

The ongoing cost is really just the server bill, so there’s a fund page if anyone wants to help keep the stack running, and a donate page if you’d rather send TAZ back into the faucet, which costs nothing and goes right back out as drips.

I’m in this one for the long haul. Best thing anyone can do is use it and shout when it breaks. Thanks for the nudge ser, keep them coming

1 Like

huge! hundreds of years from now, ppl will be still be posting about testnet faucet… or maybe not anymore!

1 Like

not anymore!

1 Like

One month update.

The faucet has been live just over a month and served 95 shielded drips, all paid from TAZ the node mines itself. Balance is around 1,800 TAZ.

When NU6.3 turned on the Ironwood pool, the beta wallet started crashing on boot over its internal note tree. We traced it to a bug in the early node software, upgraded the node and wallet, and rebuilt the tree from the chain.

This is infrastructure the community needs, so we just keep it running. If you need shielded TAZ on testnet it is at https://zcashfaucet.jinolabs.xyz. Grab some and tell us if anything breaks.

2 Likes

faucet doesn’t seem to work. Is there an issue?

Thanks for flagging it, and sorry for the downtime.

The node ended up on a dead side branch of the testnet chain and got stuck there, last night. The faucet stopped paying on purpose because it checks our node against an independent reference before every payment, saw we were behind, and refused rather than send transactions that could never be mined. Funds were fine, nobody got a drip.

In the first month we hit a few failures and built self healing for each hiccup:

  • A wallet crash looping on a dead transaction
  • a miner that stops after the node restarts
  • a container that dies
  • the app hanging

All of those fix themselves. This one was new. The node process looked healthy the whole time, so nothing fired and a person had to notice.

Two things changed. The watchdog now catches a node that is behind and not moving and heals it the same way we did by hand, so this exact failure will not need a person again. And the alerting that should have woken us up never had anywhere to send to.

It now pages a phone over Signal the moment a real outage passes thirty minutes, and when the self healing fixes something it reports what broke and what it did. So the next problem gets noticed in minutes, not hours.

It is back up. If anything else looks off, please say so.