Skip to content

Faucet (testnet HSUITE)

To do almost anything on the testnet — mint a subscription, deploy a Smart App — your wallet needs some HST. The faucet dispenses it. It’s the one surface you can call before you have a subscription: a public, wallet-authenticated bootstrap path.

The faucet uses a challenge → sign → dispense flow (the same ownership proof as Web3 auth), so only the wallet that controls the address can claim to it.

sequenceDiagram
    autonumber
    participant You as Your wallet
    participant F as Faucet
    participant XRPL as XRP Ledger
    You->>F: requestChallenge(chain, recipientAddress)
    F-->>You: { challengeId, message, expiresInSeconds }
    You->>You: sign(message) with the recipient key
    You->>F: dispense({ challengeId, signature, publicKey })
    alt trustline_required
        F-->>You: trustLine { currency, issuer, limit }
        You->>XRPL: set HST trust line, then re-request a fresh challenge
    else rate_limited
        F-->>You: retryAfterSeconds
    else faucet cannot pay
        F-->>You: HTTP 503 { reason }
    else dispensed
        F->>XRPL: send HST
        F-->>You: { amount, txHash, remainingDailyAllowance }
    end

The result is a discriminated union on status:

status Meaning What to do
dispensed HST was sent on-chain Done — txHash confirms it; remainingDailyAllowance is what’s left today
trustline_required The recipient has no HST trust line yet Set the returned trustLine on your wallet, then request a fresh challenge and dispense again
rate_limited Daily limit hit Wait retryAfterSeconds and retry

The faucet doesn’t drip a fixed constant — it sizes each payout to cover a real first subscription: the cheapest tier’s deposit priced at the live HSUITE/USD rate, plus one marketplace listing fee, plus a safety margin (and never below a configured floor). Because the amount is derived from the same quote the subscribe path prices with, a tier-price or exchange-rate move can’t silently leave you with too little HST to subscribe. The current per-wallet daily cap is reported as dailyCap by the status endpoint.

The faucet pays from its own HST balance, and it will only drip an amount it can prove covers a first subscription. When it can’t — the balance can’t cover a payout (a testnet whose faucet hasn’t been funded yet, or has run dry), or it can’t price/size the drip right now — POST /faucet/hsuite answers HTTP 503 before any signing starts and before any of your daily allowance is used — it is not a status result. The body is the standard error envelope plus a machine-readable reason:

{
"statusCode": 503,
"message": "The HSUITE faucet is out of funds and cannot pay out right now. Nothing was sent. …",
"code": "DEPENDENCY_UNAVAILABLE",
"domain": "dependency",
"retryable": true,
"timestamp": "2026-11-14T12:00:00.000Z",
"path": "/api/v3/faucet/hsuite",
"method": "POST",
"error": "DEPENDENCY_UNAVAILABLE",
"isRetryable": true,
"reason": "faucet_unfunded"
}
reason Meaning What to do
faucet_unfunded The faucet holds less HST than one payout needs Retry later, with a fresh challenge
faucet_balance_unavailable The faucet could not confirm its balance, so it refused rather than guess Retry shortly, with a fresh challenge
faucet_quote_unavailable The faucet could not price a first subscription right now (no live HSUITE/USD rate), so it refused rather than under-drip Retry shortly, with a fresh challenge
faucet_drip_exceeds_cap A first subscription now needs more HST than the faucet’s per-request limit allows A network configuration issue — report it; a retry won’t help until it is fixed

This check comes before trustline_required and rate_limited: while the faucet can’t pay, a wallet that still lacks a trust line (or already drew today) gets the 503 instead, so nobody is asked to spend an XRP reserve on a trust line for nothing.

In the SDK this is an SdkHttpError with statusCode === 503; the body above is err.details.

The SDK exposes the faucet as FaucetClient. /api/v3/faucet/* is reachable through the public gateway (unlike the retired validator raw tier — SDK 8.0), so FaucetClient is a small standalone client you point at the gateway directly with createHttpClient:

import { FaucetClient, createHttpClient } from '@hsuite/smart-engines-sdk';
const http = createHttpClient({ baseUrl: 'https://gateway.testnet.hsuite.network/api/v3' });
const faucet = new FaucetClient(http);
// 1. Request a challenge for the wallet you want funded
const challenge = await faucet.requestChallenge('xrpl', wallet.address);
// 2. Sign the challenge message with that wallet's key
const signature = await sign(challenge.message);
// 3. Dispense
let result = await faucet.dispense({
chain: 'xrpl',
recipientAddress: wallet.address,
challengeId: challenge.challengeId,
signature,
publicKey: wallet.publicKey,
});
if (result.status === 'trustline_required') {
await setTrustLine(result.trustLine); // set on the recipient wallet
const fresh = await faucet.requestChallenge('xrpl', wallet.address);
result = await faucet.dispense({
chain: 'xrpl',
recipientAddress: wallet.address,
challengeId: fresh.challengeId,
signature: await sign(fresh.message),
publicKey: wallet.publicKey,
});
}
if (result.status === 'dispensed') {
console.log(`got ${result.amount} HST — ${result.txHash}`);
}

Check today’s allowance without dispensing:

const status = await faucet.getStatus('xrpl', wallet.address);
// { dailyCap, dispensedToday, nextResetUtc }
// dailyCap is the live, derived drip size (what one claim funds today)

The fastest path — the CLI handles the challenge, signing, the trust line, and the retry for you:

Terminal window
hsuite faucet # drip HST to the wallet in .env.local (sets HST trustline if needed)

hsuite init funds a new wallet with test XRP from the XRPL test network’s own faucet, not with HST. Run hsuite faucet afterwards to get HST. See CLI.

Public bootstrap routes (no subscription / bearer token required — ownership is proven by the signature):

Method Path Body / Query
POST /api/v3/faucet/hsuite/challenge { chain, recipientAddress }
POST /api/v3/faucet/hsuite { chain, recipientAddress, challengeId, signature, publicKey? }
GET /api/v3/faucet/hsuite/status ?chain=&recipientAddress=

Testnet only chain must be xrpl (HST lives on XRPL).