diff --git a/CMakeLists.txt b/CMakeLists.txt index d9210ebc2b..1ec4dac85b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,13 +60,13 @@ endif () ##! We fetch our dependencies if (APPLE) FetchContent_Declare(mm2 - URL https://sdk.devbuilds.komodo.earth/dev/mm2_466d4f2-mac-x86-64.zip) + URL https://sdk.devbuilds.komodo.earth/main/mm2_b0fd99e-mac-x86-64.zip) elseif (UNIX AND NOT APPLE) FetchContent_Declare(mm2 - URL https://sdk.devbuilds.komodo.earth/dev/mm2_466d4f2-linux-x86-64.zip) + URL https://sdk.devbuilds.komodo.earth/main/mm2_b0fd99e-linux-x86-64.zip) else () FetchContent_Declare(mm2 - URL https://sdk.devbuilds.komodo.earth/dev/mm2_466d4f2-win-x86-64.zip) + URL https://sdk.devbuilds.komodo.earth/main/mm2_b0fd99e-win-x86-64.zip) endif () #FetchContent_Declare(qmaterial URL https://github.com/KomodoPlatform/Qaterial/archive/last-clang-working-2.zip) diff --git a/atomic_defi_design/Dex/Constants/General.qml b/atomic_defi_design/Dex/Constants/General.qml index 60a60c88a3..0c784d0b98 100644 --- a/atomic_defi_design/Dex/Constants/General.qml +++ b/atomic_defi_design/Dex/Constants/General.qml @@ -476,6 +476,11 @@ QtObject { return coin_info.tx_uri } + function getBlockUri(coin_info) { + if (coin_info.block_uri == "") return "block/" + return coin_info.block_uri + } + function getTxExplorerURL(ticker, txid, add_0x=true) { if(txid !== '') { const coin_info = API.app.portfolio_pg.global_cfg_mdl.get_coin_info(ticker) @@ -684,7 +689,7 @@ QtObject { if (prevent_coin_disabling.running) return false if (ticker === atomic_app_primary_coin || ticker === atomic_app_secondary_coin) return false if (ticker === "ETH") return !General.isParentCoinNeeded("ETH", "ERC-20") - if (ticker === "MATIC") return !General.isParentCoinNeeded("MATIC", "Matic") + if (ticker === "MATIC") return !General.isParentCoinNeeded("MATIC", "PLG-20") if (ticker === "FTM") return !General.isParentCoinNeeded("FTM", "FTM-20") if (ticker === "AVAX") return !General.isParentCoinNeeded("AVAX", "AVX-20") if (ticker === "BNB") return !General.isParentCoinNeeded("BNB", "BEP-20") @@ -722,7 +727,11 @@ QtObject { } function isERC20(current_ticker_infos) { - return current_ticker_infos.type === "ERC-20" || current_ticker_infos.type === "BEP-20" || current_ticker_infos.type == "Matic" + return current_ticker_infos.type === "ERC-20" + || current_ticker_infos.type === "BEP-20" + || current_ticker_infos.type == "PLG-20" + || current_ticker_infos.type == "FTM-20" + || current_ticker_infos.type == "AVX-20" } function isParentCoin(ticker) { diff --git a/atomic_defi_design/Dex/Constants/Style.qml b/atomic_defi_design/Dex/Constants/Style.qml index e53a2422bf..dd10970115 100644 --- a/atomic_defi_design/Dex/Constants/Style.qml +++ b/atomic_defi_design/Dex/Constants/Style.qml @@ -203,7 +203,7 @@ QtObject { case 'QRC-20': return dark_theme ? colorCoinDark["QTUM"] : colorCoin["QTUM"] case 'KRC-20': return dark_theme ? colorCoinDark["KCS"] : colorCoin["KCS"] case 'Smart Chain': return dark_theme ? colorCoinDark["KMD"] : colorCoin["KMD"] - case 'Matic': return dark_theme ? colorCoinDark["MATIC"] : colorCoin["MATIC"] + case 'PLG-20': return dark_theme ? colorCoinDark["MATIC"] : colorCoin["MATIC"] case 'Moonriver': return dark_theme ? colorCoinDark["MOVR"] : colorCoin["MOVR"] case 'HRC-20': return dark_theme ? colorCoinDark["ONE"] : colorCoin["ONE"] case 'SmartBCH': return dark_theme ? colorCoinDark["SBCH"] : colorCoin["SBCH"] @@ -245,7 +245,7 @@ QtObject { case 'QRC-20': return dark_theme ? colorCoinDark["QTUM"] : colorCoin["QTUM"] case 'KRC-20': return dark_theme ? colorCoinDark["KCS"] : colorCoin["KCS"] case 'Smart Chain': return dark_theme ? colorCoinDark["KMD"] : colorCoin["KMD"] - case 'Matic': return dark_theme ? colorCoinDark["MATIC"] : colorCoin["MATIC"] + case 'PLG-20': return dark_theme ? colorCoinDark["MATIC"] : colorCoin["MATIC"] case 'Moonriver': return dark_theme ? colorCoinDark["MOVR"] : colorCoin["MOVR"] case 'HRC-20': return dark_theme ? colorCoinDark["ONE"] : colorCoin["ONE"] case 'SmartBCH': return dark_theme ? colorCoinDark["SBCH"] : colorCoin["SBCH"] diff --git a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Trade.qml b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Trade.qml index ebea341ac2..0665bba275 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Trade.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Trade.qml @@ -398,7 +398,7 @@ ClipRRect // Trade Card width: 60 - text: _selectedTickerIcon.enabled ? atomic_qt_utilities.retrieve_main_ticker(selectedTicker) : qsTr("Pick a coin") + text: _selectedTickerIcon.enabled ? atomic_qt_utilities.retrieve_main_ticker(selectedTicker, false, true) : qsTr("Pick a coin") font.pixelSize: Constants.Style.textSizeSmall2 wrapMode: Text.NoWrap @@ -580,7 +580,7 @@ ClipRRect // Trade Card anchors.leftMargin: 10 width: 60 - text: enabled ? atomic_qt_utilities.retrieve_main_ticker(selectedOrder.coin) : "" + text: enabled ? atomic_qt_utilities.retrieve_main_ticker(selectedOrder.coin, false, true) : "" font.pixelSize: Constants.Style.textSizeSmall2 wrapMode: Text.NoWrap diff --git a/atomic_defi_design/Dex/Settings/AddCustomCoinModal.qml b/atomic_defi_design/Dex/Settings/AddCustomCoinModal.qml index d3dd686fed..d48dffbc28 100644 --- a/atomic_defi_design/Dex/Settings/AddCustomCoinModal.qml +++ b/atomic_defi_design/Dex/Settings/AddCustomCoinModal.qml @@ -14,6 +14,9 @@ MultipageModal id: root width: 700 + horizontalPadding: 20 + verticalPadding: 20 + closePolicy: Popup.NoAutoClose onClosed: { @@ -22,7 +25,7 @@ MultipageModal } property var config_fields: ({}) - property var typeList: ["ERC-20", "QRC-20","BEP-20"] + property var typeList: ["ERC-20", "BEP-20"] // QRC removed due to unresolved issues and lack of use readonly property var custom_token_data: API.app.settings_pg.custom_token_data readonly property string general_message: qsTr('Get the contract address from') readonly property bool fetching_custom_token_data_busy: API.app.settings_pg.fetching_custom_token_data_busy @@ -67,7 +70,7 @@ MultipageModal addToConfig(input_name, "name", input_name.field.text) addToConfig(input_contract_address, "contract_address", input_contract_address.text) addToConfig(input_active, "active", input_active.checked) - addToConfig(input_coingecko_id, "coingecko_id", input_coingecko_id.field.text) + addToConfig(input_coingecko_id, "coingecko_id", input_coingecko_id.field.text) fields['coinType'] = currentType.coinType root.config_fields = General.clone(fields) @@ -86,6 +89,24 @@ MultipageModal { id: type_model + // ListElement + // { + // text: "AVX-20" + // prefix: "" + // url: "https://snowtrace.io/tokens" + // name: 'SnowTrace' + // image: "avax" + // coinType: CoinType.AVX20 + // } + ListElement + { + text: "BEP-20" + prefix: "" + url: "https://bscscan.com/tokens" + name: 'BscScan' + image: "bep" + coinType: CoinType.BEP20 + } ListElement { text: "ERC-20" @@ -95,26 +116,26 @@ MultipageModal name: 'Etherscan' coinType: CoinType.ERC20 } + // ListElement + // { + // text: "PLG-20" + // prefix: "" + // image: "matic" + // url: "https://polygonscan.com/tokens" + // name: 'Polygonscan' + // coinType: CoinType.ERC20 + // } + + // ListElement + // { + // text: "QRC-20" + // prefix: "0x" + // image: "qrc" + // url: "https://explorer.qtum.org/tokens/search" + // name: 'QTUM Insight' + // coinType: CoinType.QRC20 + // } - ListElement - { - text: "QRC-20" - prefix: "0x" - image: "qrc" - url: "https://explorer.qtum.org/tokens/search" - name: 'QTUM Insight' - coinType: CoinType.QRC20 - } - - ListElement - { - text: "BEP-20" - prefix: "" - url: "https://bscscan.com/tokens" - name: 'BscScan' - image: "bep" - coinType: CoinType.BEP20 - } } readonly property bool has_contract_address: typeList.indexOf(input_type.currentText)!==-1 @@ -125,6 +146,9 @@ MultipageModal { titleText: qsTr("Choose the asset type") height: 450 + titleTopMargin: 0 + topMarginAfterTitle: 10 + flickMax: window.height - 480 DefaultComboBox { @@ -401,13 +425,13 @@ MultipageModal // Preview MultipageModalContent { - titleText: qsTr("Preview") + titleText: qsTr("Preview Token Configuration") DefaultText { id: warning_message visible: coin_name.visible Layout.fillWidth: true - text_value: qsTr("WARNING: Application will restart immidiately to apply the changes!") + text_value: qsTr("WARNING: Application will restart immediately to apply the changes!") color: Style.colorRed horizontalAlignment: Text.AlignHCenter } diff --git a/atomic_defi_design/Dex/Settings/SettingModal.qml b/atomic_defi_design/Dex/Settings/SettingModal.qml index 0b4565e827..6fc3ea22c3 100644 --- a/atomic_defi_design/Dex/Settings/SettingModal.qml +++ b/atomic_defi_design/Dex/Settings/SettingModal.qml @@ -20,7 +20,6 @@ Qaterial.Dialog { id: setting_modal property alias selectedMenuIndex: menu_list.currentIndex - readonly property string mm2_version: API.app.settings_pg.get_mm2_version() property var recommended_fiats: API.app.settings_pg.get_recommended_fiats() property var fiats: API.app.settings_pg.get_available_fiats() property var enableable_coins_count: enableable_coins_count_combo_box.currentValue @@ -733,6 +732,29 @@ Qaterial.Dialog onCopyNotificationMsg: qsTr("Qt Version copied to clipboard.") } } + + RowLayout + { + width: parent.width - 30 + anchors.horizontalCenter: parent.horizontalCenter + height: 60 + + DexLabel + { + Layout.alignment: Qt.AlignVCenter + Layout.fillWidth: true + text: qsTr("Peer ID") + } + + DexCopyableLabel + { + Layout.alignment: Qt.AlignVCenter + text: API.app.settings_pg.get_peerid() + onCopyNotificationTitle: qsTr("Peer ID") + onCopyNotificationMsg: qsTr("Peer ID copied to clipboard.") + } + } + } } } diff --git a/atomic_defi_design/Dex/Support/SupportModal.qml b/atomic_defi_design/Dex/Support/SupportModal.qml index 591bf8587d..b850e3885e 100644 --- a/atomic_defi_design/Dex/Support/SupportModal.qml +++ b/atomic_defi_design/Dex/Support/SupportModal.qml @@ -110,16 +110,22 @@ Qaterial.Dialog %1 enables you to natively trade across two different blockchain networks without proxy tokens. You can also place multiple orders with the same funds. For example, you can sell 0.1 BTC for KMD, QTUM, or VRSC — the first order that fills automatically cancels all other orders.").arg(API.app_name) } + FAQLine + { + title: qsTr("Where can I see the orderbook or market statistics online?") + text: qsTr('You can view an online orderbook and market statistics at https://markets.atomicdex.io/, or use the Komodo Wallet in your browser at https://app.komodoplatform.com!') + } + FAQLine { title: qsTr("How long does each atomic swap take?") - text: qsTr('Several factors determine the processing time for each swap. The block time of the traded assets depends on each network (Bitcoin typically being the slowest) Additionally, the user can customize security preferences. For example, (you can ask %1 to consider a KMD transaction as final after just 3 confirmations which makes the swap time shorter compared to waiting for a notarization.').arg(API.app_name) + text: qsTr('Several factors determine the processing time for each swap. The block time of the traded assets depends on each network (Bitcoin typically being the slowest) Additionally, the user can customize security preferences. For example, (you can ask %1 to consider a KMD transaction as final after just 3 confirmations which makes the swap time shorter compared to waiting for a notarization.').arg(API.app_name) } FAQLine { title: qsTr("Do I need to be online for the duration of the swap?") - text: qsTr("Yes. You must remain connected to the internet and have your app running to successfully complete each atomic swap (very short breaks in connectivity are usually fine). Otherwise, there is risk of trade cancellation if you are a maker, and risk of loss of funds if you are a taker. + text: qsTr("Yes. You must remain connected to the internet and have your app running to successfully complete each atomic swap (very short breaks in connectivity are usually fine). Otherwise, there is risk of trade cancellation if you are a maker, and risk of loss of funds if you are a taker. To mitigate this, 'watchertower' nodes have been deployed to monitor the dex network for you and, where possible, complete the swaps for you if your app goes offline. The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. @@ -202,7 +208,7 @@ There is a toggle in settings where you can turn on/off the display of these tra Layout.preferredHeight: column_layout.height hoverEnabled: true - onClicked: Qt.openUrlExternally("https://github.com/KomodoPlatform/komodo-wallet-desktop/pull/2296") + onClicked: Qt.openUrlExternally("https://github.com/KomodoPlatform/komodo-wallet-desktop/pull/2388") ColumnLayout { diff --git a/atomic_defi_design/assets/languages/atomic_defi_de.ts b/atomic_defi_design/assets/languages/atomic_defi_de.ts index 2a7b4afc2f..2686cdcffb 100644 --- a/atomic_defi_design/assets/languages/atomic_defi_de.ts +++ b/atomic_defi_design/assets/languages/atomic_defi_de.ts @@ -58,148 +58,152 @@ AddCustomCoinModal - + Get the contract address from Erhalten Sie die Vertragsadresse von - + Choose the asset type Wählen Sie den Asset-Typ aus - + Cancel Abbrechen - - - + + + Next Weiter - + Contract address Vertragsadresse - + Enter the contract address Geben Sie die Vertragsadresse ein - + Choose the asset ticker Wählen Sie den Asset-Ticker - + Ticker Ticker - + Enter the ticker Geben Sie den Ticker ein - + Get the contract address from Erhalten Sie die Vertragsadresse von - - - - + + + + Previous Vorherige - + Choose the asset logo Wählen Sie ein Logo für das Asset aus - + Browse Durchsuchen - + Please choose the asset logo Bitte wählen Sie für das Asset ein Logo aus - + Configuration Konfiguration - + All configuration fields will be fetched using the contract address you provided. Alle Konfigurationsfelder werden mit der von Ihnen angegebenen Vertragsadresse abgerufen. - + Name Name - + Enter the name Geben Sie den Namen ein - + Coingecko ID Coingecko ID - + Enter the Coingecko ID Geben Sie die Coingecko-ID ein - + Get the Coingecko ID Coingecko-ID erhalten - + Active Aktiv - - + Preview Vorschau - - WARNING: Application will restart immidiately to apply the changes! - WARNUNG: Die Anwendung wird sofort neu gestartet, um die Änderungen zu übernehmen! + + Preview Token Configuration + + WARNING: Application will restart immediately to apply the changes! + + + + Asset not found, please go back and make sure Contract Address is correct Asset nicht gefunden, bitte gehen Sie zurück und stellen Sie sicher, dass die Vertragsadresse korrekt ist - + Config Fields Konfigurationsfelder - + Fetched Data Abgerufene Daten - + Submit & Restart Bestätigen und Neu starten @@ -1511,67 +1515,67 @@ Beispiel: Kennwort = 1234 Suffix=56 Eingabe beim Login=123456Betrag eingeben - + Trading Fee Handelsgebühr - + Minimum Trading Amount Mindesthandelsbetrag - + Wallet %1 already exists WALLETNAME Brieftasche %1 existiert bereits - + %1 balance is lower than the fees amount: %2 %3 Das %1 Guthaben ist niedriger als der Gebührenbetrag: %2 %3 - + Tradable (after fees) %1 balance is lower than minimum trade amount Handelbares %1 Guthaben (nach Gebühren) ist niedriger als der Mindesthandelsbetrag - + Please fill the price field Bitte füllen Sie das Preisfeld aus - + Please fill the volume field - - + + Please wait for %1 to fully activate - - + + %1 volume is lower than minimum trade amount %1 Volumen ist niedriger als der minimale Handelsbetrag - - + + %1 needs to be enabled in order to use %2 %1 muss aktiviert werden, um %2 verwenden zu können - - + + %1 balance needs to be funded, a non-zero balance is required to pay the gas of %2 transactions Das %1 Guthaben muss finanziert werden, ein Guthaben größer Null ist erforderlich, um das Benzin von %2 Transaktionen zu bezahlen - + Unknown Error Unbekannter Fehler @@ -3415,252 +3419,263 @@ Bitte wählen Sie eine neue Order aus. SettingModal - - + + Cancel Abbrechen - + Settings Einstellungen - + General Allgemein - + Language Sprache - + User Interface Benutzeroberfläche - + Security Sicherheit - + Enable Desktop Notifications Desktop-Benachrichtigungen aktivieren - + Hide Poison Transactions in History - + Maximum number of enabled coins Maximale Anzahl aktivierter Coins - + Logs Protokolle - + Open Folder Ordner öffnen - + ZHTLC sync date - + use date sync - + Sync Date - + Reset Zurücksetzen - + Current Font Aktuelle Schriftart - + Current font changed to %1. Aktuelle Schriftart in %1 geändert. - + Theme Thema - + Changing theme to %1 Design zu %1 geändert - + Disable 2FA? 2FA deaktivieren? - + Enter your wallet password to confirm Geben Sie zur Bestätigung das Kennwort ihrer Brieftasche ein - + Type password Kennwort eingeben - + 2FA status 2FA Status - + 2FA disabled successfully 2FA erfolgreich deaktiviert - - + + Ok Ok - + Wrong password! Falsches Kennwort! - + Wallet password is incorrect Kennwort der Brieftasche ist falsch - + Reuse static RPC password - + Application Version Anwendungsversion - + copied to clipboard In die Zwischenablage kopiert - + About & Version Über & Version - - + + Reset wallet configuration Konfiguration der Brieftasche zurücksetzen - + This will restart your wallet with default settings Dadurch wird Ihre Brieftasche mit den Standardeinstellungen neu gestartet - - + + Confirm Bestätigen - + Ask system's password before sending coins ? (2FA) Vor dem Senden von Coins nach dem Kennwort des Systems fragen? (2FA) - + View seed and private keys Seed- und privaten Schlüsseln anzeigen - - + + Show Zeigen - + Setup Camouflage Password Tarnkennwort einrichten - + Open Öffnen - + Disclaimer and ToS Haftungsausschluss und Nutzungsbedingungen - + Application version Anwendungsversion - + MM2 version MM2 Version - + MM2 Version MM2 Version - + MM2 Version copied to clipboard. MM2 Version in die Zwischenablage kopiert. - + + + Peer ID + + + + + Peer ID copied to clipboard. + + + + Qt version Qt Version - + Qt Version Qt Version - + Qt Version copied to clipboard. Qt Version in die Zwischenablage kopiert. - + Search Update Update suchen - + Logout Abmelden @@ -3897,19 +3912,19 @@ Bitte wählen Sie eine neue Order aus. How long does each atomic swap take? Wie lange dauert ein Atomic Swap? - - - Several factors determine the processing time for each swap. The block time of the traded assets depends on each network (Bitcoin typically being the slowest) Additionally, the user can customize security preferences. For example, (you can ask %1 to consider a KMD transaction as final after just 3 confirmations which makes the swap time shorter compared to waiting for a <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/">notarization</a>. - Mehrere Faktoren bestimmen die Bearbeitungszeit für einen Swap. Die Blockzeit der gehandelten Assets hängt vom jeweiligen Netzwerk ab (Bitcoin ist normalerweise das langsamste). Außerdem kann der Benutzer die Sicherheitseinstellungen anpassen. Zum Beispiel (können Sie %1 bitten, eine KMD-Transaktion nach nur 3 Bestätigungen als endgültig zu betrachten, wodurch die Tauschzeit kürzer wird als beim Warten auf eine <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/">Beglaubigung </a>). - Do I need to be online for the duration of the swap? Muss ich für die Dauer des Austauschs online sein? + + + Several factors determine the processing time for each swap. The block time of the traded assets depends on each network (Bitcoin typically being the slowest) Additionally, the user can customize security preferences. For example, (you can ask %1 to consider a KMD transaction as final after just 3 confirmations which makes the swap time shorter compared to waiting for a <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/">notarization</a>. + + - Yes. You must remain connected to the internet and have your app running to successfully complete each atomic swap (very short breaks in connectivity are usually fine). Otherwise, there is risk of trade cancellation if you are a maker, and risk of loss of funds if you are a taker. + Yes. You must remain connected to the internet and have your app running to successfully complete each atomic swap (very short breaks in connectivity are usually fine). Otherwise, there is risk of trade cancellation if you are a maker, and risk of loss of funds if you are a taker. To mitigate this, 'watchertower' nodes have been deployed to monitor the dex network for you and, where possible, complete the swaps for you if your app goes offline. The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. @@ -3918,15 +3933,7 @@ If you go offline, so will your orders, and any that are in progress will fail, When you come back online, your orders will begin to broadcast again at the price you set before you went offline. If there has been significant price movement in the meantime, you might unintentionally offer someone a bargain! For this reason, we recommend cancelling orders before closing %1, or reviewing and revising your prices when restarting %1. - Ja. Sie müssen mit dem Internet verbunden bleiben und die App ausführen, um jeden Atomic Swap erfolgreich abzuschließen (sehr kurze Verbindungsunterbrechungen sind normalerweise in Ordnung). Andernfalls besteht das Risiko einer Orderstornierung, wenn Sie ein Maker sind, und das Risiko eines Geldverlusts, wenn Sie ein Taker sind. - -Das Atomic-Swap-Protokoll erfordert, dass beide Teilnehmer online bleiben und die beteiligten Blockchains überwachen, damit der Prozess atomar bleibt. - -Wenn Sie offline gehen, werden Ihre offenen und laufenden Order fehlschlagen, was zu einem potenziellen Verlust von Handels-/Transaktionsgebühren und einem Warten auf das Timeout des Swaps und die Ausstellung einer Rückerstattung führen kann. Es kann sich auch negativ auf den Reputationswert Ihrer Brieftasche für zukünftige Handelsabgleiche auswirken. - -Wenn Sie wieder online gehen, werden Ihre Order wieder zu dem Preis übertragen, den Sie festgelegt haben, bevor Sie offline gegangen sind. Wenn es in der Zwischenzeit zu erheblichen Preisbewegungen gekommen ist, könnten Sie jemandem unbeabsichtigt ein Schnäppchen anbieten! - -Aus diesem Grund empfehlen wir, Order vor dem Schließen von %1 zu stornieren oder Ihre Preise zu überprüfen und zu überarbeiten, wenn Sie %1 neu starten. + @@ -4546,7 +4553,7 @@ This might take a few minutes... atomic_dex::settings_page - + An error has occurred. @@ -4554,62 +4561,62 @@ This might take a few minutes... atomic_dex::wallet_page - + You do not have enough funds. Sie haben nicht genügend Kapital. - + %1 is not activated: click on the button to enable it or enable it manually %1 ist nicht aktiviert: Klicken Sie auf die Schaltfläche, um es zu aktivieren, oder aktivieren Sie es manuell - + You need to have %1 to pay the gas for %2 transactions. Sie benötigen %1, um das Benzin für %2 Transaktionen zu bezahlen. - + Checksum verification failed for %1. Überprüfung der Prüfsumme für %1 fehlgeschlagen. - + Invalid checksum for %1. Click the button to convert to mixed case address. Ungültige Prüfsumme für %1. Klicken Sie auf die Schaltfläche, um die Adresse in Groß-/Kleinschreibung umzuwandeln. - + Legacy address used for %1. Click the button to convert to a Cashaddress. Legacy-Adresse für %1 verwendet. Klicken Sie auf die Schaltfläche, um sie in eine Cashadresse umzuwandeln. - + %1 address must be prefixed with 0x %1 Adresse muss 0x vorangestellt werden - + %1 address length is invalid, please use a valid address. Länge der %1 Adresse ist ungültig, bitte verwenden Sie eine gültige Adresse. - + %1 address is invalid. %1 Adresse ist ungültig. - + Invalid checksum. Ungültige Prüfsumme. - + %1 address has invalid prefixes. %1 Adresse hat ungültige Vorsilben. - + Backend error: %1 Backend Fehler: %1 diff --git a/atomic_defi_design/assets/languages/atomic_defi_en.ts b/atomic_defi_design/assets/languages/atomic_defi_en.ts index c5f21ab0ca..ce47611e61 100644 --- a/atomic_defi_design/assets/languages/atomic_defi_en.ts +++ b/atomic_defi_design/assets/languages/atomic_defi_en.ts @@ -58,148 +58,152 @@ AddCustomCoinModal - + Get the contract address from - + Choose the asset type - + Cancel Cancel - - - + + + Next - + Contract address - + Enter the contract address - + Choose the asset ticker - + Ticker - + Enter the ticker - + Get the contract address from - - - - + + + + Previous - + Choose the asset logo - + Browse - + Please choose the asset logo - + Configuration - + All configuration fields will be fetched using the contract address you provided. - + Name - + Enter the name - + Coingecko ID - + Enter the Coingecko ID - + Get the Coingecko ID - + Active - - + Preview - - WARNING: Application will restart immidiately to apply the changes! + + Preview Token Configuration + WARNING: Application will restart immediately to apply the changes! + + + + Asset not found, please go back and make sure Contract Address is correct - + Config Fields - + Fetched Data - + Submit & Restart @@ -1510,67 +1514,67 @@ - + Trading Fee - + Minimum Trading Amount - + Wallet %1 already exists WALLETNAME - + %1 balance is lower than the fees amount: %2 %3 - + Tradable (after fees) %1 balance is lower than minimum trade amount - + Please fill the price field - + Please fill the volume field - - + + Please wait for %1 to fully activate - - + + %1 volume is lower than minimum trade amount - - + + %1 needs to be enabled in order to use %2 - - + + %1 balance needs to be funded, a non-zero balance is required to pay the gas of %2 transactions - + Unknown Error @@ -3413,252 +3417,263 @@ Please select a new order. SettingModal - - + + Cancel Cancel - + Settings - + General - + Language - + User Interface - + Security - + Enable Desktop Notifications - + Maximum number of enabled coins - + Logs - + Open Folder - + Reset - + Current Font - + Current font changed to %1. - + Theme - + Changing theme to %1 - + Application Version - + copied to clipboard - + About & Version - + Hide Poison Transactions in History - + ZHTLC sync date - + use date sync - + Sync Date - - + + Reset wallet configuration - + This will restart your wallet with default settings - - + + Confirm - + Ask system's password before sending coins ? (2FA) - + Disable 2FA? - + Enter your wallet password to confirm - + Type password - + 2FA status - + 2FA disabled successfully - - + + Ok - + Wrong password! - + Wallet password is incorrect - + View seed and private keys - - + + Show - + Setup Camouflage Password - + Open - + Reuse static RPC password - + Disclaimer and ToS - + Application version - + MM2 version - + MM2 Version - + MM2 Version copied to clipboard. - + + + Peer ID + + + + + Peer ID copied to clipboard. + + + + Qt version - + Qt Version - + Qt Version copied to clipboard. - + Search Update - + Logout @@ -3894,18 +3909,18 @@ Please select a new order. - - Several factors determine the processing time for each swap. The block time of the traded assets depends on each network (Bitcoin typically being the slowest) Additionally, the user can customize security preferences. For example, (you can ask %1 to consider a KMD transaction as final after just 3 confirmations which makes the swap time shorter compared to waiting for a <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/">notarization</a>. + + Do I need to be online for the duration of the swap? - - Do I need to be online for the duration of the swap? + + Several factors determine the processing time for each swap. The block time of the traded assets depends on each network (Bitcoin typically being the slowest) Additionally, the user can customize security preferences. For example, (you can ask %1 to consider a KMD transaction as final after just 3 confirmations which makes the swap time shorter compared to waiting for a <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/">notarization</a>. - Yes. You must remain connected to the internet and have your app running to successfully complete each atomic swap (very short breaks in connectivity are usually fine). Otherwise, there is risk of trade cancellation if you are a maker, and risk of loss of funds if you are a taker. + Yes. You must remain connected to the internet and have your app running to successfully complete each atomic swap (very short breaks in connectivity are usually fine). Otherwise, there is risk of trade cancellation if you are a maker, and risk of loss of funds if you are a taker. To mitigate this, 'watchertower' nodes have been deployed to monitor the dex network for you and, where possible, complete the swaps for you if your app goes offline. The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. @@ -4528,7 +4543,7 @@ This might take a few minutes... atomic_dex::settings_page - + An error has occurred. @@ -4536,62 +4551,62 @@ This might take a few minutes... atomic_dex::wallet_page - + You do not have enough funds. - + %1 is not activated: click on the button to enable it or enable it manually - + You need to have %1 to pay the gas for %2 transactions. - + Checksum verification failed for %1. - + Invalid checksum for %1. Click the button to convert to mixed case address. - + Legacy address used for %1. Click the button to convert to a Cashaddress. - + %1 address must be prefixed with 0x - + %1 address length is invalid, please use a valid address. - + %1 address is invalid. - + Invalid checksum. - + %1 address has invalid prefixes. - + Backend error: %1 diff --git a/atomic_defi_design/assets/languages/atomic_defi_es.ts b/atomic_defi_design/assets/languages/atomic_defi_es.ts index f739653a59..6999f70a16 100644 --- a/atomic_defi_design/assets/languages/atomic_defi_es.ts +++ b/atomic_defi_design/assets/languages/atomic_defi_es.ts @@ -58,148 +58,152 @@ AddCustomCoinModal - + Get the contract address from Obtener la dirección del contrato de - + Choose the asset type Elija el tipo de activo - + Cancel Cancelar - - - + + + Next Siguiente - + Contract address Dirección del contrato - + Enter the contract address Ingrese la dirección del contrato - + Choose the asset ticker Elija el ticker del activo - + Ticker Ticker - + Enter the ticker Ingrese el ticker - + Get the contract address from Obtener la dirección del contrato de - - - - + + + + Previous Anterior - + Choose the asset logo Elija el logotipo del activo - + Browse Navegar - + Please choose the asset logo Elija el logotipo del activo - + Configuration Configuración - + All configuration fields will be fetched using the contract address you provided. Todos los campos de configuración se obtendrán usando la dirección del contrato que proporcionó. - + Name Nombre - + Enter the name Ingrese el nombre - + Coingecko ID Coingecko ID - + Enter the Coingecko ID Ingrese el Coingecko ID - + Get the Coingecko ID Obtener el Coingecko ID - + Active Activo - - + Preview Vista previa - - WARNING: Application will restart immidiately to apply the changes! - ADVERTENCIA: ¡La aplicación se reiniciará inmediatamente para aplicar los cambios! + + Preview Token Configuration + + WARNING: Application will restart immediately to apply the changes! + + + + Asset not found, please go back and make sure Contract Address is correct Activo no encontrado, regrese y asegúrese de que la dirección del contrato sea correcta - + Config Fields Campos de configuracion - + Fetched Data Datos obtenidos - + Submit & Restart Enviar & Reiniciar @@ -1510,67 +1514,67 @@ Ingrese una cantidad - + Trading Fee Tarifa de Intercambio - + Minimum Trading Amount Cantidad Mínima de Intercambio - + Wallet %1 already exists WALLETNAME Monedero %1 ya existe - + %1 balance is lower than the fees amount: %2 %3 El saldo de %1 es inferior al monto de las tarifas: %2 %3 - + Tradable (after fees) %1 balance is lower than minimum trade amount El saldo de %1 (después de las tarifas) es inferior al monto mínimo de intercambio - + Please fill the price field Por favor complete el campo de precio - + Please fill the volume field Complete el campo de volumen - - + + Please wait for %1 to fully activate Espere a que %1 se active por completo - - + + %1 volume is lower than minimum trade amount El volumen de %1 es inferior al monto mínimo de intercambio - - + + %1 needs to be enabled in order to use %2 %1 debe habilitarse para usar %2 - - + + %1 balance needs to be funded, a non-zero balance is required to pay the gas of %2 transactions se debe rellenar el saldo de %1, se requiere un saldo distinto de cero para pagar el gas de %2 transacciones - + Unknown Error Error Desconocido @@ -3417,252 +3421,263 @@ Seleccione un nuevo pedido. SettingModal - - + + Cancel Cancelar - + Settings Configuración - + General General - + Language Idioma - + User Interface Interfaz - + Security Seguridad - + Enable Desktop Notifications Habilitar notificaciones de escritorio - + Maximum number of enabled coins Número máximo de monedas habilitadas - + Logs Registros - + Open Folder Carpeta Abierta - + Reset Restablecer - + Current Font Fuente Actual - + Current font changed to %1. La fuente actual cambió a %1. - + Theme Tema - + Changing theme to %1 Cambiando el tema a %1 - + Application Version La versión de la aplicación - + copied to clipboard copiado al portapapeles - + About & Version Acerca de & Versión - + Hide Poison Transactions in History - + ZHTLC sync date - + use date sync - + Sync Date - - + + Reset wallet configuration Restablecer configuración de billetera - + This will restart your wallet with default settings Esto reiniciará su billetera con la configuración predeterminada - - + + Confirm Confirmar - + Ask system's password before sending coins ? (2FA) ¿Preguntar la contraseña del sistema antes de enviar monedas? (2FA) - + Disable 2FA? ¿Deshabilitar 2FA? - + Enter your wallet password to confirm Ingrese la contraseña de su billetera para confirmar - + Type password Escriba la contraseña - + 2FA status Estado 2FA - + 2FA disabled successfully 2FA deshabilitado correctamente - - + + Ok Ok - + Wrong password! ¡Contraseña incorrecta! - + Wallet password is incorrect Contraseña de la billetera es incorrecta - + View seed and private keys Ver semilla y claves privadas - - + + Show Mostrar - + Setup Camouflage Password Configuración de Contraseña Camuflaje - + Open Abrir - + Reuse static RPC password - + Disclaimer and ToS Descargo de Responsabilidad y Terminos de Servicio - + Application version Versión de Aplicación - + MM2 version Versión MM2 - + MM2 Version Versión MM2 - + MM2 Version copied to clipboard. Versión MM2 copiada al portapapeles. - + + + Peer ID + + + + + Peer ID copied to clipboard. + + + + Qt version Versión Qt - + Qt Version Versión Qt - + Qt Version copied to clipboard. Versión de Qt copiada al portapapeles. - + Search Update Buscar Actualizacion - + Logout Cerrar sesión @@ -3899,19 +3914,19 @@ Seleccione un nuevo pedido. How long does each atomic swap take? ¿Cuánto tiempo toma cada intercambio atómico? - - - Several factors determine the processing time for each swap. The block time of the traded assets depends on each network (Bitcoin typically being the slowest) Additionally, the user can customize security preferences. For example, (you can ask %1 to consider a KMD transaction as final after just 3 confirmations which makes the swap time shorter compared to waiting for a <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/">notarization</a>. - Varios factores determinan el tiempo de procesamiento de cada intercambio. El tiempo de bloqueo de los activos negociados depende de cada red (Bitcoin suele ser la más lenta). Además, el usuario puede personalizar las preferencias de seguridad. Por ejemplo, (puede pedirle a %1 que considere una transacción KMD como final después de solo 3 confirmaciones, lo que hace que el tiempo de intercambio sea más corto en comparación con esperar un <a href="https://komodoplatform.com/security-delayed- prueba de trabajo-dpow/">certificación notarial</a>. - Do I need to be online for the duration of the swap? ¿Necesito estar en línea durante la duración del intercambio? + + + Several factors determine the processing time for each swap. The block time of the traded assets depends on each network (Bitcoin typically being the slowest) Additionally, the user can customize security preferences. For example, (you can ask %1 to consider a KMD transaction as final after just 3 confirmations which makes the swap time shorter compared to waiting for a <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/">notarization</a>. + + - Yes. You must remain connected to the internet and have your app running to successfully complete each atomic swap (very short breaks in connectivity are usually fine). Otherwise, there is risk of trade cancellation if you are a maker, and risk of loss of funds if you are a taker. + Yes. You must remain connected to the internet and have your app running to successfully complete each atomic swap (very short breaks in connectivity are usually fine). Otherwise, there is risk of trade cancellation if you are a maker, and risk of loss of funds if you are a taker. To mitigate this, 'watchertower' nodes have been deployed to monitor the dex network for you and, where possible, complete the swaps for you if your app goes offline. The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. @@ -3920,15 +3935,7 @@ If you go offline, so will your orders, and any that are in progress will fail, When you come back online, your orders will begin to broadcast again at the price you set before you went offline. If there has been significant price movement in the meantime, you might unintentionally offer someone a bargain! For this reason, we recommend cancelling orders before closing %1, or reviewing and revising your prices when restarting %1. - Sí. Debe permanecer conectado a Internet y tener su aplicación ejecutándose para completar con éxito cada intercambio atómico (las interrupciones muy breves en la conectividad generalmente están bien). De lo contrario, existe el riesgo de cancelación de la operación si es un creador y el riesgo de pérdida de fondos si es un tomador. - -El protocolo de intercambio atómico requiere que ambos participantes permanezcan en línea y monitoreen las cadenas de bloques involucradas para que el proceso permanezca atómico. - -Si se desconecta, también lo harán sus pedidos, y cualquiera que esté en curso fallará, lo que provocará una posible pérdida de tarifas comerciales / de transacción, y una espera para que el intercambio se agote y emita un reembolso. También puede afectar negativamente el puntaje de reputación de su billetera para futuras coincidencias comerciales. - -Cuando vuelva a estar en línea, sus pedidos comenzarán a transmitirse nuevamente al precio que estableció antes de desconectarse. Si ha habido un movimiento de precios significativo en el ínterin, ¡es posible que involuntariamente le ofrezcas a alguien una ganga! - -Por este motivo, recomendamos cancelar los pedidos antes de cerrar %1 o revisar y revisar sus precios al reiniciar %1. + @@ -4549,7 +4556,7 @@ Esto puede tardar unos minutos... atomic_dex::settings_page - + An error has occurred. Se ha producido un error. @@ -4557,62 +4564,62 @@ Esto puede tardar unos minutos... atomic_dex::wallet_page - + You do not have enough funds. No tiene fondos suficientes. - + %1 is not activated: click on the button to enable it or enable it manually %1 no está activado: haga clic en el botón para habilitarlo o habilítelo manualmente - + You need to have %1 to pay the gas for %2 transactions. Necesita tener %1 para pagar la gasolina de %2 transacciones. - + Checksum verification failed for %1. La verificación de la suma de comprobación falló para %1. - + Invalid checksum for %1. Click the button to convert to mixed case address. Suma de comprobación no válida para %1. Haga clic en el botón para convertir a dirección de mayúsculas y minúsculas. - + Legacy address used for %1. Click the button to convert to a Cashaddress. Dirección heredada utilizada para %1. Haga clic en el botón para convertir a una dirección de efectivo. - + %1 address must be prefixed with 0x La dirección %1 debe tener el prefijo 0x - + %1 address length is invalid, please use a valid address. La longitud de la dirección %1 no es válida, utilice una dirección válida. - + %1 address is invalid. La dirección %1 no es válida. - + Invalid checksum. Suma de comprobación no válida. - + %1 address has invalid prefixes. La dirección %1 tiene prefijos no válidos. - + Backend error: %1 Error de backend: %1 diff --git a/atomic_defi_design/assets/languages/atomic_defi_fr.ts b/atomic_defi_design/assets/languages/atomic_defi_fr.ts index c342c96189..6322084b96 100644 --- a/atomic_defi_design/assets/languages/atomic_defi_fr.ts +++ b/atomic_defi_design/assets/languages/atomic_defi_fr.ts @@ -58,148 +58,152 @@ AddCustomCoinModal - + Choose the asset type Choisir le type d'actif - + Cancel Annuler - - - + + + Next Suivant - + Enter the contract address Entrer l'adresse du contrat - + Choose the asset ticker Choisissez le symbole de l'actif - + Ticker Symbole - + Enter the ticker Entrez le symbole - + Get the contract address from Obtenez l'adresse du contrat de - + Contract address - + Get the contract address from Obtenez l'adresse du contrat de - - - - + + + + Previous Précedent - + Choose the asset logo Choisissez le logo de l'actif - + Browse Naviguer - + Please choose the asset logo S'il-vous-plaît choissisez le logo de l'actif - + Configuration Configuration - + All configuration fields will be fetched using the contract address you provided. Tous les champs de configuration vont être récupérés à partir de l'adresse du contrat que vous avez fournis. - + Name Nom - + Enter the name Entrez le nom - + Coingecko ID Coingecko ID - + Enter the Coingecko ID Entrer l'identifiant coingecko - + Get the Coingecko ID Récupérer l'identifiant coingecko - + Active Actif - - + Preview Pré-visualisation - - WARNING: Application will restart immidiately to apply the changes! - AVERTISSEMENT: l'application redémarrera immédiatement pour appliquer les modifications! + + Preview Token Configuration + + WARNING: Application will restart immediately to apply the changes! + + + + Asset not found, please go back and make sure Contract Address is correct Actif introuvable, veuillez revenir en arrière et vous assurer que l'adresse du contrat est correcte - + Config Fields Champs de configuration - + Fetched Data Données récupérées - + Submit & Restart Soumettre et redémarrer @@ -1510,67 +1514,67 @@ Entrez un montant - + Trading Fee Frais d'échanges - + Minimum Trading Amount Frais d'échange minimum - + Wallet %1 already exists WALLETNAME Le portefeuille %1 existe déjà - + %1 balance is lower than the fees amount: %2 %3 La %1 balance est inférieur aux frais: %2 %3 - + Tradable (after fees) %1 balance is lower than minimum trade amount Le solde négociable (après frais) %1 est inférieur au montant minimum de la transaction - + Please fill the price field Veuillez remplir le champ de prix - + Please fill the volume field - - + + Please wait for %1 to fully activate - - + + %1 volume is lower than minimum trade amount Le volume de %1 est inférieur au montant minimum de la transaction - - + + %1 needs to be enabled in order to use %2 %1 doit être activé pour utiliser %2 - - + + %1 balance needs to be funded, a non-zero balance is required to pay the gas of %2 transactions Le solde %1 doit être financé, un solde différent de zéro est requis pour payer les frais de transactions de %2 - + Unknown Error Erreur inconnue @@ -3413,252 +3417,263 @@ Please select a new order. SettingModal - - + + Cancel Annuler - + Settings Réglages - + Language Langue - + User Interface Interface utilsateur - + Security Sécurité - + General Général - + About & Version À propos & version - + Enable Desktop Notifications Activer les notifications - + Hide Poison Transactions in History - + Maximum number of enabled coins Nombre maximum d'actifs activés - + Logs Journaux - + Open Folder Ouvrir le dossier - + ZHTLC sync date - + use date sync - + Sync Date - - + + Reset wallet configuration Réinitialiser la configuration du portefeuille - + This will restart your wallet with default settings Cela redémarrera votre portefeuille avec les paramètres par défaut - - + + Confirm Confirmer - + Changing theme to %1 Changer le thème en %1 - + Disable 2FA? - + Enter your wallet password to confirm - + Type password Tapez votre mot de passe - + 2FA status - + 2FA disabled successfully - - + + Ok Ok - + Wrong password! - + Wallet password is incorrect - + Reuse static RPC password - + Application Version - + copied to clipboard copié dans le presse-papier - + Reset Réinitialiser - + Current Font Police actuelle - + Current font changed to %1. La police actuelle est passée à %1. - + Theme Thème - + Ask system's password before sending coins ? (2FA) Demander le mot de passe du système avant d'envoyer des actifs ? (2FA) - + Application version Version de l'application - + MM2 version Version de MM2 - + MM2 Version MM2 Version - + MM2 Version copied to clipboard. MM2 Version copiée dans le presse-papiers. - + + + Peer ID + + + + + Peer ID copied to clipboard. + + + + Qt version Version de Qt - + Qt Version Qt Version - + Qt Version copied to clipboard. Version Qt copiée dans le presse-papiers. - + Search Update Rechercher une mise à jour - + Logout Se déconnecter - + View seed and private keys Afficher la phrase de récupération et les clefs privées - - + + Show Montrer - + Setup Camouflage Password Configurer le mot de passe de camouflage - + Open Ouvrir - + Disclaimer and ToS Clause de non-responsabilité et conditions d'utilisation @@ -3893,21 +3908,19 @@ Please select a new order. How long does each atomic swap take? Combien de temps dure chaque échange atomique ? - - - Several factors determine the processing time for each swap. The block time of the traded assets depends on each network (Bitcoin typically being the slowest) Additionally, the user can customize security preferences. For example, (you can ask %1 to consider a KMD transaction as final after just 3 confirmations which makes the swap time shorter compared to waiting for a <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/">notarization</a>. - Les autres DEX ne vous permettent généralement d'échanger que des actifs basés sur un seul réseau de blockchain, d'utiliser des jetons proxy et de ne passer qu'une seule commande avec les mêmes fonds. - -Plusieurs facteurs déterminent le temps de traitement de chaque swap. Le temps de blocage des actifs échangés dépend de chaque réseau (Bitcoin étant généralement le plus lent). De plus, l'utilisateur peut personnaliser ses préférences de sécurité. Par exemple, (vous pouvez demander à %1 de considérer une transaction KMD comme finale après seulement 3 confirmations, ce qui raccourcit le temps d'échange par rapport à l'attente d'une <a href="https://komodoplatform.com/security-delayed-proof- of-work-dpow/">notarisation</a>. - Do I need to be online for the duration of the swap? Dois-je être en ligne pendant toute la durée du swap ? + + + Several factors determine the processing time for each swap. The block time of the traded assets depends on each network (Bitcoin typically being the slowest) Additionally, the user can customize security preferences. For example, (you can ask %1 to consider a KMD transaction as final after just 3 confirmations which makes the swap time shorter compared to waiting for a <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/">notarization</a>. + + - Yes. You must remain connected to the internet and have your app running to successfully complete each atomic swap (very short breaks in connectivity are usually fine). Otherwise, there is risk of trade cancellation if you are a maker, and risk of loss of funds if you are a taker. + Yes. You must remain connected to the internet and have your app running to successfully complete each atomic swap (very short breaks in connectivity are usually fine). Otherwise, there is risk of trade cancellation if you are a maker, and risk of loss of funds if you are a taker. To mitigate this, 'watchertower' nodes have been deployed to monitor the dex network for you and, where possible, complete the swaps for you if your app goes offline. The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. @@ -4530,7 +4543,7 @@ This might take a few minutes... atomic_dex::settings_page - + An error has occurred. @@ -4538,62 +4551,62 @@ This might take a few minutes... atomic_dex::wallet_page - + You do not have enough funds. Vous n'avez pas assez de fonds. - + %1 is not activated: click on the button to enable it or enable it manually %1 n'est pas activé : cliquez sur le bouton pour l'activer ou l'activer manuellement - + You need to have %1 to pay the gas for %2 transactions. Vous devez avoir %1 activée pour payer les frais de transactions de %2. - + Checksum verification failed for %1. Échec de la vérification du checksum de contrôle pour %1. - + Invalid checksum for %1. Click the button to convert to mixed case address. - + Legacy address used for %1. Click the button to convert to a Cashaddress. - + %1 address must be prefixed with 0x L'adresse %1 doit être précédée de 0x - + %1 address length is invalid, please use a valid address. La longueur de l'adresse %1 n'est pas valide, veuillez utiliser une adresse valide. - + %1 address is invalid. L'adresse %1 n'est pas valide. - + Invalid checksum. Somme de contrôle invalide. - + %1 address has invalid prefixes. L'adresse %1 a des préfixes non valides. - + Backend error: %1 Erreur de backend : %1 diff --git a/atomic_defi_design/assets/languages/atomic_defi_ru.ts b/atomic_defi_design/assets/languages/atomic_defi_ru.ts index bca0ddeeae..b45eb47eba 100644 --- a/atomic_defi_design/assets/languages/atomic_defi_ru.ts +++ b/atomic_defi_design/assets/languages/atomic_defi_ru.ts @@ -58,148 +58,152 @@ AddCustomCoinModal - + Choose the asset type Выберите тип монеты - + Cancel Отменить - - - + + + Next Далее - + Enter the contract address Введите адрес контракта - + Choose the asset ticker Введите тикер монеты - + Ticker Тикер - + Enter the ticker Введите тикер - + Get the contract address from Получить адрес контракта от - + Contract address - + Get the contract address from Получить адрес контракта от - - - - + + + + Previous Назад - + Choose the asset logo Загрузите логотип монеты - + Browse Выбрать - + Please choose the asset logo Выберите логотип монеты - + Configuration Конфигурация - + All configuration fields will be fetched using the contract address you provided. Все параметры конфигурации будут получены с помощью адреса контракта. - + Name Название - + Enter the name Введите название - + Coingecko ID Coingecko ID - + Enter the Coingecko ID Введите Coingecko ID - + Get the Coingecko ID Получить Coingecko ID - + Active Активно - - + Preview Превью - - WARNING: Application will restart immidiately to apply the changes! - ПРЕДУПРЕЖДЕНИЕ: Приложение будет немедленно перезапущено для применения изменений! + + Preview Token Configuration + + WARNING: Application will restart immediately to apply the changes! + + + + Asset not found, please go back and make sure Contract Address is correct Токен не найден, убедитесь, что адрес контракта указан верно - + Config Fields Параметры конфигурации - + Fetched Data Полученные данные - + Submit & Restart Отправить и перезапустить @@ -1516,67 +1520,67 @@ Введите количество - + Trading Fee Торговая комиссия - + Minimum Trading Amount Минимальный объем сделки - + Wallet %1 already exists WALLETNAME Кошелек %1 уже существует - + %1 balance is lower than the fees amount: %2 %3 %1 баланс менее чем размер комиссий: %2 %3 - + Tradable (after fees) %1 balance is lower than minimum trade amount Торгуемый (после комиссий) баланс %1 - меньше минимальной суммы сделки - + Please fill the price field Пожалуйста, укажите цену - + Please fill the volume field - - + + Please wait for %1 to fully activate - - + + %1 volume is lower than minimum trade amount Сумма %1 меньше минимальной суммы сделки - - + + %1 needs to be enabled in order to use %2 %1 должен быть активным для использования %2 - - + + %1 balance needs to be funded, a non-zero balance is required to pay the gas of %2 transactions нужно пополнить баланс %1 для оплаты газа %2 транзакций - + Unknown Error Неизвестная ошибка @@ -3419,252 +3423,263 @@ Please select a new order. SettingModal - - + + Cancel Отмена - + Settings Настройки - + Language Язык - + User Interface Интерфейс - + Security Приватность - + General Общие - + About & Version О программе - + Enable Desktop Notifications Включить уведомления для рабочего стола - + Hide Poison Transactions in History - + Maximum number of enabled coins Макс. количество активированных монет - + Logs Логи - + Open Folder Открыть папку с логами - + ZHTLC sync date - + use date sync - + Sync Date - - + + Reset wallet configuration Сбросить конфигурацию кошелька - + This will restart your wallet with default settings Эта опция перезапустит ваш кошелек с настройками по умолчанию - - + + Confirm Подтвердить - + Changing theme to %1 Изменить тему на %1 - + Disable 2FA? - + Enter your wallet password to confirm - + Type password Введите пароль - + 2FA status - + 2FA disabled successfully - - + + Ok Ок - + Wrong password! - + Wallet password is incorrect - + Reuse static RPC password - + Application Version - + copied to clipboard скопировано в буфер - + Reset Сбросить - + Current Font Текущий шрифт - + Current font changed to %1. Текущий шрифт изменен на %1. - + Theme Тема - + Ask system's password before sending coins ? (2FA) Спрашивать системный пароль перед отправкой монет? (2FA) - + Application version Версия приложения - + MM2 version Версия MM2 - + MM2 Version Версия MM2 - + MM2 Version copied to clipboard. Версия MM2 скопирована в буфер обмена. - + + + Peer ID + + + + + Peer ID copied to clipboard. + + + + Qt version Версия Qt - + Qt Version Версия Qt - + Qt Version copied to clipboard. Версия Qt скопирована в буфер обмена. - + Search Update Проверить на обновления - + Logout Выход - + View seed and private keys Показать seed-фразу и приватные ключи - - + + Show Показать - + Setup Camouflage Password Установить камуфляжный пароль - + Open Установить - + Disclaimer and ToS Дисклеймер и Условия Использования @@ -3899,19 +3914,19 @@ Please select a new order. How long does each atomic swap take? Сколько времени занимает каждый атомарный своп? - - - Several factors determine the processing time for each swap. The block time of the traded assets depends on each network (Bitcoin typically being the slowest) Additionally, the user can customize security preferences. For example, (you can ask %1 to consider a KMD transaction as final after just 3 confirmations which makes the swap time shorter compared to waiting for a <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/">notarization</a>. - Несколько факторов определяют время завершения каждого Атомарного Свопа. Время блока на каждой из торгуемых сетей (Bitcoin обычно самый медленный) В добавок каждый юзер может кастомизировать опции защиты. Например в пред-настройках Свопа, (вы можете установить %1 так чтобы протокол считал транзакцию KMD финальной как только она получит всего 3 подтверждения что уменьшает время Атомарного Свопа в сравнении с ожиданием <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/">нотаризации</a>. - Do I need to be online for the duration of the swap? Необходимо ли мне быть в сети во время свопа? + + + Several factors determine the processing time for each swap. The block time of the traded assets depends on each network (Bitcoin typically being the slowest) Additionally, the user can customize security preferences. For example, (you can ask %1 to consider a KMD transaction as final after just 3 confirmations which makes the swap time shorter compared to waiting for a <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/">notarization</a>. + + - Yes. You must remain connected to the internet and have your app running to successfully complete each atomic swap (very short breaks in connectivity are usually fine). Otherwise, there is risk of trade cancellation if you are a maker, and risk of loss of funds if you are a taker. + Yes. You must remain connected to the internet and have your app running to successfully complete each atomic swap (very short breaks in connectivity are usually fine). Otherwise, there is risk of trade cancellation if you are a maker, and risk of loss of funds if you are a taker. To mitigate this, 'watchertower' nodes have been deployed to monitor the dex network for you and, where possible, complete the swaps for you if your app goes offline. The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. @@ -4534,7 +4549,7 @@ This might take a few minutes... atomic_dex::settings_page - + An error has occurred. @@ -4542,62 +4557,62 @@ This might take a few minutes... atomic_dex::wallet_page - + You do not have enough funds. У вас не достаточно средств. - + %1 is not activated: click on the button to enable it or enable it manually %1 не активирован: нажмите на кнопку чтобы активировать или сделайте это вручную - + You need to have %1 to pay the gas for %2 transactions. Вам нужен %1 для оплаты газа за %2 транзакции. - + Checksum verification failed for %1. Checksum верфикация неуспешна для %1. - + Invalid checksum for %1. Click the button to convert to mixed case address. - + Legacy address used for %1. Click the button to convert to a Cashaddress. - + %1 address must be prefixed with 0x %1 адрес должен начинаться с 0x - + %1 address length is invalid, please use a valid address. %1 длина адреса не валидна, пожалуйста используйте валидный адрес. - + %1 address is invalid. некорректный адрес %1. - + Invalid checksum. Неверная чек-сумма. - + %1 address has invalid prefixes. у адреса %1 неверный префикс. - + Backend error: %1 Ошибка бэкенда: %1 diff --git a/atomic_defi_design/assets/languages/atomic_defi_tr.ts b/atomic_defi_design/assets/languages/atomic_defi_tr.ts index 6b3fca8014..ad83b47c82 100644 --- a/atomic_defi_design/assets/languages/atomic_defi_tr.ts +++ b/atomic_defi_design/assets/languages/atomic_defi_tr.ts @@ -58,148 +58,152 @@ AddCustomCoinModal - + Choose the asset type Varlık türünü seçin - + Cancel İptal - - - + + + Next İleri - + Enter the contract address Kontrat adresini girin - + Choose the asset ticker Varlık kodunu girin - + Ticker Varlık Kodu - + Enter the ticker Varlık kodunu girin - + Get the contract address from Kontrat adresini şuradan alın - + Contract address - + Get the contract address from Kontrat adresini şuradan alın - - - - + + + + Previous Geri - + Choose the asset logo Varlık logosunu seçin - + Browse Göz at - + Please choose the asset logo Lütfen varlık logosunu seçin - + Configuration Konfigürasyon - + All configuration fields will be fetched using the contract address you provided. Tüm konfigürasyon bilgileri verdiğiniz kontrat adresinden edinilip doldurulacak. - + Name İsim - + Enter the name İsmi girin - + Coingecko ID Coingecko ID - + Enter the Coingecko ID Coingecko ID'sini girin - + Get the Coingecko ID Coingecko ID'si al - + Active Aktif - - + Preview Görüntüle - - WARNING: Application will restart immidiately to apply the changes! - DİKKAT: Program değişiklikleri uygulamak için yeniden başlatılacak! + + Preview Token Configuration + + WARNING: Application will restart immediately to apply the changes! + + + + Asset not found, please go back and make sure Contract Address is correct Varlık bulunamadı, lütfen geri dönün ve Kontrat Adresi'nin doğruluğundan emin olun - + Config Fields Konfig Alanları - + Fetched Data Çekilen Veri - + Submit & Restart Yolla ve Yeniden Başlat @@ -1504,67 +1508,67 @@ Bir miktar gir - + Trading Fee Takas Ücreti - + Minimum Trading Amount Minimum Takas Hacmi - + Wallet %1 already exists WALLETNAME %1 cüzdanı zaten mevcut - + %1 balance is lower than the fees amount: %2 %3 %1 bakiye ücret tutarının altında: %2 %3 - + Tradable (after fees) %1 balance is lower than minimum trade amount Takas edilebilir (ücretlerden sonra)%1 bakiyesi minimum işlem ücretinden düşük - + Please fill the price field Lütfen fiyat alanını doldurun - + Please fill the volume field - - + + Please wait for %1 to fully activate - - + + %1 volume is lower than minimum trade amount %1 hacmi, minimum işlem ücretinden düşük - - + + %1 needs to be enabled in order to use %2 - - + + %1 balance needs to be funded, a non-zero balance is required to pay the gas of %2 transactions - + Unknown Error Bilinmeyen Hata @@ -3407,252 +3411,263 @@ Please select a new order. SettingModal - - + + Cancel İptal - + Settings Ayarlar - + Language Dil - + User Interface Kullanıcı Arayüzü - + Security Güvenlik - + General Genel - + About & Version - + Enable Desktop Notifications Masaüstü Bildirimlerini Aktif Et - + Hide Poison Transactions in History - + Maximum number of enabled coins Maksimum etkin koin sayısı - + Logs Günlük Kaydı - + Open Folder Klasörü Aç - + ZHTLC sync date - + use date sync - + Sync Date - - + + Reset wallet configuration - + This will restart your wallet with default settings - - + + Confirm Onayla - + Changing theme to %1 - + Disable 2FA? - + Enter your wallet password to confirm - + Type password - + 2FA status - + 2FA disabled successfully - - + + Ok Tamam - + Wrong password! - + Wallet password is incorrect - + Reuse static RPC password - + Application Version - + copied to clipboard - + Reset Sıfırla - + Current Font Geçerli Yazı Tipi - + Current font changed to %1. - + Theme Tema - + Ask system's password before sending coins ? (2FA) Para göndermeden önce sistem parolası sorulsun mu ? (2FA) - + Application version Uygulama sürümü - + MM2 version MM2 sürümü - + MM2 Version - + MM2 Version copied to clipboard. - + + + Peer ID + + + + + Peer ID copied to clipboard. + + + + Qt version Qt sürümü - + Qt Version - + Qt Version copied to clipboard. - + Search Update Güncelleme Ara - + Logout Çıkış - + View seed and private keys Seed ve özel anahtarları görüntüle - - + + Show Göster - + Setup Camouflage Password Kamuflaj Parolasını Ayarla - + Open - + Disclaimer and ToS Sorumluluk Reddi ve K.Ş. @@ -3887,19 +3902,19 @@ Please select a new order. How long does each atomic swap take? Her bir atomik takas ne kadar sürer? - - - Several factors determine the processing time for each swap. The block time of the traded assets depends on each network (Bitcoin typically being the slowest) Additionally, the user can customize security preferences. For example, (you can ask %1 to consider a KMD transaction as final after just 3 confirmations which makes the swap time shorter compared to waiting for a <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/">notarization</a>. - Her takas için işlem süresini birkaç faktör belirler. İşlem gören varlıkların blok süresi her bir ağa bağlıdır (Bitcoin tipik olarak en yavaş olanıdır) Ek olarak, kullanıcı güvenlik tercihlerini özelleştirebilir. (Örneğin; %1 in KMD işlemini sadece 3 onayla gerçekleştirmesini seçerek takas süresini <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/">notarizasyon</a> süresinden daha öncesine kısaltabilirsiniz. - Do I need to be online for the duration of the swap? Takas süresi boyunca çevrimiçi olmam gerekir mi? + + + Several factors determine the processing time for each swap. The block time of the traded assets depends on each network (Bitcoin typically being the slowest) Additionally, the user can customize security preferences. For example, (you can ask %1 to consider a KMD transaction as final after just 3 confirmations which makes the swap time shorter compared to waiting for a <a href="https://komodoplatform.com/security-delayed-proof-of-work-dpow/">notarization</a>. + + - Yes. You must remain connected to the internet and have your app running to successfully complete each atomic swap (very short breaks in connectivity are usually fine). Otherwise, there is risk of trade cancellation if you are a maker, and risk of loss of funds if you are a taker. + Yes. You must remain connected to the internet and have your app running to successfully complete each atomic swap (very short breaks in connectivity are usually fine). Otherwise, there is risk of trade cancellation if you are a maker, and risk of loss of funds if you are a taker. To mitigate this, 'watchertower' nodes have been deployed to monitor the dex network for you and, where possible, complete the swaps for you if your app goes offline. The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. @@ -4522,7 +4537,7 @@ This might take a few minutes... atomic_dex::settings_page - + An error has occurred. @@ -4530,62 +4545,62 @@ This might take a few minutes... atomic_dex::wallet_page - + You do not have enough funds. Bakiye yetersiz. - + %1 is not activated: click on the button to enable it or enable it manually %1 etkinleştirilmedi: etkinleştirmek için düğmeye tıklayın veya manuel olarak etkinleştirin - + You need to have %1 to pay the gas for %2 transactions. %2 işlemi için gaz ödemek üzere %1'e sahip olmanız gerekir. - + Checksum verification failed for %1. %1 için sağlama toplamı doğrulaması başarısız oldu. - + Invalid checksum for %1. Click the button to convert to mixed case address. - + Legacy address used for %1. Click the button to convert to a Cashaddress. - + %1 address must be prefixed with 0x %1 adresinin önüne 0x konulmalı - + %1 address length is invalid, please use a valid address. %1 adres uzunluğu geçersiz, lütfen geçerli bir adres kullanın. - + %1 address is invalid. - + Invalid checksum. - + %1 address has invalid prefixes. - + Backend error: %1 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0bbc1a0a12..f5d49ac68a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -113,9 +113,9 @@ add_executable(${PROJECT_NAME}_tests MACOSX_BUNDLE ${ICON} ##! API tests/api/coingecko/coingecko.tests.cpp tests/api/komodo_prices/komodo.prices.tests.cpp - tests/api/mm2/mm2.api.format.address.tests.cpp - tests/api/mm2/mm2.api.utxo.merge.params.tests.cpp - tests/api/mm2/mm2.api.balance.infos.tests.cpp + tests/api/mm2/mm2.api.address_format.tests.cpp + tests/api/mm2/mm2.api.utxo_merge_params.tests.cpp + tests/api/mm2/mm2.api.balance_infos.tests.cpp tests/api/mm2/mm2.fraction.tests.cpp tests/api/mm2/mm2.rpc2.trade_preimage.tests.cpp diff --git a/src/app/app.cpp b/src/app/app.cpp index e420b07183..8f7df9c613 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -530,9 +530,15 @@ namespace atomic_dex { SPDLOG_DEBUG("on_coin_fully_initialized_event"); #if !defined(_WIN32) - for (auto&& ticker: evt.tickers) { m_portfolio_queue.push(strdup(ticker.c_str())); } + for (auto&& ticker: evt.tickers) { + SPDLOG_DEBUG("Adding {} to m_portfolio_queue", ticker); + m_portfolio_queue.push(strdup(ticker.c_str())); + } #else - for (auto&& ticker: evt.tickers) { m_portfolio_queue.push(_strdup(ticker.c_str())); } + for (auto&& ticker: evt.tickers) { + SPDLOG_DEBUG("Adding {} to m_portfolio_queue", ticker); + m_portfolio_queue.push(_strdup(ticker.c_str())); + } #endif } } @@ -557,6 +563,7 @@ namespace atomic_dex QString application::get_balance(const QString& coin) { std::error_code ec; + SPDLOG_DEBUG("{} l{}", __FUNCTION__, __LINE__); auto res = get_mm2().my_balance(coin.toStdString(), ec); return QString::fromStdString(res); } @@ -567,6 +574,7 @@ namespace atomic_dex system_manager_.get_system().set_status("enabling_coins"); } + // Function appears to be unused. void application::refresh_orders_and_swaps() { auto& mm2 = get_mm2(); diff --git a/src/core/atomicdex/api/coingecko/coingecko.cpp b/src/core/atomicdex/api/coingecko/coingecko.cpp index 673a9253cb..8a6138d9fa 100644 --- a/src/core/atomicdex/api/coingecko/coingecko.cpp +++ b/src/core/atomicdex/api/coingecko/coingecko.cpp @@ -103,7 +103,7 @@ namespace atomic_dex::coingecko::api } std::pair, t_coingecko_registry> - from_enabled_coins(const std::vector& coins) + from_enabled_coins(const std::vector& coins) { std::vector out; t_coingecko_registry registry; diff --git a/src/core/atomicdex/api/coingecko/coingecko.hpp b/src/core/atomicdex/api/coingecko/coingecko.hpp index 88625c0a10..578db408ce 100644 --- a/src/core/atomicdex/api/coingecko/coingecko.hpp +++ b/src/core/atomicdex/api/coingecko/coingecko.hpp @@ -63,8 +63,8 @@ namespace atomic_dex::coingecko::api ENTT_API std::string to_coingecko_uri(market_infos_request&& request); ENTT_API std::string to_coingecko_uri(market_chart_request&& request); ENTT_API std::string to_coingecko_uri(market_chart_request_range&& request); - using t_coins_registry = std::unordered_map; - ENTT_API std::pair, t_coingecko_registry> from_enabled_coins(const std::vector& coins); + using t_coins_registry = std::unordered_map; + ENTT_API std::pair, t_coingecko_registry> from_enabled_coins(const std::vector& coins); ENTT_API pplx::task async_market_infos(market_infos_request&& request); ENTT_API pplx::task async_market_charts(market_chart_request&& request); diff --git a/src/core/atomicdex/api/mm2/format.address.cpp b/src/core/atomicdex/api/mm2/address_format.cpp similarity index 72% rename from src/core/atomicdex/api/mm2/format.address.cpp rename to src/core/atomicdex/api/mm2/address_format.cpp index 58a47ba160..d4320ed7d7 100644 --- a/src/core/atomicdex/api/mm2/format.address.cpp +++ b/src/core/atomicdex/api/mm2/address_format.cpp @@ -18,14 +18,28 @@ #include //! Project Headers -#include "format.address.hpp" +#include "atomicdex/api/mm2/address_format.hpp" namespace atomic_dex::mm2 { void - to_json(nlohmann::json& j, const format_address& cfg) + to_json(nlohmann::json& j, const address_format_t& req) { - j["format"] = cfg.format; - j["network"] = cfg.network; + j["format"] = req.format; + if (req.network.has_value()) + { + j["network"] = req.network.value(); + } + } + + void + from_json(const nlohmann::json& j, address_format_t& resp) + { + resp.format = j.at("format").get(); + if (j.contains("network")) + { + resp.network = j.at("network").get(); + } + } } // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/format.address.hpp b/src/core/atomicdex/api/mm2/address_format.hpp similarity index 83% rename from src/core/atomicdex/api/mm2/format.address.hpp rename to src/core/atomicdex/api/mm2/address_format.hpp index 9f2fae89e3..7b68961d12 100644 --- a/src/core/atomicdex/api/mm2/format.address.hpp +++ b/src/core/atomicdex/api/mm2/address_format.hpp @@ -21,11 +21,11 @@ namespace atomic_dex::mm2 { - struct format_address + struct address_format_t { - std::string format; - std::string network; + std::string format; + std::optional network{std::nullopt}; }; - - void to_json(nlohmann::json& j, const format_address& cfg); + void to_json(nlohmann::json& j, const address_format_t& cfg); + void from_json(const nlohmann::json& j, address_format_t& cfg); } \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/balance.infos.cpp b/src/core/atomicdex/api/mm2/balance_infos.cpp similarity index 98% rename from src/core/atomicdex/api/mm2/balance.infos.cpp rename to src/core/atomicdex/api/mm2/balance_infos.cpp index d71b8f1c1f..9140372b71 100644 --- a/src/core/atomicdex/api/mm2/balance.infos.cpp +++ b/src/core/atomicdex/api/mm2/balance_infos.cpp @@ -18,7 +18,7 @@ #include // Project Headers -#include "balance.infos.hpp" +#include "balance_infos.hpp" namespace atomic_dex::mm2 { diff --git a/src/core/atomicdex/api/mm2/balance.infos.hpp b/src/core/atomicdex/api/mm2/balance_infos.hpp similarity index 100% rename from src/core/atomicdex/api/mm2/balance.infos.hpp rename to src/core/atomicdex/api/mm2/balance_infos.hpp diff --git a/src/core/atomicdex/api/mm2/generics.cpp b/src/core/atomicdex/api/mm2/generics.cpp index 7883f60426..a8a0c0ddb4 100644 --- a/src/core/atomicdex/api/mm2/generics.cpp +++ b/src/core/atomicdex/api/mm2/generics.cpp @@ -27,7 +27,7 @@ #include "atomicdex/api/mm2/rpc_v1/rpc.recover_funds_of_swap.hpp" #include "atomicdex/api/mm2/rpc_v1/rpc.sell.hpp" #include "atomicdex/api/mm2/rpc_v1/rpc.validateaddress.hpp" -#include "atomicdex/api/mm2/rpc_v2/rpc2.best.orders.hpp" +#include "atomicdex/api/mm2/rpc_v2/rpc2.bestorders.hpp" #include "atomicdex/api/mm2/rpc_v2/rpc2.trade_preimage.hpp" namespace atomic_dex::mm2 @@ -51,7 +51,6 @@ namespace atomic_dex::mm2 template void extract_rpc_json_answer(const nlohmann::json& j, min_volume_answer& answer); template void extract_rpc_json_answer(const nlohmann::json& j, buy_answer& answer); template void extract_rpc_json_answer(const nlohmann::json& j, sell_answer& answer); - template void extract_rpc_json_answer(const nlohmann::json& j, best_orders_answer& answer); template void extract_rpc_json_answer(const nlohmann::json& j, disable_coin_answer& answer); template void extract_rpc_json_answer(const nlohmann::json& j, validate_address_answer& answer); template void extract_rpc_json_answer(const nlohmann::json& j, convert_address_answer& answer); diff --git a/src/core/atomicdex/api/mm2/mm2.client.cpp b/src/core/atomicdex/api/mm2/mm2.client.cpp index 8e71490531..1ebd7f2c7b 100644 --- a/src/core/atomicdex/api/mm2/mm2.client.cpp +++ b/src/core/atomicdex/api/mm2/mm2.client.cpp @@ -26,8 +26,12 @@ #include "atomicdex/api/mm2/rpc_v1/rpc.my_tx_history.hpp" #include "atomicdex/api/mm2/rpc_v2/rpc2.get_public_key.hpp" #include "atomicdex/api/mm2/rpc_v2/rpc2.my_tx_history.hpp" +#include "atomicdex/api/mm2/rpc_v2/rpc2.orderbook.hpp" +#include "atomicdex/api/mm2/rpc_v2/rpc2.bestorders.hpp" #include "atomicdex/api/mm2/rpc_v2/rpc2.enable_tendermint_token.hpp" #include "atomicdex/api/mm2/rpc_v2/rpc2.enable_tendermint_with_assets.hpp" +#include "atomicdex/api/mm2/rpc_v2/rpc2.enable_erc20.hpp" +#include "atomicdex/api/mm2/rpc_v2/rpc2.enable_eth_with_tokens.hpp" #include "atomicdex/api/mm2/rpc_v2/rpc2.enable_slp_rpc.hpp" #include "atomicdex/api/mm2/rpc_v2/rpc2.enable_bch_with_tokens_rpc.hpp" @@ -59,6 +63,7 @@ namespace if (Rpc::is_v2) { json_req["mmrpc"] = "2.0"; + json_req["id"] = 42; json_req.push_back({"params", json_data}); } else @@ -72,19 +77,47 @@ namespace template Rpc process_rpc_answer(const web::http::http_response& answer) { - // SPDLOG_DEBUG("rpc answer: {}", TO_STD_STR(answer.extract_string(true).get())); + std::string body = TO_STD_STR(answer.extract_string(true).get()); + if (body.size() > 1000) + { + SPDLOG_DEBUG("redacted rpc answer: {}", body.substr(0, 1000)); + } + else + { + SPDLOG_DEBUG("rpc answer: {}", body); + } + SPDLOG_DEBUG("rpc answer: {}", body); + nlohmann::json json_answer; Rpc rpc; - auto json_answer = nlohmann::json::parse(TO_STD_STR(answer.extract_string(true).get())); + try + { + json_answer = nlohmann::json::parse(body); + // SPDLOG_DEBUG("rpc answer: {}", json_answer.dump(4)); + } + catch (const nlohmann::json::parse_error& error) + { + SPDLOG_ERROR("rpc answer error: {}", error.what()); + } + if (Rpc::is_v2) { - // SPDLOG_DEBUG("v2 rpc answer") if (answer.status_code() == 200) + { rpc.result = json_answer.at("result").get(); + rpc.raw_result = json_answer.at("result").dump(); + } else + { + SPDLOG_DEBUG("rpc2 answer: error"); rpc.error = json_answer.get(); + rpc.raw_result = json_answer.dump(); + SPDLOG_DEBUG("rpc.raw_result: {}", rpc.raw_result); + } } else + { rpc.result = json_answer.get(); + } return rpc; } } // namespace @@ -160,13 +193,19 @@ namespace atomic_dex::mm2 using request_type = typename Rpc::expected_request_type; process_rpc_async(request_type{}, on_rpc_processed); } - template void mm2_client::process_rpc_async(const std::function&); + + // template void mm2_client::process_rpc_async(const std::function&); + template void mm2_client::process_rpc_async(const std::function&); + template void mm2_client::process_rpc_async(const std::function&); template void mm2_client::process_rpc_async(const std::function&); + template void mm2_client::process_rpc_async(const std::function&); + template void mm2_client::process_rpc_async(const std::function&); + template void mm2_client::process_rpc_async(const std::function&); + template void mm2_client::process_rpc_async(const std::function&); + template void mm2_client::process_rpc_async(const std::function&); template void mm2_client::process_rpc_async(const std::function&); template void mm2_client::process_rpc_async(const std::function&); template void mm2_client::process_rpc_async(const std::function&); - template void mm2_client::process_rpc_async(const std::function&); - template void mm2_client::process_rpc_async(const std::function&); template void mm2_client::process_rpc_async(typename Rpc::expected_request_type request, const std::function& on_rpc_processed) @@ -184,6 +223,7 @@ namespace atomic_dex::mm2 } catch (const std::exception& ex) { + // SPDLOG_DEBUG("process_rpc_answer rpc.result: {}", rpc.raw_result); SPDLOG_ERROR(ex.what()); } }); diff --git a/src/core/atomicdex/api/mm2/mm2.cpp b/src/core/atomicdex/api/mm2/mm2.cpp index 86e6f52125..0971464177 100644 --- a/src/core/atomicdex/api/mm2/mm2.cpp +++ b/src/core/atomicdex/api/mm2/mm2.cpp @@ -23,7 +23,7 @@ #include "atomicdex/api/mm2/rpc_v1/rpc.min_trading_vol.hpp" #include "atomicdex/api/mm2/rpc_v1/rpc.recover_funds_of_swap.hpp" #include "atomicdex/api/mm2/rpc_v1/rpc.validateaddress.hpp" -#include "atomicdex/api/mm2/rpc_v2/rpc2.best.orders.hpp" +#include "atomicdex/api/mm2/rpc_v2/rpc2.bestorders.hpp" #include "atomicdex/api/mm2/rpc_v2/rpc2.orderbook.hpp" #include "atomicdex/api/mm2/rpc_v2/rpc2.task.withdraw.status.hpp" #include "atomicdex/api/mm2/rpc_v2/rpc2.trade_preimage.hpp" @@ -584,7 +584,10 @@ namespace atomic_dex::mm2 if (is_protocol_v2) { request["mmrpc"] = "2.0"; + request["id"] = 42; } + // SPDLOG_INFO("template_request: {}", request.dump(4)); + return request; } @@ -592,6 +595,34 @@ namespace atomic_dex::mm2 rpc_version() { nlohmann::json json_data = template_request("version"); + // SPDLOG_DEBUG("version request {}", json_data.dump(4)); + try + { + auto client = std::make_unique(FROM_STD_STR(atomic_dex::g_dex_rpc)); + web::http::http_request request; + request.set_method(web::http::methods::POST); + request.set_body(json_data.dump()); + web::http::http_response resp = client->request(request).get(); + if (resp.status_code() == 200) + { + std::string body = TO_STD_STR(resp.extract_string(true).get()); + nlohmann::json body_json = nlohmann::json::parse(body); + return body_json.at("result").get(); + } + + return "error occured during rpc_version"; + } + catch (const web::http::http_exception& exception) + { + return "error occured during rpc_version"; + } + return ""; + } + + std::string + peer_id() + { + nlohmann::json json_data = template_request("get_my_peer_id"); try { auto client = std::make_unique(FROM_STD_STR(atomic_dex::g_dex_rpc)); @@ -710,7 +741,6 @@ namespace atomic_dex::mm2 template mm2::withdraw_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); template mm2::withdraw_status_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); template mm2::my_orders_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); - template mm2::orderbook_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); template mm2::trade_fee_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); template mm2::max_taker_vol_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); template mm2::min_volume_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); @@ -718,7 +748,6 @@ namespace atomic_dex::mm2 template mm2::active_swaps_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); template mm2::show_priv_key_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); template mm2::trade_preimage_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); - template mm2::best_orders_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); template mm2::validate_address_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); template mm2::convert_address_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); template mm2::recover_funds_of_swap_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); diff --git a/src/core/atomicdex/api/mm2/mm2.hpp b/src/core/atomicdex/api/mm2/mm2.hpp index fd7c9de82e..2a0efe3c65 100644 --- a/src/core/atomicdex/api/mm2/mm2.hpp +++ b/src/core/atomicdex/api/mm2/mm2.hpp @@ -43,6 +43,7 @@ namespace atomic_dex::mm2 nlohmann::json basic_batch_answer(const web::http::http_response& resp); std::string rpc_version(); + std::string peer_id(); struct trade_fee_request { diff --git a/src/core/atomicdex/api/mm2/orderbook.order.contents.hpp b/src/core/atomicdex/api/mm2/orderbook.order.contents.hpp index 6cc8742c1d..b4cbc7798e 100644 --- a/src/core/atomicdex/api/mm2/orderbook.order.contents.hpp +++ b/src/core/atomicdex/api/mm2/orderbook.order.contents.hpp @@ -55,7 +55,7 @@ namespace atomic_dex::mm2 std::string uuid; std::string depth_percent; bool is_mine; - std::optional rel_coin{std::nullopt}; + std::optional rel_coin; std::string to_string() const noexcept; }; diff --git a/src/core/atomicdex/api/mm2/paging_options.cpp b/src/core/atomicdex/api/mm2/paging_options.cpp index 95943a77ec..2d785b004c 100644 --- a/src/core/atomicdex/api/mm2/paging_options.cpp +++ b/src/core/atomicdex/api/mm2/paging_options.cpp @@ -7,7 +7,7 @@ namespace atomic_dex::mm2 { - void to_json(nlohmann::json& j, const paging_options& in) + void to_json(nlohmann::json& j, const paging_options_t& in) { if (in.from_id) { diff --git a/src/core/atomicdex/api/mm2/paging_options.hpp b/src/core/atomicdex/api/mm2/paging_options.hpp index 4f48ec69db..851ce650f7 100644 --- a/src/core/atomicdex/api/mm2/paging_options.hpp +++ b/src/core/atomicdex/api/mm2/paging_options.hpp @@ -9,11 +9,11 @@ namespace atomic_dex::mm2 { - struct paging_options + struct paging_options_t { std::optional from_id; std::optional page_number; }; - void to_json(nlohmann::json& j, const paging_options& in); + void to_json(nlohmann::json& j, const paging_options_t& in); } \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.tx.history.hpp b/src/core/atomicdex/api/mm2/rpc.tx.history.hpp index 900290bead..a761b2d954 100644 --- a/src/core/atomicdex/api/mm2/rpc.tx.history.hpp +++ b/src/core/atomicdex/api/mm2/rpc.tx.history.hpp @@ -12,9 +12,9 @@ namespace atomic_dex::mm2 { struct tx_history_request { - std::string coin; - std::size_t limit; - std::optional paging_options; + std::string coin; + std::size_t limit; + std::optional paging_options; }; void to_json(nlohmann::json& j, const tx_history_request& cfg); diff --git a/src/core/atomicdex/api/mm2/rpc_v1/rpc.electrum.cpp b/src/core/atomicdex/api/mm2/rpc_v1/rpc.electrum.cpp index 6f264979f8..f08fb1bb6f 100644 --- a/src/core/atomicdex/api/mm2/rpc_v1/rpc.electrum.cpp +++ b/src/core/atomicdex/api/mm2/rpc_v1/rpc.electrum.cpp @@ -41,9 +41,9 @@ namespace atomic_dex::mm2 { j["swap_contract_address"] = cfg.swap_contract_address.value(); } - if (cfg.fallback_swap_contract_address.has_value()) + if (cfg.fallback_swap_contract.has_value()) { - j["fallback_swap_contract_address"] = cfg.fallback_swap_contract_address.value(); + j["fallback_swap_contract"] = cfg.fallback_swap_contract.value(); } } diff --git a/src/core/atomicdex/api/mm2/rpc_v1/rpc.electrum.hpp b/src/core/atomicdex/api/mm2/rpc_v1/rpc.electrum.hpp index 2bc27fed42..c3d545c57a 100644 --- a/src/core/atomicdex/api/mm2/rpc_v1/rpc.electrum.hpp +++ b/src/core/atomicdex/api/mm2/rpc_v1/rpc.electrum.hpp @@ -22,6 +22,7 @@ //! Project Headers #include "atomicdex/config/electrum.cfg.hpp" #include "atomicdex/constants/qt.coins.enums.hpp" +#include "atomicdex/api/mm2/address_format.hpp" namespace atomic_dex::mm2 { @@ -33,8 +34,8 @@ namespace atomic_dex::mm2 bool is_testnet{false}; bool with_tx_history{true}; std::optional swap_contract_address{std::nullopt}; - std::optional fallback_swap_contract_address{std::nullopt}; - std::optional address_format; + std::optional fallback_swap_contract{std::nullopt}; + std::optional address_format; std::optional merge_params; std::optional> bchd_urls; std::optional allow_slp_unsafe_conf; diff --git a/src/core/atomicdex/api/mm2/rpc_v1/rpc.enable.cpp b/src/core/atomicdex/api/mm2/rpc_v1/rpc.enable.cpp index aa3d069876..83ee67f33e 100644 --- a/src/core/atomicdex/api/mm2/rpc_v1/rpc.enable.cpp +++ b/src/core/atomicdex/api/mm2/rpc_v1/rpc.enable.cpp @@ -37,7 +37,7 @@ namespace atomic_dex::mm2 j["gas_station_url"] = cfg.gas_station_url.value(); } } - case CoinType::Matic: + case CoinType::PLG20: { if (cfg.is_testnet) { @@ -57,13 +57,17 @@ namespace atomic_dex::mm2 { j["gas_station_decimals"] = cfg.matic_gas_station_decimals.value(); } + if (cfg.mm2.has_value()) + { + j["mm2"] = cfg.mm2.value(); + } } default: j["urls"] = cfg.urls; j["swap_contract_address"] = cfg.swap_contract_address; - if (cfg.fallback_swap_contract_address.has_value()) + if (cfg.fallback_swap_contract.has_value()) { - j["fallback_swap_contract"] = cfg.fallback_swap_contract_address.value(); + j["fallback_swap_contract"] = cfg.fallback_swap_contract.value(); } break; } diff --git a/src/core/atomicdex/api/mm2/rpc_v1/rpc.enable.hpp b/src/core/atomicdex/api/mm2/rpc_v1/rpc.enable.hpp index 5326da8f71..4f4bbafeb2 100644 --- a/src/core/atomicdex/api/mm2/rpc_v1/rpc.enable.hpp +++ b/src/core/atomicdex/api/mm2/rpc_v1/rpc.enable.hpp @@ -33,8 +33,9 @@ namespace atomic_dex::mm2 CoinType coin_type; bool is_testnet{false}; const std::string swap_contract_address; - std::optional fallback_swap_contract_address{std::nullopt}; + std::optional fallback_swap_contract{std::nullopt}; std::optional matic_gas_station_decimals{9}; + std::optional mm2{1}; std::optional gas_station_url{std::nullopt}; std::optional matic_gas_station_url{std::nullopt}; std::optional testnet_matic_gas_station_url{std::nullopt}; diff --git a/src/core/atomicdex/api/mm2/rpc_v1/rpc.my_tx_history.hpp b/src/core/atomicdex/api/mm2/rpc_v1/rpc.my_tx_history.hpp index 1da0cebe99..e59cd15d8e 100644 --- a/src/core/atomicdex/api/mm2/rpc_v1/rpc.my_tx_history.hpp +++ b/src/core/atomicdex/api/mm2/rpc_v1/rpc.my_tx_history.hpp @@ -4,7 +4,6 @@ #pragma once #include "atomicdex/api/mm2/rpc.hpp" -#include "atomicdex/api/mm2/rpc_v1/rpc.my_tx_history.hpp" namespace atomic_dex::mm2 { @@ -22,6 +21,7 @@ namespace atomic_dex::mm2 expected_request_type request; std::optional result; std::optional error; + std::string raw_result; }; using my_tx_history_request_v1_rpc = my_tx_history_v1_rpc::expected_request_type; diff --git a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.best.orders.cpp b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.bestorders.cpp similarity index 77% rename from src/core/atomicdex/api/mm2/rpc_v2/rpc2.best.orders.cpp rename to src/core/atomicdex/api/mm2/rpc_v2/rpc2.bestorders.cpp index 2a10afb2c0..ba5dd40660 100644 --- a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.best.orders.cpp +++ b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.bestorders.cpp @@ -23,23 +23,22 @@ //! Project Headers #include "atomicdex/api/mm2/generics.hpp" -#include "atomicdex/api/mm2/rpc_v2/rpc2.best.orders.hpp" +#include "atomicdex/api/mm2/rpc_v2/rpc2.bestorders.hpp" //! Implementation RPC [best_orders] namespace atomic_dex::mm2 { void - to_json(nlohmann::json& j, const best_orders_request& req) + to_json(nlohmann::json& j, const bestorders_request_rpc& req) { - SPDLOG_INFO("getting bestorders data..."); - j["params"]["coin"] = req.coin; - j["params"]["action"] = req.action; - j["params"]["request_by"]["type"] = "volume"; - j["params"]["request_by"]["value"] = req.volume; + j["coin"] = req.coin; + j["action"] = req.action; + j["request_by"]["type"] = "volume"; + j["request_by"]["value"] = req.volume; } void - from_json(const nlohmann::json& j, best_orders_answer_success& answer) + from_json(const nlohmann::json& j, bestorders_result_rpc& resp) { if (j.empty()) { @@ -59,7 +58,7 @@ namespace atomic_dex::mm2 from_json(cur_order, contents); if (uuid_visited.emplace(contents.uuid).second) { - answer.result.emplace_back(std::move(contents)); + resp.result.emplace_back(std::move(contents)); } else { @@ -69,11 +68,4 @@ namespace atomic_dex::mm2 } } } - - void - from_json(const nlohmann::json& j, best_orders_answer& answer) - { - extract_rpc_json_answer(j, answer); - } - } // namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.best.orders.hpp b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.bestorders.hpp similarity index 56% rename from src/core/atomicdex/api/mm2/rpc_v2/rpc2.best.orders.hpp rename to src/core/atomicdex/api/mm2/rpc_v2/rpc2.bestorders.hpp index b4626540d4..0c9be72572 100644 --- a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.best.orders.hpp +++ b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.bestorders.hpp @@ -18,45 +18,48 @@ //! STD #include +#include //! Deps #include //! Project Headers +#include "atomicdex/api/mm2/rpc.hpp" #include "atomicdex/api/mm2/orderbook.order.contents.hpp" namespace atomic_dex::mm2 { - struct best_orders_request + struct bestorders_rpc { - std::string coin; - std::string volume; - std::string action; - }; + static constexpr auto endpoint = "best_orders"; + static constexpr bool is_v2 = true; - void to_json(nlohmann::json& j, const best_orders_request& req); + struct expected_request_type + { + std::string coin; + std::string volume; + std::string action; + }; - struct best_orders_answer_success - { - std::vector result; - }; - void from_json(const nlohmann::json& j, best_orders_answer_success& answer); + struct expected_result_type + { + std::vector result; + }; - struct best_orders_answer - { - std::optional result; - std::optional error; - std::string raw_result; ///< internal - int rpc_result_code; ///< internal + using expected_error_type = rpc_basic_error_type; + + expected_request_type request; + std::optional result; + std::optional error; + std::string raw_result; }; - void from_json(const nlohmann::json& j, best_orders_answer& answer); -} // namespace atomic_dex::mm2 + using bestorders_request_rpc = bestorders_rpc::expected_request_type; + using bestorders_result_rpc = bestorders_rpc::expected_result_type; + using bestorders_error_rpc = bestorders_rpc::expected_error_type; -namespace atomic_dex -{ - using t_best_orders_request = mm2::best_orders_request; - using t_best_orders_answer = mm2::best_orders_answer; - using t_best_orders_answer_success = mm2::best_orders_answer_success; -} // namespace atomic_dex \ No newline at end of file + void to_json(nlohmann::json& j, const bestorders_request_rpc& req); + void from_json(const nlohmann::json& j, bestorders_result_rpc& answer); + +} // namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_bch_with_tokens_rpc.cpp b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_bch_with_tokens_rpc.cpp index 0b0529952d..0727b2d1af 100644 --- a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_bch_with_tokens_rpc.cpp +++ b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_bch_with_tokens_rpc.cpp @@ -1,6 +1,7 @@ #include -#include "rpc2.enable_bch_with_tokens_rpc.hpp" +#include "atomicdex/api/mm2/address_format.hpp" +#include "atomicdex/api/mm2/rpc_v2/rpc2.enable_bch_with_tokens_rpc.hpp" namespace atomic_dex::mm2 { @@ -32,26 +33,13 @@ namespace atomic_dex::mm2 { j["servers"] = in.servers; } - - void to_json(nlohmann::json& j, const enable_bch_with_tokens_request_rpc::address_format_t& in) - { - j["format"] = in.format; - j["network"] = in.network; - } - + void to_json(nlohmann::json& j, const enable_bch_with_tokens_request_rpc::slp_token_request_t& in) { j["ticker"] = in.ticker; if (in.required_confirmations) j["required_confirmations"] = in.required_confirmations.value(); } - - void to_json(nlohmann::json& j, const enable_bch_with_tokens_request_rpc::utxo_merge_params_t& in) - { - j["merge_at"] = in.merge_at; - j["check_every"] = in.check_every; - j["max_merge_at_once"] = in.max_merge_at_once; - } void from_json(const nlohmann::json& json, enable_bch_with_tokens_result_rpc& out) { diff --git a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_bch_with_tokens_rpc.hpp b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_bch_with_tokens_rpc.hpp index dc74ce6b93..b9141b4933 100644 --- a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_bch_with_tokens_rpc.hpp +++ b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_bch_with_tokens_rpc.hpp @@ -1,10 +1,28 @@ +/****************************************************************************** + * Copyright © 2013-2024 The Komodo Platform Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * Komodo Platform software, including this file may be copied, modified, * + * propagated or distributed except according to the terms contained in the * + * LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + #pragma once #include -#include "atomicdex/api/mm2/rpc.hpp" -#include "atomicdex/api/mm2/balance_info.hpp" #include "atomicdex/config/electrum.cfg.hpp" +#include "atomicdex/api/mm2/address_format.hpp" +#include "atomicdex/api/mm2/balance_info.hpp" +#include "atomicdex/api/mm2/rpc.hpp" +#include "atomicdex/api/mm2/utxo_merge_params.hpp" namespace atomic_dex::mm2 { @@ -27,17 +45,6 @@ namespace atomic_dex::mm2 std::string ticker; std::optional required_confirmations; }; - struct address_format_t - { - std::string format; - std::string network; - }; - struct utxo_merge_params_t - { - int merge_at; - int check_every; - int max_merge_at_once; - }; std::string ticker; std::optional allow_slp_unsafe_conf{false}; @@ -77,6 +84,7 @@ namespace atomic_dex::mm2 expected_request_type request; std::optional result; std::optional error; + std::string raw_result; }; using enable_bch_with_tokens_request_rpc = enable_bch_with_tokens_rpc::expected_request_type; @@ -86,9 +94,8 @@ namespace atomic_dex::mm2 void to_json(nlohmann::json& j, const enable_bch_with_tokens_request_rpc& in); void to_json(nlohmann::json& j, const enable_bch_with_tokens_request_rpc::mode_t& in); void to_json(nlohmann::json& j, const enable_bch_with_tokens_request_rpc::mode_t::data& in); - void to_json(nlohmann::json& j, const enable_bch_with_tokens_request_rpc::address_format_t& in); + void to_json(nlohmann::json& j, const address_format_t& in); void to_json(nlohmann::json& j, const enable_bch_with_tokens_request_rpc::slp_token_request_t& in); - void to_json(nlohmann::json& j, const enable_bch_with_tokens_request_rpc::utxo_merge_params_t& in); void from_json(const nlohmann::json& json, enable_bch_with_tokens_result_rpc& out); void from_json(const nlohmann::json& json, enable_bch_with_tokens_result_rpc::derivation_method_t& out); void from_json(const nlohmann::json& json, enable_bch_with_tokens_result_rpc::bch_address_infos_t& out); diff --git a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_erc20.hpp b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_erc20.hpp index 1d59962b05..953bb8f67d 100644 --- a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_erc20.hpp +++ b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_erc20.hpp @@ -44,9 +44,10 @@ namespace atomic_dex::mm2 using expected_error_type = rpc_basic_error_type; - expected_request_type request; - std::optional result; - std::optional error; + expected_request_type request; + std::optional result; + std::optional error; + std::string raw_result; }; using enable_erc20_rpc_request = enable_erc20_rpc::expected_request_type; diff --git a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_eth_with_tokens.cpp b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_eth_with_tokens.cpp index 6d1ab8916f..2a0bb73211 100644 --- a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_eth_with_tokens.cpp +++ b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_eth_with_tokens.cpp @@ -9,21 +9,16 @@ namespace atomic_dex::mm2 j["ticker"] = in.ticker; j["nodes"] = in.nodes; j["tx_history"] = in.tx_history; + j["get_balances"] = in.get_balances; j["erc20_tokens_requests"] = in.erc20_tokens_requests; if (in.required_confirmations.has_value()) j["required_confirmations"] = in.required_confirmations.value(); if (in.requires_notarization.has_value()) j["requires_notarization"] = in.requires_notarization.value(); + j["swap_contract_address"] = in.swap_contract_address; + j["fallback_swap_contract"] = in.fallback_swap_contract; - // Use this in mm2.service.cpp when constructing the request - // - // coin_config coin_info = get_coin_info(in.ticker); - // coin_config.fallback_swap_contract_address - // coin_config.swap_contract_address - // coin_config.gas_station_url - // coin_config.gas_station_decimals - - // SPDLOG_DEBUG("enable_erc20_with_tokens: {}", j.dump(4)); + SPDLOG_DEBUG("enable_eth_with_tokens: {}", j.dump(4)); } void to_json(nlohmann::json& j, const enable_eth_with_tokens_request_rpc::erc20_token_request_t& in) diff --git a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_eth_with_tokens.hpp b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_eth_with_tokens.hpp index 5561b2fa40..9205777d8d 100644 --- a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_eth_with_tokens.hpp +++ b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_eth_with_tokens.hpp @@ -44,6 +44,7 @@ namespace atomic_dex::mm2 std::string swap_contract_address; std::string fallback_swap_contract; bool tx_history{true}; + bool get_balances{true}; std::optional is_testnet{false}; std::optional gas_station_decimals; std::optional required_confirmations; @@ -69,8 +70,8 @@ namespace atomic_dex::mm2 }; std::size_t current_block; - std::unordered_map eth_addresses_infos; - std::unordered_map erc20_addresses_infos; + std::unordered_map eth_addresses_infos; + std::unordered_map erc20_addresses_infos; }; using expected_error_type = rpc_basic_error_type; @@ -78,6 +79,7 @@ namespace atomic_dex::mm2 expected_request_type request; std::optional result; std::optional error; + std::string raw_result; }; using enable_eth_with_tokens_request_rpc = enable_eth_with_tokens_rpc::expected_request_type; diff --git a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_slp_rpc.hpp b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_slp_rpc.hpp index ce0d53d81d..6cabbe2f72 100644 --- a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_slp_rpc.hpp +++ b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_slp_rpc.hpp @@ -51,6 +51,7 @@ namespace atomic_dex::mm2 expected_request_type request; std::optional result; std::optional error; + std::string raw_result; }; using enable_slp_rpc_request = enable_slp_rpc::expected_request_type; diff --git a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_tendermint_token.hpp b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_tendermint_token.hpp index 90b0ef37ef..86d7525f1d 100644 --- a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_tendermint_token.hpp +++ b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_tendermint_token.hpp @@ -48,6 +48,7 @@ namespace atomic_dex::mm2 expected_request_type request; std::optional result; std::optional error; + std::string raw_result; }; using enable_tendermint_token_rpc_request = enable_tendermint_token_rpc::expected_request_type; diff --git a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_tendermint_with_assets.hpp b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_tendermint_with_assets.hpp index 22aed96a49..76876d0a89 100644 --- a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_tendermint_with_assets.hpp +++ b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.enable_tendermint_with_assets.hpp @@ -47,6 +47,7 @@ namespace atomic_dex::mm2 expected_request_type request; std::optional result; std::optional error; + std::string raw_result; }; using enable_tendermint_with_assets_request_rpc = enable_tendermint_with_assets_rpc::expected_request_type; diff --git a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.get_public_key.hpp b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.get_public_key.hpp index 6872e9ffdb..98f15bc9f2 100644 --- a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.get_public_key.hpp +++ b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.get_public_key.hpp @@ -43,6 +43,7 @@ namespace atomic_dex::mm2 expected_request_type request; std::optional result; std::optional error; + std::string raw_result; }; using get_public_key_rpc_request = get_public_key_rpc::expected_request_type; diff --git a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.my_tx_history.cpp b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.my_tx_history.cpp index 800ffb4cad..9b4a104837 100644 --- a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.my_tx_history.cpp +++ b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.my_tx_history.cpp @@ -1,8 +1,23 @@ -// komodo-wallet -// Author(s): syl +/****************************************************************************** + * Copyright © 2013-2021 The Komodo Platform Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * Komodo Platform software, including this file may be copied, modified, * + * propagated or distributed except according to the terms contained in the * + * LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ +//! Deps #include +//! Project Headers #include "atomicdex/api/mm2/rpc_v2/rpc2.my_tx_history.hpp" namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.my_tx_history.hpp b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.my_tx_history.hpp index 72d4c811fb..fd7089ae59 100644 --- a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.my_tx_history.hpp +++ b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.my_tx_history.hpp @@ -11,16 +11,16 @@ namespace atomic_dex::mm2 { - struct my_tx_history_rpc + struct my_tx_history_v2_rpc { static constexpr auto endpoint = "my_tx_history"; static constexpr bool is_v2 = true; struct expected_request_type { - std::string coin; - int limit; - paging_options paging_options; + std::string coin; + int limit; + paging_options_t paging_options; }; struct expected_result_type @@ -35,11 +35,12 @@ namespace atomic_dex::mm2 expected_request_type request; std::optional result; std::optional error; + std::string raw_result; }; - using my_tx_history_request_rpc = my_tx_history_rpc::expected_request_type; - using my_tx_history_result_rpc = my_tx_history_rpc::expected_result_type; - using my_tx_history_error_rpc = my_tx_history_rpc::expected_error_type; + using my_tx_history_request_rpc = my_tx_history_v2_rpc::expected_request_type; + using my_tx_history_result_rpc = my_tx_history_v2_rpc::expected_result_type; + using my_tx_history_error_rpc = my_tx_history_v2_rpc::expected_error_type; void to_json(nlohmann::json& j, const my_tx_history_request_rpc& in); void from_json(const nlohmann::json& json, my_tx_history_result_rpc& out); diff --git a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.orderbook.cpp b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.orderbook.cpp index 1ada91bcad..f80fa1ec55 100644 --- a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.orderbook.cpp +++ b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.orderbook.cpp @@ -16,6 +16,7 @@ //! Deps #include +#include //! Project Headers #include "atomicdex/api/mm2/rpc_v2/rpc2.orderbook.hpp" @@ -24,24 +25,48 @@ namespace atomic_dex::mm2 { void - from_json(const nlohmann::json& j, orderbook_answer& answer) + to_json(nlohmann::json& j, const orderbook_request_rpc& req) { - using namespace date; - // SPDLOG_INFO("got orderbook data..."); + j["base"] = req.base; + j["rel"] = req.rel; + } - j.at("result").at("base").get_to(answer.base); - j.at("result").at("rel").get_to(answer.rel); - j.at("result").at("num_asks").get_to(answer.numasks); - j.at("result").at("num_bids").get_to(answer.numbids); - j.at("result").at("net_id").get_to(answer.netid); - j.at("result").at("timestamp").get_to(answer.timestamp); - j.at("result").at("bids").get_to(answer.bids); - j.at("result").at("asks").get_to(answer.asks); + void + from_json(const nlohmann::json& j, orderbook_result_rpc& resp) + { + using namespace date; + // atomic_dex::utils::json_keys(j); + nlohmann::json k; + if (j.contains("result")) + { + // Not sure how why where it is being returned in this format + SPDLOG_DEBUG("orderbook_result_rpc: result"); + j.at("result").at("rel").get_to(resp.rel); + j.at("result").at("num_asks").get_to(resp.numasks); + j.at("result").at("num_bids").get_to(resp.numbids); + j.at("result").at("net_id").get_to(resp.netid); + j.at("result").at("timestamp").get_to(resp.timestamp); + j.at("result").at("bids").get_to(resp.bids); + j.at("result").at("asks").get_to(resp.asks); + j.at("result").at("base").get_to(resp.base); + } + else + { + SPDLOG_DEBUG("orderbook_result_rpc: base"); + j.at("base").get_to(resp.base); + j.at("rel").get_to(resp.rel); + j.at("num_asks").get_to(resp.numasks); + j.at("num_bids").get_to(resp.numbids); + j.at("net_id").get_to(resp.netid); + j.at("timestamp").get_to(resp.timestamp); + j.at("bids").get_to(resp.bids); + j.at("asks").get_to(resp.asks); + } - answer.human_timestamp = atomic_dex::utils::to_human_date(answer.timestamp, "%Y-%m-%d %I:%M:%S"); + resp.human_timestamp = atomic_dex::utils::to_human_date(resp.timestamp, "%Y-%m-%d %I:%M:%S"); t_float_50 result_asks_f(0); - for (auto&& cur_asks: answer.asks) { + for (auto&& cur_asks: resp.asks) { cur_asks.min_volume = cur_asks.base_min_volume; cur_asks.min_volume_fraction_numer = cur_asks.base_min_volume_numer; cur_asks.min_volume_fraction_denom = cur_asks.base_min_volume_denom; @@ -59,10 +84,10 @@ namespace atomic_dex::mm2 cur_asks.total = atomic_dex::utils::adjust_precision(total_f.str()); result_asks_f = result_asks_f + safe_float(cur_asks.max_volume); } - answer.asks_total_volume = result_asks_f.str(); + resp.asks_total_volume = result_asks_f.str(); t_float_50 result_bids_f(0); - for (auto& cur_bids: answer.bids) + for (auto& cur_bids: resp.bids) { cur_bids.min_volume = cur_bids.base_min_volume; cur_bids.min_volume_fraction_numer = cur_bids.base_min_volume_numer; @@ -82,16 +107,16 @@ namespace atomic_dex::mm2 cur_bids.total = atomic_dex::utils::adjust_precision(total_f.str()); result_bids_f = result_bids_f + safe_float(cur_bids.max_volume); } - answer.bids_total_volume = result_bids_f.str(); + resp.bids_total_volume = result_bids_f.str(); - for (auto&& cur_asks: answer.asks) + for (auto&& cur_asks: resp.asks) { t_float_50 percent_f = safe_float(cur_asks.max_volume) / result_asks_f; cur_asks.depth_percent = atomic_dex::utils::adjust_precision(percent_f.str()); // SPDLOG_INFO("cur_asks: {}", cur_asks.to_string()); } - for (auto&& cur_bids: answer.bids) + for (auto&& cur_bids: resp.bids) { t_float_50 percent_f = safe_float(cur_bids.max_volume) / result_bids_f; cur_bids.depth_percent = atomic_dex::utils::adjust_precision(percent_f.str()); @@ -99,10 +124,4 @@ namespace atomic_dex::mm2 } } - void - to_json(nlohmann::json& j, const orderbook_request& request) - { - j["params"]["base"] = request.base; - j["params"]["rel"] = request.rel; - } } // namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.orderbook.hpp b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.orderbook.hpp index 4af01b8703..6b3a5bd3a2 100644 --- a/src/core/atomicdex/api/mm2/rpc_v2/rpc2.orderbook.hpp +++ b/src/core/atomicdex/api/mm2/rpc_v2/rpc2.orderbook.hpp @@ -16,48 +16,56 @@ #pragma once -//! Deps -#include +#include +#include -//! Project Headers +#include //> nlohmann::json + +#include "atomicdex/api/mm2/rpc.hpp" #include "atomicdex/api/mm2/orderbook.order.contents.hpp" namespace atomic_dex::mm2 { - struct orderbook_request + struct orderbook_rpc { - std::string base; - std::string rel; - }; + static constexpr auto endpoint = "orderbook"; + static constexpr bool is_v2 = true; - void to_json(nlohmann::json& j, const orderbook_request& request); + struct expected_request_type + { + std::string base; + std::string rel; + }; - struct orderbook_answer - { - std::size_t askdepth{0}; - std::size_t biddepth{0}; - std::vector asks; - std::vector bids; - std::string base; - std::string rel; - std::size_t numasks; - std::size_t numbids; - std::size_t timestamp; - std::size_t netid; - std::string human_timestamp; //! Moment of the orderbook request human readeable - std::string asks_total_volume; - std::string bids_total_volume; - - //! Internal - std::string raw_result; - int rpc_result_code; + struct expected_result_type + { + std::size_t askdepth; + std::size_t biddepth; + std::vector asks; + std::vector bids; + std::string base; + std::string rel; + std::size_t numasks; + std::size_t numbids; + std::size_t timestamp; + std::size_t netid; + std::string human_timestamp; //! human readable orderbook request time + std::string asks_total_volume; + std::string bids_total_volume; + }; + + using expected_error_type = rpc_basic_error_type; + + expected_request_type request; + std::optional result; + std::optional error; + std::string raw_result; }; - void from_json(const nlohmann::json& j, orderbook_answer& answer); -} + using orderbook_request_rpc = orderbook_rpc::expected_request_type; + using orderbook_result_rpc = orderbook_rpc::expected_result_type; + using orderbook_error_rpc = orderbook_rpc::expected_error_type; -namespace atomic_dex -{ - using t_orderbook_request = mm2::orderbook_request; - using t_orderbook_answer = mm2::orderbook_answer; -} \ No newline at end of file + void to_json(nlohmann::json& j, const orderbook_request_rpc& req); + void from_json(const nlohmann::json& j, orderbook_result_rpc& resp); +} diff --git a/src/core/atomicdex/api/mm2/utxo.merge.params.cpp b/src/core/atomicdex/api/mm2/utxo_merge_params.cpp similarity index 70% rename from src/core/atomicdex/api/mm2/utxo.merge.params.cpp rename to src/core/atomicdex/api/mm2/utxo_merge_params.cpp index 9073ecef8f..2a5d29c474 100644 --- a/src/core/atomicdex/api/mm2/utxo.merge.params.cpp +++ b/src/core/atomicdex/api/mm2/utxo_merge_params.cpp @@ -16,14 +16,21 @@ #include -#include "utxo.merge.params.hpp" +#include "utxo_merge_params.hpp" namespace atomic_dex::mm2 { - void to_json(nlohmann::json& j, const utxo_merge_params& cfg) + void to_json(nlohmann::json& j, const utxo_merge_params_t& req) { - j["merge_at"] = cfg.merge_at; - j["check_every"] = cfg.check_every; - j["max_merge_at_once"] = cfg.max_merge_at_once; + j["merge_at"] = req.merge_at; + j["check_every"] = req.check_every; + j["max_merge_at_once"] = req.max_merge_at_once; } -} \ No newline at end of file + void + from_json(const nlohmann::json& j, utxo_merge_params_t& resp) + { + resp.merge_at = j.at("merge_at").get(); + resp.check_every = j.at("check_every").get(); + resp.max_merge_at_once = j.at("max_merge_at_once").get(); + } +} diff --git a/src/core/atomicdex/api/mm2/utxo.merge.params.hpp b/src/core/atomicdex/api/mm2/utxo_merge_params.hpp similarity index 93% rename from src/core/atomicdex/api/mm2/utxo.merge.params.hpp rename to src/core/atomicdex/api/mm2/utxo_merge_params.hpp index 93d05c6897..db30ee5008 100644 --- a/src/core/atomicdex/api/mm2/utxo.merge.params.hpp +++ b/src/core/atomicdex/api/mm2/utxo_merge_params.hpp @@ -20,12 +20,12 @@ namespace atomic_dex::mm2 { - struct utxo_merge_params + struct utxo_merge_params_t { std::size_t merge_at; std::size_t check_every; std::size_t max_merge_at_once; }; - void to_json(nlohmann::json& j, const utxo_merge_params& cfg); + void to_json(nlohmann::json& j, const utxo_merge_params_t& cfg); } \ No newline at end of file diff --git a/src/core/atomicdex/config/coins.cfg.cpp b/src/core/atomicdex/config/coins.cfg.cpp index d7148bb30c..1f846b5376 100644 --- a/src/core/atomicdex/config/coins.cfg.cpp +++ b/src/core/atomicdex/config/coins.cfg.cpp @@ -54,9 +54,13 @@ namespace { return CoinType::SLP; } + if (coin_type == "PLG-20") + { + return CoinType::PLG20; + } if (coin_type == "Matic") { - return CoinType::Matic; + return CoinType::PLG20; } if (coin_type == "Optimism") { @@ -147,7 +151,7 @@ namespace atomic_dex } void - from_json(const nlohmann::json& j, coin_config& cfg) + from_json(const nlohmann::json& j, coin_config_t& cfg) { j.at("coin").get_to(cfg.ticker); j.at("name").get_to(cfg.name); @@ -180,13 +184,9 @@ namespace atomic_dex cfg.other_types = std::set(); for (const auto& other_type: other_types) { cfg.other_types->emplace(get_coin_type_from_str(other_type)); } } - if (j.contains("utxo_merge")) - { - cfg.utxo_merge = j.at("utxo_merge"); - } - if (j.contains("mm2_backup")) + if (j.contains("merge_utxos")) { - cfg.custom_backup = j.at("mm2_backup"); + cfg.merge_utxos = j.at("merge_utxos"); } if (j.contains("activation_status")) { @@ -245,19 +245,24 @@ namespace atomic_dex { j.at("explorer_tx_url").get_to(cfg.tx_uri); } + if (j.contains("explorer_block_url")) + { + j.at("explorer_block_url").get_to(cfg.block_uri); + } if (j.contains("explorer_address_url")) { - j.at("explorer_address_url").get_to(cfg.address_url); + j.at("explorer_address_url").get_to(cfg.address_uri); } // Swap contract addresses if (j.contains("swap_contract_address")) { cfg.swap_contract_address = j["swap_contract_address"]; } - if (j.contains("fallback_swap_contract_address")) + if (j.contains("fallback_swap_contract")) { - cfg.fallback_swap_contract_address = j["fallback_swap_contract_address"]; + cfg.fallback_swap_contract = j["fallback_swap_contract"]; } + // Gas station urls if (j.contains("gas_station_url")) { @@ -293,7 +298,7 @@ namespace atomic_dex cfg.fees_ticker = cfg.is_testnet.value() ? "BNBT" : "BNB"; cfg.is_erc_family = true; break; - case CoinType::Matic: + case CoinType::PLG20: cfg.has_parent_fees_ticker = true; cfg.fees_ticker = cfg.is_testnet.value() ? "MATICTEST" : "MATIC"; cfg.is_erc_family = true; @@ -400,7 +405,7 @@ namespace atomic_dex } void - print_coins(std::vector coins) + print_coins(std::vector coins) { std::stringstream ss; ss << "["; diff --git a/src/core/atomicdex/config/coins.cfg.hpp b/src/core/atomicdex/config/coins.cfg.hpp index ea8a455a6a..457b432e8e 100644 --- a/src/core/atomicdex/config/coins.cfg.hpp +++ b/src/core/atomicdex/config/coins.cfg.hpp @@ -22,7 +22,7 @@ #include #include "atomicdex/api/mm2/mm2.constants.hpp" -#include "atomicdex/api/mm2/utxo.merge.params.hpp" +#include "atomicdex/api/mm2/utxo_merge_params.hpp" #include "atomicdex/config/electrum.cfg.hpp" #include "atomicdex/config/enable.cfg.hpp" #include "atomicdex/constants/qt.coins.enums.hpp" @@ -30,7 +30,7 @@ namespace atomic_dex { - struct coin_config + struct coin_config_t { std::optional erc_gas_stations{std::nullopt}; std::optional matic_gas_stations{std::nullopt}; @@ -43,6 +43,7 @@ namespace atomic_dex std::string ticker; std::string gui_ticker; ///< Ticker displayed in the gui std::string name; ///< nice name + std::string fname; ///< nice name std::string parent_coin; std::string fees_ticker; std::string type; @@ -51,7 +52,8 @@ namespace atomic_dex std::string livecoinwatch_id{"test-coin"}; std::string explorer_url; std::string tx_uri{"tx/"}; - std::string address_url{"address/"}; + std::string address_uri{"address/"}; + std::string block_uri{"block/"}; std::string minimal_claim_amount{"0"}; CoinType coin_type; nlohmann::json activation_status; @@ -73,13 +75,17 @@ namespace atomic_dex std::optional alias_ticker{std::nullopt}; std::optional allow_slp_unsafe_conf; std::optional is_testnet{false}; ///< True if testnet (tBTC, tQTUM, QRC-20 on testnet, tETH) - std::optional utxo_merge{false}; + std::optional merge_utxos{false}; std::optional swap_contract_address{std::nullopt}; - std::optional fallback_swap_contract_address{std::nullopt}; + std::optional fallback_swap_contract{std::nullopt}; std::optional gas_station_url{std::nullopt}; std::optional matic_gas_station_url{std::nullopt}; std::optional testnet_matic_gas_station_url{std::nullopt}; + std::optional contract_address{std::nullopt}; + std::optional derivation_path{std::nullopt}; + std::optional decimals{std::nullopt}; std::optional matic_gas_station_decimals{std::nullopt}; + std::optional chain_id{std::nullopt}; std::optional custom_backup; std::optional> other_types; std::optional electrum_urls; @@ -90,10 +96,11 @@ namespace atomic_dex std::optional bchd_urls; }; - void from_json(const nlohmann::json& j, coin_config& cfg); + void from_json(const nlohmann::json& j, coin_config_t& cfg); - void print_coins(std::vector coins); + void print_coins(std::vector coins); bool is_wallet_only(std::string ticker); bool is_default_coin(std::string ticker); bool is_faucet_coin(std::string ticker); + } // namespace atomic_dex \ No newline at end of file diff --git a/src/core/atomicdex/config/raw.mm2.coins.cfg.hpp b/src/core/atomicdex/config/raw.mm2.coins.cfg.hpp index 3f291ed49f..503a99828c 100644 --- a/src/core/atomicdex/config/raw.mm2.coins.cfg.hpp +++ b/src/core/atomicdex/config/raw.mm2.coins.cfg.hpp @@ -12,6 +12,7 @@ #include "atomicdex/api/mm2/mm2.constants.hpp" #include "atomicdex/utilities/global.utilities.hpp" #include "atomicdex/utilities/qt.utilities.hpp" +#include "atomicdex/api/mm2/address_format.hpp" #ifndef NLOHMANN_OPT_HELPER # define NLOHMANN_OPT_HELPER @@ -76,46 +77,42 @@ namespace atomic_dex return get_optional(j, property.data()); } - struct address_format - { - std::string format; - std::optional network{std::nullopt}; - }; struct coin_element { - std::string coin; - std::optional name{std::nullopt}; - std::optional fname{std::nullopt}; - std::optional etomic{std::nullopt}; - std::optional chain_id{std::nullopt}; - std::optional rpcport{std::nullopt}; - std::optional pubtype{std::nullopt}; - std::optional p2_shtype{std::nullopt}; - std::optional wiftype{std::nullopt}; - std::optional txfee{std::nullopt}; - std::optional confpath{std::nullopt}; - std::optional mm2{std::nullopt}; - std::optional required_confirmations{std::nullopt}; - std::optional asset{std::nullopt}; - std::optional txversion{std::nullopt}; - std::optional overwintered{std::nullopt}; - std::optional requires_notarization{std::nullopt}; - std::optional is_po_s{std::nullopt}; - std::optional segwit{std::nullopt}; - std::optional address_format{std::nullopt}; - std::optional estimate_fee_mode{std::nullopt}; - std::optional taddr{std::nullopt}; - std::optional decimals{std::nullopt}; - std::optional force_min_relay_fee{std::nullopt}; - std::optional p2_p{std::nullopt}; - std::optional magic{std::nullopt}; - std::optional n_spv{std::nullopt}; - std::optional version_group_id{std::nullopt}; - std::optional consensus_branch_id{std::nullopt}; - std::optional avg_blocktime{std::nullopt}; - std::optional dust{std::nullopt}; - nlohmann::json protocol; + using addr_fmt = mm2::address_format_t; + std::string coin; + std::optional name{std::nullopt}; + std::optional fname{std::nullopt}; + std::optional etomic{std::nullopt}; + std::optional chain_id{std::nullopt}; + std::optional rpcport{std::nullopt}; + std::optional pubtype{std::nullopt}; + std::optional p2_shtype{std::nullopt}; + std::optional wiftype{std::nullopt}; + std::optional txfee{std::nullopt}; + std::optional confpath{std::nullopt}; + std::optional mm2{std::nullopt}; + std::optional required_confirmations{std::nullopt}; + std::optional asset{std::nullopt}; + std::optional txversion{std::nullopt}; + std::optional overwintered{std::nullopt}; + std::optional requires_notarization{std::nullopt}; + std::optional is_po_s{std::nullopt}; + std::optional segwit{std::nullopt}; + std::optional address_format{std::nullopt}; + std::optional estimate_fee_mode{std::nullopt}; + std::optional taddr{std::nullopt}; + std::optional decimals{std::nullopt}; + std::optional force_min_relay_fee{std::nullopt}; + std::optional p2_p{std::nullopt}; + std::optional magic{std::nullopt}; + std::optional n_spv{std::nullopt}; + std::optional version_group_id{std::nullopt}; + std::optional consensus_branch_id{std::nullopt}; + std::optional avg_blocktime{std::nullopt}; + std::optional dust{std::nullopt}; + nlohmann::json protocol; }; using coins = std::vector; @@ -129,30 +126,9 @@ namespace atomic_dex namespace atomic_dex { - void from_json(const json& j, atomic_dex::address_format& x); - void to_json(json& j, const atomic_dex::address_format& x); - void from_json(const json& j, atomic_dex::coin_element& x); void to_json(json& j, const atomic_dex::coin_element& x); - inline void - from_json(const json& j, atomic_dex::address_format& x) - { - x.format = j.at("format").get(); - x.network = atomic_dex::get_optional(j, "network"); - } - - inline void - to_json(json& j, const atomic_dex::address_format& x) - { - j = json::object(); - j["format"] = x.format; - if (x.network.has_value()) - { - j["network"] = x.network.value(); - } - } - inline void from_json(const json& j, atomic_dex::coin_element& x) { @@ -175,7 +151,7 @@ namespace atomic_dex x.requires_notarization = atomic_dex::get_optional(j, "requires_notarization"); x.is_po_s = atomic_dex::get_optional(j, "isPoS"); x.segwit = atomic_dex::get_optional(j, "segwit"); - x.address_format = atomic_dex::get_optional(j, "address_format"); + x.address_format = atomic_dex::get_optional(j, "address_format"); x.estimate_fee_mode = atomic_dex::get_optional(j, "estimate_fee_mode"); x.taddr = atomic_dex::get_optional(j, "taddr"); x.decimals = atomic_dex::get_optional(j, "decimals"); diff --git a/src/core/atomicdex/constants/qt.coins.enums.hpp b/src/core/atomicdex/constants/qt.coins.enums.hpp index a89c819a58..02832d2e16 100644 --- a/src/core/atomicdex/constants/qt.coins.enums.hpp +++ b/src/core/atomicdex/constants/qt.coins.enums.hpp @@ -37,7 +37,7 @@ namespace atomic_dex UTXO = 3, SmartChain = 4, SLP = 5, - Matic = 6, + PLG20 = 6, Optimism = 7, Arbitrum = 8, AVX20 = 9, diff --git a/src/core/atomicdex/events/events.hpp b/src/core/atomicdex/events/events.hpp index b93f884706..8b468b8031 100644 --- a/src/core/atomicdex/events/events.hpp +++ b/src/core/atomicdex/events/events.hpp @@ -117,7 +117,7 @@ namespace atomic_dex std::string ticker; }; - struct orderbook_refresh + struct refresh_orderbook_model_data { std::string base; std::string rel; @@ -125,7 +125,7 @@ namespace atomic_dex struct coin_cfg_parsed { - std::vector cfg; + std::vector cfg; }; struct fatal_notification diff --git a/src/core/atomicdex/models/qt.global.coins.cfg.model.cpp b/src/core/atomicdex/models/qt.global.coins.cfg.model.cpp index 65ca718a44..7cdc580e28 100644 --- a/src/core/atomicdex/models/qt.global.coins.cfg.model.cpp +++ b/src/core/atomicdex/models/qt.global.coins.cfg.model.cpp @@ -26,7 +26,7 @@ namespace { QJsonObject - to_qt_binding(const atomic_dex::coin_config& coin) + to_qt_binding(const atomic_dex::coin_config_t& coin) { QJsonObject j{ {"active", coin.active}, @@ -39,7 +39,8 @@ namespace {"livecoinwatch_id", QString::fromStdString(coin.livecoinwatch_id)}, {"explorer_url", QString::fromStdString(coin.explorer_url)}, {"tx_uri", QString::fromStdString(coin.tx_uri)}, - {"address_uri", QString::fromStdString(coin.address_url)}, + {"block_uri", QString::fromStdString(coin.block_uri)}, + {"address_uri", QString::fromStdString(coin.address_uri)}, {"is_custom_coin", coin.is_custom_coin}, {"is_enabled", coin.currently_enabled}, {"has_parent_fees_ticker", coin.has_parent_fees_ticker}, @@ -86,7 +87,7 @@ namespace atomic_dex return {}; } - const coin_config& item = m_model_data.at(index.row()); + const coin_config_t& item = m_model_data.at(index.row()); switch (static_cast(role)) { case TickerRole: @@ -120,7 +121,7 @@ namespace atomic_dex bool global_coins_cfg_model::setData(const QModelIndex& index, const QVariant& value, int role) { - coin_config& item = m_model_data[index.row()]; + coin_config_t& item = m_model_data[index.row()]; switch (static_cast(role)) { case CurrentlyEnabled: @@ -192,7 +193,7 @@ namespace atomic_dex namespace atomic_dex { void - global_coins_cfg_model::initialize_model(std::vector cfg) + global_coins_cfg_model::initialize_model(std::vector cfg) { m_enabled_coins.clear(); m_all_coin_types.clear(); @@ -209,7 +210,7 @@ namespace atomic_dex m_enabled_coins[cur.ticker] = cur; } } - cfg.push_back(coin_config{.ticker = "All", .active = true, .currently_enabled = true}); + cfg.push_back(coin_config_t{.ticker = "All", .active = true, .currently_enabled = true}); SPDLOG_INFO("Initializing global coin cfg model with size {}", cfg.size()); set_checked_nb(0); beginResetModel(); @@ -377,19 +378,19 @@ namespace atomic_dex return m_all_coin_types; } - const std::vector& + const std::vector& global_coins_cfg_model::get_model_data() const { return m_model_data; } - coin_config + coin_config_t global_coins_cfg_model::get_coin_info(const std::string& ticker) const { if (const auto res = this->match(this->index(0, 0), TickerRole, QString::fromStdString(ticker), 1, Qt::MatchFlag::MatchExactly); not res.isEmpty()) { const QModelIndex& idx = res.at(0); - const coin_config& item = m_model_data.at(idx.row()); + const coin_config_t& item = m_model_data.at(idx.row()); return item; } return {}; diff --git a/src/core/atomicdex/models/qt.global.coins.cfg.model.hpp b/src/core/atomicdex/models/qt.global.coins.cfg.model.hpp index a3ae85fb2e..5d629b2540 100644 --- a/src/core/atomicdex/models/qt.global.coins.cfg.model.hpp +++ b/src/core/atomicdex/models/qt.global.coins.cfg.model.hpp @@ -39,7 +39,7 @@ namespace atomic_dex // Tells QT this class uses signal/slots mechanisms and/or has GUI elements. Q_OBJECT - using t_enabled_coins_registry = std::unordered_map; + using t_enabled_coins_registry = std::unordered_map; public: // Available Qt roles. @@ -64,7 +64,7 @@ namespace atomic_dex explicit global_coins_cfg_model(entt::registry& entity_registry, QObject* parent = nullptr); ~global_coins_cfg_model() final = default; - void initialize_model(std::vector cfg); + void initialize_model(std::vector cfg); template void update_status(const TArray& tickers, bool status); @@ -76,8 +76,8 @@ namespace atomic_dex [[nodiscard]] QHash roleNames() const final; // Getters/Setters - [[nodiscard]] const std::vector& get_model_data() const; - [[nodiscard]] coin_config get_coin_info(const std::string& ticker) const; + [[nodiscard]] const std::vector& get_model_data() const; + [[nodiscard]] coin_config_t get_coin_info(const std::string& ticker) const; [[nodiscard]] t_enabled_coins_registry get_enabled_coins() const; [[nodiscard]] global_coins_cfg_proxy_model* get_all_disabled_proxy() const; [[nodiscard]] global_coins_cfg_proxy_model* get_all_proxy() const; @@ -131,7 +131,7 @@ namespace atomic_dex void checked_nbChanged(); private: - std::vector m_model_data; // Contains all the data + std::vector m_model_data; // Contains all the data t_enabled_coins_registry m_enabled_coins; // Currently enabled_coins std::array m_proxies; diff --git a/src/core/atomicdex/models/qt.orderbook.model.cpp b/src/core/atomicdex/models/qt.orderbook.model.cpp index e89331b347..2aa52b3d4f 100644 --- a/src/core/atomicdex/models/qt.orderbook.model.cpp +++ b/src/core/atomicdex/models/qt.orderbook.model.cpp @@ -364,7 +364,7 @@ namespace atomic_dex void orderbook_model::reset_orderbook(const t_orders_contents& orderbook, bool is_bestorders) { - SPDLOG_DEBUG("[orderbook_model::reset_orderbook], is_bestorders: {}", is_bestorders); + // SPDLOG_DEBUG("[orderbook_model::reset_orderbook], is_bestorders: {}", is_bestorders); if (!orderbook.empty()) { SPDLOG_INFO( @@ -522,9 +522,9 @@ namespace atomic_dex } void - orderbook_model::refresh_orderbook(const t_orders_contents& orderbook, bool is_bestorders) + orderbook_model::refresh_orderbook_model_data(const t_orders_contents& orderbook, bool is_bestorders) { - SPDLOG_DEBUG("[orderbook_model::refresh_orderbook], is_bestorders: {}", is_bestorders); + // SPDLOG_DEBUG("[orderbook_model::refresh_orderbook_model_data], is_bestorders: {}", is_bestorders); auto refresh_functor = [this](const std::vector& contents) { for (auto&& order: contents) diff --git a/src/core/atomicdex/models/qt.orderbook.model.hpp b/src/core/atomicdex/models/qt.orderbook.model.hpp index 9ba89ca2a5..2ec3b7ef84 100644 --- a/src/core/atomicdex/models/qt.orderbook.model.hpp +++ b/src/core/atomicdex/models/qt.orderbook.model.hpp @@ -89,7 +89,7 @@ namespace atomic_dex bool removeRows(int row, int count, const QModelIndex& parent) override; void reset_orderbook(const t_orders_contents& orderbook, bool is_bestorders=false); - void refresh_orderbook(const t_orders_contents& orderbook, bool is_bestorders=false); + void refresh_orderbook_model_data(const t_orders_contents& orderbook, bool is_bestorders=false); void clear_orderbook(); [[nodiscard]] int get_length() const; [[nodiscard]] orderbook_proxy_model* get_orderbook_proxy() const; diff --git a/src/core/atomicdex/models/qt.portfolio.model.cpp b/src/core/atomicdex/models/qt.portfolio.model.cpp index 60ccf34f59..9b320fb3f0 100644 --- a/src/core/atomicdex/models/qt.portfolio.model.cpp +++ b/src/core/atomicdex/models/qt.portfolio.model.cpp @@ -60,20 +60,26 @@ namespace atomic_dex for (auto&& ticker: tickers) { if (m_ticker_registry.find(ticker) != m_ticker_registry.end()) + { + SPDLOG_INFO("ticker {} not in m_ticker_registry", ticker); continue; + } + SPDLOG_INFO("initialize_portfolio for ticker: {}", ticker); const auto& mm2_system = this->m_system_manager.get_system(); const auto& price_service = this->m_system_manager.get_system(); const auto& provider = this->m_system_manager.get_system(); auto coin = mm2_system.get_coin_info(ticker); - + SPDLOG_INFO("Building portfolio for ticker {}", coin.ticker); std::error_code ec; + std::string balance = mm2_system.my_balance(coin.ticker, ec); + SPDLOG_INFO("balance for ticker {}: {}", coin.ticker, balance); const QString change_24h = retrieve_change_24h(provider, coin, *m_config, m_system_manager); portfolio_data data{ .ticker = QString::fromStdString(coin.ticker), .gui_ticker = QString::fromStdString(coin.gui_ticker), .coin_type = QString::fromStdString(coin.type), .name = QString::fromStdString(coin.name), - .balance = QString::fromStdString(mm2_system.my_balance(coin.ticker, ec)), + .balance = QString::fromStdString(balance), .main_currency_balance = QString::fromStdString(price_service.get_price_in_fiat(m_config->current_currency, coin.ticker, ec)), .change_24h = change_24h, .main_currency_price_for_one_unit = QString::fromStdString(price_service.get_rate_conversion(m_config->current_currency, coin.ticker, true)), @@ -114,13 +120,14 @@ namespace atomic_dex { if (m_ticker_registry.find(coin.ticker) == m_ticker_registry.end()) { - SPDLOG_WARN("ticker: {} not inserted yet in the model, skipping", coin.ticker); + SPDLOG_WARN("[update_currency_values] ticker: {} not inserted yet in the model, skipping", coin.ticker); return false; } const std::string& ticker = coin.ticker; if (const auto res = this->match(this->index(0, 0), TickerRole, QString::fromStdString(ticker), 1, Qt::MatchFlag::MatchExactly); not res.isEmpty()) { + // SPDLOG_INFO("[update_currency_values] for ticker: {}", coin.ticker); std::error_code ec; const QModelIndex& idx = res.at(0); const QString main_currency_balance_value = QString::fromStdString(price_service.get_price_in_fiat(currency, ticker, ec)); @@ -171,9 +178,10 @@ namespace atomic_dex SPDLOG_WARN("ticker: {} not inserted yet in the model, skipping", ticker); return false; } - // SPDLOG_DEBUG("trying updating balance values of: {}", ticker); + if (const auto res = this->match(this->index(0, 0), TickerRole, QString::fromStdString(ticker), 1, Qt::MatchFlag::MatchExactly); not res.isEmpty()) { + // SPDLOG_DEBUG("Updating balance values of: {}", ticker); const auto& mm2_system = this->m_system_manager.get_system(); const auto* global_cfg = this->m_system_manager.get_system().get_global_cfg(); const auto coin = global_cfg->get_coin_info(ticker); diff --git a/src/core/atomicdex/pages/qt.settings.page.cpp b/src/core/atomicdex/pages/qt.settings.page.cpp index 547047b90e..91bc84f931 100644 --- a/src/core/atomicdex/pages/qt.settings.page.cpp +++ b/src/core/atomicdex/pages/qt.settings.page.cpp @@ -420,6 +420,8 @@ namespace atomic_dex return std_path_to_qstring(utils::get_runtime_coins_path()); } + // QRC20 option in add custom coin form has been disabled due to unresolved issues. + // This code remains for when we re-enable it in the future void settings_page::process_qrc_20_token_add(const QString& contract_address, const QString& coingecko_id, const QString& icon_filepath) { this->set_fetching_custom_token_data_busy(true); @@ -515,9 +517,9 @@ namespace atomic_dex { switch (coin_type) { - case CoinTypeGadget::QRC20: - return std::make_tuple( - &mm2::g_qtum_proxy_http_client, "/contract/"s + contract_address.toStdString(), "QRC20"s, "QTUM"s, "QRC-20"s, "QTUM"s, "QRC20"s); + // case CoinTypeGadget::QRC20: + // return std::make_tuple( + // &mm2::g_qtum_proxy_http_client, "/contract/"s + contract_address.toStdString(), "QRC20"s, "QTUM"s, "QRC-20"s, "QTUM"s, "QRC20"s); case CoinTypeGadget::ERC20: return std::make_tuple( &mm2::g_etherscan_proxy_http_client, "/api/v1/token_infos/erc20/"s + contract_address.toStdString(), "ERC20"s, "ETH"s, "ERC-20"s, @@ -544,24 +546,25 @@ namespace atomic_dex if (resp.status_code() == 200) { - nlohmann::json raw_parent_cfg = mm2.get_raw_mm2_ticker_cfg(parent_chain); - nlohmann::json body_json = nlohmann::json::parse(body).at("result")[0]; - const auto ticker = body_json.at("symbol").get() + "-" + type; - const auto name_lowercase = body_json.at("tokenName").get(); + nlohmann::json raw_parent_cfg = mm2.get_raw_mm2_ticker_cfg(parent_chain); + nlohmann::json body_json = nlohmann::json::parse(body).at("result")[0]; + const auto ticker = body_json.at("symbol").get() + "-" + type; + const auto name_lowercase = body_json.at("tokenName").get(); + const auto& coin_info = mm2.get_coin_info(parent_chain); + std::string token_contract_address = contract_address.toStdString(); + boost::algorithm::to_lower(token_contract_address); + utils::to_eth_checksum(token_contract_address); out["ticker"] = ticker; out["name"] = name_lowercase; copy_icon(icon_filepath, get_custom_coins_icons_path(), atomic_dex::utils::retrieve_main_ticker(ticker)); if (not is_this_ticker_present_in_raw_cfg(QString::fromStdString(ticker))) { - out["mm2_cfg"]["protocol"] = nlohmann::json::object(); - out["mm2_cfg"]["protocol"]["type"] = parent_type; - out["mm2_cfg"]["protocol"]["protocol_data"] = nlohmann::json::object(); - out["mm2_cfg"]["protocol"]["protocol_data"]["platform"] = platform; - std::string out_address = contract_address.toStdString(); - boost::algorithm::to_lower(out_address); - utils::to_eth_checksum(out_address); - out["mm2_cfg"]["protocol"]["protocol_data"]["contract_address"] = out_address; + out["mm2_cfg"]["protocol"] = nlohmann::json::object(); + out["mm2_cfg"]["protocol"]["type"] = parent_type; + out["mm2_cfg"]["protocol"]["protocol_data"] = nlohmann::json::object(); + out["mm2_cfg"]["protocol"]["protocol_data"]["platform"] = platform; + out["mm2_cfg"]["protocol"]["protocol_data"]["contract_address"] = token_contract_address; out["mm2_cfg"]["rpcport"] = raw_parent_cfg.at("rpcport"); out["mm2_cfg"]["coin"] = ticker; out["mm2_cfg"]["mm2"] = 1; @@ -577,18 +580,57 @@ namespace atomic_dex if (not is_this_ticker_present_in_normal_cfg(QString::fromStdString(ticker))) { //! - out["adex_cfg"][ticker] = nlohmann::json::object(); - out["adex_cfg"][ticker]["coin"] = ticker; - out["adex_cfg"][ticker]["name"] = name_lowercase; - out["adex_cfg"][ticker]["coingecko_id"] = coingecko_id.toStdString(); - const auto& coin_info = mm2.get_coin_info(parent_chain); - out["adex_cfg"][ticker]["nodes"] = coin_info.urls.value_or(std::vector()); - out["adex_cfg"][ticker]["explorer_url"] = coin_info.explorer_url; - out["adex_cfg"][ticker]["type"] = adex_platform; - out["adex_cfg"][ticker]["active"] = true; - out["adex_cfg"][ticker]["currently_enabled"] = false; - out["adex_cfg"][ticker]["is_custom_coin"] = true; - out["adex_cfg"][ticker]["mm2_backup"] = out["mm2_cfg"]; + out["adex_cfg"][ticker] = nlohmann::json::object(); + out["adex_cfg"][ticker]["active"] = true; + if (raw_parent_cfg.contains("chain_id")) + { + out["adex_cfg"][ticker]["chain_id"] = raw_parent_cfg.at("chain_id"); + } + out["adex_cfg"][ticker]["coin"] = ticker; + out["adex_cfg"][ticker]["coingecko_id"] = coingecko_id.toStdString(); + // contract address + if (raw_parent_cfg.contains("protocol")) + { + if (raw_parent_cfg.at("protocol").contains("protocol_data")) + { + if (raw_parent_cfg.at("protocol").at("protocol_data").contains("contract_address")) + { + out["adex_cfg"][ticker]["contract_address"] = raw_parent_cfg.at("protocol").at("protocol_data").at("contract_address"); + } + } + } + + out["adex_cfg"][ticker]["currently_enabled"] = false; + if (raw_parent_cfg.contains("decimals")) + { + out["adex_cfg"][ticker]["decimals"] = raw_parent_cfg.at("decimals"); + } + if (raw_parent_cfg.contains("derivation_path")) + { + out["adex_cfg"][ticker]["derivation_path"] = raw_parent_cfg.at("derivation_path"); + } + out["adex_cfg"][ticker]["explorer_address_url"] = coin_info.address_uri; + out["adex_cfg"][ticker]["explorer_block_url"] = coin_info.block_uri; + out["adex_cfg"][ticker]["explorer_tx_url"] = coin_info.tx_uri; + out["adex_cfg"][ticker]["explorer_url"] = coin_info.explorer_url; + out["adex_cfg"][ticker]["fallback_swap_contract"] = coin_info.swap_contract_address; + out["adex_cfg"][ticker]["fname"] = name_lowercase; + out["adex_cfg"][ticker]["is_testnet"] = true; + out["adex_cfg"][ticker]["currently_enabled"] = false; + out["adex_cfg"][ticker]["mm2"] = 1; + out["adex_cfg"][ticker]["name"] = name_lowercase; + out["adex_cfg"][ticker]["nodes"] = coin_info.urls.value_or(std::vector()); + out["adex_cfg"][ticker]["parent_coin"] = parent_chain; + out["adex_cfg"][ticker]["protocol"] = nlohmann::json::object(); + out["adex_cfg"][ticker]["protocol"]["protocol_data"] = nlohmann::json::object(); + out["adex_cfg"][ticker]["protocol"]["protocol_data"]["contract_address"] = token_contract_address; + out["adex_cfg"][ticker]["protocol"]["protocol_data"]["platform"] = platform; + out["adex_cfg"][ticker]["protocol"]["type"] = parent_type; + out["adex_cfg"][ticker]["required_confirmations"] = raw_parent_cfg.at("required_confirmations"); + out["adex_cfg"][ticker]["type"] = adex_platform; + out["adex_cfg"][ticker]["swap_contract_address"] = coin_info.swap_contract_address; + out["adex_cfg"][ticker]["wallet_only"] = false; + out["adex_cfg"][ticker]["is_custom_coin"] = true; } } else @@ -707,6 +749,11 @@ namespace atomic_dex return QString::fromStdString(mm2::rpc_version()); } + QString settings_page::get_peerid() + { + return QString::fromStdString(mm2::peer_id()); + } + QString settings_page::get_export_folder() { return QString::fromStdString(utils::get_atomic_dex_export_folder().string()); diff --git a/src/core/atomicdex/pages/qt.settings.page.hpp b/src/core/atomicdex/pages/qt.settings.page.hpp index 20a2c42808..2c2ab8b7b5 100644 --- a/src/core/atomicdex/pages/qt.settings.page.hpp +++ b/src/core/atomicdex/pages/qt.settings.page.hpp @@ -121,6 +121,7 @@ namespace atomic_dex Q_INVOKABLE void submit(); Q_INVOKABLE QStringList retrieve_seed(const QString& wallet_name, const QString& password); Q_INVOKABLE static QString get_mm2_version(); + Q_INVOKABLE static QString get_peerid(); Q_INVOKABLE static QString get_log_folder(); Q_INVOKABLE static QString get_export_folder(); Q_INVOKABLE static QString get_version(); diff --git a/src/core/atomicdex/pages/qt.trading.page.cpp b/src/core/atomicdex/pages/qt.trading.page.cpp index a89095c00a..2eda40fff9 100644 --- a/src/core/atomicdex/pages/qt.trading.page.cpp +++ b/src/core/atomicdex/pages/qt.trading.page.cpp @@ -16,6 +16,7 @@ #include #include +#include //! Project Headers #include "atomicdex/api/mm2/rpc_v1/rpc.buy.hpp" @@ -83,10 +84,10 @@ namespace atomic_dex } if (bool is_wallet_only = m_system_manager.get_system().get_coin_info(base.toStdString()).wallet_only; is_wallet_only) { - SPDLOG_WARN("{} is wallet only - skipping", base.toStdString()); + // SPDLOG_WARN("{} is wallet only - skipping", base.toStdString()); return; } - SPDLOG_DEBUG("Setting current orderbook: {} / {}", base.toStdString(), rel.toStdString()); + // SPDLOG_DEBUG("Setting current orderbook: {} / {}", base.toStdString(), rel.toStdString()); auto* market_selector_mdl = get_market_pairs_mdl(); const bool to_change = base != market_selector_mdl->get_left_selected_coin() || rel != market_selector_mdl->get_right_selected_coin(); @@ -97,18 +98,23 @@ namespace atomic_dex if (to_change && m_current_trading_mode != TradingModeGadget::Simple) { - SPDLOG_DEBUG("set_current_orderbook"); + // SPDLOG_DEBUG("set_current_orderbook"); this->get_orderbook_wrapper()->clear_orderbook(); this->clear_forms("set_current_orderbook"); } emit mm2MinTradeVolChanged(); - dispatcher_.trigger(base.toStdString(), rel.toStdString()); + dispatcher_.trigger(base.toStdString(), rel.toStdString()); } void - trading_page::swap_market_pair() + trading_page::swap_market_pair(bool involves_segwit) { + if (involves_segwit) + { + // TODO: Need to resolve this case. It is not clear what to do here, backend overrides are not reflected on the front end as expected. + SPDLOG_DEBUG("swap_market_pair involves_segwit. This is undefined behaviour"); + } const auto* market_selector_mdl = get_market_pairs_mdl(); set_current_orderbook(market_selector_mdl->get_right_selected_coin(), market_selector_mdl->get_left_selected_coin()); } @@ -182,7 +188,7 @@ namespace atomic_dex if (req.is_exact_selected_order_volume) { //! Selected order and we keep the exact volume (Basically swallow the order) - SPDLOG_DEBUG("swallowing the order from the orderbook"); + // SPDLOG_DEBUG("swallowing the order from the orderbook"); req.volume_numer = m_preferred_order->at("base_max_volume_numer").get(); req.volume_denom = m_preferred_order->at("base_max_volume_denom").get(); } @@ -190,14 +196,14 @@ namespace atomic_dex is_max && !req.is_exact_selected_order_volume && m_preferred_order->contains("max_volume_numer") && m_preferred_order->contains("max_volume_denom")) { - SPDLOG_DEBUG("cannot swallow the selected order from the orderbook, use our theoretical max_volume for it"); + // SPDLOG_DEBUG("cannot swallow the selected order from the orderbook, use our theoretical max_volume for it"); //! Selected order but we cannot swallow (not enough funds) set our theoretical max_volume_numer and max_volume_denom req.volume_numer = m_preferred_order->at("max_volume_numer").get(); req.volume_denom = m_preferred_order->at("max_volume_denom").get(); } else { - SPDLOG_DEBUG("Selected order, but changing manually the volume, use input_volume"); + // SPDLOG_DEBUG("Selected order, but changing manually the volume, use input_volume"); req.selected_order_use_input_volume = true; } } @@ -281,10 +287,8 @@ namespace atomic_dex t_float_50 base_min_trade = safe_float(get_orderbook_wrapper()->get_base_min_taker_vol().toStdString()); t_float_50 cur_min_trade = safe_float(get_min_trade_vol().toStdString()); - SPDLOG_DEBUG("base_min_trade: {}, cur_min_trade: {}", base_min_trade.str(), cur_min_trade.str()); - SPDLOG_DEBUG( - "volume: {}, orderbook_available_quantity: {}, is_selected_max: {}", m_volume.toStdString(), orderbook_available_quantity.toStdString(), - is_selected_max); + // SPDLOG_DEBUG("base_min_trade: {}, cur_min_trade: {}", base_min_trade.str(), cur_min_trade.str()); + // SPDLOG_DEBUG("volume: {}, orderbook_available_quantity: {}, is_selected_max: {}", m_volume.toStdString(), orderbook_available_quantity.toStdString(), is_selected_max); t_sell_request req{ .base = base.toStdString(), .rel = rel.toStdString(), @@ -326,14 +330,14 @@ namespace atomic_dex if (t_float_50 base_min_vol_orderbook_f = safe_float(base_min_vol_orderbook); cur_min_trade <= base_min_vol_orderbook_f) { - SPDLOG_DEBUG("The selected order min_vol input is too low, using null field instead"); + // SPDLOG_DEBUG("The selected order min_vol input is too low, using null field instead"); req.min_volume = std::optional{std::nullopt}; } if (req.is_exact_selected_order_volume) { //! Selected order and we keep the exact volume (Basically swallow the order) - SPDLOG_DEBUG("swallowing the order from the orderbook"); + // SPDLOG_DEBUG("swallowing the order from the orderbook"); req.volume_numer = m_preferred_order->at("base_max_volume_numer").get(); req.volume_denom = m_preferred_order->at("base_max_volume_denom").get(); } @@ -341,13 +345,13 @@ namespace atomic_dex ///< let's forbid it in simple ///< view { - SPDLOG_DEBUG("cannot swallow the selected order from the orderbook, use max_taker_volume for it"); + // SPDLOG_DEBUG("cannot swallow the selected order from the orderbook, use max_taker_volume for it"); req.volume_denom = max_taker_vol_json_obj["denom"].toString().toStdString(); req.volume_numer = max_taker_vol_json_obj["numer"].toString().toStdString(); } else { - SPDLOG_DEBUG("Selected order, but changing manually the volume, use input_volume"); + // SPDLOG_DEBUG("Selected order, but changing manually the volume, use input_volume"); req.selected_order_use_input_volume = true; } } @@ -380,7 +384,7 @@ namespace atomic_dex nlohmann::json answer = answers[0]; this->set_buy_sell_last_rpc_data(nlohmann_json_object_to_qt_json_object(answer)); auto& cur_mm2_system = m_system_manager.get_system(); - SPDLOG_DEBUG("order successfully placed, refreshing orders and swap"); + // SPDLOG_DEBUG("order successfully placed, refreshing orders and swap"); cur_mm2_system.batch_fetch_orders_and_swap(); } else @@ -485,13 +489,14 @@ namespace atomic_dex case trading_actions::post_process_orderbook_finished: { std::error_code ec; - t_orderbook_answer result = mm2_system.get_orderbook(ec); + mm2::orderbook_result_rpc result = mm2_system.get_orderbook(ec); if (!ec) { - // SPDLOG_DEBUG("[process_action::post_process_orderbook_finished]"); + // SPDLOG_DEBUG("[process_action::post_process_orderbook_finished] Needs reset: {}", m_models_actions[orderbook_need_a_reset]); + // SPDLOG_DEBUG(">>>> triggers: {}", m_models_actions[orderbook_need_a_reset] ? "reset_orderbook" : "refresh_orderbook_model_data"); auto* wrapper = get_orderbook_wrapper(); - m_models_actions[orderbook_need_a_reset] ? wrapper->reset_orderbook(result) : wrapper->refresh_orderbook(result); + m_models_actions[orderbook_need_a_reset] ? wrapper->reset_orderbook(result) : wrapper->refresh_orderbook_model_data(result); if (m_models_actions[orderbook_need_a_reset] && this->m_current_trading_mode == TradingModeGadget::Pro) { @@ -609,7 +614,7 @@ namespace atomic_dex if (this->m_market_mode != market_mode) { this->m_market_mode = market_mode; - SPDLOG_DEBUG("switching market_mode, new mode: {}", m_market_mode == MarketMode::Buy ? "buy" : "sell"); + // SPDLOG_DEBUG("switching market_mode, new mode: {}", m_market_mode == MarketMode::Buy ? "buy" : "sell"); this->clear_forms("set_market_mode"); const auto* market_selector_mdl = get_market_pairs_mdl(); set_current_orderbook(market_selector_mdl->get_left_selected_coin(), market_selector_mdl->get_right_selected_coin()); @@ -645,7 +650,7 @@ namespace atomic_dex m_price = std::move(price); if (this->m_preferred_order.has_value() && this->m_preferred_order->contains("locked")) { - SPDLOG_WARN("releasing preferred order because price has been modified"); + // SPDLOG_WARN("releasing preferred order because price has been modified"); this->m_preferred_order = std::nullopt; emit preferredOrderChanged(); } @@ -678,12 +683,12 @@ namespace atomic_dex SPDLOG_WARN("MM2 service not available, required to clear forms - skipping"); return; } - SPDLOG_DEBUG("clearing forms : {}", from.toStdString()); + // SPDLOG_DEBUG("clearing forms : {}", from.toStdString()); if (m_preferred_order.has_value() && m_current_trading_mode == TradingModeGadget::Simple && m_selected_order_status == SelectedOrderGadget::OrderNotExistingAnymore) { - SPDLOG_DEBUG("Simple view cancel order, keeping important data"); + // SPDLOG_DEBUG("Simple view cancel order, keeping important data"); this->set_volume(QString::fromStdString(m_preferred_order->at("initial_input_volume").get())); const auto max_taker_vol = get_orderbook_wrapper()->get_base_max_taker_vol().toJsonObject()["decimal"].toString(); this->set_max_volume(max_taker_vol); @@ -733,7 +738,7 @@ namespace atomic_dex volume = "0"; } m_volume = std::move(volume); - SPDLOG_DEBUG("volume is : [{}]", m_volume.toStdString()); + // SPDLOG_DEBUG("volume is : [{}]", m_volume.toStdString()); this->determine_total_amount(); emit volumeChanged(); @@ -756,7 +761,7 @@ namespace atomic_dex { max_volume = QString::fromStdString(utils::extract_large_float(max_volume.toStdString())); m_max_volume = std::move(max_volume); - SPDLOG_DEBUG("max_volume is [{}]", m_max_volume.toStdString()); + // SPDLOG_DEBUG("max_volume is [{}]", m_max_volume.toStdString()); emit maxVolumeChanged(); } } @@ -786,9 +791,9 @@ namespace atomic_dex { auto available_quantity = m_preferred_order->at("base_max_volume").get(); t_float_50 available_quantity_order = safe_float(available_quantity); - SPDLOG_DEBUG( - "available_quantity_order: {}, max_volume: {}, max_taker_vol: {}", utils::format_float(safe_float(available_quantity)), - get_max_volume().toStdString(), max_taker_vol); + // SPDLOG_DEBUG( + // "available_quantity_order: {}, max_volume: {}, max_taker_vol: {}", utils::format_float(safe_float(available_quantity)), + // get_max_volume().toStdString(), max_taker_vol); if (available_quantity_order < safe_float(max_taker_vol) && !m_preferred_order->at("capped").get()) { max_vol_str = available_quantity; @@ -799,7 +804,7 @@ namespace atomic_dex { if (!m_preferred_order->at("capped").get()) { - SPDLOG_DEBUG("Selected order capping to max_taker_vol because our max_taker_volume is < base_max_volume"); + // SPDLOG_DEBUG("Selected order capping to max_taker_vol because our max_taker_volume is < base_max_volume"); m_preferred_order.value()["capped"] = true; this->set_max_volume(QString::fromStdString(max_vol_str)); } @@ -814,6 +819,7 @@ namespace atomic_dex //! Capping it this->cap_volume(); + //SPDLOG_WARN("max_taker_vol this->cap_volume()"); } else { @@ -862,6 +868,7 @@ namespace atomic_dex } } this->cap_volume(); + // SPDLOG_WARN("max_taker_vol this->cap_volume()"); } else { @@ -874,6 +881,7 @@ namespace atomic_dex } this->set_max_volume(QString::fromStdString(utils::format_float(res))); this->cap_volume(); + // SPDLOG_WARN("max_taker_vol this->cap_volume()"); } } } @@ -886,13 +894,13 @@ namespace atomic_dex * cap_volume is called only in MarketMode::Buy, and in Sell mode if preferred order * if the current volume text field is > the new max_volume then set volume to max_volume */ - if (auto std_volume = this->get_volume().toStdString(); - !std_volume.empty() && safe_float(std_volume) > safe_float(this->get_max_volume().toStdString())) + auto max_volume = this->get_max_volume(); + auto std_volume = this->get_volume().toStdString(); + if (!std_volume.empty() && safe_float(std_volume) > safe_float(max_volume.toStdString())) { - auto max_volume = this->get_max_volume(); if (!max_volume.isEmpty() && max_volume != "0") { - SPDLOG_DEBUG("capping volume because {} (volume) > {} (max_volume)", std_volume, max_volume.toStdString()); + // SPDLOG_DEBUG("capping volume because {} (volume) > {} (max_volume)", std_volume, max_volume.toStdString()); this->set_volume(get_max_volume()); } } @@ -975,57 +983,66 @@ namespace atomic_dex entity_registry_.template ctx().setValue("DefaultTradingMode", m_current_trading_mode); // get_market_pairs_mdl()->get_left_selection_box()->set_with_fiat_balance(m_current_trading_mode == TradingMode::Simple); get_market_pairs_mdl()->get_left_selection_box()->set_with_balance(m_current_trading_mode == TradingMode::Simple); - SPDLOG_DEBUG("Set trading mode to: {}", QMetaEnum::fromType().valueToKey(trading_mode)); + // SPDLOG_DEBUG("Set trading mode to: {}", QMetaEnum::fromType().valueToKey(trading_mode)); emit tradingModeChanged(); } } bool - trading_page::set_pair(bool is_left_side, const QString& changed_ticker) + trading_page::set_pair(bool is_left_side, const QString& requested_ticker) { - // SPDLOG_DEBUG("Changed ticker: {}", changed_ticker.toStdString()); - const auto* market_pair = get_market_pairs_mdl(); - auto base = market_pair->get_left_selected_coin(); - auto rel = market_pair->get_right_selected_coin(); + // SPDLOG_DEBUG("Changed ticker: {}", requested_ticker.toStdString()); + const auto* market_pair = get_market_pairs_mdl(); + auto base = market_pair->get_left_selected_coin(); + auto rel = market_pair->get_right_selected_coin(); + std::string requested_coin = boost::replace_all_copy(requested_ticker.toStdString(), "-segwit", ""); + std::string base_coin = boost::replace_all_copy(base.toStdString(), "-segwit", ""); + std::string rel_coin = boost::replace_all_copy(rel.toStdString(), "-segwit", ""); + bool involves_segwit = false; + if (requested_coin == base_coin && requested_coin == rel_coin) + { + SPDLOG_DEBUG("Trying to select a segwit self pair. Naughty boy!"); + involves_segwit = true; + } bool is_swap = false; - if (!changed_ticker.isEmpty()) + if (!requested_ticker.isEmpty()) { if (is_left_side) { - if (base == changed_ticker) + if (base == requested_ticker) { return false; } - if (base != changed_ticker && rel == changed_ticker) + if (base != requested_ticker && rel == requested_ticker) { is_swap = true; } else { - base = changed_ticker; + base = requested_ticker; } } else { - if (rel == changed_ticker) + if (rel == requested_ticker) { return false; } - if (rel != changed_ticker && base == changed_ticker) + if (rel != requested_ticker && base == requested_ticker) { is_swap = true; } else { - rel = changed_ticker; + rel = requested_ticker; } } } if (is_swap) { - swap_market_pair(); + swap_market_pair(involves_segwit); base = market_pair->get_left_selected_coin(); rel = market_pair->get_right_selected_coin(); } @@ -1065,7 +1082,7 @@ namespace atomic_dex { return; } - SPDLOG_DEBUG("preferred_order: {}", preferred_order.dump(-1)); + // SPDLOG_DEBUG("preferred_order: {}", preferred_order.dump(-1)); m_preferred_order = std::move(preferred_order); emit preferredOrderChanged(); if (!m_preferred_order->empty() && m_preferred_order->contains("price")) @@ -1083,7 +1100,7 @@ namespace atomic_dex } else if (this->m_current_trading_mode == TradingModeGadget::Simple && m_preferred_order->contains("initial_input_volume")) { - SPDLOG_DEBUG("From simple view, using initial_input_volume from selection to use."); + // SPDLOG_DEBUG("From simple view, using initial_input_volume from selection to use."); this->set_volume(QString::fromStdString(m_preferred_order->at("initial_input_volume").get())); } this->get_orderbook_wrapper()->refresh_best_orders(); @@ -1201,13 +1218,13 @@ namespace atomic_dex mm2::to_json(preimage_request, req); batch.push_back(preimage_request); preimage_request["userpass"] = "******"; - SPDLOG_DEBUG("trade_preimage request: {}", preimage_request.dump(4)); + // SPDLOG_DEBUG("trade_preimage request: {}", preimage_request.dump(4)); this->set_preimage_busy(true); auto answer_functor = [this, &mm2](web::http::http_response resp) { std::string body = TO_STD_STR(resp.extract_string(true).get()); - SPDLOG_INFO("[determine_fees] trade_preimage answer received: {}", body); + // SPDLOG_INFO("[determine_fees] trade_preimage answer received: {}", body); if (resp.status_code() == web::http::status_codes::OK) { auto answers = nlohmann::json::parse(body); @@ -1263,6 +1280,7 @@ namespace atomic_dex void trading_page::determine_error_cases() { + // SPDLOG_DEBUG("determine_error_cases"); if (!m_system_manager.has_system()) return; TradingError current_trading_error = TradingError::None; diff --git a/src/core/atomicdex/pages/qt.trading.page.hpp b/src/core/atomicdex/pages/qt.trading.page.hpp index fc9a9286a5..af97e46860 100644 --- a/src/core/atomicdex/pages/qt.trading.page.hpp +++ b/src/core/atomicdex/pages/qt.trading.page.hpp @@ -155,7 +155,7 @@ namespace atomic_dex Q_INVOKABLE void clear_forms(QString from); //! Trading business - Q_INVOKABLE void swap_market_pair(); ///< market_selector (button to switch market selector and orderbook) + Q_INVOKABLE void swap_market_pair(bool involves_segwit = false); ///< market_selector (button to switch market selector and orderbook) Q_INVOKABLE bool set_pair(bool is_left_side, const QString& changed_ticker); Q_INVOKABLE void set_current_orderbook(const QString& base, const QString& rel); ///< market_selector (called and selecting another coin) diff --git a/src/core/atomicdex/pages/qt.wallet.page.cpp b/src/core/atomicdex/pages/qt.wallet.page.cpp index 7950e3740f..619709365a 100644 --- a/src/core/atomicdex/pages/qt.wallet.page.cpp +++ b/src/core/atomicdex/pages/qt.wallet.page.cpp @@ -59,6 +59,7 @@ namespace atomic_dex void wallet_page::check_send_availability() { + // SPDLOG_DEBUG("check_send_availability"); auto& mm2 = m_system_manager.get_system(); auto global_coins_cfg = m_system_manager.get_system().get_global_cfg(); auto ticker_info = global_coins_cfg->get_coin_info(mm2.get_current_ticker()); @@ -274,6 +275,7 @@ namespace atomic_dex auto& mm2_system = m_system_manager.get_system(); if (mm2_system.is_mm2_running()) { + SPDLOG_DEBUG("get_ticker_infos for {} wallet page", mm2_system.get_current_ticker()); auto& price_service = m_system_manager.get_system(); const auto& settings_system = m_system_manager.get_system(); const auto& provider = m_system_manager.get_system(); diff --git a/src/core/atomicdex/pages/widgets/dex/qt.orderbook.cpp b/src/core/atomicdex/pages/widgets/dex/qt.orderbook.cpp index 64ea29bb12..29a50e8adf 100644 --- a/src/core/atomicdex/pages/widgets/dex/qt.orderbook.cpp +++ b/src/core/atomicdex/pages/widgets/dex/qt.orderbook.cpp @@ -79,30 +79,31 @@ namespace atomic_dex } void - qt_orderbook_wrapper::refresh_orderbook(t_orderbook_answer answer) + qt_orderbook_wrapper::refresh_orderbook_model_data(mm2::orderbook_result_rpc answer) { - this->m_asks->refresh_orderbook(answer.asks); - this->m_bids->refresh_orderbook(answer.bids); - const auto data = this->m_system_manager.get_system().get_data(); + SPDLOG_INFO("[qt_orderbook_wrapper::refresh_orderbook_model_data] bids/asks size: {}/{}", answer.bids.size(), answer.asks.size()); + this->m_asks->refresh_orderbook_model_data(answer.asks); + this->m_bids->refresh_orderbook_model_data(answer.bids); + const auto data = this->m_system_manager.get_system().get_bestorders_data(); if (data.empty()) { m_best_orders->clear_orderbook(); } else if (m_best_orders->rowCount() == 0) { - // SPDLOG_INFO("[qt_orderbook_wrapper::refresh_orderbook] : reset_best_orders"); + SPDLOG_INFO("[qt_orderbook_wrapper::refresh_orderbook_model_data] : reset_best_orders"); m_best_orders->reset_orderbook(data, true); } else { - // SPDLOG_INFO("[qt_orderbook_wrapper::refresh_orderbook] : refresh_best_orders"); - m_best_orders->refresh_orderbook(data, true); + SPDLOG_INFO("[qt_orderbook_wrapper::refresh_orderbook_model_data] : refresh_best_orders"); + m_best_orders->refresh_orderbook_model_data(data, true); } this->set_both_taker_vol(); } void - qt_orderbook_wrapper::reset_orderbook(t_orderbook_answer answer) + qt_orderbook_wrapper::reset_orderbook(mm2::orderbook_result_rpc answer) { this->m_asks->reset_orderbook(answer.asks); this->m_bids->reset_orderbook(answer.bids); @@ -113,6 +114,7 @@ namespace atomic_dex m_system_manager.get_system().set_preferred_order(m_selected_best_order->value()); m_selected_best_order = std::nullopt; } + SPDLOG_INFO("m_best_orders->clear_orderbook()"); m_best_orders->clear_orderbook(); ///< Remove all elements from the model this->m_system_manager.get_system().process_best_orders(); ///< re process the model } @@ -172,10 +174,12 @@ namespace atomic_dex { if (safe_float(m_system_manager.get_system().get_volume().toStdString()) > 0) { + SPDLOG_INFO("qt_orderbook_wrapper::refresh_best_orders() >> process_best_orders()"); this->m_system_manager.get_system().process_best_orders(); } else { + SPDLOG_INFO("qt_orderbook_wrapper::refresh_best_orders() >> get_best_orders()->clear_orderbook()"); get_best_orders()->clear_orderbook(); } } diff --git a/src/core/atomicdex/pages/widgets/dex/qt.orderbook.hpp b/src/core/atomicdex/pages/widgets/dex/qt.orderbook.hpp index ee3551ba92..21cd4ae3bb 100644 --- a/src/core/atomicdex/pages/widgets/dex/qt.orderbook.hpp +++ b/src/core/atomicdex/pages/widgets/dex/qt.orderbook.hpp @@ -47,8 +47,8 @@ namespace atomic_dex public: void adjust_min_vol(); - void refresh_orderbook(t_orderbook_answer answer); - void reset_orderbook(t_orderbook_answer answer); + void refresh_orderbook_model_data(mm2::orderbook_result_rpc answer); + void reset_orderbook(mm2::orderbook_result_rpc answer); void clear_orderbook(); [[nodiscard]] orderbook_model* get_asks() const; [[nodiscard]] orderbook_model* get_bids() const; diff --git a/src/core/atomicdex/services/exporter/exporter.service.cpp b/src/core/atomicdex/services/exporter/exporter.service.cpp index 2a8fdf6632..604d7a8287 100644 --- a/src/core/atomicdex/services/exporter/exporter.service.cpp +++ b/src/core/atomicdex/services/exporter/exporter.service.cpp @@ -78,6 +78,7 @@ namespace atomic_dex .to_timestamp = swaps_data.filtering_infos.to_timestamp}; to_json(my_recent_swaps, request); batch.push_back(my_recent_swaps); + // SPDLOG_INFO("my_recent_swaps req: {}", my_recent_swaps.dump(4)); auto answer_functor = [csv_path](web::http::http_response resp) { auto answers = mm2::basic_batch_answer(resp); diff --git a/src/core/atomicdex/services/internet/internet.checker.service.cpp b/src/core/atomicdex/services/internet/internet.checker.service.cpp index edc7574076..9afafd488f 100644 --- a/src/core/atomicdex/services/internet/internet.checker.service.cpp +++ b/src/core/atomicdex/services/internet/internet.checker.service.cpp @@ -173,6 +173,7 @@ namespace atomic_dex SPDLOG_INFO("mm2 is alive, checking if we are able to fetch mm2 version"); nlohmann::json batch = nlohmann::json::array(); nlohmann::json current_request = mm2::template_request("version"); + // SPDLOG_DEBUG("version request {}", current_request.dump(4)); batch.push_back(current_request); auto async_answer = mm2.get_mm2_client().async_rpc_batch_standalone(batch); generic_treat_answer(async_answer, TO_STD_STR(atomic_dex::g_dex_rpc), &internet_service_checker::is_mm2_endpoint_alive); diff --git a/src/core/atomicdex/services/mm2/mm2.service.cpp b/src/core/atomicdex/services/mm2/mm2.service.cpp index 0008d483ea..e3cefbf725 100644 --- a/src/core/atomicdex/services/mm2/mm2.service.cpp +++ b/src/core/atomicdex/services/mm2/mm2.service.cpp @@ -20,13 +20,14 @@ #include #include +#include #include #include #include #include #include -#include "atomicdex/api/mm2/utxo.merge.params.hpp" +#include "atomicdex/api/mm2/utxo_merge_params.hpp" #include "atomicdex/api/mm2/rpc_v1/rpc.electrum.hpp" #include "atomicdex/api/mm2/rpc_v1/rpc.enable.hpp" #include "atomicdex/api/mm2/rpc_v1/rpc.min_trading_vol.hpp" @@ -155,10 +156,12 @@ namespace { if (registry[ticker].is_custom_coin) { + SPDLOG_DEBUG("Setting custom ticker: {} field {} to {}", ticker, field_name, status); custom_cfg_data.at(ticker)[field_name] = status; } else { + SPDLOG_DEBUG("Setting ticker: {} field {} to {}", ticker, field_name, status); config_json_data.at(ticker)[field_name] = status; } if (field_name == "active") @@ -192,9 +195,9 @@ namespace namespace atomic_dex { - std::vector mm2_service::retrieve_coins_informations() + std::vector mm2_service::retrieve_coins_informations() { - std::vector cfg; + std::vector cfg; SPDLOG_DEBUG("retrieve_coins_informations"); check_for_reconfiguration(m_current_wallet_name); @@ -203,7 +206,7 @@ namespace atomic_dex std::string custom_tokens_filename = "custom-tokens." + m_current_wallet_name + ".json"; LOG_PATH("Retrieving Wallet information of {}", (cfg_path / filename)); - auto retrieve_cfg_functor = [](std::filesystem::path path) -> std::unordered_map + auto retrieve_cfg_functor = [](std::filesystem::path path) -> std::unordered_map { if (exists(path)) { @@ -224,7 +227,7 @@ namespace atomic_dex } } - auto res = config_json_data.get>(); + auto res = config_json_data.get>(); return res; } catch (const std::exception& error) @@ -265,10 +268,9 @@ namespace atomic_dex { m_orderbook_clock = std::chrono::high_resolution_clock::now(); m_info_clock = std::chrono::high_resolution_clock::now(); - m_coins_clock = std::chrono::high_resolution_clock::now(); dispatcher_.sink().connect<&mm2_service::on_gui_enter_trading>(*this); dispatcher_.sink().connect<&mm2_service::on_gui_leave_trading>(*this); - dispatcher_.sink().connect<&mm2_service::on_refresh_orderbook>(*this); + dispatcher_.sink().connect<&mm2_service::on_refresh_orderbook_model_data>(*this); SPDLOG_INFO("mm2_service created"); } @@ -281,45 +283,58 @@ namespace atomic_dex return; } - const auto now = std::chrono::high_resolution_clock::now(); - const auto s_coins = std::chrono::duration_cast(now - m_coins_clock); - const auto s_book = std::chrono::duration_cast(now - m_orderbook_clock); - const auto s_info = std::chrono::duration_cast(now - m_info_clock); + const auto now = std::chrono::high_resolution_clock::now(); + const auto s_orderbook = std::chrono::duration_cast(now - m_orderbook_clock); + const auto s_info = std::chrono::duration_cast(now - m_info_clock); + const auto s_activation = std::chrono::duration_cast(now - m_activation_clock); - if (s_coins >= 5s) + if (s_orderbook >= 5s) { - if (m_nb_update_required > 0) + fetch_current_orderbook_thread(false); // process_orderbook (not a reset) if on trading page + batch_fetch_orders_and_swap(); // gets 'my_orders', 'my_recent_swaps' & 'active_swaps' + m_orderbook_clock = std::chrono::high_resolution_clock::now(); + } + + if (s_activation >= 7s) + { + auto coins = this->get_enabled_coins(); + std::vector tickers; + for (auto&& coin: coins) { - auto coins = this->get_enabled_coins(); - std::vector tickers; - for (auto&& coin: coins) - { - SPDLOG_DEBUG("{}: Active [{}]", coin.ticker, coin.active); - if (!coin.active) - { - tickers.push_back(coin.ticker); - } - } - if (!tickers.empty()) + if (!coin.active) { - SPDLOG_DEBUG("coin_status_update required, {}", m_nb_update_required); - update_coin_status(this->m_current_wallet_name, tickers, true, m_coins_informations, m_coin_cfg_mutex); + tickers.push_back(coin.ticker); } - m_nb_update_required -= 1; } - m_coins_clock = std::chrono::high_resolution_clock::now(); - } + if (!tickers.empty()) + { + // Mark coins as active internally, and updates the coins file + SPDLOG_DEBUG("Making sure {} enabled coins are marked as active", tickers.size()); + update_coin_status(this->m_current_wallet_name, tickers, true, m_coins_informations, m_coin_cfg_mutex); + } - if (s_book >= 7s) - { - fetch_current_orderbook_thread(false); - batch_fetch_orders_and_swap(); - m_orderbook_clock = std::chrono::high_resolution_clock::now(); + if (!m_activation_queue.empty()) + { + std::unique_lock lock(m_activation_mutex); + SPDLOG_DEBUG("{} coins in the activation queue", m_activation_queue.size()); + t_coins to_enable; + + for (size_t i = 0; i < 20 && i < m_activation_queue.size(); ++i) { + to_enable.push_back(m_activation_queue[i]); + } + activate_coins(to_enable); + m_activation_queue.erase(m_activation_queue.begin(), m_activation_queue.begin() + to_enable.size()); + m_activation_clock = std::chrono::high_resolution_clock::now(); + } + else { + SPDLOG_DEBUG("Coins activation queue is empty."); + m_activation_clock = std::chrono::high_resolution_clock::now() + std::chrono::duration_cast(std::chrono::seconds(6)); + } } - if (s_info >= 300s) + if (s_info >= 29s) { - fetch_infos_thread(); + fetch_infos_thread(); // leads to batch_balance_and_tx m_info_clock = std::chrono::high_resolution_clock::now(); } } @@ -329,7 +344,7 @@ namespace atomic_dex SPDLOG_INFO("destroying mm2 service..."); dispatcher_.sink().disconnect<&mm2_service::on_gui_enter_trading>(*this); dispatcher_.sink().disconnect<&mm2_service::on_gui_leave_trading>(*this); - dispatcher_.sink().disconnect<&mm2_service::on_refresh_orderbook>(*this); + dispatcher_.sink().disconnect<&mm2_service::on_refresh_orderbook_model_data>(*this); SPDLOG_INFO("mm2 signals successfully disconnected"); bool mm2_stopped = false; if (m_mm2_running) @@ -423,22 +438,22 @@ namespace atomic_dex { t_enable_z_coin_cancel_request request{.task_id = task_id}; auto answer = m_mm2_client.rpc_enable_z_coin_cancel(std::move(request)); - SPDLOG_DEBUG("mm2_service::enable_z_coin_cancel: [task_id {}] result: {}", task_id, answer.raw_result); + // SPDLOG_DEBUG("mm2_service::enable_z_coin_cancel: [task_id {}] result: {}", task_id, answer.raw_result); } bool mm2_service::disable_coin(const std::string& ticker, std::error_code& ec) { - coin_config coin_info = get_coin_info(ticker); + coin_config_t coin_info = get_coin_info(ticker); if (not coin_info.currently_enabled) { - SPDLOG_DEBUG("[mm2_service::disable_coin]: {} not currently_enabled", ticker); + // SPDLOG_DEBUG("[mm2_service::disable_coin]: {} not currently_enabled", ticker); return true; } t_disable_coin_request request{.coin = ticker}; auto answer = m_mm2_client.rpc_disable_coin(std::move(request)); - SPDLOG_DEBUG("mm2_service::disable_coin: {} result: {}", ticker, answer.raw_result); + // SPDLOG_DEBUG("mm2_service::disable_coin: {} result: {}", ticker, answer.raw_result); if (answer.error.has_value()) { @@ -475,7 +490,6 @@ namespace atomic_dex auto coins = get_active_coins(); enable_coins(coins); - batch_fetch_orders_and_swap(); this->dispatcher_.trigger(); return result.load() == 1; } @@ -485,7 +499,7 @@ namespace atomic_dex enable_coin(get_coin_info(ticker)); } - void mm2_service::enable_coin(const coin_config& coin_config) + void mm2_service::enable_coin(const coin_config_t& coin_config) { enable_coins(t_coins{coin_config}); } @@ -503,6 +517,22 @@ namespace atomic_dex } void mm2_service::enable_coins(const t_coins& coins) + { + t_coins enabled_coins = get_enabled_coins(); + for (const auto& coin : coins) + { + if (ranges::any_of(enabled_coins, [&coin](const auto& enabled_coin) { return enabled_coin.ticker == coin.ticker; })) + { + SPDLOG_WARN("{} cannot be enabled because it already is or is being enabled.", coin.ticker); + continue; + } + std::unique_lock lock(m_activation_mutex); + m_activation_queue.push_back(coin); + } + m_activation_clock = std::chrono::high_resolution_clock::now() - std::chrono::duration_cast(std::chrono::seconds(13)); + } + + void mm2_service::activate_coins(const t_coins& coins) { t_coins other_coins; t_coins erc_family_coins; @@ -512,94 +542,128 @@ namespace atomic_dex t_coins osmosis_coins; t_coins iris_coins; t_coins cosmos_coins; - - for (const auto& coin_config : coins) + t_coins bep20_coins; + t_coins bep20_testnet_coins; + + SPDLOG_INFO(">>>>>>>>>>>>>>>>>>>>>>>>>>> Enabling {} coins <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", coins.size()); + for (const auto& coin_cfg : coins) { - if (coin_config.currently_enabled) + if (coin_cfg.currently_enabled) { - SPDLOG_WARN("{} cannot be enabled because it already is or being enabled.", coin_config.ticker); + SPDLOG_WARN("{} cannot be enabled because it already is or is being enabled.", coin_cfg.ticker); + continue; } - else if (coin_config.coin_type == CoinType::SLP || (coin_config.other_types && coin_config.other_types->contains(CoinType::SLP))) + // SPDLOG_INFO("Preparing {} for activation", coin_cfg.ticker); + if (coin_cfg.coin_type == CoinType::SLP || (coin_cfg.other_types && coin_cfg.other_types->contains(CoinType::SLP))) { - if (coin_config.is_testnet.value_or(false)) + if (coin_cfg.is_testnet.value_or(false)) { - slp_testnet_coins.push_back(coin_config); + slp_testnet_coins.push_back(coin_cfg); } else { - slp_coins.push_back(coin_config); + slp_coins.push_back(coin_cfg); } } - else if (coin_config.coin_type == CoinType::TENDERMINT || coin_config.coin_type == CoinType::TENDERMINTTOKEN) + else if (coin_cfg.coin_type == CoinType::TENDERMINT || coin_cfg.coin_type == CoinType::TENDERMINTTOKEN) { - if (coin_config.parent_coin == "ATOM") + if (coin_cfg.parent_coin == "ATOM") { - cosmos_coins.push_back(coin_config); + cosmos_coins.push_back(coin_cfg); } - else if (coin_config.parent_coin == "IRIS") + else if (coin_cfg.parent_coin == "IRIS") { - iris_coins.push_back(coin_config); + iris_coins.push_back(coin_cfg); } - else if (coin_config.parent_coin == "OSMO") + else if (coin_cfg.parent_coin == "OSMO") { - osmosis_coins.push_back(coin_config); + osmosis_coins.push_back(coin_cfg); } else { - SPDLOG_WARN("Unexpected Tendermint ticker: {}", coin_config.ticker); - SPDLOG_WARN("Parent coin: {}", coin_config.parent_coin); + SPDLOG_WARN("Unexpected Tendermint ticker: {}", coin_cfg.ticker); + SPDLOG_WARN("Parent coin: {}", coin_cfg.parent_coin); } } - else if (coin_config.coin_type == CoinType::ZHTLC) + else if (coin_cfg.coin_type == CoinType::ZHTLC) + { + zhtlc_coins.push_back(coin_cfg); + } + else if (coin_cfg.coin_type == CoinType::BEP20) { - zhtlc_coins.push_back(coin_config); + coin_cfg.is_testnet.value_or(false) ? bep20_testnet_coins.push_back(coin_cfg) : bep20_coins.push_back(coin_cfg); } - else if (coin_config.is_erc_family) + else if (coin_cfg.is_erc_family) { - erc_family_coins.push_back(coin_config); + erc_family_coins.push_back(coin_cfg); } else { - other_coins.push_back(coin_config); + other_coins.push_back(coin_cfg); } } if (other_coins.size() > 0) { + SPDLOG_INFO(">>>>>>>>>>>>>>>>>>>>>>>>>>> Enabling {} utxo_qrc20_coins <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", other_coins.size()); enable_utxo_qrc20_coins(other_coins); } + if (bep20_coins.size() > 0) + { + SPDLOG_INFO(">>>>>>>>>>>>>>>>>>>>>>>>>>> Enabling {} BEP20 coins <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", bep20_coins.size()); + // enable_erc20_coins(bep20_coins, "BNB"); + enable_erc_family_coins(erc_family_coins); + } + if (bep20_testnet_coins.size() > 0) + { + SPDLOG_INFO(">>>>>>>>>>>>>>>>>>>>>>>>>>> Enabling {} bep20_testnet_coins <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", bep20_testnet_coins.size()); + // enable_erc20_coins(bep20_testnet_coins, "BNBT"); + enable_erc_family_coins(erc_family_coins); + } if (erc_family_coins.size() > 0) { + SPDLOG_INFO(">>>>>>>>>>>>>>>>>>>>>>>>>>> Enabling {} erc_family_coins <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", erc_family_coins.size()); enable_erc_family_coins(erc_family_coins); } if (slp_coins.size() > 0) { + SPDLOG_INFO(">>>>>>>>>>>>>>>>>>>>>>>>>>> Enabling {} slp_coins <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", slp_coins.size()); enable_slp_coins(slp_coins); } if (slp_testnet_coins.size() > 0) { + SPDLOG_INFO(">>>>>>>>>>>>>>>>>>>>>>>>>>> Enabling {} slp_testnet_coins <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", slp_testnet_coins.size()); enable_slp_testnet_coins(slp_testnet_coins); } if (zhtlc_coins.size() > 0) { + SPDLOG_INFO(">>>>>>>>>>>>>>>>>>>>>>>>>>> Enabling {} zhtlc_coins <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", zhtlc_coins.size()); enable_zhtlc(zhtlc_coins); } if (iris_coins.size() > 0) { + SPDLOG_INFO(">>>>>>>>>>>>>>>>>>>>>>>>>>> Enabling {} iris_coins <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", iris_coins.size()); enable_tendermint_coins(iris_coins, "IRIS"); } if (cosmos_coins.size() > 0) { + SPDLOG_INFO(">>>>>>>>>>>>>>>>>>>>>>>>>>> Enabling {} cosmos_coins <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", cosmos_coins.size()); enable_tendermint_coins(cosmos_coins, "ATOM"); } if (osmosis_coins.size() > 0) { + SPDLOG_INFO(">>>>>>>>>>>>>>>>>>>>>>>>>>> Enabling {} osmosis_coins <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<", osmosis_coins.size()); enable_tendermint_coins(osmosis_coins, "OSMO"); } } - void mm2_service::enable_erc_family_coin(const coin_config& coin_config) + void mm2_service::update_coin_active(const std::vector& tickers, bool status) + { + update_coin_status(this->m_current_wallet_name, tickers, status, m_coins_informations, m_coin_cfg_mutex); + } + + void mm2_service::enable_erc_family_coin(const coin_config_t& coin_cfg) { - enable_erc_family_coins(t_coins{coin_config}); + enable_erc_family_coins(t_coins{coin_cfg}); } void mm2_service::enable_erc_family_coins(const t_coins& coins) @@ -647,6 +711,8 @@ namespace atomic_dex std::vector tickers; for (auto&& coin: activated_coins) { + + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[coin.ticker].currently_enabled = true; tickers.push_back(coin.ticker); fetch_single_balance(coin); @@ -656,17 +722,18 @@ namespace atomic_dex std::vector failed_tickers; for (auto&& coin: failed_coins) { + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[coin.ticker].currently_enabled = false; failed_tickers.push_back(coin.ticker); } - //update_coin_active(failed_tickers, false); + update_coin_active(failed_tickers, false); + fetch_infos_thread(false, false); } } catch (const std::exception& error) { SPDLOG_ERROR(error.what()); } - this->m_nb_update_required += 1; }; for (const auto& coin_config : coins) @@ -680,9 +747,17 @@ namespace atomic_dex .swap_contract_address = coin_config.swap_contract_address.value_or(""), .with_tx_history = false }; - if (coin_config.fallback_swap_contract_address.value_or("") != "") + if (coin_config.fallback_swap_contract.value_or("") != "") + { + request.fallback_swap_contract = coin_config.fallback_swap_contract; + } + if (coin_config.is_custom_coin) { - request.fallback_swap_contract_address = coin_config.fallback_swap_contract_address; + request.mm2 = 1; + } + else if (coin_config.wallet_only) + { + request.mm2 = 0; } nlohmann::json j = mm2::template_request("enable"); mm2::to_json(j, request); @@ -693,15 +768,11 @@ namespace atomic_dex .then([this, batch_array](pplx::task previous_task) { this->handle_exception_pplx_task(previous_task, "enable_common_coins", batch_array); }); } - void mm2_service::enable_utxo_qrc20_coin(coin_config coin_config) + void mm2_service::enable_utxo_qrc20_coin(coin_config_t coin_config) { enable_utxo_qrc20_coins(t_coins{std::move(coin_config)}); } - void mm2_service::update_coin_active(const std::vector& tickers, bool status) - { - update_coin_status(this->m_current_wallet_name, tickers, status, m_coins_informations, m_coin_cfg_mutex); - } void mm2_service::enable_utxo_qrc20_coins(const t_coins& coins) { @@ -749,6 +820,7 @@ namespace atomic_dex std::vector tickers; for (auto&& coin: activated_coins) { + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[coin.ticker].currently_enabled = true; tickers.push_back(coin.ticker); fetch_single_balance(coin); @@ -758,17 +830,18 @@ namespace atomic_dex std::vector failed_tickers; for (auto&& coin: failed_coins) { + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[coin.ticker].currently_enabled = false; failed_tickers.push_back(coin.ticker); } update_coin_active(failed_tickers, false); + fetch_infos_thread(false, false); } } catch (const std::exception& error) { SPDLOG_ERROR(error.what()); } - this->m_nb_update_required += 1; }; for (const auto& coin_config : coins) @@ -782,10 +855,10 @@ namespace atomic_dex .is_testnet = coin_config.is_testnet.value_or(false), .with_tx_history = true }; - if (coin_config.utxo_merge.value_or(false)) + if (coin_config.merge_utxos.value_or(false)) { - mm2::utxo_merge_params merge_params{.merge_at = 250, .check_every = 300, .max_merge_at_once = 125}; - nlohmann::json json_merge_params; + mm2::utxo_merge_params_t merge_params{.merge_at = 250, .check_every = 300, .max_merge_at_once = 125}; + nlohmann::json json_merge_params; mm2::to_json(json_merge_params, merge_params); request.merge_params = json_merge_params; @@ -794,9 +867,9 @@ namespace atomic_dex { request.swap_contract_address = coin_config.swap_contract_address; } - if (coin_config.fallback_swap_contract_address.value_or("") != "") + if (coin_config.fallback_swap_contract.value_or("") != "") { - request.fallback_swap_contract_address = coin_config.fallback_swap_contract_address; + request.fallback_swap_contract = coin_config.fallback_swap_contract; } mm2::to_json(j, request); batch_array.push_back(j); @@ -807,14 +880,139 @@ namespace atomic_dex } - void mm2_service::enable_tendermint_coin(coin_config coin_config, std::string parent_ticker) + void mm2_service::enable_erc20_coin(coin_config_t coin_config, std::string parent_ticker) + { + enable_erc20_coins(t_coins{std::move(coin_config)}, parent_ticker); + } + + void mm2_service::enable_erc20_coins(const t_coins& coins, const std::string parent_ticker) + { + auto callback = [this](RpcRequest rpc) + { + if (rpc.error) + { + SPDLOG_ERROR("{} {}: ", rpc.request.ticker, rpc.error->error_type); + if (rpc.error->error_type.find("PlatformIsAlreadyActivated") != std::string::npos) + { + SPDLOG_ERROR("{} {}: ", rpc.request.ticker, rpc.error->error_type); + fetch_single_balance(get_coin_info(rpc.request.ticker)); + std::unique_lock lock(m_coin_cfg_mutex); + m_coins_informations[rpc.request.ticker].currently_enabled = true; + dispatcher_.trigger(coin_fully_initialized{.tickers = {rpc.request.ticker}}); + if constexpr (std::is_same_v) + { + SPDLOG_ERROR("{} {}: ", rpc.request.ticker, rpc.error->error_type); + + for (const auto& erc20_coin_info : rpc.request.erc20_tokens_requests) + { + SPDLOG_ERROR("{} {}: ", erc20_coin_info.ticker, rpc.error->error_type); + fetch_single_balance(get_coin_info(erc20_coin_info.ticker)); + std::unique_lock lock(m_coin_cfg_mutex); + m_coins_informations[erc20_coin_info.ticker].currently_enabled = true; + dispatcher_.trigger(coin_fully_initialized{.tickers = {erc20_coin_info.ticker}}); + } + } + } + else if (rpc.error->error_type.find("TokenIsAlreadyActivated") != std::string::npos) + { + SPDLOG_ERROR("{} {}: ", rpc.request.ticker, rpc.error->error_type); + } + else + { + SPDLOG_ERROR("marking {} as inactive: {}", rpc.request.ticker, rpc.error->error_type); + std::unique_lock lock(m_coin_cfg_mutex); + m_coins_informations[rpc.request.ticker].currently_enabled = false; + update_coin_active({rpc.request.ticker}, false); + this->dispatcher_.trigger(rpc.request.ticker, rpc.error->error); + } + } + else + { + dispatcher_.trigger(coin_fully_initialized{.tickers = {rpc.request.ticker}}); + fetch_single_balance(get_coin_info(rpc.request.ticker)); + std::unique_lock lock(m_coin_cfg_mutex); + m_coins_informations[rpc.request.ticker].currently_enabled = true; + SPDLOG_DEBUG("marking {} as active", rpc.request.ticker); + if constexpr (std::is_same_v) + { + for (const auto& erc20_address_info : rpc.result->erc20_addresses_infos) + { + SPDLOG_DEBUG("erc20_address_info.first {}: ", erc20_address_info.first); + if (erc20_address_info.second.balances.empty()) + { + SPDLOG_DEBUG("erc20_address_info.second.balances is empty"); + } + else + { + for (const auto& balance : erc20_address_info.second.balances) + { + SPDLOG_DEBUG("marking token {} as active", balance.first); + dispatcher_.trigger(coin_fully_initialized{.tickers = {balance.first}}); + //process_balance_answer(rpc); + fetch_single_balance(get_coin_info(balance.first)); + std::unique_lock lock(m_coin_cfg_mutex); + m_coins_informations[balance.first].currently_enabled = true; + } + } + } + } + SPDLOG_DEBUG("process_balance_answer(rpc) done"); + } + }; + + if (!has_coin(parent_ticker)) + { + static constexpr auto error = "{} is not present in the config. Cannot enable {} tokens."; + this->dispatcher_.trigger(parent_ticker, fmt::format(error, parent_ticker, parent_ticker)); + return; + } + + auto parent_ticker_info = get_coin_info(parent_ticker); + + if (parent_ticker_info.currently_enabled) + { + for (const auto& token_config : coins) + { + // SPDLOG_DEBUG("Processing {} token: {}", parent_ticker, token_config.ticker); + mm2::enable_erc20_rpc rpc{.request={.ticker = token_config.ticker}}; + + if (token_config.ticker == parent_ticker_info.ticker) + { + continue; + } + m_mm2_client.process_rpc_async(rpc.request, callback); + } + } + else + { + mm2::enable_eth_with_tokens_rpc rpc; + rpc.request.ticker = parent_ticker_info.ticker; + rpc.request.nodes = parent_ticker_info.urls.value_or(std::vector{}); + rpc.request.swap_contract_address = parent_ticker_info.swap_contract_address.value_or(""); + if (parent_ticker_info.fallback_swap_contract.value_or("") != "") + { + rpc.request.fallback_swap_contract = parent_ticker_info.fallback_swap_contract.value_or(""); + } + for (const auto& coin_config : coins) + { + if (coin_config.ticker == parent_ticker_info.ticker) + { + continue; + } + rpc.request.erc20_tokens_requests.push_back({.ticker = coin_config.ticker}); + } + m_mm2_client.process_rpc_async(rpc.request, callback); + } + SPDLOG_DEBUG("mm2_service::enable_erc20_coins done for {}", parent_ticker); + } + + void mm2_service::enable_tendermint_coin(coin_config_t coin_config, std::string parent_ticker) { enable_tendermint_coins(t_coins{std::move(coin_config)}, parent_ticker); } void mm2_service::enable_tendermint_coins(const t_coins& coins, const std::string parent_ticker) { - SPDLOG_INFO("Parent ticker: {}", parent_ticker); auto callback = [this](RpcRequest rpc) { if (rpc.error) @@ -823,6 +1021,7 @@ namespace atomic_dex { SPDLOG_ERROR("{} {}: ", rpc.request.ticker, rpc.error->error_type); fetch_single_balance(get_coin_info(rpc.request.ticker)); + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[rpc.request.ticker].currently_enabled = true; dispatcher_.trigger(coin_fully_initialized{.tickers = {rpc.request.ticker}}); if constexpr (std::is_same_v) @@ -831,6 +1030,7 @@ namespace atomic_dex { SPDLOG_ERROR("{} {}: ", tendermint_coin_info.ticker, rpc.error->error_type); fetch_single_balance(get_coin_info(tendermint_coin_info.ticker)); + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[tendermint_coin_info.ticker].currently_enabled = true; dispatcher_.trigger(coin_fully_initialized{.tickers = {tendermint_coin_info.ticker}}); } @@ -838,6 +1038,7 @@ namespace atomic_dex } else { + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[rpc.request.ticker].currently_enabled = false; update_coin_active({rpc.request.ticker}, false); this->dispatcher_.trigger(rpc.request.ticker, rpc.error->error); @@ -847,6 +1048,7 @@ namespace atomic_dex { dispatcher_.trigger(coin_fully_initialized{.tickers = {rpc.request.ticker}}); fetch_single_balance(get_coin_info(rpc.request.ticker)); + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[rpc.request.ticker].currently_enabled = true; if constexpr (std::is_same_v) { @@ -854,6 +1056,7 @@ namespace atomic_dex { dispatcher_.trigger(coin_fully_initialized{.tickers = {tendermint_token_addresses_info.first}}); process_balance_answer(rpc); + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[tendermint_token_addresses_info.first].currently_enabled = true; } } @@ -900,7 +1103,70 @@ namespace atomic_dex } m_mm2_client.process_rpc_async(rpc.request, callback); } - this->m_nb_update_required += 1; + } + + void mm2_service::process_balance_answer(const mm2::enable_erc20_rpc& rpc) + { + const auto& answer = rpc.result.value(); + mm2::balance_answer balance_answer; + + balance_answer.address = answer.balances.begin()->first; + SPDLOG_DEBUG("balance_answer.address: {}", balance_answer.address); + balance_answer.balance = answer.balances.begin()->second.spendable; + SPDLOG_DEBUG("balance_answer.balance: {}", balance_answer.balance); + balance_answer.coin = answer.platform_coin; + SPDLOG_DEBUG("balance_answer.coin: {}", balance_answer.coin); + { + std::unique_lock lock(m_balance_mutex); + m_balance_informations[balance_answer.coin] = std::move(balance_answer); + } + SPDLOG_DEBUG("balance_answer for {} complete", rpc.request.ticker); + } + + void mm2_service::process_balance_answer(const mm2::enable_eth_with_tokens_rpc& rpc) + { + SPDLOG_DEBUG("mm2_service::process_balance_answer(const mm2::enable_eth_with_tokens_rpc& rpc"); + const auto& answer = rpc.result.value(); + { + mm2::balance_answer balance_answer; + balance_answer.coin = rpc.request.ticker; + SPDLOG_DEBUG("balance_answer.coin: {}", balance_answer.coin); + balance_answer.balance = answer.eth_addresses_infos.begin()->second.balances.spendable; + SPDLOG_DEBUG("balance_answer.balance: {}", balance_answer.balance); + balance_answer.address = answer.eth_addresses_infos.begin()->first; + SPDLOG_DEBUG("balance_answer.address: {}", balance_answer.address); + { + std::unique_lock lock(m_balance_mutex); + m_balance_informations[balance_answer.coin] = std::move(balance_answer); + } + SPDLOG_DEBUG("balance_answer for {} complete", rpc.request.ticker); + } + if (answer.erc20_addresses_infos.empty()) + { + SPDLOG_DEBUG("answer.erc20_addresses_infos is empty"); + return; + } + SPDLOG_DEBUG("for (auto [address, data] : answer.erc20_addresses_infos) [{}]", answer.erc20_addresses_infos.size()); + for (auto [address, data] : answer.erc20_addresses_infos) + { + SPDLOG_DEBUG("for (auto [address, data] : answer.erc20_addresses_infos) address [{}]", address); + mm2::balance_answer balance_answer; + balance_answer.address = address; + if (data.balances.empty()) + { + SPDLOG_DEBUG("data.balances is empty"); + continue; + } + balance_answer.balance = data.balances.begin()->second.spendable; + SPDLOG_DEBUG("balance_answer.coin: {}", balance_answer.balance); + balance_answer.coin = data.balances.begin()->first; + SPDLOG_DEBUG("balance_answer.coin: {}", balance_answer.coin); + { + std::unique_lock lock(m_balance_mutex); + m_balance_informations[balance_answer.coin] = std::move(balance_answer); + } + } + SPDLOG_DEBUG("process_balance_answer for enable_eth_with_tokens_rpc complete"); } void mm2_service::process_balance_answer(const mm2::enable_tendermint_token_rpc& rpc) @@ -951,7 +1217,7 @@ namespace atomic_dex } } - void mm2_service::enable_slp_coin(coin_config coin_config) + void mm2_service::enable_slp_coin(coin_config_t coin_config) { enable_slp_coins(t_coins{std::move(coin_config)}); } @@ -963,10 +1229,11 @@ namespace atomic_dex { if (rpc.error) { + SPDLOG_ERROR("{} {}: ", rpc.request.ticker, rpc.error->error_type); if (rpc.error->error_type.find("PlatformIsAlreadyActivated") != std::string::npos || rpc.error->error_type.find("TokenIsAlreadyActivated") != std::string::npos) { - SPDLOG_ERROR("{} {}: ", rpc.request.ticker, rpc.error->error_type); fetch_single_balance(get_coin_info(rpc.request.ticker)); + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[rpc.request.ticker].currently_enabled = true; dispatcher_.trigger(coin_fully_initialized{.tickers = {rpc.request.ticker}}); if constexpr (std::is_same_v) @@ -975,6 +1242,7 @@ namespace atomic_dex { SPDLOG_ERROR("{} {}: ", slp_coin_info.ticker, rpc.error->error_type); fetch_single_balance(get_coin_info(slp_coin_info.ticker)); + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[slp_coin_info.ticker].currently_enabled = true; dispatcher_.trigger(coin_fully_initialized{.tickers = {slp_coin_info.ticker}}); } @@ -982,6 +1250,7 @@ namespace atomic_dex } else { + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[rpc.request.ticker].currently_enabled = false; update_coin_active({rpc.request.ticker}, false); this->dispatcher_.trigger(rpc.request.ticker, rpc.error->error); @@ -991,6 +1260,7 @@ namespace atomic_dex { dispatcher_.trigger(coin_fully_initialized{.tickers = {rpc.request.ticker}}); fetch_single_balance(get_coin_info(rpc.request.ticker)); + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[rpc.request.ticker].currently_enabled = true; if constexpr (std::is_same_v) { @@ -1000,13 +1270,13 @@ namespace atomic_dex { dispatcher_.trigger(coin_fully_initialized{.tickers = {balance.first}}); process_balance_answer(rpc); + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[balance.first].currently_enabled = true; } } } process_balance_answer(rpc); } - this->m_nb_update_required += 1; }; if (!has_coin(bch_ticker)) @@ -1054,7 +1324,7 @@ namespace atomic_dex } - void mm2_service::enable_slp_testnet_coin(coin_config coin_config) + void mm2_service::enable_slp_testnet_coin(coin_config_t coin_config) { enable_slp_testnet_coins(t_coins{std::move(coin_config)}); } @@ -1066,10 +1336,11 @@ namespace atomic_dex { if (rpc.error) { + SPDLOG_ERROR("{} {}: ", rpc.request.ticker, rpc.error->error_type); if (rpc.error->error_type.find("PlatformIsAlreadyActivated") != std::string::npos || rpc.error->error_type.find("TokenIsAlreadyActivated") != std::string::npos) { - SPDLOG_ERROR("{} {}: ", rpc.request.ticker, rpc.error->error_type); fetch_single_balance(get_coin_info(rpc.request.ticker)); + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[rpc.request.ticker].currently_enabled = true; dispatcher_.trigger(coin_fully_initialized{.tickers = {rpc.request.ticker}}); if constexpr (std::is_same_v) @@ -1078,6 +1349,7 @@ namespace atomic_dex { SPDLOG_ERROR("{} {}: ", slp_coin_info.ticker, rpc.error->error_type); fetch_single_balance(get_coin_info(slp_coin_info.ticker)); + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[slp_coin_info.ticker].currently_enabled = true; dispatcher_.trigger(coin_fully_initialized{.tickers = {slp_coin_info.ticker}}); } @@ -1085,6 +1357,7 @@ namespace atomic_dex } else { + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[rpc.request.ticker].currently_enabled = false; update_coin_active({rpc.request.ticker}, false); this->dispatcher_.trigger(rpc.request.ticker, rpc.error->error); @@ -1094,6 +1367,7 @@ namespace atomic_dex { dispatcher_.trigger(coin_fully_initialized{.tickers = {rpc.request.ticker}}); fetch_single_balance(get_coin_info(rpc.request.ticker)); + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[rpc.request.ticker].currently_enabled = true; if constexpr (std::is_same_v) { @@ -1103,13 +1377,13 @@ namespace atomic_dex { dispatcher_.trigger(coin_fully_initialized{.tickers = {balance.first}}); process_balance_answer(rpc); + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[balance.first].currently_enabled = true; } } } process_balance_answer(rpc); } - this->m_nb_update_required += 1; }; if (!has_coin(bch_ticker)) @@ -1227,6 +1501,7 @@ namespace atomic_dex (void)tickers; (void)is_during_enabling; auto&& [batch_array, tickers_idx, tokens_to_fetch] = prepare_batch_balance_and_tx(only_tx); + SPDLOG_DEBUG("mm2_service::batch_balance_and_tx"); return m_mm2_client.async_rpc_batch_standalone(batch_array) .then( [this, tokens_to_fetch = tokens_to_fetch, is_a_reset, tickers, batch_array = batch_array](web::http::http_response resp) @@ -1287,6 +1562,7 @@ namespace atomic_dex std::tuple, std::vector> mm2_service::prepare_batch_balance_and_tx(bool only_tx) const { + SPDLOG_DEBUG("mm2_service::prepare_batch_balance_and_tx"); const auto& enabled_coins = get_enabled_coins(); nlohmann::json batch_array = nlohmann::json::array(); std::vector tickers_idx; @@ -1396,7 +1672,7 @@ namespace atomic_dex void mm2_service::enable_zhtlc(const t_coins& coins) { - auto request_functor = [this](coin_config coin_info) -> std::pair> + auto request_functor = [this](coin_config_t coin_info) -> std::pair> { const auto& settings_system = m_system_manager.get_system(); @@ -1424,7 +1700,7 @@ namespace atomic_dex mm2::to_json(j, request); nlohmann::json batch = nlohmann::json::array(); batch.push_back(j); - SPDLOG_INFO("ZHTLC request: {}", batch.dump(4)); + // SPDLOG_INFO("ZHTLC request: {}", batch.dump(4)); return {batch, {coin_info.ticker}}; }; @@ -1457,7 +1733,6 @@ namespace atomic_dex SPDLOG_DEBUG("{} activation complete!", tickers[idx]); std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[tickers[idx]].currently_enabled = true; - this->m_nb_update_required += 1; this->dispatcher_.trigger(coin_fully_initialized{.tickers = {tickers[idx]}}); this->dispatcher_.trigger(tickers[idx], "Complete!"); } @@ -1481,7 +1756,7 @@ namespace atomic_dex nlohmann::json z_batch_array = nlohmann::json::array(); t_enable_z_coin_status_request z_request{.task_id = task_id}; - SPDLOG_INFO("{} enable_z_coin Task ID: {}", tickers[idx], task_id); + // SPDLOG_INFO("{} enable_z_coin Task ID: {}", tickers[idx], task_id); nlohmann::json j = mm2::template_request("task::enable_z_coin::status", true); mm2::to_json(j, z_request); @@ -1497,11 +1772,12 @@ namespace atomic_dex std::string status = z_answers[0].at("result").at("status").get(); // SPDLOG_DEBUG("{} status : {}", tickers[idx], status); - SPDLOG_INFO("{} Activation Status: {}", tickers[idx], z_answers[0].dump()); + // SPDLOG_INFO("{} Activation Status: {}", tickers[idx], z_answers[0].dump()); if (status == "Ok") { - SPDLOG_INFO("{} activation ready...", tickers[idx]); + // SPDLOG_INFO("{} activation ready...", tickers[idx]); + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[tickers[idx]].activation_status = z_answers[0]; if (z_answers[0].at("result").at("details").contains("error")) { @@ -1516,12 +1792,10 @@ namespace atomic_dex SPDLOG_INFO("Enabling [{}] error: {}", tickers[idx], event); break; } - SPDLOG_INFO("{} activation complete!", tickers[idx]); - std::unique_lock lock(m_coin_cfg_mutex); + // SPDLOG_INFO("{} activation complete!", tickers[idx]); m_coins_informations[tickers[idx]].currently_enabled = true; dispatcher_.trigger(coin_fully_initialized{.tickers = {tickers[idx]}}); - this->m_nb_update_required += 1; break; } else if (status == "Error") @@ -1557,14 +1831,13 @@ namespace atomic_dex if (event != last_event) { - SPDLOG_INFO("Waiting for {} to enable [{}: {}]...", tickers[idx], status, event); + // SPDLOG_INFO("Waiting for {} to enable [{}: {}]...", tickers[idx], status, event); if (!m_coins_informations[tickers[idx]].currently_enabled && event != "ActivatingCoin") { std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[tickers[idx]].currently_enabled = true; dispatcher_.trigger(coin_fully_initialized{.tickers = {tickers[idx]}}); - this->m_nb_update_required += 1; } this->dispatcher_.trigger(tickers[idx], event); last_event = event; @@ -1572,6 +1845,7 @@ namespace atomic_dex // todo(syl): refactor to a background task std::this_thread::sleep_for(5s); } + std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[tickers[idx]].activation_status = z_answers[0]; z_nb_try += 1; @@ -1642,7 +1916,6 @@ namespace atomic_dex SPDLOG_DEBUG("Init balance for {}...", tickers[0]); fetch_single_balance(get_coin_info(tickers[0])); } - this->m_nb_update_required += 1; } } } @@ -1659,7 +1932,6 @@ namespace atomic_dex this->handle_exception_pplx_task(previous_task, "batch_enable_coins", batch); update_coin_status(this->m_current_wallet_name, tickers, false, m_coins_informations, m_coin_cfg_mutex); }); - this->m_nb_update_required += 1; }; for (auto&& coin: coins) @@ -1707,7 +1979,7 @@ namespace atomic_dex return true; } - coin_config mm2_service::get_coin_info(const std::string& ticker) const + coin_config_t mm2_service::get_coin_info(const std::string& ticker) const { std::shared_lock lock(m_coin_cfg_mutex); if (m_coins_informations.find(ticker) == m_coins_informations.cend()) @@ -1728,7 +2000,7 @@ namespace atomic_dex } // [smk] Only called by trading_page::process_action() - t_orderbook_answer mm2_service::get_orderbook(t_mm2_ec& ec) const + mm2::orderbook_result_rpc mm2_service::get_orderbook(t_mm2_ec& ec) const { auto&& [base, rel] = this->m_synchronized_ticker_pair.get(); const std::string pair = base + "/" + rel; @@ -1736,52 +2008,82 @@ namespace atomic_dex if (orderbook.base.empty() && orderbook.rel.empty()) { ec = dextop_error::orderbook_empty; + // SPDLOG_WARN("base/rel/orderbook mismatch: {} != {}", pair, orderbook.base + "/" + rel); return {}; } if (pair != orderbook.base + "/" + rel) { + // SPDLOG_WARN("base/rel/orderbook mismatch: {} != {}", pair, orderbook.base + "/" + rel); ec = dextop_error::orderbook_ticker_not_found; return {}; } + // SPDLOG_DEBUG("orderbook active: {}/{}", orderbook.base + "/" + orderbook.rel); return orderbook; } - nlohmann::json mm2_service::prepare_batch_orderbook(bool is_a_reset) + + nlohmann::json generate_req(std::string request_name, auto request, bool is_v2=false) { - // SPDLOG_DEBUG("[prepare_batch_orderbook] is_a_reset: {}", is_a_reset); - auto&& [base, rel] = m_synchronized_ticker_pair.get(); - if (rel.empty()) - return nlohmann::json::array(); - nlohmann::json batch = nlohmann::json::array(); + nlohmann::json current_request = mm2::template_request(std::move(request_name), is_v2); + mm2::to_json(current_request, request); + return current_request; + } + - auto generate_req = [&batch](std::string request_name, auto request, bool is_v2=false) + void mm2_service::process_orderbook(bool is_a_reset) + { + prepare_orderbook(is_a_reset); + } + + + void mm2_service::prepare_orderbook(bool is_a_reset) + { + auto callback = [this, is_a_reset](RpcRequest rpc) { - nlohmann::json current_request = mm2::template_request(std::move(request_name), is_v2); - mm2::to_json(current_request, request); - batch.push_back(current_request); + nlohmann::json batch = nlohmann::json::array(); + if (rpc.error) + { + SPDLOG_ERROR("error: bad answer json for prepare_orderbook: {}", rpc.error->error); + } + else + { + if (is_a_reset) + { + nlohmann::json batch = nlohmann::json::array(); + auto&& [base, rel] = m_synchronized_ticker_pair.get(); + batch.push_back(generate_req("max_taker_vol", mm2::max_taker_vol_request{.coin = base})); + batch.push_back(generate_req("max_taker_vol", mm2::max_taker_vol_request{.coin = rel})); + batch.push_back(generate_req("min_trading_vol", t_min_volume_request{.coin = base})); + batch.push_back(generate_req("min_trading_vol", t_min_volume_request{.coin = rel})); + process_orderbook_extras(batch, is_a_reset); + } + m_orderbook = rpc.result.value(); + // SPDLOG_DEBUG("Triggering [process_orderbook_finished]: {}", is_a_reset); + this->dispatcher_.trigger(is_a_reset); + } }; - generate_req("orderbook", t_orderbook_request{.base = base, .rel = rel}, true); - if (is_a_reset) - { - generate_req("max_taker_vol", mm2::max_taker_vol_request{.coin = base}); - generate_req("max_taker_vol", mm2::max_taker_vol_request{.coin = rel}); - generate_req("min_trading_vol", t_min_volume_request{.coin = base}); - generate_req("min_trading_vol", t_min_volume_request{.coin = rel}); - } - // SPDLOG_INFO("batch max: {}", batch.dump(4)); - return batch; + auto&& [base, rel] = m_synchronized_ticker_pair.get(); + // Avoid segwit coins self pairing, e.g. LTC/LTC-segwit + std::string base_ticker = boost::replace_all_copy(base, "-segwit", ""); + std::string rel_ticker = boost::replace_all_copy(rel, "-segwit", ""); + if (rel.empty() || base.empty() || base_ticker == rel_ticker) + SPDLOG_ERROR("Invalid ticker pair while requesting orderbook: {} {}", base, rel); + + mm2::orderbook_rpc rpc{.request={.base = base, .rel = rel}}; + m_mm2_client.process_rpc_async(rpc.request, callback); } - void mm2_service::process_orderbook(bool is_a_reset) + void mm2_service::process_orderbook_extras(nlohmann::json batch, bool is_a_reset) { - auto batch = prepare_batch_orderbook(is_a_reset); if (batch.empty()) + { + SPDLOG_WARN("prepared batch_orderbook is empty, nothing to do"); return; + } auto answer_functor = [this, is_a_reset](web::http::http_response resp) { - auto&& [base, rel] = m_synchronized_ticker_pair.get(); auto answer = mm2::basic_batch_answer(resp); if (answer.is_array()) { @@ -1791,17 +2093,16 @@ namespace atomic_dex return; } - auto orderbook_answer = mm2::rpc_process_answer_batch(answer[0], "orderbook"); - if (is_a_reset) { - if (answer.size() < 5) + if (answer.size() < 4) { SPDLOG_ERROR("Answer array did not contain enough elements"); return; } - auto base_max_taker_vol_answer = mm2::rpc_process_answer_batch(answer[1], "max_taker_vol"); + auto&& [base, rel] = m_synchronized_ticker_pair.get(); + auto base_max_taker_vol_answer = mm2::rpc_process_answer_batch(answer[0], "max_taker_vol"); if (base_max_taker_vol_answer.rpc_result_code == 200) { if (base == base_max_taker_vol_answer.result->coin) @@ -1810,7 +2111,7 @@ namespace atomic_dex } } - auto rel_max_taker_vol_answer = mm2::rpc_process_answer_batch(answer[2], "max_taker_vol"); + auto rel_max_taker_vol_answer = mm2::rpc_process_answer_batch(answer[1], "max_taker_vol"); if (rel_max_taker_vol_answer.rpc_result_code == 200) { if (rel == rel_max_taker_vol_answer.result->coin) @@ -1819,47 +2120,37 @@ namespace atomic_dex } } - auto base_min_taker_vol_answer = mm2::rpc_process_answer_batch(answer[3], "min_trading_vol"); + auto base_min_taker_vol_answer = mm2::rpc_process_answer_batch(answer[2], "min_trading_vol"); if (base_min_taker_vol_answer.rpc_result_code == 200) { m_synchronized_min_taker_vol->first = base_min_taker_vol_answer.result.value(); } - auto rel_min_taker_vol_answer = mm2::rpc_process_answer_batch(answer[4], "min_trading_vol"); + auto rel_min_taker_vol_answer = mm2::rpc_process_answer_batch(answer[3], "min_trading_vol"); if (rel_min_taker_vol_answer.rpc_result_code == 200) { m_synchronized_min_taker_vol->second = rel_min_taker_vol_answer.result.value(); } } - - if (orderbook_answer.rpc_result_code == 200) - { - m_orderbook = orderbook_answer; - this->dispatcher_.trigger(is_a_reset); - } } }; - m_mm2_client.async_rpc_batch_standalone(batch) .then(answer_functor) - .then([this, batch](pplx::task previous_task) { this->handle_exception_pplx_task(previous_task, "process_orderbook", batch); }); + .then([this, batch](pplx::task previous_task) { this->handle_exception_pplx_task(previous_task, "process_orderbook_extras", batch); }); } void mm2_service::fetch_current_orderbook_thread(bool is_a_reset) { - //! m_orderbook_thread_active ? SPDLOG_WARN("Nothing to achieve, sleeping") : SPDLOG_INFO("Fetch current orderbook"); - //! If thread is not active ex: we are not on the trading page anymore, we continue sleeping. if (!m_orderbook_thread_active) { return; } - process_orderbook(is_a_reset); } - void mm2_service::fetch_single_balance(const coin_config& cfg_infos) + void mm2_service::fetch_single_balance(const coin_config_t& cfg_infos) { nlohmann::json batch_array = nlohmann::json::array(); if (is_pin_cfg_enabled()) @@ -1867,11 +2158,13 @@ namespace atomic_dex std::shared_lock lock(m_balance_mutex); ///< shared_lock if (m_balance_informations.find(cfg_infos.ticker) != m_balance_informations.cend()) { + SPDLOG_DEBUG("m_balance_informations not found for {} ", cfg_infos.ticker); return; } } t_balance_request balance_request{.coin = cfg_infos.ticker}; + SPDLOG_DEBUG("Getting balance from mm2 for {} ", cfg_infos.ticker); nlohmann::json j = mm2::template_request("my_balance"); mm2::to_json(j, balance_request); batch_array.push_back(j); @@ -1907,6 +2200,7 @@ namespace atomic_dex else { const auto& enabled_coins = get_enabled_coins(); + SPDLOG_DEBUG("Running [fetch_infos_thread] for {} enabled coins", enabled_coins.size()); for (auto&& coin: enabled_coins) { fetch_single_balance(coin); } batch_balance_and_tx(is_a_refresh, {}, false, true); } @@ -1986,14 +2280,6 @@ namespace atomic_dex }); } - t_float_50 - mm2_service::get_balance(const std::string& ticker) const - { - std::error_code ec; - t_float_50 balance = safe_float(my_balance(ticker, ec)); - return balance; - } - std::pair mm2_service::get_tx(t_mm2_ec& ec) const { @@ -2022,17 +2308,29 @@ namespace atomic_dex return get_tx(ec).first; } + t_float_50 + mm2_service::get_balance(const std::string& ticker) const + { + std::error_code ec; + std::string balance_str = my_balance(ticker, ec); + t_float_50 balance_f = safe_float(balance_str); + // SPDLOG_DEBUG("get_balance for {}: [{}]", ticker, balance_str); + return balance_f; + } + std::string mm2_service::my_balance(const std::string& ticker, t_mm2_ec& ec) const { + // This happens too often std::shared_lock lock(m_balance_mutex); ///! read auto it = m_balance_informations.find(ticker); if (it == m_balance_informations.cend()) { + SPDLOG_DEBUG("my_balance not found for {}", ticker); ec = dextop_error::balance_of_a_non_enabled_coin; return "0"; } - + // SPDLOG_DEBUG("my_balance for {}: [{}]", ticker, it->second.balance); return it->second.balance; } @@ -2042,6 +2340,7 @@ namespace atomic_dex nlohmann::json batch = nlohmann::json::array(); nlohmann::json my_orders_request = mm2::template_request("my_orders"); batch.push_back(my_orders_request); + // SPDLOG_DEBUG("my_orders_request {}", my_orders_request.dump(4)); //! Swaps preparation @@ -2071,12 +2370,14 @@ namespace atomic_dex }; to_json(my_swaps, request); batch.push_back(my_swaps); + // SPDLOG_INFO("my_swaps req: {}", my_swaps.dump(4)); //! Active swaps nlohmann::json active_swaps = mm2::template_request("active_swaps"); t_active_swaps_request active_swaps_request{.statuses = true}; to_json(active_swaps, active_swaps_request); batch.push_back(active_swaps); + // SPDLOG_INFO("active_swaps req: {}", active_swaps.dump(4)); auto answer_functor = [this, limit, filter_infos, after_manual_reset](web::http::http_response resp) { @@ -2183,7 +2484,7 @@ namespace atomic_dex case CoinTypeGadget::BEP20: out = construct_url_functor("BNB", "BNBT", "bnb_tx_history", "bep_tx_history", ticker, address); break; - case CoinTypeGadget::Matic: + case CoinTypeGadget::PLG20: out = construct_url_functor("MATIC", "MATICTEST", "plg_tx_history", "plg_tx_history", ticker, address); break; case CoinTypeGadget::Moonriver: @@ -2302,16 +2603,21 @@ namespace atomic_dex } void - mm2_service::on_refresh_orderbook(const orderbook_refresh& evt) + mm2_service::update_sync_ticker_pair(std::string base, std::string rel) { - SPDLOG_DEBUG("on_refresh_orderbook"); + // SPDLOG_DEBUG("update_sync_ticker_pair: [{} / {}]", base, rel); + this->m_synchronized_ticker_pair = std::make_pair(base, rel); + } - // SPDLOG_INFO("refreshing orderbook pair: [{} / {}]", evt.base, evt.rel); + void + mm2_service::on_refresh_orderbook_model_data(const refresh_orderbook_model_data& evt) + { + // SPDLOG_DEBUG("refreshing orderbook pair: [{} / {}]", evt.base, evt.rel); this->m_synchronized_ticker_pair = std::make_pair(evt.base, evt.rel); if (this->m_mm2_running) { - SPDLOG_DEBUG("process_orderbook(true)"); + // SPDLOG_DEBUG("process_orderbook(true)"); process_orderbook(true); } } @@ -2334,6 +2640,7 @@ namespace atomic_dex bool mm2_service::do_i_have_enough_funds(const std::string& ticker, const t_float_50& amount) const { + SPDLOG_DEBUG("do_i_have_enough_funds for {}: [{}]", ticker, amount.str(8, std::ios_base::fixed)); t_float_50 funds = get_balance(ticker); return funds >= amount; } @@ -2407,6 +2714,7 @@ namespace atomic_dex void mm2_service::decrease_fake_balance(const std::string& ticker, const std::string& amount) { + SPDLOG_DEBUG("decrease_fake_balance for {}: [{}]", ticker, amount); t_float_50 balance = get_balance(ticker); t_float_50 amount_f(amount); t_float_50 result = balance - amount_f; @@ -2506,24 +2814,32 @@ namespace atomic_dex void mm2_service::process_balance_answer(const nlohmann::json& answer) { - t_balance_answer answer_r; - - mm2::from_json(answer, answer_r); - if (is_pin_cfg_enabled()) + try { - std::shared_lock lock(m_balance_mutex); + t_balance_answer answer_r; + + mm2::from_json(answer, answer_r); + if (is_pin_cfg_enabled()) + { + std::shared_lock lock(m_balance_mutex); + + if (m_balance_informations.find(answer_r.coin) != m_balance_informations.end()) + { + return; + } + } + t_float_50 result = t_float_50(answer_r.balance) * m_balance_factor; + answer_r.balance = result.str(8, std::ios_base::fixed); - if (m_balance_informations.find(answer_r.coin) != m_balance_informations.end()) { - return; + std::unique_lock lock(m_balance_mutex); + m_balance_informations[answer_r.coin] = std::move(answer_r); } } - t_float_50 result = t_float_50(answer_r.balance) * m_balance_factor; - answer_r.balance = result.str(8, std::ios_base::fixed); - + catch (const std::exception& error) { - std::unique_lock lock(m_balance_mutex); - m_balance_informations[answer_r.coin] = std::move(answer_r); + SPDLOG_ERROR("exception in process_balance_answer: {}", error.what()); + SPDLOG_DEBUG("exception in process_balance_answer: {}", answer.dump(4)); } } @@ -2675,7 +2991,7 @@ namespace atomic_dex mm2_service::get_electrum_server_from_token(const std::string& ticker) { std::vector servers; - const coin_config cfg = this->get_coin_info(ticker); + const coin_config_t cfg = this->get_coin_info(ticker); if (cfg.coin_type == CoinType::QRC20) { if (cfg.is_testnet.value()) diff --git a/src/core/atomicdex/services/mm2/mm2.service.hpp b/src/core/atomicdex/services/mm2/mm2.service.hpp index 8ce7eaceea..afb68afe92 100644 --- a/src/core/atomicdex/services/mm2/mm2.service.hpp +++ b/src/core/atomicdex/services/mm2/mm2.service.hpp @@ -32,13 +32,15 @@ #include "atomicdex/api/mm2/mm2.error.code.hpp" #include "atomicdex/api/mm2/mm2.hpp" #include "atomicdex/api/mm2/rpc_v1/rpc.min_trading_vol.hpp" -#include "atomicdex/api/mm2/rpc_v2/rpc2.orderbook.hpp" #include "atomicdex/api/mm2/rpc_v1/rpc.max_taker_vol.hpp" #include "atomicdex/api/mm2/rpc_v1/rpc.my_balance.hpp" +#include "atomicdex/api/mm2/rpc_v2/rpc2.orderbook.hpp" #include "atomicdex/api/mm2/rpc_v2/rpc2.enable_bch_with_tokens_rpc.hpp" #include "atomicdex/api/mm2/rpc_v2/rpc2.enable_slp_rpc.hpp" #include "atomicdex/api/mm2/rpc_v2/rpc2.enable_tendermint_with_assets.hpp" #include "atomicdex/api/mm2/rpc_v2/rpc2.enable_tendermint_token.hpp" +#include "atomicdex/api/mm2/rpc_v2/rpc2.enable_erc20.hpp" +#include "atomicdex/api/mm2/rpc_v2/rpc2.enable_eth_with_tokens.hpp" #include "atomicdex/config/raw.mm2.coins.cfg.hpp" #include "atomicdex/constants/dex.constants.hpp" #include "atomicdex/data/dex/orders.and.swaps.data.hpp" @@ -55,8 +57,8 @@ namespace atomic_dex using t_shared_synchronized_value = boost::synchronized_value; using t_ticker = std::string; - using t_coins_registry = std::unordered_map; - using t_coins = std::vector; + using t_coins_registry = std::unordered_map; + using t_coins = std::vector; class ENTT_API mm2_service final : public ag::ecs::pre_update_system { @@ -68,7 +70,7 @@ namespace atomic_dex using t_mm2_time_point = std::chrono::high_resolution_clock::time_point; using t_balance_registry = std::unordered_map; using t_tx_registry = t_shared_synchronized_value>>; - using t_orderbook = boost::synchronized_value; + using t_orderbook = boost::synchronized_value; using t_orders_and_swaps = boost::synchronized_value; using t_synchronized_ticker_pair = boost::synchronized_value>; using t_synchronized_max_taker_vol = boost::synchronized_value; @@ -90,18 +92,18 @@ namespace atomic_dex //! Timers t_mm2_time_point m_orderbook_clock; t_mm2_time_point m_info_clock; - t_mm2_time_point m_coins_clock; + t_mm2_time_point m_activation_clock; //! Atomicity / Threads std::atomic_bool m_mm2_running{false}; - std::atomic_bool m_orderbook_thread_active{false}; - std::atomic_size_t m_nb_update_required{0}; + std::atomic_bool m_orderbook_thread_active{false}; // Only active when in trading view (pro and simple) std::thread m_mm2_init_thread; //! Current wallet name std::string m_current_wallet_name; //! Mutex + mutable std::shared_mutex m_activation_mutex; mutable std::shared_mutex m_balance_mutex; mutable std::shared_mutex m_coin_cfg_mutex; mutable std::shared_mutex m_raw_coin_cfg_mutex; @@ -110,15 +112,17 @@ namespace atomic_dex t_coins_registry& m_coins_informations{entity_registry_.set()}; t_balance_registry m_balance_informations; t_tx_registry m_tx_informations; - t_orderbook m_orderbook{t_orderbook_answer{}}; + t_orderbook m_orderbook{mm2::orderbook_result_rpc{}}; t_orders_and_swaps m_orders_and_swaps{orders_and_swaps{}}; t_mm2_raw_coins_registry m_mm2_raw_coins_cfg{parse_raw_mm2_coins_file()}; + t_coins m_activation_queue; //! Balance factor double m_balance_factor{1.0}; //! Refresh the orderbook registry (internal) - nlohmann::json prepare_batch_orderbook(bool is_a_reset); + void prepare_orderbook(bool is_a_reset); + void process_orderbook_extras(nlohmann::json batch, bool is_a_reset); //! Batch balance / tx std::tuple, std::vector> prepare_batch_balance_and_tx(bool only_tx = false) const; @@ -126,13 +130,13 @@ namespace atomic_dex void process_balance_answer(const nlohmann::json& answer); void process_tx_answer(const nlohmann::json& answer_json, std::string ticker); void process_tx_tokenscan(const std::string& ticker, bool is_a_refresh); - void fetch_single_balance(const coin_config& cfg_infos); + void fetch_single_balance(const coin_config_t& cfg_infos); //! std::pair process_batch_enable_answer(const nlohmann::json& answer); [[nodiscard]] std::pair get_tx(t_mm2_ec& ec) const; std::vector get_electrum_server_from_token(const std::string& ticker); - std::vector retrieve_coins_informations(); + std::vector retrieve_coins_informations(); void handle_exception_pplx_task(pplx::task previous_task, const std::string& from, nlohmann::json batch); @@ -150,7 +154,7 @@ namespace atomic_dex ~mm2_service() final; //! Events - void on_refresh_orderbook(const orderbook_refresh& evt); + void on_refresh_orderbook_model_data(const refresh_orderbook_model_data& evt); void on_gui_enter_trading(const gui_enter_trading& evt); @@ -164,21 +168,24 @@ namespace atomic_dex // Coins enabling functions bool enable_default_coins(); // Enables required coins + coins enabled in the config + void activate_coins(const t_coins& coins); void enable_coins(const std::vector& tickers); void enable_coins(const t_coins& coins); void enable_coin(const std::string& ticker); - void enable_coin(const coin_config& coin_config); + void enable_coin(const coin_config_t& coin_config); private: void update_coin_active(const std::vector& tickers, bool status); - void enable_erc_family_coin(const coin_config& coin_config); + void enable_erc_family_coin(const coin_config_t& coin_config); void enable_erc_family_coins(const t_coins& coins); - void enable_utxo_qrc20_coin(coin_config coin_config); + void enable_utxo_qrc20_coin(coin_config_t coin_config); void enable_utxo_qrc20_coins(const t_coins& coins); - void enable_slp_coin(coin_config coin_config); + void enable_slp_coin(coin_config_t coin_config); void enable_slp_coins(const t_coins& coins); - void enable_slp_testnet_coin(coin_config coin_config); + void enable_slp_testnet_coin(coin_config_t coin_config); void enable_slp_testnet_coins(const t_coins& coins); - void enable_tendermint_coin(coin_config coin_config, std::string parent_ticker); + void enable_erc20_coin(coin_config_t coin_config, std::string parent_ticker); + void enable_erc20_coins(const t_coins& coins, const std::string parent_ticker); + void enable_tendermint_coin(coin_config_t coin_config, std::string parent_ticker); void enable_tendermint_coins(const t_coins& coins, const std::string parent_ticker); void enable_zhtlc(const t_coins& coins); @@ -187,11 +194,14 @@ namespace atomic_dex void process_balance_answer(const mm2::enable_slp_rpc& rpc); // Called after enabling an SLP coin. void process_balance_answer(const mm2::enable_tendermint_with_assets_rpc& rpc); void process_balance_answer(const mm2::enable_tendermint_token_rpc& rpc); + void process_balance_answer(const mm2::enable_eth_with_tokens_rpc& rpc); + void process_balance_answer(const mm2::enable_erc20_rpc& rpc); public: //! Add a new coin in the coin_info cfg add_new_coin(normal_cfg, mm2_cfg) void add_new_coin(const nlohmann::json& coin_cfg_json, const nlohmann::json& raw_coin_cfg_json); void remove_custom_coin(const std::string& ticker); + void update_sync_ticker_pair(std::string base, std::string rel); [[nodiscard]] bool is_this_ticker_present_in_raw_cfg(const std::string& ticker) const; [[nodiscard]] bool is_this_ticker_present_in_normal_cfg(const std::string& ticker) const; [[nodiscard]] bool is_zhtlc_coin_ready(const std::string coin) const; @@ -237,7 +247,7 @@ namespace atomic_dex [[nodiscard]] t_coins get_active_coins() const; //! Get Specific info about one coin - [[nodiscard]] coin_config get_coin_info(const std::string& ticker) const; + [[nodiscard]] coin_config_t get_coin_info(const std::string& ticker) const; // Tells if the given coin is enabled. [[nodiscard]] bool is_coin_enabled(const std::string& ticker) const; @@ -246,7 +256,7 @@ namespace atomic_dex [[nodiscard]] bool has_coin(const std::string& ticker) const; //! Get Current orderbook - [[nodiscard]] t_orderbook_answer get_orderbook(t_mm2_ec& ec) const; + [[nodiscard]] mm2::orderbook_result_rpc get_orderbook(t_mm2_ec& ec) const; //! Get Swaps [[nodiscard]] orders_and_swaps get_orders_and_swaps() const; diff --git a/src/core/atomicdex/services/price/coingecko/coingecko.wallet.charts.cpp b/src/core/atomicdex/services/price/coingecko/coingecko.wallet.charts.cpp index ff69938303..9fa3781b99 100644 --- a/src/core/atomicdex/services/price/coingecko/coingecko.wallet.charts.cpp +++ b/src/core/atomicdex/services/price/coingecko/coingecko.wallet.charts.cpp @@ -150,7 +150,7 @@ namespace atomic_dex } void - coingecko_wallet_charts_service::fetch_data_of_single_coin(const coin_config& cfg) + coingecko_wallet_charts_service::fetch_data_of_single_coin(const coin_config_t& cfg) { using namespace std::chrono_literals; SPDLOG_INFO("fetch charts data of {} {}", cfg.ticker, cfg.coingecko_id); diff --git a/src/core/atomicdex/services/price/coingecko/coingecko.wallet.charts.hpp b/src/core/atomicdex/services/price/coingecko/coingecko.wallet.charts.hpp index ad4a929b2d..390e246240 100644 --- a/src/core/atomicdex/services/price/coingecko/coingecko.wallet.charts.hpp +++ b/src/core/atomicdex/services/price/coingecko/coingecko.wallet.charts.hpp @@ -39,7 +39,7 @@ namespace atomic_dex boost::synchronized_value m_wallet_performance; //! Private member functions - void fetch_data_of_single_coin(const coin_config& cfg); + void fetch_data_of_single_coin(const coin_config_t& cfg); void fetch_all_charts_data(); void generate_fiat_chart(); diff --git a/src/core/atomicdex/services/price/coinpaprika/coinpaprika.provider.cpp b/src/core/atomicdex/services/price/coinpaprika/coinpaprika.provider.cpp index f16c4a179a..9719887871 100644 --- a/src/core/atomicdex/services/price/coinpaprika/coinpaprika.provider.cpp +++ b/src/core/atomicdex/services/price/coinpaprika/coinpaprika.provider.cpp @@ -130,7 +130,7 @@ namespace atomic_dex { template void - coinpaprika_provider::process_provider(const coin_config& current_coin, Args... args) + coinpaprika_provider::process_provider(const coin_config_t& current_coin, Args... args) { const price_converter_request request{.base_currency_id = current_coin.coinpaprika_id, .quote_currency_id = "usd-us-dollars"}; generic_rpc_paprika_process( @@ -140,7 +140,7 @@ namespace atomic_dex template void - coinpaprika_provider::process_ticker_infos(const coin_config& current_coin, Args... args) + coinpaprika_provider::process_ticker_infos(const coin_config_t& current_coin, Args... args) { const ticker_infos_request request{.ticker_currency_id = current_coin.coinpaprika_id, .ticker_quotes = {"USD", "EUR", "BTC"}}; generic_rpc_paprika_process( @@ -150,7 +150,7 @@ namespace atomic_dex template void - coinpaprika_provider::process_ticker_historical(const coin_config& current_coin, Args... args) + coinpaprika_provider::process_ticker_historical(const coin_config_t& current_coin, Args... args) { const ticker_historical_request request{.ticker_currency_id = current_coin.coinpaprika_id, .interval = "2h"}; generic_rpc_paprika_process( diff --git a/src/core/atomicdex/services/price/coinpaprika/coinpaprika.provider.hpp b/src/core/atomicdex/services/price/coinpaprika/coinpaprika.provider.hpp index ab8ac6d43b..01352719e5 100644 --- a/src/core/atomicdex/services/price/coinpaprika/coinpaprika.provider.hpp +++ b/src/core/atomicdex/services/price/coinpaprika/coinpaprika.provider.hpp @@ -70,11 +70,11 @@ namespace atomic_dex //! Private RPC Call template - void process_provider(const coin_config& current_coin, Args... args); + void process_provider(const coin_config_t& current_coin, Args... args); template - void process_ticker_infos(const coin_config& current_coin, Args... args); + void process_ticker_infos(const coin_config_t& current_coin, Args... args); template - void process_ticker_historical(const coin_config& current_coin, Args... args); + void process_ticker_historical(const coin_config_t& current_coin, Args... args); public: //! Deleted operation diff --git a/src/core/atomicdex/services/price/global.provider.cpp b/src/core/atomicdex/services/price/global.provider.cpp index 96305567b2..5156033aa3 100644 --- a/src/core/atomicdex/services/price/global.provider.cpp +++ b/src/core/atomicdex/services/price/global.provider.cpp @@ -334,6 +334,9 @@ namespace atomic_dex std::string global_price_service::get_price_in_fiat(const std::string& fiat, const std::string& ticker, std::error_code& ec, bool skip_precision) const { + // Runs often to update fiat values for all enabled coins. + // fetch ticker infos loop and on_update_portfolio_values_event triggers this. + // SPDLOG_INFO("get_price_in_fiat [{}] [{}]", fiat, ticker); try { auto& mm2_instance = m_system_manager.get_system(); @@ -352,7 +355,7 @@ namespace atomic_dex } std::error_code t_ec; - const auto amount = mm2_instance.my_balance(ticker, t_ec); + const auto amount = mm2_instance.my_balance(ticker, t_ec); // from registry if (t_ec) { diff --git a/src/core/atomicdex/services/price/komodo_prices/komodo.prices.provider.cpp b/src/core/atomicdex/services/price/komodo_prices/komodo.prices.provider.cpp index 00945a4400..bc3e5d9203 100644 --- a/src/core/atomicdex/services/price/komodo_prices/komodo.prices.provider.cpp +++ b/src/core/atomicdex/services/price/komodo_prices/komodo.prices.provider.cpp @@ -11,7 +11,7 @@ namespace atomic_dex { komodo_prices_provider::komodo_prices_provider(entt::registry& registry) : system(registry) { - SPDLOG_INFO("komodo_prices_provider created"); + // SPDLOG_INFO("komodo_prices_provider created"); m_clock = std::chrono::high_resolution_clock::now(); process_update(); } @@ -32,8 +32,7 @@ namespace atomic_dex void komodo_prices_provider::process_update(bool fallback) { - SPDLOG_INFO("komodo price service tick loop"); - + // SPDLOG_INFO("komodo price service tick loop"); auto answer_functor = [this, fallback](web::http::http_response resp) { std::string body = TO_STD_STR(resp.extract_string(true).get()); @@ -45,7 +44,7 @@ namespace atomic_dex { std::unique_lock lock(m_market_mutex); m_market_registry = std::move(answer); - SPDLOG_INFO("komodo price registry size: {}", m_market_registry.size()); + // SPDLOG_INFO("komodo price registry size: {}", m_market_registry.size()); } } else diff --git a/src/core/atomicdex/services/price/orderbook.scanner.service.cpp b/src/core/atomicdex/services/price/orderbook.scanner.service.cpp index fec2815837..76c08a5209 100644 --- a/src/core/atomicdex/services/price/orderbook.scanner.service.cpp +++ b/src/core/atomicdex/services/price/orderbook.scanner.service.cpp @@ -14,8 +14,9 @@ * * ******************************************************************************/ +#include //! Project Headers -#include "atomicdex/api/mm2/rpc_v2/rpc2.best.orders.hpp" +#include "atomicdex/api/mm2/rpc_v2/rpc2.bestorders.hpp" #include "atomicdex/pages/qt.trading.page.hpp" #include "atomicdex/services/mm2/mm2.service.hpp" #include "atomicdex/services/price/orderbook.scanner.service.hpp" @@ -38,9 +39,9 @@ namespace atomic_dex void orderbook_scanner_service::process_best_orders() { - if (m_rpc_busy) + if (m_bestorders_busy) { - // SPDLOG_INFO("process_best_orders is busy - skipping"); + SPDLOG_INFO("process_best_orders is busy - skipping"); return; } @@ -52,54 +53,39 @@ namespace atomic_dex { // SPDLOG_INFO("process_best_orders"); using namespace std::string_literals; - const auto& trading_pg = m_system_manager.get_system(); - auto volume = trading_pg.get_volume().toStdString(); - auto action = trading_pg.get_market_mode() == MarketMode::Buy ? "buy"s : "sell"s; - auto coin = trading_pg.get_market_pairs_mdl()->get_left_selected_coin().toStdString(); - t_best_orders_request req{.coin = std::move(coin), .volume = std::move(volume), .action = std::move(action)}; + const auto& trading_pg = m_system_manager.get_system(); + auto volume = trading_pg.get_volume().toStdString(); + auto action = trading_pg.get_market_mode() == MarketMode::Buy ? "buy"s : "sell"s; + auto coin = trading_pg.get_market_pairs_mdl()->get_left_selected_coin().toStdString(); - //! Prepare request - nlohmann::json batch = nlohmann::json::array(); - nlohmann::json best_orders_req_json = mm2::template_request("best_orders", true); - to_json(best_orders_req_json, req); - batch.push_back(best_orders_req_json); - - // best_orders_req_json["userpass"] = "*****"; - // SPDLOG_INFO("best_orders request: {}", best_orders_req_json.dump(4)); - - this->m_rpc_busy = true; - emit trading_pg.get_orderbook_wrapper()->bestOrdersBusyChanged(); - //! Treat answer - auto answer_functor = [this, &trading_pg](web::http::http_response resp) { - std::string body = TO_STD_STR(resp.extract_string(true).get()); - if (resp.status_code() == 200) + auto callback = [this, &trading_pg](RpcRequest rpc) + { + nlohmann::json batch = nlohmann::json::array(); + if (rpc.error) { - auto answers = nlohmann::json::parse(body); - auto best_order_answer = mm2::rpc_process_answer_batch(answers[0], "best_orders"); - if (best_order_answer.result.has_value()) + SPDLOG_ERROR("error: bad answer json for process_best_orders: {}", rpc.error->error); + this->m_bestorders_busy = false; + SPDLOG_ERROR("Triggering [process_orderbook_finished]: true"); + this->dispatcher_.trigger(true); + } + else + { + if (rpc.result.has_value()) { - this->m_best_orders_infos = best_order_answer.result.value(); + this->m_best_orders_infos = rpc.result.value(); } + this->m_bestorders_busy = false; + SPDLOG_ERROR("Triggering [process_orderbook_finished]: false"); + this->dispatcher_.trigger(false); + emit trading_pg.get_orderbook_wrapper()->bestOrdersBusyChanged(); } - this->m_rpc_busy = false; - this->dispatcher_.trigger(false); - emit trading_pg.get_orderbook_wrapper()->bestOrdersBusyChanged(); }; - mm2_system.get_mm2_client().async_rpc_batch_standalone(batch) - .then(answer_functor) - .then([this](pplx::task previous_task) { - try - { - previous_task.wait(); - } - catch (const std::exception& e) - { - SPDLOG_ERROR("pplx task error in [process_best_orders]: {}", e.what()); - this->m_rpc_busy = false; - this->dispatcher_.trigger(true); - } - }); + + this->m_bestorders_busy = true; + emit trading_pg.get_orderbook_wrapper()->bestOrdersBusyChanged(); + mm2::bestorders_rpc rpc{.request={.coin = std::move(coin), .volume = std::move(volume), .action = std::move(action)}}; + mm2_system.get_mm2_client().process_rpc_async(rpc.request, callback); } else { @@ -126,6 +112,7 @@ namespace atomic_dex const auto s = std::chrono::duration_cast(now - m_update_clock); if (s >= 30s) { + SPDLOG_DEBUG("<<<<<<<<<<< orderbook_scanner_service update loop after 30 seconds >>>>>>>>>>>>>"); process_best_orders(); m_update_clock = std::chrono::high_resolution_clock::now(); } @@ -134,11 +121,11 @@ namespace atomic_dex bool orderbook_scanner_service::is_best_orders_busy() const { - return m_rpc_busy.load(); + return m_bestorders_busy.load(); } t_orders_contents - orderbook_scanner_service::get_data() const + orderbook_scanner_service::get_bestorders_data() const { return m_best_orders_infos.get().result; } diff --git a/src/core/atomicdex/services/price/orderbook.scanner.service.hpp b/src/core/atomicdex/services/price/orderbook.scanner.service.hpp index d83136c9a6..9a7896c68f 100644 --- a/src/core/atomicdex/services/price/orderbook.scanner.service.hpp +++ b/src/core/atomicdex/services/price/orderbook.scanner.service.hpp @@ -22,7 +22,8 @@ #include //! Project Headers -#include "atomicdex/api/mm2/rpc_v2/rpc2.best.orders.hpp" +#include "atomicdex/api/mm2/mm2.client.hpp" +#include "atomicdex/api/mm2/rpc_v2/rpc2.bestorders.hpp" //! Namespace declaration namespace atomic_dex @@ -32,13 +33,13 @@ namespace atomic_dex { //! Private typedefs using t_update_time_point = std::chrono::high_resolution_clock::time_point; - using t_best_orders_synchronized = boost::synchronized_value; + using t_best_orders_synchronized = boost::synchronized_value; //! Private member fields ag::ecs::system_manager& m_system_manager; t_best_orders_synchronized m_best_orders_infos; t_update_time_point m_update_clock; - std::atomic_bool m_rpc_busy{false}; + std::atomic_bool m_bestorders_busy{false}; public: //! Constructor @@ -55,7 +56,7 @@ namespace atomic_dex [[nodiscard]] bool is_best_orders_busy() const ; - [[nodiscard]] t_orders_contents get_data() const ; + [[nodiscard]] t_orders_contents get_bestorders_data() const ; }; } // namespace atomic_dex diff --git a/src/core/atomicdex/utilities/global.utilities.cpp b/src/core/atomicdex/utilities/global.utilities.cpp index f11d804164..91d9550f6b 100644 --- a/src/core/atomicdex/utilities/global.utilities.cpp +++ b/src/core/atomicdex/utilities/global.utilities.cpp @@ -252,17 +252,18 @@ namespace atomic_dex::utils } std::string - retrieve_main_ticker(const std::string& ticker, const bool segwit_only) + retrieve_main_ticker(const std::string& ticker, bool segwit_only, bool exclude_segwit) { - auto pos = ticker.find("-"); - if (segwit_only) + bool is_segwit = ticker.find("-segwit") != std::string::npos; + if (exclude_segwit && is_segwit) { - if (ticker.find("-segwit") != std::string::npos) - { - return ticker.substr(0, pos); - } return ticker; } + auto pos = ticker.find("-"); + if (segwit_only && is_segwit) + { + return ticker.substr(0, pos); + } if (pos != std::string::npos) { return ticker.substr(0, pos); @@ -271,7 +272,7 @@ namespace atomic_dex::utils } std::vector - coin_cfg_to_ticker_cfg(std::vector in) + coin_cfg_to_ticker_cfg(std::vector in) { std::vector out; out.reserve(in.size()); @@ -306,4 +307,12 @@ namespace atomic_dex::utils } return valid_json_data; } + + void json_keys(nlohmann::json j) + { + for (auto& [key, val] : j.items()) + { + SPDLOG_DEBUG("key: {}, value: {}", key, val); + } + } } // namespace atomic_dex::utils diff --git a/src/core/atomicdex/utilities/global.utilities.hpp b/src/core/atomicdex/utilities/global.utilities.hpp index cd4b521f80..14f9753c66 100644 --- a/src/core/atomicdex/utilities/global.utilities.hpp +++ b/src/core/atomicdex/utilities/global.utilities.hpp @@ -94,10 +94,11 @@ namespace atomic_dex::utils ENTT_API std::filesystem::path get_themes_path(); ENTT_API std::filesystem::path get_logo_path(); - std::string retrieve_main_ticker(const std::string& ticker, const bool segwit_only = false); + std::string retrieve_main_ticker(const std::string& ticker, bool segwit_only=false, bool exclude_segwit=false); void to_eth_checksum(std::string& address); + void json_keys(nlohmann::json j); - std::vector coin_cfg_to_ticker_cfg(std::vector in); + std::vector coin_cfg_to_ticker_cfg(std::vector in); } // namespace atomic_dex::utils diff --git a/src/core/atomicdex/utilities/qt.utilities.cpp b/src/core/atomicdex/utilities/qt.utilities.cpp index 05eaff0f3c..c9db01b27c 100644 --- a/src/core/atomicdex/utilities/qt.utilities.cpp +++ b/src/core/atomicdex/utilities/qt.utilities.cpp @@ -50,7 +50,7 @@ namespace atomic_dex QString retrieve_change_24h( - const atomic_dex::komodo_prices_provider& provider, const atomic_dex::coin_config& coin, const atomic_dex::cfg& config, + const atomic_dex::komodo_prices_provider& provider, const atomic_dex::coin_config_t& coin, const atomic_dex::cfg& config, [[maybe_unused]] const ag::ecs::system_manager& system_manager) { QString change_24h = "0"; @@ -165,8 +165,8 @@ namespace atomic_dex } QString - qt_utilities::retrieve_main_ticker(const QString& ticker) const + qt_utilities::retrieve_main_ticker(const QString& ticker, bool segwit_only, bool exclude_segwit) const { - return QString::fromStdString(atomic_dex::utils::retrieve_main_ticker(ticker.toStdString())); + return QString::fromStdString(atomic_dex::utils::retrieve_main_ticker(ticker.toStdString(), segwit_only, exclude_segwit)); } } // namespace atomic_dex diff --git a/src/core/atomicdex/utilities/qt.utilities.hpp b/src/core/atomicdex/utilities/qt.utilities.hpp index 226967ad94..903b5fbc24 100644 --- a/src/core/atomicdex/utilities/qt.utilities.hpp +++ b/src/core/atomicdex/utilities/qt.utilities.hpp @@ -49,7 +49,7 @@ namespace atomic_dex QJsonArray nlohmann_json_array_to_qt_json_array(const nlohmann::json& j); QJsonObject nlohmann_json_object_to_qt_json_object(const nlohmann::json& j); QString retrieve_change_24h( - const atomic_dex::komodo_prices_provider& provider, const atomic_dex::coin_config& coin, const atomic_dex::cfg& config, + const atomic_dex::komodo_prices_provider& provider, const atomic_dex::coin_config_t& coin, const atomic_dex::cfg& config, const ag::ecs::system_manager& system_manager); [[nodiscard]] QString inline sha256_qstring_from_qt_byte_array(const QByteArray& byte_array) @@ -92,6 +92,6 @@ namespace atomic_dex * @return a ticker * @example -> retrieve_main_ticker("BUSD") -> BUSD retrieve_main_ticker("BUSD-ERC20") -> BUSD */ - Q_INVOKABLE QString retrieve_main_ticker(const QString& ticker) const; + Q_INVOKABLE QString retrieve_main_ticker(const QString& ticker, bool segwit_only = false, bool exclude_segwit = false) const; }; } // namespace atomic_dex diff --git a/src/tests/api/mm2/enable_bch_with_tokens_rpc_tests.cpp b/src/tests/api/mm2/enable_bch_with_tokens_rpc_tests.cpp index 625c9e65bf..c8d6c738b0 100644 --- a/src/tests/api/mm2/enable_bch_with_tokens_rpc_tests.cpp +++ b/src/tests/api/mm2/enable_bch_with_tokens_rpc_tests.cpp @@ -24,8 +24,8 @@ TEST_CASE("enable_bch_with_tokens_request_rpc serialization") .slp_tokens_requests = { { .ticker = "ASLP", .required_confirmations = 4 } }, .required_confirmations = 5, .requires_notarization = false, - .address_format = enable_bch_with_tokens_request_rpc::address_format_t{ .format = "cashaddress", .network = "bitcoincash" }, - .utxo_merge_params = enable_bch_with_tokens_request_rpc::utxo_merge_params_t{ .merge_at = 50, .check_every = 10, .max_merge_at_once = 25 } + .address_format = address_format_t{ .format = "cashaddress", .network = "bitcoincash" }, + .utxo_merge_params = utxo_merge_params_t{ .merge_at = 50, .check_every = 10, .max_merge_at_once = 25 } }; nlohmann::to_json(result, data); diff --git a/src/tests/api/mm2/mm2.api.format.address.tests.cpp b/src/tests/api/mm2/mm2.api.address_format.tests.cpp similarity index 89% rename from src/tests/api/mm2/mm2.api.format.address.tests.cpp rename to src/tests/api/mm2/mm2.api.address_format.tests.cpp index 5ef24bbd99..7b43419bb9 100644 --- a/src/tests/api/mm2/mm2.api.format.address.tests.cpp +++ b/src/tests/api/mm2/mm2.api.address_format.tests.cpp @@ -18,7 +18,7 @@ #include "doctest/doctest.h" #include -#include "atomicdex/api/mm2/format.address.hpp" +#include "atomicdex/api/mm2/address_format.hpp" TEST_CASE("mm2::address_format serialisation") { @@ -28,9 +28,9 @@ TEST_CASE("mm2::address_format serialisation") "network":"bchtest" } )"_json; - atomic_dex::mm2::format_address request{.format = "cashaddress", .network = "bchtest"}; + atomic_dex::mm2::address_format_t req{.format = "cashaddress", .network = "bchtest"}; nlohmann::json j; - atomic_dex::mm2::to_json(j, request); + to_json(j, req); CHECK_EQ(j, expected_json); } \ No newline at end of file diff --git a/src/tests/api/mm2/mm2.api.balance.infos.tests.cpp b/src/tests/api/mm2/mm2.api.balance_infos.tests.cpp similarity index 97% rename from src/tests/api/mm2/mm2.api.balance.infos.tests.cpp rename to src/tests/api/mm2/mm2.api.balance_infos.tests.cpp index c96f7efc18..9b80fab15a 100644 --- a/src/tests/api/mm2/mm2.api.balance.infos.tests.cpp +++ b/src/tests/api/mm2/mm2.api.balance_infos.tests.cpp @@ -18,7 +18,7 @@ #include "doctest/doctest.h" #include -#include "atomicdex/api/mm2/balance.infos.hpp" +#include "atomicdex/api/mm2/balance_infos.hpp" TEST_CASE("mm2::balance_infos deserialization") { diff --git a/src/tests/api/mm2/mm2.api.utxo.merge.params.tests.cpp b/src/tests/api/mm2/mm2.api.utxo_merge_params.tests.cpp similarity index 90% rename from src/tests/api/mm2/mm2.api.utxo.merge.params.tests.cpp rename to src/tests/api/mm2/mm2.api.utxo_merge_params.tests.cpp index 54b985c908..de8d38ccda 100644 --- a/src/tests/api/mm2/mm2.api.utxo.merge.params.tests.cpp +++ b/src/tests/api/mm2/mm2.api.utxo_merge_params.tests.cpp @@ -18,7 +18,7 @@ #include "doctest/doctest.h" #include -#include "atomicdex/api/mm2/utxo.merge.params.hpp" +#include "atomicdex/api/mm2/utxo_merge_params.hpp" TEST_CASE("mm2::utxo_merge_params serialisation") { @@ -29,7 +29,7 @@ TEST_CASE("mm2::utxo_merge_params serialisation") "max_merge_at_once":25 } )"_json; - atomic_dex::mm2::utxo_merge_params request{.merge_at = 50, .check_every = 10, .max_merge_at_once = 25}; + atomic_dex::mm2::utxo_merge_params_t request{.merge_at = 50, .check_every = 10, .max_merge_at_once = 25}; nlohmann::json j; atomic_dex::mm2::to_json(j, request); CHECK_EQ(j, expected_json); diff --git a/src/tests/atomic.dex.provider.cex.prices.tests.cpp b/src/tests/atomic.dex.provider.cex.prices.tests.cpp index abfa32587f..3f2772cd94 100644 --- a/src/tests/atomic.dex.provider.cex.prices.tests.cpp +++ b/src/tests/atomic.dex.provider.cex.prices.tests.cpp @@ -50,7 +50,7 @@ TEST_CASE("atomic dex cex prices provider constructor") AND_WHEN("i set the current orderbook pair to a valid supported pair (kmd-btc)") { - registry.ctx().trigger("kmd", "btc"); + registry.ctx().trigger("kmd", "btc"); using namespace std::chrono_literals; cex_system.consume_pending_tasks(); diff --git a/src/tests/config/coins.cfg.tests.cpp b/src/tests/config/coins.cfg.tests.cpp index a968fa0af7..14f47460d0 100644 --- a/src/tests/config/coins.cfg.tests.cpp +++ b/src/tests/config/coins.cfg.tests.cpp @@ -35,8 +35,8 @@ TEST_CASE("generate all coinpaprika possibilities") std::ifstream ifs(cfg_path.string()); nlohmann::json j; ifs >> j; - std::unordered_map cfg; - auto out = j.get>(); + std::unordered_map cfg; + auto out = j.get>(); CHECK_GT(out.size(), 0); std::ofstream ofs("/tmp/out.txt", std::ios::trunc); for (auto&& [key, current_cfg]: out)