Skip to content

Commit

Permalink
Merge branch 'main' of github.com:rainlanguage/rain.orderbook
Browse files Browse the repository at this point in the history
  • Loading branch information
thedavidmeister committed Mar 20, 2024
2 parents ff7a2eb + f27295b commit f036f52
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 68 deletions.
2 changes: 1 addition & 1 deletion crates/settings/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ impl TryFrom<ConfigSource> for Config {
.map(|(name, order)| {
Ok((
name,
Arc::new(order.try_into_order(&networks, &deployers, &orderbooks, &tokens)?),
Arc::new(order.try_into_order(&deployers, &orderbooks, &tokens)?),
))
})
.collect::<Result<HashMap<String, Arc<Order>>, ParseConfigSourceError>>()?;
Expand Down
2 changes: 0 additions & 2 deletions crates/settings/src/config_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ pub struct IOString {
pub struct OrderConfigSource {
pub inputs: Vec<IOString>,
pub outputs: Vec<IOString>,
pub network: NetworkRef,
pub deployer: Option<DeployerRef>,
pub orderbook: Option<OrderbookRef>,
}
Expand Down Expand Up @@ -234,7 +233,6 @@ orders:
outputs:
- token: dai
vault-id: 3
network: mainnet
deployer: mainDeployer
orderbook: mainnetOrderbook
Expand Down
90 changes: 47 additions & 43 deletions crates/settings/src/order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,11 @@ pub enum ParseOrderConfigSourceError {
impl OrderConfigSource {
pub fn try_into_order(
self,
networks: &HashMap<String, Arc<Network>>,
deployers: &HashMap<String, Arc<Deployer>>,
orderbooks: &HashMap<String, Arc<Orderbook>>,
tokens: &HashMap<String, Arc<Token>>,
) -> Result<Order, ParseOrderConfigSourceError> {
let network = networks
.get(&self.network)
.ok_or(ParseOrderConfigSourceError::NetworkNotFoundError(
self.network.clone(),
))
.map(Arc::clone)?;
let mut network = None;

let deployer = self
.deployer
Expand All @@ -71,10 +65,15 @@ impl OrderConfigSource {
ParseDeployerConfigSourceError::NetworkNotFoundError(deployer_name.clone()),
))
.map(|v| {
if v.network == network {
Ok(v.clone())
if let Some(n) = &network {
if v.network == *n {
Ok(v.clone())
} else {
Err(ParseOrderConfigSourceError::NetworkNotMatch)
}
} else {
Err(ParseOrderConfigSourceError::NetworkNotMatch)
network = Some(v.network.clone());
Ok(v.clone())
}
})?
})
Expand All @@ -91,10 +90,15 @@ impl OrderConfigSource {
),
))
.map(|v| {
if v.network == network {
Ok(v.clone())
if let Some(n) = &network {
if v.network == *n {
Ok(v.clone())
} else {
Err(ParseOrderConfigSourceError::NetworkNotMatch)
}
} else {
Err(ParseOrderConfigSourceError::NetworkNotMatch)
network = Some(v.network.clone());
Ok(v.clone())
}
})?
})
Expand All @@ -110,13 +114,21 @@ impl OrderConfigSource {
ParseTokenConfigSourceError::NetworkNotFoundError(input.token.clone()),
))
.map(|v| {
if v.network == network {
if let Some(n) = &network {
if v.network == *n {
Ok(OrderIO {
token: v.clone(),
vault_id: input.vault_id,
})
} else {
Err(ParseOrderConfigSourceError::NetworkNotMatch)
}
} else {
network = Some(v.network.clone());
Ok(OrderIO {
token: v.clone(),
vault_id: input.vault_id,
})
} else {
Err(ParseOrderConfigSourceError::NetworkNotMatch)
}
})?
})
Expand All @@ -132,13 +144,21 @@ impl OrderConfigSource {
ParseTokenConfigSourceError::NetworkNotFoundError(output.token.clone()),
))
.map(|v| {
if v.network == network {
if let Some(n) = &network {
if v.network == *n {
Ok(OrderIO {
token: v.clone(),
vault_id: output.vault_id,
})
} else {
Err(ParseOrderConfigSourceError::NetworkNotMatch)
}
} else {
network = Some(v.network.clone());
Ok(OrderIO {
token: v.clone(),
vault_id: output.vault_id,
})
} else {
Err(ParseOrderConfigSourceError::NetworkNotMatch)
}
})?
})
Expand All @@ -147,7 +167,9 @@ impl OrderConfigSource {
Ok(Order {
inputs,
outputs,
network,
network: network.ok_or(ParseOrderConfigSourceError::NetworkNotFoundError(
String::new(),
))?,
deployer,
orderbook,
})
Expand Down Expand Up @@ -180,7 +202,6 @@ mod tests {
tokens.insert("Token2".to_string(), token_output.clone());

let order_string = OrderConfigSource {
network: "Local Testnet".to_string(),
deployer: Some("Deployer1".to_string()),
orderbook: Some("Orderbook1".to_string()),
inputs: vec![IOString {
Expand All @@ -193,7 +214,7 @@ mod tests {
}],
};

let result = order_string.try_into_order(&networks, &deployers, &orderbooks, &tokens);
let result = order_string.try_into_order(&deployers, &orderbooks, &tokens);
assert!(result.is_ok());
let order = result.unwrap();

Expand All @@ -220,22 +241,14 @@ mod tests {

#[test]
fn test_try_into_order_network_not_found_error() {
let networks = HashMap::new(); // Empty network map

let order_string = OrderConfigSource {
network: "Nonexistent Network".to_string(),
deployer: None,
orderbook: None,
inputs: vec![],
outputs: vec![],
};

let result = order_string.try_into_order(
&networks,
&HashMap::new(),
&HashMap::new(),
&HashMap::new(),
);
let result = order_string.try_into_order(&HashMap::new(), &HashMap::new(), &HashMap::new());
assert!(matches!(
result,
Err(ParseOrderConfigSourceError::NetworkNotFoundError(_))
Expand All @@ -244,19 +257,16 @@ mod tests {

#[test]
fn test_try_into_order_deployer_not_found_error() {
let networks = HashMap::from([("Local Testnet".to_string(), mock_network())]);
let deployers = HashMap::new(); // Empty deployer map

let order_string = OrderConfigSource {
network: "Local Testnet".to_string(),
deployer: Some("Nonexistent Deployer".to_string()),
orderbook: None,
inputs: vec![],
outputs: vec![],
};

let result =
order_string.try_into_order(&networks, &deployers, &HashMap::new(), &HashMap::new());
let result = order_string.try_into_order(&deployers, &HashMap::new(), &HashMap::new());
assert!(matches!(
result,
Err(ParseOrderConfigSourceError::DeployerParseError(_))
Expand All @@ -265,19 +275,16 @@ mod tests {

#[test]
fn test_try_into_order_orderbook_not_found_error() {
let networks = HashMap::from([("Local Testnet".to_string(), mock_network())]);
let orderbooks = HashMap::new(); // Empty orderbook map

let order_string = OrderConfigSource {
network: "Local Testnet".to_string(),
deployer: None,
orderbook: Some("Nonexistent Orderbook".to_string()),
inputs: vec![],
outputs: vec![],
};

let result =
order_string.try_into_order(&networks, &HashMap::new(), &orderbooks, &HashMap::new());
let result = order_string.try_into_order(&HashMap::new(), &orderbooks, &HashMap::new());
assert!(matches!(
result,
Err(ParseOrderConfigSourceError::OrderbookParseError(_))
Expand All @@ -286,11 +293,9 @@ mod tests {

#[test]
fn test_try_into_order_token_not_found_error() {
let networks = HashMap::from([("Local Testnet".to_string(), mock_network())]);
let tokens = HashMap::new(); // Empty token map

let order_string = OrderConfigSource {
network: "Local Testnet".to_string(),
deployer: None,
orderbook: None,
inputs: vec![IOString {
Expand All @@ -300,8 +305,7 @@ mod tests {
outputs: vec![],
};

let result =
order_string.try_into_order(&networks, &HashMap::new(), &HashMap::new(), &tokens);
let result = order_string.try_into_order(&HashMap::new(), &HashMap::new(), &tokens);
assert!(matches!(
result,
Err(ParseOrderConfigSourceError::TokenParseError(_))
Expand Down
4 changes: 3 additions & 1 deletion tauri-app/src/lib/components/DropdownRadio.svelte
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
<script lang="ts" generics="T">
import { Button, Dropdown, Radio } from 'flowbite-svelte';
import { ChevronDownSolid } from 'flowbite-svelte-icons';
import { sortBy } from 'lodash';
// eslint-disable-next-line no-undef
export let options: Record<string, T> = {};
export let value: string | undefined = undefined;
let open = false;
$: value, open = false;
$: optionsSorted = sortBy(Object.entries(options), (o) => o[0]);
</script>

<Button color="alternative" class="w-full pl-2 pr-0 text-left flex justify-between overflow-hidden overflow-ellipsis">
Expand All @@ -16,7 +18,7 @@
</Button>

<Dropdown class="py-0 w-full min-w-72" bind:open>
{#each Object.entries(options) as [ref, option]}
{#each optionsSorted as [ref, option]}
<Radio bind:group={value} value={ref} class="w-full p-3 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-600">
<div class="ml-2">
<slot name="option" {option} {ref}></slot>
Expand Down
39 changes: 18 additions & 21 deletions tauri-app/src/lib/stores/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,23 @@ import { toasts } from './toasts';
import { pickBy } from 'lodash';
import { parseConfigSource } from '$lib/services/config';

const emptyConfig = {
deployments: {},
networks: {},
orderbooks: {},
orders: {},
subgraphs: {},
tokens: {},
deployers: {},
scenarios: {},
charts: {}
} as ConfigSource;

// general
export const settingsText = cachedWritableStore<string>('settings', "", (s) => s, (s) => s);
export const settingsFile = textFileStore('Orderbook Settings Yaml', ['yml', 'yaml'], get(settingsText));
export const settings = asyncDerived(settingsText, async ($settingsText): Promise<ConfigSource> => {
export const settings = asyncDerived(settingsText, async ($settingsText): Promise<ConfigSource | undefined> => {
try {
const config: ConfigSource = await parseConfigSource($settingsText);
return config;
} catch(e) {
toasts.error(e as string);
return emptyConfig;
}
}, { initial: emptyConfig });
});

// networks
export const activeNetworkRef = cachedWritableStringOptional("settings.activeNetworkRef");
export const activeNetwork = asyncDerived([settings, activeNetworkRef], async ([$settings, $activeNetworkRef]) => {
await settings.load();
return ($activeNetworkRef !== undefined && $settings.networks !== undefined) ? $settings.networks[$activeNetworkRef] : undefined;
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']);
Expand All @@ -58,16 +45,25 @@ export const orderbookAddress = derived(activeOrderbook, ($activeOrderbook) => $
export const hasRequiredSettings = derived([activeNetworkRef, activeOrderbookRef], ([$activeNetworkRef, $activeOrderbookRef]) => $activeNetworkRef !== undefined && $activeOrderbookRef !== undefined);

// When networks / orderbooks settings updated, reset active network / orderbook
settings.subscribe(async ($settings) => {
settings.subscribe(async () => {
await settings.load();
const $activeNetworkRef = get(activeNetworkRef);
const $activeOrderbookRef = get(activeOrderbookRef);
const $settings = get(settings);

if(!$settings.networks || $activeNetworkRef === undefined || !Object.keys($settings.networks).includes($activeNetworkRef)) {
if(
$settings?.networks === undefined
|| $activeNetworkRef === undefined
|| ($settings?.networks !== undefined && $activeNetworkRef !== undefined && !Object.keys($settings.networks).includes($activeNetworkRef))
) {
resetActiveNetworkRef();
}

if(!$settings.orderbooks || $activeOrderbookRef === undefined || !Object.keys($settings.orderbooks).includes($activeOrderbookRef)) {
if(
!$settings?.orderbooks === undefined
|| $activeOrderbookRef === undefined
|| ($settings?.orderbooks !== undefined && $activeOrderbookRef !== undefined && !Object.keys($settings.orderbooks).includes($activeOrderbookRef))
) {
resetActiveOrderbookRef();
}
});
Expand Down Expand Up @@ -102,8 +98,9 @@ function resetActiveOrderbookRef() {


// reset active orderbook to first available, otherwise undefined
function resetActiveNetworkRef() {
const $networks = get(settings).networks;
async function resetActiveNetworkRef() {
await settings.load();
const $networks = get(settings)?.networks;

if($networks !== undefined && Object.keys($networks).length > 0) {
activeNetworkRef.set(Object.keys($networks)[0]);
Expand Down

0 comments on commit f036f52

Please sign in to comment.