stellar-agent-guard-sdk
v0.1.0
Published
Integration bridge between AI agent frameworks and stellar-agent-guard smart accounts: pre-flight policy interception, agent-auth transaction signing, cost pre-checks, and on-chain event telemetry. Full recipient/amount enforcement — spend caps, allowlist
Maintainers
Readme
Stellar Agent Guard — SDK
Non-custodial TypeScript SDK and pre-flight policy interception firewall for AI agents on Stellar.
An autonomous agent holding a wallet has a single point of failure: one prompt-injection or one buggy loop can drain it. Stellar Agent Guard makes that impossible on-chain — the agent's funds stay in its own smart account, and every transaction the account must authorize is intercepted by the contract's __check_auth and rejected pre-broadcast unless it satisfies the operator's installed policy: per-transaction spend caps, a rolling-window spend limit, recipient/asset allowlists, protocol allowlists, a pause switch, and a dead-man switch. This SDK provides the integration layer: pre-flight simulation interception, zero-broadcast fee estimation, agent-auth transaction signing, and dual-stream event telemetry for AI agent frameworks (LangChain, ElizaOS).
Status: Phase 2 complete. All five enforcement scenarios were proven against live Stellar testnet (protocol 28) with real contract IDs, transaction hashes, and diagnostic events — evidence is recorded in tests/fixtures/integration-evidence.md. Phase 2 code is merged into main with green CI (ci status check). The package is verified via npm pack (stellar-agent-guard-sdk-0.1.0.tgz), publish-ready pending maintainer npm registry credentials.
🎯 What makes this different
Enforcement happens inside the account itself, via Soroban's native Custom Account Abstraction — not in a wrapper contract in front of funds, and not in an off-chain service.
- Pre-flight simulation without broadcast: The SDK evaluates guard approval against Soroban RPC before a single byte hits the network. If the transaction violates policy, it is rejected client-side with the contract's own reason code, incurring zero network fees.
- Dual-stream telemetry: Blocked decisions never commit to the ledger because Soroban rolls back failed authorizations. A listener that only tails committed ledger events sees a guard that appears to approve everything. The SDK extracts
event_auth_checkedfrom simulation diagnostics as well as committed blocks. - In-process simulation pricing:
CostPreCheckercomputes network resource and inclusion fees directly from the enforced simulation, avoiding dependencies on external profiling tools. - Framework middleware: Plug-and-play middleware for LangChain and validators for ElizaOS halt execution before external tool calls run.
⚠️ Disclaimer: This is unaudited security tooling that gates real fund access. Do not deploy to mainnet without an independent audit. See the contracts repo's SECURITY.md.
What it does
- Pre-flight policy interception (
PreFlightInterceptor): Intercepts contract calls before broadcast, simulates auth authorization, and returns a discriminatedadmissible,blocked, orundeterminedverdict. Never throws on policy refusal. - In-process cost pre-checking (
CostPreChecker): Prices transaction execution from simulation results, reporting resource fees, inclusion fees, and total fees against an optional ceiling. - Autonomous transaction execution (
invoke()): Executes the full Soroban lifecycle: probe simulation, auth signing for custom accounts, enforced simulation, and broadcast with bounded retry for stale ledger resource limits (scecExceededLimit). - Framework adapters:
createLangChainGuardMiddleware: Halts tool execution if the interceptor blocks the planned action.createGuardValidator: ElizaOS action validator returning boolean verdicts before actions run.
- Telemetry listener (
GuardTelemetryListener): Tails both committed events and diagnostic streams, decoding contract topics and reason codes.
Quick Start
Installation
Not yet on the npm registry. The package is publish-ready but awaiting registry credentials, so
npm install stellar-agent-guard-sdkcurrently returnsE404. Build from source (Node 24+) until it is published:
git clone https://github.com/aigbagbobila/stellar-agent-guard-sdk.git
cd stellar-agent-guard-sdk
npm ci
npm run buildOnce the registry publish lands, installation will be:
npm install stellar-agent-guard-sdkPre-flight Policy Interception
import { Keypair, rpc } from "@stellar/stellar-sdk";
import { PreFlightInterceptor } from "stellar-agent-guard-sdk";
const interceptor = new PreFlightInterceptor({
server: new rpc.Server("https://soroban-testnet.stellar.org"),
networkPassphrase: "Test SDF Network ; September 2015",
guard: "CAPADGEK457RHKN4RYVUMDJTFHDSG7R5HREQONKLYK7MFKC5WFENPP44",
agent: Keypair.fromSecret(process.env.AGENT_SECRET!),
source: Keypair.fromSecret(process.env.SOURCE_SECRET!),
});
const decision = await interceptor.check({
contractId: "CDCYDGBGS5AZ5BZS6XY2SK2PHJHSOEGTN3N4INCK34KF6GU2BGC7Z6MB",
method: "transfer",
args: [/* from, to, amount */],
});
if (decision.kind === "admissible") {
console.log("Allowed! Resource fee:", decision.estimatedResourceFee);
} else if (decision.kind === "blocked") {
console.log("Blocked by guard:", decision.reason);
} else {
console.log("Undetermined (fails closed)");
}Framework Middleware (LangChain & ElizaOS)
import {
createLangChainGuardMiddleware,
createGuardValidator,
} from "stellar-agent-guard-sdk";
// LangChain: intercept agent tool calls
const middleware = createLangChainGuardMiddleware({
interceptor,
toContractCall: (request) => ({
contractId: request.args.token,
method: "transfer",
args: [request.args.from, request.args.to, request.args.amount],
}),
});
// ElizaOS: validate action before execution
const validate = createGuardValidator({
interceptor,
toContractCall: (message) => ({
contractId: message.content.token,
method: "transfer",
args: [message.content.from, message.content.to, message.content.amount],
}),
});API Reference
Interception & Execution
PreFlightInterceptorconstructor(options: PreFlightInterceptorOptions)check(call: ContractCall): Promise<PreFlightDecision>— Returnsadmissible | blocked | undeterminedwithout throwing or broadcasting.assertAllowed(call: ContractCall): Promise<AdmissibleDecision>— Asserts allowed or throwsGuardBlockedError.
CostPreCheckerconstructor(options: CostPreCheckerOptions)check(call: ContractCall): Promise<CostPreCheckResult>— Returnswithin_budget | over_budget | blocked | undetermined.
invoke(options: InvokeOptions): Promise<InvokeResult>— End-to-end pipeline: probe, sign auth, simulate, and broadcast.
Telemetry & Helpers
GuardTelemetryListenerconstructor(options: GuardTelemetryListenerOptions)watch(signal?: AbortSignal): AsyncIterable<GuardEventPage>— Tails on-chain and uncommitted events.
policyToScVal(policy: GuardPolicy): xdr.ScVal— Encodes policy into Soroban sorted ScVal struct.decodeCheckResult(resultVal: xdr.ScVal): CheckResult— DecodesAllowedorBlocked(reason).decodeAuthDecision(event: SorobanRpc.Api.GetEventsResponse.Event): AuthDecisionEvent | nullguardEventsFromDiagnostics(events: xdr.DiagnosticEvent[]): GuardEvent[]explainReason(reason: string | number): string— Human-readable explanation of contract reason codes.isDeadManFrozen(status: AccountStatus | null, policy: GuardPolicy | null, nowSecs?: number): booleandeadManRemaining(status: AccountStatus | null, policy: GuardPolicy | null, nowSecs?: number): number | null
Architecture
Stellar Agent Guard operates across three dedicated repositories:
┌─────────────────────────────────────────────────────────────────────────┐
│ Operator (Browser / Freighter) │
│ │ │
│ ▼ │
│ stellar-agent-guard-dashboard (Next.js / UI) │
└─────────────────────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ AI Agent Runtime (LangChain / ElizaOS) │
│ │ │
│ ▼ │
│ stellar-agent-guard-sdk (TypeScript / RPC) │
│ • Pre-flight policy check • Cost pre-checks │
│ • Agent-auth tx signing • Event telemetry │
└─────────────────────────────────────┬───────────────────────────────────┘
│
▼ Soroban RPC
┌─────────────────────────────────────────────────────────────────────────┐
│ stellar-agent-guard-contracts (Soroban / Rust) │
│ • CustomAccount interface (`__check_auth`) │
│ • Spend caps, rolling window, allowlists, dead-man switch │
└─────────────────────────────────────────────────────────────────────────┘| Repository | Role | Documentation | |---|---|---| | stellar-agent-guard-contracts | Soroban smart contracts implementing Custom Account Abstraction and spending policy firewall | GitBook Docs | | stellar-agent-guard-sdk (this repo) | TypeScript SDK for pre-flight interception, simulation pricing, and AI agent framework integration | GitHub | | stellar-agent-guard-dashboard | Client-side operator dashboard for policy deployment, inspection, and emergency panic-button freeze | GitHub |
✅ Verified against live testnet
Proven against a real deployed instance on Stellar testnet (protocol 28, Test SDF Network ; September 2015):
- Guard (custom account):
CAPADGEK457RHKN4RYVUMDJTFHDSG7R5HREQONKLYK7MFKC5WFENPP44 - SAC Token:
CDCYDGBGS5AZ5BZS6XY2SK2PHJHSOEGTN3N4INCK34KF6GU2BGC7Z6MB - WASM bytecode hash:
f47919f92e78fdd034836aa61955fc338dd56a218c448c37df1867a8c3da0f63(identical to Phase 1 artifact)
5/5 Live Enforcement Scenarios
| Scenario | Condition | Result | Evidence |
|---|---|---|---|
| 1. Within caps | Transfer 100 within caps (cap: 1000, window: 150) | Allowed | Tx hash 5e45d989bea859aae954c9a57e08909c1c90bdbfb909071f69709875b52f1bd2 at ledger 4674156 |
| 2. Per-tx cap | Transfer 1001 > 1000 cap | Blocked (per_tx_cap_exceeded) | Diagnostic event event_auth_checked, blocked, per_tx_cap_exceeded, pre-broadcast, 0 fees |
| 3. Rolling window | Transfer 76 + 76 = 152 > 150 window cap | Blocked (window_cap_exceeded) | Rolling window accumulation refusal, balances untouched |
| 4. Recipient allowlist | Transfer to unlisted recipient | Blocked (recipient_not_allowed) | Default-deny address check refusal |
| 5. Account paused | Call while paused = true | Blocked (paused) | Account-state refusal cleanly distinguished from policy caps |
Complete run output and assertion logs are preserved in tests/fixtures/integration-evidence.md.
Honest limitations
- Enforcement boundary for arbitrary calls: Full amount/recipient limits are native to SAC token transfers. Arbitrary Soroban contract calls are enforced via protocol/function allowlists, active window, pause, and dead-man switches; per-call amount limits are not available generically from host auth contexts (tracked as v2).
- AutoGPT integration: AutoGPT lacks an extensible pre-execution interceptor hook at the surveyed revision; findings and future integration paths are documented in
docs/integration-hooks.md. - Testnet signing credentials: Running
npm run test:integrationrequires.env.phase2populated with funded testnet keypairs. When absent, CI explicitly skips the live suite with a formal notice rather than reporting a false pass.
Enforcement scope — read this before relying on the caps
Full recipient/amount enforcement — spend caps, allowlists, per-transaction limits — is native and automatic for SAC token transfers (transfer/transfer_from), since these are the calls whose arguments the Soroban auth context exposes for inspection. For other Soroban contract calls made by the guarded account (arbitrary DEX/lending/protocol calls), the policy engine still enforces window and pause state, but per-call amount/recipient limits are not yet enforced — extending fine-grained enforcement to arbitrary calls is tracked as a v2 item, not implied as already covered.
This boundary is an inherent property of the platform (the auth context does not expose arbitrary call arguments generically), not a gap this project hides or overclaims. The classification that produces this boundary (AssetTransfer vs Protocol vs Unknown default-deny) is spelled out in SPEC §6.
Maintainers
| Name | GitHub | Telegram | |---|---|---| | Hybrid | @aigbagbobila | @aigbagbobila |
Socials
Contact
- GitHub issues: https://github.com/aigbagbobila/stellar-agent-guard-sdk/issues
- Maintainer (GitHub): @aigbagbobila
- Security disclosures: see SECURITY.md (Telegram, the Stellar ecosystem norm)
License
Licensed under MIT. This is unaudited security tooling that gates real fund access — see the contracts repo's SECURITY.md before considering mainnet use.
Contributing
See CONTRIBUTING.md for details on coding standards, PR process, and project structure — including the strict one-commit-per-logical-unit rule.
Looking for something to work on? The issue backlog holds scoped issues with Summary / Acceptance Criteria / Tech Stack — good first tasks for the Drips Stellar Wave contributor sprints.
