Skip to content

Live on Stellar testnet

Agents pay.Within limits.You decide.

Halora gives every AI agent a Stellar wallet with limits it cannot break. Each payment is checked on-chain by the account contract before any money moves.

~5s
Settlement on Stellar
<$0.01
Network fee per payment
0
Keys held by Halora

Illustration: payments leave the agent and meet the policy ring. Allowed payments pass, denied ones fall back, and held ones wait for the owner.

  • 0.25 USDC to WeatherlyALLOWED
  • 18.00 USDC to MapTileHELD FOR OWNER
  • 0.02 USDC to SearchwiseALLOWED
  • 500.00 USDC to GBX7Q2DENIED: RecipientNotAllowed
  • 1.40 USDC to WeatherlyALLOWED
  • 60.00 USDC to SearchwiseDENIED: PerTxLimitExceeded

[01] Live policy check

Try to break the rules.The contract holds.

Type what an agent wants to pay. These are the real checks the SDK runs before signing, in the same order as the account contract.

halora / policy-check

policy per_tx=25 daily=100 approval>10 allowlist=4 spent_today=41.30

  1. [01]Recipient is on the allowlistWeatherlyPASS
  2. [02]Within the per payment limit0.25 USDC of 25 USDCPASS
  3. [03]Within the daily limit41.55 USDC of 100 USDC todayPASS
  4. [04]Below the approval thresholdUnder 10 USDCPASS
ALLOWED0.25 USDC to Weatherly

Settles in about 5 seconds. 58.45 USDC left today.

Try one

The last example is a prompt injection. The agent may believe it. The contract only sees an unknown recipient.

[02] What the contract enforces

Rules an agentcannot talk past.

Enforced in the account contract, not in the agent, the SDK or our servers. If any of them is compromised, the rules still hold.

  • [001]

    Per payment limit

    No single transfer can exceed it, however the agent phrases the request.

    per_tx_limit
  • [002]

    Daily limit

    The contract counts every transfer of the UTC day and refuses the one that crosses the line.

    daily_limit
  • [003]

    Recipient allowlist

    Only addresses you approved can be paid. A prompt injection cannot add one.

    allowlist
  • [004]

    Owner approval

    Above your threshold a payment waits until you approve it on-chain. The approval works once.

    approval_threshold
  • [005]

    Pause switch

    Stop every agent payment with one signature, and resume when you are ready.

    paused
  • [006]

    Expiry

    The agent key stops working on a date you choose. It can never change its own rules.

    expires_at

Enforced on-chainNo keys heldOpen source

[03] Getting started

Minutes to set up.Safe all day after.

Three steps from nothing to an agent that pays for what it needs, and never more.

  1. [01]

    Set the rules

    ~2 min

    Create the agent wallet from the dashboard and choose its limits. Your wallet signs the deployment; you stay the owner.

    > client.deployAccount({ owner, agentPublicKey, policy })
  2. [02]

    Connect the agent

    ~5 min

    Give the agent its own key through the TypeScript SDK or the MCP server. That key can pay within the rules and nothing else.

    > bunx @halora/mcp
  3. [03]

    Let it pay

    ~5 s per payment

    The agent pays for APIs and data on its own, including x402 pay-per-request. Larger payments wait in your approval inbox.

    > agent.fetch('https://api.weatherly.dev/forecast')

[04] For developers

A few linesin your agent.

Install the SDK, or add the MCP server to any MCP client such as Claude. Both check the policy before signing and name the rule a payment broke. Paying an API that answers with HTTP 402 is one call, and the agent needs no XLM for fees.

agent / sessionmcp: halora
  1. Get tomorrow's forecast for Lisbon and a tile map of the route.
  2. halora_fetch_paidapi.weatherly.dev/forecast

    Paid 0.25 USDC to Weatherly. 58.45 USDC left today.

  3. halora_pay18 USDC to MapTile

    Above your 10 USDC threshold. I asked the owner to approve it and will continue once they do.

$ bun add @halora/sdk
agent.ts
import { HaloraAgent } from '@halora/sdk';

const agent = new HaloraAgent({
  contractId: 'C...YOUR_AGENT_ACCOUNT',
  agentSecret: process.env.HALORA_AGENT_SECRET!,
  network: 'testnet',
  apiUrl: 'https://api.halora.dev',
  apiKey: process.env.HALORA_API_KEY,
});

// Pays on HTTP 402 within the policy, then retries the request.
const res = await agent.fetch('https://api.example.com/v1/report');

// Direct payment. Above the approval threshold it waits for the owner.
const result = await agent.pay({
  to: 'G...RECIPIENT',
  amount: 2_500_000n, // 0.25 USDC (7 decimals)
  reason: 'Weather data for the trip planner',
});

[05] Built on Stellar

Built with

Built with Stellar, Soroban, USDC, x402, the Model Context Protocol and Freighter.

On Stellar a payment for a single API call still makes sense: fees are a fraction of a cent and payments settle in about 5 seconds.

What Halora does not do. It never holds your keys, and it does not stop an agent key from leaking. It limits what a leaked or manipulated key can spend.

Give your agenta halo.

Create a wallet, set its rules and connect your agent on Stellar testnet. No sign-up: a Stellar wallet is your login, or explore with demo data.