The contract returns a #[contracterror] VaultError enum with stable numeric discriminants (lib.rs:112 — AlreadyInitialized = 1 … NotYourOrchestrator = 17, and growing as new issues land). When packages/orchestrator/src/agent-vault-client.ts invokes the contract and a call reverts, the failure comes back as a raw Soroban host error carrying that numeric code. Today it surfaces as an opaque string, so the orchestrator cannot distinguish, say, InsufficientAvailable (retryable after a deposit) from TaskAlreadyCompleted (terminal) — and neither can a log reader.
Goal
Parse the numeric contract error out of the failed invocation and surface it as a typed error the caller can branch on (e.g. switch (err.code)), without losing the original raw error.
Requirements & constraints
- Provide a client-side representation of the contract's error codes that mirrors
VaultError's variants and discriminants exactly.
- Unknown/unmapped codes must be preserved (surfaced as-is), never swallowed — the enum will keep growing, and a client built against an older list must degrade gracefully.
- The two enums (Rust
VaultError and the TS mirror) will drift over time; the core deliverable is a mechanism that makes drift visible. Prefer a test or generation step that fails when they diverge, rather than a hand-maintained copy with a comment.
Design decisions left to the implementer
- Sync mechanism. Options: parse
lib.rs in a unit test and assert the TS enum matches; generate the TS enum from the Rust source at build time; or a shared JSON manifest both consume. Pick one, justify it, and make CI enforce it.
- How to reliably extract the numeric code from the Soroban/RPC error object shape returned on revert (simulation vs send paths may differ — handle both).
Edge cases to consider
- A revert whose error is not a contract error (network failure, auth failure) must not be mis-mapped to a
VaultError.
- An error code higher than any known variant (newer contract than client) → preserved, flagged as unknown.
Acceptance criteria
Relevant files
packages/orchestrator/src/agent-vault-client.ts, contracts/agent-vault/src/lib.rs (reference), docs/development.md
Notes for contributors
If you'd like to work on this, comment below so we can assign it to you.
Questions welcome — see CONTRIBUTING.md for setup
and workflow.
The contract returns a
#[contracterror] VaultErrorenum with stable numeric discriminants (lib.rs:112—AlreadyInitialized = 1…NotYourOrchestrator = 17, and growing as new issues land). Whenpackages/orchestrator/src/agent-vault-client.tsinvokes the contract and a call reverts, the failure comes back as a raw Soroban host error carrying that numeric code. Today it surfaces as an opaque string, so the orchestrator cannot distinguish, say,InsufficientAvailable(retryable after a deposit) fromTaskAlreadyCompleted(terminal) — and neither can a log reader.Goal
Parse the numeric contract error out of the failed invocation and surface it as a typed error the caller can branch on (e.g.
switch (err.code)), without losing the original raw error.Requirements & constraints
VaultError's variants and discriminants exactly.VaultErrorand the TS mirror) will drift over time; the core deliverable is a mechanism that makes drift visible. Prefer a test or generation step that fails when they diverge, rather than a hand-maintained copy with a comment.Design decisions left to the implementer
lib.rsin a unit test and assert the TS enum matches; generate the TS enum from the Rust source at build time; or a shared JSON manifest both consume. Pick one, justify it, and make CI enforce it.Edge cases to consider
VaultError.Acceptance criteria
VaultErrorsVaultErrordivergenpm testpasses; the sync requirement is noted indocs/development.mdRelevant files
packages/orchestrator/src/agent-vault-client.ts,contracts/agent-vault/src/lib.rs(reference),docs/development.mdNotes for contributors
If you'd like to work on this, comment below so we can assign it to you.
Questions welcome — see CONTRIBUTING.md for setup
and workflow.