Skip to main content

validate_toolset_tool_args

Function validate_toolset_tool_args 

Source
pub fn validate_toolset_tool_args(args: &Value) -> Result<(), ToolsetArgsError>
Expand description

Validate a toolset tool argument payload before dispatch.

Performs an iterative, depth-bounded walk over args:

  • Value::Object: each key is checked against ARGS_KEY_DENYLIST. A match returns Err(ToolsetArgsError::DangerousKey { matched_key }) where matched_key is the matched &'static str constant (NOT the input key string — the error is redaction-clean). Object values are pushed onto the work-stack for further traversal.
  • Value::Array: each element is pushed onto the work-stack. Objects nested inside arrays ARE key-checked when popped.
  • Value::String / Value::Number / Value::Bool / Value::Null: no-op (scalars carry no keys to check).
  • Depth > TOOLSET_ARGS_MAX_DEPTH: returns Err(ToolsetArgsError::NestingTooDeep).
  • Total nodes visited > TOOLSET_ARGS_MAX_NODES: returns Err(ToolsetArgsError::TooManyNodes).

The walk is allocation-light: the work-stack holds &Value BORROWS of the original tree (no cloning of the payload). The stack capacity is bounded by TOOLSET_ARGS_MAX_NODES.

§Caller contract (mutation-before-guard invariant)

The caller MUST pass the FINAL post-injection Value (after all chain_id and envelope_xdr insertions). No further mutation or serde round-trip should occur between this call and serde_json::from_value::<TypedArgs>.

§Errors

§Examples

use stellar_agent_toolsets::validate_toolset_tool_args;
use serde_json::json;

// Benign payload passes.
let ok = validate_toolset_tool_args(&json!({ "account_id": "GAAZI4TCR3TY5OJHCTJC2A4QSY6CJWJH5IAJTGKIN2ER7LBNVKOCCWN" }));
assert!(ok.is_ok());

// Dangerous key rejected.
let err = validate_toolset_tool_args(&json!({ "toJSON": "value" }));
assert!(err.is_err());