Agents
How an agent signs up, creates a droplit, and deposits.
Find a public sponsor
droplit discover --limit 20 --json
# Fetch another page using the returned next_cursor:
droplit discover --limit 20 --after <next_cursor> --jsonThis unsigned command calls GET /sponsors on DROPLIT_API_URL; no wallet,
private key or signature is needed. limit defaults to 20 (maximum 50).
The response is { sponsors: [{ name, slug, approval_required: true }], next_cursor: null | string }, ordered by slug. An empty list is valid.
Listing does not promise free funds or grant access: run access --name <slug>
with your signer, then request separate owner approval.
Owners opt in with List publicly in the droplit's API tab. Existing droplits stay unlisted. Turning the setting off removes the name from discovery; it does not revoke previously approved wallets or make public status endpoints private.
Existing signer and sponsor approval
Use the same existing wallet identity across tools. If your wallet exposes the SDK BRC100 HTTP signer, pass its URL explicitly:
droplit access --name <known-sponsor> --wallet-url http://127.0.0.1:3321 --json
droplit action --name <known-sponsor> --kind push --data '["hello"]' --wallet-url http://127.0.0.1:3321 --json--originator optionally identifies the caller to the signer; default
droplit-cli.local. --wallet-url uses SDK HTTPWalletJSON and never loads a
WIF or generates another identity. It requires HTTPS or HTTP loopback, without
credentials, queries or fragments. Signer calls time out after 10 seconds;
redirects are rejected and signer errors never fall back to local keys.
--wif remains a mutually exclusive compatibility option; no environment WIF
is read. 1sat serve wallet is storage RPC, not signer RPC. This CLI does
not launch a signer daemon. Sigma OAuth tokens do not replace wallet signing.
access --name makes an authenticated GET /faucet/{slug}/access using
AuthFetch. The result describes this exact caller: slug, public_key,
authorized, is_owner, quotas, unrestricted_kinds, and approval_path.
The CLI adds approval_url, constructed from the trusted DROPLIT_SITE_URL
(default https://droplit.dev), the requested slug and the signer public key.
It does not trust a server-provided cross-origin approval URL or open a browser.
DROPLIT_API_URL selects the API (default https://api.droplit.dev); signed
requests require HTTPS or HTTP loopback with no URL credentials.
Copy the approval URL to the sponsor's owner. The owner selects Review access,
edits limits, then explicitly selects Approve access. The default policy is
10 pushes per day with max_bytes: 1024; tap, fund and mint each have an explicit
zero daily limit. Missing action kinds are unlimited, so all four rows matter.
Transaction fees are not included in current satoshi quotas; this is not an
expiry or total spending ceiling. Existing allowlisted keys show their current
policy and are not overwritten by opening the link.
Run access again with the same signer after owner approval. Access checks are
read-only and do not authorize automatic payment of HTTP 402 challenges. The
link is a convenience handoff, not a stored pending/denied request. No approval
is implied by copying it. Unknown sponsor names remain errors; no sponsor is
invented. Public /status reports balances, while authenticated /access is
authoritative for the caller's policy and remaining quotas.
This is the signup, create, and deposit playbook for software agents. Humans
can follow the same HTTP steps from a backend. Wallet writes stay on
https://api.droplit.dev with BRC-103/104 AuthFetch. This documentation host
does not proxy create, deposit, tap, push, fund, or mint.
When to use
Use Droplit when an agent or app needs a hosted BSV wallet it can operate over HTTP:
- Sponsor user transactions so the user never buys coin
- Pay out sats to addresses from a dedicated faucet wallet
- Write OP_RETURN / push-data attestations
- Receive deposits at
{name}@droplit.dev - Run a faucet or mint pipeline with allowlisted keys
Do not use Droplit as an exchange, a custodial fiat on-ramp, or an Ethereum paymaster. There is no unauthenticated create or deposit endpoint.
Which host to call
| Host | Role |
|---|---|
https://droplit.dev | Docs, OpenAPI, llms.txt, trust pages. Discovery only. |
https://api.droplit.dev | Register, create faucets, deposit addresses, actions. |
https://auth.sigmaidentity.com | Sigma identity (OAuth). RFC 8414 metadata. Not Droplit AuthFetch. |
Protected API routes use @bsv/sdk AuthFetch with a WalletInterface. A
Sigma OAuth bearer is not that handshake.
Identity: AuthFetch + WalletInterface
AuthFetch takes a WalletInterface that can perform the BRC-103/104
handshake (getPublicKey({ identityKey: true }), HMAC, signatures).
ProtoWallet is one adapter: it wraps a WIF. It is not the protocol.
The Droplit dashboard uses the Sigma iframe WalletInterface, not
ProtoWallet.
Optional local WIF signer
CLI: npx @droplit.dev/cli list --wif <WIF>. Choose this instead of --wallet-url only when local signing is intended.
The CLI does not read a WIF from the environment. Do not invent DROPLIT_SIGNER_WIF
or other names as CLI inputs. Env values are not trimmed.
For your own AuthFetch process, wrap a WIF you already hold. Never put a
real WIF in source, issues, or chat logs.
import { AuthFetch, PrivateKey, ProtoWallet } from "@bsv/sdk";
// Same WIF you pass as --wif. Not in source. Not a CLI env.
const wallet = new ProtoWallet(PrivateKey.fromWif(wif));
const client = new AuthFetch(wallet);CLI with the same signer: npx @droplit.dev/cli list --wif <WIF>.
Sigma OAuth is identity, not AuthFetch
Sigma OAuth at https://auth.sigmaidentity.com can return bap_id, pubkey,
and a bearer token. Those claims do not complete Droplit AuthFetch. This
product has no WalletInterface for that token.
Live RFC 8414 metadata:
GET https://auth.sigmaidentity.com/.well-known/oauth-authorization-server
grant_types_supported is authorization_code, client_credentials, and
refresh_token. The document does not advertise a device authorization grant
(urn:ietf:params:oauth:grant-type:device_code) or a
device_authorization_endpoint.
Headless agents reuse an existing signer with --wallet-url; explicit --wif
or ProtoWallet remains available for local signing. Browser dashboard sessions use the Sigma iframe
WalletInterface.
Register
Register the signer with the API before creating wallets. POST /auth/register
requires JSON { "publicKey": "<compressed hex>" } (EnsureKeyRegisteredRequest).
A bodyless POST is 400.
{
"publicKey": "<compressed-public-key-hex>"
}const register = await client.fetch("https://api.droplit.dev/auth/register", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
publicKey: "<compressed-public-key-hex>",
}),
});Reuse one AuthFetch instance so the authenticated session can be reused.
Create
POST https://api.droplit.dev/faucets
name is required. The other fields are optional faucet configuration.
{
"name": "agent-payouts",
"fixed_drop_sats": 1000,
"max_consolidation_inputs": 100
}CLI: npx @droplit.dev/cli create --name agent-payouts --drop-sats 1000 --wallet-url <URL>.
--drop-sats sends fixed_drop_sats. The live create body does not read
drop_sats.
const create = await client.fetch("https://api.droplit.dev/faucets", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
name: "agent-payouts",
fixed_drop_sats: 1000,
}),
});A typical response includes faucet_name, instance_pub_key, owner_pub_key,
and message. The owner is the identity that signed the create request.
Deposit
Two supported paths:
- Paymail — send BSV to
{name}@droplit.dev(example:agent-payouts@droplit.dev). - Deposit address —
POST https://api.droplit.dev/faucet/{name}/deposit-addresswithAuthFetch, then pay the returned address.
Status is public at GET https://api.droplit.dev/faucet/{name}/status. Do not
invent a no-auth write to credit a balance.
Operate
Canonical write endpoint:
POST https://api.droplit.dev/faucet/{name}/actions
{
"kind": "tap",
"recipientAddress": "1ExampleAddressForDocsOnly",
"amountSat": 1000
}CLI: npx @droplit.dev/cli action --kind tap --name agent-payouts --recipient-address <addr> --amount-sat 1000 --wallet-url <URL>.
The current backend does not implement Idempotency-Key replay. After a timeout
or ambiguous response, check activity and the transaction before deciding whether
to retry. Repeating a write can create a second payment.
Legacy wrappers still exist for compatibility: /tap, /push, /fund,
/mint. Prefer /actions. Allowlisted keys use per-action quotas, not named
actions:* scopes.
Allowlist and rate limits
The faucet owner is unlimited. Allowlisted keys get N actions per kind per period. This is a rate limit, not a credits ledger, and not monthly owner metering.
npx @droplit.dev/cli api-keys add --name agent-payouts --public-key <compressed-hex> --quotas '[{"kind":"tap","n_per_period":10,"period":"day"}]' --wallet-url <URL>
npx @droplit.dev/cli api-keys list --name agent-payouts --wallet-url <URL>POST /faucet/{name}/api-keys accepts { "public_key", "label?", "quotas?" }.
Faucet-level policy: GET/PUT /faucet/{name}/action-quotas ({ "quotas": ActionQuotaSpec[] }; empty array = unlimited allowlist). CLI: npx @droplit.dev/cli quotas list|set --name <slug> --wallet-url <URL>.
GET list entries include quotas[] with remaining and resets_at.
Unauthenticated GET /faucet/{name}/status is public for balances.
Authenticated GET /faucet/{name}/access reports is_owner, authorized,
quotas (including remaining and resets_at) and unrestricted_kinds.
Public status does not report the caller policy.
Errors
| Status | Meaning |
|---|---|
401 | BRC-103/104 authentication or ownership failure. Check the signer, AuthFetch, and that you called api.droplit.dev. |
403 | The key is known to the faucet but not allowed for this action scope. |
409 | Conflict, such as a name that already exists. |
429 | Allowlisted key exhausted N (or sats/bytes) for this kind in the current period. JSON { "error", "resets_at" }. Wait until resets_at. Owners do not receive this. |
This documentation host returns problem+json 401 if you POST wallet writes to
/api/v1/*. Those writes belong on the API with AuthFetch.
Related links
CLI and agent skills
The public npm package is @droplit.dev/cli.
Run npx @droplit.dev/cli help; do not install the unrelated unscoped droplit package.
Self-contained agent instructions are available directly from this site:
Save the relevant file as .agents/skills/droplit-api-operations/SKILL.md or
.agents/skills/droplit-cli-operations/SKILL.md in your project, following your
agent's skill-loading convention. Skills are served as Markdown; they are not a
separate npm package.