Skip to content

[Task]: Map CleverVault contract error codes to typed errors in the vault client #89

Description

@grantfox-oss

The contract returns a #[contracterror] VaultError enum with stable numeric discriminants (lib.rs:112AlreadyInitialized = 1NotYourOrchestrator = 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

  • Client throws a typed error exposing the mapped code + the original raw error for contract reverts
  • Non-contract failures are not mis-classified as VaultErrors
  • Unknown codes are preserved and marked unknown
  • A CI-enforced check fails if the TS mirror and Rust VaultError diverge
  • npm test passes; the sync requirement is noted in docs/development.md

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions