From f6001c6804c4c62fed593da9e4fc9cff818afc2e Mon Sep 17 00:00:00 2001 From: jafar75 Date: Fri, 28 Nov 2025 20:27:12 +0330 Subject: [PATCH 1/6] feat: make persistence composit + apply for mint invoices --- libs/symm-core/src/core/persistence.rs | 57 +- persistence/InvoiceManager.json | 55 ++ .../order_IZE-KYW-IHL-3516.json | 168 ++++++ .../order_JYA-NIF-EYJ-9644.json | 142 +++++ .../order_UJQ-RQJ-DAT-2626.json | 194 +++++++ src/solver/mint_invoice_manager.rs | 493 +++++++++++++++--- 6 files changed, 1043 insertions(+), 66 deletions(-) create mode 100644 persistence/InvoiceManager.json create mode 100644 persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_IZE-KYW-IHL-3516.json create mode 100644 persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_JYA-NIF-EYJ-9644.json create mode 100644 persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_UJQ-RQJ-DAT-2626.json diff --git a/libs/symm-core/src/core/persistence.rs b/libs/symm-core/src/core/persistence.rs index 7be2432..4aa2217 100644 --- a/libs/symm-core/src/core/persistence.rs +++ b/libs/symm-core/src/core/persistence.rs @@ -9,10 +9,11 @@ pub trait Persist { pub trait Persistence { fn load_value(&self) -> Result>; fn store_value(&self, value: Value) -> Result<()>; + fn child(&self, key: String) -> Result>; // To allow nested persistence } pub mod util { - use std::{fs, path::PathBuf}; + use std::{collections::HashMap, fs, path::PathBuf, sync::Arc}; use eyre::{Context, Result}; use parking_lot::RwLock; @@ -23,20 +24,35 @@ pub mod util { ; pub struct InMemoryPersistence { - data: RwLock>, + data: Arc>>, // Shared storage with keys + prefix: String, // Namespace for this instance } impl InMemoryPersistence { pub fn new() -> Self { Self { - data: RwLock::new(None), + data: Arc::new(RwLock::new(HashMap::new())), + prefix: String::new(), + } + } + + fn new_with_data(data: Arc>>, prefix: String) -> Self { + Self { data, prefix } + } + + fn get_key(&self) -> String { + if self.prefix.is_empty() { + "root".to_string() + } else { + self.prefix.clone() } } } impl Persistence for InMemoryPersistence { fn load_value(&self) -> Result> { - if let Some(json_string) = self.data.read().as_ref() { + let key = self.get_key(); + if let Some(json_string) = self.data.read().get(&key) { Ok(Some( serde_json::from_str(json_string).context("Failed to deserialize")?, )) @@ -46,10 +62,23 @@ pub mod util { } fn store_value(&self, value: Value) -> Result<()> { + let key = self.get_key(); let json_string = serde_json::to_string_pretty(&value)?; - *self.data.write() = Some(json_string); + self.data.write().insert(key, json_string); Ok(()) } + + fn child(&self, key: String) -> Result> { + let child_prefix = if self.prefix.is_empty() { + key + } else { + format!("{}/{}", self.prefix, key) + }; + Ok(Box::new(InMemoryPersistence::new_with_data( + Arc::clone(&self.data), + child_prefix, + ))) + } } pub struct JsonFilePersistence { @@ -60,6 +89,19 @@ pub mod util { pub fn new(path: impl Into) -> Self { JsonFilePersistence { path: path.into() } } + + fn create_child_path(&self, key: &str) -> PathBuf { + let mut parent_path = self.path.clone(); + + // If parent has .json extension, remove it to use as directory + if parent_path.extension().is_some() { + parent_path.set_extension(""); + } + + // Add key as filename with .json extension + parent_path.push(format!("{}.json", key)); + parent_path + } } impl Persistence for JsonFilePersistence { @@ -85,5 +127,10 @@ pub mod util { let json_string = serde_json::to_string_pretty(&value).context("Failed to serialize")?; fs::write(&self.path, &json_string).context("Failed to write json file") } + + fn child(&self, key: String) -> Result> { + let child_path = self.create_child_path(&key); + Ok(Box::new(JsonFilePersistence::new(child_path))) + } } } diff --git a/persistence/InvoiceManager.json b/persistence/InvoiceManager.json new file mode 100644 index 0000000..24e40d2 --- /dev/null +++ b/persistence/InvoiceManager.json @@ -0,0 +1,55 @@ +{ + "metadata": [ + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "amount_paid": "0.010", + "amount_remaining": "0.0000000201692423536161167180", + "assets_value": "0.0089954820897127899888888376", + "chain_id": 8453, + "client_order_id": "JYA-NIF-EYJ-9644", + "exchange_fee": "0.0000044977410448563949944445", + "fill_rate": "0.9999977589730718204314757778", + "filled_quantity": "0.0000001310933459504349211202", + "management_fee": "0.001", + "payment_id": "P-1763134390189", + "seq_num": "0x21050000000002467758c0d3c9e530ca6d71469bb678e6592274154d9cad", + "symbol": "SY100", + "timestamp": "2025-11-14T15:33:10.783466856Z", + "total_amount": "0.01" + }, + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "amount_paid": "0.0100000000000000000000000000", + "amount_remaining": "-0.0010526830005014490310057145", + "assets_value": "0.0107718962448164820064416708", + "chain_id": 8453, + "client_order_id": "IZE-KYW-IHL-3516", + "exchange_fee": "0.0000053859481224082410032209", + "fill_rate": "1.1082495000225913925807482659", + "filled_quantity": "0.0000001569814610135035622395", + "management_fee": "0.0002754008075625587835608228", + "payment_id": "P-1763682580557", + "seq_num": "0x210500000000024aa600c0d3c9e530ca6d71469bb678e6592274154d9cad", + "symbol": "SY100", + "timestamp": "2025-11-20T23:49:40.900802807Z", + "total_amount": "0.01" + }, + { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "amount_paid": "0.010", + "amount_remaining": "-0.0014574117666911317796647744", + "assets_value": "0.0104521856738542046773261113", + "chain_id": 8453, + "client_order_id": "UJQ-RQJ-DAT-2626", + "exchange_fee": "0.0000052260928369271023386631", + "fill_rate": "1.1619346407434590866294193778", + "filled_quantity": "0.0000001523222411890208624175", + "management_fee": "0.001", + "payment_id": "P-1763742738347", + "seq_num": "0x210500000000024b1b81c0d3c9e530ca6d71469bb678e6592274154d9cad", + "symbol": "SY100", + "timestamp": "2025-11-21T16:32:18.659951420Z", + "total_amount": "0.01" + } + ] +} \ No newline at end of file diff --git a/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_IZE-KYW-IHL-3516.json b/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_IZE-KYW-IHL-3516.json new file mode 100644 index 0000000..4f77731 --- /dev/null +++ b/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_IZE-KYW-IHL-3516.json @@ -0,0 +1,168 @@ +{ + "amount_paid": "0.0100000000000000000000000000", + "amount_remaining": "-0.0010526830005014490310057145", + "assets_value": "0.0107718962448164820064416708", + "client_order_id": "IZE-KYW-IHL-3516", + "exchange_fee": "0.0000053859481224082410032209", + "fill_rate": "1.1082495000225913925807482659", + "filled_quantity": "0.0000001569814610135035622395", + "lots": [ + { + "assigned_fee": "0.0000044041467545647197440242", + "assigned_quantity": "0.0000000911573347088867211024", + "assigned_timestamp": "2025-11-20T23:49:40.787995229Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390429-L-1", + "original_fee": "0.0024999999999999999999999998", + "original_quantity": "0.0000517451732361131219860377", + "price": "96627.37000000", + "remaining_quantity": "0.0000515778914983202066030796", + "symbol": "BTC" + }, + { + "assigned_fee": "0.0000002576748500608423446179", + "assigned_quantity": "0.0000005573456985039579183861", + "assigned_timestamp": "2025-11-20T23:49:40.787995229Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390428-L-0", + "original_fee": "0.0025000000000000000000000000", + "original_quantity": "0.0054074514681230735954144812", + "price": "924.65000000", + "remaining_quantity": "0.0054064286896785864595576436", + "symbol": "BNB" + }, + { + "assigned_fee": "0.0000001846040296483885199411", + "assigned_quantity": "0.0022657751414346550468374020", + "assigned_timestamp": "2025-11-20T23:49:40.787995229Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390427-L-2", + "original_fee": "0.0025000000000000000000000000", + "original_quantity": "30.684258975145750230131942314", + "price": "0.16295000", + "remaining_quantity": "30.680101078205064143335748874", + "symbol": "DOGE" + }, + { + "assigned_fee": "0.0000001975866903790019190870", + "assigned_quantity": "0.0001714938943531674860799337", + "assigned_timestamp": "2025-11-20T23:49:40.787995229Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390430-L-3", + "original_fee": "0.0025000000000000000000000000", + "original_quantity": "2.1698563555092652866380245628", + "price": "2.30430000", + "remaining_quantity": "2.1695416491089532579074317000", + "symbol": "XRP" + }, + { + "assigned_fee": "0.0000001758786482945378109736", + "assigned_quantity": "0.0000001098822625714807548207", + "assigned_timestamp": "2025-11-20T23:49:40.787995229Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390431-L-5", + "original_fee": "0.0025000000000000000000000000", + "original_quantity": "0.0015619045239002630247218248", + "price": "3201.22000000", + "remaining_quantity": "0.0015617028802706606908907844", + "symbol": "ETH" + }, + { + "assigned_fee": "0.0000001660571494607506645771", + "assigned_quantity": "0.0000023439501653010186262565", + "assigned_timestamp": "2025-11-20T23:49:40.787995229Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390426-L-4", + "original_fee": "0.0025000000000000000000000000", + "original_quantity": "0.0352883054555720234314348225", + "price": "141.69000000", + "remaining_quantity": "0.0352840041005773460725275348", + "symbol": "SOL" + } + ], + "management_fee": "0.0002754008075625587835608228", + "payment_id": "P-1763682580557", + "position": { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "created_timestamp": "2025-11-14T15:32:57.575189603Z", + "last_update_timestamp": "2025-11-20T23:49:25.727853438Z", + "side_cr": { + "closed_lots": [ + { + "created_timestamp": "2025-11-14T15:32:57.575189603Z", + "last_update_timestamp": "2025-11-14T15:33:10.783466856Z", + "payment_id": "P-1763134377575", + "preauth_amount": "0.000000", + "ready_amount": "0", + "seq_num": "0x21050000000002467758c0d3c9e530ca6d71469bb678e6592274154d9cad", + "spends": [ + { + "client_order_id": "JYA-NIF-EYJ-9644", + "payment_id": "Charges", + "preauth_amount": "0", + "spent_amount": "0.001", + "timestamp": "2025-11-14T15:33:10.184452230Z" + }, + { + "client_order_id": "JYA-NIF-EYJ-9644", + "payment_id": "P-1763134390189", + "preauth_amount": "0", + "spent_amount": "0.009000", + "timestamp": "2025-11-14T15:33:10.783466856Z" + } + ], + "spent_amount": "0.010000", + "unconfirmed_amount": "0" + }, + { + "created_timestamp": "2025-11-20T23:49:25.727853438Z", + "last_update_timestamp": "2025-11-20T23:49:40.900802807Z", + "payment_id": "P-1763682565728", + "preauth_amount": "0.0000000000000000000000000000", + "ready_amount": "0", + "seq_num": "0x210500000000024aa600c0d3c9e530ca6d71469bb678e6592274154d9cad", + "spends": [ + { + "client_order_id": "IZE-KYW-IHL-3516", + "payment_id": "Charges", + "preauth_amount": "0", + "spent_amount": "0.0002754008075625587835608228", + "timestamp": "2025-11-20T23:49:40.551382709Z" + }, + { + "client_order_id": "IZE-KYW-IHL-3516", + "payment_id": "P-1763682580557", + "preauth_amount": "0", + "spent_amount": "0.0097245991924374412164391772", + "timestamp": "2025-11-20T23:49:40.900802807Z" + } + ], + "spent_amount": "0.0100000000000000000000000000", + "unconfirmed_amount": "0" + } + ], + "created_timestamp": "2025-11-14T15:32:57.575189603Z", + "last_update_timestamp": "2025-11-20T23:49:40.551382709Z", + "open_lots": [], + "preauth_balance": "0.0000000000000000000000000000", + "ready_balance": "0.0000000000000000000000000000", + "spent_balance": "0.0200000000000000000000000000", + "unconfirmed_balance": "0.0000000000000000000000000000" + }, + "side_dr": { + "closed_lots": [], + "created_timestamp": "2025-11-14T15:32:57.575189603Z", + "last_update_timestamp": "2025-11-14T15:32:57.575189603Z", + "open_lots": [], + "preauth_balance": "0", + "ready_balance": "0", + "spent_balance": "0", + "unconfirmed_balance": "0" + } + }, + "seq_num": "0x210500000000024aa600c0d3c9e530ca6d71469bb678e6592274154d9cad", + "symbol": "SY100", + "timestamp": "2025-11-20T23:49:40.900802807Z", + "total_amount": "0.01" +} \ No newline at end of file diff --git a/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_JYA-NIF-EYJ-9644.json b/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_JYA-NIF-EYJ-9644.json new file mode 100644 index 0000000..1820619 --- /dev/null +++ b/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_JYA-NIF-EYJ-9644.json @@ -0,0 +1,142 @@ +{ + "amount_paid": "0.010", + "amount_remaining": "0.0000000201692423536161167180", + "assets_value": "0.0089954820897127899888888376", + "client_order_id": "JYA-NIF-EYJ-9644", + "exchange_fee": "0.0000044977410448563949944445", + "fill_rate": "0.9999977589730718204314757778", + "filled_quantity": "0.0000001310933459504349211202", + "lots": [ + { + "assigned_fee": "0.0000001468741616832537423280", + "assigned_quantity": "0.0000000917613670308530762197", + "assigned_timestamp": "2025-11-14T15:33:10.665234182Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390431-L-5", + "original_fee": "0.0025000000000000000000000000", + "original_quantity": "0.0015619045239002630247218248", + "price": "3201.22000000", + "remaining_quantity": "0.0015618127625332321716456051", + "symbol": "ETH" + }, + { + "assigned_fee": "0.0000001386723451371668272097", + "assigned_quantity": "0.0000019574048293763402810312", + "assigned_timestamp": "2025-11-14T15:33:10.665234182Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390426-L-4", + "original_fee": "0.0025000000000000000000000000", + "original_quantity": "0.0352883054555720234314348225", + "price": "141.69000000", + "remaining_quantity": "0.0352863480507426470911537913", + "symbol": "SOL" + }, + { + "assigned_fee": "0.0000001541606235940104017788", + "assigned_quantity": "0.0018921217992514317493560378", + "assigned_timestamp": "2025-11-14T15:33:10.665234182Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390427-L-2", + "original_fee": "0.0025000000000000000000000000", + "original_quantity": "30.684258975145750230131942314", + "price": "0.16295000", + "remaining_quantity": "30.682366853346498798382586276", + "symbol": "DOGE" + }, + { + "assigned_fee": "0.0000001650022887405019828656", + "assigned_quantity": "0.0001432125059588612445129291", + "assigned_timestamp": "2025-11-14T15:33:10.665234182Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390430-L-3", + "original_fee": "0.0025000000000000000000000000", + "original_quantity": "2.1698563555092652866380245628", + "price": "2.30430000", + "remaining_quantity": "2.1697131430033064253935116337", + "symbol": "XRP" + }, + { + "assigned_fee": "0.0000002151811942866727403946", + "assigned_quantity": "0.0000004654327459831779384515", + "assigned_timestamp": "2025-11-14T15:33:10.665234182Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390428-L-0", + "original_fee": "0.0025000000000000000000000000", + "original_quantity": "0.0054074514681230735954144812", + "price": "924.65000000", + "remaining_quantity": "0.0054069860353770904174760297", + "symbol": "BNB" + }, + { + "assigned_fee": "0.0000036778504314147892998678", + "assigned_quantity": "0.0000000761244030840286618557", + "assigned_timestamp": "2025-11-14T15:33:10.665234182Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390429-L-1", + "original_fee": "0.0024999999999999999999999998", + "original_quantity": "0.0000517451732361131219860377", + "price": "96627.37000000", + "remaining_quantity": "0.0000516690488330290933241820", + "symbol": "BTC" + } + ], + "management_fee": "0.001", + "payment_id": "P-1763134390189", + "position": { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "created_timestamp": "2025-11-14T15:32:57.575189603Z", + "last_update_timestamp": "2025-11-14T15:32:57.575189603Z", + "side_cr": { + "closed_lots": [ + { + "created_timestamp": "2025-11-14T15:32:57.575189603Z", + "last_update_timestamp": "2025-11-14T15:33:10.783466856Z", + "payment_id": "P-1763134377575", + "preauth_amount": "0.000000", + "ready_amount": "0", + "seq_num": "0x21050000000002467758c0d3c9e530ca6d71469bb678e6592274154d9cad", + "spends": [ + { + "client_order_id": "JYA-NIF-EYJ-9644", + "payment_id": "Charges", + "preauth_amount": "0", + "spent_amount": "0.001", + "timestamp": "2025-11-14T15:33:10.184452230Z" + }, + { + "client_order_id": "JYA-NIF-EYJ-9644", + "payment_id": "P-1763134390189", + "preauth_amount": "0", + "spent_amount": "0.009000", + "timestamp": "2025-11-14T15:33:10.783466856Z" + } + ], + "spent_amount": "0.010000", + "unconfirmed_amount": "0" + } + ], + "created_timestamp": "2025-11-14T15:32:57.575189603Z", + "last_update_timestamp": "2025-11-14T15:33:10.184452230Z", + "open_lots": [], + "preauth_balance": "0.000", + "ready_balance": "0.000", + "spent_balance": "0.010", + "unconfirmed_balance": "0.000000" + }, + "side_dr": { + "closed_lots": [], + "created_timestamp": "2025-11-14T15:32:57.575189603Z", + "last_update_timestamp": "2025-11-14T15:32:57.575189603Z", + "open_lots": [], + "preauth_balance": "0", + "ready_balance": "0", + "spent_balance": "0", + "unconfirmed_balance": "0" + } + }, + "seq_num": "0x21050000000002467758c0d3c9e530ca6d71469bb678e6592274154d9cad", + "symbol": "SY100", + "timestamp": "2025-11-14T15:33:10.783466856Z", + "total_amount": "0.01" +} \ No newline at end of file diff --git a/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_UJQ-RQJ-DAT-2626.json b/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_UJQ-RQJ-DAT-2626.json new file mode 100644 index 0000000..0f68474 --- /dev/null +++ b/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_UJQ-RQJ-DAT-2626.json @@ -0,0 +1,194 @@ +{ + "amount_paid": "0.010", + "amount_remaining": "-0.0014574117666911317796647744", + "assets_value": "0.0104521856738542046773261113", + "client_order_id": "UJQ-RQJ-DAT-2626", + "exchange_fee": "0.0000052260928369271023386631", + "fill_rate": "1.1619346407434590866294193778", + "filled_quantity": "0.0000001523222411890208624175", + "lots": [ + { + "assigned_fee": "0.0000001611285626214546365980", + "assigned_quantity": "0.0000022743815741612624263951", + "assigned_timestamp": "2025-11-21T16:32:18.554327486Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390426-L-4", + "original_fee": "0.0025000000000000000000000000", + "original_quantity": "0.0352883054555720234314348225", + "price": "141.69000000", + "remaining_quantity": "0.0352817297190031848101011397", + "symbol": "SOL" + }, + { + "assigned_fee": "0.0000001917223047443913405894", + "assigned_quantity": "0.0001664039445770006861861817", + "assigned_timestamp": "2025-11-21T16:32:18.554327486Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390430-L-3", + "original_fee": "0.0025000000000000000000000000", + "original_quantity": "2.1698563555092652866380245628", + "price": "2.30430000", + "remaining_quantity": "2.1693752451643762572212455183", + "symbol": "XRP" + }, + { + "assigned_fee": "0.0000042734313966089547470062", + "assigned_quantity": "0.0000000884517791720700821518", + "assigned_timestamp": "2025-11-21T16:32:18.554327486Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390429-L-1", + "original_fee": "0.0024999999999999999999999998", + "original_quantity": "0.0000517451732361131219860377", + "price": "96627.37000000", + "remaining_quantity": "0.0000514894397191481365209278", + "symbol": "BTC" + }, + { + "assigned_fee": "0.0000001706585587403538226627", + "assigned_quantity": "0.0000001066209499755429634094", + "assigned_timestamp": "2025-11-21T16:32:18.554327486Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390431-L-5", + "original_fee": "0.0025000000000000000000000000", + "original_quantity": "0.0015619045239002630247218248", + "price": "3201.22000000", + "remaining_quantity": "0.0015615962593206851479273750", + "symbol": "ETH" + }, + { + "assigned_fee": "0.0000001791249702163758630200", + "assigned_quantity": "0.0021985267900138185089905924", + "assigned_timestamp": "2025-11-21T16:32:18.554327486Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390427-L-2", + "original_fee": "0.0025000000000000000000000000", + "original_quantity": "30.684258975145750230131942314", + "price": "0.16295000", + "remaining_quantity": "30.677902551415050324826758282", + "symbol": "DOGE" + }, + { + "assigned_fee": "0.0000002500270439955719287868", + "assigned_quantity": "0.0000005408036424497310956292", + "assigned_timestamp": "2025-11-21T16:32:18.554327486Z", + "created_timestamp": "2025-11-14T15:33:10.426032788Z", + "lot_id": "O-1763134390428-L-0", + "original_fee": "0.0025000000000000000000000000", + "original_quantity": "0.0054074514681230735954144812", + "price": "924.65000000", + "remaining_quantity": "0.0054058878860361367284620144", + "symbol": "BNB" + } + ], + "management_fee": "0.001", + "payment_id": "P-1763742738347", + "position": { + "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", + "chain_id": 8453, + "created_timestamp": "2025-11-14T15:32:57.575189603Z", + "last_update_timestamp": "2025-11-21T16:32:05.403795653Z", + "side_cr": { + "closed_lots": [ + { + "created_timestamp": "2025-11-14T15:32:57.575189603Z", + "last_update_timestamp": "2025-11-14T15:33:10.783466856Z", + "payment_id": "P-1763134377575", + "preauth_amount": "0.000000", + "ready_amount": "0", + "seq_num": "0x21050000000002467758c0d3c9e530ca6d71469bb678e6592274154d9cad", + "spends": [ + { + "client_order_id": "JYA-NIF-EYJ-9644", + "payment_id": "Charges", + "preauth_amount": "0", + "spent_amount": "0.001", + "timestamp": "2025-11-14T15:33:10.184452230Z" + }, + { + "client_order_id": "JYA-NIF-EYJ-9644", + "payment_id": "P-1763134390189", + "preauth_amount": "0", + "spent_amount": "0.009000", + "timestamp": "2025-11-14T15:33:10.783466856Z" + } + ], + "spent_amount": "0.010000", + "unconfirmed_amount": "0" + }, + { + "created_timestamp": "2025-11-20T23:49:25.727853438Z", + "last_update_timestamp": "2025-11-20T23:49:40.900802807Z", + "payment_id": "P-1763682565728", + "preauth_amount": "0.0000000000000000000000000000", + "ready_amount": "0", + "seq_num": "0x210500000000024aa600c0d3c9e530ca6d71469bb678e6592274154d9cad", + "spends": [ + { + "client_order_id": "IZE-KYW-IHL-3516", + "payment_id": "Charges", + "preauth_amount": "0", + "spent_amount": "0.0002754008075625587835608228", + "timestamp": "2025-11-20T23:49:40.551382709Z" + }, + { + "client_order_id": "IZE-KYW-IHL-3516", + "payment_id": "P-1763682580557", + "preauth_amount": "0", + "spent_amount": "0.0097245991924374412164391772", + "timestamp": "2025-11-20T23:49:40.900802807Z" + } + ], + "spent_amount": "0.0100000000000000000000000000", + "unconfirmed_amount": "0" + }, + { + "created_timestamp": "2025-11-21T16:32:05.403795653Z", + "last_update_timestamp": "2025-11-21T16:32:18.659951420Z", + "payment_id": "P-1763742725404", + "preauth_amount": "0.000000", + "ready_amount": "0", + "seq_num": "0x210500000000024b1b81c0d3c9e530ca6d71469bb678e6592274154d9cad", + "spends": [ + { + "client_order_id": "UJQ-RQJ-DAT-2626", + "payment_id": "Charges", + "preauth_amount": "0", + "spent_amount": "0.001", + "timestamp": "2025-11-21T16:32:18.346353176Z" + }, + { + "client_order_id": "UJQ-RQJ-DAT-2626", + "payment_id": "P-1763742738347", + "preauth_amount": "0", + "spent_amount": "0.009000", + "timestamp": "2025-11-21T16:32:18.659951420Z" + } + ], + "spent_amount": "0.010000", + "unconfirmed_amount": "0" + } + ], + "created_timestamp": "2025-11-14T15:32:57.575189603Z", + "last_update_timestamp": "2025-11-21T16:32:18.346353176Z", + "open_lots": [], + "preauth_balance": "0.000", + "ready_balance": "0.000", + "spent_balance": "0.0300000000000000000000000000", + "unconfirmed_balance": "0.000000" + }, + "side_dr": { + "closed_lots": [], + "created_timestamp": "2025-11-14T15:32:57.575189603Z", + "last_update_timestamp": "2025-11-14T15:32:57.575189603Z", + "open_lots": [], + "preauth_balance": "0", + "ready_balance": "0", + "spent_balance": "0", + "unconfirmed_balance": "0" + } + }, + "seq_num": "0x210500000000024b1b81c0d3c9e530ca6d71469bb678e6592274154d9cad", + "symbol": "SY100", + "timestamp": "2025-11-21T16:32:18.659951420Z", + "total_amount": "0.01" +} \ No newline at end of file diff --git a/src/solver/mint_invoice_manager.rs b/src/solver/mint_invoice_manager.rs index 0444227..0cd290a 100644 --- a/src/solver/mint_invoice_manager.rs +++ b/src/solver/mint_invoice_manager.rs @@ -18,6 +18,48 @@ use crate::{ collateral::collateral_position::CollateralPosition, solver::mint_invoice::MintInvoice, }; +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct InvoiceMetadata { + pub chain_id: u32, + pub address: Address, + pub client_order_id: ClientOrderId, + pub payment_id: PaymentId, + pub seq_num: U256, + pub symbol: Symbol, + pub filled_quantity: Amount, + pub total_amount: Amount, + pub amount_paid: Amount, + pub amount_remaining: Amount, + pub management_fee: Amount, + pub assets_value: Amount, + pub exchange_fee: Amount, + pub fill_rate: Amount, + pub timestamp: DateTime, + // NOTE: No lots, no position - those are stored in individual files +} + +impl From<&MintInvoice> for InvoiceMetadata { + fn from(invoice: &MintInvoice) -> Self { + Self { + chain_id: 0, // Will be set by add_invoice + address: Address::default(), // Will be set by add_invoice + client_order_id: invoice.client_order_id.clone(), + payment_id: invoice.payment_id.clone(), + seq_num: invoice.seq_num, + symbol: invoice.symbol.clone(), + filled_quantity: invoice.filled_quantity.clone(), + total_amount: invoice.total_amount, + amount_paid: invoice.amount_paid, + amount_remaining: invoice.amount_remaining, + management_fee: invoice.management_fee, + assets_value: invoice.assets_value, + exchange_fee: invoice.exchange_fee, + fill_rate: invoice.fill_rate, + timestamp: invoice.timestamp, + } + } +} + #[derive(Serialize, Deserialize)] pub struct GetInvoiceData { pub chain_id: u32, @@ -46,117 +88,446 @@ pub struct GetInvoicesData { pub struct MintInvoiceManager { persistence: Arc, - user_invoices: HashMap<(u32, Address), VecDeque>>, - all_invoices: VecDeque<(u32, Address, Arc)>, + + // Store ALL metadata in memory (loaded from root json) + // This is lightweight - no lots, no positions + metadata: Vec, } impl MintInvoiceManager { pub fn new(persistence: Arc) -> Self { Self { persistence, - user_invoices: HashMap::new(), - all_invoices: VecDeque::new(), + metadata: Vec::new(), } } + /// Create a unique key for an invoice + fn create_invoice_key( + chain_id: u32, + address: &Address, + client_order_id: &ClientOrderId, + ) -> String { + format!( + "chain_{}/address_{}/order_{}", + chain_id, + address, + client_order_id + ) + } + + /// Add new invoice pub fn add_invoice( &mut self, chain_id: u32, address: Address, invoice: MintInvoice, ) -> eyre::Result<()> { - let invoices = self.user_invoices.entry((chain_id, address)).or_default(); - let invoice = Arc::new(invoice); - invoices.push_back(invoice.clone()); - self.all_invoices.push_back((chain_id, address, invoice)); + // 1. Store full invoice (with lots & positions) in individual file + let key = Self::create_invoice_key(chain_id, &address, &invoice.client_order_id); + let child_persistence = self.persistence.child(key)?; + + let invoice_value = serde_json::to_value(&invoice)?; + child_persistence.store_value(invoice_value)?; + + // 2. Add metadata (without lots & positions) to root + let mut meta = InvoiceMetadata::from(&invoice); + meta.chain_id = chain_id; + meta.address = address; + self.metadata.push(meta); + + // 3. Save root json (small - just metadata) + self.store()?; + Ok(()) } + /// Get specific invoice (loads full data including lots & positions) pub fn get_invoice( &self, chain_id: u32, address: Address, client_order_id: &ClientOrderId, ) -> eyre::Result> { - let Some(invoices) = self.user_invoices.get(&(chain_id, address)) else { - return Ok(None); - }; + // Check if invoice exists in metadata + let exists = self.metadata.iter().any(|m| + m.chain_id == chain_id + && m.address == address + && m.client_order_id == *client_order_id + ); - let Some(invoice) = invoices - .iter() - .find(|x| x.client_order_id.eq(client_order_id)) - else { + if !exists { return Ok(None); - }; + } - Ok(Some(GetInvoiceData { - chain_id, - address, - invoice: invoice.deref().clone(), - })) + // Load full invoice from individual file + let key = Self::create_invoice_key(chain_id, &address, client_order_id); + let child_persistence = self.persistence.child(key)?; + + if let Some(invoice_value) = child_persistence.load_value()? { + let invoice: MintInvoice = serde_json::from_value(invoice_value)?; + + Ok(Some(GetInvoiceData { + chain_id, + address, + invoice, + })) + } else { + Ok(None) + } } + /// Query invoices by date range (uses metadata only - no file loading!) pub fn get_invoices_in_date_range( &self, from_date: DateTime, to_date: DateTime, ) -> eyre::Result> { - let invoices = self - .all_invoices + // Filter metadata only - no file I/O needed! + let results = self + .metadata .iter() - .rev() - .take_while_inclusive(|(.., x)| from_date <= x.timestamp) - .map(|(chain_id, address, invoice)| (chain_id, address, invoice)) - .collect_vec(); - - let invoices = invoices - .into_iter() - .rev() - .take_while_inclusive(|(.., x)| x.timestamp <= to_date) - .map(|(chain_id, address, invoice)| GetInvoicesData { - chain_id: *chain_id, - address: *address, - client_order_id: invoice.client_order_id.clone(), - symbol: invoice.symbol.clone(), - payment_id: invoice.payment_id.clone(), - seq_num: invoice.seq_num, - filled_quantity: invoice.filled_quantity.clone(), - total_amount: invoice.total_amount, - amount_paid: invoice.amount_paid, - amount_remaining: invoice.amount_remaining, - management_fee: invoice.management_fee, - assets_value: invoice.assets_value, - exchange_fee: invoice.exchange_fee, - fill_rate: invoice.fill_rate, - timestamp: invoice.timestamp, + .filter(|m| m.timestamp >= from_date && m.timestamp <= to_date) + .map(|m| GetInvoicesData { + chain_id: m.chain_id, + address: m.address, + client_order_id: m.client_order_id.clone(), + payment_id: m.payment_id.clone(), + seq_num: m.seq_num, + symbol: m.symbol.clone(), + filled_quantity: m.filled_quantity.clone(), + total_amount: m.total_amount, + amount_paid: m.amount_paid, + amount_remaining: m.amount_remaining, + management_fee: m.management_fee, + assets_value: m.assets_value, + exchange_fee: m.exchange_fee, + fill_rate: m.fill_rate, + timestamp: m.timestamp, }) - .collect_vec(); + .collect(); - Ok(invoices) + Ok(results) } } impl Persist for MintInvoiceManager { + /// Load metadata from root json fn load(&mut self) -> eyre::Result<()> { - self.user_invoices = HashMap::new(); - self.all_invoices = VecDeque::new(); - + self.metadata = Vec::new(); if let Some(mut value) = self.persistence.load_value()? { - if let Some(invoices) = value.get_mut("invoices") { - let all_invoices: Vec<(u32, Address, MintInvoice)> = - serde_json::from_value(invoices.take())?; - - for (chain_id, address, invoice) in all_invoices { - self.add_invoice(chain_id, address, invoice)? - } + if let Some(metadata) = value.get_mut("metadata") { + self.metadata = serde_json::from_value(metadata.take())?; } } Ok(()) } + /// Store metadata to root json fn store(&self) -> eyre::Result<()> { + // Store only metadata (no lots, no positions) self.persistence - .store_value(json!({"invoices": self.all_invoices}))?; + .store_value(json!({ "metadata": self.metadata }))?; + Ok(()) } } + +// #[cfg(test)] +// mod migration { +// use super::*; +// use std::path::PathBuf; +// use symm_core::core::persistence::util::JsonFilePersistence; + +// #[test] +// fn migrate_old_format_to_new_format() -> eyre::Result<()> { +// println!("=== Starting Migration ===\n"); + +// let file_path = PathBuf::from("persistence/InvoiceManager.json"); + +// if !file_path.exists() { +// println!("File not found: {:?}", file_path); +// return Ok(()); +// } + +// // Read old format +// let old_data = std::fs::read_to_string(&file_path)?; +// let old_value: serde_json::Value = serde_json::from_str(&old_data)?; + +// // Check if already in new format +// if old_value.get("metadata").is_some() { +// println!("✓ File is already in new format. Nothing to do."); +// return Ok(()); +// } + +// // Parse old format +// let old_invoices: Vec<(u32, Address, MintInvoice)> = if let Some(invoices) = old_value.get("invoices") { +// serde_json::from_value(invoices.clone())? +// } else { +// println!("No 'invoices' key found. File format unknown."); +// return Ok(()); +// }; + +// println!("Found {} invoices in old format\n", old_invoices.len()); + +// // Create manager with new format +// let persistence = Arc::new(JsonFilePersistence::new(&file_path)); +// let mut manager = MintInvoiceManager::new(persistence); + +// // Add each invoice (creates child files and metadata) +// for (i, (chain_id, address, invoice)) in old_invoices.into_iter().enumerate() { +// println!(" [{}/3] Migrating: {}", i + 1, invoice.client_order_id); + +// // This will: +// // 1. Create child file with full invoice data +// // 2. Add metadata entry +// // 3. Update root file +// manager.add_invoice(chain_id, address, invoice)?; +// } + +// println!("\n=== Migration Complete ==="); +// println!("✓ Created {} child files", manager.metadata.len()); +// println!("✓ Updated root file to new format"); +// println!("✓ Metadata: {} entries", manager.metadata.len()); + +// // Verify by loading +// let mut verification_manager = MintInvoiceManager::new( +// Arc::new(JsonFilePersistence::new(&file_path)) +// ); +// verification_manager.load()?; + +// println!("\n=== Verification ==="); +// println!("✓ Loaded {} metadata entries", verification_manager.metadata.len()); + +// // Try to get one invoice to verify child files work +// if let Some(first_meta) = verification_manager.metadata.first() { +// let result = verification_manager.get_invoice( +// first_meta.chain_id, +// first_meta.address, +// &first_meta.client_order_id +// )?; + +// if result.is_some() { +// println!("✓ Successfully retrieved invoice from child file"); +// } else { +// println!("⚠ Could not retrieve invoice - child file issue"); +// } +// } + +// println!("\n Migration successful! You can now run regular tests."); + +// Ok(()) +// } +// } + +#[cfg(test)] +mod tests { + use super::*; + use std::path::PathBuf; + use symm_core::core::persistence::util::JsonFilePersistence; + + #[test] + fn test_load_new_format() -> eyre::Result<()> { + let file_path = PathBuf::from("persistence/InvoiceManager.json"); + + if !file_path.exists() { + println!("Skipping test - InvoiceManager.json not found"); + return Ok(()); + } + + let persistence = Arc::new(JsonFilePersistence::new(&file_path)); + let mut manager = MintInvoiceManager::new(persistence); + + manager.load()?; + + println!("Loaded {} invoices", manager.metadata.len()); + + assert!(manager.metadata.len() >= 3, "Should have loaded at least 3 invoices"); + + for meta in &manager.metadata { + assert_eq!(meta.chain_id, 8453); + println!(" - {}: {}", meta.client_order_id, meta.symbol); + } + + Ok(()) + } + + #[test] + fn test_get_invoice_with_full_data() -> eyre::Result<()> { + let file_path = PathBuf::from("persistence/InvoiceManager.json"); + + if !file_path.exists() { + println!("Skipping test - InvoiceManager.json not found"); + return Ok(()); + } + + let persistence = Arc::new(JsonFilePersistence::new(&file_path)); + let mut manager = MintInvoiceManager::new(persistence); + manager.load()?; + + if let Some(first_meta) = manager.metadata.first() { + println!("Retrieving invoice: {}", first_meta.client_order_id); + + let result = manager.get_invoice( + first_meta.chain_id, + first_meta.address, + &first_meta.client_order_id + )?; + + assert!(result.is_some(), "Should retrieve invoice"); + + let invoice_data = result.unwrap(); + assert_eq!(invoice_data.invoice.client_order_id, first_meta.client_order_id); + assert_eq!(invoice_data.chain_id, first_meta.chain_id); + + println!(" Invoice: {}", invoice_data.invoice.client_order_id); + println!(" Symbol: {}", invoice_data.invoice.symbol); + println!(" Amount: {}", invoice_data.invoice.total_amount); + println!(" Lots: {}", invoice_data.invoice.lots.len()); + } + + Ok(()) + } + + #[test] + fn test_query_by_date_range() -> eyre::Result<()> { + let file_path = PathBuf::from("persistence/InvoiceManager.json"); + + if !file_path.exists() { + println!("Skipping test - InvoiceManager.json not found"); + return Ok(()); + } + + let persistence = Arc::new(JsonFilePersistence::new(&file_path)); + let mut manager = MintInvoiceManager::new(persistence); + manager.load()?; + + let from = chrono::DateTime::parse_from_rfc3339("2025-11-01T00:00:00Z") + .unwrap() + .with_timezone(&Utc); + let to = chrono::DateTime::parse_from_rfc3339("2025-12-01T00:00:00Z") + .unwrap() + .with_timezone(&Utc); + + let results = manager.get_invoices_in_date_range(from, to)?; + + println!("Found {} invoices in November 2025", results.len()); + assert!(results.len() >= 3); + + for invoice_data in &results { + println!(" - {} ({}) at {}", + invoice_data.client_order_id, + invoice_data.symbol, + invoice_data.timestamp + ); + } + + Ok(()) + } + + #[test] + fn test_get_specific_invoice() -> eyre::Result<()> { + let file_path = PathBuf::from("persistence/InvoiceManager.json"); + + if !file_path.exists() { + println!("Skipping test - InvoiceManager.json not found"); + return Ok(()); + } + + let persistence = Arc::new(JsonFilePersistence::new(&file_path)); + let mut manager = MintInvoiceManager::new(persistence); + manager.load()?; + + // Get known invoice + let chain_id = 8453u32; + let address: Address = "0xc0d3c9e530ca6d71469bb678e6592274154d9cad".parse()?; + let client_order_id: ClientOrderId = "JYA-NIF-EYJ-9644".into(); + + let result = manager.get_invoice(chain_id, address, &client_order_id)?; + + assert!(result.is_some(), "Should find invoice JYA-NIF-EYJ-9644"); + + let invoice_data = result.unwrap(); + assert_eq!(invoice_data.invoice.symbol.to_string(), "SY100"); + assert_eq!(invoice_data.invoice.client_order_id, "JYA-NIF-EYJ-9644".into()); + + println!(" Found invoice JYA-NIF-EYJ-9644"); + println!(" Payment ID: {}", invoice_data.invoice.payment_id); + println!(" Lots: {}", invoice_data.invoice.lots.len()); + + Ok(()) + } + + #[test] + fn test_all_invoices_have_lots() -> eyre::Result<()> { + let file_path = PathBuf::from("persistence/InvoiceManager.json"); + + if !file_path.exists() { + println!("Skipping test - InvoiceManager.json not found"); + return Ok(()); + } + + let persistence = Arc::new(JsonFilePersistence::new(&file_path)); + let mut manager = MintInvoiceManager::new(persistence); + manager.load()?; + + // Get all invoices and verify they have lots + for meta in manager.metadata.clone() { + let result = manager.get_invoice( + meta.chain_id, + meta.address, + &meta.client_order_id + )?; + + if let Some(invoice_data) = result { + assert!(invoice_data.invoice.lots.len() > 0, + "Invoice {} should have lots", meta.client_order_id); + + println!("✓ {}: {} lots", + invoice_data.invoice.client_order_id, + invoice_data.invoice.lots.len() + ); + } + } + + Ok(()) + } + + #[test] + fn test_child_file_structure() -> eyre::Result<()> { + let file_path = PathBuf::from("persistence/InvoiceManager.json"); + + if !file_path.exists() { + println!("Skipping test - InvoiceManager.json not found"); + return Ok(()); + } + + let persistence = Arc::new(JsonFilePersistence::new(&file_path)); + let mut manager = MintInvoiceManager::new(persistence); + manager.load()?; + + // Verify child files exist + if let Some(first_meta) = manager.metadata.first() { + let key = MintInvoiceManager::create_invoice_key( + first_meta.chain_id, + &first_meta.address, + &first_meta.client_order_id + ); + + // Expected path format + let expected_path = format!("persistence/InvoiceManager/{}.json", key); + println!("Expected child file: {}", expected_path); + + // Verify we can load it + let result = manager.get_invoice( + first_meta.chain_id, + first_meta.address, + &first_meta.client_order_id + )?; + + assert!(result.is_some(), "Child file should exist and be loadable"); + } + + Ok(()) + } +} \ No newline at end of file From 7ea197ab3b466ace943ed17f4ad0dda25546d516 Mon Sep 17 00:00:00 2001 From: jafar75 Date: Fri, 28 Nov 2025 20:34:24 +0330 Subject: [PATCH 2/6] small code clean --- src/solver/mint_invoice_manager.rs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/solver/mint_invoice_manager.rs b/src/solver/mint_invoice_manager.rs index 0cd290a..171cb6e 100644 --- a/src/solver/mint_invoice_manager.rs +++ b/src/solver/mint_invoice_manager.rs @@ -1,12 +1,7 @@ -use std::{ - collections::{HashMap, VecDeque}, - ops::Deref, - sync::Arc, -}; +use std::sync::Arc; use alloy_primitives::U256; use chrono::{DateTime, Utc}; -use itertools::Itertools; use serde::{Deserialize, Serialize}; use serde_json::json; use symm_core::core::{ @@ -14,9 +9,7 @@ use symm_core::core::{ persistence::{Persist, Persistence}, }; -use crate::{ - collateral::collateral_position::CollateralPosition, solver::mint_invoice::MintInvoice, -}; +use crate::solver::mint_invoice::MintInvoice; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct InvoiceMetadata { From 85e3f2ee9264d54e8b4642c9c60f39973227bc72 Mon Sep 17 00:00:00 2001 From: Sadhbh Code Date: Fri, 28 Nov 2025 18:08:26 +0000 Subject: [PATCH 3/6] Added persistence to gitignore --- .gitignore | 1 + persistence/InvoiceManager.json | 55 ----- .../order_IZE-KYW-IHL-3516.json | 168 --------------- .../order_JYA-NIF-EYJ-9644.json | 142 ------------- .../order_UJQ-RQJ-DAT-2626.json | 194 ------------------ 5 files changed, 1 insertion(+), 559 deletions(-) delete mode 100644 persistence/InvoiceManager.json delete mode 100644 persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_IZE-KYW-IHL-3516.json delete mode 100644 persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_JYA-NIF-EYJ-9644.json delete mode 100644 persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_UJQ-RQJ-DAT-2626.json diff --git a/.gitignore b/.gitignore index abb984a..3e37bdb 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ CLAUDE.md .deploy /apps/*/out /apps/*/cache +/persistence diff --git a/persistence/InvoiceManager.json b/persistence/InvoiceManager.json deleted file mode 100644 index 24e40d2..0000000 --- a/persistence/InvoiceManager.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "metadata": [ - { - "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", - "amount_paid": "0.010", - "amount_remaining": "0.0000000201692423536161167180", - "assets_value": "0.0089954820897127899888888376", - "chain_id": 8453, - "client_order_id": "JYA-NIF-EYJ-9644", - "exchange_fee": "0.0000044977410448563949944445", - "fill_rate": "0.9999977589730718204314757778", - "filled_quantity": "0.0000001310933459504349211202", - "management_fee": "0.001", - "payment_id": "P-1763134390189", - "seq_num": "0x21050000000002467758c0d3c9e530ca6d71469bb678e6592274154d9cad", - "symbol": "SY100", - "timestamp": "2025-11-14T15:33:10.783466856Z", - "total_amount": "0.01" - }, - { - "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", - "amount_paid": "0.0100000000000000000000000000", - "amount_remaining": "-0.0010526830005014490310057145", - "assets_value": "0.0107718962448164820064416708", - "chain_id": 8453, - "client_order_id": "IZE-KYW-IHL-3516", - "exchange_fee": "0.0000053859481224082410032209", - "fill_rate": "1.1082495000225913925807482659", - "filled_quantity": "0.0000001569814610135035622395", - "management_fee": "0.0002754008075625587835608228", - "payment_id": "P-1763682580557", - "seq_num": "0x210500000000024aa600c0d3c9e530ca6d71469bb678e6592274154d9cad", - "symbol": "SY100", - "timestamp": "2025-11-20T23:49:40.900802807Z", - "total_amount": "0.01" - }, - { - "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", - "amount_paid": "0.010", - "amount_remaining": "-0.0014574117666911317796647744", - "assets_value": "0.0104521856738542046773261113", - "chain_id": 8453, - "client_order_id": "UJQ-RQJ-DAT-2626", - "exchange_fee": "0.0000052260928369271023386631", - "fill_rate": "1.1619346407434590866294193778", - "filled_quantity": "0.0000001523222411890208624175", - "management_fee": "0.001", - "payment_id": "P-1763742738347", - "seq_num": "0x210500000000024b1b81c0d3c9e530ca6d71469bb678e6592274154d9cad", - "symbol": "SY100", - "timestamp": "2025-11-21T16:32:18.659951420Z", - "total_amount": "0.01" - } - ] -} \ No newline at end of file diff --git a/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_IZE-KYW-IHL-3516.json b/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_IZE-KYW-IHL-3516.json deleted file mode 100644 index 4f77731..0000000 --- a/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_IZE-KYW-IHL-3516.json +++ /dev/null @@ -1,168 +0,0 @@ -{ - "amount_paid": "0.0100000000000000000000000000", - "amount_remaining": "-0.0010526830005014490310057145", - "assets_value": "0.0107718962448164820064416708", - "client_order_id": "IZE-KYW-IHL-3516", - "exchange_fee": "0.0000053859481224082410032209", - "fill_rate": "1.1082495000225913925807482659", - "filled_quantity": "0.0000001569814610135035622395", - "lots": [ - { - "assigned_fee": "0.0000044041467545647197440242", - "assigned_quantity": "0.0000000911573347088867211024", - "assigned_timestamp": "2025-11-20T23:49:40.787995229Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390429-L-1", - "original_fee": "0.0024999999999999999999999998", - "original_quantity": "0.0000517451732361131219860377", - "price": "96627.37000000", - "remaining_quantity": "0.0000515778914983202066030796", - "symbol": "BTC" - }, - { - "assigned_fee": "0.0000002576748500608423446179", - "assigned_quantity": "0.0000005573456985039579183861", - "assigned_timestamp": "2025-11-20T23:49:40.787995229Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390428-L-0", - "original_fee": "0.0025000000000000000000000000", - "original_quantity": "0.0054074514681230735954144812", - "price": "924.65000000", - "remaining_quantity": "0.0054064286896785864595576436", - "symbol": "BNB" - }, - { - "assigned_fee": "0.0000001846040296483885199411", - "assigned_quantity": "0.0022657751414346550468374020", - "assigned_timestamp": "2025-11-20T23:49:40.787995229Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390427-L-2", - "original_fee": "0.0025000000000000000000000000", - "original_quantity": "30.684258975145750230131942314", - "price": "0.16295000", - "remaining_quantity": "30.680101078205064143335748874", - "symbol": "DOGE" - }, - { - "assigned_fee": "0.0000001975866903790019190870", - "assigned_quantity": "0.0001714938943531674860799337", - "assigned_timestamp": "2025-11-20T23:49:40.787995229Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390430-L-3", - "original_fee": "0.0025000000000000000000000000", - "original_quantity": "2.1698563555092652866380245628", - "price": "2.30430000", - "remaining_quantity": "2.1695416491089532579074317000", - "symbol": "XRP" - }, - { - "assigned_fee": "0.0000001758786482945378109736", - "assigned_quantity": "0.0000001098822625714807548207", - "assigned_timestamp": "2025-11-20T23:49:40.787995229Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390431-L-5", - "original_fee": "0.0025000000000000000000000000", - "original_quantity": "0.0015619045239002630247218248", - "price": "3201.22000000", - "remaining_quantity": "0.0015617028802706606908907844", - "symbol": "ETH" - }, - { - "assigned_fee": "0.0000001660571494607506645771", - "assigned_quantity": "0.0000023439501653010186262565", - "assigned_timestamp": "2025-11-20T23:49:40.787995229Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390426-L-4", - "original_fee": "0.0025000000000000000000000000", - "original_quantity": "0.0352883054555720234314348225", - "price": "141.69000000", - "remaining_quantity": "0.0352840041005773460725275348", - "symbol": "SOL" - } - ], - "management_fee": "0.0002754008075625587835608228", - "payment_id": "P-1763682580557", - "position": { - "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", - "chain_id": 8453, - "created_timestamp": "2025-11-14T15:32:57.575189603Z", - "last_update_timestamp": "2025-11-20T23:49:25.727853438Z", - "side_cr": { - "closed_lots": [ - { - "created_timestamp": "2025-11-14T15:32:57.575189603Z", - "last_update_timestamp": "2025-11-14T15:33:10.783466856Z", - "payment_id": "P-1763134377575", - "preauth_amount": "0.000000", - "ready_amount": "0", - "seq_num": "0x21050000000002467758c0d3c9e530ca6d71469bb678e6592274154d9cad", - "spends": [ - { - "client_order_id": "JYA-NIF-EYJ-9644", - "payment_id": "Charges", - "preauth_amount": "0", - "spent_amount": "0.001", - "timestamp": "2025-11-14T15:33:10.184452230Z" - }, - { - "client_order_id": "JYA-NIF-EYJ-9644", - "payment_id": "P-1763134390189", - "preauth_amount": "0", - "spent_amount": "0.009000", - "timestamp": "2025-11-14T15:33:10.783466856Z" - } - ], - "spent_amount": "0.010000", - "unconfirmed_amount": "0" - }, - { - "created_timestamp": "2025-11-20T23:49:25.727853438Z", - "last_update_timestamp": "2025-11-20T23:49:40.900802807Z", - "payment_id": "P-1763682565728", - "preauth_amount": "0.0000000000000000000000000000", - "ready_amount": "0", - "seq_num": "0x210500000000024aa600c0d3c9e530ca6d71469bb678e6592274154d9cad", - "spends": [ - { - "client_order_id": "IZE-KYW-IHL-3516", - "payment_id": "Charges", - "preauth_amount": "0", - "spent_amount": "0.0002754008075625587835608228", - "timestamp": "2025-11-20T23:49:40.551382709Z" - }, - { - "client_order_id": "IZE-KYW-IHL-3516", - "payment_id": "P-1763682580557", - "preauth_amount": "0", - "spent_amount": "0.0097245991924374412164391772", - "timestamp": "2025-11-20T23:49:40.900802807Z" - } - ], - "spent_amount": "0.0100000000000000000000000000", - "unconfirmed_amount": "0" - } - ], - "created_timestamp": "2025-11-14T15:32:57.575189603Z", - "last_update_timestamp": "2025-11-20T23:49:40.551382709Z", - "open_lots": [], - "preauth_balance": "0.0000000000000000000000000000", - "ready_balance": "0.0000000000000000000000000000", - "spent_balance": "0.0200000000000000000000000000", - "unconfirmed_balance": "0.0000000000000000000000000000" - }, - "side_dr": { - "closed_lots": [], - "created_timestamp": "2025-11-14T15:32:57.575189603Z", - "last_update_timestamp": "2025-11-14T15:32:57.575189603Z", - "open_lots": [], - "preauth_balance": "0", - "ready_balance": "0", - "spent_balance": "0", - "unconfirmed_balance": "0" - } - }, - "seq_num": "0x210500000000024aa600c0d3c9e530ca6d71469bb678e6592274154d9cad", - "symbol": "SY100", - "timestamp": "2025-11-20T23:49:40.900802807Z", - "total_amount": "0.01" -} \ No newline at end of file diff --git a/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_JYA-NIF-EYJ-9644.json b/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_JYA-NIF-EYJ-9644.json deleted file mode 100644 index 1820619..0000000 --- a/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_JYA-NIF-EYJ-9644.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "amount_paid": "0.010", - "amount_remaining": "0.0000000201692423536161167180", - "assets_value": "0.0089954820897127899888888376", - "client_order_id": "JYA-NIF-EYJ-9644", - "exchange_fee": "0.0000044977410448563949944445", - "fill_rate": "0.9999977589730718204314757778", - "filled_quantity": "0.0000001310933459504349211202", - "lots": [ - { - "assigned_fee": "0.0000001468741616832537423280", - "assigned_quantity": "0.0000000917613670308530762197", - "assigned_timestamp": "2025-11-14T15:33:10.665234182Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390431-L-5", - "original_fee": "0.0025000000000000000000000000", - "original_quantity": "0.0015619045239002630247218248", - "price": "3201.22000000", - "remaining_quantity": "0.0015618127625332321716456051", - "symbol": "ETH" - }, - { - "assigned_fee": "0.0000001386723451371668272097", - "assigned_quantity": "0.0000019574048293763402810312", - "assigned_timestamp": "2025-11-14T15:33:10.665234182Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390426-L-4", - "original_fee": "0.0025000000000000000000000000", - "original_quantity": "0.0352883054555720234314348225", - "price": "141.69000000", - "remaining_quantity": "0.0352863480507426470911537913", - "symbol": "SOL" - }, - { - "assigned_fee": "0.0000001541606235940104017788", - "assigned_quantity": "0.0018921217992514317493560378", - "assigned_timestamp": "2025-11-14T15:33:10.665234182Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390427-L-2", - "original_fee": "0.0025000000000000000000000000", - "original_quantity": "30.684258975145750230131942314", - "price": "0.16295000", - "remaining_quantity": "30.682366853346498798382586276", - "symbol": "DOGE" - }, - { - "assigned_fee": "0.0000001650022887405019828656", - "assigned_quantity": "0.0001432125059588612445129291", - "assigned_timestamp": "2025-11-14T15:33:10.665234182Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390430-L-3", - "original_fee": "0.0025000000000000000000000000", - "original_quantity": "2.1698563555092652866380245628", - "price": "2.30430000", - "remaining_quantity": "2.1697131430033064253935116337", - "symbol": "XRP" - }, - { - "assigned_fee": "0.0000002151811942866727403946", - "assigned_quantity": "0.0000004654327459831779384515", - "assigned_timestamp": "2025-11-14T15:33:10.665234182Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390428-L-0", - "original_fee": "0.0025000000000000000000000000", - "original_quantity": "0.0054074514681230735954144812", - "price": "924.65000000", - "remaining_quantity": "0.0054069860353770904174760297", - "symbol": "BNB" - }, - { - "assigned_fee": "0.0000036778504314147892998678", - "assigned_quantity": "0.0000000761244030840286618557", - "assigned_timestamp": "2025-11-14T15:33:10.665234182Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390429-L-1", - "original_fee": "0.0024999999999999999999999998", - "original_quantity": "0.0000517451732361131219860377", - "price": "96627.37000000", - "remaining_quantity": "0.0000516690488330290933241820", - "symbol": "BTC" - } - ], - "management_fee": "0.001", - "payment_id": "P-1763134390189", - "position": { - "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", - "chain_id": 8453, - "created_timestamp": "2025-11-14T15:32:57.575189603Z", - "last_update_timestamp": "2025-11-14T15:32:57.575189603Z", - "side_cr": { - "closed_lots": [ - { - "created_timestamp": "2025-11-14T15:32:57.575189603Z", - "last_update_timestamp": "2025-11-14T15:33:10.783466856Z", - "payment_id": "P-1763134377575", - "preauth_amount": "0.000000", - "ready_amount": "0", - "seq_num": "0x21050000000002467758c0d3c9e530ca6d71469bb678e6592274154d9cad", - "spends": [ - { - "client_order_id": "JYA-NIF-EYJ-9644", - "payment_id": "Charges", - "preauth_amount": "0", - "spent_amount": "0.001", - "timestamp": "2025-11-14T15:33:10.184452230Z" - }, - { - "client_order_id": "JYA-NIF-EYJ-9644", - "payment_id": "P-1763134390189", - "preauth_amount": "0", - "spent_amount": "0.009000", - "timestamp": "2025-11-14T15:33:10.783466856Z" - } - ], - "spent_amount": "0.010000", - "unconfirmed_amount": "0" - } - ], - "created_timestamp": "2025-11-14T15:32:57.575189603Z", - "last_update_timestamp": "2025-11-14T15:33:10.184452230Z", - "open_lots": [], - "preauth_balance": "0.000", - "ready_balance": "0.000", - "spent_balance": "0.010", - "unconfirmed_balance": "0.000000" - }, - "side_dr": { - "closed_lots": [], - "created_timestamp": "2025-11-14T15:32:57.575189603Z", - "last_update_timestamp": "2025-11-14T15:32:57.575189603Z", - "open_lots": [], - "preauth_balance": "0", - "ready_balance": "0", - "spent_balance": "0", - "unconfirmed_balance": "0" - } - }, - "seq_num": "0x21050000000002467758c0d3c9e530ca6d71469bb678e6592274154d9cad", - "symbol": "SY100", - "timestamp": "2025-11-14T15:33:10.783466856Z", - "total_amount": "0.01" -} \ No newline at end of file diff --git a/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_UJQ-RQJ-DAT-2626.json b/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_UJQ-RQJ-DAT-2626.json deleted file mode 100644 index 0f68474..0000000 --- a/persistence/InvoiceManager/chain_8453/address_0xC0D3C9E530ca6d71469bB678E6592274154D9caD/order_UJQ-RQJ-DAT-2626.json +++ /dev/null @@ -1,194 +0,0 @@ -{ - "amount_paid": "0.010", - "amount_remaining": "-0.0014574117666911317796647744", - "assets_value": "0.0104521856738542046773261113", - "client_order_id": "UJQ-RQJ-DAT-2626", - "exchange_fee": "0.0000052260928369271023386631", - "fill_rate": "1.1619346407434590866294193778", - "filled_quantity": "0.0000001523222411890208624175", - "lots": [ - { - "assigned_fee": "0.0000001611285626214546365980", - "assigned_quantity": "0.0000022743815741612624263951", - "assigned_timestamp": "2025-11-21T16:32:18.554327486Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390426-L-4", - "original_fee": "0.0025000000000000000000000000", - "original_quantity": "0.0352883054555720234314348225", - "price": "141.69000000", - "remaining_quantity": "0.0352817297190031848101011397", - "symbol": "SOL" - }, - { - "assigned_fee": "0.0000001917223047443913405894", - "assigned_quantity": "0.0001664039445770006861861817", - "assigned_timestamp": "2025-11-21T16:32:18.554327486Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390430-L-3", - "original_fee": "0.0025000000000000000000000000", - "original_quantity": "2.1698563555092652866380245628", - "price": "2.30430000", - "remaining_quantity": "2.1693752451643762572212455183", - "symbol": "XRP" - }, - { - "assigned_fee": "0.0000042734313966089547470062", - "assigned_quantity": "0.0000000884517791720700821518", - "assigned_timestamp": "2025-11-21T16:32:18.554327486Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390429-L-1", - "original_fee": "0.0024999999999999999999999998", - "original_quantity": "0.0000517451732361131219860377", - "price": "96627.37000000", - "remaining_quantity": "0.0000514894397191481365209278", - "symbol": "BTC" - }, - { - "assigned_fee": "0.0000001706585587403538226627", - "assigned_quantity": "0.0000001066209499755429634094", - "assigned_timestamp": "2025-11-21T16:32:18.554327486Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390431-L-5", - "original_fee": "0.0025000000000000000000000000", - "original_quantity": "0.0015619045239002630247218248", - "price": "3201.22000000", - "remaining_quantity": "0.0015615962593206851479273750", - "symbol": "ETH" - }, - { - "assigned_fee": "0.0000001791249702163758630200", - "assigned_quantity": "0.0021985267900138185089905924", - "assigned_timestamp": "2025-11-21T16:32:18.554327486Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390427-L-2", - "original_fee": "0.0025000000000000000000000000", - "original_quantity": "30.684258975145750230131942314", - "price": "0.16295000", - "remaining_quantity": "30.677902551415050324826758282", - "symbol": "DOGE" - }, - { - "assigned_fee": "0.0000002500270439955719287868", - "assigned_quantity": "0.0000005408036424497310956292", - "assigned_timestamp": "2025-11-21T16:32:18.554327486Z", - "created_timestamp": "2025-11-14T15:33:10.426032788Z", - "lot_id": "O-1763134390428-L-0", - "original_fee": "0.0025000000000000000000000000", - "original_quantity": "0.0054074514681230735954144812", - "price": "924.65000000", - "remaining_quantity": "0.0054058878860361367284620144", - "symbol": "BNB" - } - ], - "management_fee": "0.001", - "payment_id": "P-1763742738347", - "position": { - "address": "0xc0d3c9e530ca6d71469bb678e6592274154d9cad", - "chain_id": 8453, - "created_timestamp": "2025-11-14T15:32:57.575189603Z", - "last_update_timestamp": "2025-11-21T16:32:05.403795653Z", - "side_cr": { - "closed_lots": [ - { - "created_timestamp": "2025-11-14T15:32:57.575189603Z", - "last_update_timestamp": "2025-11-14T15:33:10.783466856Z", - "payment_id": "P-1763134377575", - "preauth_amount": "0.000000", - "ready_amount": "0", - "seq_num": "0x21050000000002467758c0d3c9e530ca6d71469bb678e6592274154d9cad", - "spends": [ - { - "client_order_id": "JYA-NIF-EYJ-9644", - "payment_id": "Charges", - "preauth_amount": "0", - "spent_amount": "0.001", - "timestamp": "2025-11-14T15:33:10.184452230Z" - }, - { - "client_order_id": "JYA-NIF-EYJ-9644", - "payment_id": "P-1763134390189", - "preauth_amount": "0", - "spent_amount": "0.009000", - "timestamp": "2025-11-14T15:33:10.783466856Z" - } - ], - "spent_amount": "0.010000", - "unconfirmed_amount": "0" - }, - { - "created_timestamp": "2025-11-20T23:49:25.727853438Z", - "last_update_timestamp": "2025-11-20T23:49:40.900802807Z", - "payment_id": "P-1763682565728", - "preauth_amount": "0.0000000000000000000000000000", - "ready_amount": "0", - "seq_num": "0x210500000000024aa600c0d3c9e530ca6d71469bb678e6592274154d9cad", - "spends": [ - { - "client_order_id": "IZE-KYW-IHL-3516", - "payment_id": "Charges", - "preauth_amount": "0", - "spent_amount": "0.0002754008075625587835608228", - "timestamp": "2025-11-20T23:49:40.551382709Z" - }, - { - "client_order_id": "IZE-KYW-IHL-3516", - "payment_id": "P-1763682580557", - "preauth_amount": "0", - "spent_amount": "0.0097245991924374412164391772", - "timestamp": "2025-11-20T23:49:40.900802807Z" - } - ], - "spent_amount": "0.0100000000000000000000000000", - "unconfirmed_amount": "0" - }, - { - "created_timestamp": "2025-11-21T16:32:05.403795653Z", - "last_update_timestamp": "2025-11-21T16:32:18.659951420Z", - "payment_id": "P-1763742725404", - "preauth_amount": "0.000000", - "ready_amount": "0", - "seq_num": "0x210500000000024b1b81c0d3c9e530ca6d71469bb678e6592274154d9cad", - "spends": [ - { - "client_order_id": "UJQ-RQJ-DAT-2626", - "payment_id": "Charges", - "preauth_amount": "0", - "spent_amount": "0.001", - "timestamp": "2025-11-21T16:32:18.346353176Z" - }, - { - "client_order_id": "UJQ-RQJ-DAT-2626", - "payment_id": "P-1763742738347", - "preauth_amount": "0", - "spent_amount": "0.009000", - "timestamp": "2025-11-21T16:32:18.659951420Z" - } - ], - "spent_amount": "0.010000", - "unconfirmed_amount": "0" - } - ], - "created_timestamp": "2025-11-14T15:32:57.575189603Z", - "last_update_timestamp": "2025-11-21T16:32:18.346353176Z", - "open_lots": [], - "preauth_balance": "0.000", - "ready_balance": "0.000", - "spent_balance": "0.0300000000000000000000000000", - "unconfirmed_balance": "0.000000" - }, - "side_dr": { - "closed_lots": [], - "created_timestamp": "2025-11-14T15:32:57.575189603Z", - "last_update_timestamp": "2025-11-14T15:32:57.575189603Z", - "open_lots": [], - "preauth_balance": "0", - "ready_balance": "0", - "spent_balance": "0", - "unconfirmed_balance": "0" - } - }, - "seq_num": "0x210500000000024b1b81c0d3c9e530ca6d71469bb678e6592274154d9cad", - "symbol": "SY100", - "timestamp": "2025-11-21T16:32:18.659951420Z", - "total_amount": "0.01" -} \ No newline at end of file From fe95472d180696d9142bea4eb365b330c0113b5f Mon Sep 17 00:00:00 2001 From: jafar75 Date: Fri, 28 Nov 2025 22:30:55 +0330 Subject: [PATCH 4/6] add executable for migration of invoices --- Cargo.lock | 12 +++ Cargo.toml | 1 + apps/migrate_persistence/Cargo.toml | 12 +++ apps/migrate_persistence/src/main.rs | 114 +++++++++++++++++++++++++++ 4 files changed, 139 insertions(+) create mode 100644 apps/migrate_persistence/Cargo.toml create mode 100644 apps/migrate_persistence/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index dafe99b..2d777c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4212,6 +4212,18 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "migrate_persistence" +version = "0.1.0" +dependencies = [ + "clap", + "eyre", + "index-maker", + "serde", + "serde_json", + "symm-core", +] + [[package]] name = "mime" version = "0.3.17" diff --git a/Cargo.toml b/Cargo.toml index 8551085..7f8a9ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ members = [ "apps/anvil_orchestrator", "apps/anvil_provisioner", "apps/index_deployer", + "apps/migrate_persistence", "apps/tracker", "_deprecated/liquidity_tracker", "_deprecated/alloy-evm-connector", diff --git a/apps/migrate_persistence/Cargo.toml b/apps/migrate_persistence/Cargo.toml new file mode 100644 index 0000000..bb8a9e2 --- /dev/null +++ b/apps/migrate_persistence/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "migrate_persistence" +version = "0.1.0" +edition = "2021" + +[dependencies] +eyre = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +clap = { workspace = true} +index-maker = { workspace = true } +symm-core = { workspace = true } diff --git a/apps/migrate_persistence/src/main.rs b/apps/migrate_persistence/src/main.rs new file mode 100644 index 0000000..e1af729 --- /dev/null +++ b/apps/migrate_persistence/src/main.rs @@ -0,0 +1,114 @@ +use clap::Parser; +use eyre::Result; +use std::path::PathBuf; +use std::sync::Arc; + +// Import from your index-maker project +use index_maker::solver::mint_invoice_manager::MintInvoiceManager; +use symm_core::core::persistence::util::JsonFilePersistence; + +/// Migrate MintInvoiceManager from old format to new composite persistence format +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +struct Args { + /// Path to the InvoiceManager.json file + #[arg(short, long)] + file: PathBuf, + + /// Dry run - don't write any files + #[arg(short, long, default_value_t = false)] + dry_run: bool, +} + +fn main() -> Result<()> { + let args = Args::parse(); + + println!("=== MintInvoiceManager Migration Tool ===\n"); + println!("File: {:?}", args.file); + + if args.dry_run { + println!("Mode: DRY RUN (no files will be written)\n"); + } else { + println!("Mode: LIVE (files will be written)\n"); + } + + // Check if file exists + if !args.file.exists() { + eprintln!("Error: File not found: {:?}", args.file); + std::process::exit(1); + } + + // Read the file + println!("Reading file..."); + let file_content = std::fs::read_to_string(&args.file)?; + let root_value: serde_json::Value = serde_json::from_str(&file_content)?; + + // Check if already migrated + if root_value.get("metadata").is_some() { + println!("✓ File is already in new format (has 'metadata' key)."); + println!("✓ Nothing to do."); + return Ok(()); + } + + // Parse old format + let invoices_array = match root_value.get("invoices") { + Some(inv) => inv, + None => { + eprintln!("Error: No 'invoices' key found. Unknown format."); + std::process::exit(1); + } + }; + + use index_maker::solver::mint_invoice::MintInvoice; + use symm_core::core::bits::Address; + + let old_invoices: Vec<(u32, Address, MintInvoice)> = + serde_json::from_value(invoices_array.clone())?; + + println!("Found {} invoices in old format\n", old_invoices.len()); + + if args.dry_run { + // Just show what would happen + for (i, (chain_id, address, invoice)) in old_invoices.iter().enumerate() { + println!("[{}/{}] Would process: {}", + i + 1, + old_invoices.len(), + invoice.client_order_id + ); + println!(" -> Chain: {}, Address: {}", chain_id, address); + } + + println!("\n Run without --dry-run to apply changes"); + return Ok(()); + } + + // Create backup + let backup_path = args.file.with_extension("json.backup"); + println!("Creating backup: {:?}", backup_path); + std::fs::copy(&args.file, &backup_path)?; + println!("✓ Backup created\n"); + + // Use MintInvoiceManager to do the migration + // This automatically uses the correct key format and child path logic + let persistence = Arc::new(JsonFilePersistence::new(&args.file)); + let mut manager = MintInvoiceManager::new(persistence); + + // Add each invoice - this creates child files automatically + for (i, (chain_id, address, invoice)) in old_invoices.into_iter().enumerate() { + // This will: + // 1. Create child file with full invoice data + // 2. Add metadata entry + // 3. Update root file + manager.add_invoice(chain_id, address, invoice)?; + + println!(" Done"); + } + + println!(); + println!("=== Migration Summary ==="); + println!(" Updated root file with metadata"); + println!(" Backup saved as: {:?}", backup_path); + println!("\n Migration complete!"); + + Ok(()) +} \ No newline at end of file From 760c7a3d1f39a52259fac7a527bcd2d3e41c448a Mon Sep 17 00:00:00 2001 From: jafar75 Date: Fri, 28 Nov 2025 22:44:20 +0330 Subject: [PATCH 5/6] remove commented test + usage guide of the tiny app --- apps/migrate_persistence/README.md | 2 + src/solver/mint_invoice_manager.rs | 86 ------------------------------ 2 files changed, 2 insertions(+), 86 deletions(-) create mode 100644 apps/migrate_persistence/README.md diff --git a/apps/migrate_persistence/README.md b/apps/migrate_persistence/README.md new file mode 100644 index 0000000..eb97eec --- /dev/null +++ b/apps/migrate_persistence/README.md @@ -0,0 +1,2 @@ +### usage +cargo run --release -- --file path_to_file/old_invoice.json \ No newline at end of file diff --git a/src/solver/mint_invoice_manager.rs b/src/solver/mint_invoice_manager.rs index 171cb6e..1f926bf 100644 --- a/src/solver/mint_invoice_manager.rs +++ b/src/solver/mint_invoice_manager.rs @@ -226,92 +226,6 @@ impl Persist for MintInvoiceManager { } } -// #[cfg(test)] -// mod migration { -// use super::*; -// use std::path::PathBuf; -// use symm_core::core::persistence::util::JsonFilePersistence; - -// #[test] -// fn migrate_old_format_to_new_format() -> eyre::Result<()> { -// println!("=== Starting Migration ===\n"); - -// let file_path = PathBuf::from("persistence/InvoiceManager.json"); - -// if !file_path.exists() { -// println!("File not found: {:?}", file_path); -// return Ok(()); -// } - -// // Read old format -// let old_data = std::fs::read_to_string(&file_path)?; -// let old_value: serde_json::Value = serde_json::from_str(&old_data)?; - -// // Check if already in new format -// if old_value.get("metadata").is_some() { -// println!("✓ File is already in new format. Nothing to do."); -// return Ok(()); -// } - -// // Parse old format -// let old_invoices: Vec<(u32, Address, MintInvoice)> = if let Some(invoices) = old_value.get("invoices") { -// serde_json::from_value(invoices.clone())? -// } else { -// println!("No 'invoices' key found. File format unknown."); -// return Ok(()); -// }; - -// println!("Found {} invoices in old format\n", old_invoices.len()); - -// // Create manager with new format -// let persistence = Arc::new(JsonFilePersistence::new(&file_path)); -// let mut manager = MintInvoiceManager::new(persistence); - -// // Add each invoice (creates child files and metadata) -// for (i, (chain_id, address, invoice)) in old_invoices.into_iter().enumerate() { -// println!(" [{}/3] Migrating: {}", i + 1, invoice.client_order_id); - -// // This will: -// // 1. Create child file with full invoice data -// // 2. Add metadata entry -// // 3. Update root file -// manager.add_invoice(chain_id, address, invoice)?; -// } - -// println!("\n=== Migration Complete ==="); -// println!("✓ Created {} child files", manager.metadata.len()); -// println!("✓ Updated root file to new format"); -// println!("✓ Metadata: {} entries", manager.metadata.len()); - -// // Verify by loading -// let mut verification_manager = MintInvoiceManager::new( -// Arc::new(JsonFilePersistence::new(&file_path)) -// ); -// verification_manager.load()?; - -// println!("\n=== Verification ==="); -// println!("✓ Loaded {} metadata entries", verification_manager.metadata.len()); - -// // Try to get one invoice to verify child files work -// if let Some(first_meta) = verification_manager.metadata.first() { -// let result = verification_manager.get_invoice( -// first_meta.chain_id, -// first_meta.address, -// &first_meta.client_order_id -// )?; - -// if result.is_some() { -// println!("✓ Successfully retrieved invoice from child file"); -// } else { -// println!("⚠ Could not retrieve invoice - child file issue"); -// } -// } - -// println!("\n Migration successful! You can now run regular tests."); - -// Ok(()) -// } -// } #[cfg(test)] mod tests { From 91589639c03d395c5f47956345ab5e17ad81edb9 Mon Sep 17 00:00:00 2001 From: Sadhbh Code Date: Fri, 28 Nov 2025 23:18:38 +0000 Subject: [PATCH 6/6] Added alpine deployment for migrate persistence --- Cargo.lock | 1 + Dockerfile | 4 ++++ apps/migrate_persistence/Cargo.toml | 8 ++++++-- deploy_templates/docker-compose.prod.yaml | 15 +++++++++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d777c8..12fbf93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4219,6 +4219,7 @@ dependencies = [ "clap", "eyre", "index-maker", + "openssl", "serde", "serde_json", "symm-core", diff --git a/Dockerfile b/Dockerfile index a8c3a2f..770ba28 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,6 +17,9 @@ RUN cargo build --release --target=x86_64-unknown-linux-musl --features alpine-d # Build tracker RUN cargo build --release -p tracker --target=x86_64-unknown-linux-musl --features alpine-deploy +# Build migrate_persistence +RUN cargo build --release -p migrate_persistence --target=x86_64-unknown-linux-musl --features alpine-deploy + # Stage 2: Create the final, minimal runtime image FROM --platform=linux/amd64 alpine:3.22 @@ -26,6 +29,7 @@ RUN apk add --no-cache ca-certificates COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/index-maker ./ COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/tracker ./ +COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/migrate_persistence ./ COPY --from=builder /app/configs ./configs CMD ["./index-maker", "-b", "0.0.0.0:3000", "-c", "configs", "quote-server"] diff --git a/apps/migrate_persistence/Cargo.toml b/apps/migrate_persistence/Cargo.toml index bb8a9e2..1c5bfe4 100644 --- a/apps/migrate_persistence/Cargo.toml +++ b/apps/migrate_persistence/Cargo.toml @@ -3,10 +3,14 @@ name = "migrate_persistence" version = "0.1.0" edition = "2021" +[features] +alpine-deploy = ["openssl/vendored"] + [dependencies] +clap = { workspace = true} eyre = { workspace = true } +index-maker = { workspace = true } +openssl = { workspace = true, optional = true } serde = { workspace = true } serde_json = { workspace = true } -clap = { workspace = true} -index-maker = { workspace = true } symm-core = { workspace = true } diff --git a/deploy_templates/docker-compose.prod.yaml b/deploy_templates/docker-compose.prod.yaml index 5f28a14..a4fd873 100644 --- a/deploy_templates/docker-compose.prod.yaml +++ b/deploy_templates/docker-compose.prod.yaml @@ -96,6 +96,21 @@ services: restart: unless-stopped + +# migrate-persistence: +# platform: linux/amd64 +# image: ${DOCKER_IMAGE_NAME} +# ports: [] +# +# command: ["./migrate_persistence", "--file", "persistence/InvoiceManager.json" ] +# +# environment: +# RUST_LOG: ${RUST_LOG} +# +# volumes: +# - ./persistence_migration:/app/persistence +# + # index-maker-tracker: # platform: linux/amd64 # image: ${DOCKER_IMAGE_NAME}