Payouts
Payouts send money from a project's hot wallet: refunds, supplier payments, withdrawals to an exchange. They work on the EVM networks and Solana. Bitcoin has no hot wallet in Coldtill, so Bitcoin payouts aren't supported. Tron payouts aren't supported yet; the Tron hot wallet only pays for sweeps.
Setup
- Hot wallet (global admin): under Hot wallets, generate or import an EVM key and a Solana key, then assign them to the project. Assigning needs a two-factor code.
- Fund it: send the hot wallet enough native coin for gas, plus the tokens you plan to pay out. Keep the balance small; it is the only money a server compromise can reach.
- Limits under Project settings → Payout limits (project admin, with two-factor):
| Setting | Effect |
|---|---|
| Minimum payout (USD) | Smaller payouts are refused |
| Auto-approve up to (USD) | Larger payouts wait for an admin. 0 holds every payout |
| Hourly limit, daily limit (USD) | Payouts that would take the project's total over the limit wait for an admin. 0 means no limit |
Limits are counted per project, across every user and API key, including payouts still in flight.
- Address book: add destinations under Payouts → Address book (project admin, with two-factor). API payouts can only go to address-book entries, and entries can only be added in the dashboard.
Creating a payout
- Dashboard: Payouts → New payout (project admin, with two-factor). Any valid address is allowed, but limits still apply.
- API:
POST /api/v1/withdrawal/merchantwith anIdempotency-Key. See Merchant API.
Coldtill validates the destination for the chain. EVM addresses with a wrong mixed-case checksum are refused. On Solana, sending to a token account (rather than a wallet) is refused, as are SOL transfers that would leave a new account below rent exemption.
Approval
A held payout shows the reason (for example "above the auto-approve amount"). To approve:
- A project admin clicks Approve and enters a two-factor code.
- Coldtill emails a six-digit code to that admin. It is valid for 10 minutes and allows five attempts.
- The same admin enters the emailed code. Only the admin who started the approval can finish it.
Either step can be abandoned. Reject ends the payout. A payout that hasn't been signed yet can be cancelled.
Statuses
| Status | Meaning |
|---|---|
pending-approval |
Held by a limit or the auto-approve amount |
pending-otp-verification |
Approval started; waiting for the emailed code |
pending |
Approved, queued for signing |
signing |
Signed and stored; being broadcast |
initiated |
Broadcast; waiting for confirmations |
sent |
Confirmed on-chain |
failed |
Definitely did not happen (reverted, or refused and unknown to every node) |
rejected |
Rejected by an admin |
cancelled |
Cancelled before signing |
needs-review |
Coldtill can't tell whether it landed. See below |
How sending works
- The
payoutsprocess claims a pending payout and reserves a nonce (EVM) or a recent blockhash (Solana). - It signs the transaction and stores it before broadcasting, so a crash can never lead to a second, different transaction for the same payout.
- It broadcasts and tracks the transaction:
- EVM: a stuck transaction is re-signed with the same nonce, recipient and amount and doubled fees. Only one version can ever be mined.
- Solana: if the blockhash expires before the transaction lands, Coldtill asks every node, with full history search, whether it ever landed. It re-signs only if none has seen it.
- After the network's confirmations it becomes
sentand apayout.sentwebhook goes out.
If a node refuses a broadcast outright (for example "insufficient funds"), the payout isn't failed straight away: with failover, an earlier node may have accepted it. Coldtill waits two minutes and fails it only if the transaction is still unknown.
Needs review
needs-review means the hot wallet's nonce was used, but Coldtill can't match the transaction that used it to
this payout, even after 30 minutes. That can happen if someone used the hot wallet outside Coldtill, or if
your nodes are badly out of sync. Coldtill won't guess, because a payout wrongly marked failed invites a retry
that pays twice.
To resolve one:
- Open the hot wallet's address in a block explorer and look for a transfer of that amount to that address.
- In Payouts, click Resolve, choose It was sent or It was not sent, add a note (for example the explorer link) and confirm with two-factor.
The decision is recorded in the audit log and sends a final payout.sent or payout.failed webhook.
Good practice
- Keep the hot float to about a week of gas plus expected payouts. Top it up from your cold wallet.
- Use a low auto-approve amount and tight daily limits; raise them only as volume requires.
- Give
project_adminonly to people who should approve payouts. Admins can approve payouts they created themselves, which single-admin installs need. If you have several admins, agree that someone else approves. - Don't use the hot wallet from other software. Coldtill expects to be the only thing spending from it.