From f4844bab9d2731661e464d3678acb184795aedfd Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Fri, 1 Mar 2024 00:52:36 +0000 Subject: [PATCH 01/48] update --- crates/common/src/dotrain_add_order_lsp.rs | 2 +- crates/common/src/frontmatter.rs | 380 ++++++++++--------- crates/common/src/fuzz/mod.rs | 4 +- tauri-app/src-tauri/Cargo.lock | 1 + tauri-app/src-tauri/src/commands/settings.rs | 7 +- tauri-app/src-tauri/src/error.rs | 5 +- tauri-app/src-tauri/src/main.rs | 3 +- 7 files changed, 214 insertions(+), 188 deletions(-) diff --git a/crates/common/src/dotrain_add_order_lsp.rs b/crates/common/src/dotrain_add_order_lsp.rs index b84555200..a7c7c4a31 100644 --- a/crates/common/src/dotrain_add_order_lsp.rs +++ b/crates/common/src/dotrain_add_order_lsp.rs @@ -24,7 +24,7 @@ pub struct DotrainAddOrderLsp { } impl DotrainAddOrderLsp { - pub fn new(text_document: TextDocumentItem) -> Self { + pub fn new(text_document: TextDocumentItem, config: &Config) -> Self { let frontmatter = RainDocument::get_front_matter(&text_document.text); let rebinds = frontmatter.and_then(try_parse_frontmatter_rebinds); diff --git a/crates/common/src/frontmatter.rs b/crates/common/src/frontmatter.rs index 63512f458..f42800863 100644 --- a/crates/common/src/frontmatter.rs +++ b/crates/common/src/frontmatter.rs @@ -1,5 +1,6 @@ use alloy_primitives::{Address, U256}; use dotrain::Rebind; +use rain_orderbook_app_settings::{merge::MergeError, string_structs::Config}; use rain_orderbook_bindings::IOrderBookV3::IO; use strict_yaml_rust::{scanner::ScanError, StrictYaml, StrictYamlLoader}; use thiserror::Error; @@ -14,197 +15,212 @@ pub enum FrontmatterError { FrontmatterFieldMissing(String), #[error("Frontmatter empty")] FrontmatterEmpty, + #[error(transparent)] + SerdeYamlError(#[from] serde_yaml::Error), + #[error(transparent)] + MergeError(#[from] MergeError), } /// Parse dotrain frontmatter to extract deployer, valid-inputs and valid-outputs #[allow(clippy::type_complexity)] -pub fn try_parse_frontmatter( - frontmatter: &str, -) -> Result<(Address, Vec, Vec, Option>), FrontmatterError> { - // Parse dotrain document frontmatter - let frontmatter_yaml_vec = StrictYamlLoader::load_from_str(frontmatter) - .map_err(FrontmatterError::FrontmatterInvalidYaml)?; - let frontmatter_yaml = frontmatter_yaml_vec - .first() - .ok_or(FrontmatterError::FrontmatterEmpty)?; - - let deployer = frontmatter_yaml["orderbook"]["order"]["deployer"] - .as_str() - .ok_or(FrontmatterError::FrontmatterFieldMissing( - "orderbook.order.deployer".into(), - ))? - .parse::
() - .map_err(|_| { - FrontmatterError::FrontmatterFieldInvalid("orderbook.order.deployer".into()) - })?; - - let valid_inputs: Vec = try_parse_frontmatter_io( - frontmatter_yaml["orderbook"]["order"]["valid-inputs"].clone(), - "valid-inputs", - )?; - let valid_outputs: Vec = try_parse_frontmatter_io( - frontmatter_yaml["orderbook"]["order"]["valid-outputs"].clone(), - "valid-outputs", - )?; - - let rebinds = get_rebinds_from_yaml(frontmatter_yaml); - - Ok((deployer, valid_inputs, valid_outputs, rebinds)) -} +pub fn try_parse_frontmatter(frontmatter: &str) -> Result { + if frontmatter.is_empty() { + return Ok(Config::default()); + } + Ok(frontmatter.try_into()?) + // // Parse dotrain document frontmatter + // let frontmatter_yaml_vec = StrictYamlLoader::load_from_str(frontmatter) + // .map_err(FrontmatterError::FrontmatterInvalidYaml)?; + // let frontmatter_yaml = frontmatter_yaml_vec + // .first() + // .ok_or(FrontmatterError::FrontmatterEmpty)?; -/// parses a yaml text and tries to get rebindings from it -pub fn try_parse_frontmatter_rebinds(frontmatter: &str) -> Option> { - let frontmatter_yaml_vec = StrictYamlLoader::load_from_str(frontmatter).ok()?; - let frontmatter_yaml = frontmatter_yaml_vec.first()?; + // let deployer = frontmatter_yaml["orderbook"]["order"]["deployer"] + // .as_str() + // .ok_or(FrontmatterError::FrontmatterFieldMissing( + // "orderbook.order.deployer".into(), + // ))? + // .parse::
() + // .map_err(|_| { + // FrontmatterError::FrontmatterFieldInvalid("orderbook.order.deployer".into()) + // })?; - get_rebinds_from_yaml(frontmatter_yaml) -} + // let valid_inputs: Vec = try_parse_frontmatter_io( + // frontmatter_yaml["orderbook"]["order"]["valid-inputs"].clone(), + // "valid-inputs", + // )?; + // let valid_outputs: Vec = try_parse_frontmatter_io( + // frontmatter_yaml["orderbook"]["order"]["valid-outputs"].clone(), + // "valid-outputs", + // )?; -/// gets rebindings from a parsed yaml -pub fn get_rebinds_from_yaml(frontmatter_yaml: &StrictYaml) -> Option> { - let mut rebinds = vec![]; - let items = frontmatter_yaml["bind"].as_vec()?; - for item in items { - for (key, value) in item.as_hash()? { - rebinds.push(Rebind(key.as_str()?.to_owned(), value.as_str()?.to_owned())) - } - } - Some(rebinds) + // let rebinds = get_rebinds_from_yaml(frontmatter_yaml); + + // Ok((deployer, valid_inputs, valid_outputs, rebinds)) } -/// Parse an Io array from from frontmatter field (i.e. valid-inputs or valid-outputs) -pub fn try_parse_frontmatter_io( - io_yamls: StrictYaml, - io_field_name: &str, -) -> Result, FrontmatterError> { - io_yamls - .into_vec() - .ok_or(FrontmatterError::FrontmatterFieldMissing(format!( - "orderbook.order.{}", - io_field_name - )))? - .into_iter() - .map(|io_yaml| -> Result { - Ok(IO { - token: io_yaml["token"] - .as_str() - .ok_or(FrontmatterError::FrontmatterFieldMissing(format!( - "orderbook.order.{}.token", - io_field_name - )))? - .parse::
() - .map_err(|_| { - FrontmatterError::FrontmatterFieldInvalid(format!( - "orderbook.order.{}.token", - io_field_name - )) - })?, - decimals: io_yaml["decimals"] - .as_str() - .ok_or(FrontmatterError::FrontmatterFieldMissing(format!( - "orderbook.order.{}.decimals", - io_field_name - )))? - .parse::() - .map_err(|_| { - FrontmatterError::FrontmatterFieldInvalid(format!( - "orderbook.order.{}.decimals", - io_field_name - )) - })?, - vaultId: io_yaml["vault-id"] - .as_str() - .ok_or(FrontmatterError::FrontmatterFieldMissing(format!( - "orderbook.order.{}.vault-id", - io_field_name - )))? - .parse::() - .map_err(|_| { - FrontmatterError::FrontmatterFieldInvalid(format!( - "orderbook.order.{}.vault-id", - io_field_name - )) - })?, - }) - }) - .collect::, FrontmatterError>>() +pub fn get_merged_frontmatter( + frontmatter: &str, + top_config: &Config, +) -> Result { + let mut frontmatter_config = try_parse_frontmatter(frontmatter)?; + frontmatter_config.merge(top_config.clone())?; + Ok(frontmatter_config) } -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_try_parse_rebinds() { - let frontmatter = " -orderbook: - order: - deployer: 0x1111111111111111111111111111111111111111 - valid-inputs: - - token: 0x0000000000000000000000000000000000000001 - decimals: 18 - vault-id: 0x1 - valid-outputs: - - token: 0x0000000000000000000000000000000000000002 - decimals: 18 - vault-id: 0x2 -bind: - - some-binding: 12345 - - some-other-binding: 2e16 - - another-binding: \" some literal string \" -"; - let rebinds = try_parse_frontmatter_rebinds(frontmatter).unwrap(); - let expected = vec![ - Rebind("some-binding".to_owned(), "12345".to_owned()), - Rebind("some-other-binding".to_owned(), "2e16".to_owned()), - Rebind( - "another-binding".to_owned(), - " some literal string ".to_owned(), - ), - ]; - assert_eq!(rebinds, expected) - } +// /// parses a yaml text and tries to get rebindings from it +// pub fn try_parse_frontmatter_rebinds(frontmatter: &str) -> Option> { +// let frontmatter_yaml_vec = StrictYamlLoader::load_from_str(frontmatter).ok()?; +// let frontmatter_yaml = frontmatter_yaml_vec.first()?; - #[test] - fn test_try_parse_frontmatter() { - let frontmatter = " -orderbook: - order: - deployer: 0x1111111111111111111111111111111111111111 - valid-inputs: - - token: 0x0000000000000000000000000000000000000001 - decimals: 18 - vault-id: 0x1 - valid-outputs: - - token: 0x0000000000000000000000000000000000000002 - decimals: 18 - vault-id: 0x2 -"; - - let (deployer, valid_inputs, valid_outputs, _) = - try_parse_frontmatter(frontmatter).unwrap(); - - assert_eq!( - deployer, - "0x1111111111111111111111111111111111111111" - .parse::
() - .unwrap() - ); - assert_eq!( - valid_inputs[0].token, - "0x0000000000000000000000000000000000000001" - .parse::
() - .unwrap() - ); - assert_eq!(valid_inputs[0].decimals, 18); - assert_eq!(valid_inputs[0].vaultId, U256::from(1)); - assert_eq!( - valid_outputs[0].token, - "0x0000000000000000000000000000000000000002" - .parse::
() - .unwrap() - ); - assert_eq!(valid_outputs[0].decimals, 18); - assert_eq!(valid_outputs[0].vaultId, U256::from(2)); - } -} +// get_rebinds_from_yaml(frontmatter_yaml) +// } + +// /// gets rebindings from a parsed yaml +// pub fn get_rebinds_from_yaml(frontmatter_yaml: &StrictYaml) -> Option> { +// let mut rebinds = vec![]; +// let items = frontmatter_yaml["bind"].as_vec()?; +// for item in items { +// for (key, value) in item.as_hash()? { +// rebinds.push(Rebind(key.as_str()?.to_owned(), value.as_str()?.to_owned())) +// } +// } +// Some(rebinds) +// } + +// /// Parse an Io array from from frontmatter field (i.e. valid-inputs or valid-outputs) +// pub fn try_parse_frontmatter_io( +// io_yamls: StrictYaml, +// io_field_name: &str, +// ) -> Result, FrontmatterError> { +// io_yamls +// .into_vec() +// .ok_or(FrontmatterError::FrontmatterFieldMissing(format!( +// "orderbook.order.{}", +// io_field_name +// )))? +// .into_iter() +// .map(|io_yaml| -> Result { +// Ok(IO { +// token: io_yaml["token"] +// .as_str() +// .ok_or(FrontmatterError::FrontmatterFieldMissing(format!( +// "orderbook.order.{}.token", +// io_field_name +// )))? +// .parse::
() +// .map_err(|_| { +// FrontmatterError::FrontmatterFieldInvalid(format!( +// "orderbook.order.{}.token", +// io_field_name +// )) +// })?, +// decimals: io_yaml["decimals"] +// .as_str() +// .ok_or(FrontmatterError::FrontmatterFieldMissing(format!( +// "orderbook.order.{}.decimals", +// io_field_name +// )))? +// .parse::() +// .map_err(|_| { +// FrontmatterError::FrontmatterFieldInvalid(format!( +// "orderbook.order.{}.decimals", +// io_field_name +// )) +// })?, +// vaultId: io_yaml["vault-id"] +// .as_str() +// .ok_or(FrontmatterError::FrontmatterFieldMissing(format!( +// "orderbook.order.{}.vault-id", +// io_field_name +// )))? +// .parse::() +// .map_err(|_| { +// FrontmatterError::FrontmatterFieldInvalid(format!( +// "orderbook.order.{}.vault-id", +// io_field_name +// )) +// })?, +// }) +// }) +// .collect::, FrontmatterError>>() +// } + +// #[cfg(test)] +// mod tests { +// use super::*; + +// #[test] +// fn test_try_parse_rebinds() { +// let frontmatter = " +// orderbook: +// order: +// deployer: 0x1111111111111111111111111111111111111111 +// valid-inputs: +// - token: 0x0000000000000000000000000000000000000001 +// decimals: 18 +// vault-id: 0x1 +// valid-outputs: +// - token: 0x0000000000000000000000000000000000000002 +// decimals: 18 +// vault-id: 0x2 +// bind: +// - some-binding: 12345 +// - some-other-binding: 2e16 +// - another-binding: \" some literal string \" +// "; +// let rebinds = try_parse_frontmatter_rebinds(frontmatter).unwrap(); +// let expected = vec![ +// Rebind("some-binding".to_owned(), "12345".to_owned()), +// Rebind("some-other-binding".to_owned(), "2e16".to_owned()), +// Rebind( +// "another-binding".to_owned(), +// " some literal string ".to_owned(), +// ), +// ]; +// assert_eq!(rebinds, expected) +// } + +// #[test] +// fn test_try_parse_frontmatter() { +// let frontmatter = " +// orderbook: +// order: +// deployer: 0x1111111111111111111111111111111111111111 +// valid-inputs: +// - token: 0x0000000000000000000000000000000000000001 +// decimals: 18 +// vault-id: 0x1 +// valid-outputs: +// - token: 0x0000000000000000000000000000000000000002 +// decimals: 18 +// vault-id: 0x2 +// "; + +// let (deployer, valid_inputs, valid_outputs, _) = +// try_parse_frontmatter(frontmatter).unwrap(); + +// assert_eq!( +// deployer, +// "0x1111111111111111111111111111111111111111" +// .parse::
() +// .unwrap() +// ); +// assert_eq!( +// valid_inputs[0].token, +// "0x0000000000000000000000000000000000000001" +// .parse::
() +// .unwrap() +// ); +// assert_eq!(valid_inputs[0].decimals, 18); +// assert_eq!(valid_inputs[0].vaultId, U256::from(1)); +// assert_eq!( +// valid_outputs[0].token, +// "0x0000000000000000000000000000000000000002" +// .parse::
() +// .unwrap() +// ); +// assert_eq!(valid_outputs[0].decimals, 18); +// assert_eq!(valid_outputs[0].vaultId, U256::from(2)); +// } +// } diff --git a/crates/common/src/fuzz/mod.rs b/crates/common/src/fuzz/mod.rs index 3ee60940d..e12ca58c7 100644 --- a/crates/common/src/fuzz/mod.rs +++ b/crates/common/src/fuzz/mod.rs @@ -175,7 +175,7 @@ b: fuzzed; #handle-io :; "#; - let frontmatter = RainDocument::get_front_matter(&dotrain).unwrap(); + let frontmatter = RainDocument::get_front_matter(dotrain).unwrap(); let settings = serde_yaml::from_str::(frontmatter).unwrap(); let config = settings .try_into() @@ -185,7 +185,7 @@ b: fuzzed; let mut runner = FuzzRunner::new(dotrain, config, None).await; let single_scenario = runner - .run_scenario("mumbai".into()) + .run_scenario("mumbai") .await .map_err(|e| println!("{:#?}", e)) .unwrap(); diff --git a/tauri-app/src-tauri/Cargo.lock b/tauri-app/src-tauri/Cargo.lock index 81c07a5a4..45515c502 100644 --- a/tauri-app/src-tauri/Cargo.lock +++ b/tauri-app/src-tauri/Cargo.lock @@ -341,6 +341,7 @@ dependencies = [ "alloy-transport", "bimap", "futures", + "serde", "serde_json", "tokio", "tower", diff --git a/tauri-app/src-tauri/src/commands/settings.rs b/tauri-app/src-tauri/src/commands/settings.rs index cae78e516..2de391d3e 100644 --- a/tauri-app/src-tauri/src/commands/settings.rs +++ b/tauri-app/src-tauri/src/commands/settings.rs @@ -1,7 +1,12 @@ use crate::error::CommandResult; -use rain_orderbook_app_settings::AppSettings; +use rain_orderbook_app_settings::{config::Config, AppSettings}; #[tauri::command] pub fn parse_settings(text: String) -> CommandResult { Ok(text.try_into()?) } + +#[tauri::command] +pub fn parse_config(text: String) -> CommandResult { + Ok(text.try_into()?) +} diff --git a/tauri-app/src-tauri/src/error.rs b/tauri-app/src-tauri/src/error.rs index a8c4647a4..506ebaafb 100644 --- a/tauri-app/src-tauri/src/error.rs +++ b/tauri-app/src-tauri/src/error.rs @@ -1,6 +1,6 @@ use alloy_ethers_typecast::{client::LedgerClientError, transaction::ReadableClientError}; use alloy_primitives::ruint::FromUintError; -use rain_orderbook_app_settings::AppSettingsParseError; +use rain_orderbook_app_settings::{config::ParseConfigStringError, AppSettingsParseError}; use rain_orderbook_common::{ add_order::AddOrderArgsError, csv::TryIntoCsvError, meta::TryDecodeRainlangSourceError, rainlang::ForkParseError, utils::timestamp::FormatTimestampDisplayError, @@ -47,6 +47,9 @@ pub enum CommandError { #[error(transparent)] AppSettingsParseError(#[from] AppSettingsParseError), + + #[error(transparent)] + ConfigParseError(#[from] ParseConfigStringError), } impl Serialize for CommandError { diff --git a/tauri-app/src-tauri/src/main.rs b/tauri-app/src-tauri/src/main.rs index 8fbea8462..1e2adbc0b 100644 --- a/tauri-app/src-tauri/src/main.rs +++ b/tauri-app/src-tauri/src/main.rs @@ -11,7 +11,7 @@ use commands::dotrain::parse_dotrain; use commands::dotrain_add_order_lsp::{call_lsp_completion, call_lsp_hover, call_lsp_problems}; use commands::order::{order_add, order_detail, order_remove, orders_list, orders_list_write_csv}; use commands::order_take::{order_takes_list, order_takes_list_write_csv}; -use commands::settings::parse_settings; +use commands::settings::{parse_settings, parse_config}; use commands::vault::{ vault_balance_changes_list, vault_balance_changes_list_write_csv, vault_deposit, vault_detail, vault_withdraw, vaults_list, vaults_list_write_csv, @@ -55,6 +55,7 @@ fn run_tauri_app() { call_lsp_hover, call_lsp_problems, parse_settings, + parse_config, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); From db3983277100e55f597f2540c22f739fc1bc0100 Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Fri, 1 Mar 2024 01:01:21 +0000 Subject: [PATCH 02/48] update --- crates/common/src/frontmatter.rs | 23 +++++++++++++---------- crates/settings/src/chart.rs | 6 +++--- crates/settings/src/config.rs | 2 +- crates/settings/src/deployer.rs | 2 +- crates/settings/src/deployment.rs | 2 +- crates/settings/src/network.rs | 2 +- crates/settings/src/order.rs | 2 +- crates/settings/src/orderbook.rs | 2 +- crates/settings/src/scenario.rs | 2 +- crates/settings/src/token.rs | 2 +- 10 files changed, 24 insertions(+), 21 deletions(-) diff --git a/crates/common/src/frontmatter.rs b/crates/common/src/frontmatter.rs index f42800863..2d55df2d9 100644 --- a/crates/common/src/frontmatter.rs +++ b/crates/common/src/frontmatter.rs @@ -1,22 +1,25 @@ use alloy_primitives::{Address, U256}; use dotrain::Rebind; -use rain_orderbook_app_settings::{merge::MergeError, string_structs::Config}; +use rain_orderbook_app_settings::{ + config::{Config, ParseConfigStringError}, + merge::MergeError, +}; use rain_orderbook_bindings::IOrderBookV3::IO; use strict_yaml_rust::{scanner::ScanError, StrictYaml, StrictYamlLoader}; use thiserror::Error; #[derive(Error, Debug)] pub enum FrontmatterError { - #[error("frontmatter is not valid strict yaml: {0}")] - FrontmatterInvalidYaml(#[from] ScanError), - #[error("Invalid Field: {0}")] - FrontmatterFieldInvalid(String), - #[error("Missing Field: {0}")] - FrontmatterFieldMissing(String), - #[error("Frontmatter empty")] - FrontmatterEmpty, + // #[error("frontmatter is not valid strict yaml: {0}")] + // FrontmatterInvalidYaml(#[from] ScanError), + // #[error("Invalid Field: {0}")] + // FrontmatterFieldInvalid(String), + // #[error("Missing Field: {0}")] + // FrontmatterFieldMissing(String), + // #[error("Frontmatter empty")] + // FrontmatterEmpty, #[error(transparent)] - SerdeYamlError(#[from] serde_yaml::Error), + ParseConfigError(#[from] ParseConfigStringError), #[error(transparent)] MergeError(#[from] MergeError), } diff --git a/crates/settings/src/chart.rs b/crates/settings/src/chart.rs index f579150b0..701d9958a 100644 --- a/crates/settings/src/chart.rs +++ b/crates/settings/src/chart.rs @@ -6,7 +6,7 @@ use typeshare::typeshare; use crate::*; #[typeshare] -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub struct Chart { #[typeshare(typescript(type = "Scenario"))] pub scenario: Arc, @@ -14,14 +14,14 @@ pub struct Chart { } #[typeshare] -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub struct Plot { pub data: DataPoints, pub plot_type: String, } #[typeshare] -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub struct DataPoints { pub x: String, pub y: String, diff --git a/crates/settings/src/config.rs b/crates/settings/src/config.rs index 321f20c36..343cccdf6 100644 --- a/crates/settings/src/config.rs +++ b/crates/settings/src/config.rs @@ -8,7 +8,7 @@ use typeshare::typeshare; use url::Url; #[typeshare] -#[derive(Debug, Serialize, Deserialize, Default)] +#[derive(Debug, Serialize, Deserialize, Default, Clone)] pub struct Config { #[typeshare(typescript(type = "Record"))] pub networks: HashMap>, diff --git a/crates/settings/src/deployer.rs b/crates/settings/src/deployer.rs index 94d4ee17c..9079fff78 100644 --- a/crates/settings/src/deployer.rs +++ b/crates/settings/src/deployer.rs @@ -6,7 +6,7 @@ use thiserror::Error; use typeshare::typeshare; #[typeshare] -#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] pub struct Deployer { #[typeshare(typescript(type = "string"))] pub address: Address, diff --git a/crates/settings/src/deployment.rs b/crates/settings/src/deployment.rs index 07477be8e..44f6cdb77 100644 --- a/crates/settings/src/deployment.rs +++ b/crates/settings/src/deployment.rs @@ -5,7 +5,7 @@ use thiserror::Error; use typeshare::typeshare; #[typeshare] -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub struct Deployment { #[typeshare(typescript(type = "Scenario"))] pub scenario: Arc, diff --git a/crates/settings/src/network.rs b/crates/settings/src/network.rs index 613ed07d7..0d4572a1a 100644 --- a/crates/settings/src/network.rs +++ b/crates/settings/src/network.rs @@ -6,7 +6,7 @@ use typeshare::typeshare; use url::{ParseError, Url}; #[typeshare] -#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] pub struct Network { #[typeshare(typescript(type = "string"))] pub rpc: Url, diff --git a/crates/settings/src/order.rs b/crates/settings/src/order.rs index 66f5055b3..70ca3b789 100644 --- a/crates/settings/src/order.rs +++ b/crates/settings/src/order.rs @@ -5,7 +5,7 @@ use thiserror::Error; use typeshare::typeshare; #[typeshare] -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub struct Order { #[typeshare(typescript(type = "Token[]"))] pub inputs: Vec>, diff --git a/crates/settings/src/orderbook.rs b/crates/settings/src/orderbook.rs index b224208fa..db9d3aba7 100644 --- a/crates/settings/src/orderbook.rs +++ b/crates/settings/src/orderbook.rs @@ -8,7 +8,7 @@ use thiserror::Error; use typeshare::typeshare; #[typeshare] -#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] pub struct Orderbook { #[typeshare(typescript(type = "string"))] pub address: Address, diff --git a/crates/settings/src/scenario.rs b/crates/settings/src/scenario.rs index 91bc6a900..10c95e38c 100644 --- a/crates/settings/src/scenario.rs +++ b/crates/settings/src/scenario.rs @@ -5,7 +5,7 @@ use thiserror::Error; use typeshare::typeshare; #[typeshare] -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub struct Scenario { pub bindings: HashMap, #[typeshare(skip)] diff --git a/crates/settings/src/token.rs b/crates/settings/src/token.rs index 6f0decb30..c8353d355 100644 --- a/crates/settings/src/token.rs +++ b/crates/settings/src/token.rs @@ -6,7 +6,7 @@ use thiserror::Error; use typeshare::typeshare; #[typeshare] -#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] pub struct Token { #[typeshare(typescript(type = "Network"))] pub network: Arc, From 938e782ea328d31384235d2fd04602c140bcc478 Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Fri, 1 Mar 2024 22:42:44 +0000 Subject: [PATCH 03/48] Update deployment.rs --- crates/settings/src/deployment.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/settings/src/deployment.rs b/crates/settings/src/deployment.rs index 43a99f97f..93d0e2176 100644 --- a/crates/settings/src/deployment.rs +++ b/crates/settings/src/deployment.rs @@ -79,7 +79,6 @@ mod tests { bindings: HashMap::new(), deployer: mock_deployer(), runs: None, - // orderbook: None, }; let order = Order { inputs: vec![], @@ -107,7 +106,6 @@ mod tests { bindings: HashMap::new(), deployer: mock_deployer(), runs: None, - // orderbook: None, }; let order = Order { inputs: vec![], From 738e25f18eaf254917837cefdb0af6a15a64cd2d Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Sat, 2 Mar 2024 22:56:13 +0000 Subject: [PATCH 04/48] update --- Cargo.lock | 2 + crates/bindings/Cargo.toml | 1 + crates/bindings/src/lib.rs | 6 + crates/cli/Cargo.toml | 1 + crates/cli/src/commands/order/add.rs | 25 ++- crates/common/src/add_order.rs | 186 +++++++++++++++------ crates/common/src/dotrain_add_order_lsp.rs | 142 +++++++++------- crates/common/src/frontmatter.rs | 139 ++------------- crates/common/src/rainlang.rs | 7 +- crates/settings/src/chart.rs | 6 +- crates/settings/src/config.rs | 2 +- crates/settings/src/deployment.rs | 2 +- crates/settings/src/order.rs | 2 +- crates/settings/src/scenario.rs | 2 +- 14 files changed, 262 insertions(+), 261 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 81867d04b..114a10639 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4705,6 +4705,7 @@ version = "0.1.0" dependencies = [ "alloy-primitives 0.5.4", "alloy-sol-types 0.5.4", + "serde", ] [[package]] @@ -4718,6 +4719,7 @@ dependencies = [ "chrono", "clap", "comfy-table", + "rain_orderbook_app_settings", "rain_orderbook_bindings", "rain_orderbook_common", "rain_orderbook_subgraph_client", diff --git a/crates/bindings/Cargo.toml b/crates/bindings/Cargo.toml index 25aed80d1..da7a4af5d 100644 --- a/crates/bindings/Cargo.toml +++ b/crates/bindings/Cargo.toml @@ -9,3 +9,4 @@ homepage.workspace = true [dependencies] alloy-sol-types = { workspace = true, features = ["json"] } alloy-primitives = { workspace = true } +serde = { workspace = true } diff --git a/crates/bindings/src/lib.rs b/crates/bindings/src/lib.rs index 2823065e7..fc01496e1 100644 --- a/crates/bindings/src/lib.rs +++ b/crates/bindings/src/lib.rs @@ -2,6 +2,7 @@ use alloy_sol_types::sol; sol!( #![sol(all_derives = true)] + #[derive(serde::Serialize, serde::Deserialize)] IOrderBookV3, "../../out/IOrderBookV3.sol/IOrderBookV3.json" ); @@ -9,3 +10,8 @@ sol!( #![sol(all_derives = true)] IERC20, "../../out/IERC20.sol/IERC20.json" ); + +sol!( + #![sol(all_derives = true)] + ERC20, "../../out/ERC20.sol/ERC20.json" +); diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index f509fc9ce..5ab175c13 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -13,6 +13,7 @@ alloy-ethers-typecast = { workspace = true } rain_orderbook_subgraph_client = { workspace = true } rain_orderbook_bindings = { workspace = true } rain_orderbook_common = { workspace = true } +rain_orderbook_app_settings = { workspace = true } anyhow = { workspace = true } clap = { workspace = true } reqwest = { workspace = true } diff --git a/crates/cli/src/commands/order/add.rs b/crates/cli/src/commands/order/add.rs index 66d73ca68..27bb12645 100644 --- a/crates/cli/src/commands/order/add.rs +++ b/crates/cli/src/commands/order/add.rs @@ -4,8 +4,10 @@ use crate::{ use anyhow::{anyhow, Result}; use clap::Args; use rain_orderbook_common::add_order::AddOrderArgs; +use rain_orderbook_common::frontmatter::get_merged_config; use rain_orderbook_common::transaction::TransactionArgs; use std::fs::read_to_string; +use std::ops::Deref; use std::path::PathBuf; use tracing::info; @@ -18,22 +20,31 @@ pub struct CliOrderAddArgs { )] dotrain_file: PathBuf, + #[arg(short, long, help = "Deployment key to select from frontmatter")] + deployment: String, + #[clap(flatten)] pub transaction_args: CliTransactionArgs, } -impl TryFrom for AddOrderArgs { - type Error = anyhow::Error; - - fn try_from(val: CliOrderAddArgs) -> Result { - let text = read_to_string(val.dotrain_file).map_err(|e| anyhow!(e))?; - Ok(Self { dotrain: text }) +impl CliOrderAddArgs { + async fn to_add_order_args(&self) -> Result { + let text = read_to_string(&self.dotrain_file).map_err(|e| anyhow!(e))?; + let config = get_merged_config(text.as_str(), None)?; + if let Some(config_deployment) = config.deployments.get(&self.deployment) { + Ok( + AddOrderArgs::new_from_deployment(&text, config_deployment.deref().to_owned()) + .await?, + ) + } else { + Err(anyhow!("specified deployment is undefined!")) + } } } impl Execute for CliOrderAddArgs { async fn execute(&self) -> Result<()> { - let add_order_args: AddOrderArgs = self.clone().try_into()?; + let add_order_args: AddOrderArgs = self.clone().to_add_order_args().await?; let mut tx_args: TransactionArgs = self.transaction_args.clone().into(); tx_args.try_fill_chain_id().await?; diff --git a/crates/common/src/add_order.rs b/crates/common/src/add_order.rs index ff8f1809a..4896bca9c 100644 --- a/crates/common/src/add_order.rs +++ b/crates/common/src/add_order.rs @@ -1,23 +1,28 @@ use crate::{ dotrain_add_order_lsp::LANG_SERVICES, - frontmatter::{try_parse_frontmatter, FrontmatterError}, + frontmatter::{get_merged_config, FrontmatterError}, transaction::{TransactionArgs, TransactionArgsError}, }; use alloy_ethers_typecast::transaction::{ - ReadableClientError, ReadableClientHttp, WritableClientError, WriteTransaction, - WriteTransactionStatus, + ReadContractParameters, ReadableClientError, ReadableClientHttp, WritableClientError, + WriteTransaction, WriteTransactionStatus, }; use alloy_primitives::{hex::FromHexError, Address, U256}; -use dotrain::{error::ComposeError, RainDocument}; +use dotrain::{error::ComposeError, RainDocument, Rebind}; use rain_interpreter_dispair::{DISPair, DISPairError}; use rain_interpreter_parser::{Parser, ParserError, ParserV1}; use rain_metadata::{ ContentEncoding, ContentLanguage, ContentType, Error as RainMetaError, KnownMagic, RainMetaDocumentV1Item, }; -use rain_orderbook_bindings::IOrderBookV3::{addOrderCall, EvaluableConfigV3, OrderConfigV2}; +use rain_orderbook_app_settings::{config::Config, deployment::Deployment}; +use rain_orderbook_bindings::{ + IOrderBookV3::{addOrderCall, EvaluableConfigV3, OrderConfigV2, IO}, + ERC20::decimalsCall, +}; use serde::{Deserialize, Serialize}; use serde_bytes::ByteBuf; +use std::collections::HashMap; use thiserror::Error; pub static ORDERBOOK_ORDER_ENTRYPOINTS: [&str; 2] = ["calculate-io", "handle-io"]; @@ -26,8 +31,6 @@ pub static ORDERBOOK_ORDER_ENTRYPOINTS: [&str; 2] = ["calculate-io", "handle-io" pub enum AddOrderArgsError { #[error("Empty Front Matter")] EmptyFrontmatter, - #[error("Front Matter: {0}")] - FrontmatterError(#[from] FrontmatterError), #[error(transparent)] DISPairError(#[from] DISPairError), #[error(transparent)] @@ -68,19 +71,90 @@ pub struct AddOrderArgs { /// Text MUST have valid dotrain body succeding frontmatter. /// The dotrain body must contain two entrypoints: `calulate-io` and `handle-io`. pub dotrain: String, + pub inputs: Vec, + pub outputs: Vec, + pub deployer: Address, + pub bindings: HashMap, } impl AddOrderArgs { + /// create a new instance from Deployemnt + pub async fn new_from_deployment( + dotrain: &str, + deployment: Deployment, + ) -> Result { + let mut inputs = vec![]; + for input in &deployment.order.inputs { + if let Some(decimals) = input.token.decimals { + inputs.push(IO { + token: input.token.address, + vaultId: input.vault_id, + decimals, + }); + } else { + let client = ReadableClientHttp::new_from_url(input.token.network.rpc.to_string())?; + let parameters = ReadContractParameters { + address: input.token.address, + call: decimalsCall {}, + block_number: None, + }; + let decimals = client.read(parameters).await?._0; + inputs.push(IO { + token: input.token.address, + vaultId: input.vault_id, + decimals, + }); + } + } + + let mut outputs = vec![]; + for output in &deployment.order.inputs { + if let Some(decimals) = output.token.decimals { + outputs.push(IO { + token: output.token.address, + vaultId: output.vault_id, + decimals, + }); + } else { + let client = + ReadableClientHttp::new_from_url(output.token.network.rpc.to_string())?; + let parameters = ReadContractParameters { + address: output.token.address, + call: decimalsCall {}, + block_number: None, + }; + let decimals = client.read(parameters).await?._0; + outputs.push(IO { + token: output.token.address, + vaultId: output.vault_id, + decimals, + }); + } + } + + Ok(AddOrderArgs { + dotrain: dotrain.to_string(), + inputs, + outputs, + deployer: deployment.scenario.deployer.address, + bindings: deployment.scenario.bindings.to_owned(), + }) + } + + /// returns the frontmatter config merged with top config + pub fn get_config(&self, top_config: Option<&Config>) -> Result { + get_merged_config(&self.dotrain, top_config) + } + /// Read parser address from deployer contract, then call parser to parse rainlang into bytecode and constants async fn try_parse_rainlang( &self, rpc_url: String, - deployer: Address, rainlang: String, ) -> Result<(Vec, Vec), AddOrderArgsError> { let client = ReadableClientHttp::new_from_url(rpc_url) .map_err(AddOrderArgsError::ReadableClientError)?; - let dispair = DISPair::from_deployer(deployer, client.clone()) + let dispair = DISPair::from_deployer(self.deployer, client.clone()) .await .map_err(AddOrderArgsError::DISPairError)?; @@ -116,27 +190,29 @@ impl AddOrderArgs { // Parse file into dotrain document let meta_store = LANG_SERVICES.meta_store(); - let frontmatter = RainDocument::get_front_matter(&self.dotrain) - .ok_or(AddOrderArgsError::EmptyFrontmatter)?; - - // Prepare call - let (deployer, valid_inputs, valid_outputs, rebinds) = try_parse_frontmatter(frontmatter)?; + let mut rebinds = None; + if !self.bindings.is_empty() { + rebinds = Some( + self.bindings + .iter() + .map(|(key, value)| Rebind(key.clone(), value.clone())) + .collect(), + ); + }; let dotrain_doc = RainDocument::create(self.dotrain.clone(), Some(meta_store), None, rebinds); let rainlang = dotrain_doc.compose(&ORDERBOOK_ORDER_ENTRYPOINTS)?; - let (bytecode, constants) = self - .try_parse_rainlang(rpc_url, deployer, rainlang.clone()) - .await?; + let (bytecode, constants) = self.try_parse_rainlang(rpc_url, rainlang.clone()).await?; let meta = self.try_generate_meta(rainlang)?; Ok(addOrderCall { config: OrderConfigV2 { - validInputs: valid_inputs, - validOutputs: valid_outputs, + validInputs: self.inputs.clone(), + validOutputs: self.outputs.clone(), evaluableConfig: EvaluableConfigV3 { - deployer, + deployer: self.deployer, bytecode, constants, }, @@ -165,38 +241,38 @@ impl AddOrderArgs { } } -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_try_generate_meta() { - let dotrain_body = String::from( - " -#calculate-io -max-amount: 100e18, -price: 2e18; - -#handle-io -max-amount: 100e18, -price: 2e18; -", - ); - let args = AddOrderArgs { dotrain: "".into() }; - - let meta_bytes = args.try_generate_meta(dotrain_body).unwrap(); - assert_eq!( - meta_bytes, - vec![ - 255, 10, 137, 198, 116, 238, 120, 116, 163, 0, 88, 93, 10, 35, 99, 97, 108, 99, - 117, 108, 97, 116, 101, 45, 105, 111, 10, 109, 97, 120, 45, 97, 109, 111, 117, 110, - 116, 58, 32, 49, 48, 48, 101, 49, 56, 44, 10, 112, 114, 105, 99, 101, 58, 32, 50, - 101, 49, 56, 59, 10, 10, 35, 104, 97, 110, 100, 108, 101, 45, 105, 111, 10, 109, - 97, 120, 45, 97, 109, 111, 117, 110, 116, 58, 32, 49, 48, 48, 101, 49, 56, 44, 10, - 112, 114, 105, 99, 101, 58, 32, 50, 101, 49, 56, 59, 10, 1, 27, 255, 19, 16, 158, - 65, 51, 111, 242, 2, 120, 24, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, - 47, 111, 99, 116, 101, 116, 45, 115, 116, 114, 101, 97, 109 - ] - ); - } -} +// #[cfg(test)] +// mod tests { +// use super::*; + +// #[test] +// fn test_try_generate_meta() { +// let dotrain_body = String::from( +// " +// #calculate-io +// max-amount: 100e18, +// price: 2e18; + +// #handle-io +// max-amount: 100e18, +// price: 2e18; +// ", +// ); +// let args = AddOrderArgs { dotrain: "".into() }; + +// let meta_bytes = args.try_generate_meta(dotrain_body).unwrap(); +// assert_eq!( +// meta_bytes, +// vec![ +// 255, 10, 137, 198, 116, 238, 120, 116, 163, 0, 88, 93, 10, 35, 99, 97, 108, 99, +// 117, 108, 97, 116, 101, 45, 105, 111, 10, 109, 97, 120, 45, 97, 109, 111, 117, 110, +// 116, 58, 32, 49, 48, 48, 101, 49, 56, 44, 10, 112, 114, 105, 99, 101, 58, 32, 50, +// 101, 49, 56, 59, 10, 10, 35, 104, 97, 110, 100, 108, 101, 45, 105, 111, 10, 109, +// 97, 120, 45, 97, 109, 111, 117, 110, 116, 58, 32, 49, 48, 48, 101, 49, 56, 44, 10, +// 112, 114, 105, 99, 101, 58, 32, 50, 101, 49, 56, 59, 10, 1, 27, 255, 19, 16, 158, +// 65, 51, 111, 242, 2, 120, 24, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, +// 47, 111, 99, 116, 101, 116, 45, 115, 116, 114, 101, 97, 109 +// ] +// ); +// } +// } diff --git a/crates/common/src/dotrain_add_order_lsp.rs b/crates/common/src/dotrain_add_order_lsp.rs index a7c7c4a31..ca0e9f8ea 100644 --- a/crates/common/src/dotrain_add_order_lsp.rs +++ b/crates/common/src/dotrain_add_order_lsp.rs @@ -1,84 +1,106 @@ use crate::add_order::ORDERBOOK_ORDER_ENTRYPOINTS; -use crate::frontmatter::try_parse_frontmatter_rebinds; use crate::rainlang::parse_rainlang_on_fork; +use alloy_primitives::Address; use dotrain::{ error::{ComposeError, ErrorCode}, types::ast::Problem, - RainDocument, Rebind, + Rebind, }; use dotrain_lsp::{ lsp_types::{CompletionItem, Hover, Position, TextDocumentItem}, RainLanguageServices, }; use once_cell::sync::Lazy; +use std::collections::HashMap; /// static lang services instance /// meta store instance can be taken from this for shared access to a unfied meta store across /// all the dotrain usage in this crate pub static LANG_SERVICES: Lazy = Lazy::new(RainLanguageServices::default); -pub struct DotrainAddOrderLsp { - text_document: TextDocumentItem, - frontmatter: String, - rebinds: Option>, +/// get hover for a given text document item +pub fn hover( + text_document: &TextDocumentItem, + position: Position, + bindings: HashMap, +) -> Option { + let mut rebinds = None; + if !bindings.is_empty() { + rebinds = Some( + bindings + .iter() + .map(|(key, value)| Rebind(key.clone(), value.clone())) + .collect(), + ); + }; + LANG_SERVICES.do_hover(text_document, position, None, rebinds) } -impl DotrainAddOrderLsp { - pub fn new(text_document: TextDocumentItem, config: &Config) -> Self { - let frontmatter = RainDocument::get_front_matter(&text_document.text); - let rebinds = frontmatter.and_then(try_parse_frontmatter_rebinds); - - Self { - text_document: text_document.clone(), - frontmatter: frontmatter.unwrap_or("").to_string(), - rebinds, - } - } - - /// get hover for a given text document item - pub fn hover(&self, position: Position) -> Option { - LANG_SERVICES.do_hover(&self.text_document, position, None, self.rebinds.clone()) - } +/// get completion items for a given text document item +pub fn completion( + text_document: &TextDocumentItem, + position: Position, + bindings: HashMap, +) -> Option> { + let mut rebinds = None; + if !bindings.is_empty() { + rebinds = Some( + bindings + .iter() + .map(|(key, value)| Rebind(key.clone(), value.clone())) + .collect(), + ); + }; + LANG_SERVICES.do_complete(text_document, position, None, rebinds) +} - /// get completion items for a given text document item - pub fn completion(&self, position: Position) -> Option> { - LANG_SERVICES.do_complete(&self.text_document, position, None, self.rebinds.clone()) - } +/// get problems for a given text document item +pub async fn problems( + text_document: &TextDocumentItem, + rpc_url: &str, + block_number: Option, + bindings: HashMap, + deployer: Address, +) -> Vec { + let mut rebinds = None; + if !bindings.is_empty() { + rebinds = Some( + bindings + .iter() + .map(|(key, value)| Rebind(key.clone(), value.clone())) + .collect(), + ); + }; + let rain_document = LANG_SERVICES.new_rain_document(text_document, rebinds); + let all_problems = rain_document.all_problems(); + if !all_problems.is_empty() { + all_problems.iter().map(|&v| v.clone()).collect() + } else { + let rainlang = match rain_document.compose(&ORDERBOOK_ORDER_ENTRYPOINTS) { + Ok(v) => v, + Err(e) => match e { + ComposeError::Reject(msg) => { + return vec![Problem { + msg, + position: [0, 0], + code: ErrorCode::NativeParserError, + }] + } + ComposeError::Problems(problems) => return problems, + }, + }; - /// get problems for a given text document item - pub async fn problems(&self, rpc_url: &str, block_number: Option) -> Vec { - let rain_document = - LANG_SERVICES.new_rain_document(&self.text_document, self.rebinds.clone()); - let all_problems = rain_document.all_problems(); - if !all_problems.is_empty() { - all_problems.iter().map(|&v| v.clone()).collect() - } else { - let rainlang = match rain_document.compose(&ORDERBOOK_ORDER_ENTRYPOINTS) { - Ok(v) => v, - Err(e) => match e { - ComposeError::Reject(msg) => { - return vec![Problem { - msg, - position: [0, 0], - code: ErrorCode::NativeParserError, - }] - } - ComposeError::Problems(problems) => return problems, + parse_rainlang_on_fork(&rainlang, rpc_url, block_number, deployer) + .await + .map_or_else( + |e| { + vec![Problem { + msg: e.to_string(), + position: [0, 0], + code: ErrorCode::NativeParserError, + }] }, - }; - - parse_rainlang_on_fork(&self.frontmatter, &rainlang, rpc_url, block_number) - .await - .map_or_else( - |e| { - vec![Problem { - msg: e.to_string(), - position: [0, 0], - code: ErrorCode::NativeParserError, - }] - }, - |_| vec![], - ) - } + |_| vec![], + ) } } diff --git a/crates/common/src/frontmatter.rs b/crates/common/src/frontmatter.rs index 2d55df2d9..0bb9706bf 100644 --- a/crates/common/src/frontmatter.rs +++ b/crates/common/src/frontmatter.rs @@ -1,154 +1,41 @@ -use alloy_primitives::{Address, U256}; -use dotrain::Rebind; +use dotrain::RainDocument; use rain_orderbook_app_settings::{ config::{Config, ParseConfigStringError}, merge::MergeError, }; -use rain_orderbook_bindings::IOrderBookV3::IO; -use strict_yaml_rust::{scanner::ScanError, StrictYaml, StrictYamlLoader}; use thiserror::Error; #[derive(Error, Debug)] pub enum FrontmatterError { - // #[error("frontmatter is not valid strict yaml: {0}")] - // FrontmatterInvalidYaml(#[from] ScanError), - // #[error("Invalid Field: {0}")] - // FrontmatterFieldInvalid(String), - // #[error("Missing Field: {0}")] - // FrontmatterFieldMissing(String), - // #[error("Frontmatter empty")] - // FrontmatterEmpty, #[error(transparent)] ParseConfigError(#[from] ParseConfigStringError), #[error(transparent)] MergeError(#[from] MergeError), } -/// Parse dotrain frontmatter to extract deployer, valid-inputs and valid-outputs -#[allow(clippy::type_complexity)] +/// Parse dotrain frontmatter to extract Config pub fn try_parse_frontmatter(frontmatter: &str) -> Result { if frontmatter.is_empty() { return Ok(Config::default()); } Ok(frontmatter.try_into()?) - // // Parse dotrain document frontmatter - // let frontmatter_yaml_vec = StrictYamlLoader::load_from_str(frontmatter) - // .map_err(FrontmatterError::FrontmatterInvalidYaml)?; - // let frontmatter_yaml = frontmatter_yaml_vec - // .first() - // .ok_or(FrontmatterError::FrontmatterEmpty)?; - - // let deployer = frontmatter_yaml["orderbook"]["order"]["deployer"] - // .as_str() - // .ok_or(FrontmatterError::FrontmatterFieldMissing( - // "orderbook.order.deployer".into(), - // ))? - // .parse::
() - // .map_err(|_| { - // FrontmatterError::FrontmatterFieldInvalid("orderbook.order.deployer".into()) - // })?; - - // let valid_inputs: Vec = try_parse_frontmatter_io( - // frontmatter_yaml["orderbook"]["order"]["valid-inputs"].clone(), - // "valid-inputs", - // )?; - // let valid_outputs: Vec = try_parse_frontmatter_io( - // frontmatter_yaml["orderbook"]["order"]["valid-outputs"].clone(), - // "valid-outputs", - // )?; - - // let rebinds = get_rebinds_from_yaml(frontmatter_yaml); - - // Ok((deployer, valid_inputs, valid_outputs, rebinds)) } -pub fn get_merged_frontmatter( - frontmatter: &str, - top_config: &Config, +/// Parse dotrain frontmatter and merges it with top Config if given +pub fn get_merged_config( + dotrain: &str, + top_config: Option<&Config>, ) -> Result { + let frontmatter = RainDocument::get_front_matter(dotrain).unwrap_or(""); let mut frontmatter_config = try_parse_frontmatter(frontmatter)?; - frontmatter_config.merge(top_config.clone())?; - Ok(frontmatter_config) + if let Some(v) = top_config { + frontmatter_config.merge(v.clone())?; + Ok(frontmatter_config) + } else { + Ok(frontmatter_config) + } } -// /// parses a yaml text and tries to get rebindings from it -// pub fn try_parse_frontmatter_rebinds(frontmatter: &str) -> Option> { -// let frontmatter_yaml_vec = StrictYamlLoader::load_from_str(frontmatter).ok()?; -// let frontmatter_yaml = frontmatter_yaml_vec.first()?; - -// get_rebinds_from_yaml(frontmatter_yaml) -// } - -// /// gets rebindings from a parsed yaml -// pub fn get_rebinds_from_yaml(frontmatter_yaml: &StrictYaml) -> Option> { -// let mut rebinds = vec![]; -// let items = frontmatter_yaml["bind"].as_vec()?; -// for item in items { -// for (key, value) in item.as_hash()? { -// rebinds.push(Rebind(key.as_str()?.to_owned(), value.as_str()?.to_owned())) -// } -// } -// Some(rebinds) -// } - -// /// Parse an Io array from from frontmatter field (i.e. valid-inputs or valid-outputs) -// pub fn try_parse_frontmatter_io( -// io_yamls: StrictYaml, -// io_field_name: &str, -// ) -> Result, FrontmatterError> { -// io_yamls -// .into_vec() -// .ok_or(FrontmatterError::FrontmatterFieldMissing(format!( -// "orderbook.order.{}", -// io_field_name -// )))? -// .into_iter() -// .map(|io_yaml| -> Result { -// Ok(IO { -// token: io_yaml["token"] -// .as_str() -// .ok_or(FrontmatterError::FrontmatterFieldMissing(format!( -// "orderbook.order.{}.token", -// io_field_name -// )))? -// .parse::
() -// .map_err(|_| { -// FrontmatterError::FrontmatterFieldInvalid(format!( -// "orderbook.order.{}.token", -// io_field_name -// )) -// })?, -// decimals: io_yaml["decimals"] -// .as_str() -// .ok_or(FrontmatterError::FrontmatterFieldMissing(format!( -// "orderbook.order.{}.decimals", -// io_field_name -// )))? -// .parse::() -// .map_err(|_| { -// FrontmatterError::FrontmatterFieldInvalid(format!( -// "orderbook.order.{}.decimals", -// io_field_name -// )) -// })?, -// vaultId: io_yaml["vault-id"] -// .as_str() -// .ok_or(FrontmatterError::FrontmatterFieldMissing(format!( -// "orderbook.order.{}.vault-id", -// io_field_name -// )))? -// .parse::() -// .map_err(|_| { -// FrontmatterError::FrontmatterFieldInvalid(format!( -// "orderbook.order.{}.vault-id", -// io_field_name -// )) -// })?, -// }) -// }) -// .collect::, FrontmatterError>>() -// } - // #[cfg(test)] // mod tests { // use super::*; diff --git a/crates/common/src/rainlang.rs b/crates/common/src/rainlang.rs index e27456b4b..6ef64cc62 100644 --- a/crates/common/src/rainlang.rs +++ b/crates/common/src/rainlang.rs @@ -1,4 +1,3 @@ -use crate::frontmatter::{try_parse_frontmatter, FrontmatterError}; use alloy_ethers_typecast::transaction::{ReadableClientError, ReadableClientHttp}; use alloy_primitives::{bytes::Bytes, Address}; use once_cell::sync::Lazy; @@ -21,8 +20,6 @@ pub enum ForkParseError { ForkerError(ForkCallError), #[error("Fork Call Reverted: {0}")] ForkCallReverted(AbiDecodedErrorType), - #[error("Front Matter: {0}")] - FrontmatterError(#[from] FrontmatterError), #[error(transparent)] ReadableClientError(#[from] ReadableClientError), #[error("Failed to read Parser address from deployer")] @@ -50,13 +47,11 @@ pub const SENDER_ADDRESS: Address = Address::repeat_byte(0x1); /// with the deployer parsed from the front matter /// returns abi encoded expression config on Ok variant pub async fn parse_rainlang_on_fork( - frontmatter: &str, rainlang: &str, rpc_url: &str, block_number: Option, + deployer: Address, ) -> Result { - let deployer = try_parse_frontmatter(frontmatter)?.0; - // Prepare evm fork let block_number_val = match block_number { Some(b) => b, diff --git a/crates/settings/src/chart.rs b/crates/settings/src/chart.rs index e9c6040c1..86baeb1f4 100644 --- a/crates/settings/src/chart.rs +++ b/crates/settings/src/chart.rs @@ -6,7 +6,7 @@ use typeshare::typeshare; use crate::*; #[typeshare] -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct Chart { #[typeshare(typescript(type = "Scenario"))] pub scenario: Arc, @@ -14,14 +14,14 @@ pub struct Chart { } #[typeshare] -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct Plot { pub data: DataPoints, pub plot_type: String, } #[typeshare] -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct DataPoints { pub x: String, pub y: String, diff --git a/crates/settings/src/config.rs b/crates/settings/src/config.rs index 3ec9537b1..e4aa5b451 100644 --- a/crates/settings/src/config.rs +++ b/crates/settings/src/config.rs @@ -8,7 +8,7 @@ use typeshare::typeshare; use url::Url; #[typeshare] -#[derive(Debug, Serialize, Deserialize, Default, Clone)] +#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)] pub struct Config { #[typeshare(typescript(type = "Record"))] pub networks: HashMap>, diff --git a/crates/settings/src/deployment.rs b/crates/settings/src/deployment.rs index dd1f4ec3d..aeb61267c 100644 --- a/crates/settings/src/deployment.rs +++ b/crates/settings/src/deployment.rs @@ -5,7 +5,7 @@ use thiserror::Error; use typeshare::typeshare; #[typeshare] -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct Deployment { #[typeshare(typescript(type = "Scenario"))] pub scenario: Arc, diff --git a/crates/settings/src/order.rs b/crates/settings/src/order.rs index 2adf20dea..4feac551a 100644 --- a/crates/settings/src/order.rs +++ b/crates/settings/src/order.rs @@ -15,7 +15,7 @@ pub struct OrderIO { } #[typeshare] -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct Order { #[typeshare(typescript(type = "OrderIO[]"))] pub inputs: Vec, diff --git a/crates/settings/src/scenario.rs b/crates/settings/src/scenario.rs index 264d6b660..9647e6cfe 100644 --- a/crates/settings/src/scenario.rs +++ b/crates/settings/src/scenario.rs @@ -5,7 +5,7 @@ use thiserror::Error; use typeshare::typeshare; #[typeshare] -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct Scenario { pub bindings: HashMap, #[typeshare(skip)] From 29ec7f3290862db98dc16281ddac447aaceeebf2 Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Sat, 2 Mar 2024 23:26:17 +0000 Subject: [PATCH 05/48] wip --- crates/bindings/Cargo.toml | 2 +- crates/common/src/dotrain_add_order_lsp.rs | 34 ++++++++------ tauri-app/src-tauri/Cargo.lock | 1 + .../src/commands/{settings.rs => config.rs} | 6 +++ tauri-app/src-tauri/src/commands/dotrain.rs | 6 +-- .../src/commands/dotrain_add_order_lsp.rs | 17 ++++--- tauri-app/src-tauri/src/commands/mod.rs | 2 +- tauri-app/src-tauri/src/error.rs | 6 ++- tauri-app/src-tauri/src/main.rs | 3 +- tauri-app/src/routes/orders/add/+page.svelte | 46 ++++++++++++++++++- 10 files changed, 94 insertions(+), 29 deletions(-) rename tauri-app/src-tauri/src/commands/{settings.rs => config.rs} (58%) diff --git a/crates/bindings/Cargo.toml b/crates/bindings/Cargo.toml index da7a4af5d..0ea70f674 100644 --- a/crates/bindings/Cargo.toml +++ b/crates/bindings/Cargo.toml @@ -9,4 +9,4 @@ homepage.workspace = true [dependencies] alloy-sol-types = { workspace = true, features = ["json"] } alloy-primitives = { workspace = true } -serde = { workspace = true } +serde = { workspace = true } \ No newline at end of file diff --git a/crates/common/src/dotrain_add_order_lsp.rs b/crates/common/src/dotrain_add_order_lsp.rs index ca0e9f8ea..c0a59c1e4 100644 --- a/crates/common/src/dotrain_add_order_lsp.rs +++ b/crates/common/src/dotrain_add_order_lsp.rs @@ -60,7 +60,7 @@ pub async fn problems( rpc_url: &str, block_number: Option, bindings: HashMap, - deployer: Address, + deployer: Option
, ) -> Vec { let mut rebinds = None; if !bindings.is_empty() { @@ -90,17 +90,25 @@ pub async fn problems( }, }; - parse_rainlang_on_fork(&rainlang, rpc_url, block_number, deployer) - .await - .map_or_else( - |e| { - vec![Problem { - msg: e.to_string(), - position: [0, 0], - code: ErrorCode::NativeParserError, - }] - }, - |_| vec![], - ) + if let Some(deployer_add) = deployer { + parse_rainlang_on_fork(&rainlang, rpc_url, block_number, deployer_add) + .await + .map_or_else( + |e| { + vec![Problem { + msg: e.to_string(), + position: [0, 0], + code: ErrorCode::NativeParserError, + }] + }, + |_| vec![], + ) + } else { + vec![Problem { + msg: "undefined deployer address".to_owned(), + position: [0, 0], + code: ErrorCode::NativeParserError, + }] + } } } diff --git a/tauri-app/src-tauri/Cargo.lock b/tauri-app/src-tauri/Cargo.lock index 45515c502..ccf4c4f87 100644 --- a/tauri-app/src-tauri/Cargo.lock +++ b/tauri-app/src-tauri/Cargo.lock @@ -6612,6 +6612,7 @@ version = "0.1.0" dependencies = [ "alloy-primitives 0.5.4", "alloy-sol-types 0.5.4", + "serde", ] [[package]] diff --git a/tauri-app/src-tauri/src/commands/settings.rs b/tauri-app/src-tauri/src/commands/config.rs similarity index 58% rename from tauri-app/src-tauri/src/commands/settings.rs rename to tauri-app/src-tauri/src/commands/config.rs index 2de391d3e..461d5ba27 100644 --- a/tauri-app/src-tauri/src/commands/settings.rs +++ b/tauri-app/src-tauri/src/commands/config.rs @@ -1,5 +1,6 @@ use crate::error::CommandResult; use rain_orderbook_app_settings::{config::Config, AppSettings}; +use rain_orderbook_common::frontmatter::get_merged_config; #[tauri::command] pub fn parse_settings(text: String) -> CommandResult { @@ -10,3 +11,8 @@ pub fn parse_settings(text: String) -> CommandResult { pub fn parse_config(text: String) -> CommandResult { Ok(text.try_into()?) } + +#[tauri::command] +pub fn merge_config(dotrain: String, top_config: Config) -> CommandResult { + Ok(get_merged_config(dotrain.as_str(), Some(&top_config))?) +} diff --git a/tauri-app/src-tauri/src/commands/dotrain.rs b/tauri-app/src-tauri/src/commands/dotrain.rs index 8a734adfc..31ddd48a3 100644 --- a/tauri-app/src-tauri/src/commands/dotrain.rs +++ b/tauri-app/src-tauri/src/commands/dotrain.rs @@ -1,13 +1,13 @@ use crate::error::CommandResult; -use alloy_primitives::bytes::Bytes; +use alloy_primitives::{bytes::Bytes, Address}; use rain_orderbook_common::rainlang::parse_rainlang_on_fork; #[tauri::command] pub async fn parse_dotrain( - frontmatter: &str, rainlang: &str, rpc_url: &str, block_number: u64, + deployer: Address, ) -> CommandResult { - Ok(parse_rainlang_on_fork(frontmatter, rainlang, rpc_url, Some(block_number)).await?) + Ok(parse_rainlang_on_fork(rainlang, rpc_url, Some(block_number), deployer).await?) } diff --git a/tauri-app/src-tauri/src/commands/dotrain_add_order_lsp.rs b/tauri-app/src-tauri/src/commands/dotrain_add_order_lsp.rs index 90eb019fa..3e63b124d 100644 --- a/tauri-app/src-tauri/src/commands/dotrain_add_order_lsp.rs +++ b/tauri-app/src-tauri/src/commands/dotrain_add_order_lsp.rs @@ -1,21 +1,24 @@ use crate::error::CommandResult; +use std::collections::HashMap; +use alloy_primitives::Address; use rain_orderbook_common::{ dotrain::types::ast::Problem, - dotrain_add_order_lsp::DotrainAddOrderLsp, + dotrain_add_order_lsp::{completion, hover, problems}, dotrain_lsp::lsp_types::{CompletionItem, Hover, Position, TextDocumentItem}, }; #[tauri::command] -pub fn call_lsp_hover(text_document: TextDocumentItem, position: Position) -> Option { - DotrainAddOrderLsp::new(text_document).hover(position) +pub fn call_lsp_hover(text_document: TextDocumentItem, position: Position, bindings: HashMap) -> Option { + hover(&text_document, position, bindings) } #[tauri::command] pub fn call_lsp_completion( text_document: TextDocumentItem, position: Position, + bindings: HashMap, ) -> Option> { - DotrainAddOrderLsp::new(text_document).completion(position) + completion(&text_document, position, bindings) } #[tauri::command] @@ -23,8 +26,8 @@ pub async fn call_lsp_problems( text_document: TextDocumentItem, rpc_url: &str, block_number: Option, + bindings: HashMap, + deployer: Option
, ) -> CommandResult> { - Ok(DotrainAddOrderLsp::new(text_document) - .problems(rpc_url, block_number) - .await) + Ok(problems(&text_document, rpc_url, block_number, bindings, deployer).await) } diff --git a/tauri-app/src-tauri/src/commands/mod.rs b/tauri-app/src-tauri/src/commands/mod.rs index dccdcf8f3..f5ea7d779 100644 --- a/tauri-app/src-tauri/src/commands/mod.rs +++ b/tauri-app/src-tauri/src/commands/mod.rs @@ -1,8 +1,8 @@ pub mod chain; +pub mod config; pub mod dotrain; pub mod dotrain_add_order_lsp; pub mod order; pub mod order_take; -pub mod settings; pub mod vault; pub mod wallet; diff --git a/tauri-app/src-tauri/src/error.rs b/tauri-app/src-tauri/src/error.rs index 506ebaafb..f51565e1a 100644 --- a/tauri-app/src-tauri/src/error.rs +++ b/tauri-app/src-tauri/src/error.rs @@ -2,8 +2,7 @@ use alloy_ethers_typecast::{client::LedgerClientError, transaction::ReadableClie use alloy_primitives::ruint::FromUintError; use rain_orderbook_app_settings::{config::ParseConfigStringError, AppSettingsParseError}; use rain_orderbook_common::{ - add_order::AddOrderArgsError, csv::TryIntoCsvError, meta::TryDecodeRainlangSourceError, - rainlang::ForkParseError, utils::timestamp::FormatTimestampDisplayError, + add_order::AddOrderArgsError, csv::TryIntoCsvError, frontmatter::FrontmatterError, meta::TryDecodeRainlangSourceError, rainlang::ForkParseError, utils::timestamp::FormatTimestampDisplayError }; use rain_orderbook_subgraph_client::OrderbookSubgraphClientError; use serde::{ser::Serializer, Serialize}; @@ -50,6 +49,9 @@ pub enum CommandError { #[error(transparent)] ConfigParseError(#[from] ParseConfigStringError), + + #[error(transparent)] + FrontmatterError(#[from] FrontmatterError), } impl Serialize for CommandError { diff --git a/tauri-app/src-tauri/src/main.rs b/tauri-app/src-tauri/src/main.rs index 1e2adbc0b..e37fdaa59 100644 --- a/tauri-app/src-tauri/src/main.rs +++ b/tauri-app/src-tauri/src/main.rs @@ -7,11 +7,11 @@ pub mod transaction_status; mod commands; use commands::chain::{get_block_number, get_chainid}; +use commands::config::{parse_config, parse_settings, merge_config}; use commands::dotrain::parse_dotrain; use commands::dotrain_add_order_lsp::{call_lsp_completion, call_lsp_hover, call_lsp_problems}; use commands::order::{order_add, order_detail, order_remove, orders_list, orders_list_write_csv}; use commands::order_take::{order_takes_list, order_takes_list_write_csv}; -use commands::settings::{parse_settings, parse_config}; use commands::vault::{ vault_balance_changes_list, vault_balance_changes_list_write_csv, vault_deposit, vault_detail, vault_withdraw, vaults_list, vaults_list_write_csv, @@ -56,6 +56,7 @@ fn run_tauri_app() { call_lsp_problems, parse_settings, parse_config, + merge_config, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/tauri-app/src/routes/orders/add/+page.svelte b/tauri-app/src/routes/orders/add/+page.svelte index 74aeedcc0..80075db22 100644 --- a/tauri-app/src/routes/orders/add/+page.svelte +++ b/tauri-app/src/routes/orders/add/+page.svelte @@ -8,10 +8,30 @@ import { Helper, Label } from 'flowbite-svelte'; import InputBlockNumber from '$lib/components/InputBlockNumber.svelte'; import { forkBlockNumber } from '$lib/stores/forkBlockNumber'; + import { invoke } from '@tauri-apps/api'; + + import { activeChainSettingsIndex } from '$lib/stores/settings'; + import DropdownRadio from '$lib/components/DropdownRadio.svelte'; + import SkeletonRow from '$lib/components/SkeletonRow.svelte'; + + import { + settings, + settingsText, + } from '$lib/stores/settings'; let isSubmitting = false; - const dotrainFile = textFileStore('Rain', ['rain']); + $: dotrainFile = textFileStore('Rain', ['rain']); + $: topConfig = $settings.chains; + let config = topConfig; + $: { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + invoke("merge_config", {dotrain: $dotrainFile.text, topConfig}).then(v => config = v as any); + }; + + $: order = config[0]; + $: scenario = config[1]; + async function execute() { isSubmitting = true; @@ -42,6 +62,30 @@ on:click={execute}>Add Order + + + {#if $settings === undefined || $settings.chains.length === 0} + + {:else} + + + {selected.label ? selected.label : selected.rpc_url} + + + + {#if option.label} +
+
{option.label}
+ {option.rpc_url} +
+ {:else} +
+ {option.rpc_url} +
+ {/if} +
+
+ {/if}
From 3397d19173ac4f2f88c6322d7abb197e30a0a7aa Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Sun, 3 Mar 2024 20:28:52 +0000 Subject: [PATCH 06/48] wip --- flake.nix | 2 +- tauri-app/src-tauri/src/commands/config.rs | 11 ++- tauri-app/src-tauri/src/commands/order.rs | 5 +- tauri-app/src-tauri/src/main.rs | 4 +- .../lib/components/CodeMirrorDotrain.svelte | 11 +-- .../DropdownActiveChainSettings.svelte | 16 ++-- .../DropdownActiveOrderbookSettings.svelte | 16 ++-- tauri-app/src/lib/services/langServices.ts | 14 ++- tauri-app/src/lib/services/order.ts | 10 +- tauri-app/src/lib/stores/settings.ts | 92 +++++++++++-------- tauri-app/src/routes/orders/add/+page.svelte | 50 ++++------ tauri-app/src/scripts/typeshareFix.cjs | 2 - 12 files changed, 122 insertions(+), 111 deletions(-) diff --git a/flake.nix b/flake.nix index 5968407b0..a738cced6 100644 --- a/flake.nix +++ b/flake.nix @@ -38,7 +38,7 @@ typeshare crates/subgraph/src/types/order_take_detail.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/orderTakeDetail.ts; typeshare crates/settings/src/parse.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/appSettings.ts; - typeshare crates/settings/src/config.rs crates/settings/src/chart.rs crates/settings/src/deployer.rs crates/settings/src/network.rs crates/settings/src/order.rs crates/settings/src/orderbook.rs crates/settings/src/scenario.rs crates/settings/src/token.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/config.ts; + typeshare crates/settings/src/config.rs crates/settings/src/chart.rs crates/settings/src/deployer.rs crates/settings/src/network.rs crates/settings/src/order.rs crates/settings/src/orderbook.rs crates/settings/src/scenario.rs crates/settings/src/token.rs crates/settings/src/deployment.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/config.ts; typeshare tauri-app/src-tauri/src/toast.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/toast.ts; typeshare tauri-app/src-tauri/src/transaction_status.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/transactionStatus.ts; diff --git a/tauri-app/src-tauri/src/commands/config.rs b/tauri-app/src-tauri/src/commands/config.rs index 461d5ba27..83540b3ea 100644 --- a/tauri-app/src-tauri/src/commands/config.rs +++ b/tauri-app/src-tauri/src/commands/config.rs @@ -1,18 +1,19 @@ use crate::error::CommandResult; -use rain_orderbook_app_settings::{config::Config, AppSettings}; +use rain_orderbook_app_settings::config::Config; use rain_orderbook_common::frontmatter::get_merged_config; #[tauri::command] -pub fn parse_settings(text: String) -> CommandResult { +pub fn parse_config(text: String) -> CommandResult { Ok(text.try_into()?) } #[tauri::command] -pub fn parse_config(text: String) -> CommandResult { - Ok(text.try_into()?) +pub fn merge_config(dotrain: String, top_config: Config) -> CommandResult { + Ok(get_merged_config(dotrain.as_str(), Some(&top_config))?) } #[tauri::command] -pub fn merge_config(dotrain: String, top_config: Config) -> CommandResult { +pub fn get_config(dotrain: String, setting_text: String) -> CommandResult { + let top_config = setting_text.try_into()?; Ok(get_merged_config(dotrain.as_str(), Some(&top_config))?) } diff --git a/tauri-app/src-tauri/src/commands/order.rs b/tauri-app/src-tauri/src/commands/order.rs index 9e319d796..231fd1daa 100644 --- a/tauri-app/src-tauri/src/commands/order.rs +++ b/tauri-app/src-tauri/src/commands/order.rs @@ -5,6 +5,7 @@ use rain_orderbook_common::{ subgraph::SubgraphArgs, transaction::TransactionArgs, types::OrderDetailExtended, types::OrderFlattened, utils::timestamp::FormatTimestampDisplayError, }; +use rain_orderbook_app_settings::deployment::Deployment; use rain_orderbook_subgraph_client::{types::orders_list, PaginationArgs}; use std::fs; use std::path::PathBuf; @@ -61,10 +62,12 @@ pub async fn order_detail( #[tauri::command] pub async fn order_add( app_handle: AppHandle, - add_order_args: AddOrderArgs, + dotrain: &str, + deployment: Deployment, transaction_args: TransactionArgs, ) -> CommandResult<()> { let tx_status_notice = TransactionStatusNoticeRwLock::new("Add order".into(), None); + let add_order_args = AddOrderArgs::new_from_deployment(dotrain, deployment).await?; add_order_args .execute(transaction_args, |status| { tx_status_notice.update_status_and_emit(app_handle.clone(), status); diff --git a/tauri-app/src-tauri/src/main.rs b/tauri-app/src-tauri/src/main.rs index e37fdaa59..d7ff34bf7 100644 --- a/tauri-app/src-tauri/src/main.rs +++ b/tauri-app/src-tauri/src/main.rs @@ -7,7 +7,7 @@ pub mod transaction_status; mod commands; use commands::chain::{get_block_number, get_chainid}; -use commands::config::{parse_config, parse_settings, merge_config}; +use commands::config::{get_config, merge_config, parse_config}; use commands::dotrain::parse_dotrain; use commands::dotrain_add_order_lsp::{call_lsp_completion, call_lsp_hover, call_lsp_problems}; use commands::order::{order_add, order_detail, order_remove, orders_list, orders_list_write_csv}; @@ -54,8 +54,8 @@ fn run_tauri_app() { call_lsp_completion, call_lsp_hover, call_lsp_problems, - parse_settings, parse_config, + get_config, merge_config, ]) .run(tauri::generate_context!()) diff --git a/tauri-app/src/lib/components/CodeMirrorDotrain.svelte b/tauri-app/src/lib/components/CodeMirrorDotrain.svelte index 6d45c5e01..210ccc707 100644 --- a/tauri-app/src/lib/components/CodeMirrorDotrain.svelte +++ b/tauri-app/src/lib/components/CodeMirrorDotrain.svelte @@ -1,19 +1,12 @@ import { Helper, Label } from 'flowbite-svelte'; - import { settings, activeChainSettingsIndex } from '$lib/stores/settings'; + import { activeNetworkIndex, networks } from '$lib/stores/settings'; import DropdownRadio from '$lib/components/DropdownRadio.svelte'; import SkeletonRow from '$lib/components/SkeletonRow.svelte'; -{#if $settings === undefined || $settings.chains.length === 0} +{#if $networks === undefined || $networks.length === 0} {:else} - + - {selected.label ? selected.label : selected.rpc_url} + {selected[1].label ? selected[1].label : selected[0]} - {#if option.label} + {#if option[1].label}
-
{option.label}
- {option.rpc_url} +
{option[1].label}
+ {option[1].rpc}
{:else}
- {option.rpc_url} + {option[0]}
{/if}
diff --git a/tauri-app/src/lib/components/DropdownActiveOrderbookSettings.svelte b/tauri-app/src/lib/components/DropdownActiveOrderbookSettings.svelte index 75bffcc39..8d5c2b8a5 100644 --- a/tauri-app/src/lib/components/DropdownActiveOrderbookSettings.svelte +++ b/tauri-app/src/lib/components/DropdownActiveOrderbookSettings.svelte @@ -1,28 +1,28 @@ -{#if $activeChainSettings === undefined || $activeChainSettings.orderbooks.length === 0} +{#if $orderbooks === undefined || $orderbooks.length === 0} {:else} - + - {selected.label ? selected.label : selected.address} + {selected[1].label ? selected[1].label : selected[0]} - {#if option.label} + {#if option[1].label}
-
{option.label}
- {option.address} +
{option[1].label}
+ {option[1].address}
{:else}
- {option.address} + {option[0]}
{/if}
diff --git a/tauri-app/src/lib/services/langServices.ts b/tauri-app/src/lib/services/langServices.ts index 1db82ef91..8a54a4c26 100644 --- a/tauri-app/src/lib/services/langServices.ts +++ b/tauri-app/src/lib/services/langServices.ts @@ -3,13 +3,17 @@ import { ErrorCode, type Problem, TextDocumentItem, Position, Hover, CompletionI import { rpcUrl } from '$lib/stores/settings'; import { get } from 'svelte/store'; import { forkBlockNumber } from '$lib/stores/forkBlockNumber'; +import { deployments, activeDeploymentIndex } from '$lib/stores/settings'; /** * Provides problems callback by invoking related tauri command */ export async function problemsCallback(textDocument: TextDocumentItem): Promise { try { - return await invoke('call_lsp_problems', { textDocument, rpcUrl: get(rpcUrl), blockNumber: get(forkBlockNumber).value }); + const deployment = get(deployments)?.[get(activeDeploymentIndex)]?.[1]; + const bindings = deployment !== undefined ? deployment.scenario.bindings : {}; + const deployer = deployment !== undefined ? deployment.scenario.deployer.address : undefined; + return await invoke('call_lsp_problems', { textDocument, rpcUrl: get(rpcUrl), blockNumber: get(forkBlockNumber).value, bindings, deployer}); } catch (err) { return [{ @@ -24,12 +28,16 @@ export async function problemsCallback(textDocument: TextDocumentItem): Promise< * Provides hover callback by invoking related tauri command */ export async function hoverCallback(textDocument: TextDocumentItem, position: Position): Promise { - return await invoke('call_lsp_hover', { textDocument, position }); + const deployment = get(deployments)?.[get(activeDeploymentIndex)]?.[1]; + const bindings = deployment !== undefined ? deployment.scenario.bindings : {}; + return await invoke('call_lsp_hover', { textDocument, position, bindings }); } /** * Provides completion callback by invoking related tauri command */ export async function completionCallback(textDocument: TextDocumentItem, position: Position): Promise { - return await invoke('call_lsp_completion', { textDocument, position }); + const deployment = get(deployments)?.[get(activeDeploymentIndex)]?.[1]; + const bindings = deployment !== undefined ? deployment.scenario.bindings : {}; + return await invoke('call_lsp_completion', { textDocument, position, bindings }); } \ No newline at end of file diff --git a/tauri-app/src/lib/services/order.ts b/tauri-app/src/lib/services/order.ts index 5d9cfd8c4..6d4132988 100644 --- a/tauri-app/src/lib/services/order.ts +++ b/tauri-app/src/lib/services/order.ts @@ -2,12 +2,16 @@ import { get } from 'svelte/store'; import { invoke } from '@tauri-apps/api'; import { rpcUrl, orderbookAddress,chainId, subgraphUrl } from '$lib/stores/settings'; import { walletDerivationIndex } from '$lib/stores/wallets'; +import { deployments, activeDeploymentIndex } from '$lib/stores/settings'; export async function orderAdd(dotrain: string) { + const deployment = get(deployments)?.[get(activeDeploymentIndex)]?.[1] + if (deployment === undefined) { + return Promise.reject("undefined deployment!"); + } await invoke("order_add", { - addOrderArgs: { - dotrain, - }, + dotrain, + deployment, transactionArgs: { rpc_url: get(rpcUrl), orderbook_address: get(orderbookAddress), diff --git a/tauri-app/src/lib/stores/settings.ts b/tauri-app/src/lib/stores/settings.ts index 9bdf9ba8a..86a0beae8 100644 --- a/tauri-app/src/lib/stores/settings.ts +++ b/tauri-app/src/lib/stores/settings.ts @@ -4,59 +4,77 @@ import find from 'lodash/find'; import * as chains from 'viem/chains'; import { textFileStore } from '$lib/storesGeneric/textFileStore'; import { invoke } from '@tauri-apps/api'; -import { type AppSettings, type ChainSettings } from '$lib/typeshare/appSettings'; -import { getBlockNumberFromRpc, getChainIdFromRpc } from '$lib/services/chain'; +import { type Config } from '$lib/typeshare/config'; +import { getBlockNumberFromRpc } from '$lib/services/chain'; -interface ChainSettingsExtended extends ChainSettings { - chain_id: number, -} - -interface AppSettingsExtended { - chains: Array; -} +// dotrain text store +const dotrainFile = textFileStore('Rain', ['rain']); // general export const settingsText = cachedWritableStore('settings', "", (s) => s, (s) => s); export const settingsFile = textFileStore('Orderbook Settings Yaml', ['yml', 'yaml'], get(settingsText)); -export const settings = asyncDerived(settingsText, async ($settingsText): Promise => { - const data: AppSettings = await invoke("parse_settings", {text: $settingsText}); - const chains = await Promise.all(data.chains.map(async (c): Promise => { - const chainId: number = await getChainIdFromRpc(c.rpc_url); - return { - ...c, - chain_id: chainId, - }; - })); - return { chains }; +export const settings = asyncDerived([settingsText, dotrainFile], async ([$settingsText, $dotrainFile]): Promise => { + const config: Config = await invoke("get_config", {dotrain: $dotrainFile.text, settingText: $settingsText}); + return config; }); -// chain -export const activeChainSettingsIndex = cachedWritableInt("settings.activeChainIndex", 0); -export const activeChainSettings = derived([settings, activeChainSettingsIndex], ([$settingsData, $activeChainSettingsIndex]) => $settingsData?.chains[$activeChainSettingsIndex]); -export const rpcUrl = derived(activeChainSettings, ($activeChainSettings) => $activeChainSettings?.rpc_url); -export const chainId = derived(activeChainSettings, ($activeChainSettings) => $activeChainSettings?.chain_id); +// networks +export const networks = derived(settings, ($settingsData) => Object.entries($settingsData.networks)); +export const activeNetworkIndex = cachedWritableInt("settings.activeNetworkIndex", 0); +export const activeNetwork = derived([networks, activeNetworkIndex], ([$networks, $activeNetworkIndex]) => $networks?.[$activeNetworkIndex]); +export const rpcUrl = derived(activeNetwork, ($activeNetwork) => $activeNetwork?.[1].rpc); +export const chainId = derived(activeNetwork, ($activeNetwork) => $activeNetwork?.[1].chain_id); export const activeChain = derived(chainId, ($activeChainId) => find(Object.values(chains), (c) => c.id === $activeChainId)); export const activeChainHasBlockExplorer = derived(activeChain, ($activeChain) => { return $activeChain && $activeChain.blockExplorers?.default !== undefined; }); -export const activeChainLatestBlockNumber = derived(activeChainSettings, ($activeChainSettings) => getBlockNumberFromRpc($activeChainSettings.rpc_url)); +export const activeChainLatestBlockNumber = derived(activeNetwork, ($activeNetwork) => getBlockNumberFromRpc($activeNetwork?.[1].rpc)); // orderbook -export const activeOrderbookSettingsIndex = cachedWritableInt("settings.activeOrderbookIndex", 0); -export const activeOrderbookSettings = derived([activeChainSettings, activeOrderbookSettingsIndex], ([$activeChainSettings, $activeOrderbookSettingsIndex]) => $activeChainSettings?.orderbooks[$activeOrderbookSettingsIndex]); -export const subgraphUrl = derived(activeOrderbookSettings, ($activeOrderbookSettings) => $activeOrderbookSettings?.subgraph_url); -export const orderbookAddress = derived(activeOrderbookSettings, ($activeOrderbookSettings) => $activeOrderbookSettings?.address); +export const orderbooks = derived([settings, activeNetwork], ([$settingsData, $activeNetwork]) => Object.entries($settingsData.orderbooks).filter(v => + // filter orderbooks based on active netowkr + v[1].network.rpc === $activeNetwork?.[1].rpc + && v[1].network.chain_id === $activeNetwork?.[1].chain_id + && v[1].network.label === $activeNetwork?.[1].label + && v[1].network.network_id === $activeNetwork?.[1].network_id + && v[1].network.currency === $activeNetwork?.[1].currency +)); +export const activeOrderbookIndex = cachedWritableInt("settings.activeOrderbookIndex", 0); +export const activeOrderbook = derived([orderbooks, activeOrderbookIndex], ([$orderbooks, $activeOrderbookIndex]) => $orderbooks[$activeOrderbookIndex]); +export const subgraphUrl = derived(activeOrderbook, ($activeOrderbookSettings) => $activeOrderbookSettings?.[1].subgraph); +export const orderbookAddress = derived(activeOrderbook, ($activeOrderbookSettings) => $activeOrderbookSettings?.[1].address); -export const hasRequiredSettings = derived([activeChainSettings, activeOrderbookSettings], ([$activeChainSettings, $activeOrderbookSettings]) => $activeChainSettings !== undefined && $activeOrderbookSettings !== undefined); +export const hasRequiredSettings = derived([activeNetwork, activeOrderbook], ([$activeChainSettings, $activeOrderbookSettings]) => $activeChainSettings !== undefined && $activeOrderbookSettings !== undefined); -// When settings data updated, reset active chain -settings.subscribe((val) => { - if(val && val.chains.length < get(activeChainSettingsIndex)) { - activeChainSettingsIndex.set(0); +// When networks data updated, reset active chain +networks.subscribe((val) => { + if(val && val.length < get(activeNetworkIndex)) { + activeNetworkIndex.set(0); } }); -// When active chain updated, reset active orderbook -activeChainSettings.subscribe(async () => { - activeOrderbookSettingsIndex.set(0); +// When active network updated, reset active orderbook and deployment +activeNetwork.subscribe(async () => { + activeOrderbookIndex.set(0); + activeDeploymentIndex.set(0); }); + +// deployments +export const deployments = derived([settings, activeNetwork, activeOrderbook], ([$settingsData, $activeNetwork, $activeOrderbook]) => Object.entries($settingsData.deployments).filter(v => { + return v[1].order.network.rpc === $activeNetwork?.[1].rpc + && v[1].order.network.chain_id === $activeNetwork?.[1].chain_id + && v[1].order.network.label === $activeNetwork?.[1].label + && v[1].order.network.network_id === $activeNetwork?.[1].network_id + && v[1].order.network.currency === $activeNetwork?.[1].currency + && ( + v[1].order.orderbook !== undefined + ? ( + v[1].order.orderbook.address === $activeOrderbook?.[1].address + && v[1].order.orderbook.subgraph === $activeOrderbook?.[1].subgraph + && v[1].order.orderbook.label === $activeOrderbook?.[1].label + ) + : true + ) +})); +export const activeDeploymentIndex = cachedWritableInt("settings.activeDeploymentIndex", 0); +export const activeDeployment = derived([deployments, activeDeploymentIndex], ([$deployments, $activeDeploymentIndex]) => $deployments?.[$activeDeploymentIndex]); \ No newline at end of file diff --git a/tauri-app/src/routes/orders/add/+page.svelte b/tauri-app/src/routes/orders/add/+page.svelte index 80075db22..fe5895c7e 100644 --- a/tauri-app/src/routes/orders/add/+page.svelte +++ b/tauri-app/src/routes/orders/add/+page.svelte @@ -8,30 +8,22 @@ import { Helper, Label } from 'flowbite-svelte'; import InputBlockNumber from '$lib/components/InputBlockNumber.svelte'; import { forkBlockNumber } from '$lib/stores/forkBlockNumber'; - import { invoke } from '@tauri-apps/api'; - - import { activeChainSettingsIndex } from '$lib/stores/settings'; import DropdownRadio from '$lib/components/DropdownRadio.svelte'; import SkeletonRow from '$lib/components/SkeletonRow.svelte'; - - import { - settings, - settingsText, - } from '$lib/stores/settings'; + import { deployments, activeDeploymentIndex } from '$lib/stores/settings'; + import { RawRainlangExtension, type RawLanguageServicesCallbacks } from 'codemirror-rainlang'; + import { completionCallback, hoverCallback, problemsCallback } from '$lib/services/langServices'; let isSubmitting = false; - $: dotrainFile = textFileStore('Rain', ['rain']); - $: topConfig = $settings.chains; - let config = topConfig; - $: { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - invoke("merge_config", {dotrain: $dotrainFile.text, topConfig}).then(v => config = v as any); - }; - - $: order = config[0]; - $: scenario = config[1]; + const dotrainFile = textFileStore('Rain', ['rain']); + const callbacks: RawLanguageServicesCallbacks = { + hover: hoverCallback, + completion: completionCallback, + diagnostics: problemsCallback + } + let ext = new RawRainlangExtension(callbacks); async function execute() { isSubmitting = true; @@ -51,6 +43,7 @@ bind:value={$dotrainFile.text} disabled={isSubmitting} styles={{ '&': { minHeight: '400px' } }} + rainlangExtension={ext} /> @@ -63,26 +56,19 @@ > - - {#if $settings === undefined || $settings.chains.length === 0} + + {#if $deployments === undefined || $deployments.length === 0} {:else} - + v[0]) || []} bind:value={$activeDeploymentIndex}> - {selected.label ? selected.label : selected.rpc_url} + {selected} - {#if option.label} -
-
{option.label}
- {option.rpc_url} -
- {:else} -
- {option.rpc_url} -
- {/if} +
+ {option} +
{/if} diff --git a/tauri-app/src/scripts/typeshareFix.cjs b/tauri-app/src/scripts/typeshareFix.cjs index b05702620..75b75393c 100644 --- a/tauri-app/src/scripts/typeshareFix.cjs +++ b/tauri-app/src/scripts/typeshareFix.cjs @@ -16,11 +16,9 @@ config_content = config_content.replace(`export interface Network { config_content = config_content.replace(`export interface Scenario { bindings: Record; deployer: Deployer; - orderbook?: Orderbook; }`, `export interface Scenario { bindings: Record; runs?: number; deployer: Deployer; - orderbook?: Orderbook; }`); fs.writeFileSync("./tauri-app/src/lib/typeshare/config.ts", config_content); From c090345e05fc10a92b0ba64182ad58c93aefc87c Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Sun, 3 Mar 2024 20:41:42 +0000 Subject: [PATCH 07/48] rm parse.rs from setting crate --- crates/settings/src/lib.rs | 4 +- crates/settings/src/parse.rs | 327 ------------------------------- tauri-app/src-tauri/src/error.rs | 5 +- 3 files changed, 2 insertions(+), 334 deletions(-) delete mode 100644 crates/settings/src/parse.rs diff --git a/crates/settings/src/lib.rs b/crates/settings/src/lib.rs index 8b5faad70..321242adb 100644 --- a/crates/settings/src/lib.rs +++ b/crates/settings/src/lib.rs @@ -6,13 +6,11 @@ pub mod merge; pub mod network; pub mod order; pub mod orderbook; -pub mod parse; pub mod scenario; pub mod string_structs; pub mod token; pub(crate) use chart::*; -pub(crate) use config::*; pub(crate) use deployer::*; pub(crate) use deployment::*; pub(crate) use network::*; @@ -25,7 +23,7 @@ pub(crate) use token::*; #[cfg(test)] mod test; -pub use parse::*; +pub use config::*; #[macro_use] extern crate derive_builder; diff --git a/crates/settings/src/parse.rs b/crates/settings/src/parse.rs deleted file mode 100644 index 454914496..000000000 --- a/crates/settings/src/parse.rs +++ /dev/null @@ -1,327 +0,0 @@ -use alloy_primitives::Address; -use serde::{Deserialize, Serialize}; -use strict_yaml_rust::{scanner::ScanError, StrictYaml, StrictYamlLoader}; -use thiserror::Error; -use typeshare::typeshare; -use url::Url; - -#[derive(Error, Debug)] -pub enum AppSettingsParseError { - #[error("Invalid Yaml")] - YamlInvalid(#[from] ScanError), - #[error("chains element missing field: {0}")] - ChainSettingsFieldMissing(String), - #[error("chains element invalid field: {0}")] - ChainSettingsFieldInvalid(String), - #[error("orderbooks element missing field: {0}")] - OrderbookSettingsFieldMissing(String), - #[error("orderbooks element invalid field: {0}")] - OrderbookSettingsFieldInvalid(String), - #[error(transparent)] - AppSettingsBuilder(#[from] AppSettingsBuilderError), - #[error(transparent)] - OrderbookSettingsBuilder(#[from] OrderbookSettingsBuilderError), - #[error(transparent)] - ChainSettingsBuilder(#[from] ChainSettingsBuilderError), -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Builder)] -pub struct ChainSettings { - label: Option, - #[typeshare(typescript(type = "string"))] - rpc_url: Url, - orderbooks: Vec, -} - -impl TryFrom for ChainSettings { - type Error = AppSettingsParseError; - - fn try_from(val: StrictYaml) -> Result { - let label = val["label"].as_str().map(|s| s.into()); - let rpc_url_str = - val["rpc-url"] - .as_str() - .ok_or(AppSettingsParseError::ChainSettingsFieldMissing( - "rpc-url".into(), - ))?; - let rpc_url = Url::parse(rpc_url_str) - .map_err(|_| AppSettingsParseError::ChainSettingsFieldInvalid("rpc-url".into()))?; - let orderbooks: Vec = val["orderbooks"] - .as_vec() - .unwrap_or(&vec![]) - .iter() - .map(|o| OrderbookSettings::try_from(o.clone())) - .collect::, AppSettingsParseError>>()?; - - Ok(ChainSettingsBuilder::default() - .label(label) - .rpc_url(rpc_url) - .orderbooks(orderbooks) - .build()?) - } -} - -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Builder)] -pub struct OrderbookSettings { - label: Option, - #[typeshare(typescript(type = "string"))] - address: Address, - #[typeshare(typescript(type = "string"))] - subgraph_url: Url, -} - -impl TryFrom for OrderbookSettings { - type Error = AppSettingsParseError; - - fn try_from(val: StrictYaml) -> Result { - let label = val["label"].as_str().map(|s| s.into()); - let address = val["address"] - .as_str() - .ok_or(AppSettingsParseError::OrderbookSettingsFieldMissing( - "address".into(), - ))? - .parse::
() - .map_err(|_| AppSettingsParseError::OrderbookSettingsFieldInvalid("address".into()))?; - let subgraph_url_str = val["subgraph-url"].as_str().ok_or( - AppSettingsParseError::OrderbookSettingsFieldMissing("subgraph-url".into()), - )?; - let subgraph_url = Url::parse(subgraph_url_str).map_err(|_| { - AppSettingsParseError::OrderbookSettingsFieldInvalid("subgraph-url".into()) - })?; - - Ok(OrderbookSettingsBuilder::default() - .label(label) - .address(address) - .subgraph_url(subgraph_url) - .build()?) - } -} - -/// Parse string of settings yaml into AppSettings -/// Text MUST be strict yaml of the following structure -/// -/// ```yaml -/// chains: -/// - rpc-url: https://eth.llamarpc.com -/// orderbooks: -/// - address: 0x0000000000000000000000000000000000000001 -/// subgraph-url: https://api.thegraph.com/subgraphs/name/myname/mysubgraph1 -/// -/// - label: Polygon Infura -/// rpc-url: https://polygon-mainnet.infura.io/v3/abcd -/// orderbooks: -/// - label: My special orderbook -/// address: 0x0000000000000000000000000000000000000002 -/// subgraph-url: https://api.thegraph.com/subgraphs/name/myname/mysubgraph2 -/// -/// - address: 0x0000000000000000000000000000000000000001 -/// subgraph-url: https://api.thegraph.com/subgraphs/name/myname/mysubgraph3 -/// ``` -#[typeshare] -#[derive(Serialize, Deserialize, Debug, Clone, Builder, Default)] -pub struct AppSettings { - chains: Vec, -} - -impl TryFrom for AppSettings { - type Error = AppSettingsParseError; - - fn try_from(val: String) -> Result { - // Parse strict yaml - let yaml_vec = StrictYamlLoader::load_from_str(val.as_str()) - .map_err(AppSettingsParseError::YamlInvalid)?; - let maybe_yaml = yaml_vec.first(); - - match maybe_yaml { - // Yaml has no contents, return empty settings - None => Ok(AppSettings::default()), - - // Yaml has contents, parse them - Some(yaml) => { - let chains: Vec = yaml["chains"] - .as_vec() - .unwrap_or(&vec![]) - .iter() - .map(|v| v.clone().try_into()) - .collect::, Self::Error>>()?; - - Ok(AppSettingsBuilder::default().chains(chains).build()?) - } - } - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn can_create_settings_from_yaml() { - let settings_text: String = " -chains: - - label: Polygon Public Rpc - rpc-url: https://polygon-rpc.com/ - orderbooks: - - label: My special orderbook - address: 0x0000000000000000000000000000000000000001 - subgraph-url: https://api.thegraph.com/subgraphs/name/myname/mysubgraph1 - - - address: 0x0000000000000000000000000000000000000002 - subgraph-url: https://api.thegraph.com/subgraphs/name/myname/mysubgraph2 - - - rpc-url: https://eth-rpc.com - orderbooks: - - address: 0x0000000000000000000000000000000000000003 - subgraph-url: https://api.thegraph.com/subgraphs/name/myname/mysubgraph3 -" - .into(); - - let settings: AppSettings = settings_text.try_into().unwrap(); - - assert_eq!(settings.chains.len(), 2); - assert_eq!(settings.chains[0].label, Some("Polygon Public Rpc".into())); - assert_eq!( - settings.chains[0].rpc_url, - Url::parse("https://polygon-rpc.com/").unwrap() - ); - assert_eq!(settings.chains[0].orderbooks.len(), 2); - assert_eq!( - settings.chains[0].orderbooks[0].label, - Some("My special orderbook".into()) - ); - assert_eq!( - settings.chains[0].orderbooks[0].address, - "0x0000000000000000000000000000000000000001" - .parse::
() - .unwrap() - ); - assert_eq!( - settings.chains[0].orderbooks[0].subgraph_url, - Url::parse("https://api.thegraph.com/subgraphs/name/myname/mysubgraph1").unwrap() - ); - assert_eq!(settings.chains[0].orderbooks[1].label, None); - assert_eq!( - settings.chains[0].orderbooks[1].address, - "0x0000000000000000000000000000000000000002" - .parse::
() - .unwrap() - ); - assert_eq!( - settings.chains[0].orderbooks[1].subgraph_url, - Url::parse("https://api.thegraph.com/subgraphs/name/myname/mysubgraph2").unwrap() - ); - assert_eq!(settings.chains[1].label, None); - assert_eq!( - settings.chains[1].rpc_url, - Url::parse("https://eth-rpc.com").unwrap() - ); - assert_eq!( - settings.chains[1].orderbooks[0].address, - "0x0000000000000000000000000000000000000003" - .parse::
() - .unwrap() - ); - assert_eq!( - settings.chains[1].orderbooks[0].subgraph_url, - Url::parse("https://api.thegraph.com/subgraphs/name/myname/mysubgraph3").unwrap() - ); - } - - #[test] - fn empty_settings() { - let settings_text: String = " -chains: -" - .into(); - - let settings: AppSettings = settings_text.try_into().unwrap(); - assert_eq!(settings.chains.len(), 0); - - let settings_text: String = "".into(); - let settings: AppSettings = settings_text.try_into().unwrap(); - assert_eq!(settings.chains.len(), 0); - } - - #[test] - fn missing_chain_field_rpc_url() { - let settings_text: String = " -chains: - - label: abcd -" - .into(); - let settings: Result = settings_text.try_into(); - assert!(settings.is_err()); - } - - #[test] - fn inavalid_chain_field_rpc_url() { - let settings_text: String = " -chains: - - label: abcd - rpc-url: abcdef -" - .into(); - let settings: Result = settings_text.try_into(); - assert!(settings.is_err()); - } - - #[test] - fn missing_orderbook_field_subgraph_url() { - let settings_text: String = " -chains: - - label: abcd - rpc-url: https://rpc.com - orderbooks: - - address: 0x0000000000000000000000000000000000000003 -" - .into(); - let settings: Result = settings_text.try_into(); - assert!(settings.is_err()); - } - - #[test] - fn missing_orderbook_field_address() { - let settings_text: String = " -chains: - - label: abcd - rpc-url: https://rpc.com - orderbooks: - - subgraph-url: https://mysubgraph.com -" - .into(); - let settings: Result = settings_text.try_into(); - assert!(settings.is_err()); - } - - #[test] - fn invalid_orderbook_field_subgraph_url() { - let settings_text: String = " -chains: - - label: abcd - rpc-url: https://rpc.com - orderbooks: - - address: 0x0000000000000000000000000000000000000003 - subgraph-url: abc -" - .into(); - let settings: Result = settings_text.try_into(); - assert!(settings.is_err()); - } - - #[test] - fn invalid_orderbook_field_address() { - let settings_text: String = " -chains: - - label: abcd - rpc-url: https://rpc.com - orderbooks: - - address: abc - subgraph-url: https://mysubgraph.com -" - .into(); - let settings: Result = settings_text.try_into(); - assert!(settings.is_err()); - } -} diff --git a/tauri-app/src-tauri/src/error.rs b/tauri-app/src-tauri/src/error.rs index f51565e1a..27aecddc2 100644 --- a/tauri-app/src-tauri/src/error.rs +++ b/tauri-app/src-tauri/src/error.rs @@ -1,6 +1,6 @@ use alloy_ethers_typecast::{client::LedgerClientError, transaction::ReadableClientError}; use alloy_primitives::ruint::FromUintError; -use rain_orderbook_app_settings::{config::ParseConfigStringError, AppSettingsParseError}; +use rain_orderbook_app_settings::ParseConfigStringError; use rain_orderbook_common::{ add_order::AddOrderArgsError, csv::TryIntoCsvError, frontmatter::FrontmatterError, meta::TryDecodeRainlangSourceError, rainlang::ForkParseError, utils::timestamp::FormatTimestampDisplayError }; @@ -44,9 +44,6 @@ pub enum CommandError { #[error(transparent)] TryDecodeRainlangSourceError(#[from] TryDecodeRainlangSourceError), - #[error(transparent)] - AppSettingsParseError(#[from] AppSettingsParseError), - #[error(transparent)] ConfigParseError(#[from] ParseConfigStringError), From d2d6785256efbee2013061fa4fefd039ce5342fa Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Sun, 3 Mar 2024 20:42:52 +0000 Subject: [PATCH 08/48] fmt --- crates/common/src/lib.rs | 2 +- tauri-app/src-tauri/src/commands/dotrain_add_order_lsp.rs | 8 ++++++-- tauri-app/src-tauri/src/commands/order.rs | 2 +- tauri-app/src-tauri/src/error.rs | 4 +++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs index ad5c165e4..3a57a3d7e 100644 --- a/crates/common/src/lib.rs +++ b/crates/common/src/lib.rs @@ -3,6 +3,7 @@ pub mod csv; pub mod deposit; pub mod dotrain_add_order_lsp; pub mod frontmatter; +pub mod fuzz; pub mod meta; pub mod rainlang; pub mod remove_order; @@ -11,7 +12,6 @@ pub mod transaction; pub mod types; pub mod utils; pub mod withdraw; -pub mod fuzz; pub use dotrain; pub use dotrain_lsp; diff --git a/tauri-app/src-tauri/src/commands/dotrain_add_order_lsp.rs b/tauri-app/src-tauri/src/commands/dotrain_add_order_lsp.rs index 3e63b124d..6481677a1 100644 --- a/tauri-app/src-tauri/src/commands/dotrain_add_order_lsp.rs +++ b/tauri-app/src-tauri/src/commands/dotrain_add_order_lsp.rs @@ -1,14 +1,18 @@ use crate::error::CommandResult; -use std::collections::HashMap; use alloy_primitives::Address; use rain_orderbook_common::{ dotrain::types::ast::Problem, dotrain_add_order_lsp::{completion, hover, problems}, dotrain_lsp::lsp_types::{CompletionItem, Hover, Position, TextDocumentItem}, }; +use std::collections::HashMap; #[tauri::command] -pub fn call_lsp_hover(text_document: TextDocumentItem, position: Position, bindings: HashMap) -> Option { +pub fn call_lsp_hover( + text_document: TextDocumentItem, + position: Position, + bindings: HashMap, +) -> Option { hover(&text_document, position, bindings) } diff --git a/tauri-app/src-tauri/src/commands/order.rs b/tauri-app/src-tauri/src/commands/order.rs index 231fd1daa..adfe3a3e4 100644 --- a/tauri-app/src-tauri/src/commands/order.rs +++ b/tauri-app/src-tauri/src/commands/order.rs @@ -1,11 +1,11 @@ use crate::error::CommandResult; use crate::{toast::toast_error, transaction_status::TransactionStatusNoticeRwLock}; +use rain_orderbook_app_settings::deployment::Deployment; use rain_orderbook_common::{ add_order::AddOrderArgs, csv::TryIntoCsv, remove_order::RemoveOrderArgs, subgraph::SubgraphArgs, transaction::TransactionArgs, types::OrderDetailExtended, types::OrderFlattened, utils::timestamp::FormatTimestampDisplayError, }; -use rain_orderbook_app_settings::deployment::Deployment; use rain_orderbook_subgraph_client::{types::orders_list, PaginationArgs}; use std::fs; use std::path::PathBuf; diff --git a/tauri-app/src-tauri/src/error.rs b/tauri-app/src-tauri/src/error.rs index 27aecddc2..66b6ec8db 100644 --- a/tauri-app/src-tauri/src/error.rs +++ b/tauri-app/src-tauri/src/error.rs @@ -2,7 +2,9 @@ use alloy_ethers_typecast::{client::LedgerClientError, transaction::ReadableClie use alloy_primitives::ruint::FromUintError; use rain_orderbook_app_settings::ParseConfigStringError; use rain_orderbook_common::{ - add_order::AddOrderArgsError, csv::TryIntoCsvError, frontmatter::FrontmatterError, meta::TryDecodeRainlangSourceError, rainlang::ForkParseError, utils::timestamp::FormatTimestampDisplayError + add_order::AddOrderArgsError, csv::TryIntoCsvError, frontmatter::FrontmatterError, + meta::TryDecodeRainlangSourceError, rainlang::ForkParseError, + utils::timestamp::FormatTimestampDisplayError, }; use rain_orderbook_subgraph_client::OrderbookSubgraphClientError; use serde::{ser::Serializer, Serialize}; From 86ec0a5d275e52b4afc8ad5491b6ef4fb513f360 Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Mon, 4 Mar 2024 01:27:38 +0000 Subject: [PATCH 09/48] fix --- crates/settings/src/lib.rs | 3 - crates/settings/src/merge.rs | 21 ++++++ crates/settings/src/string_structs.rs | 2 +- flake.nix | 2 +- tauri-app/src-tauri/src/commands/config.rs | 22 ++++++- tauri-app/src-tauri/src/error.rs | 5 +- .../src/lib/components/FileTextarea.svelte | 4 ++ tauri-app/src/lib/stores/settings.ts | 66 ++++++++++++------- .../src/lib/storesGeneric/textFileStore.ts | 8 ++- tauri-app/src/routes/orders/add/+page.svelte | 38 +++++------ 10 files changed, 117 insertions(+), 54 deletions(-) diff --git a/crates/settings/src/lib.rs b/crates/settings/src/lib.rs index 321242adb..ffdf391a7 100644 --- a/crates/settings/src/lib.rs +++ b/crates/settings/src/lib.rs @@ -24,6 +24,3 @@ pub(crate) use token::*; mod test; pub use config::*; - -#[macro_use] -extern crate derive_builder; diff --git a/crates/settings/src/merge.rs b/crates/settings/src/merge.rs index 0f3c1fea9..515dd5afe 100644 --- a/crates/settings/src/merge.rs +++ b/crates/settings/src/merge.rs @@ -27,6 +27,9 @@ pub enum MergeError { #[error("There is already a chart called {0}")] ChartCollision(String), + + #[error("There is already a deployment called {0}")] + DeploymentCollision(String), } impl ConfigString { @@ -103,6 +106,15 @@ impl ConfigString { charts.insert(key, value); } + // Deployments + let deployments = &mut self.deployments; + for (key, value) in other.deployments { + if deployments.contains_key(&key) { + return Err(MergeError::DeploymentCollision(key)); + } + deployments.insert(key, value); + } + Ok(()) } } @@ -181,6 +193,15 @@ impl Config { charts.insert(key, value.clone()); } + // Deployments + let deployments = &mut self.deployments; + for (key, value) in other.deployments { + if deployments.contains_key(&key) { + return Err(MergeError::DeploymentCollision(key)); + } + deployments.insert(key, value); + } + Ok(()) } } diff --git a/crates/settings/src/string_structs.rs b/crates/settings/src/string_structs.rs index 7620040cb..184bb7945 100644 --- a/crates/settings/src/string_structs.rs +++ b/crates/settings/src/string_structs.rs @@ -225,7 +225,7 @@ charts: deployments: first-deployment: scenario: mainScenario - order: bytETH + order: sellETH second-deployment: scenario: mainScenario order: buyETH"#; diff --git a/flake.nix b/flake.nix index a738cced6..93f4f4cb7 100644 --- a/flake.nix +++ b/flake.nix @@ -43,7 +43,7 @@ typeshare tauri-app/src-tauri/src/toast.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/toast.ts; typeshare tauri-app/src-tauri/src/transaction_status.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/transactionStatus.ts; - node tauri-app/src/scripts/typeshareFix.cjs + node tauri-app/src/scripts/typeshareFix.cjs || node src/scripts/typeshareFix.cjs # Fix linting of generated types cd tauri-app && npm i && npm run lint diff --git a/tauri-app/src-tauri/src/commands/config.rs b/tauri-app/src-tauri/src/commands/config.rs index 83540b3ea..a0126de46 100644 --- a/tauri-app/src-tauri/src/commands/config.rs +++ b/tauri-app/src-tauri/src/commands/config.rs @@ -1,5 +1,8 @@ use crate::error::CommandResult; -use rain_orderbook_app_settings::config::Config; +use rain_orderbook_app_settings::{ + config::{Config, ParseConfigStringError}, + string_structs::ConfigString, +}; use rain_orderbook_common::frontmatter::get_merged_config; #[tauri::command] @@ -14,6 +17,19 @@ pub fn merge_config(dotrain: String, top_config: Config) -> CommandResult CommandResult { - let top_config = setting_text.try_into()?; - Ok(get_merged_config(dotrain.as_str(), Some(&top_config))?) + let mut top_str_config: ConfigString = setting_text + .try_into() + .map_err(|v| ParseConfigStringError::YamlDeserializerError(v))?; + + let frontmatter = if let Some(splitter) = dotrain.find("---") { + &dotrain[..splitter] + } else { + "" + }; + let dotrain_str_config: ConfigString = frontmatter + .try_into() + .map_err(|v| ParseConfigStringError::YamlDeserializerError(v))?; + + top_str_config.merge(dotrain_str_config)?; + Ok(top_str_config.try_into()?) } diff --git a/tauri-app/src-tauri/src/error.rs b/tauri-app/src-tauri/src/error.rs index 66b6ec8db..682a7de5f 100644 --- a/tauri-app/src-tauri/src/error.rs +++ b/tauri-app/src-tauri/src/error.rs @@ -1,6 +1,6 @@ use alloy_ethers_typecast::{client::LedgerClientError, transaction::ReadableClientError}; use alloy_primitives::ruint::FromUintError; -use rain_orderbook_app_settings::ParseConfigStringError; +use rain_orderbook_app_settings::{merge::MergeError, ParseConfigStringError}; use rain_orderbook_common::{ add_order::AddOrderArgsError, csv::TryIntoCsvError, frontmatter::FrontmatterError, meta::TryDecodeRainlangSourceError, rainlang::ForkParseError, @@ -51,6 +51,9 @@ pub enum CommandError { #[error(transparent)] FrontmatterError(#[from] FrontmatterError), + + #[error(transparent)] + MergeError(#[from] MergeError), } impl Serialize for CommandError { diff --git a/tauri-app/src/lib/components/FileTextarea.svelte b/tauri-app/src/lib/components/FileTextarea.svelte index 430bcb2a9..7e6e7659d 100644 --- a/tauri-app/src/lib/components/FileTextarea.svelte +++ b/tauri-app/src/lib/components/FileTextarea.svelte @@ -43,6 +43,10 @@
+
+ +
+
\ No newline at end of file diff --git a/tauri-app/src/lib/stores/settings.ts b/tauri-app/src/lib/stores/settings.ts index 86a0beae8..f5eebc9a9 100644 --- a/tauri-app/src/lib/stores/settings.ts +++ b/tauri-app/src/lib/stores/settings.ts @@ -7,26 +7,45 @@ import { invoke } from '@tauri-apps/api'; import { type Config } from '$lib/typeshare/config'; import { getBlockNumberFromRpc } from '$lib/services/chain'; +const emptyConfig = { + deployments: {}, + networks: {}, + orderbooks: {}, + orders: {}, + subgraphs: {}, + tokens: {}, + deployers: {}, + scenarios: {}, + charts: {} +}; + // dotrain text store -const dotrainFile = textFileStore('Rain', ['rain']); +export const dotrainFile = textFileStore('Rain', ['rain']); // general export const settingsText = cachedWritableStore('settings', "", (s) => s, (s) => s); export const settingsFile = textFileStore('Orderbook Settings Yaml', ['yml', 'yaml'], get(settingsText)); export const settings = asyncDerived([settingsText, dotrainFile], async ([$settingsText, $dotrainFile]): Promise => { - const config: Config = await invoke("get_config", {dotrain: $dotrainFile.text, settingText: $settingsText}); - return config; -}); + const text = $dotrainFile?.text !== undefined ? $dotrainFile.text : ""; + try { + const config: Config = await invoke("get_config", {dotrain: text, settingText: $settingsText}); + return config; + } catch(e) { + // eslint-disable-next-line no-console + console.log(e); + return emptyConfig; + } +}, { initial: emptyConfig }); // networks -export const networks = derived(settings, ($settingsData) => Object.entries($settingsData.networks)); +export const networks = derived(settings, ($settingsData) => Object.entries($settingsData?.networks)); export const activeNetworkIndex = cachedWritableInt("settings.activeNetworkIndex", 0); export const activeNetwork = derived([networks, activeNetworkIndex], ([$networks, $activeNetworkIndex]) => $networks?.[$activeNetworkIndex]); export const rpcUrl = derived(activeNetwork, ($activeNetwork) => $activeNetwork?.[1].rpc); export const chainId = derived(activeNetwork, ($activeNetwork) => $activeNetwork?.[1].chain_id); export const activeChain = derived(chainId, ($activeChainId) => find(Object.values(chains), (c) => c.id === $activeChainId)); export const activeChainHasBlockExplorer = derived(activeChain, ($activeChain) => { - return $activeChain && $activeChain.blockExplorers?.default !== undefined; + return $activeChain && $activeChain?.blockExplorers?.default !== undefined; }); export const activeChainLatestBlockNumber = derived(activeNetwork, ($activeNetwork) => getBlockNumberFromRpc($activeNetwork?.[1].rpc)); @@ -40,24 +59,11 @@ export const orderbooks = derived([settings, activeNetwork], ([$settingsData, $a && v[1].network.currency === $activeNetwork?.[1].currency )); export const activeOrderbookIndex = cachedWritableInt("settings.activeOrderbookIndex", 0); -export const activeOrderbook = derived([orderbooks, activeOrderbookIndex], ([$orderbooks, $activeOrderbookIndex]) => $orderbooks[$activeOrderbookIndex]); +export const activeOrderbook = derived([orderbooks, activeOrderbookIndex], ([$orderbooks, $activeOrderbookIndex]) => $orderbooks?.[$activeOrderbookIndex]); export const subgraphUrl = derived(activeOrderbook, ($activeOrderbookSettings) => $activeOrderbookSettings?.[1].subgraph); export const orderbookAddress = derived(activeOrderbook, ($activeOrderbookSettings) => $activeOrderbookSettings?.[1].address); -export const hasRequiredSettings = derived([activeNetwork, activeOrderbook], ([$activeChainSettings, $activeOrderbookSettings]) => $activeChainSettings !== undefined && $activeOrderbookSettings !== undefined); - -// When networks data updated, reset active chain -networks.subscribe((val) => { - if(val && val.length < get(activeNetworkIndex)) { - activeNetworkIndex.set(0); - } -}); - -// When active network updated, reset active orderbook and deployment -activeNetwork.subscribe(async () => { - activeOrderbookIndex.set(0); - activeDeploymentIndex.set(0); -}); +export const hasRequiredSettings = derived([activeNetwork, activeOrderbook], ([$activeChainSettings, $activeOrderbookSettings]) => true || ($activeChainSettings !== undefined && $activeOrderbookSettings !== undefined)); // deployments export const deployments = derived([settings, activeNetwork, activeOrderbook], ([$settingsData, $activeNetwork, $activeOrderbook]) => Object.entries($settingsData.deployments).filter(v => { @@ -75,6 +81,20 @@ export const deployments = derived([settings, activeNetwork, activeOrderbook], ( ) : true ) -})); +}) +); export const activeDeploymentIndex = cachedWritableInt("settings.activeDeploymentIndex", 0); -export const activeDeployment = derived([deployments, activeDeploymentIndex], ([$deployments, $activeDeploymentIndex]) => $deployments?.[$activeDeploymentIndex]); \ No newline at end of file +export const activeDeployment = derived([deployments, activeDeploymentIndex], ([$deployments, $activeDeploymentIndex]) => $deployments?.[$activeDeploymentIndex]); + +// // When networks data updated, reset active chain +// networks.subscribe((val) => { +// if(val && val.length < get(activeNetworkIndex)) { +// activeNetworkIndex.set(0); +// } +// }); + +// // When active network updated, reset active orderbook and deployment +// activeNetwork.subscribe(async () => { +// activeOrderbookIndex.set(0); +// activeDeploymentIndex.set(0); +// }); \ No newline at end of file diff --git a/tauri-app/src/lib/storesGeneric/textFileStore.ts b/tauri-app/src/lib/storesGeneric/textFileStore.ts index b1ce1a5e2..3f4a2ae13 100644 --- a/tauri-app/src/lib/storesGeneric/textFileStore.ts +++ b/tauri-app/src/lib/storesGeneric/textFileStore.ts @@ -1,7 +1,7 @@ import { toasts } from '$lib/stores/toasts'; import { open, save } from '@tauri-apps/api/dialog'; import { readTextFile, writeTextFile } from '@tauri-apps/api/fs'; -import { derived, get, writable, type Invalidator, type Subscriber } from "svelte/store"; +import { derived, get, writable, type Invalidator, type Subscriber, type Readable } from "svelte/store"; interface TextFileData { text: string; @@ -15,6 +15,7 @@ interface TextFileData { type Unsubscriber = () => void; export interface TextFileStore { + readable: Readable, subscribe: ( subscriber: Subscriber, invalidate?: Invalidator) => Unsubscriber, set: (v: TextFileData) => void, loadFile: () => Promise, @@ -29,7 +30,7 @@ export function textFileStore(name: string, extensions: string[], defaultText: s const isSaving = writable(false); const isSavingAs = writable(false); - const { subscribe } = derived([text, path, isLoading, isSaving, isSavingAs], ([$text, $path, $isLoading, $isSaving, $isSavingAs]) => ({ + const readable = derived([text, path, isLoading, isSaving, isSavingAs], ([$text, $path, $isLoading, $isSaving, $isSavingAs]) => ({ text: $text, path: $path, isLoading: $isLoading, @@ -115,7 +116,8 @@ export function textFileStore(name: string, extensions: string[], defaultText: s } return { - subscribe, + readable, + subscribe: readable.subscribe, set: (val: TextFileData) => text.set(val.text), loadFile, saveFile, diff --git a/tauri-app/src/routes/orders/add/+page.svelte b/tauri-app/src/routes/orders/add/+page.svelte index fe5895c7e..e7429eb04 100644 --- a/tauri-app/src/routes/orders/add/+page.svelte +++ b/tauri-app/src/routes/orders/add/+page.svelte @@ -1,8 +1,8 @@ +/** eslint-disable no-console */ From 65bc932361d88f9516ca9b93534fc16ba3a02041 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Tue, 12 Mar 2024 22:21:12 -0700 Subject: [PATCH 15/48] feat: all settings fields are kebab-case --- crates/settings/src/chart.rs | 3 +++ crates/settings/src/config.rs | 1 + crates/settings/src/deployment.rs | 1 + crates/settings/src/network.rs | 1 + crates/settings/src/order.rs | 2 ++ crates/settings/src/orderbook.rs | 1 + crates/settings/src/scenario.rs | 1 + crates/settings/src/string_structs.rs | 12 ++++++++++++ crates/settings/src/token.rs | 1 + 9 files changed, 23 insertions(+) diff --git a/crates/settings/src/chart.rs b/crates/settings/src/chart.rs index 0835f3e82..5b1421f68 100644 --- a/crates/settings/src/chart.rs +++ b/crates/settings/src/chart.rs @@ -7,6 +7,7 @@ use crate::*; #[typeshare] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +#[serde(rename_all = "kebab-case")] pub struct Chart { #[typeshare(typescript(type = "Scenario"))] pub scenario: Arc, @@ -15,6 +16,7 @@ pub struct Chart { #[typeshare] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +#[serde(rename_all = "kebab-case")] pub struct Plot { pub data: DataPoints, pub plot_type: String, @@ -22,6 +24,7 @@ pub struct Plot { #[typeshare] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +#[serde(rename_all = "kebab-case")] pub struct DataPoints { pub x: String, pub y: String, diff --git a/crates/settings/src/config.rs b/crates/settings/src/config.rs index 4fe802fe2..23bb14dc1 100644 --- a/crates/settings/src/config.rs +++ b/crates/settings/src/config.rs @@ -9,6 +9,7 @@ use url::Url; #[typeshare] #[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)] +#[serde(rename_all = "kebab-case")] pub struct Config { #[typeshare(typescript(type = "Record"))] pub networks: HashMap>, diff --git a/crates/settings/src/deployment.rs b/crates/settings/src/deployment.rs index 13afde10d..e06396dea 100644 --- a/crates/settings/src/deployment.rs +++ b/crates/settings/src/deployment.rs @@ -6,6 +6,7 @@ use typeshare::typeshare; #[typeshare] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +#[serde(rename_all = "kebab-case")] pub struct Deployment { #[typeshare(typescript(type = "Scenario"))] pub scenario: Arc, diff --git a/crates/settings/src/network.rs b/crates/settings/src/network.rs index 0d4572a1a..2588ad758 100644 --- a/crates/settings/src/network.rs +++ b/crates/settings/src/network.rs @@ -7,6 +7,7 @@ use url::{ParseError, Url}; #[typeshare] #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] pub struct Network { #[typeshare(typescript(type = "string"))] pub rpc: Url, diff --git a/crates/settings/src/order.rs b/crates/settings/src/order.rs index d2d03fff4..7e9d33c96 100644 --- a/crates/settings/src/order.rs +++ b/crates/settings/src/order.rs @@ -7,6 +7,7 @@ use typeshare::typeshare; #[typeshare] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +#[serde(rename_all = "kebab-case")] pub struct OrderIO { #[typeshare(typescript(type = "Token"))] pub token: Arc, @@ -16,6 +17,7 @@ pub struct OrderIO { #[typeshare] #[derive(Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "kebab-case")] pub struct Order { #[typeshare(typescript(type = "OrderIO[]"))] pub inputs: Vec, diff --git a/crates/settings/src/orderbook.rs b/crates/settings/src/orderbook.rs index db9d3aba7..93459943d 100644 --- a/crates/settings/src/orderbook.rs +++ b/crates/settings/src/orderbook.rs @@ -9,6 +9,7 @@ use typeshare::typeshare; #[typeshare] #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] pub struct Orderbook { #[typeshare(typescript(type = "string"))] pub address: Address, diff --git a/crates/settings/src/scenario.rs b/crates/settings/src/scenario.rs index 4e15efdf8..f8a9eb754 100644 --- a/crates/settings/src/scenario.rs +++ b/crates/settings/src/scenario.rs @@ -6,6 +6,7 @@ use typeshare::typeshare; #[typeshare] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +#[serde(rename_all = "kebab-case")] pub struct Scenario { pub name: String, pub bindings: HashMap, diff --git a/crates/settings/src/string_structs.rs b/crates/settings/src/string_structs.rs index 184bb7945..b03d91a08 100644 --- a/crates/settings/src/string_structs.rs +++ b/crates/settings/src/string_structs.rs @@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; #[derive(Debug, Serialize, Deserialize, Clone, Default)] +#[serde(rename_all = "kebab-case")] pub struct ConfigString { #[serde(default)] pub networks: HashMap, @@ -24,6 +25,7 @@ pub struct ConfigString { } #[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] pub struct NetworkString { pub rpc: String, pub chain_id: String, @@ -33,6 +35,7 @@ pub struct NetworkString { } #[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] pub struct OrderbookString { pub address: String, pub network: Option, @@ -41,6 +44,7 @@ pub struct OrderbookString { } #[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] pub struct TokenString { pub network: String, pub address: String, @@ -50,6 +54,7 @@ pub struct TokenString { } #[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] pub struct DeployerString { pub address: String, pub network: Option, @@ -57,18 +62,21 @@ pub struct DeployerString { } #[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] pub struct DeploymentString { pub scenario: String, pub order: String, } #[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] pub struct IOString { pub token: String, pub vault_id: String, } #[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] pub struct OrderString { pub inputs: Vec, pub outputs: Vec, @@ -78,6 +86,7 @@ pub struct OrderString { } #[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] pub struct ScenarioString { #[serde(default)] pub bindings: HashMap, @@ -87,18 +96,21 @@ pub struct ScenarioString { } #[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] pub struct ChartString { pub scenario: Option, pub plots: HashMap, } #[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] pub struct PlotString { pub data: DataPointsString, pub plot_type: String, } #[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] pub struct DataPointsString { pub x: String, pub y: String, diff --git a/crates/settings/src/token.rs b/crates/settings/src/token.rs index c8353d355..8d9a6a405 100644 --- a/crates/settings/src/token.rs +++ b/crates/settings/src/token.rs @@ -7,6 +7,7 @@ use typeshare::typeshare; #[typeshare] #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] pub struct Token { #[typeshare(typescript(type = "Network"))] pub network: Arc, From 11abe9cd1cd8f46854bfc43dac35af7b57ca7e73 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Tue, 12 Mar 2024 22:27:52 -0700 Subject: [PATCH 16/48] feat(tauri/ui): toast errors on settings parse error --- tauri-app/src/lib/stores/settings.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tauri-app/src/lib/stores/settings.ts b/tauri-app/src/lib/stores/settings.ts index 73073b943..1a1720f0a 100644 --- a/tauri-app/src/lib/stores/settings.ts +++ b/tauri-app/src/lib/stores/settings.ts @@ -6,6 +6,7 @@ import { textFileStore } from '$lib/storesGeneric/textFileStore'; import { invoke } from '@tauri-apps/api'; import { type Config } from '$lib/typeshare/config'; import { getBlockNumberFromRpc } from '$lib/services/chain'; +import { toasts } from './toasts'; const emptyConfig = { deployments: {}, @@ -31,8 +32,7 @@ export const settings = asyncDerived([settingsText, dotrainFile], async ([$setti const config: Config = await invoke("get_config", {dotrain: text, settingText: $settingsText}); return config; } catch(e) { - // eslint-disable-next-line no-console - console.log(e); + toasts.error(e as string); return emptyConfig; } }, { initial: emptyConfig }); From 51752e51ade7336f5268512da2e429c907e1e0fc Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Tue, 12 Mar 2024 23:03:37 -0700 Subject: [PATCH 17/48] chore: rename fn get_config -> merge_parse_configs for clarity --- crates/cli/src/commands/order/add.rs | 4 ++-- crates/common/src/add_order.rs | 9 ++++++--- crates/common/src/frontmatter.rs | 10 +--------- tauri-app/src-tauri/src/commands/config.rs | 11 +++-------- tauri-app/src-tauri/src/main.rs | 5 ++--- tauri-app/src/lib/stores/settings.ts | 2 +- 6 files changed, 15 insertions(+), 26 deletions(-) diff --git a/crates/cli/src/commands/order/add.rs b/crates/cli/src/commands/order/add.rs index 27bb12645..a0d107a92 100644 --- a/crates/cli/src/commands/order/add.rs +++ b/crates/cli/src/commands/order/add.rs @@ -4,7 +4,7 @@ use crate::{ use anyhow::{anyhow, Result}; use clap::Args; use rain_orderbook_common::add_order::AddOrderArgs; -use rain_orderbook_common::frontmatter::get_merged_config; +use rain_orderbook_common::frontmatter::merge_parse_configs; use rain_orderbook_common::transaction::TransactionArgs; use std::fs::read_to_string; use std::ops::Deref; @@ -30,7 +30,7 @@ pub struct CliOrderAddArgs { impl CliOrderAddArgs { async fn to_add_order_args(&self) -> Result { let text = read_to_string(&self.dotrain_file).map_err(|e| anyhow!(e))?; - let config = get_merged_config(text.as_str(), None)?; + let config = merge_parse_configs(text.as_str(), None)?; if let Some(config_deployment) = config.deployments.get(&self.deployment) { Ok( AddOrderArgs::new_from_deployment(&text, config_deployment.deref().to_owned()) diff --git a/crates/common/src/add_order.rs b/crates/common/src/add_order.rs index 6865f88d5..c73125d2f 100644 --- a/crates/common/src/add_order.rs +++ b/crates/common/src/add_order.rs @@ -1,6 +1,6 @@ use crate::{ dotrain_add_order_lsp::LANG_SERVICES, - frontmatter::{get_merged_config, FrontmatterError}, + frontmatter::{merge_parse_configs, FrontmatterError}, transaction::{TransactionArgs, TransactionArgsError}, }; use alloy_ethers_typecast::transaction::{ @@ -142,8 +142,11 @@ impl AddOrderArgs { } /// returns the frontmatter config merged with top config - pub fn get_config(&self, top_config: Option<&str>) -> Result { - get_merged_config(&self.dotrain, top_config) + pub fn merge_parse_configs( + &self, + top_config: Option<&str>, + ) -> Result { + merge_parse_configs(&self.dotrain, top_config) } /// Read parser address from deployer contract, then call parser to parse rainlang into bytecode and constants diff --git a/crates/common/src/frontmatter.rs b/crates/common/src/frontmatter.rs index e477de46e..2a6ddf560 100644 --- a/crates/common/src/frontmatter.rs +++ b/crates/common/src/frontmatter.rs @@ -14,16 +14,8 @@ pub enum FrontmatterError { MergeError(#[from] MergeError), } -/// Parse dotrain frontmatter to extract Config -pub fn try_parse_frontmatter(frontmatter: &str) -> Result { - if frontmatter.is_empty() { - return Ok(Config::default()); - } - Ok(frontmatter.try_into()?) -} - /// Parse dotrain frontmatter and merges it with top Config if given -pub fn get_merged_config( +pub fn merge_parse_configs( dotrain: &str, top_config: Option<&str>, ) -> Result { diff --git a/tauri-app/src-tauri/src/commands/config.rs b/tauri-app/src-tauri/src/commands/config.rs index 51019a7db..5b99e3117 100644 --- a/tauri-app/src-tauri/src/commands/config.rs +++ b/tauri-app/src-tauri/src/commands/config.rs @@ -1,15 +1,10 @@ use crate::error::CommandResult; use rain_orderbook_app_settings::config::Config; -use rain_orderbook_common::frontmatter::get_merged_config; +use rain_orderbook_common::frontmatter::merge_parse_configs as merge_parse_configs_inner; #[tauri::command] -pub fn parse_config(text: String) -> CommandResult { - Ok(text.try_into()?) -} - -#[tauri::command] -pub fn get_config(dotrain: String, setting_text: String) -> CommandResult { - Ok(get_merged_config( +pub fn merge_parse_configs(dotrain: String, setting_text: String) -> CommandResult { + Ok(merge_parse_configs_inner( dotrain.as_str(), Some(setting_text.as_str()), )?) diff --git a/tauri-app/src-tauri/src/main.rs b/tauri-app/src-tauri/src/main.rs index 26ade0bdd..9660f6338 100644 --- a/tauri-app/src-tauri/src/main.rs +++ b/tauri-app/src-tauri/src/main.rs @@ -8,7 +8,7 @@ pub mod transaction_status; mod commands; use commands::chain::{get_block_number, get_chainid}; use commands::charts::make_charts; -use commands::config::{get_config, parse_config}; +use commands::config::merge_parse_configs; use commands::dotrain::parse_dotrain; use commands::dotrain_add_order_lsp::{call_lsp_completion, call_lsp_hover, call_lsp_problems}; use commands::order::{order_add, order_detail, order_remove, orders_list, orders_list_write_csv}; @@ -55,8 +55,7 @@ fn run_tauri_app() { call_lsp_completion, call_lsp_hover, call_lsp_problems, - parse_config, - get_config, + merge_parse_configs, make_charts ]) .run(tauri::generate_context!()) diff --git a/tauri-app/src/lib/stores/settings.ts b/tauri-app/src/lib/stores/settings.ts index 1a1720f0a..45ed764f4 100644 --- a/tauri-app/src/lib/stores/settings.ts +++ b/tauri-app/src/lib/stores/settings.ts @@ -29,7 +29,7 @@ export const settingsFile = textFileStore('Orderbook Settings Yaml', ['yml', 'ya export const settings = asyncDerived([settingsText, dotrainFile], async ([$settingsText, $dotrainFile]): Promise => { const text = $dotrainFile?.text !== undefined ? $dotrainFile.text : ""; try { - const config: Config = await invoke("get_config", {dotrain: text, settingText: $settingsText}); + const config: Config = await invoke("merge_parse_configs", {dotrain: text, settingText: $settingsText}); return config; } catch(e) { toasts.error(e as string); From 29e3a3df8ffa209a53f7f3c955c43e5541d900eb Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Tue, 12 Mar 2024 23:17:32 -0700 Subject: [PATCH 18/48] revert(common): contain dotrain lsp parsing functions in a trait for dry clarity --- crates/common/src/dotrain_add_order_lsp.rs | 158 ++++++++---------- .../src/commands/dotrain_add_order_lsp.rs | 10 +- 2 files changed, 80 insertions(+), 88 deletions(-) diff --git a/crates/common/src/dotrain_add_order_lsp.rs b/crates/common/src/dotrain_add_order_lsp.rs index c0a59c1e4..e414eec35 100644 --- a/crates/common/src/dotrain_add_order_lsp.rs +++ b/crates/common/src/dotrain_add_order_lsp.rs @@ -18,97 +18,87 @@ use std::collections::HashMap; /// all the dotrain usage in this crate pub static LANG_SERVICES: Lazy = Lazy::new(RainLanguageServices::default); -/// get hover for a given text document item -pub fn hover( - text_document: &TextDocumentItem, - position: Position, - bindings: HashMap, -) -> Option { - let mut rebinds = None; - if !bindings.is_empty() { - rebinds = Some( - bindings - .iter() - .map(|(key, value)| Rebind(key.clone(), value.clone())) - .collect(), - ); - }; - LANG_SERVICES.do_hover(text_document, position, None, rebinds) +pub struct DotrainAddOrderLsp { + text_document: TextDocumentItem, + rebinds: Option>, } -/// get completion items for a given text document item -pub fn completion( - text_document: &TextDocumentItem, - position: Position, - bindings: HashMap, -) -> Option> { - let mut rebinds = None; - if !bindings.is_empty() { - rebinds = Some( - bindings - .iter() - .map(|(key, value)| Rebind(key.clone(), value.clone())) - .collect(), - ); - }; - LANG_SERVICES.do_complete(text_document, position, None, rebinds) -} - -/// get problems for a given text document item -pub async fn problems( - text_document: &TextDocumentItem, - rpc_url: &str, - block_number: Option, - bindings: HashMap, - deployer: Option
, -) -> Vec { - let mut rebinds = None; - if !bindings.is_empty() { - rebinds = Some( - bindings - .iter() - .map(|(key, value)| Rebind(key.clone(), value.clone())) - .collect(), - ); - }; - let rain_document = LANG_SERVICES.new_rain_document(text_document, rebinds); - let all_problems = rain_document.all_problems(); - if !all_problems.is_empty() { - all_problems.iter().map(|&v| v.clone()).collect() - } else { - let rainlang = match rain_document.compose(&ORDERBOOK_ORDER_ENTRYPOINTS) { - Ok(v) => v, - Err(e) => match e { - ComposeError::Reject(msg) => { - return vec![Problem { - msg, - position: [0, 0], - code: ErrorCode::NativeParserError, - }] - } - ComposeError::Problems(problems) => return problems, - }, +impl DotrainAddOrderLsp { + pub fn new(text_document: TextDocumentItem, bindings: HashMap) -> Self { + let rebinds = if !bindings.is_empty() { + Some( + bindings + .iter() + .map(|(key, value)| Rebind(key.clone(), value.clone())) + .collect(), + ) + } else { + None }; - if let Some(deployer_add) = deployer { - parse_rainlang_on_fork(&rainlang, rpc_url, block_number, deployer_add) - .await - .map_or_else( - |e| { - vec![Problem { - msg: e.to_string(), + Self { + text_document: text_document.clone(), + rebinds, + } + } + + /// get hover for a given text document item + pub fn hover(&self, position: Position) -> Option { + LANG_SERVICES.do_hover(&self.text_document, position, None, self.rebinds.clone()) + } + + /// get completion items for a given text document item + pub fn completion(&self, position: Position) -> Option> { + LANG_SERVICES.do_complete(&self.text_document, position, None, self.rebinds.clone()) + } + + /// get problems for a given text document item + pub async fn problems( + &self, + rpc_url: &str, + block_number: Option, + deployer: Option
, + ) -> Vec { + let rain_document = + LANG_SERVICES.new_rain_document(&self.text_document, self.rebinds.clone()); + let all_problems = rain_document.all_problems(); + if !all_problems.is_empty() { + all_problems.iter().map(|&v| v.clone()).collect() + } else { + let rainlang = match rain_document.compose(&ORDERBOOK_ORDER_ENTRYPOINTS) { + Ok(v) => v, + Err(e) => match e { + ComposeError::Reject(msg) => { + return vec![Problem { + msg, position: [0, 0], code: ErrorCode::NativeParserError, }] - }, - |_| vec![], - ) - } else { - vec![Problem { - msg: "undefined deployer address".to_owned(), - position: [0, 0], - code: ErrorCode::NativeParserError, - }] + } + ComposeError::Problems(problems) => return problems, + }, + }; + + if let Some(deployer_add) = deployer { + parse_rainlang_on_fork(&rainlang, rpc_url, block_number, deployer_add) + .await + .map_or_else( + |e| { + vec![Problem { + msg: e.to_string(), + position: [0, 0], + code: ErrorCode::NativeParserError, + }] + }, + |_| vec![], + ) + } else { + vec![Problem { + msg: "undefined deployer address".to_owned(), + position: [0, 0], + code: ErrorCode::NativeParserError, + }] + } } } } diff --git a/tauri-app/src-tauri/src/commands/dotrain_add_order_lsp.rs b/tauri-app/src-tauri/src/commands/dotrain_add_order_lsp.rs index 6481677a1..b84073a96 100644 --- a/tauri-app/src-tauri/src/commands/dotrain_add_order_lsp.rs +++ b/tauri-app/src-tauri/src/commands/dotrain_add_order_lsp.rs @@ -2,7 +2,7 @@ use crate::error::CommandResult; use alloy_primitives::Address; use rain_orderbook_common::{ dotrain::types::ast::Problem, - dotrain_add_order_lsp::{completion, hover, problems}, + dotrain_add_order_lsp::DotrainAddOrderLsp, dotrain_lsp::lsp_types::{CompletionItem, Hover, Position, TextDocumentItem}, }; use std::collections::HashMap; @@ -13,7 +13,7 @@ pub fn call_lsp_hover( position: Position, bindings: HashMap, ) -> Option { - hover(&text_document, position, bindings) + DotrainAddOrderLsp::new(text_document, bindings).hover(position) } #[tauri::command] @@ -22,7 +22,7 @@ pub fn call_lsp_completion( position: Position, bindings: HashMap, ) -> Option> { - completion(&text_document, position, bindings) + DotrainAddOrderLsp::new(text_document, bindings).completion(position) } #[tauri::command] @@ -33,5 +33,7 @@ pub async fn call_lsp_problems( bindings: HashMap, deployer: Option
, ) -> CommandResult> { - Ok(problems(&text_document, rpc_url, block_number, bindings, deployer).await) + Ok( + DotrainAddOrderLsp::new(text_document, bindings).problems(rpc_url, block_number, deployer).await + ) } From b9342bb99626dbc54b5aea49cfea22eca3b49aee Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Wed, 13 Mar 2024 00:04:02 -0700 Subject: [PATCH 19/48] chore(common): rm no longer accurate, incomplete frontmatter spec comment --- crates/common/src/add_order.rs | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/crates/common/src/add_order.rs b/crates/common/src/add_order.rs index c73125d2f..fb10ccb94 100644 --- a/crates/common/src/add_order.rs +++ b/crates/common/src/add_order.rs @@ -50,26 +50,8 @@ pub enum AddOrderArgsError { } #[derive(Serialize, Deserialize, Clone)] +#[serde(rename = "kebab-case")] pub struct AddOrderArgs { - /// Text of a dotrain file describing an addOrder call - /// Text MUST have strict yaml frontmatter of the following structure - /// - /// ```yaml - /// orderbook: - /// order: - /// deployer: 0x1111111111111111111111111111111111111111 - /// valid-inputs: - /// - address: 0x2222222222222222222222222222222222222222 - /// decimals: 18 - /// vault-id: 0x1234 - /// valid-outputs: - /// - address: 0x5555555555555555555555555555555555555555 - /// decimals: 8 - /// vault-id: 0x5678 - /// ``` - /// - /// Text MUST have valid dotrain body succeding frontmatter. - /// The dotrain body must contain two entrypoints: `calulate-io` and `handle-io`. pub dotrain: String, pub inputs: Vec, pub outputs: Vec, From 0d84db57116ec553516ecb6629f1ba694831c9c4 Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Wed, 13 Mar 2024 20:13:57 +0000 Subject: [PATCH 20/48] update --- Cargo.lock | 10 ++++++---- Cargo.toml | 4 ++-- tauri-app/.gitignore | 2 +- tauri-app/src-tauri/Cargo.lock | 10 ++++++---- tauri-app/src-tauri/Cargo.toml | 2 +- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e572f672d..103a51821 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1847,9 +1847,10 @@ dependencies = [ [[package]] name = "dotrain" version = "6.0.1-alpha.10" -source = "git+https://github.com/rainlanguage/dotrain?rev=b813542cb1c9a2399664a606761f3a3db7b842af#b813542cb1c9a2399664a606761f3a3db7b842af" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08708f5a322925647d011431a93bc015cccfaa42b267d6ce1167f77a7dd44952" dependencies = [ - "alloy-primitives 0.6.4", + "alloy-primitives 0.5.4", "anyhow", "async-recursion", "futures", @@ -1867,9 +1868,10 @@ dependencies = [ [[package]] name = "dotrain-lsp" version = "6.0.1-alpha.10" -source = "git+https://github.com/rainlanguage/dotrain?rev=b813542cb1c9a2399664a606761f3a3db7b842af#b813542cb1c9a2399664a606761f3a3db7b842af" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e80ac27d6e5683915149bbc025554e01ef0f031d79132242ac126aaef6acdd" dependencies = [ - "alloy-primitives 0.6.4", + "alloy-primitives 0.5.4", "anyhow", "dotrain", "lsp-types", diff --git a/Cargo.toml b/Cargo.toml index 8603d6985..f9f879657 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,8 +35,8 @@ chrono = "0.4.31" typeshare = "1.0.1" thiserror = "1.0.56" strict-yaml-rust = "0.1.2" -dotrain = { git = "https://github.com/rainlanguage/dotrain", rev = "b813542cb1c9a2399664a606761f3a3db7b842af" } -dotrain-lsp = { git = "https://github.com/rainlanguage/dotrain", rev = "b813542cb1c9a2399664a606761f3a3db7b842af" } +dotrain = "6.0.1-alpha.10" +dotrain-lsp = "6.0.1-alpha.10" rain-metadata = { path = "lib/rain.metadata/crates/cli" } rain_interpreter_bindings = { path = "lib/rain.interpreter/crates/bindings" } rain_interpreter_dispair = { path = "lib/rain.interpreter/crates/dispair" } diff --git a/tauri-app/.gitignore b/tauri-app/.gitignore index 1d1a44d54..c1b5e4282 100644 --- a/tauri-app/.gitignore +++ b/tauri-app/.gitignore @@ -8,7 +8,7 @@ node_modules !.env.example vite.config.js.timestamp-* vite.config.ts.timestamp-* -src/lib/typeshare +typeshare # for shared libs /lib \ No newline at end of file diff --git a/tauri-app/src-tauri/Cargo.lock b/tauri-app/src-tauri/Cargo.lock index 42fc1d70c..c7f723e07 100644 --- a/tauri-app/src-tauri/Cargo.lock +++ b/tauri-app/src-tauri/Cargo.lock @@ -2267,9 +2267,10 @@ checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" [[package]] name = "dotrain" version = "6.0.1-alpha.10" -source = "git+https://github.com/rainlanguage/dotrain?rev=b813542cb1c9a2399664a606761f3a3db7b842af#b813542cb1c9a2399664a606761f3a3db7b842af" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08708f5a322925647d011431a93bc015cccfaa42b267d6ce1167f77a7dd44952" dependencies = [ - "alloy-primitives 0.6.4", + "alloy-primitives 0.5.4", "anyhow", "async-recursion", "futures", @@ -2287,9 +2288,10 @@ dependencies = [ [[package]] name = "dotrain-lsp" version = "6.0.1-alpha.10" -source = "git+https://github.com/rainlanguage/dotrain?rev=b813542cb1c9a2399664a606761f3a3db7b842af#b813542cb1c9a2399664a606761f3a3db7b842af" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e80ac27d6e5683915149bbc025554e01ef0f031d79132242ac126aaef6acdd" dependencies = [ - "alloy-primitives 0.6.4", + "alloy-primitives 0.5.4", "anyhow", "dotrain", "lsp-types", diff --git a/tauri-app/src-tauri/Cargo.toml b/tauri-app/src-tauri/Cargo.toml index ead81bf3d..c16d7a157 100644 --- a/tauri-app/src-tauri/Cargo.toml +++ b/tauri-app/src-tauri/Cargo.toml @@ -29,7 +29,7 @@ serde_bytes = "0.11.14" thiserror = "1.0.56" url = "2.5.0" serde_yaml = "0.9.32" -dotrain = { git = "https://github.com/rainlanguage/dotrain", rev = "b813542cb1c9a2399664a606761f3a3db7b842af" } +dotrain = "6.0.1-alpha.10" [features] # this feature is used for production builds or when `devPath` points to the filesystem From 4eab3c6716b64bb4fad31c2fd3471eedd9c9b4eb Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Wed, 13 Mar 2024 16:22:10 -0700 Subject: [PATCH 21/48] Revert "update" This reverts commit 0d84db57116ec553516ecb6629f1ba694831c9c4. --- Cargo.lock | 10 ++++------ Cargo.toml | 4 ++-- tauri-app/.gitignore | 2 +- tauri-app/src-tauri/Cargo.lock | 10 ++++------ tauri-app/src-tauri/Cargo.toml | 2 +- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 103a51821..e572f672d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1847,10 +1847,9 @@ dependencies = [ [[package]] name = "dotrain" version = "6.0.1-alpha.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08708f5a322925647d011431a93bc015cccfaa42b267d6ce1167f77a7dd44952" +source = "git+https://github.com/rainlanguage/dotrain?rev=b813542cb1c9a2399664a606761f3a3db7b842af#b813542cb1c9a2399664a606761f3a3db7b842af" dependencies = [ - "alloy-primitives 0.5.4", + "alloy-primitives 0.6.4", "anyhow", "async-recursion", "futures", @@ -1868,10 +1867,9 @@ dependencies = [ [[package]] name = "dotrain-lsp" version = "6.0.1-alpha.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e80ac27d6e5683915149bbc025554e01ef0f031d79132242ac126aaef6acdd" +source = "git+https://github.com/rainlanguage/dotrain?rev=b813542cb1c9a2399664a606761f3a3db7b842af#b813542cb1c9a2399664a606761f3a3db7b842af" dependencies = [ - "alloy-primitives 0.5.4", + "alloy-primitives 0.6.4", "anyhow", "dotrain", "lsp-types", diff --git a/Cargo.toml b/Cargo.toml index c61620ca9..01481fd51 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,8 +35,8 @@ chrono = "0.4.31" typeshare = "1.0.1" thiserror = "1.0.56" strict-yaml-rust = "0.1.2" -dotrain = "6.0.1-alpha.10" -dotrain-lsp = "6.0.1-alpha.10" +dotrain = { git = "https://github.com/rainlanguage/dotrain", rev = "b813542cb1c9a2399664a606761f3a3db7b842af" } +dotrain-lsp = { git = "https://github.com/rainlanguage/dotrain", rev = "b813542cb1c9a2399664a606761f3a3db7b842af" } rain-metadata = { path = "lib/rain.metadata/crates/cli" } rain_interpreter_bindings = { path = "lib/rain.interpreter/crates/bindings" } rain_interpreter_dispair = { path = "lib/rain.interpreter/crates/dispair" } diff --git a/tauri-app/.gitignore b/tauri-app/.gitignore index c1b5e4282..1d1a44d54 100644 --- a/tauri-app/.gitignore +++ b/tauri-app/.gitignore @@ -8,7 +8,7 @@ node_modules !.env.example vite.config.js.timestamp-* vite.config.ts.timestamp-* -typeshare +src/lib/typeshare # for shared libs /lib \ No newline at end of file diff --git a/tauri-app/src-tauri/Cargo.lock b/tauri-app/src-tauri/Cargo.lock index dd04acf94..9b232d252 100644 --- a/tauri-app/src-tauri/Cargo.lock +++ b/tauri-app/src-tauri/Cargo.lock @@ -2267,10 +2267,9 @@ checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" [[package]] name = "dotrain" version = "6.0.1-alpha.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08708f5a322925647d011431a93bc015cccfaa42b267d6ce1167f77a7dd44952" +source = "git+https://github.com/rainlanguage/dotrain?rev=b813542cb1c9a2399664a606761f3a3db7b842af#b813542cb1c9a2399664a606761f3a3db7b842af" dependencies = [ - "alloy-primitives 0.5.4", + "alloy-primitives 0.6.4", "anyhow", "async-recursion", "futures", @@ -2288,10 +2287,9 @@ dependencies = [ [[package]] name = "dotrain-lsp" version = "6.0.1-alpha.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e80ac27d6e5683915149bbc025554e01ef0f031d79132242ac126aaef6acdd" +source = "git+https://github.com/rainlanguage/dotrain?rev=b813542cb1c9a2399664a606761f3a3db7b842af#b813542cb1c9a2399664a606761f3a3db7b842af" dependencies = [ - "alloy-primitives 0.5.4", + "alloy-primitives 0.6.4", "anyhow", "dotrain 6.0.1-alpha.10 (git+https://github.com/rainlanguage/dotrain?rev=b813542cb1c9a2399664a606761f3a3db7b842af)", "lsp-types", diff --git a/tauri-app/src-tauri/Cargo.toml b/tauri-app/src-tauri/Cargo.toml index c16d7a157..ead81bf3d 100644 --- a/tauri-app/src-tauri/Cargo.toml +++ b/tauri-app/src-tauri/Cargo.toml @@ -29,7 +29,7 @@ serde_bytes = "0.11.14" thiserror = "1.0.56" url = "2.5.0" serde_yaml = "0.9.32" -dotrain = "6.0.1-alpha.10" +dotrain = { git = "https://github.com/rainlanguage/dotrain", rev = "b813542cb1c9a2399664a606761f3a3db7b842af" } [features] # this feature is used for production builds or when `devPath` points to the filesystem From 5fbd14425fa9da889f6d7189895406ff8e37782f Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Wed, 13 Mar 2024 16:42:23 -0700 Subject: [PATCH 22/48] chore: gitignore typeshare lib --- tauri-app/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tauri-app/.gitignore b/tauri-app/.gitignore index 1d1a44d54..c1b5e4282 100644 --- a/tauri-app/.gitignore +++ b/tauri-app/.gitignore @@ -8,7 +8,7 @@ node_modules !.env.example vite.config.js.timestamp-* vite.config.ts.timestamp-* -src/lib/typeshare +typeshare # for shared libs /lib \ No newline at end of file From 11eabcbd8c231f1061b7e35d9b8b0fedfaf7fc63 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Wed, 13 Mar 2024 16:45:23 -0700 Subject: [PATCH 23/48] chore: rm unused dep --- Cargo.toml | 1 - tauri-app/src-tauri/Cargo.lock | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 01481fd51..c67c82a42 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,6 @@ rain-interpreter-eval = { path = "lib/rain.interpreter/crates/eval" } csv = "1.3.0" insta = { version = "1.34.0" } proptest = "1.4.0" -k256 = "=0.13.3" derive_builder = "0.20.0" [workspace.dependencies.rain_orderbook_bindings] diff --git a/tauri-app/src-tauri/Cargo.lock b/tauri-app/src-tauri/Cargo.lock index 9b232d252..42fc1d70c 100644 --- a/tauri-app/src-tauri/Cargo.lock +++ b/tauri-app/src-tauri/Cargo.lock @@ -2291,7 +2291,7 @@ source = "git+https://github.com/rainlanguage/dotrain?rev=b813542cb1c9a2399664a6 dependencies = [ "alloy-primitives 0.6.4", "anyhow", - "dotrain 6.0.1-alpha.10 (git+https://github.com/rainlanguage/dotrain?rev=b813542cb1c9a2399664a606761f3a3db7b842af)", + "dotrain", "lsp-types", "once_cell", "regex", @@ -6477,7 +6477,7 @@ dependencies = [ "alloy-sol-types 0.6.4", "chrono", "csv", - "dotrain 6.0.1-alpha.10 (git+https://github.com/rainlanguage/dotrain?rev=b813542cb1c9a2399664a606761f3a3db7b842af)", + "dotrain", "dotrain-lsp", "once_cell", "proptest", From 520b1c6dc0430cba34b7a1422372716970dace8a Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Wed, 13 Mar 2024 23:02:02 -0700 Subject: [PATCH 24/48] build(tauri): switch to fork of typeshare with support for u64/i64: https://github.com/1Password/typeshare/pull/140 --- Cargo.lock | 6 ++---- Cargo.toml | 2 +- flake.nix | 4 +++- tauri-app/src-tauri/Cargo.lock | 30 +++++++++++++++++++++++++----- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e572f672d..5c2b7224b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6726,8 +6726,7 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typeshare" version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f44d1a2f454cb35fbe05b218c410792697e76bd868f48d3a418f2cd1a7d527d6" +source = "git+https://github.com/1password/typeshare?rev=556b44aafd5304eedf17206800f69834e3820b7c#556b44aafd5304eedf17206800f69834e3820b7c" dependencies = [ "chrono", "serde", @@ -6738,8 +6737,7 @@ dependencies = [ [[package]] name = "typeshare-annotation" version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc670d0e358428857cc3b4bf504c691e572fccaec9542ff09212d3f13d74b7a9" +source = "git+https://github.com/1password/typeshare?rev=556b44aafd5304eedf17206800f69834e3820b7c#556b44aafd5304eedf17206800f69834e3820b7c" dependencies = [ "quote", "syn 1.0.109", diff --git a/Cargo.toml b/Cargo.toml index c67c82a42..810858232 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ comfy-table = "7.1.0" cynic-codegen = { version = "3.4.0", features = ["rkyv"] } cynic = "3.4.0" chrono = "0.4.31" -typeshare = "1.0.1" +typeshare = { git = "https://github.com/1password/typeshare", rev = "556b44aafd5304eedf17206800f69834e3820b7c" } thiserror = "1.0.56" strict-yaml-rust = "0.1.2" dotrain = { git = "https://github.com/rainlanguage/dotrain", rev = "b813542cb1c9a2399664a606761f3a3db7b842af" } diff --git a/flake.nix b/flake.nix index 868b876bd..fe4472270 100644 --- a/flake.nix +++ b/flake.nix @@ -23,6 +23,8 @@ # Generate Typescript types from rust types mkdir -p tauri-app/src/lib/typeshare; + cargo install --git https://github.com/1Password/typeshare --rev 556b44aafd5304eedf17206800f69834e3820b7c + typeshare crates/subgraph/src/types/vault_balance_changes_list.rs crates/subgraph/src/types/vault_balance_change.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/vaultBalanceChangesList.ts; typeshare crates/subgraph/src/types/order_detail.rs crates/common/src/types/order_detail_extended.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/orderDetail.ts; @@ -36,6 +38,7 @@ typeshare crates/settings/src/parse.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/appSettings.ts; typeshare crates/settings/src/config.rs crates/settings/src/chart.rs crates/settings/src/deployer.rs crates/settings/src/network.rs crates/settings/src/order.rs crates/settings/src/orderbook.rs crates/settings/src/scenario.rs crates/settings/src/token.rs crates/settings/src/deployment.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/config.ts; + typeshare crates/settings/src/string_structs.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/configString.ts; typeshare tauri-app/src-tauri/src/toast.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/toast.ts; typeshare tauri-app/src-tauri/src/transaction_status.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/transactionStatus.ts; @@ -46,7 +49,6 @@ cd tauri-app && npm i && npm run lint ''; additionalBuildInputs = [ - pkgs.typeshare pkgs.wasm-bindgen-cli rainix.rust-toolchain.${system} rainix.rust-build-inputs.${system} diff --git a/tauri-app/src-tauri/Cargo.lock b/tauri-app/src-tauri/Cargo.lock index 42fc1d70c..8723b3c8b 100644 --- a/tauri-app/src-tauri/Cargo.lock +++ b/tauri-app/src-tauri/Cargo.lock @@ -6453,7 +6453,7 @@ dependencies = [ "serde_yaml", "strict-yaml-rust", "thiserror", - "typeshare", + "typeshare 1.0.1 (git+https://github.com/1password/typeshare?rev=556b44aafd5304eedf17206800f69834e3820b7c)", "url", ] @@ -6498,7 +6498,7 @@ dependencies = [ "thiserror", "tokio", "tracing", - "typeshare", + "typeshare 1.0.1 (git+https://github.com/1password/typeshare?rev=556b44aafd5304eedf17206800f69834e3820b7c)", "url", ] @@ -6514,7 +6514,7 @@ dependencies = [ "reqwest", "serde", "thiserror", - "typeshare", + "typeshare 1.0.1 (git+https://github.com/1password/typeshare?rev=556b44aafd5304eedf17206800f69834e3820b7c)", ] [[package]] @@ -8464,7 +8464,7 @@ dependencies = [ "tauri-build", "tauri-cli", "thiserror", - "typeshare", + "typeshare 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "url", "uuid 1.7.0", ] @@ -9225,7 +9225,18 @@ dependencies = [ "chrono", "serde", "serde_json", - "typeshare-annotation", + "typeshare-annotation 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "typeshare" +version = "1.0.1" +source = "git+https://github.com/1password/typeshare?rev=556b44aafd5304eedf17206800f69834e3820b7c#556b44aafd5304eedf17206800f69834e3820b7c" +dependencies = [ + "chrono", + "serde", + "serde_json", + "typeshare-annotation 1.0.2 (git+https://github.com/1password/typeshare?rev=556b44aafd5304eedf17206800f69834e3820b7c)", ] [[package]] @@ -9238,6 +9249,15 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "typeshare-annotation" +version = "1.0.2" +source = "git+https://github.com/1password/typeshare?rev=556b44aafd5304eedf17206800f69834e3820b7c#556b44aafd5304eedf17206800f69834e3820b7c" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "ucd-trie" version = "0.1.6" From 8fa26cf51834b78bee53c18a7aeb9543782fdca4 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Wed, 13 Mar 2024 23:05:46 -0700 Subject: [PATCH 25/48] refactor(settings): ConfigString structs now take actual value types for all fields *except* 'foreign key' refs --- crates/cli/src/commands/order/add.rs | 9 ++- crates/common/src/add_order.rs | 8 +- crates/common/src/frontmatter.rs | 7 +- crates/settings/src/config.rs | 40 ++++------ crates/settings/src/deployer.rs | 29 +------ crates/settings/src/merge.rs | 16 ++-- crates/settings/src/network.rs | 78 ++----------------- crates/settings/src/order.rs | 10 +-- crates/settings/src/orderbook.rs | 38 ++-------- crates/settings/src/scenario.rs | 25 +++--- crates/settings/src/string_structs.rs | 105 +++++++++++++++++--------- crates/settings/src/token.rs | 62 ++------------- typeshare.toml | 2 + 13 files changed, 149 insertions(+), 280 deletions(-) diff --git a/crates/cli/src/commands/order/add.rs b/crates/cli/src/commands/order/add.rs index a0d107a92..b52d32b31 100644 --- a/crates/cli/src/commands/order/add.rs +++ b/crates/cli/src/commands/order/add.rs @@ -30,12 +30,13 @@ pub struct CliOrderAddArgs { impl CliOrderAddArgs { async fn to_add_order_args(&self) -> Result { let text = read_to_string(&self.dotrain_file).map_err(|e| anyhow!(e))?; - let config = merge_parse_configs(text.as_str(), None)?; + let config = merge_parse_configs(text.clone(), None)?; if let Some(config_deployment) = config.deployments.get(&self.deployment) { - Ok( - AddOrderArgs::new_from_deployment(&text, config_deployment.deref().to_owned()) - .await?, + Ok(AddOrderArgs::new_from_deployment( + text.clone(), + config_deployment.deref().to_owned(), ) + .await?) } else { Err(anyhow!("specified deployment is undefined!")) } diff --git a/crates/common/src/add_order.rs b/crates/common/src/add_order.rs index fb10ccb94..280986a94 100644 --- a/crates/common/src/add_order.rs +++ b/crates/common/src/add_order.rs @@ -60,9 +60,9 @@ pub struct AddOrderArgs { } impl AddOrderArgs { - /// create a new instance from Deployemnt + /// create a new instance from Deployment pub async fn new_from_deployment( - dotrain: &str, + dotrain: String, deployment: Deployment, ) -> Result { let mut inputs = vec![]; @@ -126,9 +126,9 @@ impl AddOrderArgs { /// returns the frontmatter config merged with top config pub fn merge_parse_configs( &self, - top_config: Option<&str>, + top_config: Option, ) -> Result { - merge_parse_configs(&self.dotrain, top_config) + merge_parse_configs(self.dotrain.clone(), top_config) } /// Read parser address from deployer contract, then call parser to parse rainlang into bytecode and constants diff --git a/crates/common/src/frontmatter.rs b/crates/common/src/frontmatter.rs index 2a6ddf560..1545dcddb 100644 --- a/crates/common/src/frontmatter.rs +++ b/crates/common/src/frontmatter.rs @@ -16,11 +16,12 @@ pub enum FrontmatterError { /// Parse dotrain frontmatter and merges it with top Config if given pub fn merge_parse_configs( - dotrain: &str, - top_config: Option<&str>, + dotrain: String, + top_config: Option, ) -> Result { - let frontmatter = RainDocument::get_front_matter(dotrain).unwrap_or(""); + let frontmatter = RainDocument::get_front_matter(dotrain.as_str()).unwrap_or(""); let mut frontmatter_str_config: ConfigString = frontmatter + .to_string() .try_into() .map_err(ParseConfigStringError::YamlDeserializerError)?; if let Some(v) = top_config { diff --git a/crates/settings/src/config.rs b/crates/settings/src/config.rs index 23bb14dc1..a0b84ad15 100644 --- a/crates/settings/src/config.rs +++ b/crates/settings/src/config.rs @@ -71,16 +71,7 @@ impl TryFrom for Config { let subgraphs = item .subgraphs .into_iter() - .map(|(name, subgraph)| { - Ok(( - name, - Arc::new( - subgraph - .parse() - .map_err(ParseConfigStringError::SubgraphParseError)?, - ), - )) - }) + .map(|(name, subgraph)| Ok((name, Arc::new(subgraph)))) .collect::>, ParseConfigStringError>>()?; let orderbooks = item @@ -182,13 +173,6 @@ impl TryFrom for Config { } } -impl TryFrom<&str> for Config { - type Error = ParseConfigStringError; - fn try_from(val: &str) -> Result { - std::convert::TryInto::::try_into(val)?.try_into() - } -} - #[cfg(test)] mod tests { use super::*; @@ -202,10 +186,10 @@ mod tests { networks.insert( "mainnet".to_string(), NetworkString { - rpc: "https://mainnet.node".to_string(), - chain_id: "1".to_string(), + rpc: Url::parse("https://mainnet.node").unwrap(), + chain_id: 1, label: Some("Ethereum Mainnet".to_string()), - network_id: Some("1".to_string()), + network_id: Some(1), currency: Some("ETH".to_string()), }, ); @@ -213,14 +197,16 @@ mod tests { let mut subgraphs = HashMap::new(); subgraphs.insert( "mainnet".to_string(), - "https://mainnet.subgraph".to_string(), + Url::parse("https://mainnet.subgraph").unwrap(), ); let mut orderbooks = HashMap::new(); orderbooks.insert( "mainnetOrderbook".to_string(), OrderbookString { - address: "0x1234567890123456789012345678901234567890".to_string(), + address: "0x1234567890123456789012345678901234567890" + .parse::
() + .unwrap(), network: Some("mainnet".to_string()), subgraph: Some("mainnet".to_string()), label: Some("Mainnet Orderbook".to_string()), @@ -232,8 +218,10 @@ mod tests { "ETH".to_string(), TokenString { network: "mainnet".to_string(), - address: "0x7890123456789012345678901234567890123456".to_string(), - decimals: Some("18".to_string()), + address: "0x7890123456789012345678901234567890123456" + .parse::
() + .unwrap(), + decimals: Some(18), label: Some("Ethereum".to_string()), symbol: Some("ETH".to_string()), }, @@ -243,7 +231,9 @@ mod tests { deployers.insert( "mainDeployer".to_string(), DeployerString { - address: "0xabcdef0123456789ABCDEF0123456789ABCDEF01".to_string(), + address: "0xabcdef0123456789ABCDEF0123456789ABCDEF01" + .parse::
() + .unwrap(), network: Some("mainnet".to_string()), label: Some("Mainnet Deployer".to_string()), }, diff --git a/crates/settings/src/deployer.rs b/crates/settings/src/deployer.rs index 9079fff78..1c2f23fb6 100644 --- a/crates/settings/src/deployer.rs +++ b/crates/settings/src/deployer.rs @@ -43,10 +43,7 @@ impl DeployerString { }; Ok(Deployer { - address: self - .address - .parse() - .map_err(ParseDeployerStringError::AddressParseError)?, + address: self.address, network: network_ref, label: self.label, }) @@ -76,7 +73,7 @@ mod tests { let network_name = "Local Testnet"; let networks = HashMap::from([(network_name.to_string(), mock_network())]); let deployer_string = DeployerString { - address: address.to_string(), + address: address, network: Some(network_name.to_string()), label: Some("Test Deployer".to_string()), }; @@ -92,31 +89,13 @@ mod tests { assert_eq!(deployer.label, Some("Test Deployer".to_string())); } - #[test] - fn test_try_into_deployer_address_parse_error() { - let invalid_address = "zzz"; // Intentionally invalid address format - let network_name = "testnet"; - let networks = HashMap::from([(network_name.to_string(), mock_network())]); - let deployer_string = DeployerString { - address: invalid_address.into(), - network: Some(network_name.to_string()), - label: Some("Invalid Deployer".to_string()), - }; - - let result = deployer_string.try_into_deployer(network_name.to_string(), &networks); - assert!(matches!( - result, - Err(ParseDeployerStringError::AddressParseError(_)) - )); - } - #[test] fn test_try_into_deployer_network_not_found_error() { let address = Address::repeat_byte(0x01); let invalid_network_name = "unknownnet"; let networks = HashMap::new(); // Empty networks map let deployer_string = DeployerString { - address: address.to_string(), + address, network: Some(invalid_network_name.to_string()), label: None, }; @@ -134,7 +113,7 @@ mod tests { let network_name = "Local Testnet"; let networks = HashMap::from([(network_name.to_string(), mock_network())]); let deployer_string = DeployerString { - address: address.to_string(), + address, network: None, // No network specified label: None, }; diff --git a/crates/settings/src/merge.rs b/crates/settings/src/merge.rs index 515dd5afe..c51c150a1 100644 --- a/crates/settings/src/merge.rs +++ b/crates/settings/src/merge.rs @@ -208,6 +208,8 @@ impl Config { #[cfg(test)] mod tests { + use url::Url; + use super::*; use std::collections::HashMap; #[test] @@ -266,13 +268,15 @@ mod tests { }; // Add a collision to cause an unsuccessful merge - config - .subgraphs - .insert("subgraph1".to_string(), "value1".to_string()); + config.subgraphs.insert( + "subgraph1".to_string(), + Url::parse("https://myurl").unwrap(), + ); - other - .subgraphs - .insert("subgraph1".to_string(), "value1".to_string()); + other.subgraphs.insert( + "subgraph1".to_string(), + Url::parse("https://myurl").unwrap(), + ); assert_eq!( config.merge(other), diff --git a/crates/settings/src/network.rs b/crates/settings/src/network.rs index 2588ad758..31eb43501 100644 --- a/crates/settings/src/network.rs +++ b/crates/settings/src/network.rs @@ -34,22 +34,10 @@ impl TryFrom for Network { fn try_from(item: NetworkString) -> Result { Ok(Network { - rpc: item - .rpc - .parse() - .map_err(ParseNetworkStringError::RpcParseError)?, - chain_id: item - .chain_id - .parse() - .map_err(ParseNetworkStringError::ChainIdParseError)?, + rpc: item.rpc, + chain_id: item.chain_id, label: item.label, - network_id: item - .network_id - .map(|id| { - id.parse() - .map_err(ParseNetworkStringError::NetworkIdParseError) - }) - .transpose()?, + network_id: item.network_id, currency: item.currency, }) } @@ -63,9 +51,9 @@ mod tests { #[test] fn test_try_from_network_string_success() { let network_string = NetworkString { - rpc: "http://127.0.0.1:8545".into(), - chain_id: "1".into(), - network_id: Some("1".into()), + rpc: Url::parse("http://127.0.0.1:8545").unwrap(), + chain_id: 1, + network_id: Some(1), label: Some("Local Testnet".into()), currency: Some("ETH".into()), }; @@ -80,58 +68,4 @@ mod tests { assert_eq!(network.label, Some("Local Testnet".into())); assert_eq!(network.currency, Some("ETH".into())); } - - #[test] - fn test_try_from_network_string_rpc_parse_error() { - let invalid_rpc = "invalid_url"; // Intentionally invalid URL - let network_string = NetworkString { - rpc: invalid_rpc.into(), - chain_id: "1".into(), - network_id: Some("1".into()), - label: None, - currency: None, - }; - - let result = Network::try_from(network_string); - assert!(matches!( - result, - Err(ParseNetworkStringError::RpcParseError(_)) - )); - } - - #[test] - fn test_try_from_network_string_chain_id_parse_error() { - let invalid_chain_id = "abc"; // Intentionally invalid number format - let network_string = NetworkString { - rpc: "http://127.0.0.1:8545".into(), - chain_id: invalid_chain_id.into(), - network_id: Some("1".into()), - label: None, - currency: None, - }; - - let result = Network::try_from(network_string); - assert!(matches!( - result, - Err(ParseNetworkStringError::ChainIdParseError(_)) - )); - } - - #[test] - fn test_try_from_network_string_network_id_parse_error() { - let invalid_network_id = "abc"; // Intentionally invalid number format - let network_string = NetworkString { - rpc: "http://127.0.0.1:8545".into(), - chain_id: "1".into(), - network_id: Some(invalid_network_id.into()), - label: None, - currency: None, - }; - - let result = Network::try_from(network_string); - assert!(matches!( - result, - Err(ParseNetworkStringError::NetworkIdParseError(_)) - )); - } } diff --git a/crates/settings/src/order.rs b/crates/settings/src/order.rs index 7e9d33c96..803bb3031 100644 --- a/crates/settings/src/order.rs +++ b/crates/settings/src/order.rs @@ -111,7 +111,7 @@ impl OrderString { if v.network == network { Ok(OrderIO { token: v.clone(), - vault_id: input.vault_id.parse::()?, + vault_id: input.vault_id, }) } else { Err(ParseOrderStringError::NetworkNotMatch) @@ -133,7 +133,7 @@ impl OrderString { if v.network == network { Ok(OrderIO { token: v.clone(), - vault_id: output.vault_id.parse::()?, + vault_id: output.vault_id, }) } else { Err(ParseOrderStringError::NetworkNotMatch) @@ -183,11 +183,11 @@ mod tests { orderbook: Some("Orderbook1".to_string()), inputs: vec![IOString { token: "Token1".to_string(), - vault_id: "1".to_string(), + vault_id: U256::from(1), }], outputs: vec![IOString { token: "Token2".to_string(), - vault_id: "2".to_string(), + vault_id: U256::from(2), }], }; @@ -293,7 +293,7 @@ mod tests { orderbook: None, inputs: vec![IOString { token: "Nonexistent Token".to_string(), - vault_id: "1".to_string(), + vault_id: U256::from(1), }], outputs: vec![], }; diff --git a/crates/settings/src/orderbook.rs b/crates/settings/src/orderbook.rs index 93459943d..27a436572 100644 --- a/crates/settings/src/orderbook.rs +++ b/crates/settings/src/orderbook.rs @@ -68,10 +68,7 @@ impl OrderbookString { }; Ok(Orderbook { - address: self - .address - .parse() - .map_err(ParseOrderbookStringError::AddressParseError)?, + address: self.address, network: network_ref, subgraph: subgraph_ref, label: self.label, @@ -104,9 +101,11 @@ mod tests { #[test] fn test_orderbook_creation_success() { let (networks, subgraphs) = setup(); - let address = "0x1234567890123456789012345678901234567890"; + let address = "0x1234567890123456789012345678901234567890" + .parse::
() + .unwrap(); let orderbook_string = OrderbookString { - address: address.to_string(), + address, network: Some("TestNetwork".to_string()), subgraph: Some("TestSubgraph".to_string()), label: Some("TestLabel".to_string()), @@ -118,7 +117,7 @@ mod tests { assert!(orderbook.is_ok()); let orderbook = orderbook.unwrap(); - assert_eq!(orderbook.address, address.parse::
().unwrap()); + assert_eq!(orderbook.address, address); assert_eq!( Arc::as_ptr(&orderbook.network), Arc::as_ptr(networks.get("TestNetwork").unwrap()) @@ -134,7 +133,7 @@ mod tests { fn test_orderbook_creation_with_missing_network() { let (networks, subgraphs) = setup(); let orderbook_string = OrderbookString { - address: "1234".to_string(), + address: Address::random(), network: Some("NonExistingNetwork".to_string()), subgraph: Some("TestSubgraph".to_string()), label: None, @@ -154,7 +153,7 @@ mod tests { fn test_orderbook_creation_with_missing_subgraph() { let (networks, subgraphs) = setup(); let orderbook_string = OrderbookString { - address: "1234".to_string(), + address: Address::random(), network: Some("TestNetwork".to_string()), subgraph: Some("NonExistingSubgraph".to_string()), label: None, @@ -169,25 +168,4 @@ mod tests { ParseOrderbookStringError::SubgraphNotFoundError("NonExistingSubgraph".to_string()) ); } - - #[test] - fn test_orderbook_creation_with_invalid_address() { - let (networks, subgraphs) = setup(); - let invalid_address = "InvalidAddress"; - let orderbook_string = OrderbookString { - address: invalid_address.to_string(), - network: Some("TestNetwork".to_string()), - subgraph: Some("TestSubgraph".to_string()), - label: None, - }; - - let result = - orderbook_string.try_into_orderbook("TestName".to_string(), &networks, &subgraphs); - - assert!(result.is_err()); - match result.unwrap_err() { - ParseOrderbookStringError::AddressParseError(_) => (), - _ => panic!("Expected AddressParseError"), - } - } } diff --git a/crates/settings/src/scenario.rs b/crates/settings/src/scenario.rs index f8a9eb754..13bbcc1a7 100644 --- a/crates/settings/src/scenario.rs +++ b/crates/settings/src/scenario.rs @@ -91,12 +91,7 @@ impl ScenarioString { let parent_scenario = Arc::new(Scenario { name: name.clone(), bindings: bindings.clone(), - runs: self - .runs - .as_ref() - .map(|s| s.parse::()) - .transpose() - .map_err(ParseScenarioStringError::RunsParseError)?, + runs: self.runs, deployer: deployer_ref.clone(), }); @@ -127,6 +122,8 @@ impl ScenarioString { mod tests { use crate::test::mock_deployer; + use alloy_primitives::Address; + use url::Url; use super::*; use std::collections::HashMap; @@ -138,10 +135,10 @@ mod tests { networks.insert( "mainnet".to_string(), NetworkString { - rpc: "https://mainnet.node".to_string(), - chain_id: "1".to_string(), + rpc: Url::parse("https://mainnet.node").unwrap(), + chain_id: 1, label: Some("Ethereum Mainnet".to_string()), - network_id: Some("1".to_string()), + network_id: Some(1), currency: Some("ETH".to_string()), }, ); @@ -151,7 +148,9 @@ mod tests { deployers.insert( "mainnet".to_string(), DeployerString { - address: "0xabcdef0123456789ABCDEF0123456789ABCDEF01".to_string(), + address: "0xabcdef0123456789ABCDEF0123456789ABCDEF01" + .parse::
() + .unwrap(), network: None, label: Some("Mainnet Deployer".to_string()), }, @@ -163,7 +162,7 @@ mod tests { "nested_scenario2".to_string(), ScenarioString { bindings: HashMap::new(), // Assuming no bindings for simplification - runs: Some("2".to_string()), + runs: Some(2), deployer: None, scenarios: None, // No further nesting }, @@ -174,7 +173,7 @@ mod tests { "nested_scenario1".to_string(), ScenarioString { bindings: HashMap::new(), // Assuming no bindings for simplification - runs: Some("5".to_string()), + runs: Some(5), deployer: None, scenarios: Some(nested_scenario2), // Include nested_scenario2 }, @@ -186,7 +185,7 @@ mod tests { "root_scenario".to_string(), ScenarioString { bindings: HashMap::new(), // Assuming no bindings for simplification - runs: Some("10".to_string()), + runs: Some(10), deployer: Some("mainnet".to_string()), scenarios: Some(nested_scenario1), // Include nested_scenario1 }, diff --git a/crates/settings/src/string_structs.rs b/crates/settings/src/string_structs.rs index b03d91a08..ee6b3f7b6 100644 --- a/crates/settings/src/string_structs.rs +++ b/crates/settings/src/string_structs.rs @@ -1,13 +1,17 @@ +use alloy_primitives::{Address, U256}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; +use typeshare::typeshare; +use url::Url; +#[typeshare] #[derive(Debug, Serialize, Deserialize, Clone, Default)] #[serde(rename_all = "kebab-case")] pub struct ConfigString { #[serde(default)] pub networks: HashMap, #[serde(default)] - pub subgraphs: HashMap, + pub subgraphs: HashMap, #[serde(default)] pub orderbooks: HashMap, #[serde(default)] @@ -24,84 +28,119 @@ pub struct ConfigString { pub deployments: HashMap, } +#[typeshare] +pub type SubgraphRef = String; + +#[typeshare] +pub type ScenarioRef = String; + +#[typeshare] +pub type NetworkRef = String; + +#[typeshare] +pub type DeployerRef = String; + +#[typeshare] +pub type OrderRef = String; + +#[typeshare] +pub type OrderbookRef = String; + +#[typeshare] +pub type TokenRef = String; + +#[typeshare] #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "kebab-case")] pub struct NetworkString { - pub rpc: String, - pub chain_id: String, + pub rpc: Url, + #[typeshare(typescript(type = "number"))] + pub chain_id: u64, pub label: Option, - pub network_id: Option, + #[typeshare(typescript(type = "number"))] + pub network_id: Option, pub currency: Option, } +#[typeshare] #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "kebab-case")] pub struct OrderbookString { - pub address: String, - pub network: Option, - pub subgraph: Option, + pub address: Address, + pub network: Option, + pub subgraph: Option, pub label: Option, } +#[typeshare] #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "kebab-case")] pub struct TokenString { - pub network: String, - pub address: String, - pub decimals: Option, + pub network: NetworkRef, + pub address: Address, + pub decimals: Option, pub label: Option, pub symbol: Option, } +#[typeshare] #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "kebab-case")] pub struct DeployerString { - pub address: String, - pub network: Option, + pub address: Address, + pub network: Option, pub label: Option, } +#[typeshare] #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "kebab-case")] pub struct DeploymentString { - pub scenario: String, - pub order: String, + pub scenario: ScenarioRef, + pub order: OrderRef, } +#[typeshare] #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "kebab-case")] pub struct IOString { - pub token: String, - pub vault_id: String, + pub token: TokenRef, + #[typeshare(typescript(type = "bigint"))] + pub vault_id: U256, } +#[typeshare] #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "kebab-case")] pub struct OrderString { pub inputs: Vec, pub outputs: Vec, - pub network: String, - pub deployer: Option, - pub orderbook: Option, + pub network: NetworkRef, + pub deployer: Option, + pub orderbook: Option, } +#[typeshare] #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "kebab-case")] pub struct ScenarioString { #[serde(default)] pub bindings: HashMap, - pub runs: Option, - pub deployer: Option, + #[typeshare(typescript(type = "number"))] + pub runs: Option, + pub deployer: Option, pub scenarios: Option>, } +#[typeshare] #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "kebab-case")] pub struct ChartString { - pub scenario: Option, + pub scenario: Option, pub plots: HashMap, } +#[typeshare] #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "kebab-case")] pub struct PlotString { @@ -109,6 +148,7 @@ pub struct PlotString { pub plot_type: String, } +#[typeshare] #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "kebab-case")] pub struct DataPointsString { @@ -123,13 +163,6 @@ impl TryFrom for ConfigString { } } -impl TryFrom<&str> for ConfigString { - type Error = serde_yaml::Error; - fn try_from(val: &str) -> Result { - serde_yaml::from_str(val) - } -} - #[cfg(test)] mod tests { use super::*; @@ -240,14 +273,15 @@ deployments: order: sellETH second-deployment: scenario: mainScenario - order: buyETH"#; + order: buyETH"# + .to_string(); let config: ConfigString = yaml_data.try_into().unwrap(); // Asserting a few values to verify successful parsing assert_eq!( config.clone().networks.get("mainnet").unwrap().rpc, - "https://mainnet.node".to_string() + Url::parse("https://mainnet.node").unwrap() ); assert_eq!( config.networks.get("mainnet").unwrap().label, @@ -255,15 +289,12 @@ deployments: ); assert_eq!( config.subgraphs.get("mainnet"), - Some(&"https://mainnet.subgraph".to_string()) + Some(&Url::parse("https://mainnet.subgraph").unwrap()) ); assert_eq!( config.orderbooks.get("mainnetOrderbook").unwrap().address, - "0x123".to_string() - ); - assert_eq!( - config.tokens.get("eth").unwrap().decimals, - Some("18".to_string()) + "0x123".parse::
().unwrap() ); + assert_eq!(config.tokens.get("eth").unwrap().decimals, Some(18)); } } diff --git a/crates/settings/src/token.rs b/crates/settings/src/token.rs index 8d9a6a405..6a56dabbb 100644 --- a/crates/settings/src/token.rs +++ b/crates/settings/src/token.rs @@ -42,18 +42,8 @@ impl TokenString { Ok(Token { network: network_ref, - address: self - .address - .parse() - .map_err(ParseTokenStringError::AddressParseError)?, - decimals: self - .decimals - .map(|decimals| { - decimals - .parse() - .map_err(ParseTokenStringError::DecimalsParseError) - }) - .transpose()?, + address: self.address, + decimals: self.decimals, label: self.label, symbol: self.symbol, }) @@ -78,8 +68,8 @@ mod token_tests { let networks = setup_networks(); let token_string = TokenString { network: "TestNetwork".to_string(), - address: Address::repeat_byte(0x01).to_string(), - decimals: Some("18".to_string()), + address: Address::repeat_byte(0x01), + decimals: Some(18), label: Some("TestToken".to_string()), symbol: Some("TTK".to_string()), }; @@ -104,7 +94,7 @@ mod token_tests { let networks = setup_networks(); let token_string = TokenString { network: "TestNetwork".to_string(), - address: Address::repeat_byte(0x01).to_string(), + address: Address::repeat_byte(0x01), decimals: None, label: None, symbol: None, @@ -130,7 +120,7 @@ mod token_tests { let networks = setup_networks(); let token_string = TokenString { network: "InvalidNetwork".to_string(), - address: "0x1234".to_string(), + address: Address::repeat_byte(0x01), decimals: None, label: None, symbol: None, @@ -144,44 +134,4 @@ mod token_tests { ParseTokenStringError::NetworkNotFoundError("InvalidNetwork".to_string()) ); } - - #[test] - fn test_token_creation_failure_due_to_invalid_address() { - let networks = setup_networks(); - let token_string = TokenString { - network: "TestNetwork".to_string(), - address: "invalid".to_string(), - decimals: None, - label: None, - symbol: None, - }; - - let token = token_string.try_into_token(&networks); - - assert!(token.is_err()); - match token.unwrap_err() { - ParseTokenStringError::AddressParseError(_) => (), - _ => panic!("Expected AddressParseError"), - } - } - - #[test] - fn test_token_creation_failure_due_to_invalid_decimals() { - let networks = setup_networks(); - let token_string = TokenString { - network: "TestNetwork".to_string(), - address: Address::repeat_byte(0x03).to_string(), - decimals: Some("invalid".to_string()), - label: None, - symbol: None, - }; - - let token = token_string.try_into_token(&networks); - - assert!(token.is_err()); - match token.unwrap_err() { - ParseTokenStringError::DecimalsParseError(_) => (), - _ => panic!("Expected DecimalsParseError"), - } - } } diff --git a/typeshare.toml b/typeshare.toml index d685ac4cb..b748fc4a6 100644 --- a/typeshare.toml +++ b/typeshare.toml @@ -5,3 +5,5 @@ "Bytes" = "string" "Uuid" = "string" "DateTime" = "string" +"Address" = "string" +"Url" = "string" \ No newline at end of file From d378597bc0746997e57216745849c2e73c111863 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Wed, 13 Mar 2024 23:07:07 -0700 Subject: [PATCH 26/48] refactor(tauri): parsing settings, selecting network & orderbook working solidly --- tauri-app/src-tauri/src/commands/config.rs | 10 +- tauri-app/src-tauri/src/commands/order.rs | 2 +- tauri-app/src-tauri/src/main.rs | 4 +- .../DropdownActiveChainSettings.svelte | 24 ++-- .../DropdownActiveOrderbookSettings.svelte | 28 ++--- .../src/lib/components/DropdownRadio.svelte | 12 +- tauri-app/src/lib/services/langServices.ts | 28 +++-- tauri-app/src/lib/services/order.ts | 9 +- tauri-app/src/lib/stores/forkBlockNumber.ts | 7 +- tauri-app/src/lib/stores/settings.ts | 104 +++++++++--------- .../lib/storesGeneric/cachedWritableStore.ts | 1 + tauri-app/src/routes/orders/add/+page.svelte | 6 +- 12 files changed, 115 insertions(+), 120 deletions(-) diff --git a/tauri-app/src-tauri/src/commands/config.rs b/tauri-app/src-tauri/src/commands/config.rs index 5b99e3117..75cf242f8 100644 --- a/tauri-app/src-tauri/src/commands/config.rs +++ b/tauri-app/src-tauri/src/commands/config.rs @@ -1,11 +1,7 @@ use crate::error::CommandResult; -use rain_orderbook_app_settings::config::Config; -use rain_orderbook_common::frontmatter::merge_parse_configs as merge_parse_configs_inner; +use rain_orderbook_app_settings::string_structs::ConfigString; #[tauri::command] -pub fn merge_parse_configs(dotrain: String, setting_text: String) -> CommandResult { - Ok(merge_parse_configs_inner( - dotrain.as_str(), - Some(setting_text.as_str()), - )?) +pub fn parse_config(text: String) -> CommandResult { + Ok(text.try_into()?) } diff --git a/tauri-app/src-tauri/src/commands/order.rs b/tauri-app/src-tauri/src/commands/order.rs index adfe3a3e4..c2ba418da 100644 --- a/tauri-app/src-tauri/src/commands/order.rs +++ b/tauri-app/src-tauri/src/commands/order.rs @@ -62,7 +62,7 @@ pub async fn order_detail( #[tauri::command] pub async fn order_add( app_handle: AppHandle, - dotrain: &str, + dotrain: String, deployment: Deployment, transaction_args: TransactionArgs, ) -> CommandResult<()> { diff --git a/tauri-app/src-tauri/src/main.rs b/tauri-app/src-tauri/src/main.rs index 9660f6338..a896388e9 100644 --- a/tauri-app/src-tauri/src/main.rs +++ b/tauri-app/src-tauri/src/main.rs @@ -8,7 +8,7 @@ pub mod transaction_status; mod commands; use commands::chain::{get_block_number, get_chainid}; use commands::charts::make_charts; -use commands::config::merge_parse_configs; +use commands::config::parse_config; use commands::dotrain::parse_dotrain; use commands::dotrain_add_order_lsp::{call_lsp_completion, call_lsp_hover, call_lsp_problems}; use commands::order::{order_add, order_detail, order_remove, orders_list, orders_list_write_csv}; @@ -55,7 +55,7 @@ fn run_tauri_app() { call_lsp_completion, call_lsp_hover, call_lsp_problems, - merge_parse_configs, + parse_config, make_charts ]) .run(tauri::generate_context!()) diff --git a/tauri-app/src/lib/components/DropdownActiveChainSettings.svelte b/tauri-app/src/lib/components/DropdownActiveChainSettings.svelte index 18c4dfc03..dbbf3e96d 100644 --- a/tauri-app/src/lib/components/DropdownActiveChainSettings.svelte +++ b/tauri-app/src/lib/components/DropdownActiveChainSettings.svelte @@ -1,30 +1,24 @@ -{#if $networks === undefined || $networks.length === 0} +{#if $settings?.networks === undefined || Object.keys($settings?.networks).length === 0} {:else} - + - {selected[1].label ? selected[1].label : selected[0]} + {selected ? selected : "Select a network"} - - {#if option[1].label} -
-
{option[1].label}
- {option[1].rpc} -
- {:else} -
- {option[0]} -
- {/if} + +
+
{option.label ? option.label : ref}
+ {option.rpc} +
{/if} diff --git a/tauri-app/src/lib/components/DropdownActiveOrderbookSettings.svelte b/tauri-app/src/lib/components/DropdownActiveOrderbookSettings.svelte index 8d5c2b8a5..0cb18abf1 100644 --- a/tauri-app/src/lib/components/DropdownActiveOrderbookSettings.svelte +++ b/tauri-app/src/lib/components/DropdownActiveOrderbookSettings.svelte @@ -1,30 +1,24 @@ -{#if $orderbooks === undefined || $orderbooks.length === 0} +{#if $activeNetworkOrderbooks === undefined || Object.keys($activeNetworkOrderbooks).length === 0} {:else} - - - {selected[1].label ? selected[1].label : selected[0]} - + + + {selected ? selected : "Select an orderbook"} + - - {#if option[1].label} -
-
{option[1].label}
- {option[1].address} -
- {:else} -
- {option[0]} -
- {/if} + +
+
{option.label ? option.label : ref}
+ {option.address} +
{/if} \ No newline at end of file diff --git a/tauri-app/src/lib/components/DropdownRadio.svelte b/tauri-app/src/lib/components/DropdownRadio.svelte index 291c82ea5..81fbcd9b1 100644 --- a/tauri-app/src/lib/components/DropdownRadio.svelte +++ b/tauri-app/src/lib/components/DropdownRadio.svelte @@ -3,23 +3,23 @@ import { ChevronDownSolid } from 'flowbite-svelte-icons'; // eslint-disable-next-line no-undef - export let options: Array = []; - export let value: number = 0; + export let options: Record = {}; + export let value: string | undefined = undefined; let open = false; $: value, open = false; - {#each options as option, index} - + {#each Object.entries(options) as [ref, option]} +
- +
{/each} diff --git a/tauri-app/src/lib/services/langServices.ts b/tauri-app/src/lib/services/langServices.ts index 8a54a4c26..6cd90c4cb 100644 --- a/tauri-app/src/lib/services/langServices.ts +++ b/tauri-app/src/lib/services/langServices.ts @@ -3,16 +3,20 @@ import { ErrorCode, type Problem, TextDocumentItem, Position, Hover, CompletionI import { rpcUrl } from '$lib/stores/settings'; import { get } from 'svelte/store'; import { forkBlockNumber } from '$lib/stores/forkBlockNumber'; -import { deployments, activeDeploymentIndex } from '$lib/stores/settings'; +import { settings, activeDeployment } from '$lib/stores/settings'; /** * Provides problems callback by invoking related tauri command */ export async function problemsCallback(textDocument: TextDocumentItem): Promise { try { - const deployment = get(deployments)?.[get(activeDeploymentIndex)]?.[1]; - const bindings = deployment !== undefined ? deployment.scenario.bindings : {}; - const deployer = deployment !== undefined ? deployment.scenario.deployer.address : undefined; + const deployment = get(activeDeployment); + if(!deployment) throw Error("Deployment not selected"); + + const scenario = get(settings).scenarios?.[deployment.scenario]; + const bindings = scenario?.bindings ? scenario.bindings : {}; + const deployer = scenario?.deployer ? get(settings).deployers?.[scenario.deployer] : undefined; + return await invoke('call_lsp_problems', { textDocument, rpcUrl: get(rpcUrl), blockNumber: get(forkBlockNumber).value, bindings, deployer}); } catch (err) { @@ -28,8 +32,12 @@ export async function problemsCallback(textDocument: TextDocumentItem): Promise< * Provides hover callback by invoking related tauri command */ export async function hoverCallback(textDocument: TextDocumentItem, position: Position): Promise { - const deployment = get(deployments)?.[get(activeDeploymentIndex)]?.[1]; - const bindings = deployment !== undefined ? deployment.scenario.bindings : {}; + const deployment = get(activeDeployment); + if(!deployment) throw Error("Deployment not selected"); + + const scenario = get(settings).scenarios?.[deployment.scenario]; + const bindings = scenario?.bindings ? scenario.bindings : {}; + return await invoke('call_lsp_hover', { textDocument, position, bindings }); } @@ -37,7 +45,11 @@ export async function hoverCallback(textDocument: TextDocumentItem, position: Po * Provides completion callback by invoking related tauri command */ export async function completionCallback(textDocument: TextDocumentItem, position: Position): Promise { - const deployment = get(deployments)?.[get(activeDeploymentIndex)]?.[1]; - const bindings = deployment !== undefined ? deployment.scenario.bindings : {}; + const deployment = get(activeDeployment); + if(!deployment) throw Error("Deployment not selected"); + + const scenario = get(settings).scenarios?.[deployment.scenario]; + const bindings = scenario?.bindings ? scenario.bindings : {}; + return await invoke('call_lsp_completion', { textDocument, position, bindings }); } \ No newline at end of file diff --git a/tauri-app/src/lib/services/order.ts b/tauri-app/src/lib/services/order.ts index 6d4132988..9f7ed8e78 100644 --- a/tauri-app/src/lib/services/order.ts +++ b/tauri-app/src/lib/services/order.ts @@ -2,13 +2,12 @@ import { get } from 'svelte/store'; import { invoke } from '@tauri-apps/api'; import { rpcUrl, orderbookAddress,chainId, subgraphUrl } from '$lib/stores/settings'; import { walletDerivationIndex } from '$lib/stores/wallets'; -import { deployments, activeDeploymentIndex } from '$lib/stores/settings'; +import { activeDeployment } from '$lib/stores/settings'; export async function orderAdd(dotrain: string) { - const deployment = get(deployments)?.[get(activeDeploymentIndex)]?.[1] - if (deployment === undefined) { - return Promise.reject("undefined deployment!"); - } + const deployment = get(activeDeployment); + if (deployment === undefined) throw Error("undefined deployment!"); + await invoke("order_add", { dotrain, deployment, diff --git a/tauri-app/src/lib/stores/forkBlockNumber.ts b/tauri-app/src/lib/stores/forkBlockNumber.ts index 73e0e395c..6992613ed 100644 --- a/tauri-app/src/lib/stores/forkBlockNumber.ts +++ b/tauri-app/src/lib/stores/forkBlockNumber.ts @@ -3,7 +3,12 @@ import { fetchableIntStore } from "$lib/storesGeneric/fetchableStore"; import { get } from "svelte/store"; import { rpcUrl } from "./settings"; -export const forkBlockNumber = fetchableIntStore("forkBlockNumber", async () => await getBlockNumberFromRpc(get(rpcUrl))); +export const forkBlockNumber = fetchableIntStore("forkBlockNumber", async () => { + const $rpcUrl = get(rpcUrl); + if(!$rpcUrl) return 0; + + return getBlockNumberFromRpc($rpcUrl); +}); // When active chain updated, reset active orderbook rpcUrl.subscribe(async () => { diff --git a/tauri-app/src/lib/stores/settings.ts b/tauri-app/src/lib/stores/settings.ts index 45ed764f4..378949887 100644 --- a/tauri-app/src/lib/stores/settings.ts +++ b/tauri-app/src/lib/stores/settings.ts @@ -1,12 +1,13 @@ import { asyncDerived, derived, get } from '@square/svelte-store'; -import { cachedWritableInt, cachedWritableStore } from '$lib/storesGeneric/cachedWritableStore'; +import { cachedWritableStore, cachedWritableStringOptional } from '$lib/storesGeneric/cachedWritableStore'; import find from 'lodash/find'; import * as chains from 'viem/chains'; import { textFileStore } from '$lib/storesGeneric/textFileStore'; import { invoke } from '@tauri-apps/api'; -import { type Config } from '$lib/typeshare/config'; +import { type ConfigString, type OrderbookRef, type OrderbookString } from '$lib/typeshare/configString'; import { getBlockNumberFromRpc } from '$lib/services/chain'; import { toasts } from './toasts'; +import { pickBy } from 'lodash'; const emptyConfig = { deployments: {}, @@ -18,7 +19,7 @@ const emptyConfig = { deployers: {}, scenarios: {}, charts: {} -}; +} as ConfigString; // dotrain text store export const dotrainFile = textFileStore('Rain', ['rain']); @@ -26,10 +27,9 @@ export const dotrainFile = textFileStore('Rain', ['rain']); // general export const settingsText = cachedWritableStore('settings', "", (s) => s, (s) => s); export const settingsFile = textFileStore('Orderbook Settings Yaml', ['yml', 'yaml'], get(settingsText)); -export const settings = asyncDerived([settingsText, dotrainFile], async ([$settingsText, $dotrainFile]): Promise => { - const text = $dotrainFile?.text !== undefined ? $dotrainFile.text : ""; +export const settings = asyncDerived([settingsText, dotrainFile], async ([$settingsText]): Promise => { try { - const config: Config = await invoke("merge_parse_configs", {dotrain: text, settingText: $settingsText}); + const config: ConfigString = await invoke("parse_config", {text: $settingsText}); return config; } catch(e) { toasts.error(e as string); @@ -38,63 +38,57 @@ export const settings = asyncDerived([settingsText, dotrainFile], async ([$setti }, { initial: emptyConfig }); // networks -export const networks = derived(settings, ($settingsData) => Object.entries($settingsData?.networks)); -export const activeNetworkIndex = cachedWritableInt("settings.activeNetworkIndex", 0); -export const activeNetwork = derived([networks, activeNetworkIndex], ([$networks, $activeNetworkIndex]) => $networks?.[$activeNetworkIndex]); -export const rpcUrl = derived(activeNetwork, ($activeNetwork) => $activeNetwork?.[1].rpc); -export const chainId = derived(activeNetwork, ($activeNetwork) => $activeNetwork?.[1].chain_id); +export const activeNetworkRef = cachedWritableStringOptional("settings.activeNetworkRef"); +export const activeNetwork = asyncDerived([settings, activeNetworkRef], async ([$settings, $activeNetworkRef]) => { + await settings.load(); + console.log('settings is ', $settings); + return ($activeNetworkRef !== undefined && $settings.networks !== undefined) ? $settings.networks[$activeNetworkRef] : undefined; +}); +export const rpcUrl = derived(activeNetwork, ($activeNetwork) => $activeNetwork?.rpc); +export const chainId = derived(activeNetwork, ($activeNetwork) => $activeNetwork?.['chain-id']); export const activeChain = derived(chainId, ($activeChainId) => find(Object.values(chains), (c) => c.id === $activeChainId)); export const activeChainHasBlockExplorer = derived(activeChain, ($activeChain) => { return $activeChain && $activeChain?.blockExplorers?.default !== undefined; }); -export const activeChainLatestBlockNumber = derived(activeNetwork, ($activeNetwork) => getBlockNumberFromRpc($activeNetwork?.[1].rpc)); +export const activeChainLatestBlockNumber = derived(activeNetwork, ($activeNetwork) => $activeNetwork !== undefined ? getBlockNumberFromRpc($activeNetwork.rpc) : 0); // orderbook -export const orderbooks = derived([settings, activeNetwork], ([$settingsData, $activeNetwork]) => Object.entries($settingsData.orderbooks).filter(v => - // filter orderbooks based on active netowkr - v[1].network.rpc === $activeNetwork?.[1].rpc - && v[1].network.chain_id === $activeNetwork?.[1].chain_id - && v[1].network.label === $activeNetwork?.[1].label - && v[1].network.network_id === $activeNetwork?.[1].network_id - && v[1].network.currency === $activeNetwork?.[1].currency -)); -export const activeOrderbookIndex = cachedWritableInt("settings.activeOrderbookIndex", 0); -export const activeOrderbook = derived([orderbooks, activeOrderbookIndex], ([$orderbooks, $activeOrderbookIndex]) => $orderbooks?.[$activeOrderbookIndex]); -export const subgraphUrl = derived(activeOrderbook, ($activeOrderbookSettings) => $activeOrderbookSettings?.[1].subgraph); -export const orderbookAddress = derived(activeOrderbook, ($activeOrderbookSettings) => $activeOrderbookSettings?.[1].address); +export const activeOrderbookRef = cachedWritableStringOptional("settings.activeOrderbookRef"); +export const activeNetworkOrderbooks = derived([settings, activeNetworkRef], ([$settings, $activeNetworkRef]) => $settings?.orderbooks ? pickBy($settings.orderbooks, (orderbook) => orderbook.network === $activeNetworkRef) as Record : {} as Record); +export const activeOrderbook = derived([settings, activeOrderbookRef], ([$settings, $activeOrderbookRef]) => ($settings?.orderbooks !== undefined && $activeOrderbookRef !== undefined) ? $settings.orderbooks[$activeOrderbookRef] : undefined); +export const subgraphUrl = derived(activeOrderbook, ($activeOrderbook) => $activeOrderbook?.subgraph); +export const orderbookAddress = derived(activeOrderbook, ($activeOrderbook) => $activeOrderbook?.address); -export const hasRequiredSettings = derived([activeNetwork, activeOrderbook], ([$activeChainSettings, $activeOrderbookSettings]) => $activeChainSettings !== undefined && $activeOrderbookSettings !== undefined); +export const hasRequiredSettings = derived([activeNetworkRef, activeOrderbookRef], ([$activeNetworkRef, $activeOrderbookRef]) => $activeNetworkRef !== undefined && $activeOrderbookRef !== undefined); // deployments -export const deployments = derived([settings, activeNetwork, activeOrderbook], ([$settingsData, $activeNetwork, $activeOrderbook]) => Object.entries($settingsData.deployments).filter(v => { - return v[1].order.network.rpc === $activeNetwork?.[1].rpc - && v[1].order.network.chain_id === $activeNetwork?.[1].chain_id - && v[1].order.network.label === $activeNetwork?.[1].label - && v[1].order.network.network_id === $activeNetwork?.[1].network_id - && v[1].order.network.currency === $activeNetwork?.[1].currency - && ( - v[1].order.orderbook !== undefined - ? ( - v[1].order.orderbook.address === $activeOrderbook?.[1].address - && v[1].order.orderbook.subgraph === $activeOrderbook?.[1].subgraph - && v[1].order.orderbook.label === $activeOrderbook?.[1].label - ) - : true - ) -}) -); -export const activeDeploymentIndex = cachedWritableInt("settings.activeDeploymentIndex", 0); -export const activeDeployment = derived([deployments, activeDeploymentIndex], ([$deployments, $activeDeploymentIndex]) => $deployments?.[$activeDeploymentIndex]); +export const deployments = derived([settings, activeNetworkRef, activeOrderbookRef], ([$settings, $activeNetworkRef, $activeOrderbookRef]) => pickBy($settings.deployments, (v) => $settings.orders?.[v.order].network === $activeNetworkRef && $settings.orders?.[v.order].orderbook === $activeOrderbookRef)); +export const activeDeploymentRef = cachedWritableStringOptional("settings.activeDeploymentRef"); +export const activeDeployment = derived([deployments, activeDeploymentRef], ([$deployments, $activeDeploymentRef]) => ($activeDeploymentRef !== undefined && $deployments !== undefined) ? $deployments[$activeDeploymentRef] : undefined); -// // When networks data updated, reset active chain -// networks.subscribe((val) => { -// if(val && val.length < get(activeNetworkIndex)) { -// activeNetworkIndex.set(0); -// } -// }); +// When networks data updated, reset active chain +settings.subscribe(async ($settings) => { + await settings.load(); + const $activeNetworkRef = get(activeNetworkRef); + if($activeNetworkRef === undefined) return; -// // When active network updated, reset active orderbook and deployment -// activeNetwork.subscribe(async () => { -// activeOrderbookIndex.set(0); -// activeDeploymentIndex.set(0); -// }); \ No newline at end of file + if(!$settings.networks || !Object.keys($settings.networks).includes($activeNetworkRef)) { + activeNetworkRef.set(undefined); + } +}); + +// When active network is updated to undefined, reset active orderbook +activeNetworkRef.subscribe(($activeNetworkRef) => { + if($activeNetworkRef === undefined) { + activeOrderbookRef.set(undefined); + } +}); + +// When active network is updated to not include active orderbook, reset active orderbook +activeNetworkOrderbooks.subscribe(async ($activeNetworkOrderbooks) => { + const $activeOrderbookRef = get(activeOrderbookRef); + + if($activeOrderbookRef !== undefined && !Object.keys($activeNetworkOrderbooks).includes($activeOrderbookRef)) { + activeOrderbookRef.set(undefined); + } +}); \ No newline at end of file diff --git a/tauri-app/src/lib/storesGeneric/cachedWritableStore.ts b/tauri-app/src/lib/storesGeneric/cachedWritableStore.ts index 9ec1ed716..c07582ecc 100644 --- a/tauri-app/src/lib/storesGeneric/cachedWritableStore.ts +++ b/tauri-app/src/lib/storesGeneric/cachedWritableStore.ts @@ -39,3 +39,4 @@ export const cachedWritableOptionalStore = ( ) => cachedWritableStore(key, defaultValue, (v) => v ? serialize(v) : '', (v) => v ? deserialize(v) : undefined); export const cachedWritableIntOptional = (key: string, defaultValue = undefined) => cachedWritableOptionalStore(key, defaultValue, (v) => v.toString(), (v) => parseInt(v)); +export const cachedWritableStringOptional = (key: string, defaultValue = undefined) => cachedWritableOptionalStore(key, defaultValue, (v) => v, (v) => v); diff --git a/tauri-app/src/routes/orders/add/+page.svelte b/tauri-app/src/routes/orders/add/+page.svelte index 6db8c4b07..92b362c3e 100644 --- a/tauri-app/src/routes/orders/add/+page.svelte +++ b/tauri-app/src/routes/orders/add/+page.svelte @@ -10,7 +10,7 @@ import { forkBlockNumber } from '$lib/stores/forkBlockNumber'; import DropdownRadio from '$lib/components/DropdownRadio.svelte'; import SkeletonRow from '$lib/components/SkeletonRow.svelte'; - import { deployments, activeDeploymentIndex, dotrainFile } from '$lib/stores/settings'; + import { deployments, activeDeploymentRef, dotrainFile } from '$lib/stores/settings'; import { RawRainlangExtension, type RawLanguageServicesCallbacks } from 'codemirror-rainlang'; import { completionCallback, hoverCallback, problemsCallback } from '$lib/services/langServices'; import { makeChartData } from '$lib/services/chart'; @@ -70,10 +70,10 @@ - {#if $deployments === undefined || $deployments.length === 0} + {#if $deployments === undefined || Object.keys($deployments).length === 0} {:else} - v[0]) || []} bind:value={$activeDeploymentIndex}> + {selected} From 62fd27b915174e63074fd169eab2d5410e23419c Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Wed, 13 Mar 2024 23:07:45 -0700 Subject: [PATCH 27/48] revert: only gitignore *intended* typeshare dir -- not other typeshare dirs accidentally created --- tauri-app/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tauri-app/.gitignore b/tauri-app/.gitignore index c1b5e4282..1d1a44d54 100644 --- a/tauri-app/.gitignore +++ b/tauri-app/.gitignore @@ -8,7 +8,7 @@ node_modules !.env.example vite.config.js.timestamp-* vite.config.ts.timestamp-* -typeshare +src/lib/typeshare # for shared libs /lib \ No newline at end of file From b1e66dea8fea6238a50072bd00576713baa99120 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Wed, 13 Mar 2024 23:18:09 -0700 Subject: [PATCH 28/48] feat(tauri/ui): label dropdown with label or ref string --- .../lib/components/DropdownActiveChainSettings.svelte | 10 ++++++++-- .../components/DropdownActiveOrderbookSettings.svelte | 10 ++++++++-- tauri-app/src/lib/components/DropdownRadio.svelte | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/tauri-app/src/lib/components/DropdownActiveChainSettings.svelte b/tauri-app/src/lib/components/DropdownActiveChainSettings.svelte index dbbf3e96d..3a6c58625 100644 --- a/tauri-app/src/lib/components/DropdownActiveChainSettings.svelte +++ b/tauri-app/src/lib/components/DropdownActiveChainSettings.svelte @@ -10,8 +10,14 @@ {:else} - - {selected ? selected : "Select a network"} + + {#if selectedRef === undefined} + Select a network + {:else if selectedOption?.label} + {selectedOption.label} + {:else} + {selectedRef} + {/if} diff --git a/tauri-app/src/lib/components/DropdownActiveOrderbookSettings.svelte b/tauri-app/src/lib/components/DropdownActiveOrderbookSettings.svelte index 0cb18abf1..2611cd9ef 100644 --- a/tauri-app/src/lib/components/DropdownActiveOrderbookSettings.svelte +++ b/tauri-app/src/lib/components/DropdownActiveOrderbookSettings.svelte @@ -10,8 +10,14 @@ {:else} - - {selected ? selected : "Select an orderbook"} + + {#if selectedRef === undefined} + Select an orderbook + {:else if selectedOption?.label} + {selectedOption.label} + {:else} + {selectedRef} + {/if} diff --git a/tauri-app/src/lib/components/DropdownRadio.svelte b/tauri-app/src/lib/components/DropdownRadio.svelte index 81fbcd9b1..aac0de16b 100644 --- a/tauri-app/src/lib/components/DropdownRadio.svelte +++ b/tauri-app/src/lib/components/DropdownRadio.svelte @@ -11,7 +11,7 @@ From 3371b118b3757557cd35716adf381668f1e41420 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Wed, 13 Mar 2024 23:25:21 -0700 Subject: [PATCH 29/48] chore(tauri/ui): rename components for clarity --- ...eChainSettings.svelte => DropdownActiveNetwork.svelte} | 0 ...bookSettings.svelte => DropdownActiveOrderbook.svelte} | 0 tauri-app/src/lib/components/Sidebar.svelte | 8 ++++---- 3 files changed, 4 insertions(+), 4 deletions(-) rename tauri-app/src/lib/components/{DropdownActiveChainSettings.svelte => DropdownActiveNetwork.svelte} (100%) rename tauri-app/src/lib/components/{DropdownActiveOrderbookSettings.svelte => DropdownActiveOrderbook.svelte} (100%) diff --git a/tauri-app/src/lib/components/DropdownActiveChainSettings.svelte b/tauri-app/src/lib/components/DropdownActiveNetwork.svelte similarity index 100% rename from tauri-app/src/lib/components/DropdownActiveChainSettings.svelte rename to tauri-app/src/lib/components/DropdownActiveNetwork.svelte diff --git a/tauri-app/src/lib/components/DropdownActiveOrderbookSettings.svelte b/tauri-app/src/lib/components/DropdownActiveOrderbook.svelte similarity index 100% rename from tauri-app/src/lib/components/DropdownActiveOrderbookSettings.svelte rename to tauri-app/src/lib/components/DropdownActiveOrderbook.svelte diff --git a/tauri-app/src/lib/components/Sidebar.svelte b/tauri-app/src/lib/components/Sidebar.svelte index d0bfc0cde..5eb74d750 100644 --- a/tauri-app/src/lib/components/Sidebar.svelte +++ b/tauri-app/src/lib/components/Sidebar.svelte @@ -12,8 +12,8 @@ import IconExternalLink from '$lib/components/IconExternalLink.svelte'; import { page } from '$app/stores'; import ButtonDarkMode from '$lib/components/ButtonDarkMode.svelte'; - import DropdownActiveChainSettings from '$lib/components/DropdownActiveChainSettings.svelte'; - import DropdownActiveOrderbookSettings from '$lib/components/DropdownActiveOrderbookSettings.svelte'; + import DropdownActiveNetwork from '$lib/components/DropdownActiveNetwork.svelte'; + import DropdownActiveOrderbook from '$lib/components/DropdownActiveOrderbook.svelte'; export let hasRequiredSettings = false; @@ -49,8 +49,8 @@ - - + + From f255ed0ab4945425f23b14f2798f2677023be35e Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Wed, 13 Mar 2024 23:45:04 -0700 Subject: [PATCH 30/48] fix(tauri/ui): when switching networks, reset orderbook to first available --- tauri-app/src/lib/stores/settings.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/tauri-app/src/lib/stores/settings.ts b/tauri-app/src/lib/stores/settings.ts index 378949887..0e5559653 100644 --- a/tauri-app/src/lib/stores/settings.ts +++ b/tauri-app/src/lib/stores/settings.ts @@ -41,7 +41,6 @@ export const settings = asyncDerived([settingsText, dotrainFile], async ([$setti export const activeNetworkRef = cachedWritableStringOptional("settings.activeNetworkRef"); export const activeNetwork = asyncDerived([settings, activeNetworkRef], async ([$settings, $activeNetworkRef]) => { await settings.load(); - console.log('settings is ', $settings); return ($activeNetworkRef !== undefined && $settings.networks !== undefined) ? $settings.networks[$activeNetworkRef] : undefined; }); export const rpcUrl = derived(activeNetwork, ($activeNetwork) => $activeNetwork?.rpc); @@ -73,14 +72,14 @@ settings.subscribe(async ($settings) => { if($activeNetworkRef === undefined) return; if(!$settings.networks || !Object.keys($settings.networks).includes($activeNetworkRef)) { - activeNetworkRef.set(undefined); + resetActiveOrderbookRef(); } }); // When active network is updated to undefined, reset active orderbook activeNetworkRef.subscribe(($activeNetworkRef) => { if($activeNetworkRef === undefined) { - activeOrderbookRef.set(undefined); + resetActiveOrderbookRef(); } }); @@ -89,6 +88,18 @@ activeNetworkOrderbooks.subscribe(async ($activeNetworkOrderbooks) => { const $activeOrderbookRef = get(activeOrderbookRef); if($activeOrderbookRef !== undefined && !Object.keys($activeNetworkOrderbooks).includes($activeOrderbookRef)) { + resetActiveOrderbookRef(); + } +}); + +// reset active orderbook to first available, otherwise undefined +function resetActiveOrderbookRef() { + const $activeNetworkOrderbooks = get(activeNetworkOrderbooks); + const $activeNetworkOrderbookRefs = Object.keys($activeNetworkOrderbooks); + + if($activeNetworkOrderbookRefs.length > 0) { + activeOrderbookRef.set($activeNetworkOrderbookRefs[0]); + } else { activeOrderbookRef.set(undefined); } -}); \ No newline at end of file +} \ No newline at end of file From 4326e267502f1eb1986da76f2e0f22cef5d5cd1d Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Thu, 14 Mar 2024 00:01:12 -0700 Subject: [PATCH 31/48] fix(tauri/ui): when settings updated, reset active orderbook & active network if not already set --- tauri-app/src/lib/stores/settings.ts | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/tauri-app/src/lib/stores/settings.ts b/tauri-app/src/lib/stores/settings.ts index 0e5559653..4368386ba 100644 --- a/tauri-app/src/lib/stores/settings.ts +++ b/tauri-app/src/lib/stores/settings.ts @@ -65,13 +65,17 @@ export const deployments = derived([settings, activeNetworkRef, activeOrderbookR export const activeDeploymentRef = cachedWritableStringOptional("settings.activeDeploymentRef"); export const activeDeployment = derived([deployments, activeDeploymentRef], ([$deployments, $activeDeploymentRef]) => ($activeDeploymentRef !== undefined && $deployments !== undefined) ? $deployments[$activeDeploymentRef] : undefined); -// When networks data updated, reset active chain +// When networks / orderbooks settings updated, reset active network / orderbooks settings.subscribe(async ($settings) => { await settings.load(); const $activeNetworkRef = get(activeNetworkRef); - if($activeNetworkRef === undefined) return; + const $activeOrderbookRef = get(activeOrderbookRef); + + if(!$settings.networks || $activeNetworkRef === undefined || !Object.keys($settings.networks).includes($activeNetworkRef)) { + resetActiveNetworkRef(); + } - if(!$settings.networks || !Object.keys($settings.networks).includes($activeNetworkRef)) { + if(!$settings.orderbooks || $activeOrderbookRef === undefined || !Object.keys($settings.orderbooks).includes($activeOrderbookRef)) { resetActiveOrderbookRef(); } }); @@ -102,4 +106,16 @@ function resetActiveOrderbookRef() { } else { activeOrderbookRef.set(undefined); } +} + + +// reset active orderbook to first available, otherwise undefined +function resetActiveNetworkRef() { + const $networks = get(settings).networks; + + if($networks !== undefined && Object.keys($networks).length > 0) { + activeNetworkRef.set(Object.keys($networks)[0]); + } else { + activeNetworkRef.set(undefined); + } } \ No newline at end of file From 32aa0179e9328a3bcbcb85889562db46b08edc60 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Thu, 14 Mar 2024 00:01:56 -0700 Subject: [PATCH 32/48] chore(tauri/ui): label 'chain' -> 'network' --- tauri-app/src/lib/components/DropdownActiveNetwork.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tauri-app/src/lib/components/DropdownActiveNetwork.svelte b/tauri-app/src/lib/components/DropdownActiveNetwork.svelte index 3a6c58625..05ea508dc 100644 --- a/tauri-app/src/lib/components/DropdownActiveNetwork.svelte +++ b/tauri-app/src/lib/components/DropdownActiveNetwork.svelte @@ -5,7 +5,7 @@ import SkeletonRow from '$lib/components/SkeletonRow.svelte'; - + {#if $settings?.networks === undefined || Object.keys($settings?.networks).length === 0} {:else} From f07f7108973de9d36dc63178a3eb0bbdf76c3326 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Thu, 14 Mar 2024 04:01:40 -0700 Subject: [PATCH 33/48] revert(tauri/ui): eslint no console --- tauri-app/.eslintrc.cjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tauri-app/.eslintrc.cjs b/tauri-app/.eslintrc.cjs index dd5816746..b805d8ba8 100644 --- a/tauri-app/.eslintrc.cjs +++ b/tauri-app/.eslintrc.cjs @@ -29,7 +29,7 @@ module.exports = { } ], rules: { - // 'no-console': 'error', + 'no-console': 'error', 'no-trailing-spaces': 'error' } }; From d0c20822e71ae560564484662b6ef28227ba9bc0 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Thu, 14 Mar 2024 04:03:59 -0700 Subject: [PATCH 34/48] refactor(tauri/ui): move dotrain file store to add order component, simplify parsing config, select deployer working --- crates/cli/src/commands/order/add.rs | 23 ++-- crates/common/src/add_order.rs | 11 +- crates/common/src/frontmatter.rs | 34 +----- tauri-app/src-tauri/src/commands/charts.rs | 16 +-- tauri-app/src-tauri/src/commands/config.rs | 18 ++- tauri-app/src-tauri/src/error.rs | 8 +- tauri-app/src-tauri/src/main.rs | 6 +- .../src/lib/components/DropdownRadio.svelte | 2 +- .../src/lib/components/FileTextarea.svelte | 4 +- .../src/lib/components/SkeletonRow.svelte | 2 +- tauri-app/src/lib/services/chart.ts | 7 +- tauri-app/src/lib/services/config.ts | 9 ++ tauri-app/src/lib/services/langServices.ts | 34 ++---- tauri-app/src/lib/services/order.ts | 7 +- tauri-app/src/lib/stores/settings.ts | 16 +-- tauri-app/src/routes/+layout.svelte | 3 +- tauri-app/src/routes/orders/add/+page.svelte | 107 ++++++++++++------ 17 files changed, 142 insertions(+), 165 deletions(-) create mode 100644 tauri-app/src/lib/services/config.ts diff --git a/crates/cli/src/commands/order/add.rs b/crates/cli/src/commands/order/add.rs index b52d32b31..dd0285260 100644 --- a/crates/cli/src/commands/order/add.rs +++ b/crates/cli/src/commands/order/add.rs @@ -3,8 +3,9 @@ use crate::{ }; use anyhow::{anyhow, Result}; use clap::Args; +use rain_orderbook_app_settings::Config; use rain_orderbook_common::add_order::AddOrderArgs; -use rain_orderbook_common::frontmatter::merge_parse_configs; +use rain_orderbook_common::frontmatter::parse_frontmatter; use rain_orderbook_common::transaction::TransactionArgs; use std::fs::read_to_string; use std::ops::Deref; @@ -30,16 +31,16 @@ pub struct CliOrderAddArgs { impl CliOrderAddArgs { async fn to_add_order_args(&self) -> Result { let text = read_to_string(&self.dotrain_file).map_err(|e| anyhow!(e))?; - let config = merge_parse_configs(text.clone(), None)?; - if let Some(config_deployment) = config.deployments.get(&self.deployment) { - Ok(AddOrderArgs::new_from_deployment( - text.clone(), - config_deployment.deref().to_owned(), - ) - .await?) - } else { - Err(anyhow!("specified deployment is undefined!")) - } + let config: Config = parse_frontmatter(text.clone())?.try_into()?; + let config_deployment = config + .deployments + .get(&self.deployment) + .ok_or(anyhow!("specified deployment is undefined!"))?; + + Ok( + AddOrderArgs::new_from_deployment(text.clone(), config_deployment.deref().clone()) + .await?, + ) } } diff --git a/crates/common/src/add_order.rs b/crates/common/src/add_order.rs index 280986a94..3a9797951 100644 --- a/crates/common/src/add_order.rs +++ b/crates/common/src/add_order.rs @@ -1,6 +1,5 @@ use crate::{ dotrain_add_order_lsp::LANG_SERVICES, - frontmatter::{merge_parse_configs, FrontmatterError}, transaction::{TransactionArgs, TransactionArgsError}, }; use alloy_ethers_typecast::transaction::{ @@ -15,7 +14,7 @@ use rain_metadata::{ ContentEncoding, ContentLanguage, ContentType, Error as RainMetaError, KnownMagic, RainMetaDocumentV1Item, }; -use rain_orderbook_app_settings::{config::Config, deployment::Deployment}; +use rain_orderbook_app_settings::deployment::Deployment; use rain_orderbook_bindings::{ IOrderBookV3::{addOrderCall, EvaluableConfigV3, OrderConfigV2, IO}, ERC20::decimalsCall, @@ -123,14 +122,6 @@ impl AddOrderArgs { }) } - /// returns the frontmatter config merged with top config - pub fn merge_parse_configs( - &self, - top_config: Option, - ) -> Result { - merge_parse_configs(self.dotrain.clone(), top_config) - } - /// Read parser address from deployer contract, then call parser to parse rainlang into bytecode and constants async fn try_parse_rainlang( &self, diff --git a/crates/common/src/frontmatter.rs b/crates/common/src/frontmatter.rs index 1545dcddb..2be2a3c21 100644 --- a/crates/common/src/frontmatter.rs +++ b/crates/common/src/frontmatter.rs @@ -1,36 +1,8 @@ use dotrain::RainDocument; -use rain_orderbook_app_settings::{ - config::{Config, ParseConfigStringError}, - merge::MergeError, - string_structs::ConfigString, -}; -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum FrontmatterError { - #[error(transparent)] - ParseConfigError(#[from] ParseConfigStringError), - #[error(transparent)] - MergeError(#[from] MergeError), -} +use rain_orderbook_app_settings::{config::ParseConfigStringError, string_structs::ConfigString}; /// Parse dotrain frontmatter and merges it with top Config if given -pub fn merge_parse_configs( - dotrain: String, - top_config: Option, -) -> Result { +pub fn parse_frontmatter(dotrain: String) -> Result { let frontmatter = RainDocument::get_front_matter(dotrain.as_str()).unwrap_or(""); - let mut frontmatter_str_config: ConfigString = frontmatter - .to_string() - .try_into() - .map_err(ParseConfigStringError::YamlDeserializerError)?; - if let Some(v) = top_config { - let top_str_config: ConfigString = v - .try_into() - .map_err(ParseConfigStringError::YamlDeserializerError)?; - frontmatter_str_config.merge(top_str_config)?; - Ok(frontmatter_str_config.try_into()?) - } else { - Ok(frontmatter_str_config.try_into()?) - } + Ok(frontmatter.to_string().try_into()?) } diff --git a/tauri-app/src-tauri/src/commands/charts.rs b/tauri-app/src-tauri/src/commands/charts.rs index 6ea4a3478..70935680a 100644 --- a/tauri-app/src-tauri/src/commands/charts.rs +++ b/tauri-app/src-tauri/src/commands/charts.rs @@ -1,21 +1,13 @@ use crate::error::CommandResult; +use crate::commands::config::merge_configstrings; use rain_orderbook_common::fuzz::*; -use rain_orderbook_app_settings::string_structs::*; use rain_orderbook_app_settings::config::*; -use dotrain::RainDocument; #[tauri::command] -pub async fn make_charts(dotrain: &str, settings: Option<&str>) -> CommandResult> { - let frontmatter = RainDocument::get_front_matter(dotrain).unwrap(); - let mut config = serde_yaml::from_str::(frontmatter)?; - let settings = settings.map(|s| serde_yaml::from_str::(s)); - match settings { - Some(Ok(s)) => config.merge(s)?, - _ => (), - }; - +pub async fn make_charts(dotrain: String, settings: String) -> CommandResult> { + let config = merge_configstrings(dotrain.clone(), settings)?; let final_config: Config = config.try_into()?; - let mut fuzzer = FuzzRunner::new(dotrain, final_config, None).await; + let mut fuzzer = FuzzRunner::new(dotrain.as_str(), final_config, None).await; let chart_data = fuzzer.build_chart_datas().await?; Ok(chart_data) diff --git a/tauri-app/src-tauri/src/commands/config.rs b/tauri-app/src-tauri/src/commands/config.rs index 75cf242f8..7aed666ab 100644 --- a/tauri-app/src-tauri/src/commands/config.rs +++ b/tauri-app/src-tauri/src/commands/config.rs @@ -1,7 +1,21 @@ use crate::error::CommandResult; -use rain_orderbook_app_settings::string_structs::ConfigString; +use rain_orderbook_app_settings::{config::Config, string_structs::ConfigString}; +use rain_orderbook_common::frontmatter::parse_frontmatter; #[tauri::command] -pub fn parse_config(text: String) -> CommandResult { +pub fn parse_configstring(text: String) -> CommandResult { Ok(text.try_into()?) } + +#[tauri::command] +pub fn merge_configstrings(dotrain: String, config_text: String) -> CommandResult { + let mut dotrain_config = parse_frontmatter(dotrain)?; + let config: ConfigString = config_text.try_into()?; + dotrain_config.merge(config)?; + Ok(dotrain_config) +} + +#[tauri::command] +pub fn convert_configstring_to_config(config_string: ConfigString) -> CommandResult { + Ok(config_string.try_into()?) +} diff --git a/tauri-app/src-tauri/src/error.rs b/tauri-app/src-tauri/src/error.rs index d31633643..fa20e89fa 100644 --- a/tauri-app/src-tauri/src/error.rs +++ b/tauri-app/src-tauri/src/error.rs @@ -4,9 +4,8 @@ use rain_orderbook_app_settings::config::ParseConfigStringError; use rain_orderbook_app_settings::merge::MergeError; use rain_orderbook_common::fuzz::FuzzRunnerError; use rain_orderbook_common::{ - add_order::AddOrderArgsError, csv::TryIntoCsvError, frontmatter::FrontmatterError, - meta::TryDecodeRainlangSourceError, rainlang::ForkParseError, - utils::timestamp::FormatTimestampDisplayError, + add_order::AddOrderArgsError, csv::TryIntoCsvError, meta::TryDecodeRainlangSourceError, + rainlang::ForkParseError, utils::timestamp::FormatTimestampDisplayError, }; use rain_orderbook_subgraph_client::OrderbookSubgraphClientError; use serde::{ser::Serializer, Serialize}; @@ -48,9 +47,6 @@ pub enum CommandError { #[error(transparent)] TryDecodeRainlangSourceError(#[from] TryDecodeRainlangSourceError), - #[error(transparent)] - FrontmatterError(#[from] FrontmatterError), - #[error(transparent)] FuzzRunnerError(#[from] FuzzRunnerError), diff --git a/tauri-app/src-tauri/src/main.rs b/tauri-app/src-tauri/src/main.rs index a896388e9..1aaeb37ea 100644 --- a/tauri-app/src-tauri/src/main.rs +++ b/tauri-app/src-tauri/src/main.rs @@ -8,7 +8,7 @@ pub mod transaction_status; mod commands; use commands::chain::{get_block_number, get_chainid}; use commands::charts::make_charts; -use commands::config::parse_config; +use commands::config::{convert_configstring_to_config, merge_configstrings, parse_configstring}; use commands::dotrain::parse_dotrain; use commands::dotrain_add_order_lsp::{call_lsp_completion, call_lsp_hover, call_lsp_problems}; use commands::order::{order_add, order_detail, order_remove, orders_list, orders_list_write_csv}; @@ -55,7 +55,9 @@ fn run_tauri_app() { call_lsp_completion, call_lsp_hover, call_lsp_problems, - parse_config, + parse_configstring, + merge_configstrings, + convert_configstring_to_config, make_charts ]) .run(tauri::generate_context!()) diff --git a/tauri-app/src/lib/components/DropdownRadio.svelte b/tauri-app/src/lib/components/DropdownRadio.svelte index aac0de16b..2e0808159 100644 --- a/tauri-app/src/lib/components/DropdownRadio.svelte +++ b/tauri-app/src/lib/components/DropdownRadio.svelte @@ -15,7 +15,7 @@ - + {#each Object.entries(options) as [ref, option]}
diff --git a/tauri-app/src/lib/components/FileTextarea.svelte b/tauri-app/src/lib/components/FileTextarea.svelte index 7e6e7659d..22f73ba92 100644 --- a/tauri-app/src/lib/components/FileTextarea.svelte +++ b/tauri-app/src/lib/components/FileTextarea.svelte @@ -43,8 +43,8 @@
-
- +
+
diff --git a/tauri-app/src/lib/components/SkeletonRow.svelte b/tauri-app/src/lib/components/SkeletonRow.svelte index 682b5e330..4c8cf5442 100644 --- a/tauri-app/src/lib/components/SkeletonRow.svelte +++ b/tauri-app/src/lib/components/SkeletonRow.svelte @@ -2,4 +2,4 @@ export let divClass = ''; -
\ No newline at end of file +
\ No newline at end of file diff --git a/tauri-app/src/lib/services/chart.ts b/tauri-app/src/lib/services/chart.ts index e6a4b0344..2078a519c 100644 --- a/tauri-app/src/lib/services/chart.ts +++ b/tauri-app/src/lib/services/chart.ts @@ -1,9 +1,4 @@ import type { ChartData } from '$lib/typeshare/fuzz'; import { invoke } from '@tauri-apps/api'; -export async function makeChartData(dotrain: string, settings: string): Promise { - console.log('makeChartData') - return await invoke("make_charts", { - dotrain, settings - }); -} \ No newline at end of file +export const makeChartData = async (dotrain: string, settings: string): Promise => invoke("make_charts", { dotrain, settings }); \ No newline at end of file diff --git a/tauri-app/src/lib/services/config.ts b/tauri-app/src/lib/services/config.ts new file mode 100644 index 000000000..e2ffee3eb --- /dev/null +++ b/tauri-app/src/lib/services/config.ts @@ -0,0 +1,9 @@ +import { settingsText } from "$lib/stores/settings"; +import type { Config } from "$lib/typeshare/config"; +import type { ConfigString } from "$lib/typeshare/configString"; +import { invoke } from "@tauri-apps/api"; +import { get } from "svelte/store"; + +export const mergeDotrainConfigWithSettings = async (dotrain: string): Promise => invoke("merge_configstrings", {dotrain, configText: get(settingsText)}); + +export const convertConfigstringToConfig = async (configString: ConfigString): Promise => invoke("convert_configstring_to_config", {configString}); diff --git a/tauri-app/src/lib/services/langServices.ts b/tauri-app/src/lib/services/langServices.ts index 6cd90c4cb..eeb937bda 100644 --- a/tauri-app/src/lib/services/langServices.ts +++ b/tauri-app/src/lib/services/langServices.ts @@ -3,20 +3,14 @@ import { ErrorCode, type Problem, TextDocumentItem, Position, Hover, CompletionI import { rpcUrl } from '$lib/stores/settings'; import { get } from 'svelte/store'; import { forkBlockNumber } from '$lib/stores/forkBlockNumber'; -import { settings, activeDeployment } from '$lib/stores/settings'; +import type { Deployer } from '$lib/typeshare/config'; + /** * Provides problems callback by invoking related tauri command */ -export async function problemsCallback(textDocument: TextDocumentItem): Promise { +export async function problemsCallback(textDocument: TextDocumentItem, bindings: Record, deployer: Deployer | undefined): Promise { try { - const deployment = get(activeDeployment); - if(!deployment) throw Error("Deployment not selected"); - - const scenario = get(settings).scenarios?.[deployment.scenario]; - const bindings = scenario?.bindings ? scenario.bindings : {}; - const deployer = scenario?.deployer ? get(settings).deployers?.[scenario.deployer] : undefined; - return await invoke('call_lsp_problems', { textDocument, rpcUrl: get(rpcUrl), blockNumber: get(forkBlockNumber).value, bindings, deployer}); } catch (err) { @@ -31,25 +25,11 @@ export async function problemsCallback(textDocument: TextDocumentItem): Promise< /** * Provides hover callback by invoking related tauri command */ -export async function hoverCallback(textDocument: TextDocumentItem, position: Position): Promise { - const deployment = get(activeDeployment); - if(!deployment) throw Error("Deployment not selected"); - - const scenario = get(settings).scenarios?.[deployment.scenario]; - const bindings = scenario?.bindings ? scenario.bindings : {}; - - return await invoke('call_lsp_hover', { textDocument, position, bindings }); -} +export const hoverCallback = (textDocument: TextDocumentItem, position: Position, bindings: Record): Promise => + invoke('call_lsp_hover', { textDocument, position, bindings }); /** * Provides completion callback by invoking related tauri command */ -export async function completionCallback(textDocument: TextDocumentItem, position: Position): Promise { - const deployment = get(activeDeployment); - if(!deployment) throw Error("Deployment not selected"); - - const scenario = get(settings).scenarios?.[deployment.scenario]; - const bindings = scenario?.bindings ? scenario.bindings : {}; - - return await invoke('call_lsp_completion', { textDocument, position, bindings }); -} \ No newline at end of file +export const completionCallback = async (textDocument: TextDocumentItem, position: Position, bindings: Record): Promise => + invoke('call_lsp_completion', { textDocument, position, bindings }); diff --git a/tauri-app/src/lib/services/order.ts b/tauri-app/src/lib/services/order.ts index 9f7ed8e78..3829ce29d 100644 --- a/tauri-app/src/lib/services/order.ts +++ b/tauri-app/src/lib/services/order.ts @@ -2,12 +2,9 @@ import { get } from 'svelte/store'; import { invoke } from '@tauri-apps/api'; import { rpcUrl, orderbookAddress,chainId, subgraphUrl } from '$lib/stores/settings'; import { walletDerivationIndex } from '$lib/stores/wallets'; -import { activeDeployment } from '$lib/stores/settings'; - -export async function orderAdd(dotrain: string) { - const deployment = get(activeDeployment); - if (deployment === undefined) throw Error("undefined deployment!"); +import type { Deployment } from '$lib/typeshare/config'; +export async function orderAdd(dotrain: string, deployment: Deployment) { await invoke("order_add", { dotrain, deployment, diff --git a/tauri-app/src/lib/stores/settings.ts b/tauri-app/src/lib/stores/settings.ts index 4368386ba..bc88fe913 100644 --- a/tauri-app/src/lib/stores/settings.ts +++ b/tauri-app/src/lib/stores/settings.ts @@ -21,15 +21,12 @@ const emptyConfig = { charts: {} } as ConfigString; -// dotrain text store -export const dotrainFile = textFileStore('Rain', ['rain']); - // general export const settingsText = cachedWritableStore('settings', "", (s) => s, (s) => s); export const settingsFile = textFileStore('Orderbook Settings Yaml', ['yml', 'yaml'], get(settingsText)); -export const settings = asyncDerived([settingsText, dotrainFile], async ([$settingsText]): Promise => { +export const settings = asyncDerived(settingsText, async ($settingsText): Promise => { try { - const config: ConfigString = await invoke("parse_config", {text: $settingsText}); + const config: ConfigString = await invoke("parse_configstring", {text: $settingsText}); return config; } catch(e) { toasts.error(e as string); @@ -55,17 +52,12 @@ export const activeChainLatestBlockNumber = derived(activeNetwork, ($activeNetwo export const activeOrderbookRef = cachedWritableStringOptional("settings.activeOrderbookRef"); export const activeNetworkOrderbooks = derived([settings, activeNetworkRef], ([$settings, $activeNetworkRef]) => $settings?.orderbooks ? pickBy($settings.orderbooks, (orderbook) => orderbook.network === $activeNetworkRef) as Record : {} as Record); export const activeOrderbook = derived([settings, activeOrderbookRef], ([$settings, $activeOrderbookRef]) => ($settings?.orderbooks !== undefined && $activeOrderbookRef !== undefined) ? $settings.orderbooks[$activeOrderbookRef] : undefined); -export const subgraphUrl = derived(activeOrderbook, ($activeOrderbook) => $activeOrderbook?.subgraph); +export const subgraphUrl = derived([settings, activeOrderbook], ([$settings, $activeOrderbook]) => ($settings?.subgraphs !== undefined && $activeOrderbook?.subgraph !== undefined) ? $settings.subgraphs[$activeOrderbook.subgraph] : undefined); export const orderbookAddress = derived(activeOrderbook, ($activeOrderbook) => $activeOrderbook?.address); export const hasRequiredSettings = derived([activeNetworkRef, activeOrderbookRef], ([$activeNetworkRef, $activeOrderbookRef]) => $activeNetworkRef !== undefined && $activeOrderbookRef !== undefined); -// deployments -export const deployments = derived([settings, activeNetworkRef, activeOrderbookRef], ([$settings, $activeNetworkRef, $activeOrderbookRef]) => pickBy($settings.deployments, (v) => $settings.orders?.[v.order].network === $activeNetworkRef && $settings.orders?.[v.order].orderbook === $activeOrderbookRef)); -export const activeDeploymentRef = cachedWritableStringOptional("settings.activeDeploymentRef"); -export const activeDeployment = derived([deployments, activeDeploymentRef], ([$deployments, $activeDeploymentRef]) => ($activeDeploymentRef !== undefined && $deployments !== undefined) ? $deployments[$activeDeploymentRef] : undefined); - -// When networks / orderbooks settings updated, reset active network / orderbooks +// When networks / orderbooks settings updated, reset active network / orderbook settings.subscribe(async ($settings) => { await settings.load(); const $activeNetworkRef = get(activeNetworkRef); diff --git a/tauri-app/src/routes/+layout.svelte b/tauri-app/src/routes/+layout.svelte index 3a9defbff..e61e748f1 100644 --- a/tauri-app/src/routes/+layout.svelte +++ b/tauri-app/src/routes/+layout.svelte @@ -13,11 +13,12 @@ import TransactionStatusNotice from '$lib/components/TransactionStatusNotice.svelte'; import WindowDraggableArea from '$lib/components/WindowDraggableArea.svelte'; import { goto } from '$app/navigation'; - import { hasRequiredSettings } from '$lib/stores/settings'; + import { hasRequiredSettings, settings } from '$lib/stores/settings'; $: $hasRequiredSettings, redirectIfMissingSettings(); async function redirectIfMissingSettings() { + await settings.load(); const hasRequiredSettingsVal = await hasRequiredSettings.load(); if (!hasRequiredSettingsVal) goto('/settings'); } diff --git a/tauri-app/src/routes/orders/add/+page.svelte b/tauri-app/src/routes/orders/add/+page.svelte index 92b362c3e..ceef0a77d 100644 --- a/tauri-app/src/routes/orders/add/+page.svelte +++ b/tauri-app/src/routes/orders/add/+page.svelte @@ -1,4 +1,3 @@ -/** eslint-disable no-console */ @@ -55,10 +86,33 @@ bind:value={$dotrainFile.text} disabled={isSubmitting} styles={{ '&': { minHeight: '400px' } }} - rainlangExtension={ext} + {rainlangExtension} /> + +
+
+ + {#if deployments === undefined || Object.keys(deployments).length === 0} + No deployments found for the selected network + {:else} + + + {selectedRef !== undefined ? selectedRef : 'Select a deployment'} + + + +
+ {ref} +
+
+
+ {/if} +
+
+
+ Add Order - - - - {#if $deployments === undefined || Object.keys($deployments).length === 0} - - {:else} - - - {selected} - - - -
- {option} -
-
-
- {/if} -
From 620b20f557d525b739f92c156cd8e7b268beaae9 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Thu, 14 Mar 2024 10:56:32 -0700 Subject: [PATCH 35/48] fix(tauri/ui): include deployer address in lsp problems call --- tauri-app/src/lib/services/langServices.ts | 6 ++---- tauri-app/src/routes/orders/add/+page.svelte | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/tauri-app/src/lib/services/langServices.ts b/tauri-app/src/lib/services/langServices.ts index eeb937bda..2179f910f 100644 --- a/tauri-app/src/lib/services/langServices.ts +++ b/tauri-app/src/lib/services/langServices.ts @@ -3,15 +3,13 @@ import { ErrorCode, type Problem, TextDocumentItem, Position, Hover, CompletionI import { rpcUrl } from '$lib/stores/settings'; import { get } from 'svelte/store'; import { forkBlockNumber } from '$lib/stores/forkBlockNumber'; -import type { Deployer } from '$lib/typeshare/config'; - /** * Provides problems callback by invoking related tauri command */ -export async function problemsCallback(textDocument: TextDocumentItem, bindings: Record, deployer: Deployer | undefined): Promise { +export async function problemsCallback(textDocument: TextDocumentItem, bindings: Record, deployerAddress: string | undefined): Promise { try { - return await invoke('call_lsp_problems', { textDocument, rpcUrl: get(rpcUrl), blockNumber: get(forkBlockNumber).value, bindings, deployer}); + return await invoke('call_lsp_problems', { textDocument, rpcUrl: get(rpcUrl), blockNumber: get(forkBlockNumber).value, bindings, deployer: deployerAddress }); } catch (err) { return [{ diff --git a/tauri-app/src/routes/orders/add/+page.svelte b/tauri-app/src/routes/orders/add/+page.svelte index ceef0a77d..d355ea75a 100644 --- a/tauri-app/src/routes/orders/add/+page.svelte +++ b/tauri-app/src/routes/orders/add/+page.svelte @@ -4,7 +4,7 @@ import ButtonLoading from '$lib/components/ButtonLoading.svelte'; import { orderAdd } from '$lib/services/order'; import FileTextarea from '$lib/components/FileTextarea.svelte'; - import { Helper, Label, Button, Spinner } from 'flowbite-svelte'; + import { Helper, Label, Button, Spinner} from 'flowbite-svelte'; import InputBlockNumber from '$lib/components/InputBlockNumber.svelte'; import { forkBlockNumber } from '$lib/stores/forkBlockNumber'; import { RawRainlangExtension } from 'codemirror-rainlang'; @@ -37,7 +37,7 @@ $: rainlangExtension = new RawRainlangExtension({ hover: (text, position) => hoverCallback.apply(null, [text, position, bindings]), - diagnostics: (text) => problemsCallback.apply(null, [text, bindings, deployment?.order.deployer]), + diagnostics: (text) => problemsCallback.apply(null, [text, bindings, deployment?.scenario.deployer.address]), completion: (text, position) => completionCallback.apply(null, [text, position, bindings]), }); From 4036d023fd6923ba427ce1785b500249facda692 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Thu, 14 Mar 2024 11:02:00 -0700 Subject: [PATCH 36/48] feat(tauri/ui): styling of deployment properties in dropdown --- .../src/lib/components/DropdownProperty.svelte | 13 +++++++++++++ tauri-app/src/routes/orders/add/+page.svelte | 9 ++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 tauri-app/src/lib/components/DropdownProperty.svelte diff --git a/tauri-app/src/lib/components/DropdownProperty.svelte b/tauri-app/src/lib/components/DropdownProperty.svelte new file mode 100644 index 000000000..34bc5252e --- /dev/null +++ b/tauri-app/src/lib/components/DropdownProperty.svelte @@ -0,0 +1,13 @@ + + +
+
+ {key} +
+

+ {value} +

+
diff --git a/tauri-app/src/routes/orders/add/+page.svelte b/tauri-app/src/routes/orders/add/+page.svelte index d355ea75a..a0afaeac0 100644 --- a/tauri-app/src/routes/orders/add/+page.svelte +++ b/tauri-app/src/routes/orders/add/+page.svelte @@ -20,6 +20,7 @@ import DropdownRadio from '$lib/components/DropdownRadio.svelte'; import { toasts } from '$lib/stores/toasts'; import type { ConfigString } from '$lib/typeshare/configString'; + import DropdownProperty from '$lib/components/DropdownProperty.svelte'; let isSubmitting = false; let isCharting = false; @@ -102,9 +103,11 @@ {selectedRef !== undefined ? selectedRef : 'Select a deployment'} - -
- {ref} + +
+
{ref}
+ +
From 8fa2117966a18f89f850dbc3dd3e84f5c367209d Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Thu, 14 Mar 2024 11:06:23 -0700 Subject: [PATCH 37/48] fix(tauri/ui): avoid undefined error --- tauri-app/src/routes/orders/add/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tauri-app/src/routes/orders/add/+page.svelte b/tauri-app/src/routes/orders/add/+page.svelte index a0afaeac0..599913e81 100644 --- a/tauri-app/src/routes/orders/add/+page.svelte +++ b/tauri-app/src/routes/orders/add/+page.svelte @@ -32,7 +32,7 @@ $: $dotrainFile.text, updateMergedConfig(); $: deployments = (mergedConfigString !== undefined && mergedConfigString?.deployments !== undefined && mergedConfigString?.orders !== undefined) ? - pickBy(mergedConfigString.deployments, (d) => mergedConfigString?.orders?.[d.order].network === $activeNetworkRef) : {}; + pickBy(mergedConfigString.deployments, (d) => mergedConfigString?.orders?.[d.order]?.network === $activeNetworkRef) : {}; $: deployment = (deploymentRef !== undefined && mergedConfig !== undefined) ? mergedConfig.deployments[deploymentRef] : undefined; $: bindings = deployment ? deployment.scenario.bindings : {}; From ee0bdc49e88cb6e7551d3666a5bb2d4e95b3cd90 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Thu, 14 Mar 2024 11:15:05 -0700 Subject: [PATCH 38/48] fix(tauri/ui): display frontmatter parsing problems in LSP, not error toasts --- tauri-app/src/routes/orders/add/+page.svelte | 28 +++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/tauri-app/src/routes/orders/add/+page.svelte b/tauri-app/src/routes/orders/add/+page.svelte index 599913e81..8ff2ea9f8 100644 --- a/tauri-app/src/routes/orders/add/+page.svelte +++ b/tauri-app/src/routes/orders/add/+page.svelte @@ -7,7 +7,7 @@ import { Helper, Label, Button, Spinner} from 'flowbite-svelte'; import InputBlockNumber from '$lib/components/InputBlockNumber.svelte'; import { forkBlockNumber } from '$lib/stores/forkBlockNumber'; - import { RawRainlangExtension } from 'codemirror-rainlang'; + import { ErrorCode, RawRainlangExtension, type Problem } from 'codemirror-rainlang'; import { completionCallback, hoverCallback, problemsCallback } from '$lib/services/langServices'; import { makeChartData } from '$lib/services/chart'; import { settingsText, activeNetworkRef } from '$lib/stores/settings'; @@ -30,15 +30,32 @@ let mergedConfigString: ConfigString | undefined = undefined; let mergedConfig: Config | undefined = undefined; - $: $dotrainFile.text, updateMergedConfig(); $: deployments = (mergedConfigString !== undefined && mergedConfigString?.deployments !== undefined && mergedConfigString?.orders !== undefined) ? pickBy(mergedConfigString.deployments, (d) => mergedConfigString?.orders?.[d.order]?.network === $activeNetworkRef) : {}; $: deployment = (deploymentRef !== undefined && mergedConfig !== undefined) ? mergedConfig.deployments[deploymentRef] : undefined; $: bindings = deployment ? deployment.scenario.bindings : {}; + $: $dotrainFile.text, updateMergedConfig(); $: rainlangExtension = new RawRainlangExtension({ hover: (text, position) => hoverCallback.apply(null, [text, position, bindings]), - diagnostics: (text) => problemsCallback.apply(null, [text, bindings, deployment?.scenario.deployer.address]), + diagnostics: async (text) => { + // get problems with merging settings config with frontmatter + const allProblems: Problem[] = []; + try { + await mergeDotrainConfigWithSettings($dotrainFile.text); + } catch(e) { + allProblems.push({ + msg: typeof e === "string" ? e : e instanceof Error ? e.message : "something went wrong!", + position: [0, 0], + code: ErrorCode.InvalidRainDocument + } as Problem); + } + + // get problems with dotrain + const problems = await problemsCallback.apply(null, [text, bindings, deployment?.scenario.deployer.address]); + + return [...allProblems, ...problems] as Problem[]; + }, completion: (text, position) => completionCallback.apply(null, [text, position, bindings]), }); @@ -52,9 +69,8 @@ try { mergedConfigString = await mergeDotrainConfigWithSettings($dotrainFile.text); mergedConfig = await convertConfigstringToConfig(mergedConfigString); - } catch(e) { - toasts.error(e as string); - } + // eslint-disable-next-line no-empty + } catch(e) {} } async function execute() { From d687828e68b0e5c137cceeaad347896c5afc9aeb Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Thu, 14 Mar 2024 11:45:54 -0700 Subject: [PATCH 39/48] fix(tauri/ui): display settings parsing problems in LSP, not error toasts --- ...l.svelte => CodeMirrorConfigString.svelte} | 9 +++++ tauri-app/src/lib/services/config.ts | 35 +++++++++++++++++++ tauri-app/src/lib/stores/settings.ts | 4 +-- tauri-app/src/routes/orders/add/+page.svelte | 17 +++------ tauri-app/src/routes/settings/+page.svelte | 4 +-- 5 files changed, 52 insertions(+), 17 deletions(-) rename tauri-app/src/lib/components/{CodeMirrorYaml.svelte => CodeMirrorConfigString.svelte} (54%) diff --git a/tauri-app/src/lib/components/CodeMirrorYaml.svelte b/tauri-app/src/lib/components/CodeMirrorConfigString.svelte similarity index 54% rename from tauri-app/src/lib/components/CodeMirrorYaml.svelte rename to tauri-app/src/lib/components/CodeMirrorConfigString.svelte index 7744917fa..8eba1c203 100644 --- a/tauri-app/src/lib/components/CodeMirrorYaml.svelte +++ b/tauri-app/src/lib/components/CodeMirrorConfigString.svelte @@ -2,14 +2,23 @@ import CodeMirror from 'svelte-codemirror-editor'; import { codeMirrorTheme } from '$lib/stores/darkMode'; import { yaml } from '@codemirror/lang-yaml'; + import { parseConfigStringProblems } from '$lib/services/config'; + import { RawRainlangExtension } from 'codemirror-rainlang'; export let value: string; export let disabled = false; export let styles = {}; + + const configStringExtension = new RawRainlangExtension({ + hover: async () => null, + completion: async () => null, + diagnostics: async (textDocument) => parseConfigStringProblems(textDocument.text), + }); => invoke("parse_configstring", {text}); export const mergeDotrainConfigWithSettings = async (dotrain: string): Promise => invoke("merge_configstrings", {dotrain, configText: get(settingsText)}); export const convertConfigstringToConfig = async (configString: ConfigString): Promise => invoke("convert_configstring_to_config", {configString}); + +export async function parseConfigStringProblems(text: string) { + const problems: Problem[] = []; + + try { + await parseConfigString(text); + } catch(e) { + problems.push(convertErrorToProblem(e)); + } + + return problems; +} + +export async function mergeDotrainConfigWithSettingsProblems(dotrain: string) { + const problems: Problem[] = []; + + try { + await mergeDotrainConfigWithSettings(dotrain); + } catch(e) { + problems.push(convertErrorToProblem(e)); + } + + return problems; +} + +function convertErrorToProblem(e: unknown) { + return { + msg: typeof e === "string" ? e : e instanceof Error ? e.message : "something went wrong!", + position: [0, 0], + code: ErrorCode.InvalidRainDocument + } as Problem +} \ No newline at end of file diff --git a/tauri-app/src/lib/stores/settings.ts b/tauri-app/src/lib/stores/settings.ts index bc88fe913..0b35b0013 100644 --- a/tauri-app/src/lib/stores/settings.ts +++ b/tauri-app/src/lib/stores/settings.ts @@ -3,11 +3,11 @@ import { cachedWritableStore, cachedWritableStringOptional } from '$lib/storesGe import find from 'lodash/find'; import * as chains from 'viem/chains'; import { textFileStore } from '$lib/storesGeneric/textFileStore'; -import { invoke } from '@tauri-apps/api'; import { type ConfigString, type OrderbookRef, type OrderbookString } from '$lib/typeshare/configString'; import { getBlockNumberFromRpc } from '$lib/services/chain'; import { toasts } from './toasts'; import { pickBy } from 'lodash'; +import { parseConfigString } from '$lib/services/config'; const emptyConfig = { deployments: {}, @@ -26,7 +26,7 @@ export const settingsText = cachedWritableStore('settings', "", (s) => s export const settingsFile = textFileStore('Orderbook Settings Yaml', ['yml', 'yaml'], get(settingsText)); export const settings = asyncDerived(settingsText, async ($settingsText): Promise => { try { - const config: ConfigString = await invoke("parse_configstring", {text: $settingsText}); + const config: ConfigString = await parseConfigString($settingsText); return config; } catch(e) { toasts.error(e as string); diff --git a/tauri-app/src/routes/orders/add/+page.svelte b/tauri-app/src/routes/orders/add/+page.svelte index 8ff2ea9f8..ec9bbac35 100644 --- a/tauri-app/src/routes/orders/add/+page.svelte +++ b/tauri-app/src/routes/orders/add/+page.svelte @@ -7,7 +7,7 @@ import { Helper, Label, Button, Spinner} from 'flowbite-svelte'; import InputBlockNumber from '$lib/components/InputBlockNumber.svelte'; import { forkBlockNumber } from '$lib/stores/forkBlockNumber'; - import { ErrorCode, RawRainlangExtension, type Problem } from 'codemirror-rainlang'; + import { RawRainlangExtension, type Problem } from 'codemirror-rainlang'; import { completionCallback, hoverCallback, problemsCallback } from '$lib/services/langServices'; import { makeChartData } from '$lib/services/chart'; import { settingsText, activeNetworkRef } from '$lib/stores/settings'; @@ -15,7 +15,7 @@ import Charts from '$lib/components/Charts.svelte'; import { textFileStore } from '$lib/storesGeneric/textFileStore'; import { pickBy } from 'lodash'; - import { convertConfigstringToConfig, mergeDotrainConfigWithSettings } from '$lib/services/config'; + import { convertConfigstringToConfig, mergeDotrainConfigWithSettings, mergeDotrainConfigWithSettingsProblems } from '$lib/services/config'; import type { Config } from '$lib/typeshare/config'; import DropdownRadio from '$lib/components/DropdownRadio.svelte'; import { toasts } from '$lib/stores/toasts'; @@ -40,21 +40,12 @@ hover: (text, position) => hoverCallback.apply(null, [text, position, bindings]), diagnostics: async (text) => { // get problems with merging settings config with frontmatter - const allProblems: Problem[] = []; - try { - await mergeDotrainConfigWithSettings($dotrainFile.text); - } catch(e) { - allProblems.push({ - msg: typeof e === "string" ? e : e instanceof Error ? e.message : "something went wrong!", - position: [0, 0], - code: ErrorCode.InvalidRainDocument - } as Problem); - } + const configProblems = await mergeDotrainConfigWithSettingsProblems(text.text); // get problems with dotrain const problems = await problemsCallback.apply(null, [text, bindings, deployment?.scenario.deployer.address]); - return [...allProblems, ...problems] as Problem[]; + return [...configProblems, ...problems] as Problem[]; }, completion: (text, position) => completionCallback.apply(null, [text, position, bindings]), }); diff --git a/tauri-app/src/routes/settings/+page.svelte b/tauri-app/src/routes/settings/+page.svelte index e08041ca0..029e401c3 100644 --- a/tauri-app/src/routes/settings/+page.svelte +++ b/tauri-app/src/routes/settings/+page.svelte @@ -5,7 +5,7 @@ settingsText, } from '$lib/stores/settings'; import PageHeader from '$lib/components/PageHeader.svelte'; - import CodeMirrorYaml from '$lib/components/CodeMirrorYaml.svelte'; + import CodeMirrorConfigString from '$lib/components/CodeMirrorConfigString.svelte'; import ButtonLoading from '$lib/components/ButtonLoading.svelte'; import { settingsFile }from '$lib/stores/settings'; import FileTextarea from '$lib/components/FileTextarea.svelte'; @@ -31,7 +31,7 @@ - From f251aca546781aa2d7b7ec15c72307834059f095 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Thu, 14 Mar 2024 11:55:43 -0700 Subject: [PATCH 40/48] fix(cli): short arg conflict --- crates/cli/src/commands/order/add.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cli/src/commands/order/add.rs b/crates/cli/src/commands/order/add.rs index dd0285260..c9c5482ca 100644 --- a/crates/cli/src/commands/order/add.rs +++ b/crates/cli/src/commands/order/add.rs @@ -21,7 +21,7 @@ pub struct CliOrderAddArgs { )] dotrain_file: PathBuf, - #[arg(short, long, help = "Deployment key to select from frontmatter")] + #[arg(short = 'e', long, help = "Deployment key to select from frontmatter")] deployment: String, #[clap(flatten)] From c33b184bffa6400e1f5111bb075b625b83bd5578 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Thu, 14 Mar 2024 12:01:42 -0700 Subject: [PATCH 41/48] refactor: remove no longer needed typeshareFix script, since we switched to fork of typeshare that can handle u64 --- crates/settings/src/network.rs | 4 ++-- crates/settings/src/scenario.rs | 2 +- flake.nix | 2 -- tauri-app/src/scripts/typeshareFix.cjs | 24 ------------------------ 4 files changed, 3 insertions(+), 29 deletions(-) delete mode 100644 tauri-app/src/scripts/typeshareFix.cjs diff --git a/crates/settings/src/network.rs b/crates/settings/src/network.rs index 31eb43501..1a4be7cd1 100644 --- a/crates/settings/src/network.rs +++ b/crates/settings/src/network.rs @@ -11,10 +11,10 @@ use url::{ParseError, Url}; pub struct Network { #[typeshare(typescript(type = "string"))] pub rpc: Url, - #[typeshare(skip)] + #[typeshare(typescript(type = "number"))] pub chain_id: u64, pub label: Option, - #[typeshare(skip)] + #[typeshare(typescript(type = "number"))] pub network_id: Option, pub currency: Option, } diff --git a/crates/settings/src/scenario.rs b/crates/settings/src/scenario.rs index 13bbcc1a7..b856dc3a2 100644 --- a/crates/settings/src/scenario.rs +++ b/crates/settings/src/scenario.rs @@ -10,7 +10,7 @@ use typeshare::typeshare; pub struct Scenario { pub name: String, pub bindings: HashMap, - #[typeshare(skip)] + #[typeshare(typescript(type = "number"))] pub runs: Option, #[typeshare(typescript(type = "Deployer"))] pub deployer: Arc, diff --git a/flake.nix b/flake.nix index fe4472270..df78e31ed 100644 --- a/flake.nix +++ b/flake.nix @@ -43,8 +43,6 @@ typeshare tauri-app/src-tauri/src/toast.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/toast.ts; typeshare tauri-app/src-tauri/src/transaction_status.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/transactionStatus.ts; - node tauri-app/src/scripts/typeshareFix.cjs - # Fix linting of generated types cd tauri-app && npm i && npm run lint ''; diff --git a/tauri-app/src/scripts/typeshareFix.cjs b/tauri-app/src/scripts/typeshareFix.cjs deleted file mode 100644 index 75b75393c..000000000 --- a/tauri-app/src/scripts/typeshareFix.cjs +++ /dev/null @@ -1,24 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-var-requires -const fs = require("fs"); - -let config_content = fs.readFileSync("./tauri-app/src/lib/typeshare/config.ts", { encoding: "utf-8" }); -config_content = config_content.replace(`export interface Network { - rpc: string; - label?: string; - currency?: string; -}`, `export interface Network { - rpc: string; - chain_id: number; - label?: string; - network_id?: number; - currency?: string; -}`); -config_content = config_content.replace(`export interface Scenario { - bindings: Record; - deployer: Deployer; -}`, `export interface Scenario { - bindings: Record; - runs?: number; - deployer: Deployer; -}`); -fs.writeFileSync("./tauri-app/src/lib/typeshare/config.ts", config_content); From 4035dbecc9978baa4b21a7422080c692fe72c089 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Thu, 14 Mar 2024 13:03:34 -0700 Subject: [PATCH 42/48] fix(settings): kebab case in test --- crates/settings/src/string_structs.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/settings/src/string_structs.rs b/crates/settings/src/string_structs.rs index ee6b3f7b6..6d0889f94 100644 --- a/crates/settings/src/string_structs.rs +++ b/crates/settings/src/string_structs.rs @@ -173,15 +173,15 @@ mod tests { networks: mainnet: rpc: https://mainnet.node - chain_id: 1 + chain-id: 1 label: Mainnet - network_id: 1 + network-id: 1 currency: ETH testnet: rpc: https://testnet.node - chain_id: 2 + chain-id: 2 label: Testnet - network_id: 2 + network-id: 2 currency: ETH subgraphs: From 4625f8e07944789aa2e10a024f13359b7ff30762 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Thu, 14 Mar 2024 13:10:51 -0700 Subject: [PATCH 43/48] chore: fmt + clippy --- crates/settings/src/deployer.rs | 2 +- tauri-app/src-tauri/src/commands/charts.rs | 6 +++--- tauri-app/src-tauri/src/commands/dotrain_add_order_lsp.rs | 6 +++--- tauri-app/src-tauri/src/commands/mod.rs | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/settings/src/deployer.rs b/crates/settings/src/deployer.rs index 1c2f23fb6..d4f773b0d 100644 --- a/crates/settings/src/deployer.rs +++ b/crates/settings/src/deployer.rs @@ -73,7 +73,7 @@ mod tests { let network_name = "Local Testnet"; let networks = HashMap::from([(network_name.to_string(), mock_network())]); let deployer_string = DeployerString { - address: address, + address, network: Some(network_name.to_string()), label: Some("Test Deployer".to_string()), }; diff --git a/tauri-app/src-tauri/src/commands/charts.rs b/tauri-app/src-tauri/src/commands/charts.rs index 70935680a..978c1d2b2 100644 --- a/tauri-app/src-tauri/src/commands/charts.rs +++ b/tauri-app/src-tauri/src/commands/charts.rs @@ -1,7 +1,7 @@ -use crate::error::CommandResult; use crate::commands::config::merge_configstrings; -use rain_orderbook_common::fuzz::*; +use crate::error::CommandResult; use rain_orderbook_app_settings::config::*; +use rain_orderbook_common::fuzz::*; #[tauri::command] pub async fn make_charts(dotrain: String, settings: String) -> CommandResult> { @@ -11,4 +11,4 @@ pub async fn make_charts(dotrain: String, settings: String) -> CommandResult, deployer: Option
, ) -> CommandResult> { - Ok( - DotrainAddOrderLsp::new(text_document, bindings).problems(rpc_url, block_number, deployer).await - ) + Ok(DotrainAddOrderLsp::new(text_document, bindings) + .problems(rpc_url, block_number, deployer) + .await) } diff --git a/tauri-app/src-tauri/src/commands/mod.rs b/tauri-app/src-tauri/src/commands/mod.rs index bb08b9d12..471f43562 100644 --- a/tauri-app/src-tauri/src/commands/mod.rs +++ b/tauri-app/src-tauri/src/commands/mod.rs @@ -1,6 +1,6 @@ pub mod chain; -pub mod config; pub mod charts; +pub mod config; pub mod dotrain; pub mod dotrain_add_order_lsp; pub mod order; From 237ff78de014abc5a58e3d1bb0cfbc61c38eafb6 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Thu, 14 Mar 2024 13:51:08 -0700 Subject: [PATCH 44/48] fix: tests kebab-case --- crates/common/src/fuzz/mod.rs | 8 ++++---- crates/settings/src/string_structs.rs | 26 ++++++++++++++------------ 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/crates/common/src/fuzz/mod.rs b/crates/common/src/fuzz/mod.rs index 1f5f10648..beba99674 100644 --- a/crates/common/src/fuzz/mod.rs +++ b/crates/common/src/fuzz/mod.rs @@ -255,7 +255,7 @@ deployers: networks: mumbai: rpc: https://polygon-mumbai.g.alchemy.com/v2/_i0186N-488iRU9wUwMQDreCAKy-MEXa - chain_id: 80001 + chain-id: 80001 scenarios: mumbai: runs: 5 @@ -301,7 +301,7 @@ b: fuzzed; networks: mumbai: rpc: https://polygon-mumbai.g.alchemy.com/v2/_i0186N-488iRU9wUwMQDreCAKy-MEXa - chain_id: 80001 + chain-id: 80001 scenarios: mumbai: runs: 5 @@ -318,12 +318,12 @@ b: fuzzed; data: x: 0.0 y: 0.1 - plot_type: line + plot-type: line plot2: data: x: 0.0 y: 0.2 - plot_type: bar + plot-type: bar --- #bound !bind it #fuzzed !fuzz it diff --git a/crates/settings/src/string_structs.rs b/crates/settings/src/string_structs.rs index 6d0889f94..ff2460716 100644 --- a/crates/settings/src/string_structs.rs +++ b/crates/settings/src/string_structs.rs @@ -190,12 +190,12 @@ subgraphs: orderbooks: mainnetOrderbook: - address: 0x123 + address: 0xabc0000000000000000000000000000000000001 network: mainnet subgraph: mainnet label: Mainnet Orderbook testnetOrderbook: - address: 0x456 + address: 0xabc0000000000000000000000000000000000002 network: testnet subgraph: testnet label: Testnet Orderbook @@ -203,24 +203,24 @@ orderbooks: tokens: eth: network: mainnet - address: 0xdef + address: 0xabc0000000000000000000000000000000000003 decimals: 18 label: Ethereum symbol: ETH dai: network: mainnet - address: 0xghi + address: 0xabc0000000000000000000000000000000000004 decimals: 18 label: Dai symbol: DAI deployers: mainDeployer: - address: 0xjkl + address: 0xabc0000000000000000000000000000000000005 network: mainnet label: Main Deployer testDeployer: - address: 0xmnop + address: 0xabc0000000000000000000000000000000000006 network: testnet label: Test Deployer @@ -228,12 +228,12 @@ orders: buyETH: inputs: - token: eth - vault_id: 2 + vault-id: 2 - token: dai - vault_id: 0x1 + vault-id: 0x1 outputs: - token: dai - vault_id: 3 + vault-id: 3 network: mainnet deployer: mainDeployer orderbook: mainnetOrderbook @@ -261,12 +261,12 @@ charts: data: x: dataX y: dataY - plot_type: line + plot-type: line plot2: data: x: dataX2 y: dataY2 - plot_type: bar + plot-type: bar deployments: first-deployment: scenario: mainScenario @@ -293,7 +293,9 @@ deployments: ); assert_eq!( config.orderbooks.get("mainnetOrderbook").unwrap().address, - "0x123".parse::
().unwrap() + "0xabc0000000000000000000000000000000000001" + .parse::
() + .unwrap() ); assert_eq!(config.tokens.get("eth").unwrap().decimals, Some(18)); } From 8b1784fb567b05263034bc861df0090b57efd9dd Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Fri, 15 Mar 2024 14:46:41 +0000 Subject: [PATCH 45/48] fix --- crates/cli/src/commands/chart/mod.rs | 2 +- crates/settings/src/string_structs.rs | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/cli/src/commands/chart/mod.rs b/crates/cli/src/commands/chart/mod.rs index 1af23ffe2..67699837f 100644 --- a/crates/cli/src/commands/chart/mod.rs +++ b/crates/cli/src/commands/chart/mod.rs @@ -1,7 +1,7 @@ use crate::execute::Execute; use anyhow::{anyhow, Result}; use clap::Args; -use rain_orderbook_app_settings::string_structs::ConfigString; +use rain_orderbook_app_settings::{string_structs::ConfigString, Config}; use rain_orderbook_common::dotrain::RainDocument; use rain_orderbook_common::fuzz::FuzzRunner; use std::fs::read_to_string; diff --git a/crates/settings/src/string_structs.rs b/crates/settings/src/string_structs.rs index ff2460716..48b62976d 100644 --- a/crates/settings/src/string_structs.rs +++ b/crates/settings/src/string_structs.rs @@ -163,6 +163,13 @@ impl TryFrom for ConfigString { } } +impl TryFrom<&str> for ConfigString { + type Error = serde_yaml::Error; + fn try_from(val: &str) -> Result { + serde_yaml::from_str(val) + } +} + #[cfg(test)] mod tests { use super::*; From b7311e5ebea704676b22abd1811712166a43db0c Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Fri, 15 Mar 2024 15:39:48 +0000 Subject: [PATCH 46/48] fix shell script --- prep-tauri.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prep-tauri.sh b/prep-tauri.sh index 5d5464a1f..4a19f8e78 100755 --- a/prep-tauri.sh +++ b/prep-tauri.sh @@ -11,7 +11,7 @@ nix develop -i --command rainix-rs-prelude nix develop -i --command i9r-prelude cd - -nix develop -i .#tauri-shell --command ob-tauri-prelude +nix develop .#tauri-shell --command ob-tauri-prelude nix develop -i .#tauri-shell --command ob-tauri-test # Run commands in tauri-app From 106689aefbff5157f72a60927545c4d21ea68b64 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Fri, 15 Mar 2024 11:14:52 -0700 Subject: [PATCH 47/48] fix: ensure typeshare is in PATH for ob-tauri-prelude --- flake.nix | 7 +++++-- prep-tauri.sh | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/flake.nix b/flake.nix index df78e31ed..0710aa052 100644 --- a/flake.nix +++ b/flake.nix @@ -21,9 +21,12 @@ set -euxo pipefail # Generate Typescript types from rust types - mkdir -p tauri-app/src/lib/typeshare; - + mkdir -p tauri-app/src/lib/typeshare + + mkdir /tmp/cargo + export CARGO_HOME=/tmp/cargo/ cargo install --git https://github.com/1Password/typeshare --rev 556b44aafd5304eedf17206800f69834e3820b7c + export PATH=$PATH:$CARGO_HOME/bin typeshare crates/subgraph/src/types/vault_balance_changes_list.rs crates/subgraph/src/types/vault_balance_change.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/vaultBalanceChangesList.ts; typeshare crates/subgraph/src/types/order_detail.rs crates/common/src/types/order_detail_extended.rs --lang=typescript --output-file=tauri-app/src/lib/typeshare/orderDetail.ts; diff --git a/prep-tauri.sh b/prep-tauri.sh index 4a19f8e78..5d5464a1f 100755 --- a/prep-tauri.sh +++ b/prep-tauri.sh @@ -11,7 +11,7 @@ nix develop -i --command rainix-rs-prelude nix develop -i --command i9r-prelude cd - -nix develop .#tauri-shell --command ob-tauri-prelude +nix develop -i .#tauri-shell --command ob-tauri-prelude nix develop -i .#tauri-shell --command ob-tauri-test # Run commands in tauri-app From 791cb41f59511fc5d2a1ec6362afe33d86ebf5b0 Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Fri, 15 Mar 2024 11:15:03 -0700 Subject: [PATCH 48/48] fix: failing build --- crates/cli/src/commands/chart/mod.rs | 2 +- crates/settings/src/string_structs.rs | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/crates/cli/src/commands/chart/mod.rs b/crates/cli/src/commands/chart/mod.rs index 67699837f..a0b6b5437 100644 --- a/crates/cli/src/commands/chart/mod.rs +++ b/crates/cli/src/commands/chart/mod.rs @@ -22,7 +22,7 @@ impl Execute for Chart { async fn execute(&self) -> Result<()> { let dotrain = read_to_string(self.dotrain_file.clone()).map_err(|e| anyhow!(e))?; let frontmatter = RainDocument::get_front_matter(&dotrain).unwrap(); - let config_string: ConfigString = frontmatter.try_into()?; + let config_string: ConfigString = frontmatter.to_string().try_into()?; let config: Config = config_string.try_into()?; let mut fuzzer = FuzzRunner::new(&dotrain, config, None).await; let chart_data = fuzzer.build_chart_datas().await?; diff --git a/crates/settings/src/string_structs.rs b/crates/settings/src/string_structs.rs index 48b62976d..ff2460716 100644 --- a/crates/settings/src/string_structs.rs +++ b/crates/settings/src/string_structs.rs @@ -163,13 +163,6 @@ impl TryFrom for ConfigString { } } -impl TryFrom<&str> for ConfigString { - type Error = serde_yaml::Error; - fn try_from(val: &str) -> Result { - serde_yaml::from_str(val) - } -} - #[cfg(test)] mod tests { use super::*;