Skip to content

Commit

Permalink
Merge pull request #1014 from rainlanguage/2024-11-20-gui-config-sour…
Browse files Browse the repository at this point in the history
…ce-update

Implementing token selection and config source updates
  • Loading branch information
findolor authored Nov 25, 2024
2 parents 4a6cf55 + dcff07e commit b956e3e
Show file tree
Hide file tree
Showing 9 changed files with 675 additions and 48 deletions.
108 changes: 94 additions & 14 deletions crates/common/src/dotrain_order/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashMap;

use crate::GH_COMMIT_SHA;
use crate::{
add_order::{ORDERBOOK_ADDORDER_POST_TASK_ENTRYPOINTS, ORDERBOOK_ORDER_ENTRYPOINTS},
Expand All @@ -17,7 +19,6 @@ use rain_orderbook_app_settings::{
#[cfg(target_family = "wasm")]
use rain_orderbook_bindings::{impl_all_wasm_traits, wasm_traits::prelude::*};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use thiserror::Error;
use typeshare::typeshare;

Expand Down Expand Up @@ -75,6 +76,12 @@ pub enum DotrainOrderError {

#[error("Deployment {0} not found")]
DeploymentNotFound(String),

#[error("Order {0} not found")]
OrderNotFound(String),

#[error("Token {0} not found")]
TokenNotFound(String),
}

#[cfg(target_family = "wasm")]
Expand Down Expand Up @@ -390,22 +397,79 @@ impl DotrainOrder {
Ok(())
}

fn update_config_source(
&mut self,
config_source: ConfigSource,
) -> Result<(), DotrainOrderError> {
self.config_source = config_source.clone();
self.config = config_source.try_into()?;
Ok(())
}

pub fn update_config_source_bindings(
&mut self,
scenario_name: &str,
bindings: HashMap<String, String>,
) -> Result<(), DotrainOrderError> {
let scenario_parts = scenario_name.split('.').collect::<Vec<_>>();
let base_scenario = scenario_parts[0];

let mut scenario = self
.config_source
.scenarios
.get(base_scenario)
.ok_or(DotrainOrderError::ScenarioNotFound(
base_scenario.to_string(),
))?
.clone();

if scenario_parts.len() == 1 {
scenario.bindings = bindings;
} else {
let mut current_scenario = &mut scenario;
for &part in scenario_parts.iter().skip(1) {
if let Some(sub_scenarios) = &mut current_scenario.scenarios {
current_scenario =
sub_scenarios
.get_mut(part)
.ok_or(DotrainOrderError::ScenarioNotFound(
scenario_name.to_string(),
))?;
} else {
return Err(DotrainOrderError::ScenarioNotFound(
scenario_name.to_string(),
));
}
}
current_scenario.bindings = bindings;
}

self.config_source
.scenarios
.insert(base_scenario.to_string(), scenario);
self.update_config_source(self.config_source.clone())?;
Ok(())
}

pub fn populate_vault_ids(&mut self, deployment_name: &str) -> Result<(), DotrainOrderError> {
let mut deployment = self
.config
let deployment = self
.config_source
.deployments
.get(deployment_name)
.cloned()
.ok_or(DotrainOrderError::DeploymentNotFound(
deployment_name.to_string(),
))?
.as_ref()
.clone();
let mut order = deployment.order.as_ref().clone();
let mut order = self
.config_source
.orders
.get(&deployment.order)
.ok_or(DotrainOrderError::OrderNotFound(deployment.order.clone()))?
.clone();

let vault_id = rand::random();

let new_inputs = deployment
.order
let new_inputs = order
.inputs
.iter()
.map(|input| {
Expand All @@ -414,8 +478,7 @@ impl DotrainOrder {
input
})
.collect();
let new_outputs = deployment
.order
let new_outputs = order
.outputs
.iter()
.map(|output| {
Expand All @@ -427,13 +490,30 @@ impl DotrainOrder {

order.inputs = new_inputs;
order.outputs = new_outputs;
deployment.order = Arc::new(order);
self.config
.deployments
.insert(deployment_name.to_string(), Arc::new(deployment));
self.config_source
.orders
.insert(deployment.order.clone(), order.clone());
self.update_config_source(self.config_source.clone())?;

Ok(())
}

pub fn update_token_address(
&mut self,
token_name: String,
address: Address,
) -> Result<(), DotrainOrderError> {
let mut token = self
.config_source
.tokens
.get(&token_name)
.ok_or(DotrainOrderError::TokenNotFound(token_name.clone()))?
.clone();
token.address = address;
self.config_source.tokens.insert(token_name, token);
self.update_config_source(self.config_source.clone())?;
Ok(())
}
}

#[cfg(test)]
Expand Down
14 changes: 12 additions & 2 deletions crates/js_api/src/gui/field_values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ pub struct PairValue {
}
impl_all_wasm_traits!(PairValue);

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Tsify)]
pub struct AllFieldValuesResult {
pub binding: String,
pub value: GuiPreset,
}
impl_all_wasm_traits!(AllFieldValuesResult);

#[wasm_bindgen]
impl DotrainOrderGui {
#[wasm_bindgen(js_name = "saveFieldValue")]
Expand Down Expand Up @@ -69,10 +76,13 @@ impl DotrainOrderGui {
}

#[wasm_bindgen(js_name = "getAllFieldValues")]
pub fn get_all_field_values(&self) -> Result<Vec<GuiPreset>, GuiError> {
pub fn get_all_field_values(&self) -> Result<Vec<AllFieldValuesResult>, GuiError> {
let mut result = Vec::new();
for (binding, _) in self.field_values.iter() {
result.push(self.get_field_value(binding.clone())?);
result.push(AllFieldValuesResult {
binding: binding.clone(),
value: self.get_field_value(binding.clone())?,
});
}
Ok(result)
}
Expand Down
56 changes: 51 additions & 5 deletions crates/js_api/src/gui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ use alloy::primitives::Address;
use alloy_ethers_typecast::transaction::ReadableClientError;
use base64::{engine::general_purpose::URL_SAFE, Engine};
use flate2::{read::GzDecoder, write::GzEncoder, Compression};
use rain_orderbook_app_settings::gui::{
Gui, GuiDeployment, GuiFieldDefinition, GuiPreset, ParseGuiConfigSourceError,
use rain_orderbook_app_settings::{
gui::{Gui, GuiDeployment, GuiFieldDefinition, GuiPreset, ParseGuiConfigSourceError},
Config,
};
use rain_orderbook_bindings::{impl_all_wasm_traits, wasm_traits::prelude::*};
use rain_orderbook_common::{
Expand All @@ -18,6 +19,7 @@ use thiserror::Error;
mod deposits;
mod field_values;
mod order_operations;
mod select_tokens;
mod state_management;

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
Expand All @@ -27,6 +29,7 @@ pub struct DotrainOrderGui {
deployment: GuiDeployment,
field_values: BTreeMap<String, field_values::PairValue>,
deposits: Vec<deposits::TokenDeposit>,
select_tokens: Option<BTreeMap<String, Address>>,
onchain_token_info: BTreeMap<Address, TokenInfo>,
}
#[wasm_bindgen]
Expand All @@ -48,6 +51,13 @@ impl DotrainOrderGui {
.find(|deployment| deployment.deployment_name == deployment_name)
.ok_or(GuiError::DeploymentNotFound(deployment_name))?;

let select_tokens = gui_deployment.select_tokens.clone().map(|tokens| {
tokens
.iter()
.map(|token: &String| (token.clone(), Address::ZERO))
.collect::<BTreeMap<String, Address>>()
});

let rpc_url = gui_deployment
.deployment
.order
Expand All @@ -57,11 +67,18 @@ impl DotrainOrderGui {
.network
.rpc
.clone();
let mut onchain_token_info = BTreeMap::new();
let mut onchain_token_info: BTreeMap<Address, TokenInfo> = BTreeMap::new();
for token in gui_deployment.deposits.iter() {
if onchain_token_info.contains_key(&token.token.address) {
continue;
}

if let Some(select_tokens) = &select_tokens {
if select_tokens.contains_key(&token.token_name) {
continue;
}
}

let erc20 = ERC20::new(rpc_url.clone(), token.token.address);
let token_info = erc20.token_info(multicall_address.clone()).await?;
onchain_token_info.insert(token.token.address, token_info);
Expand All @@ -72,15 +89,40 @@ impl DotrainOrderGui {
deployment: gui_deployment.clone(),
field_values: BTreeMap::new(),
deposits: vec![],
select_tokens,
onchain_token_info,
})
}

fn refresh_gui_deployment(&mut self) -> Result<(), GuiError> {
let config = self.dotrain_order.config();
let gui_config = config.gui.clone().ok_or(GuiError::GuiConfigNotFound)?;
let gui_deployment = gui_config
.deployments
.iter()
.find(|deployment| deployment.deployment_name == self.deployment.deployment_name)
.ok_or(GuiError::DeploymentNotFound(
self.deployment.deployment_name.clone(),
))?;
self.deployment = gui_deployment.clone();
Ok(())
}

#[wasm_bindgen(js_name = "getDotrainConfig")]
pub fn get_dotrain_config(&self) -> Config {
self.dotrain_order.config().clone()
}

#[wasm_bindgen(js_name = "getGuiConfig")]
pub fn get_gui_config(&self) -> Gui {
self.dotrain_order.config().gui.clone().unwrap()
}

#[wasm_bindgen(js_name = "getCurrentDeployment")]
pub fn get_current_deployment(&self) -> GuiDeployment {
self.deployment.clone()
}

/// Get all token infos in input and output vaults
///
/// Returns a map of token address to [`TokenInfo`]
Expand Down Expand Up @@ -108,10 +150,14 @@ pub enum GuiError {
VaultIdNotFound,
#[error("Deployer not found")]
DeployerNotFound,
#[error("Token not found")]
TokenNotFound,
#[error("Token not found {0}")]
TokenNotFound(String),
#[error("Invalid preset")]
InvalidPreset,
#[error("Select tokens not set")]
SelectTokensNotSet,
#[error("Token must be selected: {0}")]
TokenMustBeSelected(String),
#[error(transparent)]
DotrainOrderError(#[from] DotrainOrderError),
#[error(transparent)]
Expand Down
Loading

0 comments on commit b956e3e

Please sign in to comment.