Web faucet for the XRPL EVM Sidechain. Supports two networks:
- Testnet — bridges XRP from XRPL Testnet through the Axelar gateway. The Ripple altnet faucet funds an ephemeral XRPL wallet, which then sends a
Paymentcarrying interchain-transfer memos to the bridge gateway. Status is tracked client-side by polling Axelar's GMP indexer (primary) and the XRPL EVM explorer's token-transfers endpoint (fallback). - Devnet — mints XRP directly. The browser POSTs the user's address to a Vercel API route (
/api/devnet-faucet), which signsmint(address, 100e18)against the native XRP ERC20 at0xEee…EEeEusing a server-held private key.
Built with Next.js 16 (App Router), React 19, Tailwind v4, viem, and xrpl@4.5.
| Testnet | Devnet | |
|---|---|---|
| Chain ID | 1449000 (0x161228) |
1449900 (0x161FAC) |
| RPC | https://rpc.testnet.xrplevm.org/ |
https://rpc.devnet.xrplevm.org/ |
| Explorer | https://explorer.testnet.xrplevm.org |
https://explorer.devnet.xrplevm.org |
| Faucet amount | 98.83 XRP | 100 XRP |
| Mechanism | XRPL → bridge | Direct ERC20 mint |
| Anti-abuse | None (open) | None (open) |
npm install
cp .env.example .env.local
# fill in DEVNET_FAUCET_PRIVATE_KEY
npm run devOpen http://localhost:5089.
The Testnet flow works without any env vars. The Devnet flow requires DEVNET_FAUCET_PRIVATE_KEY to be set to a funded EOA that has permission to call mint on the native XRP ERC20.
Submits a mint(address, 100e18) transaction on XRPL EVM Devnet and returns the broadcast hash. Confirmation is the client's job — see lib/use-poll-devnet-tx-status.ts, which polls eth_getTransactionReceipt against the public RPC every 2s for up to ~2 min.
Request:
{ "address": "0x..." }Response (200):
{ "txHash": "0x..." }Errors:
400— invalid JSON body or invalid EVM address500—DEVNET_FAUCET_PRIVATE_KEYnot configured orwriteContractrejected (e.g. signer lacks mint permission, RPC down)
| Variable | Required | Purpose |
|---|---|---|
DEVNET_FAUCET_PRIVATE_KEY |
Yes (Devnet only) | EOA private key authorised to call mint(address,uint256) on 0xEee…EEeE. With or without the 0x prefix. |
See .env.example.
The project deploys to Vercel as-is — app/api/devnet-faucet/route.ts is picked up as a serverless function automatically. Set DEVNET_FAUCET_PRIVATE_KEY in the Vercel project's environment variables (Production + Preview as needed) before the first deploy.
app/
page.tsx Single-page UI shell
layout.tsx Root layout, fonts, branding
api/devnet-faucet/route.ts Devnet mint endpoint
components/
faucet.tsx Main faucet form (network selector, request flow, modal)
connect-wallet-button.tsx MetaMask connect / disconnect
metamask-button.tsx "Add network to MetaMask" buttons + chain configs
bridging-progress.tsx Spinner + rotating trivia (Testnet only)
...
lib/
use-get-xrp.ts Testnet bridge flow (XRPL faucet → bridge payment)
use-mint-xrp.ts Devnet flow (POST to API route)
use-poll-devnet-tx-status.ts eth_getTransactionReceipt polling (Devnet only)
use-poll-destination-tx-status.ts Axelar + explorer polling (Testnet only)
- The "Follow on X" / "Join Discord" gate is a client-side honor system, not a security check.
- Testnet faucet-down fallback: the Testnet bridge polling runs up to ~25 min before marking
Timeout. After 130s inPending, the transaction modal surfaces a soft warning pointing users to the community faucet in the#🚰・faucetchannel of the XRPL EVM Discord. The polling keeps running underneath; the warning is additive and disappears as soon as the bridge resolves. - The Devnet endpoint has no rate limit or anti-bot protection. If you need either later, the natural fit is Upstash Redis for per-address / per-IP
SET NX EXrate limits, plus Cloudflare Turnstile for browser attestation. - Concurrent Devnet requests share one signer key; viem auto-fetches nonces per call, so simultaneous requests can collide. If traffic warrants it, add a queue or use viem's nonce manager.
npm run lint && npx tsc --noEmit && npm run buildESLint runs through the native flat config exported by eslint-config-next@16 (eslint-config-next/core-web-vitals + /typescript). All three commands should pass clean before opening a PR.