Funding
In sandbox, the faucet mints Demo USD (and drips a little ETH for gas) into a
wallet so you can exercise payments without
real money. Demo USD is Permara's own six-decimal test token (DUSD, no
monetary value); the asset wire name stays usdc. It is TEST-only,
testnet-only (a wallet on a mainnet chain is refused with
FAUCET_NOT_AVAILABLE) and rate-limited — see the caps in
Environments. GET /v1/capabilities reports
features.faucet and each chain's settlementToken.
| Asset | Default drip | Max per drip |
|---|---|---|
usdc | 250 | 1000 |
eth | 0.02 | 0.02 |
Drips are additionally rate-limited per wallet and per tenant. There is no
live faucet — requests authenticated with a live-environment key (pm_live_)
are rejected before any wallet is touched.
Key endpoints
| Method | Path | Scope | Purpose |
|---|---|---|---|
GET | /v1/balance | status:read | Where the money is: your smart account and your org account, live. ?ensure=true provisions what is missing. |
POST | /v1/faucet/drips | wallets:fund | Demo USD into your smart account (default) or org account. |
POST | /v1/wallets/{id}/fund | wallets:fund | Drip an asset into a Safe by wallet id. |
GET | /v1/faucet/drips | wallets:fund | List drips (optional walletId filter). |
GET | /v1/faucet/drips/{dripId} | wallets:fund | Get one drip. |
Fund a wallet
Body is optional — omit it to get the default 250 Demo USD. Both asset and
amount are optional fields on FundWalletBody.
- curl
- TypeScript
- CLI
# USDC (specific amount)
curl -X POST https://api.sandbox.permara.com/v1/wallets/w_1a2b3c/fund \
-H "X-SafeBank-Api-Key: $PERMARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "asset": "usdc", "amount": "250" }'
# ETH for gas
curl -X POST https://api.sandbox.permara.com/v1/wallets/w_1a2b3c/fund \
-H "X-SafeBank-Api-Key: $PERMARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "asset": "eth" }'
await pm.wallets.fund('w_1a2b3c', { asset: 'usdc', amount: '250' })
await pm.wallets.fund('w_1a2b3c', { asset: 'eth' }) // 0.02 ETH for gas
// Inspect drip history:
const { drips } = await pm.faucet.listDrips('w_1a2b3c')
permara wallets fund w_1a2b3c --usdc 250
permara wallets fund w_1a2b3c --eth
The response is a Drip. status starts SUBMITTED and moves to CONFIRMED
once the transfer lands (or FAILED, with a failureReason):
{
"id": "d_9z8y",
"walletId": "w_1a2b3c",
"asset": "usdc",
"amount": "250",
"chainId": 84532,
"status": "SUBMITTED",
"txHash": null,
"failureReason": null,
"createdAt": "2026-08-09T12:00:05.000Z"
}
Poll GET /v1/faucet/drips/{dripId} (or pm.faucet.getDrip(id)) until status
is CONFIRMED and txHash is populated before spending the balance.
For live funding, move real USDC into the wallet's Safe address directly on
Base (chainId 8453), or use the Bridge on-ramp surface. The faucet exists
only in sandbox.
Next
- Send a payment from the funded wallet.