Self-custody wallets
Screen the recipient before the user signs a send. Warn on review, stop on block.
guard() before signScreen a recipient before you sign, watch your hot wallets, verify webhooks and file Travel Rule transfers, all with typed calls. Muxed addresses and memos just work.
npm install @hera/sdkimport { Hera, HeraBlockedError } from "@hera/sdk";
// Server-side, with a `screen`-scoped key.
const hera = new Hera({ apiKey: process.env.HERA_API_KEY! });
// Before signing a send in your wallet:
try {
const verdict = await hera.guard({
address: recipient,
memo: { type: "id", value: memo },
});
if (verdict.needsReview) await flag(verdict.screening);
await signAndSubmit(tx);
} catch (error) {
if (error instanceof HeraBlockedError) {
showWarning(error.screening.reasons[0]?.title);
} else throw error; // network or auth: your policy
}Screen the recipient before the user signs a send. Warn on review, stop on block.
guard() before signScreen deposits before crediting and withdrawals before sending. File Travel Rule records above threshold.
guard + webhooks + travel ruleSEP-6/24/31 flows with memo and muxed customers. Score the customer, not the omnibus.
guard with memo / M…Screen the recipient at quote and again at send. Above threshold, file a record.
guard + travel ruleScreen the payer when payment arrives, before you fulfil the order.
guard after receiptScreen the connecting wallet through your proxy. Gate writes, never block reads.
guard on connectScreen every payee when the proposal is created, and again at execution.
guard at propose + executeScreen the depositor on the source chain and the recipient on the destination.
guard + watchScreen buyer and seller at purchase, and every royalty or payout address.
guard at purchaseScreen payee wallets at onboarding, watch them for later exposure, and guard each run.
guard + watchEverything an exchange does, plus watching every client address and evidence PDFs for audits.
watch + webhooks + reports| Error class | When it happens |
|---|---|
| HeraValidationError | Bad address, checksum or field. Thrown before any request; fields says where. |
| HeraBlockedError | guard() said block. Carries the full screening. |
| HeraAuthError | Key missing, revoked or missing a scope. |
| HeraRateLimitError | Slow down; retryAfter tells you when. |
| HeraConnectionError | Hera unreachable or slow. Apply your fail-open or fail-closed policy. |
| HeraWebhookSignatureError | Delivery wasn't signed by Hera, or is stale. Respond 400. |
| HeraError | Anything else, like not_found or invalid_transition. Check code. |
The SDK refuses to run in a browser by default. Expose a narrow route instead: authenticate the user, rate-limit, forward only the address, and return only what the UI needs.
export async function POST(req: Request) {
const user = await requireUser(req); // no anonymous calls
await rateLimit(user.id);
const { address } = await req.json();
const r = await hera.screen({ address });
return Response.json({ decision: r.decision });
}Prefer raw HTTP, or another language? Every endpoint, with request and response schemas, is in one OpenAPI document. Point your client generator or HTTP tool at it. Authenticate with Authorization: Bearer hera_live_….
| Method | Path | Scope |
|---|---|---|
| POST | /v1/screen | screen |
| GET | /v1/screenings[/:id] | read |
| GET · POST · DELETE | /v1/wallets… | read / monitor |
| GET · PATCH | /v1/alerts… | read / monitor |
| GET · POST | /v1/travel-rule/transfers… | travel_rule |
| GET · POST | /v1/reports… | read |
| GET | /v1/reports/verify?sha256= | public |
Webhooks and API keys are managed in the dashboard.