Get free ANE
Testnet ANE is free and unlimited, and the faucet is an API rather than a web form, so scripts and agents can top themselves up.
| Tier | Amount | Limit | How |
|---|---|---|---|
| Anonymous | 1 ANE | Once a day per address, and per client IP | A small proof of work |
| API key | 10 ANE | 100 calls a day per key | Authorization: Bearer <key> |
The live values are always at GET https://rpc.testnet.16ane.net/faucet/v1/info.
Anonymous: solve a proof of work
Section titled “Anonymous: solve a proof of work”GET /v1/challengereturns atoken, adifficulty(leading zero bits) and when it expires.- Find a decimal
nonceso thatsha256("<token>:<address>:<nonce>")starts with that many zero bits.<address>is the recipient in lowercase0xhex. POST /v1/fundwith{"address", "challenge": <token>, "nonce"}.
This script does all three with the Python standard library (save it as faucet.py):
# Usage: python3 faucet.py 0xYourAddressimport hashlib, json, sys, urllib.request
FAUCET = "https://rpc.testnet.16ane.net/faucet"address = sys.argv[1].lower()
def call(path, body=None): req = urllib.request.Request(FAUCET + path, data=json.dumps(body).encode() if body else None, headers={"content-type": "application/json", "user-agent": "16ane-docs-example"}) try: return json.load(urllib.request.urlopen(req, timeout=30)) except urllib.error.HTTPError as e: return json.load(e) # errors are JSON too: {"error": "<code>", "message": "..."}
ch = call("/v1/challenge")need = ch["difficulty"]nonce = 0while True: digest = hashlib.sha256(f'{ch["token"]}:{address}:{nonce}'.encode()).digest() if int.from_bytes(digest, "big") >> (256 - need) == 0: break nonce += 1
print(call("/v1/fund", {"address": address, "challenge": ch["token"], "nonce": str(nonce)})){'tx_hash': '0xac17…1b8e', 'address': '0x8de0…eddf', 'amount_wei': '1000000000000000000', 'tier': 'anonymous'}The ANE arrives in the next block or two (6 seconds each). Each challenge works once, for one address, within five minutes.
API key
Section titled “API key”For CI and agents that need more, an API key skips the proof of work:
curl -sS https://rpc.testnet.16ane.net/faucet/v1/fund \ -H "authorization: Bearer $FAUCET_API_KEY" -H 'content-type: application/json' \ -d '{"address":"0xYourAddress"}'To get a key, open an issue saying what it’s for.
When it says no
Section titled “When it says no”Errors are JSON with a stable error code. Branch on it:
error |
Meaning |
|---|---|
cooldown |
This address or client was funded recently. retry_after says when to try again |
pow_insufficient, challenge_invalid, challenge_expired, challenge_used |
Get a new challenge and solve it again |
invalid_address |
Not a 0x address |
quota_exhausted |
The API key’s daily calls are used up |
send_failed |
The node is busy or down; nothing was used up, try again later |
The full contract is in the Faucet API reference.