diff --git a/.github/workflows/book.yaml b/.github/workflows/book.yaml index 29e1a2aec..2321ef3c1 100644 --- a/.github/workflows/book.yaml +++ b/.github/workflows/book.yaml @@ -35,7 +35,7 @@ jobs: - name: Install rust toolchain uses: actions-rs/toolchain@v1 with: - toolchain: 1.73.0 + toolchain: 1.75.0 override: true - name: Install mdbook-katex @@ -46,4 +46,4 @@ jobs: - name: Run tests run: | cd documentation - mdbook test \ No newline at end of file + mdbook test diff --git a/Cargo.toml b/Cargo.toml index b678d4a5f..1671c72ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,6 @@ +[workspace] +members = ["crates/*", "documentation"] + [package] name = "excalibur" version = "0.2.0" @@ -9,8 +12,6 @@ authors = ["Primitive Bits, Inc."] name = "excalibur" path = "bin/src/main.rs" -[workspace] -members = ["crates/*", "documentation", "bin"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -18,10 +19,10 @@ members = ["crates/*", "documentation", "bin"] # Local bindings = { path = "./crates/bindings", version = "0.1.0" } analysis = { path = "./crates/analysis", version = "0.1.0" } -cfmm_math = { path = "./crates/cfmm_math", version = "0.1.0" } clients = { path = "./crates/clients", version = "0.1.0" } sim = { path = "./crates/sim", version = "0.1.0" } datatypes = { path = "./crates/datatypes", version = "0.1.0" } +cfmm_math = { path = "./crates/cfmm_math", version = "0.1.0" } # External arbiter-bindings = { version = "0.1.0" } @@ -48,10 +49,8 @@ alloy-rlp = "0.3" alloy-pubsub = { git = "https://github.com/alloy-rs/alloy.git", rev = "0ba6b61" } alloy-signer = { git = "https://github.com/alloy-rs/alloy.git", rev = "0ba6b61" } - reqwest = "=0.11.23" - ## Config and parsing serde = "=1.0.192" serde_json = "=1.0.108" @@ -93,14 +92,14 @@ criterion = "=0.5.1" chrono = { version = "=0.4.31", features = ["serde"] } [dependencies] -# main excalibur application -app = { path = "./crates/app", version = "0.1.0" } -sim = { path = "./crates/sim", version = "0.1.0" } +datatypes.workspace = true +clients.workspace = true +cfmm_math.workspace = true +sim.workspace = true clap = { version = "=4.4.14", features = ["derive"] } criterion.workspace = true -cfmm_math.workspace = true analysis.workspace = true tokio.workspace = true @@ -112,6 +111,68 @@ dotenv.workspace = true RustQuant.workspace = true statrs.workspace = true +# crates + + +# deps +iced = { version = "=0.10.0", features = [ + "system", + "tokio", + "lazy", + "image", + "palette", + "advanced", + "canvas", + "svg", +] } +iced_aw = { version = "=0.7.0", default-features = false, features = [ + "menu", + "icon_text", + "icons", + "spinner", + "floating_element", +] } +plotters-backend = "=0.3.5" +plotters-iced = "=0.9.0" +iced-loading-indicator = { git = "https://github.com/BB-301/iced-loading-indicator.git", rev = "a09296f" } +url = "=2.5.0" + +# workspace crates + +# revm +revm.workspace = true +revm-primitives.workspace = true + +# alloy +alloy-primitives.workspace = true +alloy-sol-types.workspace = true +alloy-providers.workspace = true +alloy-networks.workspace = true +alloy-rpc-client.workspace = true +alloy-rpc-types.workspace = true +alloy-transport-ws.workspace = true +alloy-rlp.workspace = true +alloy-pubsub.workspace = true +alloy-transport-http.workspace = true +alloy-signer.workspace = true +reqwest.workspace = true + +# workspace deps +chrono.workspace = true +arbiter-bindings.workspace = true +bindings.workspace = true +async-trait.workspace = true +reikna.workspace = true +arbiter-core.workspace = true +ethers.workspace = true +directories-next.workspace = true +plotters.workspace = true +tokio-util.workspace = true +serde.workspace = true +serde_json.workspace = true +uuid.workspace = true + + [dev-dependencies] # For book mdbook = "0.4.35" diff --git a/bin/Cargo.toml b/bin/Cargo.toml index b733c4f18..6fa1d76b7 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -8,7 +8,6 @@ authors = ["Primitive Bits, Inc."] [dependencies] # main excalibur application -app = { path = "../crates/app", version = "0.1.0" } sim = { path = "../crates/sim", version = "0.1.0" } clap = { version = "=4.4.14", features = ["derive"] } diff --git a/crates/app/src/app.rs b/bin/src/app.rs similarity index 94% rename from crates/app/src/app.rs rename to bin/src/app.rs index a44b4370f..a809b264e 100644 --- a/crates/app/src/app.rs +++ b/bin/src/app.rs @@ -63,7 +63,7 @@ pub fn app_span() -> Span { /// Root message for the Application. #[derive(Debug, Default)] -pub enum Message { +pub enum AppMessage { /// An empty message used as a default. #[default] Empty, @@ -72,7 +72,7 @@ pub enum Message { /// Exits the application immediately. QuitReady, /// All children controllers wrap their messages in View. - View(view::Message), + View(view::ViewMessage), /// Modifications to the persistent user profile. UpdateUser(UserProfileMessage), /// Switches the active "app" to the target Route. @@ -100,14 +100,14 @@ pub enum UserProfileMessage { ClearRPCs, } -pub type RootMessage = Message; -pub type RootViewMessage = view::Message; +pub type RootMessage = AppMessage; +pub type RootViewMessage = view::ViewMessage; -impl MessageWrapper for Message { - type ParentMessage = Message; +impl MessageWrapper for AppMessage { + type ParentMessage = AppMessage; } -impl From for Message { +impl From for AppMessage { fn from(message: UserProfileMessage) -> Self { Self::UpdateUser(message) } @@ -196,7 +196,7 @@ impl App { pub fn new( model: Model, client: Arc>, - ) -> (Self, Command) { + ) -> (Self, Command) { let dashboard = PortfolioRoot::new(Some(client.clone()), model.clone()).into(); let mut sidebar = Sidebar::new(); sidebar.page = view::sidebar::Page::Portfolio; @@ -207,14 +207,14 @@ impl App { windows: Windows::new(dashboard, sidebar), app_clock: AppClock::new(), }, - Command::perform(async {}, |_| Message::Load), + Command::perform(async {}, |_| AppMessage::Load), ) } /// This function is responsible for loading the sidebar and the default /// screen. It is called when a user starts the application, after the /// new() function. - pub fn load(&mut self) -> Command { + pub fn load(&mut self) -> Command { // Load the sidebar and the current window. let cmds = vec![ self.windows.sidebar.load().map(|x| x.into()), @@ -245,18 +245,18 @@ impl App { /// /// This function will panic if the `Message::ModelSyncResult` variant is /// used and the result is an error. - pub fn update(&mut self, message: Message) -> Command { + pub fn update(&mut self, message: AppMessage) -> Command { // Handle the update clock first. self.app_clock.update(); // Handle the update. app_span().in_scope(|| match message { - Message::Load => self.load(), - Message::QuitReady => { + AppMessage::Load => self.load(), + AppMessage::QuitReady => { // Caught by the lib.rs and exits the application. Command::none() } - Message::ModelSyncResult(Ok(model)) => { + AppMessage::ModelSyncResult(Ok(model)) => { // Update the root model. self.model = model.clone(); @@ -264,17 +264,17 @@ impl App { // todo: remove side effects, @alex what did you mean by this? self.windows .screen - .update(Message::ModelSyncResult(Ok(model))) + .update(AppMessage::ModelSyncResult(Ok(model))) } - Message::ModelSyncResult(Err(e)) => { + AppMessage::ModelSyncResult(Err(e)) => { tracing::error!( "Critical failure - sync model threw an error while updating: {:?}", e ); Command::none() } - Message::UpdateUser(msg) => self.update_user(msg), - Message::View(view::Message::Root(msg)) => match msg { + AppMessage::UpdateUser(msg) => self.update_user(msg), + AppMessage::View(view::ViewMessage::Root(msg)) => match msg { view::RootMessage::ModelSyncRequest => self.sync_model(), view::RootMessage::Route(route) => self.switch_window(&route), view::RootMessage::CopyToClipboard(contents) => iced::clipboard::write(contents), @@ -285,7 +285,7 @@ impl App { tracing::debug!("Confirming exit"); self.windows .screen - .update(Message::View(view::Message::Root(msg))) + .update(AppMessage::View(view::ViewMessage::Root(msg))) .map(|x| x) } }, @@ -306,13 +306,13 @@ impl App { /// /// # Returns /// * `Element` - The view of the application. - pub fn view(&self) -> Element { + pub fn view(&self) -> Element { view::app_layout( &self.app_clock, &self.windows.sidebar, self.windows.screen.view(), ) - .map(Message::View) + .map(AppMessage::View) } /// Returns the subscription of the current screen. @@ -324,7 +324,7 @@ impl App { /// /// # Returns /// * `Subscription` - The subscription of the current screen. - pub fn subscription(&self) -> Subscription { + pub fn subscription(&self) -> Subscription { self.windows.screen.subscription() } @@ -340,7 +340,7 @@ impl App { /// # Returns /// * `Command` - A batch of commands to be executed during the /// exit process. - pub fn exit(&mut self) -> Command { + pub fn exit(&mut self) -> Command { // Save the profile to disk. let result = self.model.save(); match result { @@ -360,7 +360,7 @@ impl App { save_snapshot(self.client.clone()), UserProfileMessage::SaveAnvilSnapshot, ) - .map(Message::UpdateUser); + .map(AppMessage::UpdateUser); commands.push(cmd); } @@ -378,7 +378,7 @@ impl App { /// # Returns /// * `Command` - A command containing the result of the model /// synchronization. - fn sync_model(&mut self) -> Command { + fn sync_model(&mut self) -> Command { let model = self.model.clone(); let provider = self.client.get_client(); Command::perform( @@ -387,7 +387,7 @@ impl App { model.update(provider).await?; Ok(model) }, - Message::ModelSyncResult, + AppMessage::ModelSyncResult, ) } @@ -410,7 +410,7 @@ impl App { /// * `Command` - A command to sync the RPCs after updating the /// user profile. // #[allow(unused_assignments)] - fn update_user(&mut self, message: UserProfileMessage) -> Command { + fn update_user(&mut self, message: UserProfileMessage) -> Command { let model = &mut self.model; match message { UserProfileMessage::SaveAnvilSnapshot(snapshot) => { @@ -428,7 +428,7 @@ impl App { } // Exits the application after saving the anvil snapshot. - return Command::perform(async {}, |_| Message::QuitReady); + return Command::perform(async {}, |_| AppMessage::QuitReady); } UserProfileMessage::AddAddress(name, address, category) => { model.user.contacts.add( @@ -468,7 +468,7 @@ impl App { let rpcs = model.user.rpcs.clone(); Command::perform(async {}, move |_| { - view::Message::Settings(settings::Message::Rpc(settings::rpc::Message::Sync(rpcs))) + view::ViewMessage::Settings(settings::Message::Rpc(settings::rpc::Message::Sync(rpcs))) }) .map(|x| x.into()) } @@ -484,7 +484,7 @@ impl App { /// window and adds it to the command vector. Finally, it batches all /// the commands in the vector and returns them. #[allow(unreachable_patterns)] - fn switch_window(&mut self, navigate_to: &view::sidebar::Route) -> Command { + fn switch_window(&mut self, navigate_to: &view::sidebar::Route) -> Command { let mut cmds = Vec::new(); let exit_cmd = self.windows.screen.exit(); @@ -542,6 +542,12 @@ pub struct Update { pub duration: Duration, } +impl Default for AppClock { + fn default() -> Self { + Self::new() + } +} + impl AppClock { /// Constructor for AppClock. pub fn new() -> Self { diff --git a/crates/app/src/components/button.rs b/bin/src/components/button.rs similarity index 100% rename from crates/app/src/components/button.rs rename to bin/src/components/button.rs diff --git a/crates/app/src/components/chart/mod.rs b/bin/src/components/chart/mod.rs similarity index 100% rename from crates/app/src/components/chart/mod.rs rename to bin/src/components/chart/mod.rs diff --git a/crates/app/src/components/input.rs b/bin/src/components/input.rs similarity index 100% rename from crates/app/src/components/input.rs rename to bin/src/components/input.rs diff --git a/crates/app/src/components/logos.rs b/bin/src/components/logos.rs similarity index 90% rename from crates/app/src/components/logos.rs rename to bin/src/components/logos.rs index b9f31085d..dd35711a6 100644 --- a/crates/app/src/components/logos.rs +++ b/bin/src/components/logos.rs @@ -13,22 +13,22 @@ use crate::components::styles::MINT_500; /// Placeholder for the Excalibur logo. #[allow(dead_code)] -const EXCALIBUR_LOGO: &[u8] = include_bytes!("../../../../assets/logos/excalibur_logo.png"); +const EXCALIBUR_LOGO: &[u8] = include_bytes!("../../../assets/logos/excalibur_logo.png"); #[allow(dead_code)] pub fn excalibur_logo() -> icon::Icon { icon::from_file_data(EXCALIBUR_LOGO, None).unwrap() } -const EXCALIBUR_LOGO_2: &[u8] = include_bytes!("../../../../assets/logos/daggeremoji.png"); +const EXCALIBUR_LOGO_2: &[u8] = include_bytes!("../../../assets/logos/daggeremoji.png"); pub fn excalibur_logo_2() -> icon::Icon { icon::from_file_data(EXCALIBUR_LOGO_2, None).unwrap() } -const ETHER_LOGO: &[u8] = include_bytes!("../../../../assets/logos/ethtokenicon.svg"); -const USDC_LOGO: &[u8] = include_bytes!("../../../../assets/logos/usdcvector.svg"); -const LP_LOGO: &[u8] = include_bytes!("../../../../assets/logos/ethusdclp.svg"); +const ETHER_LOGO: &[u8] = include_bytes!("../../../assets/logos/ethtokenicon.svg"); +const USDC_LOGO: &[u8] = include_bytes!("../../../assets/logos/usdcvector.svg"); +const LP_LOGO: &[u8] = include_bytes!("../../../assets/logos/ethusdclp.svg"); pub fn ether_logo() -> iced::widget::svg::Handle { svg::Handle::from_memory(ETHER_LOGO) diff --git a/crates/app/src/components/mod.rs b/bin/src/components/mod.rs similarity index 97% rename from crates/app/src/components/mod.rs rename to bin/src/components/mod.rs index c461d7767..8501c8f9f 100644 --- a/crates/app/src/components/mod.rs +++ b/bin/src/components/mod.rs @@ -35,7 +35,7 @@ use self::{ tables::{builder::TableBuilder, cells::CellBuilder, columns::ColumnBuilder, rows::RowBuilder}, }; // These components should return View messages. -use super::{view::Message, *}; +use super::{view::ViewMessage, *}; /// Renders a tab-like button #[allow(dead_code)] @@ -94,10 +94,10 @@ where .align_items(alignment::Alignment::Center) } #[allow(dead_code)] -pub fn copyable_text<'a, E: Into>>( +pub fn copyable_text<'a, E: Into>>( label: E, value: String, -) -> iced::widget::Button<'a, view::Message> { +) -> iced::widget::Button<'a, view::ViewMessage> { let copy_button = button(label) .style( CustomButtonStyle::text(&iced::Theme::Dark) @@ -110,7 +110,7 @@ pub fn copyable_text<'a, E: Into>>( .as_custom(), ) .padding(0) - .on_press(view::Message::Root(view::RootMessage::CopyToClipboard( + .on_press(view::ViewMessage::Root(view::RootMessage::CopyToClipboard( value, ))); copy_button @@ -446,7 +446,7 @@ where pub fn custom_icon_button<'a>( icon: icons::Icon, font_size: u16, -) -> iced::widget::Button<'a, Message> { +) -> iced::widget::Button<'a, ViewMessage> { let content = text(icon_to_char(icon)) .font(ICON_FONT) .size(font_size) @@ -488,12 +488,12 @@ where } } -impl Default for NavigationStep { +impl Default for NavigationStep { fn default() -> Self { Self { icon: Icon::Check, cta: "Default".to_string(), - on_press: Message::default(), + on_press: ViewMessage::default(), active: false, disabled: false, } diff --git a/crates/app/src/components/progress.rs b/bin/src/components/progress.rs similarity index 100% rename from crates/app/src/components/progress.rs rename to bin/src/components/progress.rs diff --git a/crates/app/src/components/select.rs b/bin/src/components/select.rs similarity index 100% rename from crates/app/src/components/select.rs rename to bin/src/components/select.rs diff --git a/crates/app/src/components/styles.rs b/bin/src/components/styles.rs similarity index 100% rename from crates/app/src/components/styles.rs rename to bin/src/components/styles.rs diff --git a/crates/app/src/components/system.rs b/bin/src/components/system.rs similarity index 100% rename from crates/app/src/components/system.rs rename to bin/src/components/system.rs diff --git a/crates/app/src/components/tables/builder.rs b/bin/src/components/tables/builder.rs similarity index 89% rename from crates/app/src/components/tables/builder.rs rename to bin/src/components/tables/builder.rs index 2dc21f4c8..00ed34bd9 100644 --- a/crates/app/src/components/tables/builder.rs +++ b/bin/src/components/tables/builder.rs @@ -2,11 +2,11 @@ use super::*; -pub struct TableBuilder +pub struct TableBuilder where - Message: 'static + Default, + Msg: 'static + Default, { - columns: Vec>, + columns: Vec>, spacing_col: Option, spacing_row: Option, spacing_cell: Option, @@ -16,18 +16,18 @@ where padding_cell_internal: Option, } -impl Default for TableBuilder +impl Default for TableBuilder where - Message: 'static + Default, + Msg: 'static + Default, { fn default() -> Self { Self::new() } } -impl TableBuilder +impl TableBuilder where - Message: 'static + Default, + Msg: 'static + Default, { pub fn new() -> Self { Self { @@ -89,18 +89,18 @@ where self } - pub fn column(mut self, column: ColumnBuilder) -> Self { + pub fn column(mut self, column: ColumnBuilder) -> Self { self.columns.push(column); self } - pub fn build<'a>(self) -> Row<'a, Message> { + pub fn build<'a>(self) -> Row<'a, Msg> { let mut table = Row::new(); for column in self.columns { // Specifies the spacing between rows in a column. // And the spacing between cells in a row. - let column: Column<'static, Message> = column + let column: Column<'static, Msg> = column .spacing(self.spacing_row.unwrap_or_default()) .spacing_cell(self.spacing_cell.unwrap_or_default()) .padding_row(self.padding_row.unwrap_or_default()) diff --git a/crates/app/src/components/tables/cells/input.rs b/bin/src/components/tables/cells/input.rs similarity index 100% rename from crates/app/src/components/tables/cells/input.rs rename to bin/src/components/tables/cells/input.rs diff --git a/crates/app/src/components/tables/cells/mod.rs b/bin/src/components/tables/cells/mod.rs similarity index 100% rename from crates/app/src/components/tables/cells/mod.rs rename to bin/src/components/tables/cells/mod.rs diff --git a/crates/app/src/components/tables/cells/select.rs b/bin/src/components/tables/cells/select.rs similarity index 100% rename from crates/app/src/components/tables/cells/select.rs rename to bin/src/components/tables/cells/select.rs diff --git a/crates/app/src/components/tables/cells/toggle.rs b/bin/src/components/tables/cells/toggle.rs similarity index 100% rename from crates/app/src/components/tables/cells/toggle.rs rename to bin/src/components/tables/cells/toggle.rs diff --git a/crates/app/src/components/tables/columns/mod.rs b/bin/src/components/tables/columns/mod.rs similarity index 100% rename from crates/app/src/components/tables/columns/mod.rs rename to bin/src/components/tables/columns/mod.rs diff --git a/crates/app/src/components/tables/mod.rs b/bin/src/components/tables/mod.rs similarity index 100% rename from crates/app/src/components/tables/mod.rs rename to bin/src/components/tables/mod.rs diff --git a/crates/app/src/components/tables/rows/mod.rs b/bin/src/components/tables/rows/mod.rs similarity index 100% rename from crates/app/src/components/tables/rows/mod.rs rename to bin/src/components/tables/rows/mod.rs diff --git a/crates/app/src/controller/empty.rs b/bin/src/controller/empty.rs similarity index 83% rename from crates/app/src/controller/empty.rs rename to bin/src/controller/empty.rs index 198ff77f5..5520fd61a 100644 --- a/crates/app/src/controller/empty.rs +++ b/bin/src/controller/empty.rs @@ -7,6 +7,12 @@ use crate::components::system::label; pub struct EmptyScreen; +impl Default for EmptyScreen { + fn default() -> Self { + Self::new() + } +} + impl EmptyScreen { pub fn new() -> Self { Self @@ -20,8 +26,8 @@ impl From for Screen { } impl State for EmptyScreen { - type AppMessage = app::Message; - type ViewMessage = view::Message; + type AppMessage = app::AppMessage; + type ViewMessage = view::ViewMessage; fn load(&self) -> Command { Command::none() diff --git a/crates/app/src/controller/exit.rs b/bin/src/controller/exit.rs similarity index 85% rename from crates/app/src/controller/exit.rs rename to bin/src/controller/exit.rs index 7302c0bb8..70bc92d96 100644 --- a/crates/app/src/controller/exit.rs +++ b/bin/src/controller/exit.rs @@ -22,8 +22,8 @@ impl From for Screen { } impl State for ExitScreen { - type AppMessage = app::Message; - type ViewMessage = view::Message; + type AppMessage = app::AppMessage; + type ViewMessage = view::ViewMessage; fn load(&self) -> Command { Command::none() @@ -31,11 +31,13 @@ impl State for ExitScreen { fn update(&mut self, message: Self::AppMessage) -> Command { match message { - Self::AppMessage::View(view::Message::Root(message)) => match message { + Self::AppMessage::View(view::ViewMessage::Root(message)) => match message { view::RootMessage::ConfirmExit => { self.show_confirm = false; Command::perform(async { Ok::<(), ()>(()) }, |_| { - Self::AppMessage::View(view::Message::Root(view::RootMessage::SaveAndExit)) + Self::AppMessage::View(view::ViewMessage::Root( + view::RootMessage::SaveAndExit, + )) }) } view::RootMessage::SaveAndExit => { diff --git a/crates/app/src/controller/mod.rs b/bin/src/controller/mod.rs similarity index 98% rename from crates/app/src/controller/mod.rs rename to bin/src/controller/mod.rs index 04a9ce015..fc985872a 100644 --- a/crates/app/src/controller/mod.rs +++ b/bin/src/controller/mod.rs @@ -144,7 +144,7 @@ pub trait State { /// Alias for the type of screen. /// Windows are like tabs in a browser. -type WindowScreen = dyn State; +type WindowScreen = dyn State; /// Wraps anything that implements WindowScreen type of State trait into an /// easier to use struct. diff --git a/crates/app/src/controller/portfolio/mod.rs b/bin/src/controller/portfolio/mod.rs similarity index 89% rename from crates/app/src/controller/portfolio/mod.rs rename to bin/src/controller/portfolio/mod.rs index 708629d3f..a9a62141d 100644 --- a/crates/app/src/controller/portfolio/mod.rs +++ b/bin/src/controller/portfolio/mod.rs @@ -25,11 +25,11 @@ pub enum Page { impl From for RootMessage { fn from(message: Message) -> Self { - Self::View(view::Message::Portfolio(message)) + Self::View(view::ViewMessage::Portfolio(message)) } } -impl From for view::Message { +impl From for view::ViewMessage { fn from(message: Message) -> Self { Self::Portfolio(message) } @@ -61,8 +61,8 @@ impl From for Screen { } impl State for PortfolioRoot { - type AppMessage = app::Message; - type ViewMessage = view::Message; + type AppMessage = app::AppMessage; + type ViewMessage = view::ViewMessage; fn load(&self) -> Command { self.monolithic @@ -72,15 +72,17 @@ impl State for PortfolioRoot { fn update(&mut self, message: Self::AppMessage) -> Command { match message { - Self::AppMessage::View(view::Message::Portfolio(message)) => match message { + Self::AppMessage::View(view::ViewMessage::Portfolio(message)) => match message { Message::SyncModel => Command::perform(async {}, |_| { Self::ViewMessage::Root(view::RootMessage::ModelSyncRequest) }) .map(Self::AppMessage::View), Message::Empty => Command::none(), Message::Monolithic(monolithic::Message::SyncModel(_block)) => { - Command::perform(async {}, |_| view::Message::Portfolio(Message::SyncModel)) - .map(Self::AppMessage::View) + Command::perform(async {}, |_| { + view::ViewMessage::Portfolio(Message::SyncModel) + }) + .map(Self::AppMessage::View) } Message::Monolithic(message) => self .monolithic diff --git a/crates/app/src/controller/portfolio/monolithic/create.rs b/bin/src/controller/portfolio/monolithic/create.rs similarity index 100% rename from crates/app/src/controller/portfolio/monolithic/create.rs rename to bin/src/controller/portfolio/monolithic/create.rs diff --git a/crates/app/src/controller/portfolio/monolithic/inventory.rs b/bin/src/controller/portfolio/monolithic/inventory.rs similarity index 100% rename from crates/app/src/controller/portfolio/monolithic/inventory.rs rename to bin/src/controller/portfolio/monolithic/inventory.rs diff --git a/crates/app/src/controller/portfolio/monolithic/metrics.rs b/bin/src/controller/portfolio/monolithic/metrics.rs similarity index 100% rename from crates/app/src/controller/portfolio/monolithic/metrics.rs rename to bin/src/controller/portfolio/monolithic/metrics.rs diff --git a/crates/app/src/controller/portfolio/monolithic/mod.rs b/bin/src/controller/portfolio/monolithic/mod.rs similarity index 100% rename from crates/app/src/controller/portfolio/monolithic/mod.rs rename to bin/src/controller/portfolio/monolithic/mod.rs diff --git a/crates/app/src/controller/portfolio/monolithic/tx_history.rs b/bin/src/controller/portfolio/monolithic/tx_history.rs similarity index 100% rename from crates/app/src/controller/portfolio/monolithic/tx_history.rs rename to bin/src/controller/portfolio/monolithic/tx_history.rs diff --git a/crates/app/src/controller/portfolio/monolithic/view.rs b/bin/src/controller/portfolio/monolithic/view.rs similarity index 100% rename from crates/app/src/controller/portfolio/monolithic/view.rs rename to bin/src/controller/portfolio/monolithic/view.rs diff --git a/crates/app/src/controller/settings/contacts.rs b/bin/src/controller/settings/contacts.rs similarity index 92% rename from crates/app/src/controller/settings/contacts.rs rename to bin/src/controller/settings/contacts.rs index 9aa45b436..fe03e31d9 100644 --- a/crates/app/src/controller/settings/contacts.rs +++ b/bin/src/controller/settings/contacts.rs @@ -25,6 +25,12 @@ impl From for ::ParentMessage { pub struct ContactsManagement; +impl Default for ContactsManagement { + fn default() -> Self { + Self::new() + } +} + impl ContactsManagement { pub fn new() -> Self { Self diff --git a/crates/app/src/controller/settings/mod.rs b/bin/src/controller/settings/mod.rs similarity index 96% rename from crates/app/src/controller/settings/mod.rs rename to bin/src/controller/settings/mod.rs index 873390482..4c3ba2aae 100644 --- a/crates/app/src/controller/settings/mod.rs +++ b/bin/src/controller/settings/mod.rs @@ -36,7 +36,7 @@ impl MessageWrapperView for Message { // normal message which are not clone impl From for ::ParentMessage { fn from(message: Message) -> Self { - Self::View(view::Message::Settings(message)) + Self::View(view::ViewMessage::Settings(message)) } } @@ -113,7 +113,7 @@ impl State for SettingsScreen { } fn update(&mut self, message: Self::AppMessage) -> Command { - if let Self::AppMessage::View(view::Message::Settings(message)) = message { + if let Self::AppMessage::View(view::ViewMessage::Settings(message)) = message { match message { Message::Rpc(message) => match message { rpc::Message::Delete => { @@ -161,7 +161,7 @@ impl State for SettingsScreen { tracing::error!("Failed to submit new RPC packet: {:?}", e); Command::perform(async {}, move |_| { - view::Message::Settings(settings::Message::Rpc( + view::ViewMessage::Settings(settings::Message::Rpc( settings::rpc::Message::Feedback(anyhow!(e).into()), )) }) diff --git a/crates/app/src/controller/settings/rpc.rs b/bin/src/controller/settings/rpc.rs similarity index 100% rename from crates/app/src/controller/settings/rpc.rs rename to bin/src/controller/settings/rpc.rs diff --git a/crates/app/src/controller/settings/signers.rs b/bin/src/controller/settings/signers.rs similarity index 98% rename from crates/app/src/controller/settings/signers.rs rename to bin/src/controller/settings/signers.rs index b81c9eed4..2c2a14ba1 100644 --- a/crates/app/src/controller/settings/signers.rs +++ b/bin/src/controller/settings/signers.rs @@ -50,6 +50,12 @@ pub async fn connect_to_ledger() -> Result<(Arc, Address), Arc Self { + Self::new() + } +} + impl SignerManagement { pub fn new() -> Self { Self::NotConnected diff --git a/crates/app/src/loader.rs b/bin/src/loader.rs similarity index 93% rename from crates/app/src/loader.rs rename to bin/src/loader.rs index 2df6d54ad..0e32f1ea1 100644 --- a/crates/app/src/loader.rs +++ b/bin/src/loader.rs @@ -14,7 +14,6 @@ use iced::{ use iced_aw::graphics::icons::ICON_FONT_BYTES; use sim::from_ethers_address; -use super::{middleware::*, model::contacts, *}; use crate::{ app::AnvilSave, components::{ @@ -28,11 +27,17 @@ use crate::{ type LoadResult = anyhow::Result<(Model, Arc>), anyhow::Error>; +use self::{ + middleware::{start_anvil, ExcaliburMiddleware}, + model::contacts, +}; +use super::*; + #[derive(Debug)] -pub enum Message { +pub enum LoaderMessage { View, Tick, - Loaded(super::Flags), + Loaded(Flags), Connected, LoadingFailed, Ready(LoadResult), @@ -77,7 +82,7 @@ pub fn load_user_data() -> anyhow::Result { /// Contracts that we start up the client with /// ORDER MATTERS HERE WHICH IS VERY BIG BAD. -pub const CONTRACT_NAMES: [&str; 6] = [ +const CONTRACT_NAMES: [&str; 6] = [ "protocol", "strategy", "token_x", "token_y", "lex", "solver", ]; @@ -85,7 +90,7 @@ pub const CONTRACT_NAMES: [&str; 6] = [ /// On load, the application will emit the Ready message to the root /// application, which will then open the App. #[tracing::instrument(level = "debug")] -pub async fn load_app(flags: super::Flags) -> LoadResult { +pub async fn load_app(flags: Flags) -> LoadResult { // Load the user's save or create a new one. let mut model = load_user_data()?; @@ -352,8 +357,7 @@ pub async fn connect_to_server() -> anyhow::Result<()> { Ok(()) } -pub const DAGGER_SQUARE_FONT_BYTES: &[u8] = - include_bytes!("../../../assets/fonts/DAGGERSQUARE.otf"); +pub const DAGGER_SQUARE_FONT_BYTES: &[u8] = include_bytes!("../../assets/fonts/DAGGERSQUARE.otf"); impl Loader { /// Creates a new Loader with the given flags and returns a tuple of the @@ -366,7 +370,7 @@ impl Loader { /// If any of these operations fail, a LoadingFailed message is returned. /// If all operations are successful, a tuple of the Loader and a Command is /// returned. - pub fn new(flags: super::Flags) -> (Self, Command) { + pub fn new(flags: Flags) -> (Self, Command) { let max_load_seconds = 5.0; let ticks_per_s = 40.0; @@ -387,36 +391,36 @@ impl Loader { Command::perform(connect_to_server(), |res| { if let Err(e) = res { tracing::error!("Failed to connect to server: {:?}", e); - return Message::LoadingFailed; + return LoaderMessage::LoadingFailed; } - Message::Connected + LoaderMessage::Connected }), font::load(ICON_FONT_BYTES).map(move |res| { if let Err(e) = res { tracing::error!("Failed to load icon font: {:?}", e); - return Message::LoadingFailed; + return LoaderMessage::LoadingFailed; } - Message::IconFontLoaded + LoaderMessage::IconFontLoaded }), font::load(DAGGER_SQUARE_FONT_BYTES).map(move |res| { if let Err(e) = res { tracing::error!("Failed to load icon font: {:?}", e); - return Message::LoadingFailed; + return LoaderMessage::LoadingFailed; } - Message::BrandFontLoaded + LoaderMessage::BrandFontLoaded }), - Command::perform(async {}, move |_| Message::Loaded(flags)), + Command::perform(async {}, move |_| LoaderMessage::Loaded(flags)), ]), ) } /// Takes in the application flags and returns a command to load the /// application. The loading process is performed asynchronously. - fn load(&mut self, flags: super::Flags) -> Command { - Command::perform(load_app(flags), Message::Ready) + fn load(&mut self, flags: Flags) -> Command { + Command::perform(load_app(flags), LoaderMessage::Ready) } /// Updates the state of the loader based on the received message. @@ -424,11 +428,11 @@ impl Loader { /// loader's state accordingly. For example, it updates the progress of /// the loading process, handles connection status, and initiates the /// loading process. - pub fn update(&mut self, message: Message) -> Command { + pub fn update(&mut self, message: LoaderMessage) -> Command { self.logo.cache.clear(); match message { - Message::Tick => { + LoaderMessage::Tick => { self.feedback = self.get_progress_feedback(); if !self.screen_open { @@ -441,12 +445,12 @@ impl Loader { Command::none() } - Message::Connected => { + LoaderMessage::Connected => { self.screen_open = true; self.load_ticks = 0.0; Command::none() } - Message::Loaded(flags) => self.load(flags), + LoaderMessage::Loaded(flags) => self.load(flags), _ => Command::none(), } } @@ -476,7 +480,7 @@ impl Loader { /// symbols. The symbol changes with each update of the progress bar. /// The function also displays a feedback message that corresponds to the /// current stage of the loading process. - pub fn view(&self) -> Element { + pub fn view(&self) -> Element { let all_symbols = GREEK_SYMBOLS .iter() .chain(CURRENCY_SYMBOLS.iter()) @@ -527,8 +531,8 @@ impl Loader { } // Every 25ms update the progress bar by 0.001. - pub fn subscription(&self) -> Subscription { - iced::time::every(std::time::Duration::from_millis(25)).map(|_| Message::Tick) + pub fn subscription(&self) -> Subscription { + iced::time::every(std::time::Duration::from_millis(25)).map(|_| LoaderMessage::Tick) } } diff --git a/bin/src/main.rs b/bin/src/main.rs index 0f23666dd..fea232f0e 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -1,6 +1,49 @@ +//! Building the Excalibur application, laws, rules, and axioms. +//! +//! We can break rules, find loopholes in laws, but cannot avoid axioms. +//! +//! +//! # Axioms +//! - Models handle data. Views handle presentation. Controllers manage user +//! input, models, and views. +//! - Models and views do not communicate directly. +//! - Data flows in one direction, starting at the model, and ending at the +//! view. +//! +//! # Rules +//! - Switching to new controllers/screens/anything being rendered should +//! offload as much logic as possible from `new` to a dedicated `load`. +//! - Add more rules! +use ethers::prelude::*; +use iced::{ + alignment, + event::Event, + executor, + theme::Palette, + widget::{button, container, scrollable, text, Column, Row, Text}, + window, Application, Command, Element, Length, Settings, Subscription, Theme, +}; + +pub mod app; +mod components; +mod controller; +mod loader; +mod middleware; +mod model; +mod tracer; +mod view; + +use std::sync::Arc; + use anyhow::Result; +use app::{App, AppMessage}; use clap::{ArgAction, Parser, Subcommand}; +use components::{system::ExcaliburTheme, *}; +use controller::*; use dotenv::dotenv; +use loader::{Loader, LoaderMessage}; +use model::Model; +use styles::*; #[derive(Parser)] #[clap(name = "Excalibur")] @@ -91,8 +134,291 @@ fn main() -> Result<()> { match &args.command { Some(Commands::Simulate { config_path }) => sim::run(config_path, args.verbose)?, Some(Commands::Analyze) => todo!(), - Some(Commands::Ui) => app::run(args.dev)?, - None => app::run(args.dev)?, + Some(Commands::Ui) => run(args.dev)?, + None => run(args.dev)?, } Ok(()) } + +/// The MVP struct represents the Model-View-Presenter pattern used in this +/// application. It contains the state of the application and a tracer for +/// debugging. The state can be either the application itself or a loader. +/// The MVP struct also implements the Application trait from the iced library. +/// This is the outermost layer of the application. +pub struct MVP { + state: State, + #[allow(dead_code)] + tracer: tracer::Tracer, +} +/// The `State` enum represents the current state of the application. +/// It can be either `App` when the application is running or `Loader` when the +/// application is loading. The state should only be in the loader state when +/// the application is starting up in the beginning. +enum State { + App(App), + Loader(Loader), +} + +/// The `Message` enum represents the different types of messages that can be +/// sent within the application. It can be either `Load` when the application is +/// loading, `Update` when the application is updating, `Event` when an event +/// occurs, `Quit` when the application is quitting, or `ForceQuit` when the +/// application is forced to quit. +#[derive(Debug)] +pub enum Message { + Load(LoaderMessage), + Update(AppMessage), + Event(Event), + Quit, + ForceQuit, +} + +/// The `Flags` struct represents the flags that can be passed to the +/// application. It contains a single flag `dev_mode` which indicates whether +/// the application is running in development mode. +#[derive(Debug, Clone, Copy)] +pub struct Flags { + pub dev_mode: bool, +} + +/// The `Application` trait implementation for the `MVP` struct. +/// This trait provides the necessary types for the application to run. +/// `Message` is the type of messages that can be sent within the application. +/// `Theme` is the type of theme used in the application. +/// `Executor` is the type of executor used to run the application. +/// `Flags` is the type of flags that can be passed to the application. +impl Application for MVP { + type Message = Message; + type Theme = Theme; + type Executor = executor::Default; + type Flags = Flags; + + /// Creates a new instance of the MVP struct. + /// + /// This function takes a Flags struct as an argument and returns a tuple + /// containing an MVP struct and a Command. The Flags struct contains a + /// single flag `dev_mode` which indicates whether the application is + /// running in development mode. If the `dev_mode` flag is set, the + /// "DEV_MODE" environment variable is also set to "true". + /// + /// The function initializes the application with the Loader state and a + /// Load message. + /// + /// # Arguments + /// + /// * `flags: Flags` - The flags that can be passed to the application. + /// + /// # Returns + /// + /// * `(MVP, Command)` - A tuple containing an MVP struct and a + /// Command. + fn new(flags: Flags) -> (MVP, Command) { + let tracer = tracer::setup_with_channel(); + if flags.dev_mode { + std::env::set_var("DEV_MODE", "true"); + } + + let (loader, command) = Loader::new(flags); + let state = State::Loader(loader); + + (MVP { state, tracer }, command.map(Message::Load)) + } + + /// Returns the title of the application. + /// + /// This function takes no arguments and returns a String. + /// The title of the application depends on the current state of the + /// application. If the application is in the Loader state, the title is + /// "Loading Excalibur". If the application is in the App state, the + /// title is "Excalibur". + /// + /// # Returns + /// + /// * `String` - The title of the application. + fn title(&self) -> String { + match &self.state { + State::Loader(_) => String::from("Loading Excalibur"), + State::App(_) => String::from("Excalibur"), + } + } + + /// Updates the state of the application based on the incoming message. + /// + /// This function takes a mutable reference to the application and a + /// message. It updates the state of the application based on the + /// message and returns a command. + /// + /// The function handles different types of messages including ForceQuit, + /// Quit, Load, and Update. It also handles the transition from the + /// Loader state to the App state. + /// + /// # Arguments + /// + /// * `&mut self` - A mutable reference to the application. + /// * `message: Self::Message` - The incoming message. + /// + /// # Returns + /// + /// * `Command` - The command to be executed after the state + /// update. + fn update(&mut self, message: Self::Message) -> Command { + match (&mut self.state, message) { + (_, Message::ForceQuit) => window::close(), + (_, Message::Quit) + | ( + _, + Message::Event(iced::event::Event::Window(iced::window::Event::CloseRequested)), + ) => { + let state_cmd = match self.state { + State::App(ref mut app) => app.exit().map(Message::Update), + // todo: handle specific closure logic for the loading screen. + _ => Command::perform(async {}, |()| Message::ForceQuit), + }; + + Command::batch(vec![state_cmd]) + } + (State::Loader(l), Message::Load(msg)) => match msg { + // 3. Got the message from the loader we are ready to go! + loader::LoaderMessage::Ready(Ok((model, client))) => { + // 4. Create our app and move to the app state. + let (app, command) = App::new(model, client); + self.state = State::App(app); + + // 5. Get to the next branch. + command.map(Message::Update) + } + loader::LoaderMessage::Ready(Err(error_message)) => { + tracing::error!("Failed to load app: {}", error_message); + Command::none() + } + loader::LoaderMessage::Quit => Command::perform(async {}, |()| Message::ForceQuit), + // 2. Loader emits the Load message, update the loader state. + _ => l.update(msg).map(Message::Load), + }, + (State::App(app), Message::Update(msg)) => { + if let app::AppMessage::QuitReady = msg { + return Command::perform(async {}, |()| Message::ForceQuit); + } + // 6. Arrived at main application loop. + // note: application loop is by mapping the result of update with Update + // message. + app.update(msg).map(Message::Update) + } + _ => Command::none(), + } + } + + /// The `view` function is responsible for rendering the current state of + /// the application. It matches on the current state and calls the + /// corresponding `view` function. + /// + /// If the current state is `Loader`, it calls the `view` function of the + /// `Loader` struct. The `Loader`'s `view` function returns an `Element` + /// that is then mapped to a `Load` message. + /// + /// If the current state is `App`, it calls the `view` function of the `App` + /// struct. The `App`'s `view` function returns an `Element` that is + /// then mapped to an `Update` message. + /// + /// # Returns + /// + /// * `Element` - The `Element` to be rendered based on the + /// current state. + fn view(&self) -> Element { + match &self.state { + State::Loader(loader) => loader.view().map(Message::Load), + State::App(app) => app.view().map(Message::Update), + } + } + + /// The `subscription` function is responsible for managing the + /// subscriptions of the application. It matches on the current state + /// and calls the corresponding `subscription` function. + /// + /// If the current state is `Loader`, it calls the `subscription` function + /// of the `Loader` struct. The `Loader`'s `subscription` function + /// returns a `Subscription` that is then mapped to a `Load` message. + /// + /// If the current state is `App`, it calls the `subscription` function of + /// the `App` struct. The `App`'s `subscription` function returns a + /// `Subscription` that is then mapped to an `Update` message. + /// + /// Additionally, it listens for window close events and maps them to + /// `Event` messages. + /// + /// # Returns + /// + /// * `Subscription` - The `Subscription` to be used based on + /// the current state. + fn subscription(&self) -> Subscription { + Subscription::batch(vec![ + match &self.state { + State::Loader(loader) => loader.subscription().map(Message::Load), + State::App(app) => app.subscription().map(Message::Update), + }, + iced::subscription::events_with(|event, _status| { + if matches!( + event, + iced::event::Event::Window(iced::window::Event::CloseRequested) + ) { + Some(Self::Message::Event(event)) + } else { + None + } + }), + ]) + } + + fn theme(&self) -> Theme { + ExcaliburTheme::theme() + } +} + +/// Runs the Excalibur application +/// +/// The function first creates a `Settings` object with the specified `dev_mode` +/// using the `Settings::with_flags` function. It then sets various properties +/// of the `Settings` object: +/// - The window icon is set to the Excalibur logo. +/// - Antialiasing is enabled for smoother graphics. +/// - The application is set to not exit when a close request is received. This +/// allows the application to handle the close request in its own way. +/// - The id of the application is set to "excalibur-app". This is used by the +/// operating system to identify the application. +/// - The window size is set to 1280x832 pixels. +/// +/// The function runs the application with the specified settings using the +/// `MVP::run` function. +/// +/// # Arguments +/// +/// * `dev_mode` - A boolean indicating whether the application should run in +/// development mode. +/// +/// # Returns +/// +/// * `iced::Result` - The result of running the application. If the application +/// runs successfully, it returns `Ok(())`. If an error occurs, it returns +/// `Err(e)` where `e` is the error. +pub fn run(dev_mode: bool) -> iced::Result { + let mut settings = Settings::with_flags(Flags { dev_mode }); + settings.window.icon = Some(logos::excalibur_logo_2()); + settings.antialiasing = true; + settings.exit_on_close_request = false; + settings.id = Some("excalibur-app".to_string()); + settings.window.size = (1280, 832); + // im kinda confused about this, what logic actually runs, i can't really follow + // form this point on + MVP::run(settings) +} + +/// Returns a custom theme for the application. +pub fn custom_theme() -> iced::theme::Custom { + iced::theme::Custom::new(Palette { + background: iced::Color::BLACK, + primary: MINT_500, + text: PRIMARY_COLOR, + success: MINT_500, + danger: RED_400, + }) +} diff --git a/crates/app/src/middleware.rs b/bin/src/middleware.rs similarity index 100% rename from crates/app/src/middleware.rs rename to bin/src/middleware.rs diff --git a/crates/app/src/model/contacts/classification.rs b/bin/src/model/contacts/classification.rs similarity index 100% rename from crates/app/src/model/contacts/classification.rs rename to bin/src/model/contacts/classification.rs diff --git a/crates/app/src/model/contacts/list.rs b/bin/src/model/contacts/list.rs similarity index 100% rename from crates/app/src/model/contacts/list.rs rename to bin/src/model/contacts/list.rs diff --git a/crates/app/src/model/contacts/mod.rs b/bin/src/model/contacts/mod.rs similarity index 100% rename from crates/app/src/model/contacts/mod.rs rename to bin/src/model/contacts/mod.rs diff --git a/crates/app/src/model/mod.rs b/bin/src/model/mod.rs similarity index 100% rename from crates/app/src/model/mod.rs rename to bin/src/model/mod.rs diff --git a/crates/app/src/model/portfolio.rs b/bin/src/model/portfolio.rs similarity index 99% rename from crates/app/src/model/portfolio.rs rename to bin/src/model/portfolio.rs index d7913e416..303facaeb 100644 --- a/crates/app/src/model/portfolio.rs +++ b/bin/src/model/portfolio.rs @@ -2866,7 +2866,7 @@ mod tests { .spawn(); let url = anvil.ws_endpoint().to_string(); - let wallet: LocalWallet = anvil.keys().get(0).unwrap().clone().into(); + let wallet: LocalWallet = anvil.keys().first().unwrap().clone().into(); let wallet = wallet.with_chain_id(anvil.chain_id()); println!("Connected to URL: {}", url); diff --git a/crates/app/src/model/rpcs/mod.rs b/bin/src/model/rpcs/mod.rs similarity index 100% rename from crates/app/src/model/rpcs/mod.rs rename to bin/src/model/rpcs/mod.rs diff --git a/crates/app/src/model/user.rs b/bin/src/model/user.rs similarity index 100% rename from crates/app/src/model/user.rs rename to bin/src/model/user.rs diff --git a/crates/app/src/tracer.rs b/bin/src/tracer.rs similarity index 100% rename from crates/app/src/tracer.rs rename to bin/src/tracer.rs diff --git a/crates/app/src/view/mod.rs b/bin/src/view/mod.rs similarity index 87% rename from crates/app/src/view/mod.rs rename to bin/src/view/mod.rs index fedab8f3c..e0d81d489 100644 --- a/crates/app/src/view/mod.rs +++ b/bin/src/view/mod.rs @@ -20,7 +20,7 @@ pub mod sidebar; /// This enables controllers to communicate with controllers above them because /// the view messages start at the root application controller. #[derive(Debug, Clone, Default)] -pub enum Message { +pub enum ViewMessage { #[default] Empty, // Root controller messages are "caught" in flight in the application's @@ -52,17 +52,17 @@ pub enum RootMessage { ModelSyncRequest, } -impl MessageWrapperView for Message { - type ParentMessage = Message; +impl MessageWrapperView for ViewMessage { + type ParentMessage = ViewMessage; } -impl MessageWrapper for Message { - type ParentMessage = app::Message; +impl MessageWrapper for ViewMessage { + type ParentMessage = app::AppMessage; } -impl From for app::Message { - fn from(message: Message) -> Self { - app::Message::View(message) +impl From for app::AppMessage { + fn from(message: ViewMessage) -> Self { + app::AppMessage::View(message) } } @@ -73,11 +73,11 @@ impl From for app::Message { /// - Content /// /// Content is wrapped by its own layout. -pub fn app_layout<'a, T: Into>>( +pub fn app_layout<'a, T: Into>>( app_clock: &'a AppClock, menu: &'a sidebar::Sidebar, content: T, -) -> Element<'a, Message> { +) -> Element<'a, ViewMessage> { let floating_clock = floating_element( Container::new(Column::new()) .width(Length::Fixed(100.0)) @@ -123,10 +123,10 @@ pub fn app_layout<'a, T: Into>>( } /// For rendering content inside a screen that implements [`State`]. -pub fn screen_layout<'a, T: Into>>( +pub fn screen_layout<'a, T: Into>>( _window: &'a Page, content: T, -) -> Element<'a, Message> { +) -> Element<'a, ViewMessage> { Container::new(content) .center_x() .center_y() diff --git a/crates/app/src/view/portfolio_view.rs b/bin/src/view/portfolio_view.rs similarity index 100% rename from crates/app/src/view/portfolio_view.rs rename to bin/src/view/portfolio_view.rs diff --git a/crates/app/src/view/sidebar.rs b/bin/src/view/sidebar.rs similarity index 95% rename from crates/app/src/view/sidebar.rs rename to bin/src/view/sidebar.rs index c597276c6..c3e5f5e12 100644 --- a/crates/app/src/view/sidebar.rs +++ b/bin/src/view/sidebar.rs @@ -32,24 +32,24 @@ pub enum Location { } impl MessageWrapper for Route { - type ParentMessage = app::Message; + type ParentMessage = app::AppMessage; } /// For converting a `Route` into a `view::Message` that can be sent to the view /// to update the UI. impl MessageWrapperView for Route { - type ParentMessage = view::Message; + type ParentMessage = view::ViewMessage; } impl From for ::ParentMessage { fn from(msg: Route) -> Self { - app::Message::View(view::Message::Root(view::RootMessage::Route(msg))) + app::AppMessage::View(view::ViewMessage::Root(view::RootMessage::Route(msg))) } } impl From for ::ParentMessage { fn from(msg: Route) -> Self { - view::Message::Root(view::RootMessage::Route(msg)) + view::ViewMessage::Root(view::RootMessage::Route(msg)) } } @@ -73,7 +73,7 @@ impl Sidebar { impl Sidebar { /// Renders a section header with a label. #[allow(dead_code)] - pub fn section<'a>(&self, header: String) -> Row<'a, view::Message> { + pub fn section<'a>(&self, header: String) -> Row<'a, view::ViewMessage> { Row::new() .push(Space::with_width(Length::Fixed(Sizes::Xs.into()))) .push( @@ -87,7 +87,7 @@ impl Sidebar { } /// Renders the inner column below the sidebar's header section. - pub fn layout(&self) -> Element<'_, view::Message> { + pub fn layout(&self) -> Element<'_, view::ViewMessage> { let mut column = Column::new(); column = column.push(self.page.view().map(|x| x.into())); column @@ -99,7 +99,7 @@ impl Sidebar { impl controller::State for Sidebar { type AppMessage = Route; - type ViewMessage = view::Message; + type ViewMessage = view::ViewMessage; fn update(&mut self, message: Route) -> Command { self.state = message.clone(); diff --git a/crates/analysis/src/unpacker.rs b/crates/analysis/src/unpacker.rs index f29e4c65d..f11515459 100644 --- a/crates/analysis/src/unpacker.rs +++ b/crates/analysis/src/unpacker.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, env}; -use sim::agents::{base_agents::price_changer::PriceProcess, AgentParameters}; +use sim::agents::{base::price_changer::PriceProcess, AgentParameters}; use tokio::{fs, sync::mpsc, task}; use super::*; diff --git a/crates/app/Cargo.toml b/crates/app/Cargo.toml deleted file mode 100644 index 1c588138f..000000000 --- a/crates/app/Cargo.toml +++ /dev/null @@ -1,81 +0,0 @@ -[package] -name = "app" -version = "0.1.0" -edition = "2021" -authors = ["Primitive Bits, Inc."] - - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -# crates -datatypes = { path = "../datatypes" } -clients = { path = "../clients" } -cfmm_math = { path = "../cfmm_math" } - - -# deps -iced = { version = "=0.10.0", features = [ - "system", - "tokio", - "lazy", - "image", - "palette", - "advanced", - "canvas", - "svg", -] } -iced_aw = { version = "=0.7.0", default-features = false, features = [ - "menu", - "icon_text", - "icons", - "spinner", - "floating_element", -] } -plotters-backend = "=0.3.5" -plotters-iced = "=0.9.0" -iced-loading-indicator = { git = "https://github.com/BB-301/iced-loading-indicator.git", rev = "a09296f" } -url = "=2.5.0" - -# workspace crates -sim.workspace = true - -# revm -revm.workspace = true -revm-primitives.workspace = true - -# alloy -alloy-primitives.workspace = true -alloy-sol-types.workspace = true -alloy-providers.workspace = true -alloy-networks.workspace = true -alloy-rpc-client.workspace = true -alloy-rpc-types.workspace = true -alloy-transport-ws.workspace = true -alloy-rlp.workspace = true -alloy-pubsub.workspace = true -alloy-transport-http.workspace = true -alloy-signer.workspace = true -reqwest.workspace = true - -# workspace deps -chrono.workspace = true -RustQuant.workspace = true -arbiter-bindings.workspace = true -bindings.workspace = true -async-trait.workspace = true -reikna.workspace = true -statrs.workspace = true -arbiter-core.workspace = true -anyhow.workspace = true -criterion.workspace = true -ethers.workspace = true -directories-next.workspace = true -plotters.workspace = true -tracing.workspace = true -tracing-subscriber.workspace = true -tokio.workspace = true -tokio-util.workspace = true -serde.workspace = true -serde_json.workspace = true -uuid.workspace = true diff --git a/crates/app/src/lib.rs b/crates/app/src/lib.rs deleted file mode 100644 index b788b1e0d..000000000 --- a/crates/app/src/lib.rs +++ /dev/null @@ -1,329 +0,0 @@ -//! Building the Excalibur application, laws, rules, and axioms. -//! -//! We can break rules, find loopholes in laws, but cannot avoid axioms. -//! -//! -//! # Axioms -//! - Models handle data. Views handle presentation. Controllers manage user -//! input, models, and views. -//! - Models and views do not communicate directly. -//! - Data flows in one direction, starting at the model, and ending at the -//! view. -//! -//! # Rules -//! - Switching to new controllers/screens/anything being rendered should -//! offload as much logic as possible from `new` to a dedicated `load`. -//! - Add more rules! -use ethers::prelude::*; -use iced::{ - alignment, executor, - theme::Palette, - widget::{button, container, scrollable, text, Column, Row, Text}, - window, Application, Command, Element, Length, Settings, Subscription, Theme, -}; - -mod app; -mod components; -mod controller; -mod loader; -mod middleware; -mod model; -mod tracer; -mod view; - -use std::sync::Arc; - -use app::App; -use components::{system::ExcaliburTheme, *}; -use controller::*; -use loader::Loader; -use model::Model; -use styles::*; - -/// The MVP struct represents the Model-View-Presenter pattern used in this -/// application. It contains the state of the application and a tracer for -/// debugging. The state can be either the application itself or a loader. -/// The MVP struct also implements the Application trait from the iced library. -/// This is the outermost layer of the application. -pub struct MVP { - state: State, - #[allow(dead_code)] - tracer: tracer::Tracer, -} -/// The `State` enum represents the current state of the application. -/// It can be either `App` when the application is running or `Loader` when the -/// application is loading. The state should only be in the loader state when -/// the application is starting up in the beginning. -enum State { - App(App), - Loader(Loader), -} - -/// The `Message` enum represents the different types of messages that can be -/// sent within the application. It can be either `Load` when the application is -/// loading, `Update` when the application is updating, `Event` when an event -/// occurs, `Quit` when the application is quitting, or `ForceQuit` when the -/// application is forced to quit. -#[derive(Debug)] -pub enum Message { - Load(Box), - Update(Box), - Event(iced::event::Event), - Quit, - ForceQuit, -} - -/// The `Flags` struct represents the flags that can be passed to the -/// application. It contains a single flag `dev_mode` which indicates whether -/// the application is running in development mode. -#[derive(Debug, Clone, Copy)] -pub struct Flags { - pub dev_mode: bool, -} - -/// The `Application` trait implementation for the `MVP` struct. -/// This trait provides the necessary types for the application to run. -/// `Message` is the type of messages that can be sent within the application. -/// `Theme` is the type of theme used in the application. -/// `Executor` is the type of executor used to run the application. -/// `Flags` is the type of flags that can be passed to the application. -impl Application for MVP { - type Message = Message; - type Theme = Theme; - type Executor = executor::Default; - type Flags = Flags; - - /// Creates a new instance of the MVP struct. - /// - /// This function takes a Flags struct as an argument and returns a tuple - /// containing an MVP struct and a Command. The Flags struct contains a - /// single flag `dev_mode` which indicates whether the application is - /// running in development mode. If the `dev_mode` flag is set, the - /// "DEV_MODE" environment variable is also set to "true". - /// - /// The function initializes the application with the Loader state and a - /// Load message. - /// - /// # Arguments - /// - /// * `flags: Flags` - The flags that can be passed to the application. - /// - /// # Returns - /// - /// * `(MVP, Command)` - A tuple containing an MVP struct and a - /// Command. - fn new(flags: Flags) -> (MVP, Command) { - let tracer = tracer::setup_with_channel(); - if flags.dev_mode { - std::env::set_var("DEV_MODE", "true"); - } - - let (loader, command) = Loader::new(flags); - let state = State::Loader(loader); - - ( - MVP { state, tracer }, - command.map(|msg| Message::Load(Box::new(msg))), - ) - } - - /// Returns the title of the application. - /// - /// This function takes no arguments and returns a String. - /// The title of the application depends on the current state of the - /// application. If the application is in the Loader state, the title is - /// "Loading Excalibur". If the application is in the App state, the - /// title is "Excalibur". - /// - /// # Returns - /// - /// * `String` - The title of the application. - fn title(&self) -> String { - match &self.state { - State::Loader(_) => String::from("Loading Excalibur"), - State::App(_) => String::from("Excalibur"), - } - } - - /// Updates the state of the application based on the incoming message. - /// - /// This function takes a mutable reference to the application and a - /// message. It updates the state of the application based on the - /// message and returns a command. - /// - /// The function handles different types of messages including ForceQuit, - /// Quit, Load, and Update. It also handles the transition from the - /// Loader state to the App state. - /// - /// # Arguments - /// - /// * `&mut self` - A mutable reference to the application. - /// * `message: Self::Message` - The incoming message. - /// - /// # Returns - /// - /// * `Command` - The command to be executed after the state - /// update. - fn update(&mut self, message: Self::Message) -> Command { - match (&mut self.state, message) { - (_, Message::ForceQuit) => window::close(), - (_, Message::Quit) - | ( - _, - Message::Event(iced::event::Event::Window(iced::window::Event::CloseRequested)), - ) => { - let state_cmd = match self.state { - State::App(ref mut app) => app.exit().map(|msg| Message::Update(Box::new(msg))), - // todo: handle specific closure logic for the loading screen. - _ => Command::perform(async {}, |()| Message::ForceQuit), - }; - - Command::batch(vec![state_cmd]) - } - (State::Loader(l), Message::Load(msg)) => match *msg { - // 3. Got the message from the loader we are ready to go! - loader::Message::Ready(Ok((model, client))) => { - // 4. Create our app and move to the app state. - let (app, command) = App::new(model, client); - self.state = State::App(app); - - // 5. Get to the next branch. - command.map(|msg| Message::Update(Box::new(msg))) - } - loader::Message::Ready(Err(error_message)) => { - tracing::error!("Failed to load app: {}", error_message); - Command::none() - } - loader::Message::Quit => Command::perform(async {}, |()| Message::ForceQuit), - // 2. Loader emits the Load message, update the loader state. - _ => l.update(*msg).map(|msg| Message::Load(Box::new(msg))), - }, - (State::App(app), Message::Update(msg)) => { - if let app::Message::QuitReady = *msg { - return Command::perform(async {}, |()| Message::ForceQuit); - } - // 6. Arrived at main application loop. - // note: application loop is by mapping the result of update with Update - // message. - app.update(*msg).map(|msg| Message::Update(Box::new(msg))) - } - _ => Command::none(), - } - } - - /// The `view` function is responsible for rendering the current state of - /// the application. It matches on the current state and calls the - /// corresponding `view` function. - /// - /// If the current state is `Loader`, it calls the `view` function of the - /// `Loader` struct. The `Loader`'s `view` function returns an `Element` - /// that is then mapped to a `Load` message. - /// - /// If the current state is `App`, it calls the `view` function of the `App` - /// struct. The `App`'s `view` function returns an `Element` that is - /// then mapped to an `Update` message. - /// - /// # Returns - /// - /// * `Element` - The `Element` to be rendered based on the - /// current state. - fn view(&self) -> Element { - match &self.state { - State::Loader(loader) => loader.view().map(|msg| Message::Load(Box::new(msg))), - State::App(app) => app.view().map(|msg| Message::Update(Box::new(msg))), - } - } - - /// The `subscription` function is responsible for managing the - /// subscriptions of the application. It matches on the current state - /// and calls the corresponding `subscription` function. - /// - /// If the current state is `Loader`, it calls the `subscription` function - /// of the `Loader` struct. The `Loader`'s `subscription` function - /// returns a `Subscription` that is then mapped to a `Load` message. - /// - /// If the current state is `App`, it calls the `subscription` function of - /// the `App` struct. The `App`'s `subscription` function returns a - /// `Subscription` that is then mapped to an `Update` message. - /// - /// Additionally, it listens for window close events and maps them to - /// `Event` messages. - /// - /// # Returns - /// - /// * `Subscription` - The `Subscription` to be used based on - /// the current state. - fn subscription(&self) -> Subscription { - Subscription::batch(vec![ - match &self.state { - State::Loader(loader) => loader - .subscription() - .map(|msg| Message::Load(Box::new(msg))), - State::App(app) => app.subscription().map(|msg| Message::Update(Box::new(msg))), - }, - iced::subscription::events_with(|event, _status| { - if matches!( - event, - iced::event::Event::Window(iced::window::Event::CloseRequested) - ) { - Some(Self::Message::Event(event)) - } else { - None - } - }), - ]) - } - - fn theme(&self) -> Theme { - ExcaliburTheme::theme() - } -} - -/// Runs the Excalibur application -/// -/// The function first creates a `Settings` object with the specified `dev_mode` -/// using the `Settings::with_flags` function. It then sets various properties -/// of the `Settings` object: -/// - The window icon is set to the Excalibur logo. -/// - Antialiasing is enabled for smoother graphics. -/// - The application is set to not exit when a close request is received. This -/// allows the application to handle the close request in its own way. -/// - The id of the application is set to "excalibur-app". This is used by the -/// operating system to identify the application. -/// - The window size is set to 1280x832 pixels. -/// -/// The function runs the application with the specified settings using the -/// `MVP::run` function. -/// -/// # Arguments -/// -/// * `dev_mode` - A boolean indicating whether the application should run in -/// development mode. -/// -/// # Returns -/// -/// * `iced::Result` - The result of running the application. If the application -/// runs successfully, it returns `Ok(())`. If an error occurs, it returns -/// `Err(e)` where `e` is the error. -pub fn run(dev_mode: bool) -> iced::Result { - let mut settings = Settings::with_flags(Flags { dev_mode }); - settings.window.icon = Some(logos::excalibur_logo_2()); - settings.antialiasing = true; - settings.exit_on_close_request = false; - settings.id = Some("excalibur-app".to_string()); - settings.window.size = (1280, 832); - // im kinda confused about this, what logic actually runs, i can't really follow - // form this point on - MVP::run(settings) -} - -/// Returns a custom theme for the application. -pub fn custom_theme() -> iced::theme::Custom { - iced::theme::Custom::new(Palette { - background: iced::Color::BLACK, - primary: MINT_500, - text: PRIMARY_COLOR, - success: MINT_500, - danger: RED_400, - }) -} diff --git a/crates/sim/Cargo.toml b/crates/sim/Cargo.toml index 258b179bf..cc0872346 100644 --- a/crates/sim/Cargo.toml +++ b/crates/sim/Cargo.toml @@ -8,7 +8,6 @@ edition = "2021" [dependencies] datatypes.workspace = true bindings.workspace = true -cfmm_math.workspace = true clients.workspace = true @@ -41,4 +40,4 @@ statrs.workspace = true linked-hash-map.workspace = true # Historical Data -rust-gecko = { git = "https://github.com/0xJepsen/rust-gecko.git", branch = "main" } \ No newline at end of file +rust-gecko = { git = "https://github.com/0xJepsen/rust-gecko.git", branch = "main" } diff --git a/crates/sim/src/agents/base_agents/block_admin.rs b/crates/sim/src/agents/base/block_admin.rs similarity index 100% rename from crates/sim/src/agents/base_agents/block_admin.rs rename to crates/sim/src/agents/base/block_admin.rs diff --git a/crates/sim/src/agents/base_agents/mod.rs b/crates/sim/src/agents/base/mod.rs similarity index 100% rename from crates/sim/src/agents/base_agents/mod.rs rename to crates/sim/src/agents/base/mod.rs diff --git a/crates/sim/src/agents/base_agents/price_changer.rs b/crates/sim/src/agents/base/price_changer.rs similarity index 100% rename from crates/sim/src/agents/base_agents/price_changer.rs rename to crates/sim/src/agents/base/price_changer.rs diff --git a/crates/sim/src/agents/base_agents/token_admin.rs b/crates/sim/src/agents/base/token_admin.rs similarity index 100% rename from crates/sim/src/agents/base_agents/token_admin.rs rename to crates/sim/src/agents/base/token_admin.rs diff --git a/crates/sim/src/agents/mod.rs b/crates/sim/src/agents/mod.rs index ea987083b..c5266134e 100644 --- a/crates/sim/src/agents/mod.rs +++ b/crates/sim/src/agents/mod.rs @@ -1,14 +1,17 @@ -pub mod base_agents; -pub mod portfolio_management_agents; +pub mod base; +pub mod portfolio_management; -use base_agents::{block_admin::*, price_changer::*, token_admin::*}; -use portfolio_management_agents::{ - base::parameter_manager::*, - g3m::{dca_g3m_liquidity_provider::*, g3m_liquidity_provider::*}, - lognormal::ln_liquidity_provider::*, -}; +use base::{block_admin::*, price_changer::*, token_admin::*}; +use portfolio_management::{base::parameter_manager::*, g3m::dca_g3m_liquidity_provider::*}; -use self::portfolio_management_agents::g3m::dca_swapper::DcaSwapperParameters; +use self::portfolio_management::{ + base::parameter_manager::ParameterManagerParameters, + g3m::{ + dca_g3m_liquidity_provider::DcaG3mLiquidityProviderParameters, + dca_swapper::DcaSwapperParameters, g3m_liquidity_provider::G3mLiquidityProviderParameters, + }, + lognormal::ln_liquidity_provider::LogNormalLiquidityProviderParameters, +}; use super::*; #[derive(Clone, Debug, Serialize, Deserialize)] diff --git a/crates/sim/src/agents/portfolio_management_agents/base/arbitrageur.rs b/crates/sim/src/agents/portfolio_management/base/arbitrageur.rs similarity index 98% rename from crates/sim/src/agents/portfolio_management_agents/base/arbitrageur.rs rename to crates/sim/src/agents/portfolio_management/base/arbitrageur.rs index f4a09f7d9..a1f0666f5 100644 --- a/crates/sim/src/agents/portfolio_management_agents/base/arbitrageur.rs +++ b/crates/sim/src/agents/portfolio_management/base/arbitrageur.rs @@ -5,7 +5,7 @@ use clients::protocol::{pool::PoolKind, ProtocolClient}; use ethers::{types::U256, utils::parse_ether}; use super::{ - agents::base_agents::token_admin::TokenAdmin, + agents::base::token_admin::TokenAdmin, bindings::{arb_math::ArbMath, atomic_v2::AtomicV2}, Environment, Result, RevmMiddleware, *, }; diff --git a/crates/sim/src/agents/portfolio_management_agents/base/mod.rs b/crates/sim/src/agents/portfolio_management/base/mod.rs similarity index 100% rename from crates/sim/src/agents/portfolio_management_agents/base/mod.rs rename to crates/sim/src/agents/portfolio_management/base/mod.rs diff --git a/crates/sim/src/agents/portfolio_management_agents/base/parameter_manager.rs b/crates/sim/src/agents/portfolio_management/base/parameter_manager.rs similarity index 100% rename from crates/sim/src/agents/portfolio_management_agents/base/parameter_manager.rs rename to crates/sim/src/agents/portfolio_management/base/parameter_manager.rs diff --git a/crates/sim/src/agents/portfolio_management_agents/g3m/dca_g3m_liquidity_provider.rs b/crates/sim/src/agents/portfolio_management/g3m/dca_g3m_liquidity_provider.rs similarity index 98% rename from crates/sim/src/agents/portfolio_management_agents/g3m/dca_g3m_liquidity_provider.rs rename to crates/sim/src/agents/portfolio_management/g3m/dca_g3m_liquidity_provider.rs index 658a4e0b0..da613b880 100644 --- a/crates/sim/src/agents/portfolio_management_agents/g3m/dca_g3m_liquidity_provider.rs +++ b/crates/sim/src/agents/portfolio_management/g3m/dca_g3m_liquidity_provider.rs @@ -5,7 +5,7 @@ use clients::protocol::{G3mF64, PoolInitParamsF64, ProtocolClient}; use ethers::{types::U256, utils::parse_ether}; use super::{agent::*, *}; -use crate::agents::base_agents::token_admin::TokenAdmin; +use crate::agents::base::token_admin::TokenAdmin; #[derive(Debug, Clone)] pub struct DcaG3mLiquidityProvider { diff --git a/crates/sim/src/agents/portfolio_management_agents/g3m/dca_swapper.rs b/crates/sim/src/agents/portfolio_management/g3m/dca_swapper.rs similarity index 97% rename from crates/sim/src/agents/portfolio_management_agents/g3m/dca_swapper.rs rename to crates/sim/src/agents/portfolio_management/g3m/dca_swapper.rs index a9591d122..44e591aeb 100644 --- a/crates/sim/src/agents/portfolio_management_agents/g3m/dca_swapper.rs +++ b/crates/sim/src/agents/portfolio_management/g3m/dca_swapper.rs @@ -4,8 +4,8 @@ use arbiter_bindings::bindings::{arbiter_token::ArbiterToken, liquid_exchange::L use ethers::utils::{parse_ether, parse_units, ParseUnits}; use super::{ - agent::*, agents::base_agents::token_admin::TokenAdmin, - bindings::portfolio_tracker::PortfolioTracker, Environment, Result, RevmMiddleware, *, + agent::*, agents::base::token_admin::TokenAdmin, bindings::portfolio_tracker::PortfolioTracker, + Environment, Result, RevmMiddleware, *, }; use crate::settings::parameters::LinspaceParameters; diff --git a/crates/sim/src/agents/portfolio_management_agents/g3m/g3m_arbitrageur.rs b/crates/sim/src/agents/portfolio_management/g3m/g3m_arbitrageur.rs similarity index 98% rename from crates/sim/src/agents/portfolio_management_agents/g3m/g3m_arbitrageur.rs rename to crates/sim/src/agents/portfolio_management/g3m/g3m_arbitrageur.rs index 16388116e..6e2f99533 100644 --- a/crates/sim/src/agents/portfolio_management_agents/g3m/g3m_arbitrageur.rs +++ b/crates/sim/src/agents/portfolio_management/g3m/g3m_arbitrageur.rs @@ -10,10 +10,7 @@ use tracing::log::info; use super::{ agent::*, - agents::{ - base_agents::token_admin::TokenAdmin, - portfolio_management_agents::base::arbitrageur::Arbitrageur, - }, + agents::{base::token_admin::TokenAdmin, portfolio_management::base::arbitrageur::Arbitrageur}, Environment, Result, RevmMiddleware, *, }; diff --git a/crates/sim/src/agents/portfolio_management_agents/g3m/g3m_liquidity_provider.rs b/crates/sim/src/agents/portfolio_management/g3m/g3m_liquidity_provider.rs similarity index 98% rename from crates/sim/src/agents/portfolio_management_agents/g3m/g3m_liquidity_provider.rs rename to crates/sim/src/agents/portfolio_management/g3m/g3m_liquidity_provider.rs index cf7bb4aab..51da67b6d 100644 --- a/crates/sim/src/agents/portfolio_management_agents/g3m/g3m_liquidity_provider.rs +++ b/crates/sim/src/agents/portfolio_management/g3m/g3m_liquidity_provider.rs @@ -5,7 +5,7 @@ use clients::protocol::{G3mF64, PoolInitParamsF64, ProtocolClient}; use ethers::{types::U256, utils::parse_ether}; use super::{agent::*, *}; -use crate::agents::base_agents::token_admin::TokenAdmin; +use crate::agents::base::token_admin::TokenAdmin; #[derive(Debug, Clone)] pub struct G3mLiquidityProvider { diff --git a/crates/sim/src/agents/portfolio_management_agents/g3m/mod.rs b/crates/sim/src/agents/portfolio_management/g3m/mod.rs similarity index 100% rename from crates/sim/src/agents/portfolio_management_agents/g3m/mod.rs rename to crates/sim/src/agents/portfolio_management/g3m/mod.rs diff --git a/crates/sim/src/agents/portfolio_management_agents/lognormal/ln_arbitrageur.rs b/crates/sim/src/agents/portfolio_management/lognormal/ln_arbitrageur.rs similarity index 97% rename from crates/sim/src/agents/portfolio_management_agents/lognormal/ln_arbitrageur.rs rename to crates/sim/src/agents/portfolio_management/lognormal/ln_arbitrageur.rs index 8fc6218d0..b58d88e3b 100644 --- a/crates/sim/src/agents/portfolio_management_agents/lognormal/ln_arbitrageur.rs +++ b/crates/sim/src/agents/portfolio_management/lognormal/ln_arbitrageur.rs @@ -8,9 +8,9 @@ use ethers::{ }; use tracing::info; -use self::agents::portfolio_management_agents::base::arbitrageur::Arbitrageur; +use self::agents::portfolio_management::base::arbitrageur::Arbitrageur; use super::{ - agent::*, agents::base_agents::token_admin::TokenAdmin, Environment, Result, RevmMiddleware, *, + agent::*, agents::base::token_admin::TokenAdmin, Environment, Result, RevmMiddleware, *, }; #[derive(Debug, Clone)] diff --git a/crates/sim/src/agents/portfolio_management_agents/lognormal/ln_liquidity_provider.rs b/crates/sim/src/agents/portfolio_management/lognormal/ln_liquidity_provider.rs similarity index 98% rename from crates/sim/src/agents/portfolio_management_agents/lognormal/ln_liquidity_provider.rs rename to crates/sim/src/agents/portfolio_management/lognormal/ln_liquidity_provider.rs index e23ffae50..ab74385a1 100644 --- a/crates/sim/src/agents/portfolio_management_agents/lognormal/ln_liquidity_provider.rs +++ b/crates/sim/src/agents/portfolio_management/lognormal/ln_liquidity_provider.rs @@ -5,7 +5,7 @@ use clients::protocol::{LogNormalF64, PoolInitParamsF64, ProtocolClient}; use ethers::{types::U256, utils::parse_ether}; use super::{agent::*, *}; -use crate::agents::base_agents::token_admin::TokenAdmin; +use crate::agents::base::token_admin::TokenAdmin; #[derive(Debug, Clone)] pub struct LogNormalLiquidityProvider { diff --git a/crates/sim/src/agents/portfolio_management_agents/lognormal/mod.rs b/crates/sim/src/agents/portfolio_management/lognormal/mod.rs similarity index 100% rename from crates/sim/src/agents/portfolio_management_agents/lognormal/mod.rs rename to crates/sim/src/agents/portfolio_management/lognormal/mod.rs diff --git a/crates/sim/src/agents/portfolio_management_agents/mod.rs b/crates/sim/src/agents/portfolio_management/mod.rs similarity index 100% rename from crates/sim/src/agents/portfolio_management_agents/mod.rs rename to crates/sim/src/agents/portfolio_management/mod.rs diff --git a/crates/sim/src/scenarios.rs b/crates/sim/src/scenarios.rs index 445696648..9af89eb8a 100644 --- a/crates/sim/src/scenarios.rs +++ b/crates/sim/src/scenarios.rs @@ -2,16 +2,14 @@ use arbiter_core::data_collection::EventLogger; use clients::protocol::ProtocolClient; use revm::db::{CacheDB, EmptyDB}; -use self::agents::portfolio_management_agents::{ +use self::agents::portfolio_management::{ g3m::{dca_g3m_setup, g3m_setup}, lognormal::ln_setup, }; use super::*; use crate::{ agent::Agents, - agents::base_agents::{ - block_admin::BlockAdmin, price_changer::PriceChanger, token_admin::TokenAdmin, - }, + agents::base::{block_admin::BlockAdmin, price_changer::PriceChanger, token_admin::TokenAdmin}, }; #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]