simulator-api 0.16.0

Wire-protocol types for the Solana simulator backtest WebSocket API
Documentation
//! Pins the `AgentParams` JSON wire contract. The address-shaped fields are
//! typed `Address` behind `DisplayFromStr`, so they must still serialize as
//! base58 strings — clients and the `--agents-json` sidecar arg depend on it.

use simulator_api::AgentParams;

/// Same shape as the reroute/agent e2e fixture.
const AGENTS_JSON: &str = r#"[
  {
    "agentType": "arb",
    "wallet": "JDc3SSoX3BoTRZHvkbzoG7zRfMViYCT7VGbXsgDHHpKh",
    "seedSolLamports": 100000000000000,
    "seedTokenAccounts": {
      "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v": 100000000000
    },
    "arbRoutes": [
      {
        "baseMint": "So11111111111111111111111111111111111111112",
        "tempMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
        "buyDexes": ["BiSoNHVpsVZW2F7rx2eQ59yQwKxzU5NvBcmKshCSUypi"],
        "sellDexes": [],
        "minInput": 1000000,
        "maxInput": 10000000000,
        "minProfit": 10000
      }
    ]
  }
]"#;

#[test]
fn address_fields_round_trip_as_base58() {
    let agents: Vec<AgentParams> = serde_json::from_str(AGENTS_JSON).expect("parse");
    let agent = &agents[0];
    assert_eq!(
        agent.wallet.expect("wallet").to_string(),
        "JDc3SSoX3BoTRZHvkbzoG7zRfMViYCT7VGbXsgDHHpKh"
    );
    assert_eq!(
        agent.arb_routes[0].base_mint.to_string(),
        "So11111111111111111111111111111111111111112"
    );

    let mut round_tripped: serde_json::Value =
        serde_json::from_str(&serde_json::to_string(&agents).expect("serialize")).expect("json");
    // `keypair` carries no skip_serializing_if, so an absent one emits `null`.
    round_tripped[0]
        .as_object_mut()
        .expect("object")
        .remove("keypair");

    let original: serde_json::Value = serde_json::from_str(AGENTS_JSON).expect("json");
    assert_eq!(original, round_tripped);
}

#[test]
fn a_malformed_address_is_rejected_at_deserialization() {
    // Previously this parsed fine and was dropped later with only a warn!, so an
    // agent silently seeded nothing.
    let bad = r#"[{"agentType":"arb","wallet":"not-a-real-address","arbRoutes":[]}]"#;
    assert!(serde_json::from_str::<Vec<AgentParams>>(bad).is_err());
}