Skip to content

feat(rpc): implement typed simulate_transaction method (#99)#112

Open
Sendi0011 wants to merge 5 commits intoToolbox-Lab:mainfrom
Sendi0011:feat/simulate-transaction-rpc
Open

feat(rpc): implement typed simulate_transaction method (#99)#112
Sendi0011 wants to merge 5 commits intoToolbox-Lab:mainfrom
Sendi0011:feat/simulate-transaction-rpc

Conversation

@Sendi0011
Copy link
Copy Markdown


feat(rpc): implement typed simulate_transaction method — closes #99

What changed

The existing simulate_transaction stub returned a raw serde_json::Value, giving callers no type safety and forcing them to manually dig through JSON to extract footprint/auth data. This PR replaces it with a fully typed implementation.

Key additions in crates/core/src/network/rpc.rs:

  • SimulateTransactionResponse — top-level typed response matching the Soroban RPC spec, with fields for soroban_data (the SorobanTransactionData XDR to stamp onto the tx), min_resource_fee, auth entries, per-invocation results, diagnostic events, and cost estimates
  • SimulateResult — per-invocation return value XDR + auth entries
  • SimulateCost, SimulateFootprint, SimulateAuthEntry, SimulateSorobanData — supporting types
  • simulate_transaction now returns PrismResult<SimulateTransactionResponse> — simulation-level errors (the error field in the response) are surfaced as PrismError::RpcError so callers get a proper Rust error without inspecting the struct
  • is_success() and return_value_xdr() convenience methods on the response

crates/core/src/network/mod.rs: re-exports the public simulation types for ergonomic access as prism_core::network::SimulateTransactionResponse etc.

How to use after this PR:

let client = RpcClient::new(NetworkConfig::testnet());
let sim = client.simulate_transaction(&unsigned_tx_xdr).await?;

// Stamp the transaction before submission
let soroban_data_xdr = sim.soroban_data.unwrap();
let min_fee = sim.min_resource_fee.unwrap();

// Collect auth entries to sign
for auth_xdr in &sim.auth {
    // sign or attach as-is for invoker auth
}

Replace the raw serde_json::Value stub with a fully typed implementation
of the simulateTransaction Soroban RPC method.

Changes:
- Add SimulateTransactionResponse struct with all fields from the
  Soroban RPC spec: soroban_data (transactionData XDR), min_resource_fee,
  auth entries, per-invocation results, diagnostic events, and cost estimates
- Add supporting types: SimulateResult, SimulateCost, SimulateFootprint,
  SimulateAuthEntry, SimulateSorobanData
- simulate_transaction now returns PrismResult<SimulateTransactionResponse>
  instead of PrismResult<serde_json::Value>
- Simulation-level errors (response.error field) are surfaced as
  PrismError::RpcError so callers get a proper Rust error
- Add is_success() and return_value_xdr() convenience methods on the
  response type
- Re-export public simulation types from network::mod for ergonomic access

Closes Toolbox-Lab#99
@drips-wave
Copy link
Copy Markdown

drips-wave bot commented Mar 28, 2026

@Sendi0011 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

- main upgraded call() to generic call<T: Deserialize> and added typed
  GetTransactionResponse — kept those changes in full
- adapted simulate_transaction to use the new generic call<T> directly
  instead of going through serde_json::Value, removing the intermediate
  from_value() step
- all other main changes (address types, xdr codec, config updates) merged cleanly
@Emrys02 Emrys02 self-requested a review March 29, 2026 06:48
Copy link
Copy Markdown
Contributor

@Emrys02 Emrys02 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Sendi0011 PR reviewed

@Emrys02
Copy link
Copy Markdown
Contributor

Emrys02 commented Mar 29, 2026

@Sendi0011 please resolve conflicts

Main renamed RpcClient to SorobanRpcClient, changed constructor to take
&NetworkConfig, added reqwest headers, and made JsonRpcRequest generic.
Also fixed several bugs in main's call() (wrong variable names: envelope,
response_body, rpc_resp, self.config.rpc_url).

Resolution:
- Keep our typed SimulateTransactionResponse + simulate_transaction impl
- Adopt main's SorobanRpcClient struct, new(&NetworkConfig), and improved call()
- Fix all callers: state.rs, decode/mod.rs, contract_error.rs, serve.rs
- get_transaction now returns GetTransactionResponse; updated callers accordingly
- Drop duplicate struct definitions and broken test blocks from main
@Sendi0011
Copy link
Copy Markdown
Author

@Sendi0011 please resolve conflicts

Gm @Emrys02 i have resolve the conflicts

…/state.rs

Conflicts were minor — main renamed tx_data -> tx_response in decode/mod.rs
and replay/state.rs, and still had the envelope/rpc_resp bugs plus duplicate
struct definitions in rpc.rs. Kept our typed simulate_transaction, fixed all
bugs, merged duplicate test blocks into one.
@Emrys02
Copy link
Copy Markdown
Contributor

Emrys02 commented Mar 29, 2026

@Sendi0011 I merged a PR before yours, please fix conflict, i will merge this to avoid more conflict

Main cleaned up the file (removed doc comments on private items, dropped
explicit ::<serde_json::Value> turbofish, added HTTP non-2xx error check).
Kept our typed simulate_transaction impl and simulate tests, adopted all
other improvements from main.
@Sendi0011
Copy link
Copy Markdown
Author

Gm @Emrys02 all conflicts resolved

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement simulate_transaction method in SorobanRpcClient

2 participants