From 40c4356f2a0af2f6d966aad8f6a03870916a94db Mon Sep 17 00:00:00 2001 From: Matt Gabrenya Date: Wed, 24 Jan 2024 16:09:18 -0700 Subject: [PATCH] feat(common): use dotrain to split out text and frontmatter, parse contents of frontmatter as strict yaml --- Cargo.toml | 3 +- crates/common/Cargo.toml | 4 +- crates/common/src/add_order.rs | 80 +++++++++++++++++++++++----------- 3 files changed, 57 insertions(+), 30 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1f94f294d..23bbbb042 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://github.com/rainprotocol/rain.orderbook" [workspace.dependencies] alloy-ethers-typecast = { git = "https://github.com/rainlanguage/alloy-ethers-typecast", rev = "eb0e02ee40699808fb984461a920286c19a6c754" } -dotrain = { git = "https://github.com/rainlanguage/dotrain.git", rev = "b302dfa52eb1a5455d2ffb04b4fa6e7f51518021" } +dotrain = { git = "https://github.com/rainlanguage/dotrain.git", rev = "21663b09177b9ebf00cb43da7233fbdd9b63da3a" } rain_interpreter_bindings = { git = "https://github.com/rainlanguage/rain.interpreter.git", rev = "4c6b9246020e1ff86888ce85aa892f5cfe123dcb", module = "crates/bindings" } dotrain_interpreter_dispair = { git = "https://github.com/rainlanguage/rain.interpreter.git", rev = "4c6b9246020e1ff86888ce85aa892f5cfe123dcb", module = "crates/dispair" } dotrain_interpreter_parser = { git = "https://github.com/rainlanguage/rain.interpreter.git", rev = "4c6b9246020e1ff86888ce85aa892f5cfe123dcb", module = "crates/parser" } @@ -33,6 +33,7 @@ cynic = "3.4.0" chrono = "0.4.31" typeshare = "1.0.1" thiserror = "1.0.56" +strict-yaml-rust = "0.1.2" [workspace.dependencies.rain_orderbook_bindings] path = "crates/bindings" diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml index ae7b0a722..1d668114e 100644 --- a/crates/common/Cargo.toml +++ b/crates/common/Cargo.toml @@ -20,6 +20,4 @@ alloy-sol-types = { workspace = true } url = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } - -[dev-dependencies] -tempfile = { workspace = true } +strict-yaml-rust = { workspace = true } diff --git a/crates/common/src/add_order.rs b/crates/common/src/add_order.rs index efa643308..cafac1a8b 100644 --- a/crates/common/src/add_order.rs +++ b/crates/common/src/add_order.rs @@ -1,34 +1,59 @@ use alloy_primitives::Address; use anyhow::Result; -use dotrain::{parser::RainLangDocument, types::Namespace}; +use dotrain::{parser::RainDocument, types::Namespace}; use dotrain_interpreter_dispair::DISPair; use dotrain_interpreter_parser::ParserV1; use rain_interpreter_bindings::IParserV1::parseReturn; use rain_orderbook_bindings::IOrderBookV3::{addOrderCall, EvaluableConfigV3, OrderConfigV2}; use std::{convert::TryInto, fs::read_to_string, path::PathBuf}; +use strict_yaml_rust::StrictYamlLoader; pub struct AddOrderArgs { - /// Path to a .rain file - pub dotrain_path: PathBuf, + /// Body of a Dotrain file describing an addOrder call + /// File should have [strict yaml] frontmatter of the following structure + /// + /// ```yaml + /// orderbook: + /// order: + /// deployer: 0x11111111111111111111111111111111 + /// validInputs: + /// - address: 0x22222222222222222222222222222222 + /// decimals: 18 + /// vaultId: 0x1234 + /// validOutputs: + /// - address: 0x55555555555555555555555555555555 + /// decimals: 8 + /// vaultId: 0x5678 + /// ``` + pub dotrain: String, } impl AddOrderArgs { async fn try_into_call(self) -> Result { - let rainlangdoc = RainLangDocument::create(dotrain_body, Namespace::Dispair, None); - - // @todo use dotrain parser to extract frontmatter - // - parse frontmatter as yaml - // - read deployer from yaml - // - read validInputs from yaml - // - read validOutputs from yaml - + // Parse file into dotrain document + let meta_store = Arc::new(RwLock::new(Store::default())); + let raindoc = RainDocument::create(dotrain_body, meta_store); + + // Parse dotrain document frontmatter + let frontmatter_yaml = StrictYamlLoader::load_from_str(raindoc.front_matter())? + let deployer = &frontmatter_yaml[0]["orderbook"]["order"]["deployer"].parse::
()?; + let valid_inputs: Vec = &frontmatter_yaml[0]["orderbook"]["order"]["validInputs"].iter().map(|t| IO { + token: t["address"].parse::
()?, + decimals: t["decimals"].parse::()?, + vault_id: U256::from_str(t["vaultId"])?, + }).collect(); + let valid_outputs: Vec = &frontmatter_yaml[0]["orderbook"]["order"]["validOutputs"].iter().map(|t| IO { + token: t["address"].parse::
()?, + decimals: t["decimals"].parse::()?, + vault_id: U256::from_str(t["vaultId"])?, + }).collect(); + // Get DISPair addresses - let deployer_address = self.deployer.parse::
()?; - let dispair = DISPair::from_deployer(deployer_address).await?; + let dispair = DISPair::from_deployer(deployer).await?; - // Parse rainlang into bytecode + constants + // Parse rainlang text into bytecode + constants let parser: ParserV1 = dispair.into(); - let rainlang_parsed = parser.parse_text(rainlangdoc.text).await?; + let rainlang_parsed = parser.parse_text(raindoc.text()).await?; // @todo generate valid metadata including rainlangdoc.text // meta: arbitrary metadata https://github.com/rainlanguage/rain.metadata @@ -38,10 +63,10 @@ impl AddOrderArgs { Ok(addOrderCall { config: OrderConfigV2 { - validInputs: vec![], - validOutputs: vec![], + validInputs: valid_inputs, + validOutputs: valid_outputs, evaluableConfig: EvaluableConfigV3 { - deployer: deployer_address, + deployer, bytecode: rainlang_parsed.bytecode, constants: rainlang_parsed.constants, }, @@ -63,14 +88,17 @@ mod tests { fn test_add_order_args_try_into() { let dotrain_text = " --- -- validInputs: - - token: 0x0000000000000000000000000000000000000001 - decimals: 16 - vaultId: 1 -- validOutputs: - - token: 0x0000000000000000000000000000000000000002 - decimals: 16 - vaultId: 2 +orderbook: + order: + deployer: 0x11111111111111111111111111111111 + validInputs: + - token: 0x0000000000000000000000000000000000000001 + decimals: 16 + vaultId: 0x1 + validOutputs: + - token: 0x0000000000000000000000000000000000000002 + decimals: 16 + vaultId: 0x2 --- start-time: 160000, end-time: 160600,