Add limits to your AI agent.
Curb wraps your agent's payments with simple rules — spending caps, an allowlist of who it can pay, and approvals for big payments — and writes every decision to Hedera so it's auditable. It plugs straight into the Hedera Agent Kit. Add it in a few lines of code, or set it up from your terminal with no code at all.
Install
Add Curb alongside the Hedera Agent Kit and SDK — they're its peer dependencies.
npm i hedera-curb @hashgraph/hedera-agent-kit @hiero-ledger/sdkQuickstart
One call — createCurb() — provisions everything and hands you the hooks you drop into the Agent Kit. After this, every payment your agent attempts is checked against your rules before it runs.
import { createCurb } from 'hedera-curb';
// one call sets up the audit topic, the policy registry, storage, and the policy
const curb = await createCurb({
client, // your Hedera operator client
agentAccountId, // the account the agent pays from
perDay: 25, // optional — daily spending cap (HBAR)
});
// drop the hooks into the Agent Kit — that's the whole integration
new HederaAIToolkit({ client, configuration: {
context: { hooks: curb.hooks },
}});Audit topic— creates an HCS topic where every decision (allowed / blocked / approved) is recorded immutably.Policy registry— creates an HCS-2 topic that versions your spending rules on-chain, so any change is auditable.Storage— defaults to an in-memory store (great for tests). Swap in Redis for production — see Storage below.Starting policy— publishes your caps to the registry so the on-chain policy is live from the first payment.Returns— an object:{ hooks, config, store, auditTopicId, policyTopicId }. Pass any of those back in to reuse existing topics.
Terminal setup (no code)
Don't want to write setup code? Run one command in your terminal. It creates the same two topics and prints their ids — paste them into your .env and you're governed.
npx hedera-curb init --network testnet
# ✓ Audit topic: 0.0.x
# ✓ Policy topic: 0.0.y (HCS-2, only you can change it)Storage
Curb needs somewhere to track how much the agent has spent and which approvals are pending. For tests or a single server, the built-in in-memory store just works. For production — where you might run several servers — implement the small CurbStore interface against Redis or Postgres so the state is shared and survives restarts.
Spend is tracked as a rolling 24-hour window. A payment that's mid-flight places a short-lived hold so two payments can't both slip under the cap at the same time; once it settles, the hold becomes committed spend.
interface CurbStore {
isAllowed(agent, account): Promise<boolean>; // is this counterparty allowlisted?
getDailySpend(agent): Promise<number>; // committed (settled) spend in the window
incrDailySpend(agent, amount): Promise<void>;
tryReserveSpend(agent, key, amount, cap): Promise<boolean>; // place an atomic hold
commitSpend(agent, key, amount): Promise<void>; // hold → committed
getApproval(requestId): Promise<Status | null>;
setApproval(requestId, status, meta?): Promise<void>;
consumeApproval(requestId): Promise<void>; // approvals are single-use
}The trust ladder
Curb enforces the same policy at three levels of trust. You pick how much to trust the server running the agent — start at L0 for speed, climb to L2 for guarantees that hold even if everything else is compromised.
This package. The hooks check your caps, allowlist, and approvals before every payment, and write each decision to Hedera. Fast and simple — but it trusts the server holding the agent’s key.
Every decision and every rule change lives on Hedera. The policy itself is versioned on an HCS-2 registry, and anyone can recompute the spend straight from the chain. Now the history and the rules can’t be quietly changed.
CurbVault — a smart contract — enforces the caps and allowlist in Hedera consensus itself. Even if the agent’s key is stolen, it still can’t overspend or pay someone off the allowlist.
API reference
Every export, with full parameters, types, and examples. Click any entry for its page.
Setup
createCurbfunction →One-call setup. Auto-provisions the audit + HCS-2 policy topics, defaults the store, publishes the starting policy, and returns ready-to-use Agent Kit hooks.
buildCurbHooksfunction →The ordered policy + audit stack, if you want to wire things up yourself instead of using createCurb.
Storage
Policies
SpendLimitPolicyclass →Blocks any payment that would breach the per-task or rolling daily budget.
CounterpartyAllowlistPolicyclass →Blocks payments to any account not on the allowlist.
ApprovalTierPolicyclass →Tiered human-in-the-loop: auto-approve below autoUnder; block until a human approves at/above it. Each approval is single-use.
CurbAuditHookclass →Records every settled payment on HCS and commits the spend hold (advances the daily counter).
Policy versioning (HCS-2)
createAuditTopicfunction →Create an immutable HCS audit topic (no admin key, so its config can never change).
createPolicyRegistryfunction →Create an HCS-2 indexed registry topic for policy versions, with an owner-only submit key.
publishPolicyVersionfunction →Publish the current config as a new immutable policy version on the registry.
readPolicyVersionsfunction →Read the full policy version history from the registry via the mirror node (consensus order).
currentPolicyfunction →The current (latest) policy version on the registry, or null if empty.
Audit & helpers
writeRecordfunction →Append an immutable record to the Curb audit topic on HCS.
extractPaymentfunction →Pull the amount + recipients out of a governed transfer’s normalised params.
paymentKeyfunction →Deterministic 16-char key for a payment (agent + recipient + amount) — used for spend holds and approvals.
Config & constants
CurbConfiginterface →The policy config every Curb policy and hook reads.
DEFAULT_CONFIGconstant →The default caps: HBAR · perTask 10 · perDay 25 · autoUnder 3 · approveUnder 10.
GOVERNED_TRANSFER_TOOLSconstant →The value-moving tools Curb governs: transfer_hbar (custodial) and transfer_hbar_with_allowance (non-custodial).
Types
Curbinterface →What createCurb returns.
CurbDepsinterface →What every policy and hook needs at construction.
ApprovalStatustype →The lifecycle of a payment that needs human approval.
ApprovalMetainterface →Optional context stored with a pending approval (used by setApproval on the interface).
PaymentIntentinterface →What extractPayment returns — the value and recipients of a governed transfer.
PolicySnapshotinterface →The policy fields versioned on-chain (returned by publishPolicyVersion).
PolicyVersioninterface →A single on-chain policy version (returned by readPolicyVersions / currentPolicy).
CurbRecordinterface →One immutable line in the HCS audit trail (returned by writeRecord).