diff --git a/crates/js_api/src/gui/mod.rs b/crates/js_api/src/gui/mod.rs index 8dc8de73b..29a48d6ed 100644 --- a/crates/js_api/src/gui/mod.rs +++ b/crates/js_api/src/gui/mod.rs @@ -160,9 +160,28 @@ impl DotrainOrderGui { #[wasm_bindgen(js_name = "getAllTokenInfos")] pub async fn get_all_token_infos(&self) -> Result { - let token_infos = self.dotrain_order.orderbook_yaml().get_token_keys()?; + let select_tokens = self.get_select_tokens()?; + + let token_keys = match select_tokens.0.is_empty() { + true => { + let order_key = DeploymentCfg::parse_order_key( + self.dotrain_order.dotrain_yaml().documents, + &self.selected_deployment, + )?; + OrderCfg::parse_io_token_keys( + self.dotrain_order.dotrain_yaml().documents, + &order_key, + )? + } + false => select_tokens + .0 + .iter() + .map(|token| token.key.clone()) + .collect(), + }; + let mut result = Vec::new(); - for key in token_infos.iter() { + for key in token_keys.iter() { result.push(self.get_token_info(key.clone()).await?); } Ok(AllTokenInfos(result)) @@ -237,6 +256,8 @@ pub enum GuiError { DepositNotSet(String), #[error("Orderbook not found")] OrderbookNotFound, + #[error("Order not found: {0}")] + OrderNotFound(String), #[error("Deserialized dotrain mismatch")] DotrainMismatch, #[error("Vault id not found for output index: {0}")] diff --git a/crates/js_api/src/gui/select_tokens.rs b/crates/js_api/src/gui/select_tokens.rs index dd5d02960..76a8f92d8 100644 --- a/crates/js_api/src/gui/select_tokens.rs +++ b/crates/js_api/src/gui/select_tokens.rs @@ -6,7 +6,7 @@ use rain_orderbook_app_settings::{ use std::str::FromStr; #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Tsify)] -pub struct SelectTokens(Vec); +pub struct SelectTokens(pub Vec); impl_wasm_traits!(SelectTokens); #[wasm_bindgen] diff --git a/crates/settings/src/order.rs b/crates/settings/src/order.rs index 3b05cbddf..3517bc543 100644 --- a/crates/settings/src/order.rs +++ b/crates/settings/src/order.rs @@ -2,7 +2,7 @@ use crate::{yaml::FieldErrorKind, *}; use alloy::primitives::{private::rand, U256}; use serde::{Deserialize, Serialize}; use std::{ - collections::HashMap, + collections::{BTreeSet, HashMap}, str::FromStr, sync::{Arc, RwLock}, }; @@ -434,6 +434,41 @@ impl OrderCfg { Ok(vault_ids) } + + pub fn parse_io_token_keys( + documents: Vec>>, + order_key: &str, + ) -> Result, YamlError> { + let mut token_keys = BTreeSet::new(); + + for document in documents { + let document_read = document.read().map_err(|_| YamlError::ReadLockError)?; + + if let Ok(orders_hash) = require_hash(&document_read, Some("orders"), None) { + if let Some(order_yaml) = + orders_hash.get(&StrictYaml::String(order_key.to_string())) + { + let location = format!("order '{}'", order_key); + + let inputs = require_vec(order_yaml, "inputs", Some(location.clone()))?; + let outputs = require_vec(order_yaml, "outputs", Some(location.clone()))?; + + for input in inputs { + let token_key = + require_string(input, Some("token"), Some(location.clone()))?; + token_keys.insert(token_key); + } + for output in outputs { + let token_key = + require_string(output, Some("token"), Some(location.clone()))?; + token_keys.insert(token_key); + } + } + } + } + + Ok(token_keys.into_iter().collect()) + } } impl YamlParsableHash for OrderCfg { diff --git a/crates/settings/src/yaml/dotrain.rs b/crates/settings/src/yaml/dotrain.rs index 4aac4842e..582e2c081 100644 --- a/crates/settings/src/yaml/dotrain.rs +++ b/crates/settings/src/yaml/dotrain.rs @@ -320,6 +320,11 @@ mod tests { OrderCfg::parse_vault_ids(dotrain_yaml.documents.clone(), &order.key, false).unwrap(); assert_eq!(output_vault_ids.len(), 1); assert_eq!(output_vault_ids[0], Some("2".to_string())); + let io_token_keys = + OrderCfg::parse_io_token_keys(dotrain_yaml.documents.clone(), &order.key).unwrap(); + assert_eq!(io_token_keys.len(), 2); + assert_eq!(io_token_keys[0], "token1"); + assert_eq!(io_token_keys[1], "token2"); let scenario_keys = dotrain_yaml.get_scenario_keys().unwrap(); assert_eq!(scenario_keys.len(), 3);