diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 3a058c8b6c..a6c06597fa 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,6 @@ --- name: Bug report -about: Create a report to help us improve +about: Something looks wierd or doesn't work as expected? Let us know the details so we can fix it! title: "[BUG]: " labels: bug assignees: '' @@ -8,25 +8,28 @@ assignees: '' --- **Describe the bug** -A clear and concise description of what the bug is. +Please give us a clear and concise description of what the bug is, including screenshots or video if applicable. + **To Reproduce** Steps to reproduce the behavior: 1. Go to '...' -2. Click on '....' -3. Scroll down to '....' +2. Scroll down to '....' +3. Click on '....' 4. See error + **Expected behavior** -A clear and concise description of what you expected to happen. +Please describe what you expected to happen. + -**Screenshots** -If applicable, add screenshots to help explain your problem. +**Operating Environment(s):** + - OS: [e.g. Windows/OSX/Linux. If Linux, include distro. ] + - OS version: [e.g. 7/10/11, 10.13/10.15, 18.04/20.04 ] + - AtomicDEX Version: [e.g. 0.5.7] + - Build branch: [e.g. master/dev] -**Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] **Additional context** -Add any other context about the problem here. + - Add any related context about the problem here (e.g. screen resolution, mining activity on address) + - Attach [log files](https://forum.komodoplatform.com/t/accessing-atomicdex-desktop-log-files/540) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 89af96c70e..11f973fa6c 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,20 +1,24 @@ --- name: Feature request -about: Suggest an idea for this project -title: "[FEATURE REQUEST]: " +about: Something missing? Got a cool idea? Let us know! +title: "[FR]: " labels: '' assignees: '' --- **Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] +What problem does your suggestion solve? E.g. It would be more convenient if [...] + + +**Describe your solution** +A clear and concise description of how your solution could be implemented. -**Describe the solution you'd like** -A clear and concise description of what you want to happen. **Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. +Have you considered any alternative approaches to solving to the problem? + **Additional context** -Add any other context or screenshots about the feature request here. +For visual features, screenshots are great to include. +If your request is similar to a feature frm a different app, please include a link. diff --git a/.github/ISSUE_TEMPLATE/support.md b/.github/ISSUE_TEMPLATE/support.md new file mode 100644 index 0000000000..c3b49f6c2a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/support.md @@ -0,0 +1,12 @@ +--- +name: Support query +about: Did something go wrong? Need some help? Please follow the links below for assistance +title: "[SQ]: " +labels: 'support' +assignees: '' + +--- + +[Komodo Platform Discord Support Channel](https://discord.gg/RRZ8hzc) +[Komodo Platform Forum](https://forum.komodoplatform.com/t/atomicdex-desktop-collection/541) +[Develper Documentation](https://developers.komodoplatform.com/) \ No newline at end of file diff --git a/.github/workflows/firodex-desktop-ci.yml b/.github/workflows/firodex-desktop-ci.yml index 71908c8064..93238ce19e 100644 --- a/.github/workflows/firodex-desktop-ci.yml +++ b/.github/workflows/firodex-desktop-ci.yml @@ -11,6 +11,9 @@ on: - cron: '0 0 * * 1' env: + DEX_API: "mm2" + DEX_RPCPORT: 7783 + DEX_RPC: "http://127.0.0.1:7783" DEX_PROJECT_NAME: "firodex" DEX_DISPLAY_NAME: "Firo Dex" DEX_COMPANY: "Firo" @@ -26,112 +29,133 @@ jobs: fail-fast: false matrix: name: [ - ubuntu-qt-5-15-2, - osx-qt-5-15-2, - windows-10-qt-5-15-2 + ubuntu-release, + ubuntu-debug, + osx-release, + osx-debug, + windows-release, + windows-debug ] include: - - name: ubuntu-qt-5-15-2 - os: ubuntu-18.04 + - name: ubuntu-release + os: ubuntu-20.04 qt: '5.15.2' - type: 'release' + type: 'Release' + host: 'linux' - - name: osx-qt-5-15-2 - os: macos-latest + - name: ubuntu-debug + os: ubuntu-20.04 qt: '5.15.2' - type: 'release' + type: 'Debug' + host: 'linux' - - name: windows-10-qt-5-15-2 + - name: osx-release + os: macos-11 + qt: '5.15.2' + type: 'Release' + host: 'mac' + + - name: osx-debug + os: macos-11 + qt: '5.15.2' + type: 'Debug' + host: 'mac' + + - name: windows-release os: windows-latest qt: '5.15.2' - type: 'release' + type: 'Release' + host: 'windows' - #- name: osx-qt-5-15-2-dbg - # os: macos-latest - # qt: '5.15.2' - # type: 'debug' + - name: windows-debug + os: windows-latest + qt: '5.15.2' + type: 'Debug' + host: 'windows' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} submodules: 'true' - name: Setup Python - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 with: python-version: '3.9' - - name: Install QT (Linux) - if: runner.os == 'Linux' - uses: KomodoPlatform/install-qt-action@v2.14.0 + - name: Install MSVC + if: runner.os == 'Windows' + uses: ilammy/msvc-dev-cmd@v1.12.0 + + - name: Build libwally (Windows) + if: runner.os == 'Windows' + run: | + cd '${{ github.workspace }}' + git clone -b v0.8.5 --recurse-submodules https://github.com/KomodoPlatform/libwally-core.git + cd '${{ github.workspace }}\libwally-core' + git submodule init + git submodule sync --recursive + git submodule update --init --recursive + $env:LIBWALLY_DIR='${{ github.workspace }}\libwally-core' + "$env:LIBWALLY_DIR\tools\msvc\gen_ecmult_static_context.bat" + copy src\ccan\ccan\str\hex\hex.c src\ccan\ccan\str\hex\hex_.c + copy src\ccan\ccan\base64\base64.c src\ccan\ccan\base64\base64_.c + cl /utf-8 /DUSE_ECMULT_STATIC_PRECOMPUTATION /DECMULT_WINDOW_SIZE=15 /DWALLY_CORE_BUILD /DHAVE_CONFIG_H /DSECP256K1_BUILD /I$env:LIBWALLY_DIR\src\wrap_js\windows_config /I$env:LIBWALLY_DIR /I$env:LIBWALLY_DIR\src /I$env:LIBWALLY_DIR\include /I$env:LIBWALLY_DIR\src\ccan /I$env:LIBWALLY_DIR\src\ccan\base64 /I$env:LIBWALLY_DIR\src\secp256k1 /Zi /LD src/aes.c src/anti_exfil.c src/base58.c src/base64.c src/bech32.c src/bip32.c src/bip38.c src/bip39.c src/blech32.c src/ecdh.c src/elements.c src/hex.c src/hmac.c src/internal.c src/mnemonic.c src/pbkdf2.c src/pullpush.c src/psbt.c src/script.c src/scrypt.c src/sign.c src/symmetric.c src/transaction.c src/wif.c src/wordlist.c src/ccan/ccan/crypto/ripemd160/ripemd160.c src/ccan/ccan/crypto/sha256/sha256.c src/ccan/ccan/crypto/sha512/sha512.c src/ccan/ccan/base64/base64_.c src\ccan\ccan\str\hex\hex_.c src/secp256k1/src/secp256k1.c src/secp256k1/src/precomputed_ecmult_gen.c src/secp256k1/src/precomputed_ecmult.c /Fewally.dll + Copy-Item "${{ github.workspace }}\libwally-core\wally.dll" -Destination "${{ github.workspace }}\wally\wally.dll" -force + + + - name: Install QT (macOS) + if: runner.os == 'macOS' + uses: jurplel/install-qt-action@v3.0.0 with: version: ${{ matrix.qt }} - setup-python: 'false' - host: 'linux' - target: 'desktop' + host: ${{ matrix.host }} dir: '${{ github.workspace }}' - modules: 'qtcharts qtwidgets debug_info qtwebengine qtwebview' - aqtversion: '==0.8' - py7zrversion: '==0.6' + target: 'desktop' + modules: 'qtcharts debug_info qtwebengine' + tools: 'tools_ifw' + setup-python: 'false' + cache: true - - name: Install QT (MacOS) - if: runner.os == 'macOS' - uses: KomodoPlatform/install-qt-action@v2.14.0 + - name: Install QT (Linux) + if: runner.os == 'Linux' + uses: jurplel/install-qt-action@v3.0.0 with: version: ${{ matrix.qt }} - setup-python: 'false' - host: 'mac' - target: 'desktop' + host: ${{ matrix.host }} dir: '${{ github.workspace }}' - modules: 'qtcharts qtwidgets debug_info qtwebview qtwebengine' - - - name: Install QT IFW (MacOS) - if: runner.os == 'macOS' - run: | - python3 -m aqt tool mac tools_ifw 4.3.0 qt.tools.ifw.43 --outputdir ${{ github.workspace }}/Qt - echo "${{ github.workspace }}/Qt/Tools/QtInstallerFramework/4.0/bin" >> $GITHUB_PATH - echo "${{ github.workspace }}/Qt/Tools/QtInstallerFramework/4.1/bin" >> $GITHUB_PATH - echo "${{ github.workspace }}/Qt/Tools/QtInstallerFramework/4.2/bin" >> $GITHUB_PATH - echo "${{ github.workspace }}/Qt/Tools/QtInstallerFramework/4.3/bin" >> $GITHUB_PATH + target: 'desktop' + modules: 'qtcharts debug_info qtwebengine' + setup-python: 'false' + cache: true - name: Install QT (Windows) if: runner.os == 'Windows' - uses: KomodoPlatform/install-qt-action@v2.14.0 + uses: jurplel/install-qt-action@v3.0.0 with: version: ${{ matrix.qt }} - host: 'windows' + host: ${{ matrix.host }} + dir: 'C:\' target: 'desktop' + modules: 'qtcharts debug_info qtwebengine' + tools: 'tools_ifw' arch: 'win64_msvc2019_64' - dir: 'C:\' - modules: 'qtcharts qtwidgets debug_info qtwebview qtwebengine' - - - name: Install QT IFW (Windows) - if: runner.os == 'Windows' - run: | - python -m pip install --upgrade pip - python -m aqt tool windows tools_ifw 4.3.0 qt.tools.ifw.43 --outputdir C:/Qt - echo "C:/Qt/Tools/QtInstallerFramework/4.0/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - echo "C:/Qt/Tools/QtInstallerFramework/4.1/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - echo "C:/Qt/Tools/QtInstallerFramework/4.2/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - echo "C:/Qt/Tools/QtInstallerFramework/4.3/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - echo $env:GITHUB_PATH - echo $env:PATH + cache: true - name: Install nim (Linux) if: runner.os == 'Linux' run: | export DEBIAN_FRONTEND=noninteractive export SHELL=/bin/bash - echo "CHOOSENIM_CHOOSE_VERSION=1.4.8" >> $GITHUB_ENV - export CHOOSENIM_CHOOSE_VERSION=1.4.8 + echo "CHOOSENIM_CHOOSE_VERSION=1.6.10" >> $GITHUB_ENV + export CHOOSENIM_CHOOSE_VERSION=1.6.10 curl https://nim-lang.org/choosenim/init.sh > choosenim.sh chmod +x choosenim.sh ./choosenim.sh -y export PATH=/home/runner/.nimble/bin:$PATH - ls /home/runner/.choosenim/toolchains - chmod +x /home/runner/.choosenim/toolchains/nim-1.4.8/bin/* + chmod +x /home/runner/.choosenim/toolchains/nim-1.6.10/bin/* - name: Install deps (Linux) if: runner.os == 'Linux' @@ -140,21 +164,6 @@ jobs: echo ${{ github.sha }} sudo ./ci_tools_atomic_dex/ci_scripts/linux_script.sh - - name: Upload env variable for vpkg (Linux) - if: runner.os == 'Linux' - run: | - #echo "CXXFLAGS=-stdlib=libc++" >> $GITHUB_ENV - #echo "LDFLAGS=-stdlib=libc++" >> $GITHUB_ENV - echo "CXX=clang++-12" >> $GITHUB_ENV - echo "CC=clang-12" >> $GITHUB_ENV - - - name: vcpkg deps (All) - uses: KomodoPlatform/run-vcpkg@v7 - with: - vcpkgDirectory: '${{ github.workspace }}/ci_tools_atomic_dex/vcpkg-repo' - setupOnly: true - appendedCacheKey: ${{ hashFiles('vcpkg.json') }} - - name: Install deps (MacOS) if: runner.os == 'macOS' run: | @@ -166,25 +175,22 @@ jobs: echo "CXX=/usr/local/opt/llvm/bin/clang++" >> $GITHUB_ENV echo "CC=/usr/local/opt/llvm/bin/clang" >> $GITHUB_ENV - - name: Build FiroDEX (Linux) + - name: Upload env variable for vpkg (Linux) if: runner.os == 'Linux' run: | - export QT_INSTALL_CMAKE_PATH=${{ github.workspace }}/Qt/${{ matrix.qt }}/gcc_64/lib/cmake - export QT_ROOT=${{ github.workspace }}/Qt/${{ matrix.qt }} - export PATH=${{ github.workspace }}/Qt/${{ matrix.qt }}/gcc_64/bin:$PATH - export PATH=$HOME/.nimble/bin:$PATH - #export CXXFLAGS=-stdlib=libc++ - #export LDFLAGS=-stdlib=libc++ - export CXX=clang++-12 - export CC=clang-12 - cd ci_tools_atomic_dex - nimble build -y + echo "CXX=clang++-12" >> $GITHUB_ENV + echo "CC=clang-12" >> $GITHUB_ENV + + - name: vcpkg deps (All) + uses: lukka/run-vcpkg@v10 + with: + vcpkgDirectory: '${{ github.workspace }}/ci_tools_atomic_dex/vcpkg-repo' + appendedCacheKey: ${{ hashFiles('vcpkg.json') }} + vcpkgJsonGlob: 'vcpkg.json' - ./ci_tools_atomic_dex build release - ./ci_tools_atomic_dex bundle release # - name: import code signing certificates (macos) - # if: runner.os == 'macOS' + # if: runner.os == 'macOS' && 'firoorg/FiroDEX-Desktop' == github.repository # uses: Apple-Actions/import-codesign-certs@v1 # with: # keychain: ${{ github.run_id }} @@ -193,7 +199,7 @@ jobs: # p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }} # - name: import installer code signing certificates (macos) - # if: runner.os == 'macOS' + # if: runner.os == 'macOS' && 'firoorg/FiroDEX-Desktop' == github.repository # uses: apple-actions/import-codesign-certs@v1 # with: # keychain: ${{ github.run_id }} @@ -202,91 +208,80 @@ jobs: # p12-file-base64: ${{ secrets.CERTIFICATES_INSTALLER_P12 }} # p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }} - - name: Build FiroDEX (MacOS) + + + - name: Build AtomicDEX (MacOS) if: runner.os == 'macOS' run: | + xcrun --sdk macosx --show-sdk-path + export SDK_PATH=$(xcrun --sdk macosx --show-sdk-path) + ls /Applications/Xcode_13.2.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs + echo $HOME/sdk + ls $HOME/sdk export MAC_SIGN_IDENTITY="${{ secrets.MAC_SIGN_IDENTITY }}" export INSTALLER_MAC_SIGN_IDENTITY="${{ secrets.INSTALLER_MAC_SIGN_IDENTITY }}" export APPLE_ATOMICDEX_PASSWORD="${{ secrets.APPLE_ATOMICDEX_PASSWORD }}" export APPLE_ID="${{ secrets.APPLE_ID }}" + export ASC_PUBLIC_ID="${{ secrets.ASC_PUBLIC_ID }}" export QT_INSTALL_CMAKE_PATH=${{ github.workspace }}/Qt/${{ matrix.qt }}/clang_64/lib/cmake export QT_ROOT=${{ github.workspace }}/Qt/${{ matrix.qt }} - export MACOSX_DEPLOYMENT_TARGET=10.13 + export MACOSX_DEPLOYMENT_TARGET=10.15 export CC=clang export CXX=clang++ cd ci_tools_atomic_dex nimble build -y - ./ci_tools_atomic_dex bundle ${{ matrix.type }} --osx_sdk=$HOME/sdk/MacOSX10.14.sdk --compiler=clang++ + ./ci_tools_atomic_dex bundle ${{ matrix.type }} --osx_sdk=$HOME/sdk/MacOSX10.15.sdk --compiler=clang++ - - name: Build FiroDEX (Windows) - if: runner.os == 'Windows' - shell: powershell - run: | - $Env:QT_VERSION = "${{ matrix.qt }}" - .\ci_tools_atomic_dex\ci_scripts\windows_script.ps1 - # - name: Running Tests (Linux) - # working-directory: ci_tools_atomic_dex - # if: runner.os == 'Linux' && 'firoorg/FiroDEX-Desktop' == github.repository - # run: | - # export QT_INSTALL_CMAKE_PATH=${{ github.workspace }}/Qt/${{ matrix.qt }}/gcc_64/lib/cmake - # export QT_ROOT=${{ github.workspace }}/Qt/${{ matrix.qt }} - # export PATH=${{ github.workspace }}/Qt/${{ matrix.qt }}/gcc_64/bin:$PATH - # export PATH=$HOME/.nimble/bin:$PATH - # #export CXXFLAGS=-stdlib=libc++ - # #export LDFLAGS=-stdlib=libc++ - # export CXX=clang++-12 - # export CC=clang-12 - # echo "Running tests" - # ./ci_tools_atomic_dex tests release - # cd build-Release/bin/AntaraAtomicDexTestsAppDir/usr/bin - # cat ${{ env.DEX_PROJECT_NAME }}-tests-result.xml - # #curl https://report.ci/upload.py --output upload.py - # ls - # #python upload.py --sha `git rev-parse HEAD` -n "[Doctest Linux]" --include='${{ env.DEX_PROJECT_NAME }}-tests-result.xml' --framework=doctest --merge ".*" - # #echo "Uploading tests on Linux finished" - - name: Running Tests (MacOS) - working-directory: ci_tools_atomic_dex - if: runner.os == 'macOS' && 'firoorg/FiroDEX-Desktop' == github.repository + - name: Build AtomicDEX (Linux) + if: runner.os == 'Linux' run: | - export QT_INSTALL_CMAKE_PATH=${{ github.workspace }}/Qt/${{ matrix.qt }}/clang_64/lib/cmake + export QT_INSTALL_CMAKE_PATH=${{ github.workspace }}/Qt/${{ matrix.qt }}/gcc_64/lib/cmake export QT_ROOT=${{ github.workspace }}/Qt/${{ matrix.qt }} - export CC=clang - export CXX=clang++ - echo "Running tests" - #./ci_tools_atomic_dex tests ${{ matrix.type }} - #cd build-${{ matrix.type }}/bin/${{ env.DEX_PROJECT_NAME }}_tests.app/Contents/MacOS - #cat ${{ env.DEX_PROJECT_NAME }}-tests-result.xml - #curl https://report.ci/upload.py --output upload.py - ls - #python upload.py --sha `git rev-parse HEAD` -n "[Doctest MacOS ${{ matrix.type }}]" --include='${{ env.DEX_PROJECT_NAME }}-tests-result.xml' --framework=doctest --merge ".*" - #echo "Uploading tests on OSX finished" + export PATH=${{ github.workspace }}/Qt/${{ matrix.qt }}/gcc_64/bin:$PATH + export PATH=$HOME/.nimble/bin:$PATH + #export CXXFLAGS=-stdlib=libc++ + #export LDFLAGS=-stdlib=libc++ + export CXX=clang++-12 + export CC=clang-12 + cd ci_tools_atomic_dex + nimble build -y - - name: Running Tests (Windows) + ./ci_tools_atomic_dex build ${{ matrix.type }} + ./ci_tools_atomic_dex bundle ${{ matrix.type }} + + + - name: Build FiroDEX (Windows) + if: runner.os == 'Windows' shell: powershell - if: runner.os == 'Windows' && 'firoorg/FiroDEX-Desktop' == github.repository run: | - echo "Running tests" - $Env:QT_INSTALL_CMAKE_PATH = "C:\Qt\${{ matrix.qt }}\msvc2019_64" - cd build\bin - ./${{ env.DEX_PROJECT_NAME }}_tests.exe --reporters=xml --out=${{ env.DEX_PROJECT_NAME }}-tests-result.xml -s - #Invoke-WebRequest -Uri https://report.ci/upload.py -OutFile upload.py - #python upload.py --sha $(git rev-parse HEAD) -n "[Doctest Windows]" --include='${{ env.DEX_PROJECT_NAME }}-tests-result.xml' --framework=doctest --merge ".*" - + $Env:QT_VERSION = "${{ matrix.qt }}" + $Env:CMAKE_BUILD_TYPE = "${{ matrix.type }}" + .\ci_tools_atomic_dex\ci_scripts\windows_script.ps1 - name: Upload env variable for artifacts (Linux) if: runner.os == 'Linux' run: | - ls ./bundled/linux/ + echo "artifact_name_zstd=${{ env.DEX_PROJECT_NAME }}-${{ matrix.name }}-$(git rev-parse --short HEAD).tar.zst" >> $GITHUB_ENV echo "artifact_name_zip=${{ env.DEX_PROJECT_NAME }}-${{ matrix.name }}-$(git rev-parse --short HEAD).zip" >> $GITHUB_ENV echo "artifact_name_appimage=${{ env.DEX_PROJECT_NAME }}-${{ matrix.name }}-$(git rev-parse --short HEAD)-x86_64.AppImage" >> $GITHUB_ENV echo "target_name_zip=${{ env.DEX_PROJECT_NAME }}-linux-$(git rev-parse --short HEAD).zip" >> $GITHUB_ENV - echo "target_name_appimage=${{ env.DEX_PROJECT_NAME }}-$(git rev-parse --short HEAD)-x86_64.AppImage" >> $GITHUB_ENV + echo "target_name_appimage=${{ env.DEX_PROJECT_NAME }}-linux-$(git rev-parse --short HEAD)-x86_64.AppImage" >> $GITHUB_ENV + + + + - name: Upload bundle artifact (Linux ZSTD) + if: runner.os == 'Linux' + uses: actions/upload-artifact@v3 + with: + name: ${{ env.artifact_name_zstd }} + path: ./bundled/linux/${{ env.target_name_zstd }} + retention-days: 7 - name: Upload bundle artifact (Linux ZIP) if: runner.os == 'Linux' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{ env.artifact_name_zip }} path: ./bundled/linux/${{ env.target_name_zip }} @@ -294,7 +289,7 @@ jobs: - name: Upload bundle artifact (Linux AppImage) if: runner.os == 'Linux' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{ env.artifact_name_appimage }} path: ./bundled/linux/${{ env.target_name_appimage }} @@ -303,13 +298,12 @@ jobs: - name: Upload env variable for artifacts (macOS) if: runner.os == 'macOS' run: | - ls ./bundled/osx/ echo "artifact_name_dmg=${{ env.DEX_PROJECT_NAME }}-${{ matrix.name }}-$(git rev-parse --short HEAD).dmg" >> $GITHUB_ENV echo "artifact_name_installer=${{ env.DEX_PROJECT_NAME }}-installer-${{ matrix.name }}-$(git rev-parse --short HEAD).7z" >> $GITHUB_ENV - name: Upload artifacts (MacOS dmg) if: runner.os == 'macOS' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{ env.artifact_name_dmg }} path: ./bundled/osx/${{ env.DEX_PROJECT_NAME }}.dmg @@ -317,7 +311,7 @@ jobs: - name: Upload artifacts (MacOS installer) if: runner.os == 'macOS' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{ env.artifact_name_installer }} path: ./bundled/osx/${{ env.DEX_PROJECT_NAME }}_installer.7z @@ -328,22 +322,78 @@ jobs: run: | echo "on_windows" echo "artifact_name_zip=${{ env.DEX_PROJECT_NAME }}-${{ matrix.name }}-$(git rev-parse --short HEAD).zip" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - echo "artifact_name_installer=${{ env.DEX_PROJECT_NAME }}-installer-${{ matrix.name }}-$(git rev-parse --short HEAD).exe" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "artifact_name_installer=${{ env.DEX_PROJECT_NAME }}-${{ matrix.name }}-installer-$(git rev-parse --short HEAD).exe" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - name: Upload artifacts (Windows zip) if: runner.os == 'Windows' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{ env.artifact_name_zip }} - path: ./bundled/windows/bin.zip + path: ./bundled/windows/${{ env.DEX_PROJECT_NAME }}.zip retention-days: 7 - name: Upload artifacts (Windows installer) if: runner.os == 'Windows' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{ env.artifact_name_installer }} path: ./bundled/windows/${{ env.DEX_PROJECT_NAME }}_installer.exe retention-days: 7 - - \ No newline at end of file + + + + - name: Running Tests (Linux) + working-directory: ci_tools_atomic_dex + continue-on-error: true + if: runner.os == 'Linux' && 'firoorg/FiroDEX-Desktop' == github.repository + run: | + export REPORT_CI_TOKEN=${{ secrets.REPORT_CI_TOKEN_SECRET }} + export ATOMICDEX_TEST_SEED=${{ secrets.ATOMICDEX_TEST_SEED }} + export ATOMICDEX_PASSWORD=${{ secrets.ATOMICDEX_PASSWORD }} + export QT_INSTALL_CMAKE_PATH=${{ github.workspace }}/Qt/${{ matrix.qt }}/gcc_64/lib/cmake + export QT_ROOT=${{ github.workspace }}/Qt/${{ matrix.qt }} + export PATH=${{ github.workspace }}/Qt/${{ matrix.qt }}/gcc_64/bin:$PATH + export PATH=$HOME/.nimble/bin:$PATH + export CXX=clang++-12 + export CC=clang-12 + #echo "Running tests" + #./ci_tools_atomic_dex tests ${{ matrix.type }} + #cd build-${{ matrix.type }}/bin/AntaraAtomicDexTestsAppDir/usr/bin + #cat ${{ env.DEX_PROJECT_NAME }}-tests-result.xml + + - name: Running Tests (MacOS) + working-directory: ci_tools_atomic_dex + continue-on-error: true + if: runner.os == 'macOS' && 'firoorg/FiroDEX-Desktop' == github.repository + run: | + export MAC_SIGN_IDENTITY="${{ secrets.MAC_SIGN_IDENTITY }}" + export INSTALLER_MAC_SIGN_IDENTITY="${{ secrets.INSTALLER_MAC_SIGN_IDENTITY }}" + export APPLE_ATOMICDEX_PASSWORD="${{ secrets.APPLE_ATOMICDEX_PASSWORD }}" + export APPLE_ID="${{ secrets.APPLE_ID }}" + export ASC_PUBLIC_ID="${{ secrets.ASC_PUBLIC_ID }}" + export MACOSX_DEPLOYMENT_TARGET=10.13 + export REPORT_CI_TOKEN=${{ secrets.REPORT_CI_TOKEN_SECRET }} + export ATOMICDEX_TEST_SEED=${{ secrets.ATOMICDEX_TEST_SEED }} + export ATOMICDEX_PASSWORD=${{ secrets.ATOMICDEX_PASSWORD }} + export QT_INSTALL_CMAKE_PATH=${{ github.workspace }}/Qt/${{ matrix.qt }}/clang_64/lib/cmake + export QT_ROOT=${{ github.workspace }}/Qt/${{ matrix.qt }} + export CC=clang + export CXX=clang++ + #echo "Running tests" + #nimble build -y + #./ci_tools_atomic_dex tests ${{ matrix.type }} + #cd build-${{ matrix.type }}/bin/${{ env.DEX_PROJECT_NAME }}_tests.app/Contents/MacOS + #cat ${{ env.DEX_PROJECT_NAME }}-tests-result.xml + + - name: Running Tests (Windows) + shell: powershell + continue-on-error: true + if: runner.os == 'Windows' && 'firoorg/FiroDEX-Desktop' == github.repository + run: | + #echo "Running tests" + $Env:REPORT_CI_TOKEN = "${{ secrets.REPORT_CI_TOKEN_SECRET }}" + $Env:QT_INSTALL_CMAKE_PATH = "C:\Qt\${{ matrix.qt }}\msvc2019_64" + #cd b\bin + #./${{ env.DEX_PROJECT_NAME }}_tests.exe --reporters=xml --out=${{ env.DEX_PROJECT_NAME }}-tests-result.xml -s + #Invoke-WebRequest -Uri https://report.ci/upload.py -OutFile upload.py + #python upload.py --sha $(git rev-parse HEAD) -n "[Doctest Windows]" --include='${{ env.DEX_PROJECT_NAME }}-tests-result.xml' --framework=doctest --merge ".*" diff --git a/.github/workflows/firodex-desktop-release-vt.yml b/.github/workflows/firodex-desktop-release-vt.yml index 2e3e9c0f5d..9f4621b286 100644 --- a/.github/workflows/firodex-desktop-release-vt.yml +++ b/.github/workflows/firodex-desktop-release-vt.yml @@ -10,7 +10,7 @@ jobs: steps: - name: VirusTotal Scan - uses: crazy-max/ghaction-virustotal@v2.4.1 + uses: crazy-max/ghaction-virustotal@v3.1.0 with: vt_api_key: ${{ secrets.VT_API_KEY }} github_token: ${{ github.token }} diff --git a/CMakeLists.txt b/CMakeLists.txt index eac6256686..4dbf66bc0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,14 +11,13 @@ include(vcpkg_prerequisites) include(qt_prerequisites) include(cfg_hash) -project(${DEX_PROJECT_NAME} LANGUAGES CXX VERSION 0.5.5) +project(${DEX_PROJECT_NAME} LANGUAGES CXX VERSION 0.5.7) message(STATUS "${PROJECT_NAME} is version ${PROJECT_VERSION}") include(cmake_default_options) include(ipo_prerequisites) ##! Options -option(PREFER_BOOST_FILESYSTEM "Enable to use boost filesystem instead of std::filesystem" OFF) option(WITH_HOTRELOAD "Enable to use qml Hot reload" OFF) if (NOT WITH_HOTRELOAD) @@ -61,13 +60,13 @@ endif () ##! We fetch our dependencies if (APPLE) FetchContent_Declare(mm2 - URL https://github.com/KomodoPlatform/atomicDEX-API/releases/download/beta-2.1.5182/mm2-0fea16d6b-Darwin-Release.zip) + URL https://github.com/KomodoPlatform/atomicDEX-API/releases/download/beta-2.1.8741/mm2-6e4de5d21-Darwin-Release.zip) elseif (UNIX AND NOT APPLE) FetchContent_Declare(mm2 - URL https://github.com/KomodoPlatform/atomicDEX-API/releases/download/beta-2.1.5182/mm2-0fea16d6b-Linux-Release.zip) + URL https://github.com/KomodoPlatform/atomicDEX-API/releases/download/beta-2.1.8741/mm2-6e4de5d21-Linux-Release.zip) else () FetchContent_Declare(mm2 - URL https://github.com/KomodoPlatform/atomicDEX-API/releases/download/beta-2.1.5182/mm2-0fea16d6b-Windows_NT-Release.zip) + URL https://github.com/KomodoPlatform/atomicDEX-API/releases/download/beta-2.1.8741/mm2-6e4de5d21-Windows_NT-Release.zip) endif () #FetchContent_Declare(qmaterial URL https://github.com/KomodoPlatform/Qaterial/archive/last-clang-working-2.zip) @@ -88,15 +87,15 @@ FetchContent_MakeAvailable(mm2 jl777-coins qmaterial) ##! Configure our needs. if (UNIX) - configure_file(assets/config/${PROJECT_VERSION}-coins.json ${CMAKE_CURRENT_SOURCE_DIR}/assets/config/${PROJECT_VERSION}-coins.json COPYONLY) + configure_file(${jl777-coins_SOURCE_DIR}/utils/coins_config.json ${CMAKE_CURRENT_SOURCE_DIR}/assets/config/${PROJECT_VERSION}-coins.json COPYONLY) configure_file(${jl777-coins_SOURCE_DIR}/coins ${CMAKE_CURRENT_SOURCE_DIR}/assets/tools/mm2/coins COPYONLY) - configure_file(${mm2_SOURCE_DIR}/mm2 ${CMAKE_CURRENT_SOURCE_DIR}/assets/tools/mm2/mm2 COPYONLY) + configure_file(${mm2_SOURCE_DIR}/mm2 ${CMAKE_CURRENT_SOURCE_DIR}/assets/tools/mm2/${DEX_API} COPYONLY) + file(COPY ${jl777-coins_SOURCE_DIR}/icons/ DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/atomic_defi_design/assets/images/coins/) else () - configure_file(assets/config/${PROJECT_VERSION}-coins.json ${CMAKE_BINARY_DIR}/bin/assets/config/${PROJECT_VERSION}-coins.json COPYONLY) + configure_file(${jl777-coins_SOURCE_DIR}/utils/coins_config.json ${CMAKE_BINARY_DIR}/bin/assets/config/${PROJECT_VERSION}-coins.json COPYONLY) configure_file(${jl777-coins_SOURCE_DIR}/coins ${CMAKE_BINARY_DIR}/bin/assets/tools/mm2/coins COPYONLY) - configure_file(${mm2_SOURCE_DIR}/mm2.exe ${CMAKE_BINARY_DIR}/bin/assets/tools/mm2/mm2.exe COPYONLY) + configure_file(${mm2_SOURCE_DIR}/mm2.exe ${CMAKE_BINARY_DIR}/bin/assets/tools/mm2/${DEX_API}.exe COPYONLY) configure_file(${mm2_SOURCE_DIR}/msvcp140.dll ${CMAKE_BINARY_DIR}/bin/assets/tools/mm2/msvcp140.dll COPYONLY) - configure_file(${mm2_SOURCE_DIR}/msvcr100.dll ${CMAKE_BINARY_DIR}/bin/assets/tools/mm2/msvcr100.dll COPYONLY) configure_file(${mm2_SOURCE_DIR}/vcruntime140.dll ${CMAKE_BINARY_DIR}/bin/assets/tools/mm2/vcruntime140.dll COPYONLY) endif () diff --git a/assets/config/.gitignore b/assets/config/.gitignore new file mode 100644 index 0000000000..2f7e12e1e9 --- /dev/null +++ b/assets/config/.gitignore @@ -0,0 +1 @@ +*-coins.json diff --git a/assets/config/0.5.5-coins.json b/assets/config/0.5.5-coins.json deleted file mode 100644 index ea92f45e79..0000000000 --- a/assets/config/0.5.5-coins.json +++ /dev/null @@ -1,9794 +0,0 @@ -{ - "1INCH-AVX20": { - "coin": "1INCH-AVX20", - "name": "1inch", - "coinpaprika_id": "1inch-1inch", - "coingecko_id": "1inch", - "nomics_id": "1INCH", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "1INCH-BEP20": { - "coin": "1INCH-BEP20", - "name": "1inch", - "coinpaprika_id": "1inch-1inch", - "coingecko_id": "1inch", - "nomics_id": "1INCH", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "1INCH-ERC20": { - "coin": "1INCH-ERC20", - "name": "1inch", - "coinpaprika_id": "1inch-1inch", - "coingecko_id": "1inch", - "nomics_id": "1INCH", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "1INCH-HRC20": { - "coin": "1INCH-HRC20", - "name": "1inch", - "coinpaprika_id": "1inch-1inch", - "coingecko_id": "1inch", - "nomics_id": "1INCH", - "nodes": [ - "https://api.harmony.one", - "https://api.s0.t.hmny.io" - ], - "explorer_url": [ - "https://explorer.harmony.one/" - ], - "type": "HRC-20", - "active": false, - "currently_enabled": false - }, - "1INCH-KRC20": { - "coin": "1INCH-KRC20", - "name": "1inch", - "coinpaprika_id": "1inch-1inch", - "coingecko_id": "1inch", - "nomics_id": "1INCH", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "1INCH-PLG20": { - "coin": "1INCH-PLG20", - "name": "1inch", - "coinpaprika_id": "1inch-1inch", - "coingecko_id": "1inch", - "nomics_id": "1INCH", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "AAVE-AVX20": { - "coin": "AAVE-AVX20", - "name": "Aave", - "coinpaprika_id": "aave-new", - "coingecko_id": "aave", - "nomics_id": "AAVE", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "AAVE-BEP20": { - "coin": "AAVE-BEP20", - "name": "Aave", - "coinpaprika_id": "aave-new", - "coingecko_id": "aave", - "nomics_id": "AAVE", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "AAVE-ERC20": { - "coin": "AAVE-ERC20", - "name": "Aave", - "coinpaprika_id": "aave-new", - "coingecko_id": "aave", - "nomics_id": "AAVE", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "AAVE-FTM20": { - "coin": "AAVE-FTM20", - "name": "Aave", - "coinpaprika_id": "aave-new", - "coingecko_id": "aave", - "nomics_id": "AAVE", - "nodes": [ - "https://rpc.ftm.tools/" - ], - "explorer_url": [ - "https://ftmscan.com/" - ], - "type": "FTM-20", - "active": false, - "currently_enabled": false - }, - "AAVE-HCO20": { - "coin": "AAVE-HCO20", - "name": "Aave", - "coinpaprika_id": "aave-new", - "coingecko_id": "aave", - "nomics_id": "AAVE", - "nodes": [ - "https://http-mainnet.hecochain.com" - ], - "explorer_url": [ - "https://hecoinfo.com/" - ], - "type": "HecoChain", - "active": false, - "currently_enabled": false - }, - "AAVE-HRC20": { - "coin": "AAVE-HRC20", - "name": "Aave", - "coinpaprika_id": "aave-new", - "coingecko_id": "aave", - "nomics_id": "AAVE", - "nodes": [ - "https://api.harmony.one", - "https://api.s0.t.hmny.io" - ], - "explorer_url": [ - "https://explorer.harmony.one/" - ], - "type": "HRC-20", - "active": false, - "currently_enabled": false - }, - "AAVE-KRC20": { - "coin": "AAVE-KRC20", - "name": "Aave", - "coinpaprika_id": "aave-new", - "coingecko_id": "aave", - "nomics_id": "AAVE", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "AAVE-PLG20": { - "coin": "AAVE-PLG20", - "name": "Aave", - "coinpaprika_id": "aave-new", - "coingecko_id": "aave", - "nomics_id": "AAVE", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "ABY-OLD": { - "coin": "ABY-OLD", - "name": "ArtByte (OLD)", - "coinpaprika_id": "aby-artbyte", - "coingecko_id": "artbyte", - "electrum": [ - { - "url": "electrumx.aby.ewmcx.biz:50002", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "failover.aby.ewmcx.biz:50002", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "http://aby-explorer.ewmcx.info/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "ABY": { - "coin": "ABY", - "name": "ArtByte", - "coinpaprika_id": "aby-artbyte", - "coingecko_id": "artbyte", - "electrum": [ - { - "url": "elec-seeder-one.artbytecoin.org:50012", - "protocol": "SSL", - "disable_cert_verification": true, - "ws_url": "elec-seeder-one.artbytecoin.org:50013" - }, - { - "url": "elec-seeder-two.artbytecoin.org:50012", - "protocol": "SSL", - "disable_cert_verification": true, - "ws_url": "elec-seeder-two.artbytecoin.org:50013" - }, - { - "url": "electrumx-three.artbyte.live:50012", - "protocol": "SSL", - "disable_cert_verification": false, - "ws_url": "electrumx-three.artbyte.live:50013" - }, - { - "url": "electrumx-four.artbyte.live:50012", - "protocol": "SSL", - "disable_cert_verification": false, - "ws_url": "electrumx-four.artbyte.live:50013" - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/aby/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "ADA-BEP20": { - "coin": "ADA-BEP20", - "name": "Cardano", - "coinpaprika_id": "ada-cardano", - "coingecko_id": "cardano", - "nomics_id": "ADA", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "ADX-BEP20": { - "coin": "ADX-BEP20", - "name": "AdEx", - "coinpaprika_id": "adx-adex", - "coingecko_id": "adex", - "nomics_id": "ADX", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "ADX-ERC20": { - "coin": "ADX-ERC20", - "name": "AdEx", - "coinpaprika_id": "adx-adex", - "coingecko_id": "adex", - "nomics_id": "ADX", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "AGIX-ERC20": { - "coin": "AGIX-ERC20", - "name": "SingularityNET", - "coinpaprika_id": "agix-singularitynet", - "coingecko_id": "singularitynet", - "nomics_id": "AGIX", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "AGIX-PLG20": { - "coin": "AGIX-PLG20", - "name": "SingularityNET", - "coinpaprika_id": "agix-singularitynet", - "coingecko_id": "singularitynet", - "nomics_id": "AGIX", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "ANKR-BEP20": { - "coin": "ANKR-BEP20", - "name": "Ankr", - "coinpaprika_id": "ankr-ankr-network", - "coingecko_id": "ankr", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "ANKR-ERC20": { - "coin": "ANKR-ERC20", - "name": "Ankr", - "coinpaprika_id": "ankr-ankr-network", - "coingecko_id": "ankr", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "ARRR-BEP20": { - "coin": "ARRR-BEP20", - "name": "Pirate", - "coinpaprika_id": "arrr-pirate", - "coingecko_id": "pirate-chain", - "nomics_id": "ARRR", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "ARPA-BEP20": { - "coin": "ARPA-BEP20", - "name": "ARPA Chain", - "coinpaprika_id": "arpa-arpa-chain", - "coingecko_id": "arpa-chain", - "nomics_id": "ARPA", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "ARPA-ERC20": { - "coin": "ARPA-ERC20", - "name": "ARPA Chain", - "coinpaprika_id": "arpa-arpa-chain", - "coingecko_id": "arpa-chain", - "nomics_id": "ARPA", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "ATOM-BEP20": { - "coin": "ATOM-BEP20", - "name": "Cosmos", - "coinpaprika_id": "atom-cosmos", - "coingecko_id": "cosmos", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "AUR": { - "coin": "AUR", - "name": "Auroracoin", - "coinpaprika_id": "aur-auroracoin", - "coingecko_id": "auroracoin", - "nomics_id": "AUR", - "electrum": [ - { - "url": "electrumx.aur.ewmcx.info:50002", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "failover.aur.ewmcx.biz:50002", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/aur/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "AVA-BEP20": { - "coin": "AVA-BEP20", - "name": "Travala.com", - "coinpaprika_id": "ava-travala", - "coingecko_id": "concierge-io", - "nomics_id": "AVA", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "AVAX-BEP20": { - "coin": "AVAX-BEP20", - "name": "Avalanche", - "coinpaprika_id": "avax-avalanche", - "coingecko_id": "avalanche-2", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "AVAX": { - "coin": "AVAX", - "name": "Avalanche", - "coinpaprika_id": "avax-avalanche", - "coingecko_id": "avalanche-2", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "AVAXT": { - "coin": "AVAXT", - "name": "Avalanche Testnet", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "is_testnet": true, - "nodes": [ - "https://api.avax-test.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://cchain.explorer.avax-test.network/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "AXE": { - "coin": "AXE", - "name": "Axe", - "coinpaprika_id": "axe-axe", - "coingecko_id": "axe", - "nomics_id": "AXE", - "electrum": [ - { - "url": "electrum1.cipig.net:10057", - "ws_url": "electrum1.cipig.net:30057" - }, - { - "url": "electrum2.cipig.net:10057", - "ws_url": "electrum2.cipig.net:30057" - }, - { - "url": "electrum3.cipig.net:10057", - "ws_url": "electrum3.cipig.net:30057" - } - ], - "explorer_url": [ - "https://axe-explorer.arcpool.com/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "AXS-BEP20": { - "coin": "AXS-BEP20", - "name": "Axie Infinity", - "coinpaprika_id": "axs-axie-infinity", - "coingecko_id": "axie-infinity", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "AXS-ERC20": { - "coin": "AXS-ERC20", - "name": "Axie Infinity", - "coinpaprika_id": "axs-axie-infinity", - "coingecko_id": "axie-infinity", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "BABYDOGE-BEP20": { - "coin": "BABYDOGE-BEP20", - "name": "Baby Doge Coin", - "coinpaprika_id": "babydoge-baby-doge-coin", - "coingecko_id": "baby-doge-coin", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "BAL-BEP20": { - "coin": "BAL-BEP20", - "name": "Balancer", - "coinpaprika_id": "bal-balancer", - "coingecko_id": "balancer", - "nomics_id": "BAL", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "BAL-ERC20": { - "coin": "BAL-ERC20", - "name": "Balancer", - "coinpaprika_id": "bal-balancer", - "coingecko_id": "balancer", - "nomics_id": "BAL", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "BAL-KRC20": { - "coin": "BAL-KRC20", - "name": "Balancer", - "coinpaprika_id": "bal-balancer", - "coingecko_id": "balancer", - "nomics_id": "BAL", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "BAL-PLG20": { - "coin": "BAL-PLG20", - "name": "Balancer", - "coinpaprika_id": "bal-balancer", - "coingecko_id": "balancer", - "nomics_id": "BAL", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "BANANO-BEP20": { - "coin": "BANANO-BEP20", - "name": "Banano", - "nomics_id": "BAN", - "coinpaprika_id": "ban-banano", - "coingecko_id": "banano", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "BAND-BEP20": { - "coin": "BAND-BEP20", - "name": "Band Protocol", - "coinpaprika_id": "band-band-protocol", - "coingecko_id": "band-protocol", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "BAND-ERC20": { - "coin": "BAND-ERC20", - "name": "Band Protocol", - "coinpaprika_id": "band-band-protocol", - "coingecko_id": "band-protocol", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "BAND-FTM20": { - "coin": "BAND-FTM20", - "name": "Band Protocol", - "coinpaprika_id": "band-band-protocol", - "coingecko_id": "band-protocol", - "nodes": [ - "https://rpc.ftm.tools/" - ], - "explorer_url": [ - "https://ftmscan.com/" - ], - "type": "FTM-20", - "active": false, - "currently_enabled": false - }, - "BAND-PLG20": { - "coin": "BAND-PLG20", - "name": "Band Protocol", - "coinpaprika_id": "band-band-protocol", - "coingecko_id": "band-protocol", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "BCH": { - "coin": "BCH", - "coingecko_id": "bitcoin-cash", - "coinpaprika_id": "bch-bitcoin-cash", - "nomics_id": "BCH", - "active": false, - "currently_enabled": false, - "electrum": [ - { - "url": "electrum1.cipig.net:10055", - "ws_url": "electrum1.cipig.net:30055" - }, - { - "url": "electrum2.cipig.net:10055", - "ws_url": "electrum2.cipig.net:30055" - }, - { - "url": "electrum3.cipig.net:10055", - "ws_url": "electrum3.cipig.net:30055" - } - ], - "explorer_url": [ - "https://explorer.bitcoin.com/bch/" - ], - "type": "UTXO", - "name": "Bitcoin Cash" - }, - "BCH-ERC20": { - "coin": "BCH-ERC20", - "name": "Bitcoin Cash", - "coinpaprika_id": "bch-bitcoin-cash", - "coingecko_id": "bitcoin-cash", - "nomics_id": "BCH", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "BCH-BEP20": { - "coin": "BCH-BEP20", - "name": "Bitcoin Cash", - "coinpaprika_id": "bch-bitcoin-cash", - "coingecko_id": "bitcoin-cash", - "nomics_id": "BCH", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "BCH-HCO20": { - "coin": "BCH-HCO20", - "name": "Bitcoin Cash", - "coinpaprika_id": "bch-bitcoin-cash", - "coingecko_id": "bitcoin-cash", - "nomics_id": "BCH", - "nodes": [ - "https://http-mainnet.hecochain.com" - ], - "explorer_url": [ - "https://hecoinfo.com/" - ], - "type": "HecoChain", - "active": false, - "currently_enabled": false - }, - "BIDR-BEP20": { - "coin": "BIDR-BEP20", - "name": "BIDR", - "forex_id": "IDR", - "coinpaprika_id": "bidr-binanceidr", - "coingecko_id": "binanceidr", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "BLK": { - "coin": "BLK", - "name": "BlackCoin", - "coinpaprika_id": "blk-blackcoin", - "coingecko_id": "blackcoin", - "nomics_id": "BLK", - "electrum": [ - { - "url": "electrum1.blackcoin.nl:10002", - "protocol": "SSL", - "disable_cert_verification": false - }, - { - "url": "electrum2.blackcoin.nl:20002", - "protocol": "SSL", - "disable_cert_verification": false - }, - { - "url": "electrum3.blackcoin.nl:30002", - "protocol": "SSL", - "disable_cert_verification": false - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/blk/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "tBLK": { - "coin": "tBLK", - "name": "BlackCoin (testnet)", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "is_testnet": true, - "electrum": [ - { - "url": "electrum1.blackcoin.nl:10012", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "electrum2.blackcoin.nl:20012", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "electrum3.blackcoin.nl:30012", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "https://explorer.blackcoin.nl/" - ], - "explorer_tx_url": "tx/", - "explorer_address_url": "address/", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "BNB": { - "coin": "BNB", - "name": "Binance Coin", - "coinpaprika_id": "bnb-binance-coin", - "coingecko_id": "binancecoin", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": true, - "currently_enabled": false - }, - "BNBT": { - "coin": "BNBT", - "name": "Binance Coin (Testnet)", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "nodes": [ - "https://data-seed-prebsc-1-s2.binance.org:8545" - ], - "explorer_url": [ - "https://testnet.bscscan.com/" - ], - "is_testnet": true, - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "BNT-BEP20": { - "coin": "BNT-BEP20", - "name": "Bancor", - "coinpaprika_id": "bnt-bancor", - "coingecko_id": "bancor", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "BNT-ERC20": { - "coin": "BNT-ERC20", - "name": "Bancor", - "coinpaprika_id": "bnt-bancor", - "coingecko_id": "bancor", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "BNT-PLG20": { - "coin": "BNT-PLG20", - "name": "Bancor", - "coinpaprika_id": "bnt-bancor", - "coingecko_id": "bancor", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "BONE-ERC20" : { - "coin": "BONE-ERC20", - "name": "Bone ShibaSwap", - "coinpaprika_id": "bone-bone-shibaswap", - "coingecko_id": "bone-shibaswap", - "nomics_id": "BONE6", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "BRZ-BEP20": { - "coin": "BRZ-BEP20", - "name": "Brazilian Digital Token", - "forex_id": "BRL", - "coinpaprika_id": "brz-brazilian-digital-token", - "coingecko_id": "brz", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "BRZ-ERC20": { - "coin": "BRZ-ERC20", - "name": "Brazilian Digital Token", - "forex_id": "BRL", - "coinpaprika_id": "brz-brazilian-digital-token", - "coingecko_id": "brz", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "BSTY": { - "coin": "BSTY", - "name": "GlobalBoost-Y", - "coinpaprika_id": "bsty-globalboost-y", - "coingecko_id": "globalboost", - "nomics_id": "BSTY", - "electrum": [ - { - "url": "66.172.33.175:50001", - "protocol": "TCP" - }, - { - "url": "bsty-main.coinmunity.gold:50012", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "bsty-bkp.coinmunity.gold:50012", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "https://insight.globalboost.info/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "RBTC": { - "coin": "RBTC", - "name": "RSK Smart Bitcoin", - "alias_ticker": "BTC", - "coinpaprika_id": "rbtc-smart-bitcoin", - "coingecko_id": "rootstock", - "nodes": [ - "https://public-node.rsk.co" - ], - "explorer_url": [ - "https://explorer.rsk.co" - ], - "type": "RSK Smart Bitcoin", - "active": false, - "currently_enabled": false - }, - "BTC": { - "coin": "BTC", - "name": "Bitcoin", - "type": "UTXO", - "coingecko_id": "bitcoin", - "coinpaprika_id": "btc-bitcoin", - "nomics_id": "BTC", - "electrum": [ - { - "url": "electrum3.cipig.net:10000", - "ws_url": "electrum3.cipig.net:30000" - }, - { - "url": "electrum2.cipig.net:10000", - "ws_url": "electrum2.cipig.net:30000" - }, - { - "url": "electrum1.cipig.net:10000", - "ws_url": "electrum1.cipig.net:30000" - } - ], - "explorer_url": [ - "https://blockstream.info/" - ], - "active": true, - "currently_enabled": false - }, - "BTC-BEP20": { - "coin": "BTC-BEP20", - "name": "Bitcoin", - "coinpaprika_id": "btc-bitcoin", - "coingecko_id": "bitcoin", - "nomics_id": "BTC", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "BTCZ": { - "coin": "BTCZ", - "name": "BitcoinZ", - "coinpaprika_id": "btcz-bitcoinz", - "coingecko_id": "bitcoinz", - "nomics_id": "BTCZ", - "electrum": [ - { - "url": "electrum1.btcz.rocks:50001" - }, - { - "url": "electrum2.btcz.rocks:50001" - } - ], - "explorer_url": [ - "https://explorer.btcz.rocks/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "BTX": { - "coin": "BTX", - "name": "BitCore", - "coinpaprika_id": "btx-bitcore", - "coingecko_id": "bitcore", - "nomics_id": "BTX", - "electrum": [ - { - "url": "btx-electrumx.coinsmunity.com:50002", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/btx/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "BTX-BEP20": { - "coin": "BTX-BEP20", - "name": "BitCore", - "coinpaprika_id": "btx-bitcore", - "coingecko_id": "bitcore", - "nomics_id": "BTX", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "BET": { - "coin": "BET", - "name": "BET", - "type": "Smart Chain", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10012", - "ws_url": "electrum1.cipig.net:30012" - }, - { - "url": "electrum2.cipig.net:10012", - "ws_url": "electrum2.cipig.net:30012" - }, - { - "url": "electrum3.cipig.net:10012", - "ws_url": "electrum3.cipig.net:30012" - } - ], - "explorer_url": [ - "https://bet.explorer.dexstats.info/" - ], - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "BOTS": { - "coin": "BOTS", - "name": "BOTS", - "type": "Smart Chain", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10007", - "ws_url": "electrum1.cipig.net:30007" - }, - { - "url": "electrum2.cipig.net:10007", - "ws_url": "electrum2.cipig.net:30007" - }, - { - "url": "electrum3.cipig.net:10007", - "ws_url": "electrum3.cipig.net:30007" - } - ], - "explorer_url": [ - "https://bots.explorer.dexstats.info/" - ], - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "BTT-BEP20": { - "coin": "BTT-BEP20", - "name": "BitTorrent (OLD)", - "coinpaprika_id": "btt-bittorrent", - "coingecko_id": "bittorrent-old", - "nomics_id": "BITTORRENT", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "BTTC-BEP20": { - "coin": "BTTC-BEP20", - "name": "BitTorrent", - "coinpaprika_id": "bttc-bittorrent-chain", - "coingecko_id": "bittorrent", - "nomics_id": "BTT2", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "BTU-ERC20": { - "coin": "BTU-ERC20", - "name": "BTU Protocol", - "coinpaprika_id": "btu-btu-protocol", - "coingecko_id": "btu-protocol", - "nomics_id": "BTU", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "BTU-PLG20": { - "coin": "BTU-PLG20", - "name": "BTU Protocol", - "coinpaprika_id": "btu-btu-protocol", - "coingecko_id": "btu-protocol", - "nomics_id": "BTU", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "BUSD-AVX20": { - "coin": "BUSD-AVX20", - "name": "Binance USD", - "coinpaprika_id": "busd-binance-usd", - "coingecko_id": "binance-usd", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "BUSD-MVR20": { - "coin": "BUSD-MVR20", - "name": "Binance USD", - "coinpaprika_id": "busd-binance-usd", - "coingecko_id": "binance-usd", - "nodes": [ - "https://rpc.api.moonriver.moonbeam.network" - ], - "explorer_url": [ - "https://moonriver.moonscan.io/" - ], - "type": "Moonriver", - "active": false, - "currently_enabled": false - }, - "BUSD-ERC20": { - "coin": "BUSD-ERC20", - "name": "Binance USD", - "coinpaprika_id": "busd-binance-usd", - "coingecko_id": "binance-usd", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "BUSD-BEP20": { - "coin": "BUSD-BEP20", - "name": "Binance USD", - "coinpaprika_id": "busd-binance-usd", - "coingecko_id": "binance-usd", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": true, - "currently_enabled": false - }, - "BUSD-HRC20": { - "coin": "BUSD-HRC20", - "name": "Binance USD", - "coinpaprika_id": "busd-binance-usd", - "coingecko_id": "binance-usd", - "nodes": [ - "https://api.harmony.one", - "https://api.s0.t.hmny.io" - ], - "explorer_url": [ - "https://explorer.harmony.one/" - ], - "type": "HRC-20", - "active": false, - "currently_enabled": false - }, - "BUSD-PLG20": { - "coin": "BUSD-PLG20", - "name": "Binance USD", - "coinpaprika_id": "busd-binance-usd", - "coingecko_id": "binance-usd", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "BTE": { - "coin": "BTE", - "name": "Bitweb", - "type": "UTXO", - "coingecko_id": "bitweb", - "coinpaprika_id": "bte-bitweb", - "nomics_id": "BTE3", - "electrum": [ - { - "url": "electrumx.bitwebcore.org:20001" - }, - { - "url": "electrumx6.scalaris.info:20001" - }, - { - "url": "electrumx7.scalaris.info:20001" - } - ], - "explorer_url": [ - "https://explorer.bitwebcore.org/" - ], - "active": false, - "currently_enabled": false - }, - "CADC-ERC20": { - "coin": "CADC-ERC20", - "name": "CAD Coin", - "forex_id": "CAD", - "coinpaprika_id": "cadc-cad-coin", - "coingecko_id": "cad-coin", - "nomics_id": "CADC", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "CADC-PLG20": { - "coin": "CADC-PLG20", - "name": "CAD Coin", - "forex_id": "CAD", - "coinpaprika_id": "cadc-cad-coin", - "coingecko_id": "cad-coin", - "nomics_id": "CADC", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "CAKE": { - "coin": "CAKE", - "name": "PancakeSwap", - "coinpaprika_id": "cake-pancakeswap", - "coingecko_id": "pancakeswap-token", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "CASE": { - "coin": "CASE", - "name": "Case Token", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "nomics_id": "CASE", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "CCL": { - "coin": "CCL", - "name": "CoinCollect", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10029", - "ws_url": "electrum1.cipig.net:30029" - }, - { - "url": "electrum2.cipig.net:10029", - "ws_url": "electrum2.cipig.net:30029" - }, - { - "url": "electrum3.cipig.net:10029", - "ws_url": "electrum3.cipig.net:30029" - } - ], - "explorer_url": [ - "https://ccl.explorer.dexstats.info/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false - }, - "CDN": { - "coin": "CDN", - "name": "Canada eCoin", - "coinpaprika_id": "cdn-canada-ecoin", - "coingecko_id": "test-coin", - "nomics_id": "CDN", - "electrum": [ - { - "url": "mumbai.ecoincore.com:34333", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "holland.ecoincore.com:34333", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "miami.ecoincore.com:34333", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "woolloomooloo.ecoincore.com:34333", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "lenoir.ecoincore.com:34333", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/cdn/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "CELR-ERC20": { - "coin": "CELR-ERC20", - "name": "Celer Network", - "coinpaprika_id": "celr-celer-network", - "coingecko_id": "celer-network", - "nomics_id": "CELR", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "CELR-BEP20": { - "coin": "CELR-BEP20", - "name": "Celer Network", - "coinpaprika_id": "celr-celer-network", - "coingecko_id": "celer-network", - "nomics_id": "CELR", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "CELR-ARB20": { - "coin": "CELR-ARB20", - "name": "Celer Network", - "coinpaprika_id": "celr-celer-network", - "coingecko_id": "celer-network", - "nomics_id": "CELR", - "nodes": [ - "https://arb1.arbitrum.io/rpc" - ], - "explorer_url": [ - "https://arbiscan.io/" - ], - "type": "Arbitrum", - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "CLC": { - "coin": "CLC", - "name": "Collider Coin", - "coinpaprika_id": "clc-collider-coin", - "coingecko_id": "test-coin", - "nomics_id": "CLC2", - "electrum": [ - { - "url": "electrumx.cryptocollider.com:10001" - }, - { - "url": "electrumx2.cryptocollider.com:10001" - } - ], - "explorer_url": [ - "https://clc.explorer.dexstats.info/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false - }, - "COMP-AVX20": { - "coin": "COMP-AVX20", - "name": "Compound", - "coinpaprika_id": "comp-compoundd", - "coingecko_id": "compound-governance-token", - "nomics_id": "COMP", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "COMP-BEP20": { - "coin": "COMP-BEP20", - "name": "Compound", - "coinpaprika_id": "comp-compoundd", - "coingecko_id": "compound-governance-token", - "nomics_id": "COMP", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "COMP-ERC20": { - "coin": "COMP-ERC20", - "name": "Compound", - "coinpaprika_id": "comp-compoundd", - "coingecko_id": "compound-governance-token", - "nomics_id": "COMP", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "COMP-KRC20": { - "coin": "COMP-KRC20", - "name": "Compound", - "coinpaprika_id": "comp-compoundd", - "coingecko_id": "compound-governance-token", - "nomics_id": "COMP", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "COMP-PLG20": { - "coin": "COMP-PLG20", - "name": "Compound", - "coinpaprika_id": "comp-compoundd", - "coingecko_id": "compound-governance-token", - "nomics_id": "COMP", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "CRYPTO": { - "coin": "CRYPTO", - "name": "CRYPTO", - "type": "Smart Chain", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10008", - "ws_url": "electrum1.cipig.net:30008" - }, - { - "url": "electrum2.cipig.net:10008", - "ws_url": "electrum2.cipig.net:30008" - }, - { - "url": "electrum3.cipig.net:10008", - "ws_url": "electrum3.cipig.net:30008" - } - ], - "explorer_url": [ - "https://crypto.explorer.dexstats.info/" - ], - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "CUMMIES-BEP20": { - "coin": "CUMMIES-BEP20", - "name": "CumRocket", - "nomics_id": "CUMMIES", - "coinpaprika_id": "cummies-cumrocket", - "coingecko_id": "cumrocket", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "DAI-AVX20": { - "coin": "DAI-AVX20", - "name": "Dai", - "coinpaprika_id": "dai-dai", - "coingecko_id": "dai", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "DAI-FTM20": { - "coin": "DAI-FTM20", - "name": "Dai", - "coinpaprika_id": "dai-dai", - "coingecko_id": "dai", - "nodes": [ - "https://rpc.ftm.tools/" - ], - "explorer_url": [ - "https://ftmscan.com/" - ], - "type": "FTM-20", - "active": false, - "currently_enabled": false - }, - "DAI-HCO20": { - "coin": "DAI-HCO20", - "name": "Dai", - "coinpaprika_id": "dai-dai", - "coingecko_id": "dai", - "nodes": [ - "https://http-mainnet.hecochain.com" - ], - "explorer_url": [ - "https://hecoinfo.com/" - ], - "type": "HecoChain", - "active": false, - "currently_enabled": false - }, - "DAI-HRC20": { - "coin": "DAI-HRC20", - "name": "Dai", - "coinpaprika_id": "dai-dai", - "coingecko_id": "dai", - "nodes": [ - "https://api.harmony.one", - "https://api.s0.t.hmny.io" - ], - "explorer_url": [ - "https://explorer.harmony.one/" - ], - "type": "HRC-20", - "active": false, - "currently_enabled": false - }, - "DAI-BEP20": { - "coin": "DAI-BEP20", - "name": "Dai", - "coinpaprika_id": "dai-dai", - "coingecko_id": "dai", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": true, - "currently_enabled": false - }, - "DAI-ERC20": { - "coin": "DAI-ERC20", - "name": "Dai", - "coinpaprika_id": "dai-dai", - "coingecko_id": "dai", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "DAI-MVR20": { - "coin": "DAI-MVR20", - "name": "Dai", - "coinpaprika_id": "dai-dai", - "coingecko_id": "dai", - "nodes": [ - "https://rpc.api.moonriver.moonbeam.network" - ], - "explorer_url": [ - "https://moonriver.moonscan.io/" - ], - "type": "Moonriver", - "active": false, - "currently_enabled": false - }, - "DAI-PLG20": { - "coin": "DAI-PLG20", - "name": "Dai", - "coinpaprika_id": "dai-dai", - "coingecko_id": "dai", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "DASH": { - "active": false, - "coin": "DASH", - "name": "Dash", - "coingecko_id": "dash", - "coinpaprika_id": "dash-dash", - "nomics_id": "DASH", - "currently_enabled": false, - "electrum": [ - { - "url": "electrum1.cipig.net:10061", - "ws_url": "electrum1.cipig.net:30061" - }, - { - "url": "electrum2.cipig.net:10061", - "ws_url": "electrum2.cipig.net:30061" - }, - { - "url": "electrum3.cipig.net:10061", - "ws_url": "electrum3.cipig.net:30061" - } - ], - "explorer_url": [ - "https://blockchair.com/dash/" - ], - "explorer_tx_url": "transaction/", - "type": "UTXO" - }, - "DUST": { - "coin": "DUST", - "name": "Dragonfairy", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "electrum": [ - { - "url": "51.222.85.227:10001", - "ws_url": "51.222.85.227:9001" - }, - { - "url": "78.141.233.64:10001", - "ws_url": "78.141.233.64:9001" - }, - { - "url": "192.248.166.207:10001", - "ws_url": "192.248.166.207:9001" - } - ], - "explorer_url": [ - "http://dragonfairy.gives/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false - }, - "DGB": { - "active": false, - "coin": "DGB", - "name": "DigiByte", - "coinpaprika_id": "dgb-digibyte", - "coingecko_id": "digibyte", - "nomics_id": "DGB", - "currently_enabled": false, - "electrum": [ - { - "url": "electrum1.cipig.net:10059", - "ws_url": "electrum1.cipig.net:30059" - }, - { - "url": "electrum2.cipig.net:10059", - "ws_url": "electrum2.cipig.net:30059" - }, - { - "url": "electrum3.cipig.net:10059", - "ws_url": "electrum3.cipig.net:30059" - } - ], - "explorer_url": [ - "https://digiexplorer.info/" - ], - "type": "UTXO" - }, - "DGC": { - "coin": "DGC", - "name": "Digitalcoin", - "coinpaprika_id": "dgc-digitalcoin", - "coingecko_id": "digitalcoin", - "nomics_id": "DGC", - "electrum": [ - { - "url": "electrumx.dgc.ewmcx.org:50001", - "protocol": "TCP" - }, - { - "url": "failover.dgc.ewmcx.biz:50002", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/dgc/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "DIA-ERC20": { - "coin": "DIA-ERC20", - "name": "DIAToken", - "coinpaprika_id": "dia-dia", - "coingecko_id": "dia-data", - "nomics_id": "DIA", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "DIA-BEP20": { - "coin": "DIA-BEP20", - "name": "DIAToken", - "coinpaprika_id": "dia-dia", - "coingecko_id": "dia-data", - "nomics_id": "DIA", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "DIMI": { - "coin": "DIMI", - "name": "Diminutive Coin", - "coinpaprika_id": "dimi-diminutive-coin", - "coingecko_id": "diminutive-coin", - "nomics_id": "DIMI", - "electrum": [ - { - "url": "electrumx1.diminutivecoin.com:50012", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "electrumx2.diminutivecoin.com:50012", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "https://explorer.diminutivecoin.com/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "DIMI-BEP20": { - "coin": "DIMI-BEP20", - "name": "DiminutiveCoin", - "coinpaprika_id": "dimi-diminutive-coin", - "coingecko_id": "diminutive-coin", - "nomics_id": "DIMI", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "DIMI-QRC20": { - "coin": "DIMI-QRC20", - "name": "DiminutiveCoin", - "coinpaprika_id": "dimi-diminutive-coin", - "coingecko_id": "diminutive-coin", - "nomics_id": "DIMI", - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20", - "active": false, - "currently_enabled": false - }, - "DODO-BEP20": { - "coin": "DODO-BEP20", - "name": "DODO", - "coinpaprika_id": "dodo-dodo", - "coingecko_id": "dodo", - "nomics_id": "DODO", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "DODO-ERC20": { - "coin": "DODO-ERC20", - "name": "DODO", - "coinpaprika_id": "dodo-dodo", - "coingecko_id": "dodo", - "nomics_id": "DODO", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "DODO-KRC20": { - "coin": "DODO-KRC20", - "name": "DODO", - "coinpaprika_id": "dodo-dodo", - "coingecko_id": "dodo", - "nomics_id": "DODO", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "DOGE": { - "coin": "DOGE", - "name": "Dogecoin", - "coinpaprika_id": "doge-dogecoin", - "coingecko_id": "dogecoin", - "electrum": [ - { - "url": "electrum1.cipig.net:10060", - "ws_url": "electrum1.cipig.net:30060" - }, - { - "url": "electrum2.cipig.net:10060", - "ws_url": "electrum2.cipig.net:30060" - }, - { - "url": "electrum3.cipig.net:10060", - "ws_url": "electrum3.cipig.net:30060" - } - ], - "explorer_url": [ - "https://dogechain.info/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "DOI": { - "coin": "DOI", - "name": "Doichain", - "coinpaprika_id": "doi-doicoin", - "coingecko_id": "doichain", - "nomics_id": "DOI", - "electrum": [ - { - "url": "itchy-jellyfish-89.doi.works:50002", - "protocol": "SSL", - "ws-url": "itchy-jellyfish-89.doi.works:50004" - }, - { - "url": "big-parrot-60.doi.works:50002", - "protocol": "SSL", - "ws-url": "big-parrot-60.doi.works:50004" - }, - { - "url": "ugly-bird-70.doi.works:50002", - "protocol": "SSL", - "ws-url": "ugly-bird-70.doi.works:50004" - }, - { - "url":"pink-deer-69.doi.works:50002", - "protocol": "SSL", - "ws-url": "pink-deer-69.doi.works:50004" - }, - { - "url":"pink-deer-69.doi.works:50001", - "protocol": "TCP" - } - ], - "explorer_url": [ - "https://explorer.doichain.org/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "DOGE-BEP20": { - "coin": "DOGE-BEP20", - "name": "Dogecoin", - "coinpaprika_id": "doge-dogecoin", - "coingecko_id": "dogecoin", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "DOGEDASH-BEP20": { - "coin": "DOGEDASH-BEP20", - "name": "Doge Dash", - "nomics_id": "DOGEDASH", - "coinpaprika_id": "dogedash-doge-dash", - "coingecko_id": "doge-dash", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "DOGGY-BEP20": { - "coin": "DOGGY-BEP20", - "name": "Doggy", - "nomics_id": "DOGGY", - "coinpaprika_id": "doggy-doggy", - "coingecko_id": "doggy", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "DOT-BEP20": { - "coin": "DOT-BEP20", - "name": "Polkadot", - "coinpaprika_id": "dot-polkadot", - "coingecko_id": "polkadot", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "DOT-HCO20": { - "coin": "DOT-HCO20", - "name": "Polkadot", - "coinpaprika_id": "dot-polkadot", - "coingecko_id": "polkadot", - "nodes": [ - "https://http-mainnet.hecochain.com" - ], - "explorer_url": [ - "https://hecoinfo.com/" - ], - "type": "HecoChain", - "active": false, - "currently_enabled": false - }, - "DP": { - "coin": "DP", - "name": "DigitalPrice", - "coinpaprika_id": "dp-digitalprice", - "coingecko_id": "digitalprice", - "nomics_id": "DP", - "electrum": [ - { - "url": "1.eu.dp.electrum.dexstats.info:10021" - } - ], - "explorer_url": [ - "https://dp.explorer.dexstats.info/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false - }, - "ECA": { - "coin": "ECA", - "name": "Electra", - "coinpaprika_id": "eca-electra", - "coingecko_id": "electra", - "nomics_id": "ECA", - "electrum": [ - { - "url": "electrum1.cipig.net:10052", - "ws_url": "electrum1.cipig.net:30052" - }, - { - "url": "electrum2.cipig.net:10052", - "ws_url": "electrum2.cipig.net:30052" - }, - { - "url": "electrum3.cipig.net:10052", - "ws_url": "electrum3.cipig.net:30052" - } - ], - "explorer_url": [ - "https://eca.ccore.online/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "EFL": { - "coin": "EFL", - "name": "e-Gulden", - "coinpaprika_id": "efl-e-gulden", - "coingecko_id": "electronicgulden", - "nomics_id": "EFL", - "electrum": [ - { - "url": "holland.ecoincore.com:11017", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "lenoir.ecoincore.com:11017", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "electrum1.egulden.org:50002", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "electrum2.egulden.org:50002", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "electrum5.egulden.org:11017", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/efl/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "EGLD-BEP20": { - "coin": "EGLD-BEP20", - "name": "Elrond", - "coinpaprika_id": "egld-elrond", - "coingecko_id": "elrond-erd-2", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "ELF-BEP20": { - "coin": "ELF-BEP20", - "name": "aelf", - "coinpaprika_id": "elf-aelf", - "coingecko_id": "aelf", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "ELF-ERC20": { - "coin": "ELF-ERC20", - "name": "aelf", - "coinpaprika_id": "elf-aelf", - "coingecko_id": "aelf", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "EMC2": { - "coin": "EMC2", - "name": "Einsteinium", - "coinpaprika_id": "emc2-einsteinium", - "coingecko_id": "einsteinium", - "nomics_id": "EMC2", - "electrum": [ - { - "url": "electrum1.cipig.net:10062", - "ws_url": "electrum1.cipig.net:30062" - }, - { - "url": "electrum2.cipig.net:10062", - "ws_url": "electrum2.cipig.net:30062" - }, - { - "url": "electrum3.cipig.net:10062", - "ws_url": "electrum3.cipig.net:30062" - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/emc2/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "EOS-BEP20": { - "coin": "EOS-BEP20", - "name": "EOS", - "coinpaprika_id": "eos-eos", - "coingecko_id": "eos", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "ETC": { - "coin": "ETC", - "name": "Ethereum Classic", - "coinpaprika_id": "etc-ethereum-classic", - "coingecko_id": "ethereum-classic", - "nodes": [ - "https://www.ethercluster.com/etc" - ], - "explorer_url": [ - "https://blockscout.com/etc/mainnet/" - ], - "type": "Ethereum Classic", - "active": false, - "currently_enabled": false - }, - "ETC-BEP20": { - "coin": "ETC-BEP20", - "name": "Ethereum Classic", - "coinpaprika_id": "etc-ethereum-classic", - "coingecko_id": "ethereum-classic", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "FET-ERC20": { - "coin": "FET-ERC20", - "name": "Fetch.ai", - "coinpaprika_id": "fetch-ai", - "coingecko_id": "fetch-ai", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "FET-BEP20": { - "coin": "FET-BEP20", - "name": "Fetch.ai", - "coinpaprika_id": "fetch-ai", - "coingecko_id": "fetch-ai", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "FET-PLG20": { - "coin": "FET-PLG20", - "name": "Fetch.ai", - "coinpaprika_id": "fetch-ai", - "coingecko_id": "fetch-ai", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "FIL-BEP20": { - "coin": "FIL-BEP20", - "name": "Filecoin", - "coinpaprika_id": "fil-filecoin", - "coingecko_id": "filecoin", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "FIL-HCO20": { - "coin": "FIL-HCO20", - "name": "Filecoin", - "coinpaprika_id": "fil-filecoin", - "coingecko_id": "filecoin", - "nodes": [ - "https://http-mainnet.hecochain.com" - ], - "explorer_url": [ - "https://hecoinfo.com/" - ], - "type": "HecoChain", - "active": false, - "currently_enabled": false - }, - "FLOKI-BEP20": { - "coin": "FLOKI-BEP20", - "name": "Floki Inu", - "nomics_id": "FLOKI15", - "coinpaprika_id": "floki-floki-inu", - "coingecko_id": "floki-inu", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "FLUX": { - "coin": "FLUX", - "name": "Flux", - "coinpaprika_id": "zel-zelcash", - "coingecko_id": "zelcash", - "nomics_id": "ZEL", - "electrum": [ - { - "url": "electrumx.runonflux.io:50002", - "protocol": "SSL", - "disable_cert_verification": true, - "ws_url": "electrumx.runonflux.io:50004" - }, - { - "url": "electrumx2.runonflux.io:50001", - "protocol": "TCP", - "ws_url": "electrumx2.runonflux.io:50004" - } - ], - "explorer_url": [ - "https://explorer.runonflux.io/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "FLUX-ERC20": { - "coin": "FLUX-ERC20", - "name": "Flux", - "coinpaprika_id": "zel-zelcash", - "coingecko_id": "zelcash", - "nomics_id": "ZEL", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "FLUX-BEP20": { - "coin": "FLUX-BEP20", - "name": "Flux", - "coinpaprika_id": "zel-zelcash", - "coingecko_id": "zelcash", - "nomics_id": "ZEL", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "FIRO": { - "coin": "FIRO", - "name": "Firo", - "coinpaprika_id": "firo-firo", - "coingecko_id": "zcoin", - "nomics_id": "FIRO", - "electrum": [ - { - "url": "electrumx.firo.org:50001", - "protocol": "TCP" - }, - { - "url": "electrumx01.firo.org:50001" - }, - { - "url": "electrumx02.firo.org:50001" - }, - { - "url": "electrumx03.firo.org:50001" - } - ], - "explorer_url": [ - "https://explorer.firo.org/" - ], - "type": "UTXO", - "active": true, - "currently_enabled": false - }, - "FIRO-BEP20": { - "coin": "FIRO-BEP20", - "name": "Firo", - "coinpaprika_id": "firo-firo", - "coingecko_id": "zcoin", - "nomics_id": "FIRO", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": true, - "currently_enabled": false - }, - "FJC": { - "coin": "FJC", - "name": "Fujicoin", - "coinpaprika_id": "fjc-fujicoin", - "coingecko_id": "fujicoin", - "nomics_id": "FJC", - "electrum": [ - { - "url": "electrumx1.fujicoin.org:50001", - "protocol": "TCP" - }, - { - "url": "electrumx2.fujicoin.org:50001", - "protocol": "TCP" - } - ], - "explorer_url": [ - "https://explorer.fujicoin.org/" - ], - "explorer_tx_url": "tx/", - "explorer_address_url": "address/", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "FJC-BEP20": { - "coin": "FJC-BEP20", - "name": "Fujicoin", - "coinpaprika_id": "fjc-fujicoin", - "coingecko_id": "fujicoin", - "nomics_id": "FJC", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "FJCB": { - "coin": "FJCB", - "name": "FJCB Fujicoin", - "coinpaprika_id": "fjcb-fjcb-fujicoin", - "coingecko_id": "test-coin", - "nomics_id": "FJCB", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "FLOW-BEP20": { - "coin": "FLOW-BEP20", - "name": "Flow", - "coinpaprika_id": "flow-flow", - "coingecko_id": "flow", - "nomics_id": "FLOW2", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "STFIRO": { - "coin": "STFIRO", - "name": "StakedFIRO", - "coinpaprika_id": "test-coin", - "coingecko_id": "stakehound", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": true, - "currently_enabled": false - }, - "FTC": { - "coin": "FTC", - "name": "Feathercoin", - "coinpaprika_id": "ftc-feathercoin", - "coingecko_id": "feathercoin", - "nomics_id": "FTC", - "electrum": [ - { - "url": "electrum1.cipig.net:10054", - "ws_url": "electrum1.cipig.net:30054" - }, - { - "url": "electrum2.cipig.net:10054", - "ws_url": "electrum2.cipig.net:30054" - }, - { - "url": "electrum3.cipig.net:10054", - "ws_url": "electrum3.cipig.net:30054" - } - ], - "explorer_url": [ - "http://explorer.feathercoin.com/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "FTMT": { - "coin": "FTMT", - "name": "Fantom Testnet", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "is_testnet": true, - "nodes": [ - "https://rpc.testnet.fantom.network/" - ], - "explorer_url": [ - "https://testnet.ftmscan.com/" - ], - "type": "FTM-20", - "active": false, - "currently_enabled": false - }, - "FTM": { - "coin": "FTM", - "name": "Fantom", - "coinpaprika_id": "ftm-fantom", - "coingecko_id": "fantom", - "nodes": [ - "https://rpc.ftm.tools/" - ], - "explorer_url": [ - "https://ftmscan.com/" - ], - "type": "FTM-20", - "active": false, - "currently_enabled": false - }, - "FTM-BEP20": { - "coin": "FTM-BEP20", - "name": "Fantom", - "coinpaprika_id": "ftm-fantom", - "coingecko_id": "fantom", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "FTM-ERC20": { - "coin": "FTM-ERC20", - "name": "Fantom", - "coinpaprika_id": "ftm-fantom", - "coingecko_id": "fantom", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "GALA-ERC20": { - "coin": "GALA-ERC20", - "name": "Gala", - "coinpaprika_id": "gala-gala", - "coingecko_id": "gala", - "nomics_id": "GALA", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "GALA-BEP20": { - "coin": "GALA-BEP20", - "name": "Gala", - "coinpaprika_id": "gala-gala", - "coingecko_id": "gala", - "nomics_id": "GALA", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "GLEEC": { - "coin": "GLEEC", - "name": "Gleec", - "coinpaprika_id": "gleec-gleec-coin", - "coingecko_id": "gleec-coin", - "nomics_id": "GLEEC", - "electrum": [ - { - "url": "electrum1.cipig.net:10022", - "ws_url": "electrum1.cipig.net:30022" - }, - { - "url": "electrum2.cipig.net:10022", - "ws_url": "electrum2.cipig.net:30022" - }, - { - "url": "electrum3.cipig.net:10022", - "ws_url": "electrum3.cipig.net:30022" - } - ], - "explorer_url": [ - "https://gleec.explorer.dexstats.info/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false - }, - "GM-BEP20": { - "coin": "GM-BEP20", - "name": "GM Wagmi", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "GRMS": { - "coin": "GRMS", - "type": "Smart Chain", - "name": "GRMS", - "coingecko_id": "test-coin", - "coinpaprika_id": "grms-grms", - "nomics_id": "GRMS", - "electrum": [ - { - "url": "89.108.102.188:17485" - }, - { - "url": "31.31.199.13:17485" - } - ], - "explorer_url": [ - "https://explorer.grms.pw/" - ], - "active": false, - "currently_enabled": false - }, - "GRS": { - "coin": "GRS", - "name": "Groestlcoin", - "coinpaprika_id": "grs-groestlcoin", - "coingecko_id": "groestlcoin", - "nomics_id": "GRS", - "electrum": [ - { - "url": "electrum11.groestlcoin.org:50001" - }, - { - "url": "electrum12.groestlcoin.org:50001" - }, - { - "url": "electrum13.groestlcoin.org:50001" - }, - { - "url": "electrum14.groestlcoin.org:50001" - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/grs/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "GRT-AVX20": { - "coin": "GRT-AVX20", - "name": "The Graph", - "coinpaprika_id": "grt-the-graph", - "coingecko_id": "the-graph", - "nomics_id": "GRT", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "GRT-ERC20": { - "coin": "GRT-ERC20", - "name": "The Graph", - "coinpaprika_id": "grt-the-graph", - "coingecko_id": "the-graph", - "nomics_id": "GRT", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "GRT-KRC20": { - "coin": "GRT-KRC20", - "name": "The Graph", - "coinpaprika_id": "grt-the-graph", - "coingecko_id": "the-graph", - "nomics_id": "GRT", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "GRT-PLG20": { - "coin": "GRT-PLG20", - "name": "The Graph", - "coinpaprika_id": "grt-the-graph", - "coingecko_id": "the-graph", - "nomics_id": "GRT", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "HODL": { - "coin": "HODL", - "name": "HODL", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10009", - "ws_url": "electrum1.cipig.net:30009" - }, - { - "url": "electrum2.cipig.net:10009", - "ws_url": "electrum2.cipig.net:30009" - }, - { - "url": "electrum3.cipig.net:10009", - "ws_url": "electrum3.cipig.net:30009" - } - ], - "explorer_url": [ - "https://hodl.explorer.dexstats.info/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "INJ-BEP20": { - "coin": "INJ-BEP20", - "name": "Injective Protocol", - "coinpaprika_id": "inj-injective-protocol", - "coingecko_id": "injective-protocol", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "INJ-ERC20": { - "coin": "INJ-ERC20", - "name": "Injective Protocol", - "coinpaprika_id": "inj-injective-protocol", - "coingecko_id": "injective-protocol", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "IOTA-BEP20": { - "coin": "IOTA-BEP20", - "name": "IOTA", - "coinpaprika_id": "miota-iota", - "coingecko_id": "iota", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "IOTX-BEP20": { - "coin": "IOTX-BEP20", - "name": "IoTeX", - "coinpaprika_id": "iotx-iotex", - "coingecko_id": "iotex", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "IOTX-PLG20": { - "coin": "IOTX-PLG20", - "name": "IoTeX", - "coinpaprika_id": "iotx-iotex", - "coingecko_id": "iotex", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "JCHF-ERC20": { - "coin": "JCHF-ERC20", - "name": "Jarvis Swiss Franc", - "forex_id": "CHF", - "coinpaprika_id": "test-coin", - "coingecko_id": "jarvis-synthetic-swiss-franc", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "JCHF-PLG20": { - "coin": "JCHF-PLG20", - "name": "Jarvis Swiss Franc", - "forex_id": "CHF", - "coinpaprika_id": "test-coin", - "coingecko_id": "jarvis-synthetic-swiss-franc", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "JEUR-ERC20": { - "coin": "JEUR-ERC20", - "name": "Jarvis Euro", - "forex_id": "EUR", - "coinpaprika_id": "test-coin", - "coingecko_id": "jarvis-synthetic-euro", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "JEUR-PLG20": { - "coin": "JEUR-PLG20", - "name": "Jarvis Euro", - "forex_id": "EUR", - "coinpaprika_id": "test-coin", - "coingecko_id": "jarvis-synthetic-euro", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "JGBP-ERC20": { - "coin": "JGBP-ERC20", - "name": "Jarvis British Pound", - "forex_id": "GBP", - "coinpaprika_id": "test-coin", - "coingecko_id": "jarvis-synthetic-british-pound", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "JGBP-PLG20": { - "coin": "JGBP-PLG20", - "name": "Jarvis British Pound", - "forex_id": "GBP", - "coinpaprika_id": "test-coin", - "coingecko_id": "jarvis-synthetic-british-pound", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "JPYC-ERC20": { - "coin": "JPYC-ERC20", - "name": "JPY Coin", - "forex_id": "JPY", - "coinpaprika_id": "test-coin", - "coingecko_id": "jpyc", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "JPYC-PLG20": { - "coin": "JPYC-PLG20", - "name": "JPY Coin", - "forex_id": "JPY", - "coinpaprika_id": "test-coin", - "coingecko_id": "jpyc", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "JRT-ERC20": { - "coin": "JRT-ERC20", - "name": "Jarvis Reward Token", - "coinpaprika_id": "jrt-jarvis-reward-token", - "coingecko_id": "jarvis-reward-token", - "nomics_id": "JRT", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "JRT-PLG20": { - "coin": "JRT-PLG20", - "name": "Jarvis Reward Token", - "coinpaprika_id": "jrt-jarvis-reward-token", - "coingecko_id": "jarvis-reward-token", - "nomics_id": "JRT", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "JSTR": { - "coin": "JSTR", - "name": "Ropsten test ERC20", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "is_testnet": true, - "nodes": [ - "https://ropsten.infura.io/v3/1d059a9aca7d49a3a380c71068bffb1c" - ], - "explorer_url": [ - "https://ropsten.etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "JUMBLR": { - "coin": "JUMBLR", - "name": "JUMBLR", - "type": "Smart Chain", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10004", - "ws_url": "electrum1.cipig.net:30004" - }, - { - "url": "electrum2.cipig.net:10004", - "ws_url": "electrum2.cipig.net:30004" - }, - { - "url": "electrum3.cipig.net:10004", - "ws_url": "electrum3.cipig.net:30004" - } - ], - "explorer_url": [ - "https://jumblr.explorer.dexstats.info/" - ], - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "KNC-BEP20": { - "coin": "KNC-BEP20", - "name": "Kyber Network", - "coinpaprika_id": "knc-kyber-network", - "coingecko_id": "kyber-network-crystal", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "KNC-ERC20": { - "coin": "KNC-ERC20", - "name": "Kyber Network", - "coinpaprika_id": "knc-kyber-network", - "coingecko_id": "kyber-network-crystal", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "KOIN": { - "coin": "KOIN", - "name": "Koinon", - "coinpaprika_id": "koin-koinon", - "coingecko_id": "koinon", - "nomics_id": "KOIN", - "electrum": [ - { - "url": "electrum1.cipig.net:10024", - "ws_url": "electrum1.cipig.net:30024" - }, - { - "url": "electrum2.cipig.net:10024", - "ws_url": "electrum2.cipig.net:30024" - }, - { - "url": "electrum3.cipig.net:10024", - "ws_url": "electrum3.cipig.net:30024" - } - ], - "explorer_url": [ - "https://koin.explorer.dexstats.info/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false - }, - "LBC": { - "coin": "LBC", - "name": "LBRY Credits", - "coinpaprika_id": "lbc-lbry-credits", - "coingecko_id": "lbry-credits", - "nomics_id": "LBC", - "electrum": [ - { - "url": "spv1.lbry.com:50001" - }, - { - "url": "spv17.lbry.com:50001" - }, - { - "url": "spv19.lbry.com:50001" - } - ], - "explorer_url": [ - "https://explorer.lbry.com/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "LCC": { - "coin": "LCC", - "name": "Litecoin Cash", - "coinpaprika_id": "lcc-litecoin-cash", - "coingecko_id": "litecoin-cash", - "nomics_id": "LCC", - "electrum": [ - { - "url": "188.166.117.139:50001" - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/lcc/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "LTC": { - "active": false, - "coin": "LTC", - "coingecko_id": "litecoin", - "coinpaprika_id": "ltc-litecoin", - "nomics_id": "LTC", - "currently_enabled": false, - "electrum": [ - { - "url": "electrum1.cipig.net:10063", - "ws_url": "electrum1.cipig.net:30063" - }, - { - "url": "electrum2.cipig.net:10063", - "ws_url": "electrum2.cipig.net:30063" - }, - { - "url": "electrum3.cipig.net:10063", - "ws_url": "electrum3.cipig.net:30063" - } - ], - "explorer_url": [ - "https://blockexplorer.one/litecoin/mainnet/" - ], - "type": "UTXO", - "name": "Litecoin", - "is_segwit_on": false - }, - "LUNA-ERC20": { - "coin": "LUNA-ERC20", - "name": "Terra", - "coinpaprika_id": "luna-terra", - "coingecko_id": "terra-luna", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "LUNA-BEP20": { - "coin": "LUNA-BEP20", - "name": "Terra", - "coinpaprika_id": "luna-terra", - "coingecko_id": "terra-luna", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "LUNA-HRC20": { - "coin": "LUNA-HRC20", - "name": "Terra", - "coinpaprika_id": "luna-terra", - "coingecko_id": "terra-luna", - "nodes": [ - "https://api.harmony.one", - "https://api.s0.t.hmny.io" - ], - "explorer_url": [ - "https://explorer.harmony.one/" - ], - "type": "HRC-20", - "active": false, - "currently_enabled": false - }, - "LUNA-PLG20": { - "coin": "LUNA-PLG20", - "name": "Terra", - "coinpaprika_id": "luna-terra", - "coingecko_id": "terra-luna", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "LYNX": { - "coin": "LYNX", - "name": "Lynx", - "coinpaprika_id": "lynx-lynx", - "coingecko_id": "lynx", - "nomics_id": "LYNX", - "electrum": [ - { - "url": "electrum.getlynx.io:50002", - "protocol": "SSL", - "disable_cert_verification": false - }, - { - "url": "electrum.logware.us:50002", - "protocol": "SSL", - "disable_cert_verification": false - }, - { - "url": "electrum.logware.club:50002", - "protocol": "SSL", - "disable_cert_verification": false - }, - { - "url": "electrum.logware.io:50002", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/lynx/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "LTFN": { - "coin": "LTFN", - "name": "Litecoin Finance", - "coinpaprika_id": "test-coin", - "coingecko_id": "litecoin-finance", - "nomics_id": "LTFN", - "electrum": [ - { - "url": "eltfnx.scalaris.info:30001" - }, - { - "url": "eltfnx6.scalaris.info:30001" - }, - { - "url": "eltfnx7.scalaris.info:30001" - } - ], - "explorer_url": [ - "https://openchains.info/coin/ltfn/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "MATICTEST": { - "coin": "MATICTEST", - "name": "Matic Testnet", - "is_testnet": true, - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "nodes": [ - "https://rpc-mumbai.matic.today", - "https://matic-mumbai.chainstacklabs.com", - "https://rpc-mumbai.maticvigil.com" - ], - "explorer_url": [ - "https://mumbai.polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "MATIC": { - "coin": "MATIC", - "name": "Polygon", - "coinpaprika_id": "matic-matic-network", - "coingecko_id": "matic-network", - "nomics_id": "MATIC", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "MATIC-BEP20": { - "coin": "MATIC-BEP20", - "name": "Polygon", - "coinpaprika_id": "matic-matic-network", - "coingecko_id": "matic-network", - "nomics_id": "MATIC", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "MATIC-ERC20": { - "coin": "MATIC-ERC20", - "name": "Polygon", - "coinpaprika_id": "matic-matic-network", - "coingecko_id": "matic-network", - "nomics_id": "MATIC", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "MATIC-HCO20": { - "coin": "MATIC-HCO20", - "name": "Polygon", - "coinpaprika_id": "matic-matic-network", - "coingecko_id": "matic-network", - "nomics_id": "MATIC", - "nodes": [ - "https://http-mainnet.hecochain.com" - ], - "explorer_url": [ - "https://hecoinfo.com/" - ], - "type": "HecoChain", - "active": false, - "currently_enabled": false - }, - "MATIC-HRC20": { - "coin": "MATIC-HRC20", - "name": "Polygon", - "coinpaprika_id": "matic-matic-network", - "coingecko_id": "matic-network", - "nomics_id": "MATIC", - "nodes": [ - "https://api.harmony.one", - "https://api.s0.t.hmny.io" - ], - "explorer_url": [ - "https://explorer.harmony.one/" - ], - "type": "HRC-20", - "active": false, - "currently_enabled": false - }, - "MATIC-KRC20": { - "coin": "MATIC-KRC20", - "name": "Polygon", - "coinpaprika_id": "matic-matic-network", - "coingecko_id": "matic-network", - "nomics_id": "MATIC", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "MCL": { - "coin": "MCL", - "name": "Marmara Credit Loops", - "coingecko_id": "test-coin", - "coinpaprika_id": "mcl-marmara-credit-loops", - "nomics_id": "MCL", - "electrum": [ - { - "url": "electrum1.cipig.net:10023", - "ws_url": "electrum1.cipig.net:30023" - }, - { - "url": "electrum2.cipig.net:10023", - "ws_url": "electrum2.cipig.net:30023" - }, - { - "url": "electrum3.cipig.net:10023", - "ws_url": "electrum3.cipig.net:30023" - } - ], - "explorer_url": [ - "http://explorer.marmara.io/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false - }, - "GMS": { - "coin": "GMS", - "type": "Smart Chain", - "name": "GMSmining", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "electrum.gmsmining.pw:17485" - }, - { - "url": "electrum1.gmsmining.pw:17485" - } - ], - "explorer_url": [ - "https://explorer.gmsmining.pw/" - ], - "active": false, - "currently_enabled": false - }, - "MIR-ERC20": { - "coin": "MIR-ERC20", - "name": "Mirror Protocol", - "coinpaprika_id": "mir-mirror-protocol", - "coingecko_id": "mirror-protocol", - "nomics_id": "MIRROR", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "MIR-BEP20": { - "coin": "MIR-BEP20", - "name": "Mirror Protocol", - "coinpaprika_id": "mir-mirror-protocol", - "coingecko_id": "mirror-protocol", - "nomics_id": "MIRROR", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "MM-ERC20": { - "coin": "MM-ERC20", - "name": "Million", - "coinpaprika_id": "mm-million", - "coingecko_id": "million", - "nomics_id": "MM4", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "MM-AVX20": { - "coin": "MM-AVX20", - "name": "Million", - "coinpaprika_id": "mm-million", - "coingecko_id": "million", - "nomics_id": "MM4", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "MM-BEP20": { - "coin": "MM-BEP20", - "name": "Million", - "coinpaprika_id": "mm-million", - "coingecko_id": "million", - "nomics_id": "MM4", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "MM-MVR20": { - "coin": "MM-MVR20", - "name": "Million", - "coinpaprika_id": "mm-million", - "coingecko_id": "million", - "nomics_id": "MM4", - "nodes": [ - "https://rpc.api.moonriver.moonbeam.network" - ], - "explorer_url": [ - "https://moonriver.moonscan.io/" - ], - "type": "Moonriver", - "active": false, - "currently_enabled": false - }, - "MM-PLG20": { - "coin": "MM-PLG20", - "name": "Million", - "coinpaprika_id": "mm-million", - "coingecko_id": "million", - "nomics_id": "MM4", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "MSHARK": { - "coin": "MSHARK", - "name": "MiliShark", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10013", - "ws_url": "electrum1.cipig.net:30013" - }, - { - "url": "electrum2.cipig.net:10013", - "ws_url": "electrum2.cipig.net:30013" - }, - { - "url": "electrum3.cipig.net:10013", - "ws_url": "electrum3.cipig.net:30013" - } - ], - "explorer_url": [ - "https://mshark.explorer.dexstats.info/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "NEAR-BEP20": { - "coin": "NEAR-BEP20", - "name": "NEAR Protocol", - "coinpaprika_id": "near-near-protocol", - "coingecko_id": "near", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "OCEAN-BEP20": { - "coin": "OCEAN-BEP20", - "name": "Ocean Protocol", - "coinpaprika_id": "ocean-ocean-protocol", - "coingecko_id": "ocean-protocol", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "OCEAN-ERC20": { - "coin": "OCEAN-ERC20", - "name": "Ocean Protocol", - "coinpaprika_id": "ocean-ocean-protocol", - "coingecko_id": "ocean-protocol", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "OCEAN-PLG20": { - "coin": "OCEAN-PLG20", - "name": "Ocean Protocol", - "coinpaprika_id": "ocean-ocean-protocol", - "coingecko_id": "ocean-protocol", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "ONE": { - "active": false, - "coin": "ONE", - "coingecko_id": "harmony", - "coinpaprika_id": "one-harmony", - "currently_enabled": false, - "nodes": [ - "https://api.harmony.one", - "https://api.s0.t.hmny.io" - ], - "explorer_url": [ - "https://explorer.harmony.one/" - ], - "type": "HRC-20", - "name": "Harmony" - }, - "ONT-BEP20": { - "coin": "ONT-BEP20", - "name": "Ontology", - "coinpaprika_id": "ont-ontology", - "coingecko_id": "ontology", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "PAX-BEP20": { - "coin": "PAX-BEP20", - "name": "Paxos Standard", - "coinpaprika_id": "pax-paxos-standard-token", - "coingecko_id": "paxos-standard", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "PAX-ERC20": { - "coin": "PAX-ERC20", - "name": "Paxos Standard", - "coinpaprika_id": "pax-paxos-standard-token", - "coingecko_id": "paxos-standard", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "PAX-KRC20": { - "coin": "PAX-KRC20", - "name": "Paxos Standard", - "coinpaprika_id": "pax-paxos-standard-token", - "coingecko_id": "paxos-standard", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "PAX-PLG20": { - "coin": "PAX-PLG20", - "name": "Paxos Standard", - "coinpaprika_id": "pax-paxos-standard-token", - "coingecko_id": "paxos-standard", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "PAXG-BEP20": { - "coin": "PAXG-BEP20", - "name": "PAX Gold", - "coinpaprika_id": "paxg-pax-gold", - "coingecko_id": "pax-gold", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "PAXG-ERC20": { - "coin": "PAXG-ERC20", - "name": "PAX Gold", - "coinpaprika_id": "paxg-pax-gold", - "coingecko_id": "pax-gold", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "PAXG-PLG20": { - "coin": "PAXG-PLG20", - "name": "PAX Gold", - "coinpaprika_id": "paxg-pax-gold", - "coingecko_id": "pax-gold", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "KCS": { - "active": false, - "coin": "KCS", - "coingecko_id": "kucoin-shares", - "coinpaprika_id": "kcs-kucoin-token", - "nomics_id": "KCS", - "currently_enabled": false, - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "name": "KuCoin Token" - }, - "MOVR": { - "active": false, - "coin": "MOVR", - "coingecko_id": "moonriver", - "coinpaprika_id": "movr-moonriver", - "nomics_id": "MOVR", - "currently_enabled": false, - "nodes": [ - "https://rpc.api.moonriver.moonbeam.network" - ], - "explorer_url": [ - "https://moonriver.moonscan.io/" - ], - "type": "Moonriver", - "name": "Moonriver" - }, - "GLMR": { - "active": false, - "coin": "GLMR", - "coingecko_id": "moonbeam", - "coinpaprika_id": "glmr-moonbeam", - "nomics_id": "GLMR", - "currently_enabled": false, - "nodes": [ - "https://rpc.api.moonbeam.network" - ], - "explorer_url": [ - "https://moonscan.io/" - ], - "type": "Moonbeam", - "name": "Moonbeam" - }, - "ETH": { - "active": true, - "coin": "ETH", - "coingecko_id": "ethereum", - "coinpaprika_id": "eth-ethereum", - "nomics_id": "ETH", - "currently_enabled": false, - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "name": "Ethereum" - }, - "ETH-BEP20": { - "coin": "ETH-BEP20", - "name": "Ethereum", - "coinpaprika_id": "eth-ethereum", - "coingecko_id": "ethereum", - "nomics_id": "ETH", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "ETH-AVX20": { - "coin": "ETH-AVX20", - "name": "Ethereum", - "coinpaprika_id": "eth-ethereum", - "coingecko_id": "ethereum", - "nomics_id": "ETH", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "ETH-FTM20": { - "coin": "ETH-FTM20", - "name": "Ethereum", - "coinpaprika_id": "eth-ethereum", - "coingecko_id": "ethereum", - "nomics_id": "ETH", - "nodes": [ - "https://rpc.ftm.tools/" - ], - "explorer_url": [ - "https://ftmscan.com/" - ], - "type": "FTM-20", - "active": false, - "currently_enabled": false - }, - "ETH-HCO20": { - "coin": "ETH-HCO20", - "name": "Ethereum", - "coinpaprika_id": "eth-ethereum", - "coingecko_id": "ethereum", - "nomics_id": "ETH", - "nodes": [ - "https://http-mainnet.hecochain.com" - ], - "explorer_url": [ - "https://hecoinfo.com/" - ], - "type": "HecoChain", - "active": false, - "currently_enabled": false - }, - "ETH-HRC20": { - "coin": "ETH-HRC20", - "name": "Ethereum", - "coinpaprika_id": "eth-ethereum", - "coingecko_id": "ethereum", - "nomics_id": "ETH", - "nodes": [ - "https://api.harmony.one", - "https://api.s0.t.hmny.io" - ], - "explorer_url": [ - "https://explorer.harmony.one/" - ], - "type": "HRC-20", - "active": false, - "currently_enabled": false - }, - "ETH-KRC20": { - "coin": "ETH-KRC20", - "name": "Ethereum", - "coinpaprika_id": "eth-ethereum", - "coingecko_id": "ethereum", - "nomics_id": "ETH", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "ETH-PLG20": { - "coin": "ETH-PLG20", - "name": "Ethereum", - "coinpaprika_id": "eth-ethereum", - "coingecko_id": "ethereum", - "nomics_id": "ETH", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "ETH-ARB20": { - "active": false, - "wallet_only": true, - "coin": "ETH-ARB20", - "coingecko_id": "ethereum", - "coinpaprika_id": "eth-ethereum", - "nomics_id": "ETH", - "currently_enabled": false, - "nodes": [ - "https://arb1.arbitrum.io/rpc" - ], - "explorer_url": [ - "https://arbiscan.io/" - ], - "type": "Arbitrum", - "name": "Ethereum" - }, - "ETHK-OPT20": { - "active": false, - "wallet_only": true, - "coin": "ETHK-OPT20", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "currently_enabled": false, - "is_testnet": true, - "nodes": [ - "https://kovan.optimism.io" - ], - "explorer_url": [ - "https://kovan-optimistic.etherscan.io/" - ], - "type": "Optimism", - "name": "EthKovan Optimism (Testnet)" - }, - "ETHR-ARB20": { - "active": false, - "wallet_only": true, - "coin": "ETHR-ARB20", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "currently_enabled": false, - "is_testnet": true, - "nodes": [ - "https://rinkeby.arbitrum.io/rpc" - ], - "explorer_url": [ - "https://rinkeby-explorer.arbitrum.io/#/" - ], - "type": "Arbitrum", - "name": "EthRinkeby Arbitrum (Testnet)" - }, - "ETHR": { - "active": false, - "coin": "ETHR", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "currently_enabled": false, - "is_testnet": true, - "nodes": [ - "https://ropsten.infura.io/v3/1d059a9aca7d49a3a380c71068bffb1c" - ], - "explorer_url": [ - "https://ropsten.etherscan.io/" - ], - "type": "ERC-20", - "name": "Ethereum Ropsten (Testnet)" - }, - "UIS": { - "coin": "UIS", - "name": "Unitus", - "coinpaprika_id": "uis-unitus", - "coingecko_id": "unitus", - "nomics_id": "UIS", - "electrum": [ - { - "url": "failover.trc-uis.ewmcx.biz:50002", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "electrumx.uis.ewmcx.info:50001" - } - ], - "explorer_url": [ - "https://explorer.unitus.network/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "UNO": { - "coin": "UNO", - "name": "Unobtanium", - "coinpaprika_id": "uno-unobtanium", - "coingecko_id": "unobtanium", - "nomics_id": "UNO", - "electrum": [ - { - "url": "uno-main.coinmunity.gold:50002", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "uno-bkp.coinmunity.gold:50002", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/uno/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "USDC-AVX20": { - "coin": "USDC-AVX20", - "name": "USD Coin", - "coinpaprika_id": "usdc-usd-coin", - "coingecko_id": "usd-coin", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "USDC-MVR20": { - "coin": "USDC-MVR20", - "name": "USD Coin", - "coinpaprika_id": "usdc-usd-coin", - "coingecko_id": "usd-coin", - "nodes": [ - "https://rpc.api.moonriver.moonbeam.network" - ], - "explorer_url": [ - "https://moonriver.moonscan.io/" - ], - "type": "Moonriver", - "active": false, - "currently_enabled": false - }, - "USDC-FTM20": { - "coin": "USDC-FTM20", - "name": "USD Coin", - "coinpaprika_id": "usdc-usd-coin", - "coingecko_id": "usd-coin", - "nodes": [ - "https://rpc.ftm.tools/" - ], - "explorer_url": [ - "https://ftmscan.com/" - ], - "type": "FTM-20", - "active": false, - "currently_enabled": false - }, - "USDC-BEP20": { - "coin": "USDC-BEP20", - "name": "USD Coin", - "coinpaprika_id": "usdc-usd-coin", - "coingecko_id": "usd-coin", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": true, - "currently_enabled": false - }, - "USDC-ERC20": { - "coin": "USDC-ERC20", - "name": "USD Coin", - "coinpaprika_id": "usdc-usd-coin", - "coingecko_id": "usd-coin", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "USDC-KRC20": { - "coin": "USDC-KRC20", - "name": "USD Coin", - "coinpaprika_id": "usdc-usd-coin", - "coingecko_id": "usd-coin", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "USDC-HCO20": { - "coin": "USDC-HCO20", - "name": "USD Coin", - "coinpaprika_id": "usdc-usd-coin", - "coingecko_id": "usd-coin", - "nodes": [ - "https://http-mainnet.hecochain.com" - ], - "explorer_url": [ - "https://hecoinfo.com/" - ], - "type": "HecoChain", - "active": false, - "currently_enabled": false - }, - "USDC-HRC20": { - "coin": "USDC-HRC20", - "name": "USD Coin", - "coinpaprika_id": "usdc-usd-coin", - "coingecko_id": "usd-coin", - "nodes": [ - "https://api.harmony.one", - "https://api.s0.t.hmny.io" - ], - "explorer_url": [ - "https://explorer.harmony.one/" - ], - "type": "HRC-20", - "active": false, - "currently_enabled": false - }, - "USDC-PLG20": { - "coin": "USDC-PLG20", - "name": "USD Coin", - "coinpaprika_id": "usdc-usd-coin", - "coingecko_id": "usd-coin", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "USDI": { - "coin": "USDI", - "name": "USD Inflation Coin", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "nomics_id": "USDI", - "electrum": [ - { - "url": "usdi1.blackcoin.nl:10002", - "protocol": "SSL" - }, - { - "url": "usdi2.blackcoin.nl:20002", - "protocol": "SSL" - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/usdi/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "USDT-MVR20": { - "coin": "USDT-MVR20", - "name": "Tether", - "coinpaprika_id": "usdt-tether", - "coingecko_id": "tether", - "nodes": [ - "https://rpc.api.moonriver.moonbeam.network" - ], - "explorer_url": [ - "https://moonriver.moonscan.io/" - ], - "type": "Moonriver", - "active": false, - "currently_enabled": false - }, - "USDT-HCO20": { - "coin": "USDT-HCO20", - "name": "Tether", - "coinpaprika_id": "usdt-tether", - "coingecko_id": "tether", - "nodes": [ - "https://http-mainnet.hecochain.com" - ], - "explorer_url": [ - "https://hecoinfo.com/" - ], - "type": "HecoChain", - "active": false, - "currently_enabled": false - }, - "USDT-FTM20": { - "coin": "USDT-FTM20", - "name": "Tether", - "coinpaprika_id": "usdt-tether", - "coingecko_id": "tether", - "nodes": [ - "https://rpc.ftm.tools/" - ], - "explorer_url": [ - "https://ftmscan.com/" - ], - "type": "FTM-20", - "active": false, - "currently_enabled": false - }, - "USDT-KRC20": { - "coin": "USDT-KRC20", - "name": "Tether", - "coinpaprika_id": "usdt-tether", - "coingecko_id": "tether", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "USDT-ARB20": { - "coin": "USDT-ARB20", - "name": "Tether", - "wallet_only": true, - "coinpaprika_id": "usdt-tether", - "coingecko_id": "tether", - "nodes": [ - "https://arb1.arbitrum.io/rpc" - ], - "explorer_url": [ - "https://arbiscan.io/" - ], - "type": "Arbitrum", - "active": false, - "currently_enabled": false - }, - "USDT-AVX20": { - "coin": "USDT-AVX20", - "name": "Tether", - "coinpaprika_id": "usdt-tether", - "coingecko_id": "tether", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "USDT-PLG20": { - "coin": "USDT-PLG20", - "name": "Tether", - "coinpaprika_id": "usdt-tether", - "coingecko_id": "tether", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "USDT-BEP20": { - "coin": "USDT-BEP20", - "name": "Tether", - "coinpaprika_id": "usdt-tether", - "coingecko_id": "tether", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": true, - "currently_enabled": false - }, - "USDT-ERC20": { - "coin": "USDT-ERC20", - "name": "Tether", - "coinpaprika_id": "usdt-tether", - "coingecko_id": "tether", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "USDT-HRC20": { - "coin": "USDT-HRC20", - "name": "Tether", - "coinpaprika_id": "usdt-tether", - "coingecko_id": "tether", - "nodes": [ - "https://api.harmony.one", - "https://api.s0.t.hmny.io" - ], - "explorer_url": [ - "https://explorer.harmony.one/" - ], - "type": "HRC-20", - "active": false, - "currently_enabled": false - }, - "AWC": { - "active": false, - "coin": "AWC", - "coingecko_id": "atomic-wallet-coin", - "coinpaprika_id": "awc-atomic-wallet-coin", - "currently_enabled": false, - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "name": "Atomic Wallet Coin" - }, - "BAT-AVX20": { - "coin": "BAT-AVX20", - "name": "Basic Attention Token", - "coinpaprika_id": "bat-basic-attention-token", - "coingecko_id": "basic-attention-token", - "nomics_id": "BAT", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "BAT-ERC20": { - "coin": "BAT-ERC20", - "name": "Basic Attention Token", - "coinpaprika_id": "bat-basic-attention-token", - "coingecko_id": "basic-attention-token", - "nomics_id": "BAT", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "BAT-BEP20": { - "coin": "BAT-BEP20", - "name": "Basic Attention Token", - "coinpaprika_id": "bat-basic-attention-token", - "coingecko_id": "basic-attention-token", - "nomics_id": "BAT", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "BAT-KRC20": { - "coin": "BAT-KRC20", - "name": "Basic Attention Token", - "coinpaprika_id": "bat-basic-attention-token", - "coingecko_id": "basic-attention-token", - "nomics_id": "BAT", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "BAT-PLG20": { - "coin": "BAT-PLG20", - "name": "Basic Attention Token", - "coinpaprika_id": "bat-basic-attention-token", - "coingecko_id": "basic-attention-token", - "nomics_id": "BAT", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "KMD": { - "coin": "KMD", - "name": "Komodo", - "type": "Smart Chain", - "is_claimable": true, - "minimal_claim_amount": "10", - "coingecko_id": "komodo", - "coinpaprika_id": "kmd-komodo", - "nomics_id": "KMD", - "electrum": [ - { - "url": "electrum3.cipig.net:10001", - "ws_url": "electrum3.cipig.net:30001" - }, - { - "url": "electrum2.cipig.net:10001", - "ws_url": "electrum2.cipig.net:30001" - }, - { - "url": "electrum1.cipig.net:10001", - "ws_url": "electrum1.cipig.net:30001" - } - ], - "explorer_url": [ - "https://kmdexplorer.io/" - ], - "active": false, - "currently_enabled": false - }, - "KMD-BEP20": { - "coin": "KMD-BEP20", - "name": "Komodo", - "coinpaprika_id": "kmd-komodo", - "coingecko_id": "komodo", - "nomics_id": "KMD", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "KSM-BEP20": { - "coin": "KSM-BEP20", - "name": "Kusama", - "coinpaprika_id": "ksm-kusama", - "coingecko_id": "kusama", - "nomics_id": "KSM", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "LABS": { - "coin": "LABS", - "name": "Labs", - "type": "Smart Chain", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10019", - "ws_url": "electrum1.cipig.net:30019" - }, - { - "url": "electrum2.cipig.net:10019", - "ws_url": "electrum2.cipig.net:30019" - }, - { - "url": "electrum3.cipig.net:10019", - "ws_url": "electrum3.cipig.net:30019" - } - ], - "explorer_url": [ - "https://labs.explorer.dexstats.info/" - ], - "active": false, - "currently_enabled": false - }, - "LINK-AVX20": { - "coin": "LINK-AVX20", - "name": "Chainlink", - "coinpaprika_id": "link-chainlink", - "coingecko_id": "chainlink", - "nomics_id": "LINK", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "LINK-BEP20": { - "coin": "LINK-BEP20", - "name": "Chainlink", - "coinpaprika_id": "link-chainlink", - "coingecko_id": "chainlink", - "nomics_id": "LINK", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "LINK-ERC20": { - "coin": "LINK-ERC20", - "name": "Chainlink", - "coinpaprika_id": "link-chainlink", - "coingecko_id": "chainlink", - "nomics_id": "LINK", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "LINK-FTM20": { - "coin": "LINK-FTM20", - "name": "Chainlink", - "coinpaprika_id": "link-chainlink", - "coingecko_id": "chainlink", - "nomics_id": "LINK", - "nodes": [ - "https://rpc.ftm.tools/" - ], - "explorer_url": [ - "https://ftmscan.com/" - ], - "type": "FTM-20", - "active": false, - "currently_enabled": false - }, - "LINK-HCO20": { - "coin": "LINK-HCO20", - "name": "Chainlink", - "coinpaprika_id": "link-chainlink", - "coingecko_id": "chainlink", - "nomics_id": "LINK", - "nodes": [ - "https://http-mainnet.hecochain.com" - ], - "explorer_url": [ - "https://hecoinfo.com/" - ], - "type": "HecoChain", - "active": false, - "currently_enabled": false - }, - "LINK-HRC20": { - "coin": "LINK-HRC20", - "name": "Chainlink", - "coinpaprika_id": "link-chainlink", - "coingecko_id": "chainlink", - "nomics_id": "LINK", - "nodes": [ - "https://api.harmony.one", - "https://api.s0.t.hmny.io" - ], - "explorer_url": [ - "https://explorer.harmony.one/" - ], - "type": "HRC-20", - "active": false, - "currently_enabled": false - }, - "LINK-KRC20": { - "coin": "LINK-KRC20", - "name": "Chainlink", - "coinpaprika_id": "link-chainlink", - "coingecko_id": "chainlink", - "nomics_id": "LINK", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "LINK-PLG20": { - "coin": "LINK-PLG20", - "name": "Chainlink", - "coinpaprika_id": "link-chainlink", - "coingecko_id": "chainlink", - "nomics_id": "LINK", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "MESH": { - "coin": "MESH", - "name": "SuperMESH", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10016" - }, - { - "url": "electrum2.cipig.net:10016" - }, - { - "url": "electrum3.cipig.net:10016" - } - ], - "explorer_url": [ - "https://mesh.kmdexplorer.io/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false - }, - "MINDS": { - "coin": "MINDS", - "name": "Minds", - "coinpaprika_id": "minds-minds", - "coingecko_id": "minds", - "nomics_id": "MINDS", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "MGW": { - "coin": "MGW", - "name": "MGW", - "type": "Smart Chain", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10015", - "ws_url": "electrum1.cipig.net:30015" - }, - { - "url": "electrum2.cipig.net:10015", - "ws_url": "electrum2.cipig.net:30015" - }, - { - "url": "electrum3.cipig.net:10015", - "ws_url": "electrum3.cipig.net:30015" - } - ], - "explorer_url": [ - "https://mgw.explorer.dexstats.info/" - ], - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "DEX": { - "coin": "DEX", - "name": "Dex", - "type": "Smart Chain", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10006", - "ws_url": "electrum1.cipig.net:30006" - }, - { - "url": "electrum2.cipig.net:10006", - "ws_url": "electrum2.cipig.net:30006" - }, - { - "url": "electrum3.cipig.net:10006", - "ws_url": "electrum3.cipig.net:30006" - } - ], - "explorer_url": [ - "https://dex.explorer.dexstats.info/" - ], - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "RICK": { - "coin": "RICK", - "asset": "RICK", - "type": "Smart Chain", - "name": "Rick (TESTCOIN)", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "electrum3.cipig.net:10017", - "ws_url": "electrum3.cipig.net:30017" - }, - { - "url": "electrum2.cipig.net:10017", - "ws_url": "electrum2.cipig.net:30017" - }, - { - "url": "electrum1.cipig.net:10017", - "ws_url": "electrum1.cipig.net:30017" - } - ], - "explorer_url": [ - "https://rick.explorer.dexstats.info/" - ], - "active": false, - "currently_enabled": false - }, - "MORTY": { - "coin": "MORTY", - "asset": "MORTY", - "type": "Smart Chain", - "name": "Morty (TESTCOIN)", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "electrum3.cipig.net:10018", - "ws_url": "electrum3.cipig.net:30018" - }, - { - "url": "electrum2.cipig.net:10018", - "ws_url": "electrum2.cipig.net:30018" - }, - { - "url": "electrum1.cipig.net:10018", - "ws_url": "electrum1.cipig.net:30018" - } - ], - "explorer_url": [ - "https://morty.explorer.dexstats.info/" - ], - "active": false, - "currently_enabled": false - }, - "NYAN": { - "coin": "NYAN", - "name": "Nyancoin", - "coinpaprika_id": "nyan-nyancoin", - "coingecko_id": "test-coin", - "nomics_id": "NYAN", - "electrum": [ - { - "url": "txserver.live:50022", - "protocol": "SSL" - }, - { - "url": "txserver.live:50020", - "protocol": "TCP" - }, - { - "url": "electrumx.live:50022", - "protocol": "SSL" - }, - { - "url": "electrumx.live:50020", - "protocol": "TCP" - } - ], - "explorer_url": [ - "https://www.nyanchain.com/" - ], - "explorer_tx_url": "tx.nyan?", - "explorer_address_url": "ad.nyan?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "PANGEA": { - "coin": "PANGEA", - "name": "Pangea", - "type": "Smart Chain", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10010", - "ws_url": "electrum1.cipig.net:30010" - }, - { - "url": "electrum2.cipig.net:10010", - "ws_url": "electrum2.cipig.net:30010" - }, - { - "url": "electrum3.cipig.net:10010", - "ws_url": "electrum3.cipig.net:30010" - } - ], - "explorer_url": [ - "https://pangea.explorer.dexstats.info/" - ], - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "PGX-PLG20": { - "coin": "PGX-PLG20", - "name": "Pegaxy Stone", - "coinpaprika_id": "test-coin", - "coingecko_id": "pegaxy-stone", - "nomics_id": "PGX", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "PIC": { - "coin": "PIC", - "name": "Picacoin", - "coinpaprika_id": "pic-picacoin", - "coingecko_id": "test-coin", - "electrum": [ - { - "url": "143.198.143.180:50001" - }, - { - "url": "134.122.120.47:50001" - } - ], - "explorer_url": [ - "http://explorer.picacoin.org/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "PPC": { - "coin": "PPC", - "name": "Peercoin", - "coinpaprika_id": "ppc-peercoin", - "coingecko_id": "peercoin", - "nomics_id": "PPC", - "electrum": [ - { - "url": "electrum.peercoinexplorer.net:50002", - "protocol": "SSL", - "disable_cert_verification": false - }, - { - "url": "allingas.peercoinexplorer.net:50002", - "protocol": "SSL", - "disable_cert_verification": false - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/ppc/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "PPC-ERC20": { - "coin": "PPC-ERC20", - "name": "Peercoin", - "coinpaprika_id": "ppc-peercoin", - "coingecko_id": "peercoin", - "nomics_id": "PPC", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "PPC-PLG20": { - "coin": "PPC-PLG20", - "name": "Peercoin", - "coinpaprika_id": "ppc-peercoin", - "coingecko_id": "peercoin", - "nomics_id": "PPC", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "PRUX": { - "coin": "PRUX", - "name": "PRUX", - "coinpaprika_id": "prux-prux-coin", - "coingecko_id": "test-coin", - "nomics_id": "PRUX", - "electrum": [ - { - "url": "txserver.live:50002", - "protocol": "SSL" - }, - { - "url": "electrumx.live:50012", - "protocol": "SSL" - }, - { - "url": "txserver.live:50001", - "protocol": "TCP" - }, - { - "url": "electrumx.live:50010", - "protocol": "TCP" - } - ], - "explorer_url": [ - "https://explorer.prux.info/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "QIAIR": { - "coin": "QIAIR", - "name": "Qi Airdrop Token", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "active": false, - "currently_enabled": false, - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20" - }, - "QI": { - "coin": "QI", - "name": "QiSwap", - "coingecko_id": "qiswap", - "coinpaprika_id": "qi-qiswap", - "nomics_id": "QI", - "active": false, - "currently_enabled": false, - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20" - }, - "QNT-ERC20": { - "coin": "QNT-ERC20", - "name": "Quant", - "coinpaprika_id": "qnt-quant", - "coingecko_id": "quant-network", - "nomics_id": "QNT", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "QNT-KRC20": { - "coin": "QNT-KRC20", - "name": "Quant", - "coinpaprika_id": "qnt-quant", - "coingecko_id": "quant-network", - "nomics_id": "QNT", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "REVS": { - "coin": "REVS", - "name": "REVS", - "type": "Smart Chain", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10003", - "ws_url": "electrum1.cipig.net:30003" - }, - { - "url": "electrum2.cipig.net:10003", - "ws_url": "electrum2.cipig.net:30003" - }, - { - "url": "electrum3.cipig.net:10003", - "ws_url": "electrum3.cipig.net:30003" - } - ], - "explorer_url": [ - "https://revs.explorer.dexstats.info/" - ], - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "SBCH": { - "coin": "SBCH", - "name": "SmartBCH", - "alias_ticker": "BCH", - "coinpaprika_id": "bch-bitcoin-cash", - "coingecko_id": "bitcoin-cash", - "nomics_id": "BCH", - "nodes": [ - "https://smartbch.fountainhead.cash/mainnet" - ], - "explorer_url": [ - "https://www.smartscan.cash/" - ], - "type": "SmartBCH", - "active": false, - "currently_enabled": false - }, - "SIBM-BEP20": { - "coin": "SIBM-BEP20", - "name": "SibMining", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "SMTF-v2": { - "coin": "SMTF-v2", - "name": "SmartFi", - "coinpaprika_id": "smtf-smartfi", - "coingecko_id": "test-coin", - "nomics_id": "SMTF", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "SOULJA": { - "coin": "SOULJA", - "name": "SouljaCoin", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10035", - "ws_url": "electrum1.cipig.net:30035" - }, - { - "url": "electrum2.cipig.net:10035", - "ws_url": "electrum2.cipig.net:30035" - }, - { - "url": "electrum3.cipig.net:10035", - "ws_url": "electrum3.cipig.net:30035" - } - ], - "explorer_url": [ - "https://explorer.souljacoin.cash/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false - }, - "SXP-BEP20": { - "coin": "SXP-BEP20", - "name": "Swipe", - "coinpaprika_id": "sxp-swipe", - "coingecko_id": "swipe", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "SXP-ERC20": { - "coin": "SXP-ERC20", - "name": "Swipe", - "coinpaprika_id": "sxp-swipe", - "coingecko_id": "swipe", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "SYS": { - "coin": "SYS", - "name": "Syscoin", - "coinpaprika_id": "sys-syscoin", - "coingecko_id": "syscoin", - "nomics_id": "SYS", - "electrum": [ - { - "url": "electrum1.cipig.net:10064", - "ws_url": "electrum1.cipig.net:30064" - }, - { - "url": "electrum2.cipig.net:10064", - "ws_url": "electrum2.cipig.net:30064" - }, - { - "url": "electrum3.cipig.net:10064", - "ws_url": "electrum3.cipig.net:30064" - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/sys/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "WSB": { - "coin": "WSB", - "name": "WallStreetBets", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10033", - "ws_url": "electrum1.cipig.net:30033" - }, - { - "url": "electrum2.cipig.net:10033", - "ws_url": "electrum2.cipig.net:30033" - }, - { - "url": "electrum3.cipig.net:10033", - "ws_url": "electrum3.cipig.net:30033" - } - ], - "explorer_url": [ - "https://wsb.explorer.dexstats.info/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false - }, - "CHIPS": { - "coin": "CHIPS", - "type": "UTXO", - "name": "Chips", - "coingecko_id": "test-coin", - "coinpaprika_id": "chips-chips", - "nomics_id": "CHIPS6", - "electrum": [ - { - "url": "electrum3.cipig.net:10053", - "ws_url": "electrum3.cipig.net:30053" - }, - { - "url": "electrum2.cipig.net:10053", - "ws_url": "electrum2.cipig.net:30053" - }, - { - "url": "electrum1.cipig.net:10053", - "ws_url": "electrum1.cipig.net:30053" - } - ], - "explorer_url": [ - "https://explorer.chips.cash/" - ], - "active": false, - "currently_enabled": false - }, - "SCA": { - "coin": "SCA", - "name": "Scalaris", - "type": "UTXO", - "coingecko_id": "test-coin", - "coinpaprika_id": "sca-scalaris", - "nomics_id": "SCA2", - "electrum": [ - { - "url": "electrum1.scalaris.info:10001" - }, - { - "url": "electrum2.scalaris.info:10001" - }, - { - "url": "electrum3.scalaris.info:10001" - } - ], - "explorer_url": [ - "https://explorer.scalaris.info/" - ], - "active": false, - "currently_enabled": false - }, - "SUPERNET": { - "coin": "SUPERNET", - "name": "Supernet", - "type": "Smart Chain", - "coingecko_id": "test-coin", - "coinpaprika_id": "unity-supernet", - "nomics_id": "UNITY", - "electrum": [ - { - "url": "electrum1.cipig.net:10005", - "ws_url": "electrum1.cipig.net:30005" - }, - { - "url": "electrum2.cipig.net:10005", - "ws_url": "electrum2.cipig.net:30005" - }, - { - "url": "electrum3.cipig.net:10005", - "ws_url": "electrum3.cipig.net:30005" - } - ], - "explorer_url": [ - "https://supernet.explorer.dexstats.info/" - ], - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "SUSHI-AVX20": { - "coin": "SUSHI-AVX20", - "name": "Sushi", - "coinpaprika_id": "sushi-sushi", - "coingecko_id": "sushi", - "nomics_id": "SUSHI", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "SUSHI-BEP20": { - "coin": "SUSHI-BEP20", - "name": "Sushi", - "coinpaprika_id": "sushi-sushi", - "coingecko_id": "sushi", - "nomics_id": "SUSHI", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "SUSHI-ERC20": { - "coin": "SUSHI-ERC20", - "name": "Sushi", - "coinpaprika_id": "sushi-sushi", - "coingecko_id": "sushi", - "nomics_id": "SUSHI", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "SUSHI-FTM20": { - "coin": "SUSHI-FTM20", - "name": "Sushi", - "coinpaprika_id": "sushi-sushi", - "coingecko_id": "sushi", - "nomics_id": "SUSHI", - "nodes": [ - "https://rpc.ftm.tools/" - ], - "explorer_url": [ - "https://ftmscan.com/" - ], - "type": "FTM-20", - "active": false, - "currently_enabled": false - }, - "SUSHI-HRC20": { - "coin": "SUSHI-HRC20", - "name": "Sushi", - "coinpaprika_id": "sushi-sushi", - "coingecko_id": "sushi", - "nomics_id": "SUSHI", - "nodes": [ - "https://api.harmony.one", - "https://api.s0.t.hmny.io" - ], - "explorer_url": [ - "https://explorer.harmony.one/" - ], - "type": "HRC-20", - "active": false, - "currently_enabled": false - }, - "SUSHI-KRC20": { - "coin": "SUSHI-KRC20", - "name": "Sushi", - "coinpaprika_id": "sushi-sushi", - "coingecko_id": "sushi", - "nomics_id": "SUSHI", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "SUSHI-MVR20": { - "coin": "SUSHI-MVR20", - "name": "Sushi", - "coinpaprika_id": "sushi-sushi", - "coingecko_id": "sushi", - "nomics_id": "SUSHI", - "nodes": [ - "https://rpc.api.moonriver.moonbeam.network" - ], - "explorer_url": [ - "https://moonriver.moonscan.io/" - ], - "type": "Moonriver", - "active": false, - "currently_enabled": false - }, - "SUSHI-PLG20": { - "coin": "SUSHI-PLG20", - "name": "Sushi", - "coinpaprika_id": "sushi-sushi", - "coingecko_id": "sushi", - "nomics_id": "SUSHI", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "VITE-BEP20": { - "coin": "VITE-BEP20", - "name": "Vite", - "coinpaprika_id": "vite-vite", - "coingecko_id": "vite", - "nomics_id": "VITE", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "VRSC": { - "coin": "VRSC", - "type": "Smart Chain", - "name": "Verus Coin", - "coingecko_id": "verus-coin", - "coinpaprika_id": "vrsc-verus-coin", - "nomics_id": "VRSC", - "electrum": [ - { - "url": "el0.verus.io:17486", - "protocol": "SSL", - "disable_cert_verification": false - }, - { - "url": "el1.verus.io:17486", - "protocol": "SSL", - "disable_cert_verification": false - }, - { - "url": "el2.verus.io:17486", - "protocol": "SSL", - "disable_cert_verification": false - } - ], - "explorer_url": [ - "https://explorer.verus.io/" - ], - "active": false, - "currently_enabled": false - }, - "IL8P": { - "coin": "IL8P", - "name": "InfiniLooP", - "coinpaprika_id": "il8p-infiniloop", - "coingecko_id": "test-coin", - "nomics_id": "IL8P", - "electrum": [ - { - "url": "il8p.electrumx.transcenders.name:50002", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "il9p.electrumx.transcenders.name:50002", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/il8p/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "ILN": { - "coin": "ILN", - "type": "Smart Chain", - "name": "iLien", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "electrum1.ilien.io:65011" - }, - { - "url": "electrum2.ilien.io:65011" - } - ], - "explorer_url": [ - "https://iln.explorer.dexstats.info/" - ], - "active": false, - "currently_enabled": false - }, - "MKR-AVX20": { - "coin": "MKR-AVX20", - "name": "Maker", - "coinpaprika_id": "mkr-maker", - "coingecko_id": "maker", - "nomics_id": "MKR", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "MKR-BEP20": { - "coin": "MKR-BEP20", - "name": "Maker", - "coinpaprika_id": "mkr-maker", - "coingecko_id": "maker", - "nomics_id": "MKR", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "MKR-ERC20": { - "coin": "MKR-ERC20", - "name": "Maker", - "coinpaprika_id": "mkr-maker", - "coingecko_id": "maker", - "nomics_id": "MKR", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "MKR-KRC20": { - "coin": "MKR-KRC20", - "name": "Maker", - "coinpaprika_id": "mkr-maker", - "coingecko_id": "maker", - "nomics_id": "MKR", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "MONA": { - "coin": "MONA", - "name": "MonaCoin", - "coinpaprika_id": "mona-monacoin", - "coingecko_id": "monacoin", - "nomics_id": "MONA", - "electrum": [ - { - "url": "electrumx3.monacoin.nl:50001" - }, - { - "url": "103.125.218.246:50001" - }, - { - "url": "electrumx.tamami-foundation.org:50001" - } - ], - "explorer_url": [ - "https://blockbook.electrum-mona.org/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "NAV": { - "coin": "NAV", - "name": "NavCoin", - "coinpaprika_id": "nav-navcoin", - "coingecko_id": "nav-coin", - "nomics_id": "NAV", - "electrum": [ - { - "url": "electrum.nav.community:40002", - "protocol": "SSL", - "ws_url": "electrum.nav.community:40004" - }, - { - "url": "electrum2.nav.community:40002", - "protocol": "SSL", - "ws_url": "electrum2.nav.community:40004" - }, - { - "url": "electrum3.nav.community:40002", - "protocol": "SSL", - "ws_url": "electrum3.nav.community:40004" - }, - { - "url": "electrum4.nav.community:40002", - "protocol": "SSL", - "ws_url": "electrum4.nav.community:40004" - } - ], - "explorer_url": [ - "https://www.navexplorer.com/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "NAV-BEP20": { - "coin": "NAV-BEP20", - "name": "Navcoin", - "coinpaprika_id": "nav-navcoin", - "coingecko_id": "nav-coin", - "nomics_id": "NAV", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "NEXO-ERC20": { - "coin": "NEXO-ERC20", - "name": "Nexo", - "coinpaprika_id": "nexo-nexo", - "coingecko_id": "nexo", - "nomics_id": "NEXO", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "NEXO-KRC20": { - "coin": "NEXO-KRC20", - "name": "Nexo", - "coinpaprika_id": "nexo-nexo", - "coingecko_id": "nexo", - "nomics_id": "NEXO", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "NEXO-PLG20": { - "coin": "NEXO-PLG20", - "name": "Nexo", - "coinpaprika_id": "nexo-nexo", - "coingecko_id": "nexo", - "nomics_id": "NEXO", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "NMC": { - "coin": "NMC", - "name": "Namecoin", - "coinpaprika_id": "nmc-namecoin", - "coingecko_id": "namecoin", - "nomics_id": "NMC", - "electrum": [ - { - "url": "82.119.233.36:50001" - }, - { - "url": "nmc2.bitcoins.sk:57002", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "46.229.238.187:57001" - } - ], - "explorer_url": [ - "https://nmc.tokenview.com/en/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "NVC": { - "coin": "NVC", - "name": "Novacoin", - "coinpaprika_id": "nvc-novacoin", - "coingecko_id": "novacoin", - "nomics_id": "NVC", - "electrum": [ - { - "url": "electrumx.nvc.ewmcx.org:50002", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "failover.nvc.ewmcx.biz:50002", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "https://explorer.novaco.in/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "NVC-BEP20": { - "coin": "NVC-BEP20", - "name": "Novacoin", - "coinpaprika_id": "nvc-novacoin", - "coingecko_id": "novacoin", - "nomics_id": "NVC", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "NVC-QRC20": { - "coin": "NVC-QRC20", - "name": "Novacoin", - "coinpaprika_id": "nvc-novacoin", - "coingecko_id": "novacoin", - "nomics_id": "NVC", - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20", - "active": false, - "currently_enabled": false - }, - "NZDS-ERC20": { - "coin": "NZDS-ERC20", - "name": "NZD Stablecoin", - "forex_id": "NZD", - "coinpaprika_id": "test-coin", - "coingecko_id": "nzd-stablecoin", - "nomics_id": "NZDS", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "NZDS-PLG20": { - "coin": "NZDS-PLG20", - "name": "NZD Stablecoin", - "forex_id": "NZD", - "coinpaprika_id": "test-coin", - "coingecko_id": "nzd-stablecoin", - "nomics_id": "NZDS", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "OMG-ERC20": { - "coin": "OMG-ERC20", - "name": "OMG Network", - "coinpaprika_id": "omg-omg-network", - "coingecko_id": "omisego", - "nomics_id": "OMG", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "OMG-PLG20": { - "coin": "OMG-PLG20", - "name": "OMG Network", - "coinpaprika_id": "omg-omg-network", - "coingecko_id": "omisego", - "nomics_id": "OMG", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "QKC-BEP20": { - "coin": "QKC-BEP20", - "name": "QuarkChain", - "coinpaprika_id": "qkc-quarkchain", - "coingecko_id": "quark-chain", - "nomics_id": "QKC", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "QKC-ERC20": { - "coin": "QKC-ERC20", - "name": "QuarkChain", - "coinpaprika_id": "qkc-quarkchain", - "coingecko_id": "quark-chain", - "nomics_id": "QKC", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "QTUM": { - "need_electrum": true, - "coin": "QTUM", - "name": "Qtum", - "coinpaprika_id": "qtum-qtum", - "coingecko_id": "qtum", - "nomics_id": "QTUM", - "electrum": [ - { - "url": "electrum1.cipig.net:10050", - "ws_url": "electrum1.cipig.net:30050" - }, - { - "url": "electrum2.cipig.net:10050", - "ws_url": "electrum2.cipig.net:30050" - }, - { - "url": "electrum3.cipig.net:10050", - "ws_url": "electrum3.cipig.net:30050" - } - ], - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20", - "active": false, - "currently_enabled": false - }, - "QTUM-ERC20": { - "coin": "QTUM-ERC20", - "name": "Qtum", - "coinpaprika_id": "qtum-qtum", - "coingecko_id": "qtum", - "nomics_id": "QTUM", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "REN-ERC20": { - "coin": "REN-ERC20", - "name": "Ren", - "coinpaprika_id": "ren-republic-protocol", - "coingecko_id": "republic-protocol", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "REN-HRC20": { - "coin": "REN-HRC20", - "name": "Ren", - "coinpaprika_id": "ren-republic-protocol", - "coingecko_id": "republic-protocol", - "nodes": [ - "https://api.harmony.one", - "https://api.s0.t.hmny.io" - ], - "explorer_url": [ - "https://explorer.harmony.one/" - ], - "type": "HRC-20", - "active": false, - "currently_enabled": false - }, - "REN-HCO20": { - "coin": "REN-HCO20", - "name": "Ren", - "coinpaprika_id": "ren-republic-protocol", - "coingecko_id": "republic-protocol", - "nodes": [ - "https://http-mainnet.hecochain.com" - ], - "explorer_url": [ - "https://hecoinfo.com/" - ], - "type": "HecoChain", - "active": false, - "currently_enabled": false - }, - "RSR-ERC20": { - "coin": "RSR-ERC20", - "name": "Reserve Rights", - "coinpaprika_id": "rsr-reserve-rights", - "coingecko_id": "reserve-rights-token", - "nomics_id": "RSR", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "RTM": { - "coin": "RTM", - "name": "Raptoreum", - "coinpaprika_id": "rtm-raptoreum", - "coingecko_id": "raptoreum", - "nomics_id": "RTM", - "electrum": [ - { - "url": "209.151.151.21:50001", - "protocol": "TCP" - }, - { - "url": "209.50.52.239:50001", - "protocol": "TCP" - } - ], - "explorer_url": [ - "https://explorer.raptoreum.com/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "RVN": { - "coin": "RVN", - "name": "Ravencoin", - "coinpaprika_id": "rvn-ravencoin", - "coingecko_id": "ravencoin", - "nomics_id": "RVN", - "electrum": [ - { - "url": "electrum1.cipig.net:10051", - "ws_url": "electrum1.cipig.net:30051" - }, - { - "url": "electrum2.cipig.net:10051", - "ws_url": "electrum2.cipig.net:30051" - }, - { - "url": "electrum3.cipig.net:10051", - "ws_url": "electrum3.cipig.net:30051" - } - ], - "explorer_url": [ - "https://ravencoin.network/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "SAND-ERC20": { - "coin": "SAND-ERC20", - "name": "The Sandbox", - "coinpaprika_id": "sand-the-sandbox", - "coingecko_id": "the-sandbox", - "nomics_id": "SAND2", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "SAND-PLG20": { - "coin": "SAND-PLG20", - "name": "The Sandbox", - "coinpaprika_id": "sand-the-sandbox", - "coingecko_id": "the-sandbox", - "nomics_id": "SAND2", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "SNX-AVX20": { - "coin": "SNX-AVX20", - "name": "Synthetix", - "coinpaprika_id": "snx-synthetix-network-token", - "coingecko_id": "havven", - "nomics_id": "SNX", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "SNX-BEP20": { - "coin": "SNX-BEP20", - "name": "Synthetix", - "coinpaprika_id": "snx-synthetix-network-token", - "coingecko_id": "havven", - "nomics_id": "SNX", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "SNX-ERC20": { - "coin": "SNX-ERC20", - "name": "Synthetix", - "coinpaprika_id": "snx-synthetix-network-token", - "coingecko_id": "havven", - "nomics_id": "SNX", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "SNX-FTM20": { - "coin": "SNX-FTM20", - "name": "Synthetix", - "coinpaprika_id": "snx-synthetix-network-token", - "coingecko_id": "havven", - "nomics_id": "SNX", - "nodes": [ - "https://rpc.ftm.tools/" - ], - "explorer_url": [ - "https://ftmscan.com/" - ], - "type": "FTM-20", - "active": false, - "currently_enabled": false - }, - "SNX-KRC20": { - "coin": "SNX-KRC20", - "name": "Synthetix", - "coinpaprika_id": "snx-synthetix-network-token", - "coingecko_id": "havven", - "nomics_id": "SNX", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "SNX-PLG20": { - "coin": "SNX-PLG20", - "name": "Synthetix", - "coinpaprika_id": "snx-synthetix-network-token", - "coingecko_id": "havven", - "nomics_id": "SNX", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "SOL-BEP20": { - "coin": "SOL-BEP20", - "name": "Solana", - "coinpaprika_id": "sol-solana", - "coingecko_id": "solana", - "nomics_id": "SOL", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "SPACE": { - "coin": "SPACE", - "name": "Spacecoin", - "coingecko_id": "test-coin", - "coinpaprika_id": "space-spacecoin7367", - "nomics_id": "SPACE7", - "electrum": [ - { - "url": "electrum3.cipig.net:10011", - "ws_url": "electrum3.cipig.net:30011" - }, - { - "url": "electrum2.cipig.net:10011", - "ws_url": "electrum2.cipig.net:30011" - }, - { - "url": "electrum1.cipig.net:10011", - "ws_url": "electrum1.cipig.net:30011" - } - ], - "explorer_url": [ - "https://explorer.spaceworks.co/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false - }, - "TEL-ERC20": { - "coin": "TEL-ERC20", - "name": "Telcoin", - "coinpaprika_id": "tel-telcoin", - "coingecko_id": "telcoin", - "nomics_id": "TEL", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "TEL-PLG20": { - "coin": "TEL-PLG20", - "name": "Telcoin", - "coinpaprika_id": "tel-telcoin", - "coingecko_id": "telcoin", - "nomics_id": "TEL", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "TEL-KRC20": { - "coin": "TEL-KRC20", - "name": "Telcoin", - "coinpaprika_id": "tel-telcoin", - "coingecko_id": "telcoin", - "nomics_id": "TEL", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "TFT-BEP20": { - "coin": "TFT-BEP20", - "name": "ThreeFold", - "coinpaprika_id": "tft-threefold-token", - "coingecko_id": "threefold-token", - "nomics_id": "THREEFOLDBEP20", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "THC": { - "coin": "THC", - "name": "HempCoin", - "coinpaprika_id": "thc-hempcoin", - "coingecko_id": "hempcoin-thc", - "nomics_id": "THC", - "electrum": [ - { - "url": "1.eu.thc.electrum.dexstats.info:10020" - }, - { - "url": "2.eu.thc.electrum.dexstats.info:10020" - } - ], - "explorer_url": [ - "https://thc.explorer.dexstats.info/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false - }, - "THC-BEP20": { - "coin": "THC-BEP20", - "name": "HempCoin", - "coinpaprika_id": "thc-hempcoin", - "coingecko_id": "hempcoin-thc", - "nomics_id": "THC", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "TKL": { - "coin": "TKL", - "name": "Tokel", - "coinpaprika_id": "tkl-tokel", - "coingecko_id": "tokel", - "nomics_id": "TKL2", - "electrum": [ - { - "url": "1.eu.tokel.electrum.dexstats.info:10077" - }, - { - "url": "2.eu.tokel.electrum.dexstats.info:10077" - } - ], - "explorer_url": [ - "https://tokel.explorer.dexstats.info/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false - }, - "TRC": { - "coin": "TRC", - "name": "Terracoin", - "coinpaprika_id": "trc-terracoin", - "coingecko_id": "terracoin", - "nomics_id": "TRC", - "electrum": [ - { - "url": "failover.trc-uis.ewmcx.biz:50006", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "electrum.terracoin.io:50001" - }, - { - "url": "electrum.southofheaven.ca:50001" - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/trc/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "TRX-BEP20": { - "coin": "TRX-BEP20", - "name": "TRON", - "coinpaprika_id": "trx-tron", - "coingecko_id": "tron", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "TRYB-AVX20": { - "coin": "TRYB-AVX20", - "name": "BiLira", - "forex_id": "TRY", - "coinpaprika_id": "tryb-bilira", - "coingecko_id": "bilira", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "TRYB-BEP20": { - "coin": "TRYB-BEP20", - "name": "BiLira", - "forex_id": "TRY", - "coinpaprika_id": "tryb-bilira", - "coingecko_id": "bilira", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "TRYB-PLG20": { - "coin": "TRYB-PLG20", - "name": "BiLira", - "forex_id": "TRY", - "coinpaprika_id": "tryb-bilira", - "coingecko_id": "bilira", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "TRYB-ERC20": { - "coin": "TRYB-ERC20", - "name": "BiLira", - "forex_id": "TRY", - "coinpaprika_id": "tryb-bilira", - "coingecko_id": "bilira", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "TUSD-BEP20": { - "coin": "TUSD-BEP20", - "name": "TrueUSD", - "coinpaprika_id": "tusd-trueusd", - "coingecko_id": "true-usd", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "TUSD-ERC20": { - "coin": "TUSD-ERC20", - "name": "TrueUSD", - "coinpaprika_id": "tusd-trueusd", - "coingecko_id": "true-usd", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "TUSD-HCO20": { - "coin": "TUSD-HCO20", - "name": "TrueUSD", - "coinpaprika_id": "tusd-trueusd", - "coingecko_id": "true-usd", - "nodes": [ - "https://http-mainnet.hecochain.com" - ], - "explorer_url": [ - "https://hecoinfo.com/" - ], - "type": "HecoChain", - "active": false, - "currently_enabled": false - }, - "TUSD-KRC20": { - "coin": "TUSD-KRC20", - "name": "TrueUSD", - "coinpaprika_id": "tusd-trueusd", - "coingecko_id": "true-usd", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "TUSD-PLG20": { - "coin": "TUSD-PLG20", - "name": "TrueUSD", - "coinpaprika_id": "tusd-trueusd", - "coingecko_id": "true-usd", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "UST-ERC20": { - "coin": "UST-ERC20", - "name": "TerraUSD", - "coinpaprika_id": "ust-terrausd", - "coingecko_id": "terrausd", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "UST-BEP20": { - "coin": "UST-BEP20", - "name": "TerraUSD", - "coinpaprika_id": "ust-terrausd", - "coingecko_id": "terrausd", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "UST-HRC20": { - "coin": "UST-HRC20", - "name": "TerraUSD", - "coinpaprika_id": "ust-terrausd", - "coingecko_id": "terrausd", - "nodes": [ - "https://api.harmony.one", - "https://api.s0.t.hmny.io" - ], - "explorer_url": [ - "https://explorer.harmony.one/" - ], - "type": "HRC-20", - "active": false, - "currently_enabled": false - }, - "UST-PLG20": { - "coin": "UST-PLG20", - "name": "TerraUSD", - "coinpaprika_id": "ust-terrausd", - "coingecko_id": "terrausd", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "VAL": { - "coin": "VAL", - "name": "Validity", - "coinpaprika_id": "val-validity", - "coingecko_id": "radium", - "nomics_id": "RADS", - "electrum": [ - { - "url": "e1.validitytech.com:11002", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "e2.validitytech.com:11002", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "e3.validitytech.com:11002", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/val/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "VRA": { - "coin": "VRA", - "name": "Verasity", - "coingecko_id": "verasity", - "coinpaprika_id": "vra-verasity", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "VRM": { - "coin": "VRM", - "name": "Verium Reserve", - "coingecko_id": "test-coin", - "coinpaprika_id": "vrm-veriumreserve", - "nomics_id": "VRM", - "electrum": [ - { - "url": "electrum01-vrm.vericonomy.com:50001" - }, - { - "url": "electrum02-vrm.vericonomy.com:50001" - } - ], - "explorer_url": [ - "https://explorer-vrm.vericonomy.com/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "WBTC-ERC20": { - "coin": "WBTC-ERC20", - "name": "Wrapped Bitcoin", - "coinpaprika_id": "wbtc-wrapped-bitcoin", - "coingecko_id": "wrapped-bitcoin", - "nomics_id": "WBTC", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "WBTC-HRC20": { - "coin": "WBTC-HRC20", - "name": "Wrapped Bitcoin", - "coinpaprika_id": "wbtc-wrapped-bitcoin", - "coingecko_id": "wrapped-bitcoin", - "nomics_id": "WBTC", - "nodes": [ - "https://api.harmony.one", - "https://api.s0.t.hmny.io" - ], - "explorer_url": [ - "https://explorer.harmony.one/" - ], - "type": "HRC-20", - "active": false, - "currently_enabled": false - }, - "WCN": { - "coin": "WCN", - "name": "Widecoin", - "coinpaprika_id": "wcn-widecoin", - "coingecko_id": "widecoin", - "nomics_id": "WCN2", - "electrum": [ - { - "url": "electrumx.widecoin.org:50001" - }, - { - "url": "electrumx2.widecoin.org:50001" - } - ], - "explorer_url": [ - "https://explorer.widecoin.org/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "WWCN-ERC20": { - "coin": "WWCN-ERC20", - "name": "Wrapped Widecoin", - "coinpaprika_id": "wwcn-wrapped-widecoin", - "coingecko_id": "wrapped-widecoin", - "nomics_id": "WWCN", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "XEC": { - "coin": "XEC", - "name": "eCash", - "coingecko_id": "ecash", - "coinpaprika_id": "xec-ecash", - "nomics_id": "XEC", - "electrum": [ - { - "url": "electrum.bitcoinabc.org:50002", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "fulcrum.pepipierre.fr:50002", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "https://blockchair.com/ecash/" - ], - "explorer_tx_url": "transaction/", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "XEP-BEP20": { - "coin": "XEP-BEP20", - "name": "Electra Protocol", - "coinpaprika_id": "xep-electra-protocol", - "coingecko_id": "electra-protocol", - "nomics_id": "XEP", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "XLM-BEP20": { - "coin": "XLM-BEP20", - "name": "Stellar", - "coinpaprika_id": "xlm-stellar", - "coingecko_id": "stellar", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "XMY": { - "coin": "XMY", - "name": "Myriad", - "coinpaprika_id": "xmy-myriad", - "coingecko_id": "myriadcoin", - "nomics_id": "XMY", - "electrum": [ - { - "url": "lenoir.ecoincore.com:10891", - "protocol": "TCP" - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/xmy/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "XPM": { - "coin": "XPM", - "name": "Primecoin", - "coinpaprika_id": "xpm-primecoin", - "coingecko_id": "primecoin", - "nomics_id": "XPM", - "electrum": [ - { - "url": "electrumx.primecoin.org:50001", - "protocol": "TCP" - }, - { - "url": "electrumx.mainnet.primecoin.org:50011", - "protocol": "TCP" - }, - { - "url": "electrumx.gemmer.primecoin.org:50011", - "protocol": "TCP" - } - ], - "explorer_url": [ - "https://www.blockseek.io/xpm/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "XRP-BEP20": { - "coin": "XRP-BEP20", - "name": "XRP", - "coinpaprika_id": "xrp-xrp", - "coingecko_id": "ripple", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "XRG": { - "coin": "XRG", - "active": false, - "coinpaprika_id": "xrg-ergon", - "coingecko_id": "test-coin", - "nomics_id": "XRG", - "currently_enabled": false, - "electrum": [ - { - "url": "fulcrum.ergon.network:52138", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "blackie.c3-soft.com:52138", - "protocol": "SSL" - } - ], - "explorer_url": [ - "https://explorer.ergon.network/" - ], - "type": "UTXO", - "name": "Ergon" - }, - "XSGD-ERC20": { - "coin": "XSGD-ERC20", - "name": "StraitsX SGD", - "forex_id": "SGD", - "coinpaprika_id": "xsgd-xsgd", - "coingecko_id": "xsgd", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "XSGD-PLG20": { - "coin": "XSGD-PLG20", - "name": "StraitsX SGD", - "forex_id": "SGD", - "coinpaprika_id": "xsgd-xsgd", - "coingecko_id": "xsgd", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "XTZ-BEP20": { - "coin": "XTZ-BEP20", - "name": "Tezos", - "coinpaprika_id": "xtz-tezos", - "coingecko_id": "tezos", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "XVC": { - "coin": "XVC", - "name": "Vanillacash", - "coinpaprika_id": "xvc-vcash", - "coingecko_id": "vcash", - "nomics_id": "XVC", - "electrum": [ - { - "url": "electrumx.xvc.ewmcx.org:50001", - "protocol": "TCP" - }, - { - "url": "failover.xvc.ewmcx.biz:50001", - "protocol": "TCP" - } - ], - "explorer_url": [ - "https://xvc.freicoin.info/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false, - "wallet_only": true - }, - "XVC-BEP20": { - "coin": "XVC-BEP20", - "name": "Vanillacash", - "coinpaprika_id": "xvc-vcash", - "coingecko_id": "vcash", - "nomics_id": "XVC", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "XVC-QRC20": { - "coin": "XVC-QRC20", - "name": "Vanillacash", - "coinpaprika_id": "xvc-vcash", - "coingecko_id": "vcash", - "nomics_id": "XVC", - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20", - "active": false, - "currently_enabled": false - }, - "XVS": { - "coin": "XVS", - "name": "Venus", - "coinpaprika_id": "xvs-venus", - "coingecko_id": "venus", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "YFI-AVX20": { - "coin": "YFI-AVX20", - "name": "yearn.finance", - "coinpaprika_id": "yfi-yearnfinance", - "coingecko_id": "yearn-finance", - "nomics_id": "YFI", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "YFI-BEP20": { - "coin": "YFI-BEP20", - "name": "yearn.finance", - "coinpaprika_id": "yfi-yearnfinance", - "coingecko_id": "yearn-finance", - "nomics_id": "YFI", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "YFI-ERC20": { - "coin": "YFI-ERC20", - "name": "yearn.finance", - "coinpaprika_id": "yfi-yearnfinance", - "coingecko_id": "yearn-finance", - "nomics_id": "YFI", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "YFI-FTM20": { - "coin": "YFI-FTM20", - "name": "yearn.finance", - "coinpaprika_id": "yfi-yearnfinance", - "coingecko_id": "yearn-finance", - "nomics_id": "YFI", - "nodes": [ - "https://rpc.ftm.tools/" - ], - "explorer_url": [ - "https://ftmscan.com/" - ], - "type": "FTM-20", - "active": false, - "currently_enabled": false - }, - "YFI-KRC20": { - "coin": "YFI-KRC20", - "name": "yearn.finance", - "coinpaprika_id": "yfi-yearnfinance", - "coingecko_id": "yearn-finance", - "nomics_id": "YFI", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "YFII-BEP20": { - "coin": "YFII-BEP20", - "name": "DFI.Money", - "coinpaprika_id": "yfii-dfimoney", - "coingecko_id": "yfii-finance", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "YFII-ERC20": { - "coin": "YFII-ERC20", - "name": "DFI.Money", - "coinpaprika_id": "yfii-dfimoney", - "coingecko_id": "yfii-finance", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "ZEC": { - "coin": "ZEC", - "name": "Zcash", - "coinpaprika_id": "zec-zcash", - "coingecko_id": "zcash", - "nomics_id": "ZEC", - "electrum": [ - { - "url": "electrum1.cipig.net:10058", - "ws_url": "electrum1.cipig.net:30058" - }, - { - "url": "electrum2.cipig.net:10058", - "ws_url": "electrum2.cipig.net:30058" - }, - { - "url": "electrum3.cipig.net:10058", - "ws_url": "electrum3.cipig.net:30058" - } - ], - "explorer_tx_url": "transactions/", - "explorer_url": [ - "https://explorer.zcha.in/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "ZER": { - "coin": "ZER", - "name": "Zero", - "coinpaprika_id": "zer-zero", - "coingecko_id": "zero", - "nomics_id": "ZER", - "electrum": [ - { - "url": "electrum1.cipig.net:10065" - }, - { - "url": "electrum2.cipig.net:10065" - }, - { - "url": "electrum3.cipig.net:10065" - } - ], - "explorer_url": [ - "https://insight.zerocurrency.io/insight/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "ZET-OLD": { - "coin": "ZET-OLD", - "name": "Zetacoin (OLD)", - "coinpaprika_id": "zet-zetacoin", - "coingecko_id": "zetacoin", - "nomics_id": "ZET", - "electrum": [ - { - "url": "failover.zet.ewmci.xyz:50002", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "electrumx.zet.ewmcx.info:50001", - "protocol": "TCP" - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/zet-old/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "ZET": { - "coin": "ZET", - "name": "Zetacoin", - "coinpaprika_id": "zet-zetacoin", - "coingecko_id": "zetacoin", - "nomics_id": "ZET", - "electrum": [ - { - "url": "207.180.252.200:50011", - "protocol": "TCP" - }, - { - "url": "zeta-seed-c.zetacoin.tech:50012", - "protocol": "SSL", - "disable_cert_verification": false - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/zet/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "ZIL-BEP20": { - "coin": "ZIL-BEP20", - "name": "Zilliqa", - "coinpaprika_id": "zil-zilliqa", - "coingecko_id": "zilliqa", - "nomics_id": "ZIL", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "ZILLA": { - "coin": "ZILLA", - "name": "ChainZilla", - "coinpaprika_id": "zilla-chainzilla", - "coingecko_id": "test-coin", - "nomics_id": "ZILLA", - "electrum": [ - { - "url": "electrum1.cipig.net:10028", - "ws_url": "electrum1.cipig.net:30028" - }, - { - "url": "electrum2.cipig.net:10028", - "ws_url": "electrum2.cipig.net:30028" - }, - { - "url": "electrum3.cipig.net:10028", - "ws_url": "electrum3.cipig.net:30028" - } - ], - "explorer_url": [ - "https://zilla.explorer.dexstats.info/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false - }, - "ZRX-AVX20": { - "coin": "ZRX-AVX20", - "name": "0x", - "coinpaprika_id": "zrx-0x", - "coingecko_id": "0x", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "ZRX-ERC20": { - "coin": "ZRX-ERC20", - "name": "0x", - "coinpaprika_id": "zrx-0x", - "coingecko_id": "0x", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "ZRX-PLG20": { - "coin": "ZRX-PLG20", - "name": "0x", - "coinpaprika_id": "zrx-0x", - "coingecko_id": "0x", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "tBTC-TEST": { - "coin": "tBTC-TEST", - "name": "tBTC (testnet)", - "is_testnet": true, - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "testnet.aranguren.org:51001", - "protocol": "TCP" - }, - { - "url": "electrum1.cipig.net:10068" - }, - { - "url": "electrum2.cipig.net:10068" - }, - { - "url": "electrum3.cipig.net:10068" - } - ], - "explorer_url": [ - "https://blockstream.info/testnet/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "QRC20": { - "is_testnet": true, - "active": false, - "coin": "QRC20", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "currently_enabled": false, - "explorer_url": [ - "https://testnet.qtum.info/" - ], - "name": "QRC20 (testnet)", - "type": "QRC-20" - }, - "tQTUM": { - "coin": "tQTUM", - "name": "tQTUM (testnet)", - "need_electrum": true, - "is_testnet": true, - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10071" - }, - { - "url": "electrum2.cipig.net:10071" - }, - { - "url": "electrum3.cipig.net:10071" - } - ], - "explorer_url": [ - "https://testnet.qtum.info/" - ], - "type": "QRC-20", - "active": false, - "currently_enabled": false - }, - "INK": { - "coin": "INK", - "name": "Ink", - "coingecko_id": "ink", - "coinpaprika_id": "ink-ink", - "nomics_id": "INK", - "active": false, - "currently_enabled": false, - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20" - }, - "SPC": { - "coin": "SPC", - "name": "SpaceChain", - "coingecko_id": "spacechain-erc-20", - "coinpaprika_id": "spc-spacechain", - "nomics_id": "SPC", - "active": false, - "currently_enabled": false, - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20" - }, - "HPY": { - "coin": "HPY", - "name": "Hyper Pay", - "coingecko_id": "hyper-pay", - "coinpaprika_id": "hpy-hyper-pay", - "nomics_id": "HPY", - "active": false, - "currently_enabled": false, - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20" - }, - "HLC": { - "coin": "HLC", - "name": "HalalChain", - "coingecko_id": "halalchain", - "coinpaprika_id": "hlc-halalchain", - "nomics_id": "HLC", - "active": false, - "currently_enabled": false, - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20" - }, - "LSTR": { - "coin": "LSTR", - "name": "Luna Stars", - "coingecko_id": "meetluna", - "coinpaprika_id": "lstr-luna-stars", - "nomics_id": "LSTR", - "active": false, - "currently_enabled": false, - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20" - }, - "QBT": { - "coin": "QBT", - "name": "Qbao", - "coingecko_id": "qbao", - "coinpaprika_id": "qbt-qbao", - "nomics_id": "QBT", - "active": false, - "currently_enabled": false, - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20" - }, - "OC": { - "coin": "OC", - "name": "OceanChain", - "coingecko_id": "oceanchain", - "coinpaprika_id": "oc-oceanchain", - "nomics_id": "OC", - "active": false, - "currently_enabled": false, - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20" - }, - "PUT": { - "coin": "PUT", - "name": "Profile Utility Token", - "coingecko_id": "profile-utility-token", - "coinpaprika_id": "put-profile-utility-token", - "nomics_id": "PUT", - "active": false, - "currently_enabled": false, - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20" - }, - "TSL": { - "coin": "TSL", - "name": "Energo", - "coingecko_id": "energo", - "coinpaprika_id": "tsl-energo", - "nomics_id": "TSL", - "active": false, - "currently_enabled": false, - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20" - }, - "QC": { - "coin": "QC", - "name": "Qcash", - "forex_id": "CNY", - "coingecko_id": "qcash", - "coinpaprika_id": "qc-qcash", - "nomics_id": "QC", - "active": false, - "currently_enabled": false, - "explorer_url": [ - "https://explorer.qtum.org/" - ], - "type": "QRC-20" - }, - "SFUSD": { - "coin": "SFUSD", - "name": "SmartUSD", - "forex_id": "USD", - "coinpaprika_id": "test-coin", - "coingecko_id": "test-coin", - "electrum": [ - { - "url": "electrum1.cipig.net:10070", - "ws_url": "electrum1.cipig.net:30070" - }, - { - "url": "electrum2.cipig.net:10070", - "ws_url": "electrum2.cipig.net:30070" - }, - { - "url": "electrum3.cipig.net:10070", - "ws_url": "electrum3.cipig.net:30070" - } - ], - "explorer_url": [ - "https://explorer.sfusd.kmd.sh/" - ], - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "ANT": { - "coin": "ANT", - "name": "Aragon", - "coinpaprika_id": "ant-aragon", - "coingecko_id": "aragon", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "BEST": { - "coin": "BEST", - "name": "Bitpanda Ecosystem Token", - "coinpaprika_id": "best-bitpanda-ecosystem-token", - "coingecko_id": "bitpanda-ecosystem-token", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "CEL-ERC20": { - "coin": "CEL-ERC20", - "name": "Celsius", - "coinpaprika_id": "cel-celsius", - "coingecko_id": "celsius-degree-token", - "nomics_id": "CEL", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "CEL-PLG20": { - "coin": "CEL-PLG20", - "name": "Celsius", - "coinpaprika_id": "cel-celsius", - "coingecko_id": "celsius-degree-token", - "nomics_id": "CEL", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "CENNZ": { - "coin": "CENNZ", - "name": "Centrality Token", - "coinpaprika_id": "cennz-centrality", - "coingecko_id": "centrality", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "CHSB-ERC20": { - "coin": "CHSB-ERC20", - "name": "SwissBorg", - "coinpaprika_id": "chsb-swissborg", - "coingecko_id": "swissborg", - "nomics_id": "CHSB", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "CHSB-PLG20": { - "coin": "CHSB-PLG20", - "name": "SwissBorg", - "coinpaprika_id": "chsb-swissborg", - "coingecko_id": "swissborg", - "nomics_id": "CHSB", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "CHZ-ERC20": { - "coin": "CHZ-ERC20", - "name": "chiliZ", - "coinpaprika_id": "chz-chiliz", - "coingecko_id": "chiliz", - "nomics_id": "CHZ", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "CHZ-KRC20": { - "coin": "CHZ-KRC20", - "name": "chiliZ", - "coinpaprika_id": "chz-chiliz", - "coingecko_id": "chiliz", - "nomics_id": "CHZ", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "CHZ-PLG20": { - "coin": "CHZ-PLG20", - "name": "chiliZ", - "coinpaprika_id": "chz-chiliz", - "coingecko_id": "chiliz", - "nomics_id": "CHZ", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "CRO-ERC20": { - "coin": "CRO-ERC20", - "name": "Crypto.com", - "coinpaprika_id": "cro-cryptocom-chain", - "coingecko_id": "crypto-com-chain", - "nomics_id": "CRO", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "CRO-KRC20": { - "coin": "CRO-KRC20", - "name": "Crypto.com", - "coinpaprika_id": "cro-cryptocom-chain", - "coingecko_id": "crypto-com-chain", - "nomics_id": "CRO", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "CRO-PLG20": { - "coin": "CRO-PLG20", - "name": "Crypto.com", - "coinpaprika_id": "cro-cryptocom-chain", - "coingecko_id": "crypto-com-chain", - "nomics_id": "CRO", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "CRV-ERC20": { - "coin": "CRV-ERC20", - "name": "Curve DAO Token", - "coinpaprika_id": "crv-curve-dao-token", - "coingecko_id": "curve-dao-token", - "nomics_id": "CRV", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "CRV-AVX20": { - "coin": "CRV-AVX20", - "name": "Curve DAO Token", - "coinpaprika_id": "crv-curve-dao-token", - "coingecko_id": "curve-dao-token", - "nomics_id": "CRV", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "CRV-FTM20": { - "coin": "CRV-FTM20", - "name": "Curve DAO Token", - "coinpaprika_id": "crv-curve-dao-token", - "coingecko_id": "curve-dao-token", - "nomics_id": "CRV", - "nodes": [ - "https://rpc.ftm.tools/" - ], - "explorer_url": [ - "https://ftmscan.com/" - ], - "type": "FTM-20", - "active": false, - "currently_enabled": false - }, - "CRV-KRC20": { - "coin": "CRV-KRC20", - "name": "Curve DAO Token", - "coinpaprika_id": "crv-curve-dao-token", - "coingecko_id": "curve-dao-token", - "nomics_id": "CRV", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "CRV-PLG20": { - "coin": "CRV-PLG20", - "name": "Curve DAO Token", - "coinpaprika_id": "crv-curve-dao-token", - "coingecko_id": "curve-dao-token", - "nomics_id": "CRV", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "CVC": { - "coin": "CVC", - "name": "Civic", - "coinpaprika_id": "cvc-civic", - "coingecko_id": "civic", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "CVT": { - "coin": "CVT", - "name": "CyberVeinToken", - "coinpaprika_id": "cvt-cybervein", - "coingecko_id": "cybervein", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "DX": { - "coin": "DX", - "name": "DxChain Token", - "coinpaprika_id": "dx-dxchain-token", - "coingecko_id": "dxchain", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "ENJ-ERC20": { - "coin": "ENJ-ERC20", - "name": "Enjin Coin", - "coinpaprika_id": "enj-enjin-coin", - "coingecko_id": "enjincoin", - "nomics_id": "ENJ", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "ENJ-KRC20": { - "coin": "ENJ-KRC20", - "name": "Enjin Coin", - "coinpaprika_id": "enj-enjin-coin", - "coingecko_id": "enjincoin", - "nomics_id": "ENJ", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "ENJ-PLG20": { - "coin": "ENJ-PLG20", - "name": "Enjin Coin", - "coinpaprika_id": "enj-enjin-coin", - "coingecko_id": "enjincoin", - "nomics_id": "ENJ", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "EURS-ERC20": { - "coin": "EURS-ERC20", - "name": "STASIS EURO", - "forex_id": "EUR", - "coinpaprika_id": "eurs-stasis-eurs", - "coingecko_id": "stasis-eurs", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "EURS-PLG20": { - "coin": "EURS-PLG20", - "name": "STASIS EURO", - "forex_id": "EUR", - "coinpaprika_id": "eurs-stasis-eurs", - "coingecko_id": "stasis-eurs", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "GNO-ERC20": { - "coin": "GNO-ERC20", - "name": "Gnosis", - "coinpaprika_id": "gno-gnosis", - "coingecko_id": "gnosis", - "nomics_id": "GNO", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "GNO-PLG20": { - "coin": "GNO-PLG20", - "name": "Gnosis", - "coinpaprika_id": "gno-gnosis", - "coingecko_id": "gnosis", - "nomics_id": "GNO", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "HEX-ERC20": { - "coin": "HEX-ERC20", - "name": "HEX", - "coinpaprika_id": "hex-hex", - "coingecko_id": "hex", - "nomics_id": "HEX", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "HEX-PLG20": { - "coin": "HEX-PLG20", - "name": "HEX", - "coinpaprika_id": "hex-hex", - "coingecko_id": "hex", - "nomics_id": "HEX", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "HOT-ERC20": { - "coin": "HOT-ERC20", - "name": "Holo", - "coinpaprika_id": "hot-holo", - "coingecko_id": "holotoken", - "nomics_id": "HOT", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "HOT-PLG20": { - "coin": "HOT-PLG20", - "name": "Holo", - "coinpaprika_id": "hot-holo", - "coingecko_id": "holotoken", - "nomics_id": "HOT", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "HT": { - "active": false, - "coin": "HT", - "coingecko_id": "huobi-token", - "coinpaprika_id": "ht-huobi-token", - "nomics_id": "HT", - "currently_enabled": false, - "nodes": [ - "https://http-mainnet.hecochain.com" - ], - "explorer_url": [ - "https://hecoinfo.com/" - ], - "type": "HecoChain", - "name": "Huobi Token" - }, - "HT-ERC20": { - "coin": "HT-ERC20", - "name": "Huobi Token", - "coinpaprika_id": "ht-huobi-token", - "coingecko_id": "huobi-token", - "nomics_id": "HT", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "HUSD-ERC20": { - "coin": "HUSD-ERC20", - "name": "HUSD", - "coinpaprika_id": "husd-husd", - "coingecko_id": "husd", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "HUSD-HCO20": { - "coin": "HUSD-HCO20", - "name": "HUSD", - "coinpaprika_id": "husd-husd", - "coingecko_id": "husd", - "nodes": [ - "https://http-mainnet.hecochain.com" - ], - "explorer_url": [ - "https://hecoinfo.com/" - ], - "type": "HecoChain", - "active": false, - "currently_enabled": false - }, - "HUSD-KRC20": { - "coin": "HUSD-KRC20", - "name": "HUSD", - "coinpaprika_id": "husd-husd", - "coingecko_id": "husd", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "HUSD-PLG20": { - "coin": "HUSD-PLG20", - "name": "HUSD", - "coinpaprika_id": "husd-husd", - "coingecko_id": "husd", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "LEASH-ERC20" : { - "coin": "LEASH-ERC20", - "name": "Doge Killer", - "coinpaprika_id": "leash-doge-killer", - "coingecko_id": "leash", - "nomics_id": "LEASH", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "LEO-ERC20": { - "coin": "LEO-ERC20", - "name": "LEO Token", - "coinpaprika_id": "leo-leo-token", - "coingecko_id": "leo-token", - "nomics_id": "LEO", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "LEO-PLG20": { - "coin": "LEO-PLG20", - "name": "LEO Token", - "coinpaprika_id": "leo-leo-token", - "coingecko_id": "leo-token", - "nomics_id": "LEO", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "LRC-ERC20": { - "coin": "LRC-ERC20", - "name": "Loopring", - "coinpaprika_id": "lrc-loopring", - "coingecko_id": "loopring", - "nomics_id": "LRC", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "LRC-PLG20": { - "coin": "LRC-PLG20", - "name": "Loopring", - "coinpaprika_id": "lrc-loopring", - "coingecko_id": "loopring", - "nomics_id": "LRC", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "MANA-ERC20": { - "coin": "MANA-ERC20", - "name": "Decentraland", - "coinpaprika_id": "mana-decentraland", - "coingecko_id": "decentraland", - "nomics_id": "MANA", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "MANA-KRC20": { - "coin": "MANA-KRC20", - "name": "Decentraland", - "coinpaprika_id": "mana-decentraland", - "coingecko_id": "decentraland", - "nomics_id": "MANA", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "MANA-PLG20": { - "coin": "MANA-PLG20", - "name": "Decentraland", - "coinpaprika_id": "mana-decentraland", - "coingecko_id": "decentraland", - "nomics_id": "MANA", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "MLN": { - "coin": "MLN", - "name": "Melon Token", - "coinpaprika_id": "mln-melon", - "coingecko_id": "melon", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "OKB": { - "coin": "OKB", - "name": "OKB", - "coinpaprika_id": "okb-okb", - "coingecko_id": "okb", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "PNK": { - "coin": "PNK", - "name": "Pinakion", - "coinpaprika_id": "pnk-kleros", - "coingecko_id": "kleros", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "POWR-ERC20": { - "coin": "POWR-ERC20", - "name": "Power Ledger", - "coinpaprika_id": "powr-power-ledger", - "coingecko_id": "power-ledger", - "nomics_id": "POWR", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "POWR-PLG20": { - "coin": "POWR-PLG20", - "name": "Power Ledger", - "coinpaprika_id": "powr-power-ledger", - "coingecko_id": "power-ledger", - "nomics_id": "POWR", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "PRCY-BEP20": { - "coin": "PRCY-BEP20", - "name": "PRivaCY Coin", - "coinpaprika_id": "prcy-privacy-coin", - "coingecko_id": "privacy-coin", - "nomics_id": "PRCY", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "PRCY-ERC20": { - "coin": "PRCY-ERC20", - "name": "PRivaCY Coin", - "coinpaprika_id": "prcy-privacy-coin", - "coingecko_id": "privacy-coin", - "nomics_id": "PRCY", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "PRCY-PLG20": { - "coin": "PRCY-PLG20", - "name": "PRivaCY Coin", - "coinpaprika_id": "prcy-privacy-coin", - "coingecko_id": "privacy-coin", - "nomics_id": "PRCY", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "REP": { - "coin": "REP", - "name": "Reputation", - "coinpaprika_id": "rep-augur", - "coingecko_id": "augur", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "REV": { - "coin": "REV", - "name": "Revain", - "coinpaprika_id": "rev-revain", - "coingecko_id": "revain", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "RLC-ERC20": { - "coin": "RLC-ERC20", - "name": "iExec RLC", - "coinpaprika_id": "rlc-iexec-rlc", - "coingecko_id": "iexec-rlc", - "nomics_id": "RLC", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "RLC-PLG20": { - "coin": "RLC-PLG20", - "name": "iExec RLC", - "coinpaprika_id": "rlc-iexec-rlc", - "coingecko_id": "iexec-rlc", - "nomics_id": "RLC", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "S4F": { - "coin": "S4F", - "name": "S4FE", - "coinpaprika_id": "s4f-s4fe", - "coingecko_id": "s4fe", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "SHIB-BEP20": { - "coin": "SHIB-BEP20", - "name": "Shiba Inu", - "coinpaprika_id": "shib-shiba-inu", - "coingecko_id": "shiba-inu", - "nomics_id": "SHIB", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "SHIB-ERC20": { - "coin": "SHIB-ERC20", - "name": "Shiba Inu", - "coinpaprika_id": "shib-shiba-inu", - "coingecko_id": "shiba-inu", - "nomics_id": "SHIB", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "SHR": { - "coin": "SHR", - "name": "ShareToken", - "coinpaprika_id": "shr-sharetoken", - "coingecko_id": "sharering", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "SKL": { - "coin": "SKL", - "name": "SKALE", - "coinpaprika_id": "skl-skale", - "coingecko_id": "skale", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "SNT": { - "coin": "SNT", - "name": "StatusNetwork", - "coinpaprika_id": "snt-status", - "coingecko_id": "status", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "SRM-ERC20": { - "coin": "SRM-ERC20", - "name": "Serum", - "coinpaprika_id": "srm-serum", - "coingecko_id": "serum", - "nomics_id": "SRM", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "SRM-PLG20": { - "coin": "SRM-PLG20", - "name": "Serum", - "coinpaprika_id": "srm-serum", - "coingecko_id": "serum", - "nomics_id": "SRM", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "STORJ": { - "coin": "STORJ", - "name": "Storj", - "coinpaprika_id": "storj-storj", - "coingecko_id": "storj", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "TMTG": { - "coin": "TMTG", - "name": "The Midas Touch Gold", - "coinpaprika_id": "tmtg-the-midas-touch-gold", - "coingecko_id": "the-midas-touch-gold", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "TRAC": { - "coin": "TRAC", - "name": "Trace", - "coinpaprika_id": "trac-origintrail", - "coingecko_id": "origintrail", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "TTT": { - "coin": "TTT", - "name": "The Transfer Token", - "coinpaprika_id": "ttt-the-transfer-token", - "coingecko_id": "the-transfer-token", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "UBQ": { - "coin": "UBQ", - "name": "Ubiq", - "coinpaprika_id": "ubq-ubiq", - "coingecko_id": "ubiq", - "nomics_id": "UBQ", - "nodes": [ - "https://rpc.octano.dev/" - ], - "explorer_url": [ - "https://ubiqscan.io/" - ], - "type": "Ubiq", - "active": false, - "currently_enabled": false - }, - "UBT-ERC20": { - "coin": "UBT-ERC20", - "name": "Unibright", - "coinpaprika_id": "ubt-unibright", - "coingecko_id": "unibright", - "nomics_id": "UBT", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "UBT-PLG20": { - "coin": "UBT-PLG20", - "name": "Unibright", - "coinpaprika_id": "ubt-unibright", - "coingecko_id": "unibright", - "nomics_id": "UBT", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "UMA-AVX20": { - "coin": "UMA-AVX20", - "name": "UMA", - "coinpaprika_id": "uma-uma", - "coingecko_id": "uma", - "nomics_id": "UMA", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "UMA-ERC20": { - "coin": "UMA-ERC20", - "name": "UMA", - "coinpaprika_id": "uma-uma", - "coingecko_id": "uma", - "nomics_id": "UMA", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "UMA-PLG20": { - "coin": "UMA-PLG20", - "name": "UMA", - "coinpaprika_id": "uma-uma", - "coingecko_id": "uma", - "nomics_id": "UMA", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "UNI-AVX20": { - "coin": "UNI-AVX20", - "name": "Uniswap", - "coinpaprika_id": "uni-uniswap", - "coingecko_id": "uniswap", - "nodes": [ - "https://api.avax.network/ext/bc/C/rpc" - ], - "explorer_url": [ - "https://snowtrace.io/" - ], - "type": "AVX-20", - "active": false, - "currently_enabled": false - }, - "UNI-BEP20": { - "coin": "UNI-BEP20", - "name": "Uniswap", - "coinpaprika_id": "uni-uniswap", - "coingecko_id": "uniswap", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "UNI-ERC20": { - "coin": "UNI-ERC20", - "name": "Uniswap", - "coinpaprika_id": "uni-uniswap", - "coingecko_id": "uniswap", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "UNI-HCO20": { - "coin": "UNI-HCO20", - "name": "Uniswap", - "coinpaprika_id": "uni-uniswap", - "coingecko_id": "uniswap", - "nodes": [ - "https://http-mainnet.hecochain.com" - ], - "explorer_url": [ - "https://hecoinfo.com/" - ], - "type": "HecoChain", - "active": false, - "currently_enabled": false - }, - "UNI-KRC20": { - "coin": "UNI-KRC20", - "name": "Uniswap", - "coinpaprika_id": "uni-uniswap", - "coingecko_id": "uniswap", - "nodes": [ - "https://rpc-mainnet.kcc.network" - ], - "explorer_url": [ - "https://explorer.kcc.io/en/" - ], - "type": "KRC-20", - "active": false, - "currently_enabled": false - }, - "UNI-PLG20": { - "coin": "UNI-PLG20", - "name": "Uniswap", - "coinpaprika_id": "uni-uniswap", - "coingecko_id": "uniswap", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "UOS": { - "coin": "UOS", - "name": "Ultra Token", - "coinpaprika_id": "uos-ultra", - "coingecko_id": "ultra", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "UQC": { - "coin": "UQC", - "name": "Uquid Coin", - "coinpaprika_id": "uqc-uquid-coin", - "coingecko_id": "uquid-coin", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "USBL": { - "coin": "USBL", - "name": "Balanced Dollar", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "nomics_id": "USBL", - "electrum": [ - { - "url": "swap.softbalanced.com:50001", - "protocol": "TCP" - }, - { - "url": "swap.softbalanced.com:50002", - "protocol": "SSL", - "disable_cert_verification": true - } - ], - "explorer_url": [ - "https://softbalanced.com:3001/insight/" - ], - "explorer_tx_url": "tx/", - "type": "UTXO", - "active": false, - "currently_enabled": false - }, - "UTK": { - "coin": "UTK", - "name": "UTRUST", - "coinpaprika_id": "utk-utrust", - "coingecko_id": "utrust", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "VGX-ERC20": { - "coin": "VGX-ERC20", - "name": "Voyager", - "coinpaprika_id": "ethos-ethos", - "coingecko_id": "ethos", - "nomics_id": "VGX", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "VGX-PLG20": { - "coin": "VGX-PLG20", - "name": "Voyager", - "coinpaprika_id": "ethos-ethos", - "coingecko_id": "ethos", - "nomics_id": "VGX", - "nodes": [ - "https://polygon-rpc.com" - ], - "explorer_url": [ - "https://polygonscan.com/" - ], - "type": "Matic", - "active": false, - "currently_enabled": false - }, - "WHIVE": { - "coin": "WHIVE", - "name": "Whive", - "coingecko_id": "whive", - "coinpaprika_id": "whive-the-whive-protocol", - "nomics_id": "WHIVE", - "electrum": [ - { - "url": "electrumx1.cointest.com:50002", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "electrumx2.cointest.com:50002", - "protocol": "SSL", - "disable_cert_verification": true - }, - { - "url": "electrumx1.cointest.com:50001", - "protocol": "TCP" - }, - { - "url": "electrumx2.cointest.com:50001", - "protocol": "TCP" - } - ], - "explorer_url": [ - "https://whiveexplorer.cointest.com/" - ], - "type": "UTXO", - "active": false, - "is_segwit_on": false, - "currently_enabled": false - }, - "XOR": { - "coin": "XOR", - "name": "Sora Token", - "coinpaprika_id": "xor-sora", - "coingecko_id": "sora", - "nodes": [ - "http://eth1.cipig.net:8555", - "http://eth2.cipig.net:8555", - "http://eth3.cipig.net:8555" - ], - "explorer_url": [ - "https://etherscan.io/" - ], - "type": "ERC-20", - "active": false, - "currently_enabled": false - }, - "CIPHS": { - "coin": "CIPHS", - "name": "Ciphscoin", - "coingecko_id": "test-coin", - "coinpaprika_id": "test-coin", - "electrum": [ - { - "url": "152.89.247.97:10001" - }, - { - "url": "212.114.52.2:10001" - } - ], - "explorer_url": [ - "http://152.89.247.97:50604/" - ], - "type": "Smart Chain", - "active": false, - "currently_enabled": false - }, - "ZINU-BEP20": { - "coin": "ZINU-BEP20", - "name": "Zombie Inu", - "nomics_id": "ZINUBEP20", - "coinpaprika_id": "zombie-inu", - "coingecko_id": "zinu-zombie-inu", - "nodes": [ - "http://bsc1.cipig.net:8655", - "http://bsc2.cipig.net:8655", - "http://bsc3.cipig.net:8655" - ], - "explorer_url": [ - "https://bscscan.com/" - ], - "type": "BEP-20", - "active": false, - "currently_enabled": false - }, - "IC": { - "coin": "IC", - "name": "Ignition", - "coingecko_id": "ignition", - "coinpaprika_id": "ic-ignition", - "nomics_id": "IC", - "electrum": [ - { - "url": "electrum1.ignitioncoin.org:10001", - "protocol": "TCP" - }, - { - "url": "electrum2.ignitioncoin.org:10001", - "protocol": "TCP" - } - ], - "explorer_url": [ - "https://chainz.cryptoid.info/ic/" - ], - "explorer_tx_url": "tx.dws?", - "explorer_address_url": "address.dws?", - "type": "UTXO", - "active": false, - "currently_enabled": false - } -} diff --git a/assets/themes/Binance - Dark/colors.json b/assets/themes/Binance - Dark/colors.json new file mode 100644 index 0000000000..4a30ca5a52 --- /dev/null +++ b/assets/themes/Binance - Dark/colors.json @@ -0,0 +1,81 @@ +{ + "accentColor": "#0A0A0AFF", + "foregroundColor": "#ffffffFF", + "backgroundColor": "#161515FF", + "backgroundColorDeep": "#0A0A0AFF", + + "busyIndicatorColor": "#cb9800FF", + + "buttonColorDisabled": "#8B6900FF", + "buttonColorEnabled": "#cb9800FF", + "buttonColorHovered": "#EBB514FF", + "buttonColorPressed": "#EBB514FF", + "buttonTextDisabledColor": "#3B3B3BFF", + "buttonTextEnabledColor": "#fafffaFF", + "buttonTextHoveredColor": "#000000FF", + "buttonTextPressedColor": "#000000FF", + + "gradientButtonStartColor": "#cb9800FF", + "gradientButtonEndColor": "#cb9800FF", + "gradientButtonDisabledStartColor": "#8B6900FF", + "gradientButtonDisabledEndColor": "#8B6900FF", + "gradientButtonHoveredStartColor": "#EBB514FF", + "gradientButtonHoveredEndColor": "#EBB514FF", + "gradientButtonPressedStartColor": "#EBB514FF", + "gradientButtonPressedEndColor": "#EBB514FF", + "gradientButtonTextEnabledColor": "#080707FF", + "gradientButtonTextDisabledColor": "#3B3B3BFF", + "gradientButtonTextHoveredColor": "#000000FF", + "gradientButtonTextPressedColor": "#000000FF", + + "checkBoxTickColor": "#FFFFFFFF", + "checkBoxGradientStartColor": "#cb9800FF", + "checkBoxGradientEndColor": "#EBB514FF", + + "switchGradientStartColor": "#cb9800FF", + "switchGradientEndColor": "#EBB514FF", + "switchGradientStartColor2": "#FFFFFFFF", + "switchGradientEndColor2": "#FFFFFFFF", + + "modalPageCounterGradientStartColor": "#cb9800FF", + "modalPageCounterGradientEndColor": "#EBB514FF", + + "tabSelectedColor": "#EBB514FF", + + "textDisabledColor": "#444444FF", + "textSelectionColor": "#4986EAFF", + "textPlaceholderColor": "#8B6900FF", + "textSelectedColor": "#0e1021FF", + + "textFieldBackgroundColor": "#0e0e0eFF", + "textFieldActiveBackgroundColor": "#0c0c0cFF", + "textFieldPrefixColor": "#8790B2FF", + "textFieldSuffixColor": "#456078FF", + + "comboBoxBackgroundColor": "#0A0A0AFF", + "comboBoxArrowsColor": "#FFFFFFFF", + "comboBoxDropdownItemHighlightedColor": "#111111FF", + + "chartTradingLineBackgroundColor": "#24283dFF", + "chartTradingLineColor": "#74fbeeFF", + + "innerBackgroundColor": "#111111FF", + + "floatingBackgroundColor": "#222222FF", + + "sidebarBgColor": "#161515FF", + "sidebarVersionTextColor": "#BBBBBBFF", + "sidebarCursorStartColor": "#cb9800FF", + "sidebarCursorEndColor": "#EBB51400", + "sidebarLineTextHovered": "#8B6900FF", + + "okColor": "#74fbeeFF", + "noColor": "#d13990FF", + + "senderColorStart": "#F85757FF", + "receiverColorStart": "#845FEFFF", + "arrowUpColor": "#F85757FF", + "arrowDownColor": "#845FEFFF", + + "lineSeparatorColor": "#222222FF" +} \ No newline at end of file diff --git a/assets/themes/Default - Dark/colors.json b/assets/themes/Default - Dark/colors.json index 4e78b10e1d..ccd4c5acab 100644 --- a/assets/themes/Default - Dark/colors.json +++ b/assets/themes/Default - Dark/colors.json @@ -1,20 +1,19 @@ { "accentColor": "#212020", "foregroundColor": "#ffffff", - "foregroundColor2": "#7A8EA1FF", - "foregroundColor3": "#ABC0D3FF", - "backgroundColor": "#161515", - "secondBackgroundColor": "#1F1E1E", + "backgroundColor": "#1F1E1E", "backgroundColorDeep": "#1F1E1E", + "busyIndicatorColor": "#EB1C2EAF", + "buttonColorDisabled": "#3E34349A", "buttonColorEnabled": "#3E3434", "buttonColorHovered": "#3E34346A", "buttonColorPressed": "#3E34342A", "buttonTextDisabledColor": "#444444", "buttonTextEnabledColor": "#ffffff", - "buttonTextHoveredColor": "#ffffff", - "buttonTextPressedColor": "#ffffff", + "buttonTextHoveredColor": "#7A8EA1FF", + "buttonTextPressedColor": "#ABC0D3FF", "gradientButtonStartColor": "#9B1C2EFF", "gradientButtonEndColor": "#EE5C78FF", @@ -29,8 +28,9 @@ "gradientButtonTextHoveredColor": "#FFF", "gradientButtonTextPressedColor": "#FFF", - "checkBoxGradientStartColor": "#BA2A45FF", - "checkBoxGradientEndColor": "#BA2A45FF", + "checkBoxTickColor": "#FFFFFFFF", + "checkBoxGradientStartColor": "#6673E3FF", + "checkBoxGradientEndColor": "#5EBBF0FF", "switchGradientStartColor": "#BA2A45FF", "switchGradientEndColor": "#ECB6BEFF", @@ -66,8 +66,8 @@ "textFieldPrefixColor": "#FFFFFFFF", "textFieldSuffixColor": "#FFFFFFFF", - "chartTradingLineBackgroundColor": "#24283d", - "chartTradingLineColor": "#74fbee", + "chartTradingLineBackgroundColor": "#24283dFF", + "chartTradingLineColor": "#74fbeeFF", "innerBackgroundColor": "#1F1E1E", @@ -78,8 +78,9 @@ "rangeSliderIndicatorBackgroundStartColor": "#EE5C78FF", "rangeSliderIndicatorBackgroundEndColor": "#EE5C78FF", - "loginWalletIconColorStart": "#9B1C2E", - "loginWalletIconColorEnd": "#EE5C78", + "userIconColorStart": "#9B1C2E", + "userIconColorEnd": "#EE5C78", + "sidebarBgColor": "#161515FF", "sidebarVersionTextColor": "#878787FF", "sidebarCursorStartColor": "#BA2A45", @@ -93,11 +94,16 @@ "tradeSellModeSelectorBackgroundColorEnd": "#F48EA1FF", "tradeMarketModeSelectorNotSelectedBackgroundColor": "#89B6FF21", - "okColor": "#00C058", - "noColor": "#E52167", + "addressBookTagColors": ["#627EEAFF", "#FFD87AFF", "#F7931AFF"], + + "okColor": "#00C058FF", + "noColor": "#E52167FF", + + "senderColorStart": "#F85757FF", + "receiverColorStart": "#845FEFFF", - "arrowUpColor": "#F85757", - "arrowDownColor": "#845FEF", + "arrowUpColor": "#F85757FF", + "arrowDownColor": "#845FEFFF", "lineSeparatorColor": "#65656542" } diff --git a/assets/themes/Default - Light/colors.json b/assets/themes/Default - Light/colors.json index 1a584de697..8b22d12e81 100644 --- a/assets/themes/Default - Light/colors.json +++ b/assets/themes/Default - Light/colors.json @@ -1,20 +1,19 @@ { "accentColor": "#F0F0F0FF", "foregroundColor": "#110202", - "foregroundColor2": "#878787FF", - "foregroundColor3": "#8FA0B1B2", - "backgroundColor": "#FCFCFCFF", - "secondBackgroundColor": "#F9F5F5FF", + "backgroundColor": "#F9F5F5FF", "backgroundColorDeep": "#F9F5F5FF", + "busyIndicatorColor": "#CB1C2EAF", + "buttonColorDisabled": "#D8E3F8", "buttonColorEnabled": "#F0F6F9", "buttonColorHovered": "#F0F6F9AA", "buttonColorPressed": "#F0F6F97A", "buttonTextDisabledColor": "#444444", "buttonTextEnabledColor": "#110202", - "buttonTextHoveredColor": "#110202", - "buttonTextPressedColor": "#110202", + "buttonTextHoveredColor": "#878787FF", + "buttonTextPressedColor": "#8FA0B1B2", "gradientButtonStartColor": "#9B1C2EFF", "gradientButtonEndColor": "#EE5C78FF", @@ -29,8 +28,9 @@ "gradientButtonTextHoveredColor": "#EEF5FF", "gradientButtonTextPressedColor": "#EEF5FF", - "checkBoxGradientStartColor": "#BA2A45FF", - "checkBoxGradientEndColor": "#BA2A45FF", + "checkBoxTickColor": "#000000FF", + "checkBoxGradientStartColor": "#8892EBFF", + "checkBoxGradientEndColor": "#9DD4F3FF", "switchGradientStartColor": "#BA2A45FF", "switchGradientEndColor": "#ECB6BEFF", @@ -78,8 +78,9 @@ "rangeSliderIndicatorBackgroundStartColor": "#EE5C78FF", "rangeSliderIndicatorBackgroundEndColor": "#EE5C78FF", - "loginWalletIconColorStart": "#9B1C2E", - "loginWalletIconColorEnd": "#EE5C78", + "loginWalletIconColorStart": "#5A68E6FF", + "loginWalletIconColorEnd": "#4986EAAD", + "sidebarBgColor": "#FCFCFCFF", "sidebarVersionTextColor": "#110202FF", "sidebarCursorStartColor": "#F6D7DBFF", @@ -93,11 +94,16 @@ "tradeSellModeSelectorBackgroundColorEnd": "#F48EA1FF", "tradeMarketModeSelectorNotSelectedBackgroundColor": "#89B6FF21", - "okColor": "#00C058", - "noColor": "#E52167", + "addressBookTagColors": ["#627EEAFF", "#FFD87AFF", "#F7931AFF"], + + "okColor": "#00C058FF", + "noColor": "#E52167FF", + + "senderColorStart": "#F85757", + "receiverColorStart": "#845FEF", - "arrowUpColor": "#F85757", - "arrowDownColor": "#845FEF", + "arrowUpColor": "#F85757FF", + "arrowDownColor": "#845FEFFF", "lineSeparatorColor": "#65656542" } diff --git a/assets/tools/.gitignore b/assets/tools/.gitignore new file mode 100644 index 0000000000..b7e0b1c746 --- /dev/null +++ b/assets/tools/.gitignore @@ -0,0 +1,2 @@ +mm2 +coins diff --git a/atomic_defi_design/Dex/.gitignore b/atomic_defi_design/Dex/.gitignore new file mode 100644 index 0000000000..90d1f28b17 --- /dev/null +++ b/atomic_defi_design/Dex/.gitignore @@ -0,0 +1 @@ +qml.qrc \ No newline at end of file diff --git a/atomic_defi_design/Dex/Addressbook/AddAddressForm.qml b/atomic_defi_design/Dex/Addressbook/AddAddressForm.qml new file mode 100644 index 0000000000..7fdf8b444d --- /dev/null +++ b/atomic_defi_design/Dex/Addressbook/AddAddressForm.qml @@ -0,0 +1,315 @@ +import QtQuick 2.12 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 + +import Qaterial 1.0 as Qaterial + +import Dex.Themes 1.0 as Dex +import Dex.Components 1.0 as Dex +import "../Components" as Dex +import "../Constants" as Dex + +Dex.Rectangle +{ + id: root + + property var contactModel + + // Edition mode variables + property bool editionMode: false + property string addressType + property string addressKey + property string addressValue + + property var availableNetworkStandards: ["QRC-20", "ERC-20", "BEP-20", "Smart Chain", "SLP"] + + // Return the asset type that will be used in the backend to validate the address + function getTypeForAddressChecker(addressType) + { + switch (addressType) + { + case "QRC-20": return "QTUM" + case "BEP-20": return "BNB" + case "ERC-20": return "ETH" + case "Smart Chain": return "KMD" + case "SLP": return "USDT-SLP" + } + + let coinInfo = Dex.API.app.portfolio_pg.global_cfg_mdl.get_coin_info(addressType); + if (coinInfo.has_parent_fees_ticker && coinInfo.type !== "SLP") + return coinInfo.fees_ticker; + return addressType + } + + // Tells if the given address type represents a network standard address (e.g. BEP-20) + function isNetworkStandard(addressType) + { + switch (addressType) + { + case "QRC-20": return true + case "BEP-20": return true + case "ERC-20": return true + case "Smart Chain": return true + case "SLP": return true + } + return false + } + + signal cancel() + signal addressCreated() + + width: 500 + height: column.height + 26 + radius: 10 + + onVisibleChanged: + { + if (!visible) + { + // Resets data when address is added/edited. + addressKeyField.text = "" + addressValueField.text = "" + invalidAddressValueLabel.text = "" + editionMode = false + addressType = "" + addressKey = "" + addressValue = "" + } + else if (editionMode) + { + // Feeds form with the data we are currently editing. + + if (!isNetworkStandard(addressType)) + { + useStandardsCheckBox.checked = false + let addressTypeIndex = + Dex.API.app.portfolio_pg.global_cfg_mdl.all_proxy.match( + Dex.API.app.portfolio_pg.global_cfg_mdl.all_proxy.index(0, 0), + Qt.UserRole + 1, addressType, 1, Qt.MatchExactly)[0] + addressTypeComboBox.currentIndex = addressTypeIndex.row + } + else + { + useStandardsCheckBox.checked = true + let addressTypeIndex = availableNetworkStandards.indexOf(addressType) + addressTypeComboBox.currentIndex = addressTypeIndex + } + addressKeyField.text = addressKey + addressValueField.text = addressValue + } + } + + ColumnLayout + { + id: column + anchors.centerIn: parent + spacing: 17 + + RowLayout + { + Layout.preferredWidth: 458 + Layout.preferredHeight: 38 + + AddressTypeSelector + { + id: addressTypeComboBox + Layout.fillWidth: true + Layout.fillHeight: true + showAssetStandards: useStandardsCheckBox.checked + } + + RowLayout { + id: rowLayout + spacing: 4 + Dex.DefaultCheckBox + { + id: useStandardsCheckBox + Layout.preferredWidth: 30 + Layout.fillHeight: true + Layout.leftMargin: 4 + } + Dex.DefaultText { + Layout.minimumWidth: 120 + Layout.maximumWidth: 120 + text: qsTr("Use standard network address") + font: Dex.DexTypo.caption + } + } + } + + Dex.TextField + { + id: addressKeyField + Layout.preferredWidth: 458 + Layout.preferredHeight: 38 + placeholderText: qsTr("Label") + + Dex.ToolTip + { + id: addressKeyAlreadyExistsToolTip + contentItem: Dex.Text { text_value: qsTr("This key already exists.") } + } + } + + Dex.TextField + { + id: addressValueField + Layout.preferredWidth: 458 + Layout.preferredHeight: 38 + placeholderText: qsTr("Address") + } + + Dex.Text + { + id: invalidAddressValueLabel + Layout.preferredWidth: 458 + Layout.preferredHeight: 60 + visible: text !== "" + color: Dex.CurrentTheme.noColor + wrapMode: Dex.Text.WordWrap + elide: Dex.Text.ElideRight + horizontalAlignment: Text.AlignHCenter + } + + RowLayout + { + Layout.topMargin: 10 + Layout.fillWidth: true + + Dex.Button + { + Layout.preferredWidth: 116 + Layout.preferredHeight: 38 + radius: 18 + text: qsTr("Cancel") + onClicked: cancel() + } + + Item { Layout.fillWidth: true } + + Dex.GradientButton + { + property bool isConvertMode: Dex.API.app.wallet_pg.validate_address_data.convertible ?? false + + enabled: addressKeyField.length > 0 && addressValueField.length > 0 && !Dex.API.app.wallet_pg.validate_address_busy + Layout.preferredWidth: 116 + Layout.preferredHeight: 38 + radius: 18 + text: isConvertMode ? qsTr("Convert") : editionMode ? qsTr("Edit") : qsTr("Add") + onClicked: + { + let addressType = getTypeForAddressChecker(addressTypeComboBox.currentText) + + if (!Dex.API.app.portfolio_pg.global_cfg_mdl.get_coin_info(addressType).is_enabled) + { + enableAssetModal.assetTicker = addressType + enableAssetModal.open() + } + else if (isConvertMode) + Dex.API.app.wallet_pg.convert_address(addressValueField.text, addressType, Dex.API.app.wallet_pg.validate_address_data.to_address_format); + else + Dex.API.app.wallet_pg.validate_address(addressValueField.text, addressType) + } + } + } + } + + Connections + { + target: Dex.API.app.wallet_pg + + function onConvertAddressBusyChanged() + { + if (Dex.API.app.wallet_pg.convert_address_busy) // Currently converting entered address + { + return + } + + addressValueField.text = Dex.API.app.wallet_pg.converted_address + Dex.API.app.wallet_pg.validate_address_data = {} + invalidAddressValueLabel.text = "" + } + + function onValidateAddressBusyChanged() + { + if (Dex.API.app.wallet_pg.validate_address_busy) // Currently checking entered address + { + return + } + + let validation_data = Dex.API.app.wallet_pg.validate_address_data + if (!validation_data.is_valid) // Entered address is invalid. + { + invalidAddressValueLabel.text = validation_data.reason + + return + } + + if (editionMode) // Removes old address entry before if we are in edition mode. + { + contactModel.removeAddressEntry(addressType, addressKey); + } + + var createAddressResult = contactModel.addAddressEntry(addressTypeComboBox.currentText, addressKeyField.text, addressValueField.text); + if (createAddressResult === true) + { + addressCreated() + Dex.API.app.addressbookPg.model.proxy.searchExp = "x" + Dex.API.app.addressbookPg.model.proxy.searchExp = "" + } + else + { + addressKeyAlreadyExistsToolTip.visible = true + } + } + } + + Dex.ModalLoader + { + id: enableAssetModal + + property string assetTicker + + onLoaded: item.assetTicker = assetTicker + + sourceComponent: Dex.MultipageModal + { + property string assetTicker + Dex.MultipageModalContent + { + Layout.fillWidth: true + titleText: qsTr("Enable " + assetTicker) + + Dex.Text + { + Layout.fillWidth: true + text: qsTr("You need to enable %1 before adding this kind of address.").arg(assetTicker) + } + + footer: + [ + // Enable button + Dex.Button + { + text: qsTr("Enable") + + onClicked: + { + Dex.API.app.enable_coin(assetTicker) + close() + } + }, + + // Cancel button + Dex.Button + { + Layout.rightMargin: 5 + text: qsTr("Cancel") + + onClicked: close() + } + ] + } + } + } +} diff --git a/atomic_defi_design/Dex/Addressbook/AddTagPopup.qml b/atomic_defi_design/Dex/Addressbook/AddTagPopup.qml new file mode 100644 index 0000000000..0e53be333c --- /dev/null +++ b/atomic_defi_design/Dex/Addressbook/AddTagPopup.qml @@ -0,0 +1,60 @@ +// Qt Imports +import QtQuick 2.15 +import QtQuick.Layouts 1.15 + +// Project Imports +import "../Constants" +import Dex.Components 1.0 as Dex + +Dex.Popup +{ + id: root + + width: 250 + height: 55 + + onClosed: tagNameField.text = "" + + contentItem: Row + { + spacing: 4 + + Dex.TextField + { + id: tagNameField + width: parent.width * 0.6 + height: parent.height + placeholderText: qsTr("Tag name") + + Dex.ToolTip + { + id: tagAlreadyTakenToolTip + visible: false + timeout: 3000 + contentItem: Dex.Text + { + text_value: qsTr("Contact already has this tag.") + } + } + } + + Dex.Button + { + width: parent.width * 0.36 + height: parent.height + text: qsTr("+ ADD") + onClicked: + { + if (tagNameField.text.length === 0) + { + return + } + + var addTagResult = contactModel.addCategory(tagNameField.text) + + if (addTagResult === false) tagAlreadyTakenToolTip.visible = true + else root.close() + } + } + } +} diff --git a/atomic_defi_design/Dex/Addressbook/AddressTypeSelector.qml b/atomic_defi_design/Dex/Addressbook/AddressTypeSelector.qml new file mode 100644 index 0000000000..b8ad13881b --- /dev/null +++ b/atomic_defi_design/Dex/Addressbook/AddressTypeSelector.qml @@ -0,0 +1,102 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.3 + +import Qaterial 1.0 as Qaterial + +import Dex.Themes 1.0 as Dex +import Dex.Components 1.0 as Dex +import "../Components" as Dex +import "../Constants" as Dex + +Dex.ComboBoxWithSearchBar +{ + id: control + + property bool showAssetStandards: false + property var assetStandards: availableNetworkStandards + + function resetList() + { + if (showAssetStandards) currentIndex = 0; else { resetSearch(); currentIndex = 1 } + setContentItem(currentIndex) + } + + function resetSearch() + { + Dex.API.app.portfolio_pg.global_cfg_mdl.all_proxy.setFilterFixedString(""); + searchBar.textField.text = ""; + } + + function setContentItem(index) + { + if (showAssetStandards) + { + _contentRow.ticker = assetStandards[index] + _contentRow.name = assetStandards[index] + _contentRow.type = assetStandards[index] + } + else + { + _contentRow.ticker = model.data(model.index(index, 0), Qt.UserRole + 1) + _contentRow.name = model.data(model.index(index, 0), Qt.UserRole + 3) + _contentRow.type = model.data(model.index(index, 0), Qt.UserRole + 9) + } + } + + popupForceMaxHeight: true + popupMaxHeight: 220 + + model: showAssetStandards ? assetStandards : Dex.API.app.portfolio_pg.global_cfg_mdl.all_proxy + textRole: showAssetStandards ? "" : "ticker" + + searchBar.visible: !showAssetStandards + searchBar.searchModel: model + + delegate: ItemDelegate + { + id: _delegate + + visible: model.ticker !== "All" + + width: control.width + height: visible ? 40 : 0 + highlighted: control.highlightedIndex === index + + contentItem: AssetRow + { + ticker: showAssetStandards ? modelData : model.ticker + name: showAssetStandards ? modelData : model.name + type: showAssetStandards ? modelData : model.type + } + + background: Dex.Rectangle + { + anchors.fill: _delegate + color: _delegate.highlighted ? Dex.CurrentTheme.comboBoxDropdownItemHighlightedColor : Dex.CurrentTheme.comboBoxBackgroundColor + } + } + + contentItem: Item + { + AssetRow + { + id: _contentRow + + anchors.left: parent.left + anchors.leftMargin: 13 + anchors.verticalCenter: parent.verticalCenter + } + } + + onCurrentIndexChanged: + { + if (!showAssetStandards && currentIndex === 0 && searchBar.textField.text == "") currentIndex = 1 + setContentItem(currentIndex) + } + onActivated: setContentItem(index) + onShowAssetStandardsChanged: resetList() + onVisibleChanged: if (!visible) resetList() + Component.onDestruction: resetList() + Component.onCompleted: resetList() +} diff --git a/atomic_defi_design/Dex/Addressbook/AssetFromStandardSelector.qml b/atomic_defi_design/Dex/Addressbook/AssetFromStandardSelector.qml new file mode 100644 index 0000000000..c7416f1727 --- /dev/null +++ b/atomic_defi_design/Dex/Addressbook/AssetFromStandardSelector.qml @@ -0,0 +1,108 @@ +import QtQuick 2.12 +import QtQuick.Layouts 1.3 + +import Dex.Components 1.0 as Dex +import Dex.Themes 1.0 as Dex +import "../Constants" as Dex + +Dex.MultipageModal +{ + id: root + + property string standard + + signal selected(var assetTicker) + + width: 560 + + Component.onDestruction: + { + Dex.API.app.portfolio_pg.global_cfg_mdl.all_qrc20_proxy.setFilterFixedString("") + Dex.API.app.portfolio_pg.global_cfg_mdl.all_erc20_proxy.setFilterFixedString("") + Dex.API.app.portfolio_pg.global_cfg_mdl.all_bep20_proxy.setFilterFixedString("") + Dex.API.app.portfolio_pg.global_cfg_mdl.all_smartchains_proxy.setFilterFixedString("") + } + + Dex.MultipageModalContent + { + titleText: qsTr("Choose a valid ") + standard + qsTr(" asset") + contentSpacing: 8 + + Dex.SearchField + { + Layout.fillWidth: true + Layout.preferredHeight: 30 + textField.placeholderText: qsTr("Search an asset") + textField.onTextChanged: + { + switch (standard) + { + case "QRC-20": Dex.API.app.portfolio_pg.global_cfg_mdl.all_qrc20_proxy.setFilterFixedString(textField.text) + break; + case "ERC-20": Dex.API.app.portfolio_pg.global_cfg_mdl.all_erc20_proxy.setFilterFixedString(textField.text) + break; + case "BEP-20": Dex.API.app.portfolio_pg.global_cfg_mdl.all_bep20_proxy.setFilterFixedString(textField.text) + break; + default: Dex.API.app.portfolio_pg.global_cfg_mdl.all_smartchains_proxy.setFilterFixedString(textField.text) + break; + } + } + } + + Dex.ListView + { + id: list + + Layout.fillWidth: true + Layout.maximumHeight: 500 + + model: standard == "QRC-20" ? Dex.API.app.portfolio_pg.global_cfg_mdl.all_qrc20_proxy : + standard == "ERC-20" ? Dex.API.app.portfolio_pg.global_cfg_mdl.all_erc20_proxy : + standard == "BEP-20" ? Dex.API.app.portfolio_pg.global_cfg_mdl.all_bep20_proxy : + Dex.API.app.portfolio_pg.global_cfg_mdl.all_smartchains_proxy + + spacing: 8 + + delegate: Item + { + width: list.width + height: 40 + + Dex.Rectangle + { + anchors.fill: parent + color: mouseArea.containsMouse ? Dex.CurrentTheme.buttonColorHovered : "transparent" + } + + AssetRow + { + id: assetRow + height: parent.height + ticker: model.ticker + type: model.type + name: model.name + } + + Dex.Text + { + visible: !model.enabled + anchors.left: assetRow.right + anchors.leftMargin: 6 + anchors.verticalCenter: parent.verticalCenter + text: qsTr("Disabled") + color: Dex.CurrentTheme.noColor + font: Dex.DexTypo.caption + } + + Dex.MouseArea + { + id: mouseArea + + anchors.fill: parent + hoverEnabled: true + onClicked: root.selected(model.ticker) + } + } + } + } +} diff --git a/atomic_defi_design/Dex/Addressbook/AssetRow.qml b/atomic_defi_design/Dex/Addressbook/AssetRow.qml new file mode 100644 index 0000000000..12a4ee31d6 --- /dev/null +++ b/atomic_defi_design/Dex/Addressbook/AssetRow.qml @@ -0,0 +1,35 @@ +import QtQuick 2.12 + +import Dex.Components 1.0 as Dex +import "../Constants" as Dex + +Row +{ + property string ticker + property string name + property string type + + spacing: 10 + + Dex.Image + { + width: 25 + height: 25 + anchors.verticalCenter: parent.verticalCenter + source: Dex.General.coinIcon(ticker) + } + + Dex.Text + { + anchors.verticalCenter: parent.verticalCenter + text: name + } + + Dex.Text + { + anchors.verticalCenter: parent.verticalCenter + text: type + color: Dex.Style.getCoinTypeColor(type) + font: Dex.DexTypo.overLine + } +} diff --git a/atomic_defi_design/Dex/Addressbook/EditContactModal.qml b/atomic_defi_design/Dex/Addressbook/EditContactModal.qml new file mode 100644 index 0000000000..673c52936a --- /dev/null +++ b/atomic_defi_design/Dex/Addressbook/EditContactModal.qml @@ -0,0 +1,312 @@ +import QtQuick 2.12 +import QtQuick.Layouts 1.15 + +import Qaterial 1.0 as Qaterial + +import Dex.Themes 1.0 as Dex +import Dex.Components 1.0 as Dex +import "../Constants" as Dex + +Dex.MultipageModal +{ + id: root + + property var contactModel: { "name": "", "categories": [] } + + Dex.MultipageModalContent + { + titleText: qsTr("Edit contact") + titleTopMargin: 0 + titleAlignment: Qt.AlignHCenter + contentSpacing: 24 + + Dex.TextFieldWithTitle + { + id: contactNameInput + title: qsTr("Contact name") + field.placeholderText: qsTr("Enter a contact name") + field.text: contactModel.name + field.onTextChanged: if (field.text.length > 30) field.text = field.text.substring(0, 30) + } + + Column + { + id: addressList + property bool contactAddAddressMode: false + + Layout.fillWidth: true + spacing: 18 + + Dex.Text + { + text: qsTr("Address list") + } + + Dex.ListView + { + visible: !addressList.contactAddAddressMode + model: contactModel.proxyFilter + spacing: 10 + height: contentHeight > 190 ? 190 : contentHeight + width: parent.width + + delegate: Dex.MouseArea + { + id: addressRowMouseArea + height: 82 + width: addressList.width - 10 + hoverEnabled: true + + Dex.Rectangle + { + visible: parent.containsMouse + anchors.fill: parent + radius: 17 + color: Dex.CurrentTheme.accentColor + } + + Item + { + anchors.fill: parent + anchors.verticalCenter: parent.verticalCenter + anchors.margins: 10 + + ColumnLayout + { + property var coinInfo: Dex.API.app.portfolio_pg.global_cfg_mdl.get_coin_info(address_type) + + Row + { + spacing: 10 + Dex.Image + { + anchors.verticalCenter: parent.verticalCenter + width: 25 + height: 25 + source: Dex.General.coinIcon(address_type.toLowerCase()) + } + + Dex.Text + { + anchors.verticalCenter: parent.verticalCenter + text: address_type + } + + Dex.Text + { + anchors.verticalCenter: parent.verticalCenter + text: parent.parent.coinInfo.type + color: Dex.Style.getCoinTypeColor(parent.parent.coinInfo.type) + font: Dex.DexTypo.overLine + } + + Dex.Button + { + visible: addressRowMouseArea.containsMouse + anchors.verticalCenter: parent.verticalCenter + width: 9 + height: 9 + color: "transparent" + iconSource: Qaterial.Icons.close + onClicked: contactModel.removeAddressEntry(address_type, address_key) + } + } + + Dex.Text + { + Layout.leftMargin: 36 + Layout.maximumWidth: 330 + text: address_key + font: Dex.DexTypo.caption + elide: Text.ElideRight + } + + Dex.Text + { + Layout.leftMargin: 36 + Layout.maximumWidth: 330 + text: address_value + font: Dex.DexTypo.caption + elide: Text.ElideRight + + Dex.Button + { + width: 18 + height: 20 + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.right + anchors.leftMargin: 3 + color: "transparent" + iconSource: Qaterial.Icons.contentCopy + + onClicked: + { + Dex.API.qt_utilities.copy_text_to_clipboard(address_value) + app.notifyCopy(qsTr("Address Book"), qsTr("address copied to clipboard")) + } + } + } + } + + Row + { + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + spacing: 20 + + Dex.ClickableText + { + anchors.verticalCenter: parent.verticalCenter + visible: addressRowMouseArea.containsMouse + text: qsTr("Edit") + font.underline: true + onClicked: + { + addAddressForm.editionMode = true + addAddressForm.addressType = address_type + addAddressForm.addressKey = address_key + addAddressForm.addressValue = address_value + addressList.contactAddAddressMode = true + } + } + + Dex.Button + { + anchors.verticalCenter: parent.verticalCenter + width: 37 + height: 37 + radius: 18.5 + visible: addressRowMouseArea.containsMouse + iconSource: Qaterial.Icons.sendOutline + onClicked: + { + trySend(address_value, address_type) + } + } + } + } + } + } + + Dex.Button + { + visible: !addressList.contactAddAddressMode + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("+ Add") + width: 211 + height: 38 + radius: 18 + onClicked: addressList.contactAddAddressMode = true + } + + AddAddressForm + { + id: addAddressForm + visible: addressList.contactAddAddressMode + contactModel: root.contactModel + onCancel: addressList.contactAddAddressMode = false + onAddressCreated: addressList.contactAddAddressMode = false + } + } + + Column + { + Layout.fillWidth: true + spacing: 12 + + Dex.Text + { + text: qsTr("Tags") + } + + Dex.ListView + { + width: parent.width + model: contactModel.categories + orientation: Qt.Horizontal + spacing: 6 + delegate: Dex.MouseArea + { + width: tagBg.width + tagRemoveBut.width + 2 + height: tagBg.height + hoverEnabled: true + + Dex.Rectangle + { + id: tagBg + anchors.verticalCenter: parent.verticalCenter + width: tagLabel.width + 12 + height: 21 + radius: 20 + color: Dex.CurrentTheme.accentColor + + Dex.Text + { + id: tagLabel + anchors.centerIn: parent + text: modelData + } + } + + Dex.Button + { + id: tagRemoveBut + visible: parent.containsMouse + anchors.left: tagBg.right + anchors.leftMargin: 2 + anchors.verticalCenter: parent.verticalCenter + width: 18 + height: 18 + color: "transparent" + iconSource: Qaterial.Icons.close + onClicked: contactModel.removeCategory(modelData) + } + } + } + + Dex.Button + { + iconSource: Qaterial.Icons.plus + text: qsTr("Add tag") + font: Dex.DexTypo.body2 + color: "transparent" + onClicked: addTagPopup.open() + + AddTagPopup + { + y: -10 + x: parent.width + 10 + id: addTagPopup + } + } + } + + footer: + [ + Dex.Button + { + Layout.preferredWidth: 199 + Layout.preferredHeight: 48 + radius: 18 + text: qsTr("Cancel") + onClicked: root.close() + }, + + Item { Layout.fillWidth: true }, + + Dex.GradientButton + { + Layout.preferredWidth: 199 + Layout.preferredHeight: 48 + radius: 18 + text: qsTr("Confirm") + onClicked: + { + contactModel.name = contactNameInput.field.text + contactModel.save() + root.close() + } + } + ] + } +} diff --git a/atomic_defi_design/Dex/Addressbook/EnableAssetModal.qml b/atomic_defi_design/Dex/Addressbook/EnableAssetModal.qml new file mode 100644 index 0000000000..63317676f5 --- /dev/null +++ b/atomic_defi_design/Dex/Addressbook/EnableAssetModal.qml @@ -0,0 +1,46 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 + +import "../Constants" as Dex +import Dex.Components 1.0 as Dex + +Dex.MultipageModal +{ + property string assetTicker + + Dex.MultipageModalContent + { + Layout.fillWidth: true + titleText: qsTr("Enable " + assetTicker) + + Dex.Text + { + Layout.fillWidth: true + text: qsTr("The selected address belongs to a disabled asset, you need to enabled it before sending.") + } + + footer: + [ + // Enable button + Dex.Button + { + text: qsTr("Enable") + + onClicked: + { + Dex.API.app.enable_coin(assetTicker) + close() + } + }, + + // Cancel button + Dex.Button + { + Layout.rightMargin: 5 + text: qsTr("Cancel") + + onClicked: close() + } + ] + } +} diff --git a/atomic_defi_design/Dex/Addressbook/Main.qml b/atomic_defi_design/Dex/Addressbook/Main.qml new file mode 100644 index 0000000000..df7b1e4a2a --- /dev/null +++ b/atomic_defi_design/Dex/Addressbook/Main.qml @@ -0,0 +1,418 @@ +// Qt Imports +import QtQuick 2.15 +import QtQuick.Layouts 1.15 + +import Qaterial 1.0 as Qaterial + +// Project Imports +import Dex.Components 1.0 as Dex +import "../Components" as Dex +import Dex.Themes 1.0 as Dex +import "../Constants" as Dex +import "../Wallet" as Wallet + +Item +{ + function trySend(address, type) + { + // Checks if the selected address type represents an asset standard instead of an asset. + if (Dex.API.app.portfolio_pg.global_cfg_mdl.is_coin_type(type)) + { + assetFromStandardSelectorLoader.address = address + assetFromStandardSelectorLoader.standard = type + assetFromStandardSelectorLoader.open() + } + + // Checks if the asset is currently enabled. + else if (!Dex.API.app.portfolio_pg.is_coin_enabled(type)) + { + enabledAssetModalLoader.assetTicker = type; + enabledAssetModalLoader.open() + } + + // If the coin is enabled, opens the send modal. + else + { + if (assetFromStandardSelectorLoader.visible) + assetFromStandardSelectorLoader.close() + Dex.API.app.wallet_pg.ticker = type + sendModalLoader.address = address + sendModalLoader.open() + } + } + + ColumnLayout + { + anchors.fill: parent + anchors.margins: 30 + + spacing: 32 + + Row + { + Layout.fillWidth: true + + Column + { + width: parent.width * 0.5 + spacing: 34 + + Dex.Text + { + text: qsTr("Address Book") + font: Dex.DexTypo.head5 + } + + Dex.SearchField + { + id: searchbar + + width: 206 + height: 42 + textField.forceFocus: true + textField.placeholderText: qsTr("Search contact") + + textField.onTextChanged: Dex.API.app.addressbookPg.model.proxy.searchExp = textField.text + Component.onDestruction: Dex.API.app.addressbookPg.model.proxy.searchExp = "" + } + } + + Row + { + width: parent.width * 0.5 + layoutDirection: Qt.RightToLeft + + Dex.GradientButton + { + height: 40 + radius: 15 + text: qsTr("+ NEW CONTACT") + + onClicked: newContactPopup.open() + + NewContactPopup + { + id: newContactPopup + } + } + } + } + + // Contact table header + Row + { + Layout.fillWidth: true + Layout.topMargin: 30 + + Dex.Text + { + width: parent.width * 0.3 + text: qsTr("Name") + font: Dex.DexTypo.head8 + leftPadding: 18 + } + + Dex.Text + { + text: qsTr("Tags") + font: Dex.DexTypo.head8 + leftPadding: 18 + } + } + + // Contact table content + Dex.DefaultListView + { + id: contactTable + + function _getCurrentTagColorId() + { + if (typeof _getCurrentTagColorId.counter == 'undefined') + _getCurrentTagColorId.counter = 0 + if (_getCurrentTagColorId.counter >= Dex.CurrentTheme.addressBookTagColors.length) + _getCurrentTagColorId.counter = 0 + + return _getCurrentTagColorId.counter++ + } + + Layout.fillWidth: true + Layout.fillHeight: true + + model: Dex.API.app.addressbookPg.model.proxy + + delegate: Dex.Expandable + { + id: expandable + + padding: 10 + color: index % 2 === 0 ? Dex.CurrentTheme.innerBackgroundColor : Dex.CurrentTheme.backgroundColor + width: contactTable.width + + header: Item + { + height: 56 + width: expandable.width + + Dex.DefaultMouseArea + { + anchors.fill: parent + onClicked: expandable.isExpanded = !expandable.isExpanded + } + + Row + { + width: parent.width * 0.3 + anchors.verticalCenter: parent.verticalCenter + spacing: 12 + + Dex.UserIcon + { + anchors.verticalCenter: parent.verticalCenter + } + + Dex.Text + { + anchors.verticalCenter: parent.verticalCenter + text: modelData.name + } + + Dex.Arrow + { + anchors.verticalCenter: parent.verticalCenter + up: expandable.isExpanded + } + } + + Flow + { + anchors.verticalCenter: parent.verticalCenter + x: parent.width * 0.3 + width: parent.width * 0.57 + spacing: 17 + + Repeater + { + model: modelData.categories.slice(0, 6) + + delegate: Dex.Rectangle + { + property int _currentColorIndex: contactTable._getCurrentTagColorId() + + width: tagLabel.width > 73 ? 83 : tagLabel.width + 10 + height: 21 + radius: 20 + color: Dex.CurrentTheme.addressBookTagColors[_currentColorIndex] + + Dex.MouseArea + { + anchors.fill: parent + onClicked: searchbar.textField.text = modelData + } + + Dex.Text + { + id: tagLabel + width: 70 + anchors.centerIn: parent + text: modelData + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight + } + } + } + } + + Row + { + spacing: 45 + width: edit_contact.implicitWidth + delete_contact.implicitWidth + 65 + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 20 + + Dex.ClickableText + { + id: edit_contact + anchors.verticalCenter: parent.verticalCenter + font: Dex.DexTypo.underline14 + text: qsTr("Edit") + onClicked: + { + editContactLoader.contactModel = modelData + editContactLoader.open() + } + } + + Dex.ClickableText + { + id: delete_contact + anchors.verticalCenter: parent.verticalCenter + font: Dex.DexTypo.underline14 + text: qsTr("Delete") + onClicked: removeContactPopup.open() + + RemoveContactPopup + { + id: removeContactPopup + + contactName: modelData.name + } + } + } + } + + content: Item + { + height: noAddressLabel.visible ? 50 : addressList.height + width: contactTable.width + + Dex.ListView + { + id: addressList + + visible: addressList.model.rowCount() > 0 + x: 30 + model: modelData.proxyFilter + width: parent.width - 40 + implicitHeight: contentHeight > 240 ? 240 : contentHeight + spacing: 18 + + delegate: Item + { + property var coinInfo: Dex.API.app.portfolio_pg.global_cfg_mdl.get_coin_info(address_type) + + width: addressList.width + height: 30 + + Row + { + anchors.verticalCenter: parent.verticalCenter + spacing: 10 + Dex.Image + { + anchors.verticalCenter: parent.verticalCenter + width: 25 + height: 25 + source: Dex.General.coinIcon(address_type.toLowerCase()) + } + + Dex.Text + { + anchors.verticalCenter: parent.verticalCenter + text: address_type + } + + Dex.Text + { + anchors.verticalCenter: parent.verticalCenter + text: parent.parent.coinInfo.type + color: Dex.Style.getCoinTypeColor(parent.parent.coinInfo.type) + font: Dex.DexTypo.overLine + } + } + + Row + { + x: parent.width * 0.25 + spacing: 3 + + Dex.Text + { + anchors.verticalCenter: parent.verticalCenter + text: "%1 : %2".arg(address_key).arg(address_value) + } + + + Dex.Button + { + width: 25 + height: 25 + iconSource: Qaterial.Icons.contentCopy + color: "transparent" + onClicked: + { + Dex.API.qt_utilities.copy_text_to_clipboard(address_value) + app.notifyCopy(qsTr("Address Book"), qsTr("address copied to clipboard")) + } + } + + Dex.Button + { + width: 25 + height: 25 + iconSource: Qaterial.Icons.sendOutline + color: "transparent" + onClicked: trySend(address_value, address_type) + } + } + } + } + + Dex.Text + { + id: noAddressLabel + height: 20 + x: 30 + y: 15 + visible: addressList.model.rowCount() === 0 + text: qsTr("This contact does not have any registered address.") + } + } + } + } + } + + Dex.ModalLoader + { + id: editContactLoader + + property var contactModel + + onLoaded: item.contactModel = contactModel + + sourceComponent: EditContactModal { } + } + + Dex.ModalLoader + { + id: sendModalLoader + + property string address + + onLoaded: item.address_field.text = address + + sourceComponent: Wallet.SendModal + { + address_field.enabled: false + } + } + + Dex.ModalLoader + { + id: assetFromStandardSelectorLoader + + property string standard + property string address + + onLoaded: item.standard = standard + + sourceComponent: AssetFromStandardSelector + { + onSelected: + { + trySend(assetFromStandardSelectorLoader.address, assetTicker) + } + } + } + + Dex.ModalLoader + { + id: enabledAssetModalLoader + + property string assetTicker + + onLoaded: item.assetTicker = assetTicker + + sourceComponent: EnableAssetModal { } + } +} diff --git a/atomic_defi_design/Dex/Addressbook/NewContactPopup.qml b/atomic_defi_design/Dex/Addressbook/NewContactPopup.qml new file mode 100644 index 0000000000..4c61b27c64 --- /dev/null +++ b/atomic_defi_design/Dex/Addressbook/NewContactPopup.qml @@ -0,0 +1,74 @@ +// Qt Imports +import QtQuick 2.15 +import QtQuick.Layouts 1.15 + +// Project Imports +import "../Components" +import "../Constants" +import Dex.Components 1.0 as Dex + +Dex.Popup +{ + id: root + width: parent.width < 180 ? 180 : parent.width + height: 88 + onOpened: nameField.forceActiveFocus() + onClosed: nameField.text = "" + + contentItem: Column + { + id: new_contact_input + anchors.centerIn: parent + anchors.fill: parent + anchors.margins: 8 + spacing: 8 + + Dex.TextField + { + id: nameField + height: 30 + width: parent.width - 20 + anchors.horizontalCenter: parent.horizontalCenter + placeholderText: qsTr("Contact name") + + Dex.ToolTip + { + id: nameAlreadyTakenToolTip + visible: false + timeout: 3000 + contentItem: Dex.Text + { + text_value: qsTr("This contact name already exists.") + } + } + } + + DefaultButton + { + id: add_contact_btn + font: DexTypo.body2 + text: qsTr("+ ADD") + height: 30 + anchors.horizontalCenter: parent.horizontalCenter + onClicked: + { + if (nameField.text.length === 0) + { + return + } + + var createContactResult = API.app.addressbookPg.model.addContact(nameField.text) + + if (createContactResult === false) nameAlreadyTakenToolTip.visible = true + else + { + root.close() + + let contactModelIndex = API.app.addressbookPg.model.index(API.app.addressbookPg.model.rowCount() - 1, 0) + editContactLoader.contactModel = API.app.addressbookPg.model.data(contactModelIndex, Qt.UserRole + 1) + editContactLoader.open() + } + } + } + } +} diff --git a/atomic_defi_design/Dex/Addressbook/RemoveContactPopup.qml b/atomic_defi_design/Dex/Addressbook/RemoveContactPopup.qml new file mode 100644 index 0000000000..419c5c64b4 --- /dev/null +++ b/atomic_defi_design/Dex/Addressbook/RemoveContactPopup.qml @@ -0,0 +1,51 @@ +// Qt Imports +import QtQuick 2.15 +import QtQuick.Layouts 1.15 + +// Project Imports +import "../Constants" as Dex +import Dex.Components 1.0 as Dex + +Dex.Popup +{ + id: root + + property string contactName + + width: 140 + height: 120 + + contentItem: ColumnLayout + { + spacing: 8 + width: root.width + + Dex.Text + { + Layout.fillWidth: true + text: qsTr("Do you want to remove this contact ?") + } + + Row + { + Layout.fillWidth: true + spacing: 6 + Dex.ClickableText + { + text: qsTr("Yes") + font.underline: true + onClicked: + { + Dex.API.app.addressbookPg.model.removeContact(contactName) + close() + } + } + Dex.ClickableText + { + text: qsTr("No") + font.underline: true + onClicked: close() + } + } + } +} diff --git a/atomic_defi_design/Dex/App.qml b/atomic_defi_design/Dex/App.qml index 44999a5cd1..b0137c1c15 100644 --- a/atomic_defi_design/Dex/App.qml +++ b/atomic_defi_design/Dex/App.qml @@ -23,28 +23,37 @@ DexRectangle // This enumeration represents every possible visual state (commonly named "screen") of the application enum ScreenType { - Startup, // Wallets selection, login, create wallet, import wallet, etc. - Dashboard // After logged to a wallet. + Startup, // Wallets selection, login, create wallet, import wallet, etc. + Dashboard // After logged to a wallet. } property string currentWalletName: API.app.wallet_mgr.wallet_default_name property bool debug: debug_bar - property - var notification_modal: notifications_modal - property - var notifications_list: _currentPage === App.ScreenType.Dashboard ? loader.item.notifications_list : [] + property var notification_modal: notifications_modal + property var logout_confirm_modal: logout_modal + property var notifications_list: _currentPage === App.ScreenType.Dashboard ? loader.item.notifications_list : [] property bool segwit_on: false - property - var _currentPage: API.app.wallet_mgr.log_status() ? App.ScreenType.Dashboard : App.ScreenType.Startup - property - var _availablePages: [_startup, dashboard] + property var _currentPage: API.app.wallet_mgr.log_status() ? App.ScreenType.Dashboard : App.ScreenType.Startup + property var _availablePages: [_startup, dashboard] + property alias pageLoader: loader + property alias globalGradient: globalGradient // Preload Chart signal pairChanged(string base, string rel) + + function return_to_login() { + app.notifications_list = [] + userMenu.close() + app.currentWalletName = "" + API.app.disconnect() + app.onDisconnect() + window.logged = false + logout_modal.close() + } function onDisconnect() { @@ -137,6 +146,12 @@ DexRectangle error_log_modal.item.field.text = content } + ModalLoader + { + id: logout_modal + sourceComponent: LogoutModal {} + } + // Toast ToastManager { @@ -146,7 +161,7 @@ DexRectangle // Update Modal NewUpdateModal { - id: new_update_modal + id: newUpdateModal visible: false } @@ -422,15 +437,10 @@ DexRectangle return dialog } - function showText(data) - { - return showDialog(data); - } - function getText(data) { data['getText'] = true; - return showText(data); + return showDialog(data); } Component.onCompleted: diff --git a/atomic_defi_design/Dex/Components/Arrow.qml b/atomic_defi_design/Dex/Components/Arrow.qml index 7e2df67f7e..827d13e558 100644 --- a/atomic_defi_design/Dex/Components/Arrow.qml +++ b/atomic_defi_design/Dex/Components/Arrow.qml @@ -1,8 +1,9 @@ +// Qt Imports import QtQuick 2.15 -import "../Constants" -import "../Components" -import Dex.Themes 1.0 as Dex +// Project Imports +import "../Constants" //> General.image_path +import Dex.Themes 1.0 as Dex //> CurrentTheme Item { property bool up: true @@ -27,7 +28,7 @@ Item { anchors.fill: img source: img - color: up ? Dex.CurrentTheme.arrowUpColor : Dex.CurrentTheme.arrowDownColor + color: Dex.CurrentTheme.foregroundColor } } diff --git a/atomic_defi_design/Dex/Components/CheckEye.qml b/atomic_defi_design/Dex/Components/CheckEye.qml new file mode 100644 index 0000000000..e3bb0bca61 --- /dev/null +++ b/atomic_defi_design/Dex/Components/CheckEye.qml @@ -0,0 +1,55 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.12 + +import Qaterial 1.0 as Qaterial + +import App 1.0 +import Dex.Themes 1.0 as Dex + +Item +{ + id: control + + property alias text: _label.text + property alias iconSource: _icon.source + property var target + + width: parent.width + height: row.height + + RowLayout + { + id: row + width: parent.width - 20 + spacing: 10 + + Qaterial.ColorIcon + { + id: _icon + Layout.alignment: Qt.AlignVCenter + source: target.visible ? Qaterial.Icons.eyeOutline : Qaterial.Icons.eyeOffOutline + color: target.visible ? Dex.CurrentTheme.foregroundColor : Dex.CurrentTheme.buttonTextDisabledColor + iconSize: 17 + } + + DefaultText + { + id: _label + font.pixelSize: 15 + text: "" + color: target.visible ? Dex.CurrentTheme.foregroundColor : Dex.CurrentTheme.buttonTextDisabledColor + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter + } + } + + DefaultMouseArea + { + anchors.fill: parent + onClicked: + { + if (target.visible) target.visible = false + else target.visible = true + } + } +} diff --git a/atomic_defi_design/Dex/Components/ClickableText.qml b/atomic_defi_design/Dex/Components/ClickableText.qml index 8f1af06991..7c4c6e86b6 100644 --- a/atomic_defi_design/Dex/Components/ClickableText.qml +++ b/atomic_defi_design/Dex/Components/ClickableText.qml @@ -4,7 +4,7 @@ import Dex.Themes 1.0 as Dex Text { - id: root + id: control property alias hoverEnabled: _mouseArea.hoverEnabled property alias containsMouse: _mouseArea.containsMouse @@ -26,6 +26,6 @@ Text anchors.fill: parent hoverEnabled: true cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor - onClicked: root.clicked(); + onClicked: control.clicked() } } diff --git a/atomic_defi_design/Dex/Components/CoinMenu.qml b/atomic_defi_design/Dex/Components/CoinMenu.qml index a28b0fcaf6..73227c6835 100644 --- a/atomic_defi_design/Dex/Components/CoinMenu.qml +++ b/atomic_defi_design/Dex/Components/CoinMenu.qml @@ -9,6 +9,7 @@ Menu { Universal.accent: Style.colorQtThemeAccent Universal.foreground: Style.colorQtThemeForeground Universal.background: Style.colorQtThemeBackground + property bool can_disable; // Ugly but required hack for automatic menu width, otherwise long texts are being cut width: { @@ -28,7 +29,7 @@ Menu { id: disable_action text: qsTr("Disable %1", "TICKER").arg(ticker) onTriggered: API.app.disable_coins([ticker]) - enabled: General.canDisable(ticker) + enabled: can_disable } MenuItem { diff --git a/atomic_defi_design/Dex/Components/ColumnHeader.qml b/atomic_defi_design/Dex/Components/ColumnHeader.qml index 75330b9c3a..0fdcc5abd6 100644 --- a/atomic_defi_design/Dex/Components/ColumnHeader.qml +++ b/atomic_defi_design/Dex/Components/ColumnHeader.qml @@ -1,66 +1,82 @@ import QtQuick 2.15 +import QtQuick.Layouts 1.12 import "../Constants" import App 1.0 -Item { +Item +{ property int sort_type + property alias header_font: title.font property alias text: title.text_value - - property bool icon_at_left - - width: text.length * title.font.pixelSize - height: title.height + property alias h_align: title.horizontalAlignment // Click area - - DefaultText { - id: title - anchors.left: icon_at_left ? parent.left : undefined - anchors.right: icon_at_left ? undefined : parent.right - - //color: Qt.lighter(DexTheme.accentColor, click_area.containsMouse ? Style.hoverLightMultiplier : 1.0) - } - - - // Arrow icon - DefaultImage { - id: arrow_icon - - source: General.image_path + "arrow-" + (ascending ? "down" : "up") + ".svg" - - width: title.font.pixelSize * 0.5 - - anchors.left: icon_at_left ? title.right : undefined - anchors.leftMargin: icon_at_left ? 10 : undefined - anchors.right: icon_at_left ? undefined : title.left - anchors.rightMargin: icon_at_left ? undefined : 10 - anchors.verticalCenter: title.verticalCenter - - visible: false - } - - DefaultColorOverlay { - visible: current_sort === sort_type - anchors.fill: arrow_icon - source: arrow_icon - color: title.color - } - DefaultMouseArea { + DexMouseArea + { id: click_area anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor - onClicked: { - if(current_sort === sort_type) { + + onClicked: + { + if(current_sort === sort_type) + { ascending = !ascending } - else { + else + { current_sort = sort_type ascending = false } - applyCurrentSort() } + + RowLayout + { + width: parent.width + height: parent.height + + Item { + visible: title.horizontalAlignment != Text.AlignLeft + Layout.fillWidth: true + Layout.fillHeight: true + } + + DexLabel + { + id: title + verticalAlignment: Text.AlignVCenter + //color: Qt.lighter(DexTheme.accentColor, click_area.containsMouse ? Style.hoverLightMultiplier : 1.0) + + // Arrow icon + DefaultImage + { + id: arrow_icon + anchors.left: parent.right + anchors.leftMargin: 3 + anchors.verticalCenter: parent.verticalCenter + source: General.image_path + "arrow-" + (ascending ? "down" : "up") + ".svg" + width: title.font.pixelSize * 0.5 + visible: current_sort === sort_type + + DefaultColorOverlay + { + visible: current_sort === sort_type + anchors.fill: parent + source: arrow_icon + color: title.color + } + } + } + + + Item { + visible: title.horizontalAlignment != Text.AlignRight + Layout.fillWidth: true + Layout.fillHeight: true + } + } } } diff --git a/atomic_defi_design/Dex/Components/ComboBoxWithSearchBar.qml b/atomic_defi_design/Dex/Components/ComboBoxWithSearchBar.qml new file mode 100644 index 0000000000..908c6a407f --- /dev/null +++ b/atomic_defi_design/Dex/Components/ComboBoxWithSearchBar.qml @@ -0,0 +1,138 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.3 + +import Qaterial 1.0 as Qaterial + +import Dex.Themes 1.0 as Dex +import "../Constants" + +ComboBox +{ + id: control + + property int radius: 20 + property int popupWidth: width + property int popupMaxHeight: 450 + property bool popupForceMaxHeight: false + property color backgroundColor: Dex.CurrentTheme.comboBoxBackgroundColor + property color popupBackgroundColor: Dex.CurrentTheme.comboBoxBackgroundColor + property color highlightedBackgroundColor: Dex.CurrentTheme.comboBoxDropdownItemHighlightedColor + property alias searchBar: _searchBar + property string searchBarPlaceholderText: qsTr("Search") + + background: Rectangle + { + id: bg + implicitWidth: control.width + implicitHeight: control.height + color: control.backgroundColor + radius: control.radius + } + + popup: Popup + { + id: popup + width: control.popupWidth + height: popupForceMaxHeight ? control.popupMaxHeight : Math.min(contentItem.implicitHeight, control.popupMaxHeight) + leftPadding: 0 + rightPadding: 0 + topPadding: 16 + bottomPadding: 16 + + contentItem: ColumnLayout + { + width: popup.width + height: popup.height + + SearchField + { + id: _searchBar + textField.placeholderText: searchBarPlaceholderText + Layout.fillWidth: true + Layout.leftMargin: 5 + Layout.rightMargin: 5 + Layout.preferredHeight: 40 + searchModel: control.delegateModel + textField.forceFocus: true + } + + DefaultListView + { + id: _list + Layout.fillHeight: true + model: control.popup.visible ? control.delegateModel : null + currentIndex: control.highlightedIndex + ScrollBar.vertical: ScrollBar + { + visible: _list.contentHeight > control.dropDownMaxHeight + anchors.right: _list.right + anchors.rightMargin: 2 + width: 7 + background: DefaultRectangle + { + radius: 12 + color: Dex.CurrentTheme.scrollBarBackgroundColor + } + contentItem: DefaultRectangle + { + radius: 12 + color: Dex.CurrentTheme.scrollBarIndicatorColor + } + } + } + } + + background: Rectangle + { + radius: control.radius + color: control.popupBackgroundColor + } + } + + delegate: ItemDelegate + { + id: delegate + + width: control.width + highlighted: control.highlightedIndex === index + + contentItem: DefaultText + { + width: control.width + font: DexTypo.subtitle2 + text_value: control.textRole === "" ? model.modelData : !model.modelData ? model[textRole] : model.modelData[textRole] + elide: Text.ElideRight + } + + background: Rectangle + { + anchors.fill: delegate + color: delegate.highlighted ? Dex.CurrentTheme.comboBoxDropdownItemHighlightedColor : Dex.CurrentTheme.comboBoxBackgroundColor + } + } + + indicator: Column + { + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 8 + spacing: -12 + + Qaterial.Icon + { + width: 20 + height: 20 + color: Dex.CurrentTheme.comboBoxArrowsColor + icon: Qaterial.Icons.chevronUp + } + + Qaterial.Icon + { + width: 20 + height: 20 + color: Dex.CurrentTheme.comboBoxArrowsColor + icon: Qaterial.Icons.chevronDown + } + } +} diff --git a/atomic_defi_design/Dex/Components/ComboBoxWithTitle.qml b/atomic_defi_design/Dex/Components/ComboBoxWithTitle.qml index f40920dbbe..5623f39e52 100644 --- a/atomic_defi_design/Dex/Components/ComboBoxWithTitle.qml +++ b/atomic_defi_design/Dex/Components/ComboBoxWithTitle.qml @@ -14,7 +14,7 @@ ColumnLayout TitleText { id: title_text } - DefaultComboBox + DexComboBox { id: input_field Layout.preferredWidth: 300 diff --git a/atomic_defi_design/Dex/Components/ComponentWithTitle.qml b/atomic_defi_design/Dex/Components/ComponentWithTitle.qml index 8465e89673..c36298acd9 100644 --- a/atomic_defi_design/Dex/Components/ComponentWithTitle.qml +++ b/atomic_defi_design/Dex/Components/ComponentWithTitle.qml @@ -8,6 +8,7 @@ import Dex.Themes 1.0 as Dex ColumnLayout { property alias title: title.text + property alias title_font: title.font property bool expandable: false property bool expanded: false readonly property bool show_content: !expandable || expanded diff --git a/atomic_defi_design/Dex/Components/DatePicker.qml b/atomic_defi_design/Dex/Components/DatePicker.qml new file mode 100644 index 0000000000..c0ce19742e --- /dev/null +++ b/atomic_defi_design/Dex/Components/DatePicker.qml @@ -0,0 +1,80 @@ +import QtQuick 2.12 +import QtQuick.Layouts 1.12 + +import Qaterial 1.0 as Qaterial + +import Dex.Themes 1.0 as Dex +import "../Constants" + +DefaultMouseArea +{ + id: control + + property alias titleText: title.text + property alias minimumDate: calendar.minimumDate + property alias maximumDate: calendar.maximumDate + property alias selectedDate: calendar.selectedDate + + signal accepted() + + width: 100 + height: column.height + + onClicked: modal.open() + + Column + { + id: column + width: parent.width + + DefaultText + { + id: title + text: qsTr("Date") + font: DexTypo.overLine + color: Dex.CurrentTheme.foregroundColor2 + } + + RowLayout + { + width: parent.width + + DefaultText + { + id: label + text: selectedDate.toLocaleDateString(Locale.ShortFormat, "yyyy-MM-dd") + font: DexTypo.caption + } + Item { Layout.fillWidth: true } + DefaultImage + { + Layout.preferredWidth: 25 + Layout.preferredHeight: 25 + source: Qaterial.Icons.calendarBlank + + DefaultColorOverlay + { + source: parent + anchors.fill: parent + color: Dex.CurrentTheme.foregroundColor2 + } + } + } + } + + DefaultModal + { + id: modal + width: 300 + height: 450 + verticalPadding: 0 + horizontalPadding: 0 + + DefaultCalendar + { + id: calendar + anchors.fill: parent + onSelectedDateChanged: {modal.close(); control.accepted()} + } + } +} diff --git a/atomic_defi_design/Dex/Components/DefaultBusyIndicator.qml b/atomic_defi_design/Dex/Components/DefaultBusyIndicator.qml index 4aa72cb414..73992fc6dc 100644 --- a/atomic_defi_design/Dex/Components/DefaultBusyIndicator.qml +++ b/atomic_defi_design/Dex/Components/DefaultBusyIndicator.qml @@ -4,14 +4,4 @@ import QtQuick.Controls.Universal 2.15 import "../Constants" import App 1.0 -BusyIndicator { - id: control - - Universal.theme: Style.dark_theme ? Universal.Dark : Universal.Light - Universal.accent: DexTheme.colorBusyIndicator - Universal.foreground: Style.colorQtThemeForeground - Universal.background: Style.colorQtThemeBackground - - implicitWidth: 48 - implicitHeight: 48 -} +DexBusyIndicator {} diff --git a/atomic_defi_design/Dex/Components/DefaultCalendar.qml b/atomic_defi_design/Dex/Components/DefaultCalendar.qml new file mode 100644 index 0000000000..c366cf1c8c --- /dev/null +++ b/atomic_defi_design/Dex/Components/DefaultCalendar.qml @@ -0,0 +1,136 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +import Qaterial 1.0 as Qaterial + +import Dex.Themes 1.0 as Dex + +Calendar +{ + width: 300 + height: 450 + style: CalendarStyle + { + gridColor: "transparent" + gridVisible: false + + background: DefaultRectangle + { + color: Dex.CurrentTheme.floatingBackgroundColor + radius: 18 + } + + navigationBar: DefaultRectangle + { + height: 50 + color: Dex.CurrentTheme.floatingBackgroundColor + radius: 18 + + DefaultButton + { + id: previousYear + width: previousMonth.width + height: width + anchors.left: parent.left + anchors.leftMargin: 5 + anchors.verticalCenter: parent.verticalCenter + iconSource: Qaterial.Icons.arrowLeft + onClicked: control.showPreviousYear() + } + + DefaultButton + { + id: previousMonth + width: parent.height - 14 + height: width + anchors.left: previousYear.right + anchors.leftMargin: 2 + anchors.verticalCenter: parent.verticalCenter + iconSource: Qaterial.Icons.arrowLeft + onClicked: control.showPreviousMonth() + } + + DefaultText + { + id: dateText + text: styleData.title + elide: Text.ElideRight + horizontalAlignment: Text.AlignHCenter + anchors.verticalCenter: parent.verticalCenter + anchors.left: previousMonth.right + anchors.leftMargin: 2 + anchors.right: nextMonth.left + anchors.rightMargin: 2 + } + + DefaultButton + { + id: nextYear + width: nextMonth.width + height: width + anchors.right: parent.right + anchors.rightMargin: 5 + anchors.verticalCenter: parent.verticalCenter + iconSource: Qaterial.Icons.arrowRight + onClicked: control.showNextYear() + } + + DefaultButton + { + id: nextMonth + width: parent.height - 14 + height: width + anchors.verticalCenter: parent.verticalCenter + anchors.right: nextYear.left + anchors.rightMargin: 2 + iconSource: Qaterial.Icons.arrowRight + onClicked: control.showNextMonth() + } + } + + dayOfWeekDelegate: DefaultRectangle + { + color: "transparent" + implicitHeight: 20 + Label + { + text: control.locale.dayName(styleData.dayOfWeek, control.dayOfWeekFormat) + anchors.centerIn: parent + color: Dex.CurrentTheme.foregroundColor + } + } + + dayDelegate: DefaultRectangle + { + anchors.fill: parent + color: styleData.date !== undefined && styleData.selected ? selectedDateColor : styleData.hovered ? hoveredDateColor : "transparent" + + readonly property bool addExtraMargin: control.frameVisible && styleData.selected + readonly property color sameMonthDateTextColor: Dex.CurrentTheme.foregroundColor + readonly property color hoveredDateColor: Dex.CurrentTheme.buttonColorHovered + readonly property color selectedDateColor: Dex.CurrentTheme.buttonColorPressed + readonly property color selectedDateTextColor: Dex.CurrentTheme.foregroundColor + readonly property color differentMonthDateTextColor: Dex.CurrentTheme.foregroundColor3 + readonly property color invalidDateColor: Dex.CurrentTheme.textDisabledColor + DefaultText + { + id: dayDelegateText + text: styleData.date.getDate() + anchors.centerIn: parent + horizontalAlignment: Text.AlignRight + font.pixelSize: Math.min(parent.height/3, parent.width/3) + color: { + var theColor = invalidDateColor; + if (styleData.valid) { + // Date is within the valid range. + theColor = styleData.visibleMonth ? sameMonthDateTextColor : differentMonthDateTextColor; + if (styleData.selected) + theColor = selectedDateTextColor; + } + theColor; + } + } + } + } +} diff --git a/atomic_defi_design/Dex/Components/DefaultCopyIcon.qml b/atomic_defi_design/Dex/Components/DefaultCopyIcon.qml new file mode 100644 index 0000000000..4c52187303 --- /dev/null +++ b/atomic_defi_design/Dex/Components/DefaultCopyIcon.qml @@ -0,0 +1,30 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import Qaterial 1.0 as Qaterial +import App 1.0 + +Qaterial.Icon +{ + property int iconSize: 14 + property string copyText: "" + property string notifyTitle: "" + property string notifyMsg: qsTr("copied to clipboard") + + Layout.alignment: Qt.AlignVCenter + + size: iconSize + icon: Qaterial.Icons.contentCopy + color: copyArea.containsMouse ? Style.colorText2 : DexTheme.foregroundColor + + DexMouseArea + { + id: copyArea + anchors.fill: parent + hoverEnabled: true + onClicked: + { + Qaterial.Clipboard.text = copyText + app.notifyCopy(notifyTitle, notifyMsg) + } + } +} \ No newline at end of file diff --git a/atomic_defi_design/Dex/Components/DefaultFlickable.qml b/atomic_defi_design/Dex/Components/DefaultFlickable.qml index 4fb99fe9fc..c4b68109aa 100644 --- a/atomic_defi_design/Dex/Components/DefaultFlickable.qml +++ b/atomic_defi_design/Dex/Components/DefaultFlickable.qml @@ -1,7 +1,8 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 -Flickable { +Flickable +{ id: root property bool scrollbar_visible: contentHeight > height diff --git a/atomic_defi_design/Dex/Components/DefaultImage.qml b/atomic_defi_design/Dex/Components/DefaultImage.qml index cd38dadb58..09d4a0cb39 100644 --- a/atomic_defi_design/Dex/Components/DefaultImage.qml +++ b/atomic_defi_design/Dex/Components/DefaultImage.qml @@ -1,6 +1,3 @@ import QtQuick 2.15 -Image { - mipmap: true - fillMode: Image.PreserveAspectFit -} +DexImage {} diff --git a/atomic_defi_design/Dex/Components/CexInfoTrigger.qml b/atomic_defi_design/Dex/Components/DefaultInfoTrigger.qml similarity index 57% rename from atomic_defi_design/Dex/Components/CexInfoTrigger.qml rename to atomic_defi_design/Dex/Components/DefaultInfoTrigger.qml index 90e2feb801..0fd98f8e73 100644 --- a/atomic_defi_design/Dex/Components/CexInfoTrigger.qml +++ b/atomic_defi_design/Dex/Components/DefaultInfoTrigger.qml @@ -3,6 +3,7 @@ import QtQuick 2.15 DefaultMouseArea { id: mouse_area property bool no_default: true + property var triggerModal anchors.fill: parent - onClicked: no_default ? cex_rates_modal.open() : () => {} + onClicked: no_default ? triggerModal.open() : () => {} } diff --git a/atomic_defi_design/Dex/Components/DefaultLinkIcon.qml b/atomic_defi_design/Dex/Components/DefaultLinkIcon.qml new file mode 100644 index 0000000000..845777d965 --- /dev/null +++ b/atomic_defi_design/Dex/Components/DefaultLinkIcon.qml @@ -0,0 +1,25 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import Qaterial 1.0 as Qaterial +import App 1.0 + + +Qaterial.Icon +{ + property int iconSize: 14 + property string linkURL: "" + + Layout.alignment: Qt.AlignVCenter + + size: iconSize + icon: Qaterial.Icons.linkVariant + color: linkArea.containsMouse ? Style.colorText2 : DexTheme.foregroundColor + + DexMouseArea + { + id: linkArea + anchors.fill: parent + hoverEnabled: true + onClicked: Qt.openUrlExternally(linkURL) + } +} \ No newline at end of file diff --git a/atomic_defi_design/Dex/Components/DefaultListView.qml b/atomic_defi_design/Dex/Components/DefaultListView.qml index d723a2b199..107ae3076a 100644 --- a/atomic_defi_design/Dex/Components/DefaultListView.qml +++ b/atomic_defi_design/Dex/Components/DefaultListView.qml @@ -4,32 +4,5 @@ import QtQuick.Controls 2.15 import "../Constants" import App 1.0 -ListView -{ - id: root - - property bool scrollbar_visible: contentItem.childrenRect.height > height - readonly property double scrollbar_margin: scrollbar_visible ? 8 : 0 - property bool visibleBackground: true - - boundsBehavior: Flickable.StopAtBounds - ScrollBar.vertical: DefaultScrollBar - { - visibleBackground: root.visibleBackground - } - - implicitWidth: contentItem.childrenRect.width - implicitHeight: contentItem.childrenRect.height - - clip: true - - // Opacity animation - opacity: root.count === 0 ? 0 : enabled ? 1 : 0.2 - Behavior on opacity - { - SmoothedAnimation - { - duration: Style.animationDuration * 0.5;velocity: -1 - } - } -} +DexListView +{} diff --git a/atomic_defi_design/Dex/Components/DefaultModal.qml b/atomic_defi_design/Dex/Components/DefaultModal.qml index 1302c9e155..8aa3f955bc 100644 --- a/atomic_defi_design/Dex/Components/DefaultModal.qml +++ b/atomic_defi_design/Dex/Components/DefaultModal.qml @@ -22,7 +22,7 @@ Popup background: DefaultRectangle { radius: root.radius; color: Dex.CurrentTheme.floatingBackgroundColor } - Overlay.modal: Rectangle { color: "#AA000000" } + Overlay.modal: DefaultRectangle { color: "#AA000000" } // Fade in animation onVisibleChanged: diff --git a/atomic_defi_design/Dex/Components/DefaultMouseArea.qml b/atomic_defi_design/Dex/Components/DefaultMouseArea.qml index 62648b6f0f..cac534d7ca 100644 --- a/atomic_defi_design/Dex/Components/DefaultMouseArea.qml +++ b/atomic_defi_design/Dex/Components/DefaultMouseArea.qml @@ -1,6 +1,3 @@ import QtQuick 2.15 -MouseArea -{ - cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor -} +DexMouseArea {} diff --git a/atomic_defi_design/Dex/Components/DefaultPopup.qml b/atomic_defi_design/Dex/Components/DefaultPopup.qml new file mode 100644 index 0000000000..e893062d08 --- /dev/null +++ b/atomic_defi_design/Dex/Components/DefaultPopup.qml @@ -0,0 +1,15 @@ +// Qt Imports +import QtQuick 2.12 +import QtQuick.Controls 2.15 //> Popup + +Popup +{ + id: popup + + y: parent.height + x: (parent.width / 2) - (width / 2) + + closePolicy: Popup.CloseOnPressOutsideParent | Popup.CloseOnEscape + + background: FloatingBackground { } +} diff --git a/atomic_defi_design/Dex/Components/DefaultProgressBar.qml b/atomic_defi_design/Dex/Components/DefaultProgressBar.qml new file mode 100644 index 0000000000..ed56dd814b --- /dev/null +++ b/atomic_defi_design/Dex/Components/DefaultProgressBar.qml @@ -0,0 +1,69 @@ +// Qt Imports +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 + +// Project Imports +import "../Constants" as Dex +import "../Components" as Dex +import App 1.0 + +RowLayout +{ + id: root + property double label_width: 175 + property double bar_width_pct: 0 + property color bar_color: Dex.DexTheme.greenColor + property alias label: _label + property alias pct_bar: _pct_bar + property alias pct_value: _pct_value + anchors.leftMargin: 10 + anchors.rightMargin: 10 + width: parent.width + height: 42 + spacing: 10 + + Dex.DexLabel + { + id: _label + font.bold: true + Layout.preferredWidth: label_width + Layout.alignment: Qt.AlignVCenter + Component.onCompleted: font.weight = Font.Bold + } + + // Progress bar + Item + { + Layout.alignment: Qt.AlignVCenter + Layout.fillWidth: true + height: 5 + + Rectangle + { + id: bg_bar + anchors.fill: parent + radius: 5 + opacity: 0.1 + color: DexTheme.foregroundColorLightColor5 + } + + Rectangle + { + id: _pct_bar + height: parent.height + radius: 5 + width: bar_width_pct / 100 * parent.width + color: root.bar_color + } + } + + Dex.DexLabel + { + id: _pct_value + Layout.preferredWidth: 60 + text: "0.00 %" + Layout.alignment: Qt.AlignVCenter + Component.onCompleted: font.family = 'lato' + } +} diff --git a/atomic_defi_design/Dex/Components/DefaultRangeSlider.qml b/atomic_defi_design/Dex/Components/DefaultRangeSlider.qml index 8cda0a3363..390e62c0fd 100644 --- a/atomic_defi_design/Dex/Components/DefaultRangeSlider.qml +++ b/atomic_defi_design/Dex/Components/DefaultRangeSlider.qml @@ -34,14 +34,14 @@ RangeSlider width: control.availableWidth height: implicitHeight radius: 2 - color: Dex.CurrentTheme.rangeSliderDistanceColor + color: control.rangeDistanceColor Rectangle { x: control.first.visualPosition * parent.width width: control.second.visualPosition * parent.width - x height: parent.height - color: Dex.CurrentTheme.rangeSliderBackgroundColor + color: control.rangeBackgroundColor radius: 2 } } diff --git a/atomic_defi_design/Dex/Components/DefaultRectangle.qml b/atomic_defi_design/Dex/Components/DefaultRectangle.qml index 07fee4bb2a..7b2a0740b2 100644 --- a/atomic_defi_design/Dex/Components/DefaultRectangle.qml +++ b/atomic_defi_design/Dex/Components/DefaultRectangle.qml @@ -1,10 +1,3 @@ import QtQuick 2.15 -import Dex.Themes 1.0 as Dex - -AnimatedRectangle -{ - id: rect - color: Dex.CurrentTheme.backgroundColor -} - +DexRectangle {} diff --git a/atomic_defi_design/Dex/Components/DefaultSlider.qml b/atomic_defi_design/Dex/Components/DefaultSlider.qml index e043ba8dda..be74bd2ce4 100644 --- a/atomic_defi_design/Dex/Components/DefaultSlider.qml +++ b/atomic_defi_design/Dex/Components/DefaultSlider.qml @@ -1,8 +1,48 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 + import "../Constants" import App 1.0 +import Dex.Themes 1.0 as Dex + +Slider +{ + id: control + value: 0.5 + opacity: enabled ? 1 : .5 + + background: Rectangle + { + x: control.leftPadding + y: control.topPadding + control.availableHeight / 2 - height / 2 + implicitWidth: 200 + implicitHeight: 4 + width: control.availableWidth + height: implicitHeight + radius: 2 + color: Dex.CurrentTheme.rangeSliderDistanceColor -DexSlider { + Rectangle + { + width: control.visualPosition * parent.width + height: parent.height + color: Dex.CurrentTheme.rangeSliderBackgroundColor + radius: 2 + } + } + handle: Rectangle + { + x: control.leftPadding + control.visualPosition * (control.availableWidth - width) + y: control.topPadding + control.availableHeight / 2 - height / 2 + implicitWidth: 18 + implicitHeight: 18 + radius: 13 + gradient: Gradient + { + orientation: Gradient.Horizontal + GradientStop { position: 0.125; color: Dex.CurrentTheme.rangeSliderIndicatorBackgroundStartColor } + GradientStop { position: 0.925; color: Dex.CurrentTheme.rangeSliderIndicatorBackgroundEndColor } + } + } } diff --git a/atomic_defi_design/Dex/Components/DefaultSweetComboBox.qml b/atomic_defi_design/Dex/Components/DefaultSweetComboBox.qml index b09ae04093..b125969769 100644 --- a/atomic_defi_design/Dex/Components/DefaultSweetComboBox.qml +++ b/atomic_defi_design/Dex/Components/DefaultSweetComboBox.qml @@ -1,3 +1,4 @@ import QtQuick 2.15 -DexSweetComboBox { } \ No newline at end of file +DexSweetComboBox +{} \ No newline at end of file diff --git a/atomic_defi_design/Dex/Components/DefaultTextEdit.qml b/atomic_defi_design/Dex/Components/DefaultTextEdit.qml index 18b948d573..adfa328500 100644 --- a/atomic_defi_design/Dex/Components/DefaultTextEdit.qml +++ b/atomic_defi_design/Dex/Components/DefaultTextEdit.qml @@ -2,9 +2,14 @@ import QtQuick 2.15 import "../Constants" import App 1.0 -TextEdit { +TextEdit +{ + id: control property string text_value property bool privacy: false + property string linkURL: "" + property string onCopyNotificationTitle: "" + property string onCopyNotificationMsg: qsTr("copied to clipboard") font.family: Style.font_family font.pixelSize: Style.textSize @@ -21,9 +26,29 @@ TextEdit { onLinkActivated: Qt.openUrlExternally(link) - DefaultMouseArea { + DefaultMouseArea + { anchors.fill: parent cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor acceptedButtons: Qt.NoButton } -} + + DefaultCopyIcon + { + id: copy_icon + anchors.verticalCenter: parent.verticalCenter + copyText: control.text_value + notifyTitle: control.onCopyNotificationTitle + notifyMsg: control.onCopyNotificationMsg + x: control.implicitWidth + 6 + iconSize: 14 + } + + DefaultLinkIcon + { + anchors.verticalCenter: parent.verticalCenter + linkURL: control.linkURL + x: control.onCopyNotificationTitle == '' ? control.implicitWidth + 6 : control.implicitWidth + copy_icon.implicitWidth + 8 + iconSize: 14 + } +} \ No newline at end of file diff --git a/atomic_defi_design/Dex/Components/DexAppButton.qml b/atomic_defi_design/Dex/Components/DexAppButton.qml index 962bab8002..4414add9d2 100644 --- a/atomic_defi_design/Dex/Components/DexAppButton.qml +++ b/atomic_defi_design/Dex/Components/DexAppButton.qml @@ -47,7 +47,6 @@ DexRectangle Dex.CurrentTheme.buttonColorDisabled opacity: _controlMouseArea.containsMouse ? 1 : .8 - Row { id: _contentRow @@ -74,7 +73,7 @@ DexRectangle { id: _label anchors.verticalCenter: parent.verticalCenter - font: DexTypo.button + font: DexTypo.body2 text: control.text color: enabled ? _controlMouseArea.containsMouse ? _controlMouseArea.containsPress ? Dex.CurrentTheme.buttonTextPressedColor : diff --git a/atomic_defi_design/Dex/Components/DexAppOutlineButton.qml b/atomic_defi_design/Dex/Components/DexAppOutlineButton.qml index b754fb2e19..41c9bfdff5 100644 --- a/atomic_defi_design/Dex/Components/DexAppOutlineButton.qml +++ b/atomic_defi_design/Dex/Components/DexAppOutlineButton.qml @@ -61,8 +61,10 @@ DexRectangle { color: DexTheme.buttonGradientEnabled2 } } + color: outlinedColor gradient: outlinedColor !== "" ? undefined : btnGradient + DexRectangle { visible: !parent.containsMouse radius: parent.radius - 2 @@ -75,16 +77,20 @@ DexRectangle { height: _label.implicitHeight + (padding * verticalPadding) width: _contentRow.implicitWidth + (padding * horizontalPadding) - Row { + Row + { id: _contentRow - anchors { + anchors + { horizontalCenter: parent.horizontalAlignment == Qt.AlignHCenter ? parent.horizontalCenter : undefined verticalCenter: parent.verticalAlignment == Qt.AlignVCenter ? parent.verticalCenter : undefined } spacing: _icon.visible ? parent.spacing : 0 - Qaterial.ColorIcon { + + Qaterial.ColorIcon + { id: _icon iconSize: _label.font.pixelSize + 2 visible: control.iconSource === "" ? false : true @@ -93,14 +99,16 @@ DexRectangle { anchors.verticalCenter: parent.verticalCenter } - DexLabel { + DexLabel + { id: _label anchors.verticalCenter: parent.verticalCenter - font: DexTypo.body1 + font: DexTypo.body2 text: control.text color: control.foregroundColor } } + DexMouseArea { id: _controlMouseArea anchors.fill: parent diff --git a/atomic_defi_design/Dex/Components/DexAppPasswordField.qml b/atomic_defi_design/Dex/Components/DexAppPasswordField.qml index 65d6a4e7fd..a071c90e17 100644 --- a/atomic_defi_design/Dex/Components/DexAppPasswordField.qml +++ b/atomic_defi_design/Dex/Components/DexAppPasswordField.qml @@ -6,6 +6,7 @@ import Qaterial 1.0 as Qaterial import App 1.0 import Dex.Themes 1.0 as Dex +import "../Constants" DexAppTextField { @@ -19,7 +20,7 @@ DexAppTextField height: 50 width: 300 background.radius: 25 - max_length: 1000 + max_length: General.max_std_pw_length field.echoMode: TextField.Password field.font: Qt.font( { diff --git a/atomic_defi_design/Dex/Components/DexAppTextField.qml b/atomic_defi_design/Dex/Components/DexAppTextField.qml index 156e1136f7..9fd086e981 100644 --- a/atomic_defi_design/Dex/Components/DexAppTextField.qml +++ b/atomic_defi_design/Dex/Components/DexAppTextField.qml @@ -15,9 +15,8 @@ Item property int leftWidth: -1 property int max_length: 180 - property alias value: input_field.text - property alias field: input_field + property alias value: input_field.text property alias background: _background property string leftText: "" @@ -25,6 +24,7 @@ Item property string placeholderText: "" property bool error: false + onErrorChanged: { if (error) @@ -33,6 +33,7 @@ Item _animate.start() } } + Timer { id: _animationTimer @@ -43,11 +44,13 @@ Item _background.x = 0 } } + Timer { id: _animate interval: 30 repeat: true + onTriggered: { if (_background.x == -3) @@ -65,6 +68,7 @@ Item { input_field.text = "" } + Rectangle { id: _background @@ -74,6 +78,7 @@ Item color: Dex.CurrentTheme.backgroundColor border.color: control.error ? Dex.CurrentTheme.noColor : input_field.focus ? Dex.CurrentTheme.accentColor : color border.width: input_field.focus ? 1 : 0 + Behavior on x { NumberAnimation @@ -89,11 +94,13 @@ Item anchors.leftMargin: 5 anchors.rightMargin: 5 spacing: 2 + Item { visible: leftText !== "" Layout.preferredWidth: leftWidth !== -1 ? leftWidth : _title_label.implicitWidth + 2 Layout.fillHeight: true + DexLabel { id: _title_label @@ -107,10 +114,12 @@ Item font.weight: Font.Medium } } + Item { Layout.fillWidth: true Layout.fillHeight: true + Rectangle { anchors.fill: parent @@ -118,9 +127,20 @@ Item anchors.bottomMargin: 1 radius: _background.radius color: background.color + DexTextField { id: input_field + anchors.fill: parent + horizontalAlignment: Qt.AlignLeft + + font.weight: Font.Medium + font.family: 'Lato' + font.pixelSize: 13 + echoMode: TextInput.Normal + background: Item + {} + onTextChanged: { if (text.length > control.max_length) @@ -129,15 +149,9 @@ Item } control.error = false } - horizontalAlignment: Qt.AlignLeft - echoMode: TextInput.Normal - background: Item - {} - font.weight: Font.Medium - font.family: 'Lato' - font.pixelSize: 13 - anchors.fill: parent + } + DexLabel { text: control.placeholderText @@ -153,11 +167,13 @@ Item } } } + Item { visible: rightText !== "" Layout.preferredWidth: _suffix_label.implicitWidth + 2 Layout.fillHeight: true + DexLabel { id: _suffix_label diff --git a/atomic_defi_design/Dex/Components/DexBusyIndicator.qml b/atomic_defi_design/Dex/Components/DexBusyIndicator.qml new file mode 100644 index 0000000000..0390ddea6e --- /dev/null +++ b/atomic_defi_design/Dex/Components/DexBusyIndicator.qml @@ -0,0 +1,75 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Controls.Universal 2.15 +import "../Constants" +import Dex.Themes 1.0 as Dex +import App 1.0 + +BusyIndicator +{ + id: control + property int indicatorSize: 64 + property int indicatorDotSize: 10 + + contentItem: Item + { + implicitWidth: indicatorSize + implicitHeight: indicatorSize + + Item + { + id: item + x: (parent.width - indicatorSize) / 2 + y: (parent.height - indicatorSize) / 2 + width: indicatorSize + height: indicatorSize + opacity: control.running ? 1 : 0 + + Behavior on opacity + { + OpacityAnimator + { + duration: 250 + } + } + + RotationAnimator + { + target: item + running: control.visible && control.running + from: 0 + to: 360 + loops: Animation.Infinite + duration: 1250 + } + + Repeater + { + id: repeater + model: 6 + + Rectangle + { + x: (item.width - width) / 2 + y: (item.height - height) / 2 + implicitWidth: indicatorDotSize + implicitHeight: indicatorDotSize + radius: indicatorDotSize / 2 + color: Dex.CurrentTheme.busyIndicatorColor + transform: [ + Translate + { + y: -Math.min(item.width, item.height) * 0.5 + indicatorDotSize / 2 + }, + Rotation + { + angle: index / repeater.count * 360 + origin.x: indicatorDotSize / 2 + origin.y: indicatorDotSize / 2 + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/atomic_defi_design/Dex/Components/DexCheckBox.qml b/atomic_defi_design/Dex/Components/DexCheckBox.qml index e8332163bb..b471d0d922 100644 --- a/atomic_defi_design/Dex/Components/DexCheckBox.qml +++ b/atomic_defi_design/Dex/Components/DexCheckBox.qml @@ -1,5 +1,6 @@ //! Qt Imports. import QtQuick 2.15 +import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 import QtQuick.Controls.Universal 2.15 @@ -12,38 +13,22 @@ CheckBox id: control property alias label: _label - property color textColor: Dex.CurrentTheme.foregroundColor - property alias boxWidth: _indicator.implicitWidth property alias boxHeight: _indicator.implicitHeight - - Universal.accent: Dex.CurrentTheme.accentColor - Universal.foreground: Dex.CurrentTheme.foregroundColor - Universal.background: Dex.CurrentTheme.backgroundColor + property alias mouseArea: mouseArea + property color textColor: Dex.CurrentTheme.foregroundColor + property int labelWidth: 0 font.family: Style.font_family - contentItem: DefaultText - { - id: _label - text: control.text - font: control.font - color: control.textColor - horizontalAlignment: DexLabel.AlignLeft - verticalAlignment: DexLabel.AlignVCenter - leftPadding: control.indicator.width + control.spacing - wrapMode: Label.Wrap - } - - indicator: DexRectangle + indicator: DefaultRectangle { id: _indicator - - implicitWidth: 26 - implicitHeight: 26 - x: control.leftPadding - control.spacing anchors.verticalCenter: control.verticalCenter - radius: 20 + + implicitWidth: 20 + implicitHeight: 20 + radius: 4 gradient: Gradient { @@ -52,20 +37,57 @@ CheckBox GradientStop { position: 0.6; color: Dex.CurrentTheme.checkBoxGradientEndColor } } - DexRectangle + DefaultImage { + id: check_icon + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: parent.width - 6 + height: parent.height - 6 + source: General.image_path + "white_check.svg" + visible: control.checkState === Qt.Checked + } + + DefaultColorOverlay + { + anchors.fill: check_icon + source: check_icon + color: Dex.CurrentTheme.checkBoxTickColor + } + + DefaultRectangle { visible: !control.checked anchors.centerIn: parent - implicitWidth: parent.width - 6 - implicitHeight: parent.height - 6 + width: parent.width - 6 + height: parent.height - 6 radius: parent.radius } opacity: enabled ? 1 : 0.5 } + contentItem: RowLayout + { + id: _content + Layout.alignment: Qt.AlignVCenter + height: _label.height + spacing: 0 + + DefaultText + { + id: _label + text: control.text + font: control.font + color: control.textColor + verticalAlignment: Text.AlignVCenter + leftPadding: control.indicator.width + control.spacing + wrapMode: Label.Wrap + } + } + DefaultMouseArea { + id: mouseArea anchors.fill: parent acceptedButtons: Qt.NoButton } diff --git a/atomic_defi_design/Dex/Components/DexCheckEye.qml b/atomic_defi_design/Dex/Components/DexCheckEye.qml deleted file mode 100644 index bf9439911c..0000000000 --- a/atomic_defi_design/Dex/Components/DexCheckEye.qml +++ /dev/null @@ -1,54 +0,0 @@ -import QtQuick 2.15 -import Qaterial 1.0 as Qaterial -import QtQuick.Layouts 1.12 - -import App 1.0 -import Dex.Themes 1.0 as Dex - -Item -{ - id: control - - property bool checked: eval("target." + control.targetProperty) - property alias text: _label.text - property alias iconSource: _icon.source - property string targetProperty: "" - property var target - - width: parent.width - height: row.height - - RowLayout - { - id: row - width: parent.width - 20 - spacing: 10 - Qaterial.ColorIcon - { - id: _icon - Layout.alignment: Qt.AlignVCenter - source: control.checked ? Qaterial.Icons.eyeOutline : Qaterial.Icons.eyeOffOutline - color: control.checked ? Dex.CurrentTheme.foregroundColor : Dex.CurrentTheme.buttonTextDisabledColor - iconSize: 17 - DexMouseArea - { - anchors.fill: parent - onClicked: - { - if (control.checked) eval("target." + control.targetProperty + " = false") - else eval("target." + control.targetProperty + " = true") - } - } - } - DefaultText - { - id: _label - font.pixelSize: 15 - text: "" - color: control.checked ? Dex.CurrentTheme.foregroundColor : Dex.CurrentTheme.buttonTextDisabledColor - opacity: .5 - Layout.fillWidth: true - Layout.alignment: Qt.AlignVCenter - } - } -} diff --git a/atomic_defi_design/Dex/Components/DexComboBox.qml b/atomic_defi_design/Dex/Components/DexComboBox.qml index fcc8879263..38245425d2 100644 --- a/atomic_defi_design/Dex/Components/DexComboBox.qml +++ b/atomic_defi_design/Dex/Components/DexComboBox.qml @@ -2,7 +2,6 @@ import QtQuick 2.15 import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 import QtQuick.Controls.impl 2.15 -import QtQuick.Controls.Universal 2.15 import Qaterial 1.0 as Qaterial @@ -14,51 +13,40 @@ ComboBox { id: control - property alias radius: bg_rect.radius - property color lineHoverColor: DexTheme.hoverColor - property color mainBackgroundColor: Dex.CurrentTheme.floatingBackgroundColor - property int dropDownMaxHeight: 300 - property color dropdownBackgroundColor: Dex.CurrentTheme.floatingBackgroundColor - property - var dropdownLineText: m => textRole === "" ? - m.modelData : - !m.modelData ? m[textRole] : m.modelData[textRole] + property alias radius: bg_rect.radius + property int dropDownMaxHeight: 450 + property color comboBoxBackgroundColor: Dex.CurrentTheme.comboBoxBackgroundColor + property color mainBackgroundColor: Dex.CurrentTheme.comboBoxBackgroundColor + property color popupBackgroundColor: Dex.CurrentTheme.comboBoxBackgroundColor + property color highlightedBackgroundColor: Dex.CurrentTheme.comboBoxDropdownItemHighlightedColor property string mainLineText: control.displayText - - readonly property bool disabled: !enabled + property var dropdownLineText: m => textRole === "" ? + m.modelData : + !m.modelData ? m[textRole] : m.modelData[textRole] font.family: Style.font_family - - Behavior on lineHoverColor - { - ColorAnimation - { - duration: Style.animationDuration - } - } - hoverEnabled: true // Main, selected text contentItem: Item { - anchors.fill: parent DefaultText { anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 13 + width: parent.width - anchors.leftMargin font: DexTypo.subtitle2 text_value: control.mainLineText + elide: Text.ElideRight } } - // Main background background: FloatingBackground { id: bg_rect - implicitWidth: 120 + implicitWidth: 150 implicitHeight: 45 color: control.mainBackgroundColor radius: 20 @@ -68,7 +56,6 @@ ComboBox popup: Popup { width: control.width - height: _list.contentHeight > control.dropDownMaxHeight ? control.dropDownMaxHeight : _list.contentHeight leftPadding: 0 rightPadding: 0 topPadding: 16 @@ -78,14 +65,15 @@ ComboBox { id: _list model: control.popup.visible ? control.delegateModel : null + implicitHeight: contentHeight > control.dropDownMaxHeight ? control.dropDownMaxHeight : contentHeight currentIndex: control.highlightedIndex ScrollBar.vertical: ScrollBar { + visible: _list.contentHeight > control.dropDownMaxHeight anchors.right: _list.right anchors.rightMargin: 2 width: 7 - visible: true background: DefaultRectangle { radius: 12 @@ -108,21 +96,30 @@ ComboBox background: Rectangle { radius: control.radius - color: control.dropdownBackgroundColor + color: control.popupBackgroundColor } } // Each dropdown item delegate: ItemDelegate { - Universal.accent: Dex.CurrentTheme.comboBoxDropdownItemHighlightedColor + id: combo_item + width: control.width highlighted: control.highlightedIndex === index - contentItem: DexLabel + contentItem: DefaultText { + width: control.width font: DexTypo.subtitle2 text_value: control.dropdownLineText(model) + elide: Text.ElideRight + } + + background: Rectangle + { + anchors.fill: combo_item + color: combo_item.highlighted ? Dex.CurrentTheme.comboBoxDropdownItemHighlightedColor : Dex.CurrentTheme.comboBoxBackgroundColor } } @@ -156,4 +153,4 @@ ComboBox anchors.fill: parent acceptedButtons: Qt.NoButton } -} \ No newline at end of file +} diff --git a/atomic_defi_design/Dex/Components/DexDialogTextField.qml b/atomic_defi_design/Dex/Components/DexDialogTextField.qml index e696f2fb99..cee884a867 100644 --- a/atomic_defi_design/Dex/Components/DexDialogTextField.qml +++ b/atomic_defi_design/Dex/Components/DexDialogTextField.qml @@ -17,7 +17,7 @@ Item { property string rightText: "" property string placeholderText: "" property int leftWidth: -1 - readonly property int max_length: 40 + property int max_length: 40 property bool error: false onErrorChanged: { if (error) { diff --git a/atomic_defi_design/Dex/Components/DexGradientAppButton.qml b/atomic_defi_design/Dex/Components/DexGradientAppButton.qml index f74b4ab822..5624512c13 100644 --- a/atomic_defi_design/Dex/Components/DexGradientAppButton.qml +++ b/atomic_defi_design/Dex/Components/DexGradientAppButton.qml @@ -93,7 +93,7 @@ DexRectangle { id: _label anchors.verticalCenter: parent.verticalCenter - font: DexTypo.button + font: DexTypo.body2 text: control.text color: enabled ? _controlMouseArea.containsMouse ? _controlMouseArea.containsPress ? Dex.CurrentTheme.gradientButtonTextPressedColor : @@ -112,6 +112,7 @@ DexRectangle anchors.verticalCenter: parent.verticalCenter } } + DexMouseArea { id: _controlMouseArea diff --git a/atomic_defi_design/Dex/Components/DexImage.qml b/atomic_defi_design/Dex/Components/DexImage.qml index c0cbe489f5..603f734457 100644 --- a/atomic_defi_design/Dex/Components/DexImage.qml +++ b/atomic_defi_design/Dex/Components/DexImage.qml @@ -1,6 +1,7 @@ import QtQuick 2.15 -Image { +Image +{ mipmap: true fillMode: Image.PreserveAspectFit } \ No newline at end of file diff --git a/atomic_defi_design/Dex/Components/DexKeyChecker.qml b/atomic_defi_design/Dex/Components/DexKeyChecker.qml index 437caadbc9..fe8634f5e2 100644 --- a/atomic_defi_design/Dex/Components/DexKeyChecker.qml +++ b/atomic_defi_design/Dex/Components/DexKeyChecker.qml @@ -13,6 +13,7 @@ ColumnLayout { property bool new_password: true property bool double_validation: false property string match_password + property int max_pw_len: General.max_std_pw_length property bool high_security: true function isValid() { @@ -96,7 +97,7 @@ ColumnLayout { font: DexTypo.body2 Layout.fillWidth: true wrapMode: DexLabel.Wrap - text_value: hintPrefix(hasEnoughCharacters()) + qsTr("At least %n character(s)", "", high_security ? 16 : 1) + text_value: hintPrefix(hasEnoughCharacters()) + qsTr("Between %1 and %2 character(s)").arg(high_security ? 16 : 1).arg(max_pw_len) color: hintColor(hasEnoughCharacters()) } DexLabel { diff --git a/atomic_defi_design/Dex/Components/DexLabel.qml b/atomic_defi_design/Dex/Components/DexLabel.qml index 1047c3fbae..ef6694978d 100644 --- a/atomic_defi_design/Dex/Components/DexLabel.qml +++ b/atomic_defi_design/Dex/Components/DexLabel.qml @@ -10,6 +10,7 @@ Text { property string text_value property bool privacy: false + property bool monospace: false Behavior on color { @@ -19,12 +20,7 @@ Text } } - font: Qt.font - ({ - pixelSize: 14, - letterSpacing: 0.25, - weight: Font.Normal - }) + font: monospace ? Dex.DexTypo.monoSmall : Dex.DexTypo.body2 color: enabled ? Dex.CurrentTheme.foregroundColor : Dex.CurrentTheme.textDisabledColor diff --git a/atomic_defi_design/Dex/Components/DexLanguage.qml b/atomic_defi_design/Dex/Components/DexLanguage.qml index 1d587cc673..1029bc7abb 100644 --- a/atomic_defi_design/Dex/Components/DexLanguage.qml +++ b/atomic_defi_design/Dex/Components/DexLanguage.qml @@ -8,34 +8,50 @@ import QtGraphicalEffects 1.0 import "../Constants" import App 1.0 +import Dex.Themes 1.0 as Dex -RoundComboBox +DexComboBox { id: control model: API.app.settings_pg.get_available_langs() + height: 50 + displayText: API.app.settings_pg.lang leftPadding: 5 + + // Each dropdown item delegate: ItemDelegate { + id: combo_item width: control.width - height: 30 + height: 35 highlighted: control.highlightedIndex === index - RowLayout + + contentItem: RowLayout { anchors.fill: parent - spacing: -13 - DefaultImage + spacing: -25 + + DexImage { id: image - Layout.preferredHeight: 14 + Layout.preferredHeight: 25 source: General.image_path + "lang/" + modelData + ".png" } + DexLabel { text: modelData - } } + + background: Rectangle + { + anchors.fill: combo_item + radius: 6 + color: combo_item.highlighted ? Dex.CurrentTheme.comboBoxDropdownItemHighlightedColor : Dex.CurrentTheme.comboBoxBackgroundColor + } + onClicked: { if (modelData !== API.app.settings_pg.lang) @@ -44,26 +60,31 @@ RoundComboBox } } } + + // Main, selected item contentItem: Text { + anchors.fill: parent leftPadding: 0 rightPadding: control.indicator.width + control.spacing - - //text: control.displayText - font: control.font - color: control.pressed ? "#17a81a" : "#21be2b" verticalAlignment: Text.AlignVCenter - elide: Text.ElideRight - DefaultImage + + DexImage { id: image - height: 12 - x: 8 + height: 25 + x: 12 anchors.verticalCenter: parent.verticalCenter source: General.image_path + "lang/" + control.displayText + ".png" } } + background: FloatingBackground + { + radius: 20 + color: Dex.CurrentTheme.comboBoxBackgroundColor + } + DexMouseArea { anchors.fill: parent diff --git a/atomic_defi_design/Dex/Components/DexListView.qml b/atomic_defi_design/Dex/Components/DexListView.qml index 388156262c..a65904698f 100644 --- a/atomic_defi_design/Dex/Components/DexListView.qml +++ b/atomic_defi_design/Dex/Components/DexListView.qml @@ -2,34 +2,37 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 import "../Constants" -as Constants import App 1.0 -ListView { +ListView +{ id: root - property bool scrollbar_visible: contentItem.childrenRect.height > height property alias position: scrollVert.position property alias scrollVert: scrollVert - readonly property double scrollbar_margin: scrollbar_visible ? 8 : 0 + property bool scrollbar_visible: contentItem.childrenRect.height > height property bool visibleBackground: false + readonly property double scrollbar_margin: scrollbar_visible ? 8 : 0 boundsBehavior: Flickable.StopAtBounds - ScrollBar.vertical: DexScrollBar { - id: scrollVert - visibleBackground: root.visibleBackground - } - - implicitWidth: contentItem.childrenRect.width implicitHeight: contentItem.childrenRect.height - + implicitWidth: contentItem.childrenRect.width clip: true - // Opacity animation opacity: root.count === 0 ? 0 : enabled ? 1 : 0.2 - Behavior on opacity { - SmoothedAnimation { - duration: Constants.Style.animationDuration * 0.5;velocity: -1 + + Behavior on opacity + { + SmoothedAnimation + { + duration: Style.animationDuration * 0.5 + velocity: -1 } } -} \ No newline at end of file + + ScrollBar.vertical: DefaultScrollBar + { + id: scrollVert + visibleBackground: root.visibleBackground + } +} diff --git a/atomic_defi_design/Dex/Components/DexMacosHeaderControl.qml b/atomic_defi_design/Dex/Components/DexMacosHeaderControl.qml index 8886236630..190d60301c 100644 --- a/atomic_defi_design/Dex/Components/DexMacosHeaderControl.qml +++ b/atomic_defi_design/Dex/Components/DexMacosHeaderControl.qml @@ -4,6 +4,9 @@ import QtQuick.Controls.Universal 2.15 import QtQuick.Layouts 1.12 import Qaterial 1.0 as Qaterial +import ModelHelper 0.1 + +import "../Constants" Row { @@ -11,6 +14,7 @@ Row property real size: 13 property bool hovered: minimizeButton.containsMouse || closeButton.containsMouse || extendButton.containsMouse + property var orders: API.app.orders_mdl.orders_proxy_mdl.ModelHelper anchors.top: parent.top width: 195 @@ -40,10 +44,9 @@ Row id: closeButton hoverEnabled: true anchors.fill: parent - onClicked: - { - Qt.quit() - console.log("Window.visibility: " + window.visibility) + onClicked: { + if (orders.count === 0 || !API.app.wallet_mgr.log_status()) Qt.quit() + else app.logout_confirm_modal.open() } } } diff --git a/atomic_defi_design/Dex/Components/DexModal.qml b/atomic_defi_design/Dex/Components/DexModal.qml index d5d1781717..7b476bca3a 100644 --- a/atomic_defi_design/Dex/Components/DexModal.qml +++ b/atomic_defi_design/Dex/Components/DexModal.qml @@ -2,6 +2,8 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 +import Dex.Themes 1.0 as Dex + Popup { id: control parent: Overlay.overlay @@ -13,18 +15,19 @@ Popup { property alias footer: _footer.contentItem modal: true padding: 0 - Overlay.modeless: DexRectangle { - color: DexTheme.dexBoxBackgroundColor + Overlay.modeless: DefaultRectangle { + color: Dex.CurrentTheme.dexBoxBackgroundColor opacity: .3 } + background: ClipRRect { radius: 8 - DexRectangle { + DefaultRectangle { id: _backgroundColor anchors.fill: parent border.width: 2 radius: parent.radius - color: DexTheme.dexBoxBackgroundColor + color: Dex.CurrentTheme.dexBoxBackgroundColor Container { id: _header width: parent.width diff --git a/atomic_defi_design/Dex/Components/DexMouseArea.qml b/atomic_defi_design/Dex/Components/DexMouseArea.qml index fa58b5512f..3f237b7d42 100644 --- a/atomic_defi_design/Dex/Components/DexMouseArea.qml +++ b/atomic_defi_design/Dex/Components/DexMouseArea.qml @@ -1,5 +1,6 @@ import QtQuick 2.15 -MouseArea { +MouseArea +{ cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor } \ No newline at end of file diff --git a/atomic_defi_design/Dex/Components/DexPaginator.qml b/atomic_defi_design/Dex/Components/DexPaginator.qml index 35fc8bc653..cbe088fb83 100644 --- a/atomic_defi_design/Dex/Components/DexPaginator.qml +++ b/atomic_defi_design/Dex/Components/DexPaginator.qml @@ -17,6 +17,8 @@ RowLayout property var pageSize: Constants.API.app.orders_mdl.nb_pages property var currentValue: Constants.API.app.orders_mdl.current_page + property alias itemsPerPageComboBox: itemsPerPageComboBox + function refreshBtn() { currentValue = Constants.API.app.orders_mdl.current_page @@ -68,13 +70,17 @@ RowLayout refreshBtn() } - DefaultComboBox + DexComboBox { + id: itemsPerPageComboBox + readonly property int item_count: Constants.API.app.orders_mdl.limit_nb_elements readonly property var options: [5, 10, 25, 50, 100, 200] Layout.preferredWidth: (root.width / 100) * 14 + Layout.maximumWidth: 62 + Layout.preferredHeight: 35 Layout.alignment: Qt.AlignLeft model: options @@ -82,12 +88,14 @@ RowLayout onCurrentValueChanged: Constants.API.app.orders_mdl.limit_nb_elements = currentValue } - DefaultText + DexText { - Layout.preferredWidth: (root.width / 100) * 10 + Layout.preferredWidth: (root.width / 100) * 16 + Layout.leftMargin: 20 Layout.alignment: Qt.AlignLeft - font.pixelSize: 11 - text_value: qsTr("items per page") + font.pixelSize: 12 + text: qsTr("items per page") + color: Dex.CurrentTheme.foregroundColor2 } Item diff --git a/atomic_defi_design/Dex/Components/DexRectangle.qml b/atomic_defi_design/Dex/Components/DexRectangle.qml index e204762aba..38fe98b08b 100644 --- a/atomic_defi_design/Dex/Components/DexRectangle.qml +++ b/atomic_defi_design/Dex/Components/DexRectangle.qml @@ -1,13 +1,15 @@ import QtQuick 2.15 import App 1.0 +import Dex.Themes 1.0 as Dex + AnimatedRectangle { id: rect property bool sizeAnimation: false property int sizeAnimationDuration: 150 radius: DexTheme.rectangleRadius - color: DexTheme.contentColorTopBold - border.color: DexTheme.contentColorTopBold + color: Dex.CurrentTheme.backgroundColor + border.color: color border.width: 1 Behavior on width { diff --git a/atomic_defi_design/Dex/Components/DexScrollBar.qml b/atomic_defi_design/Dex/Components/DexScrollBar.qml index 14f5c65766..c17969e286 100644 --- a/atomic_defi_design/Dex/Components/DexScrollBar.qml +++ b/atomic_defi_design/Dex/Components/DexScrollBar.qml @@ -14,6 +14,7 @@ ScrollBar policy: scrollbar_visible ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff property bool visibleBackground: true width: 6 + contentItem: Item { DexRectangle @@ -29,7 +30,6 @@ ScrollBar background: Item { width: 6 - x: 0 DexRectangle { visible: control.visibleBackground diff --git a/atomic_defi_design/Dex/Components/DexSlider.qml b/atomic_defi_design/Dex/Components/DexSlider.qml deleted file mode 100644 index be3dfc714d..0000000000 --- a/atomic_defi_design/Dex/Components/DexSlider.qml +++ /dev/null @@ -1,41 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Controls 2.15 -import "../Constants" -import App 1.0 -Slider { - id: control - value: 0.5 - opacity: enabled ? 1 : .5 - - background: Rectangle { - x: control.leftPadding - y: control.topPadding + control.availableHeight / 2 - height / 2 - implicitWidth: 200 - implicitHeight: 4 - width: control.availableWidth - height: implicitHeight - radius: 2 - color: "#bdbebf" - - Rectangle { - width: control.visualPosition * parent.width - height: parent.height - color: DexTheme.accentColor - radius: 2 - } - } - handle: FloatingBackground { - x: control.leftPadding + control.visualPosition * (control.availableWidth - width) - y: control.topPadding + control.availableHeight / 2 - height / 2 - implicitWidth: 26 - implicitHeight: 26 - radius: 13 - Rectangle { - anchors.centerIn: parent - width: 10 - height: 10 - radius: 10 - color: DexTheme.accentColor - } - } -} \ No newline at end of file diff --git a/atomic_defi_design/Dex/Components/DexSweetComboBox.qml b/atomic_defi_design/Dex/Components/DexSweetComboBox.qml index a54f7f8131..e8a7086ab6 100644 --- a/atomic_defi_design/Dex/Components/DexSweetComboBox.qml +++ b/atomic_defi_design/Dex/Components/DexSweetComboBox.qml @@ -13,22 +13,53 @@ ComboBox { id: control + property alias radius: bg_rect.radius + property color comboBoxBackgroundColor: Dex.CurrentTheme.comboBoxBackgroundColor + property color popupBackgroundColor: Dex.CurrentTheme.floatingBackgroundColor + property color highlightedBackgroundColor: Dex.CurrentTheme.comboBoxDropdownItemHighlightedColor + property color mainBackgroundColor: Dex.CurrentTheme.floatingBackgroundColor + property string currentTicker: "All" property var dropdownLineText: m => textRole === "" ? m.modelData : !m.modelData ? m[textRole] : m.modelData[textRole] - property string currentTicker: "All" - property color backgroundColor: Dex.CurrentTheme.floatingBackgroundColor - property color popupBackgroundColor: Dex.CurrentTheme.floatingBackgroundColor + // Combobox Dropdown Button Background + background: DexRectangle + { + id: bg_rect + implicitHeight: 40 + color: comboBoxBackgroundColor + radius: 20 + } + + contentItem: DexLabel + { + leftPadding: 10 + verticalAlignment: Text.AlignVCenter + width: bg_rect.width - leftPadding + height: bg_rect.height + text: control.currentTicker + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + + // Each dropdown item delegate: ItemDelegate { + id: combo_item width: control.width + 50 highlighted: control.highlightedIndex === index - contentItem: DefaultText + + contentItem: DexLabel { text_value: control.currentTicker color: Dex.CurrentTheme.foregroundColor } + + background: DexRectangle { + anchors.fill: combo_item + color: combo_item.highlighted ? highlightedBackgroundColor : mainBackgroundColor + } } indicator: Qaterial.Icon @@ -39,35 +70,15 @@ ComboBox icon: Qaterial.Icons.chevronDown } - contentItem: DefaultText - { - leftPadding: 10 - verticalAlignment: Text.AlignVCenter - width: _background.width - leftPadding - height: _background.height - text: control.currentTicker - elide: Text.ElideRight - wrapMode: Text.NoWrap - } - - background: DefaultRectangle - { - id: _background - - implicitHeight: 40 - colorAnimation: false - color: control.backgroundColor - radius: 20 - } - + // Dropdown itself popup: Popup { - id: comboPopup - - readonly property double max_height: 350 + id: combo_popup + readonly property double max_height: 450 width: control.width - height: Math.min(contentItem.implicitHeight, popup.max_height) + 20 + height: Math.min(contentItem.implicitHeight, max_height) + 20 + padding: 1 contentItem: ColumnLayout @@ -79,13 +90,20 @@ ComboBox id: input_coin_filter placeholderText: qsTr("Search") - background: DefaultRectangle + font.pixelSize: 16 + Layout.fillWidth: true + Layout.leftMargin: 0 + Layout.preferredHeight: 40 + Layout.rightMargin: 2 + Layout.topMargin: Layout.leftMargin + + background: DexRectangle { anchors.fill: parent anchors.topMargin: -5 anchors.rightMargin: -1 - radius: 20 - color: control.popupBackgroundColor + radius: control.radius + color: control.mainBackgroundColor } onTextChanged: control.model.setFilterFixedString(text) @@ -110,17 +128,8 @@ ComboBox } } - - - font.pixelSize: 16 - Layout.fillWidth: true - Layout.leftMargin: 0 - Layout.preferredHeight: 40 - Layout.rightMargin: 2 - Layout.topMargin: Layout.leftMargin Keys.onDownPressed: control.incrementCurrentIndex() Keys.onUpPressed: control.decrementCurrentIndex() - Keys.onPressed: { if (event.key === Qt.Key_Return) @@ -135,11 +144,13 @@ ComboBox } } } + Item { Layout.maximumHeight: popup.max_height - 100 Layout.fillWidth: true implicitHeight: popup_list_view.contentHeight + 5 + DexListView { id: popup_list_view @@ -148,11 +159,15 @@ ComboBox anchors.fill: parent anchors.bottomMargin: 10 anchors.rightMargin: 2 + clip: true + + visibleBackground: true + highlight: DefaultRectangle { radius: 0 } - clip: true + delegate: ItemDelegate { width: control.width + 50 @@ -165,7 +180,7 @@ ComboBox background: DefaultRectangle { colorAnimation: false - color: popup_list_view.currentIndex === index ? Dex.CurrentTheme.buttonColorHovered : control.popupBackgroundColor + color: popup_list_view.currentIndex === index ? Dex.CurrentTheme.buttonColorHovered : control.mainBackgroundColor } onClicked: @@ -175,23 +190,6 @@ ComboBox } } - ScrollBar.vertical: ScrollBar - { - anchors.right: popup_list_view.right - anchors.rightMargin: 2 - width: 7 - background: DefaultRectangle - { - radius: 12 - color: Dex.CurrentTheme.scrollBarBackgroundColor - } - contentItem: DefaultRectangle - { - radius: 12 - color: Dex.CurrentTheme.scrollBarIndicatorColor - } - } - DexMouseArea { anchors.fill: parent @@ -204,12 +202,12 @@ ComboBox background: DefaultRectangle { - y: -5 - radius: 20 - colorAnimation: false width: parent.width height: parent.height + radius: control.radius color: control.popupBackgroundColor + colorAnimation: false + border.width: 1 } } diff --git a/atomic_defi_design/Dex/Components/DexSwitch.qml b/atomic_defi_design/Dex/Components/DexSwitch.qml index d3c0779f82..10fd5a6090 100644 --- a/atomic_defi_design/Dex/Components/DexSwitch.qml +++ b/atomic_defi_design/Dex/Components/DexSwitch.qml @@ -1,5 +1,6 @@ //! Qt Imports. import QtQuick 2.15 +import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 import QtQuick.Controls.Universal 2.15 @@ -12,54 +13,63 @@ Switch { id: control - property alias switchButtonWidth: indicator.width - property alias switchButtonHeight: indicator.height - property alias switchButtonRadius: indicator.radius + property alias label: _label + property alias label2: _label2 + property alias switchButtonWidth: _indicator.width + property alias switchButtonHeight: _indicator.height + property alias switchButtonRadius: _indicator.radius property alias mouseArea: _mouseArea + property color textColor: Dex.CurrentTheme.foregroundColor + property int labelWidth: label.text == '' ? 0 : 120 - Universal.foreground: Dex.CurrentTheme.foregroundColor - Universal.background: Dex.CurrentTheme.backgroundColor + width: labelWidth + 60 + height: 50 font.family: DexTypo.fontFamily - indicator: DexRectangle + indicator: DefaultRectangle { - id: indicator - anchors.verticalCenter: parent.verticalCenter + id: _indicator width: 52 height: 28 radius: 13 + anchors.verticalCenter: control.verticalCenter gradient: Gradient { orientation: Gradient.Horizontal GradientStop { - position: 0;color: Dex.CurrentTheme.switchGradientStartColor + position: 0 + color: Dex.CurrentTheme.switchGradientStartColor } GradientStop { - position: 0.9311;color: Dex.CurrentTheme.switchGradientEndColor + position: 0.9311 + color: Dex.CurrentTheme.switchGradientEndColor } } Rectangle { visible: !control.checked - anchors.centerIn: parent width: parent.width - 4 height: parent.height - 4 radius: parent.radius + x: 2 + y: 2 gradient: Gradient { orientation: Gradient.Horizontal GradientStop { - position: 0;color: control.checked ? Dex.CurrentTheme.switchGradientStartColor : Dex.CurrentTheme.switchGradientStartColor2 + position: 0; + color: control.checked ? Dex.CurrentTheme.switchGradientStartColor : Dex.CurrentTheme.switchGradientStartColor2 } GradientStop { - position: 0.9311;color: control.checked ? Dex.CurrentTheme.switchGradientEndColor : Dex.CurrentTheme.switchGradientEndColor2 + position: 0.9311; + color: control.checked ? Dex.CurrentTheme.switchGradientEndColor : Dex.CurrentTheme.switchGradientEndColor2 } } } @@ -67,7 +77,7 @@ Switch Rectangle { x: control.checked ? parent.width - width - 4 : 4 - anchors.verticalCenter: parent.verticalCenter + y: 3 width: parent.width / 2 - 2 height: parent.height - 6 radius: parent.radius + 2 @@ -77,21 +87,59 @@ Switch orientation: Gradient.Horizontal GradientStop { - position: 0;color: control.checked ? Dex.CurrentTheme.switchGradientStartColor2 : Dex.CurrentTheme.switchGradientStartColor + position: 0; + color: control.checked ? Dex.CurrentTheme.switchGradientStartColor2 : Dex.CurrentTheme.switchGradientStartColor } GradientStop { - position: 0.9311;color: control.checked ? Dex.CurrentTheme.switchGradientEndColor2 : Dex.CurrentTheme.switchGradientEndColor + position: 0.9311; + color: control.checked ? Dex.CurrentTheme.switchGradientEndColor2 : Dex.CurrentTheme.switchGradientEndColor } } } } + ColumnLayout + { + Layout.preferredWidth: labelWidth + Layout.preferredHeight: control.height + Layout.alignment: Qt.AlignVCenter + anchors.verticalCenter: control.verticalCenter + + visible: _label.text != '' + + DefaultText + { + id: _label + Layout.fillHeight: true + Layout.alignment: Qt.AlignVCenter + visible: _label.text != '' + font: control.font + color: control.textColor + leftPadding: _indicator.width + control.spacing + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Label.Wrap + } + + DefaultText + { + id: _label2 + Layout.fillHeight: true + visible: _label2.text != '' + font: DexTypo.caption + color: control.textColor + leftPadding: _indicator.width + control.spacing + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Label.Wrap + } + } + DefaultMouseArea { id: _mouseArea - anchors.fill: parent + anchors.fill: control acceptedButtons: Qt.NoButton } - -} \ No newline at end of file +} diff --git a/atomic_defi_design/Dex/Components/DexTextField.qml b/atomic_defi_design/Dex/Components/DexTextField.qml index 7025abc0e4..485f4b449a 100644 --- a/atomic_defi_design/Dex/Components/DexTextField.qml +++ b/atomic_defi_design/Dex/Components/DexTextField.qml @@ -26,7 +26,6 @@ TextField leftPadding: Math.max(0, left_text.width + 20) rightPadding: Math.max(0, right_text.width + 20) - topPadding: 7 background: DefaultRectangle { @@ -54,7 +53,7 @@ TextField RightClickMenu {} - DefaultText + DexLabel { id: left_text visible: text_value !== "" @@ -65,7 +64,7 @@ TextField font.pixelSize: text_field.font.pixelSize } - DefaultText + DexLabel { id: right_text visible: text_value !== "" @@ -80,4 +79,8 @@ TextField { if (forceFocus) text_field.forceActiveFocus() } + + onVisibleChanged: { + if (forceFocus && visible) text_field.forceActiveFocus() + } } diff --git a/atomic_defi_design/Dex/Components/DexTooltip.qml b/atomic_defi_design/Dex/Components/DexTooltip.qml index 78a3782e8b..070374053a 100644 --- a/atomic_defi_design/Dex/Components/DexTooltip.qml +++ b/atomic_defi_design/Dex/Components/DexTooltip.qml @@ -7,6 +7,7 @@ import Dex.Themes 1.0 as Dex ToolTip { id: control + property bool background_visible: true contentItem: DexLabel { @@ -17,6 +18,7 @@ ToolTip background: FloatingBackground { + visible: background_visible color: Dex.CurrentTheme.accentColor } } \ No newline at end of file diff --git a/atomic_defi_design/Dex/Components/DexWindowHeaderControl.qml b/atomic_defi_design/Dex/Components/DexWindowHeaderControl.qml index dca30634f5..f84d8c9013 100644 --- a/atomic_defi_design/Dex/Components/DexWindowHeaderControl.qml +++ b/atomic_defi_design/Dex/Components/DexWindowHeaderControl.qml @@ -2,13 +2,17 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Controls.Universal 2.15 import QtQuick.Layouts 1.12 +import ModelHelper 0.1 import Qaterial 1.0 as Qaterial +import "../Constants" import Dex.Themes 1.0 as Dex RowLayout { + property var orders: API.app.orders_mdl.orders_proxy_mdl.ModelHelper + width: 120 anchors.right: parent.right height: 30 @@ -68,6 +72,10 @@ RowLayout foregroundColor: Dex.CurrentTheme.foregroundColor icon.source: Qaterial.Icons.windowClose - onClicked: Qt.quit() + onClicked: + { + if (orders.count === 0 || !API.app.wallet_mgr.log_status()) Qt.quit() + else app.logout_confirm_modal.open() + } } } diff --git a/atomic_defi_design/Dex/Components/ElidableText.qml b/atomic_defi_design/Dex/Components/ElidableText.qml new file mode 100644 index 0000000000..a3e3682c2d --- /dev/null +++ b/atomic_defi_design/Dex/Components/ElidableText.qml @@ -0,0 +1,6 @@ +import QtQuick 2.12 + +DefaultText +{ + elide: Text.ElideRight +} diff --git a/atomic_defi_design/Dex/Components/EulaModal.qml b/atomic_defi_design/Dex/Components/EulaModal.qml index a5b5e5fec0..4191801010 100644 --- a/atomic_defi_design/Dex/Components/EulaModal.qml +++ b/atomic_defi_design/Dex/Components/EulaModal.qml @@ -41,7 +41,7 @@ MultipageModal contentWidth: eula_text.width - 10 contentHeight: eula_text.height - DexLabel + DefaultText { id: eula_text font: DexTypo.body1 @@ -53,17 +53,21 @@ MultipageModal } // Checkboxes - DexCheckBox + DefaultCheckBox { id: accept_eula + Layout.preferredWidth: parent.width visible: !close_only + labelWidth: eula_rect.width - 80 text: qsTr("Accept EULA") } - DexCheckBox + DefaultCheckBox { id: accept_tac + Layout.preferredWidth: parent.width visible: !close_only + labelWidth: eula_rect.width - 80 text: qsTr("Accept Terms and Conditions") } diff --git a/atomic_defi_design/Dex/Components/Expandable.qml b/atomic_defi_design/Dex/Components/Expandable.qml new file mode 100644 index 0000000000..d4858cf8b4 --- /dev/null +++ b/atomic_defi_design/Dex/Components/Expandable.qml @@ -0,0 +1,35 @@ +import QtQuick 2.12 + +Rectangle +{ + id: root + + property bool isExpanded: false + property real padding: 10 + + property alias header: headerLoader.sourceComponent + property alias content: contentLoader.sourceComponent + + implicitHeight: (padding * 2 + headerLoader.implicitHeight) + (isExpanded ? contentLoader.implicitHeight + padding * 2 : 0) + clip: true + + Loader + { + id: headerLoader + + anchors.top: parent.top + anchors.left: parent.left + anchors.margins: root.padding + } + + Loader + { + id: contentLoader + + visible: root.isExpanded + + anchors.top: headerLoader.bottom + anchors.left: parent.left + anchors.margins: root.padding + } +} diff --git a/atomic_defi_design/Dex/Components/GasInfoModal.qml b/atomic_defi_design/Dex/Components/GasInfoModal.qml new file mode 100644 index 0000000000..be86f0dd52 --- /dev/null +++ b/atomic_defi_design/Dex/Components/GasInfoModal.qml @@ -0,0 +1,42 @@ +// Qt Imports +import QtQuick 2.15 +import QtQuick.Layouts 1.15 + +// Project Imports +import "../Constants" +import App 1.0 + +MultipageModal { + id: root + + // Inside modal + MultipageModalContent { + titleText: General.cex_icon + " " + qsTr("How do I calculate gas?") + + DefaultText { + Layout.fillWidth: true + + text: qsTr('Gas is measured in gwei. Gwei is just a unit of Ether, and is equal to 0.000000001 ETH (or the equivalent platform coin such as AVAX or BNB). The gas price varies over time depending on network congestion.') + } + DefaultText { + Layout.fillWidth: true + + text: qsTr('The gas limit is how many units of gas (maximum) you allocate to pay for a transaction. The gas required depending on the size of the transaction & data being transmitted.') + } + DefaultText { + Layout.fillWidth: true + + text: qsTr('A standard transaction not involving contracts uses 21,000 gas units, with any of the limit remaining returned to the source address.') + } + DefaultText { + Layout.fillWidth: true + + text: qsTr('Transactions involving contracts may result in the whole limit being consumed, so be careful not to set it too high.') + } + DefaultText { + Layout.fillWidth: true + + text: qsTr('For more information, read the article at https://support.mycrypto.com/how-to/sending/how-to-know-what-gas-limit-to-use') + } + } +} diff --git a/atomic_defi_design/Dex/Components/HideFieldButton.qml b/atomic_defi_design/Dex/Components/HideFieldButton.qml index 7ebf622afb..d2657d7873 100644 --- a/atomic_defi_design/Dex/Components/HideFieldButton.qml +++ b/atomic_defi_design/Dex/Components/HideFieldButton.qml @@ -3,7 +3,7 @@ import "../Constants" import App 1.0 DefaultImage { - property alias mouse_area: mouse_area + property alias mouseArea: mouseArea property bool use_default_behaviour: true source: General.image_path + "dashboard-eye" + (hiding ? "" : "-hide") + ".svg" visible: hidable @@ -13,10 +13,10 @@ DefaultImage { anchors.verticalCenter: parent.verticalCenter antialiasing: true - opacity: mouse_area.containsMouse ? Style.hoverOpacity : 1 + opacity: mouseArea.containsMouse ? Style.hoverOpacity : 1 DefaultMouseArea { - id: mouse_area + id: mouseArea anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter } height: input_field.height; width: input_field.height diff --git a/atomic_defi_design/Dex/Components/LinkIcon.qml b/atomic_defi_design/Dex/Components/LinkIcon.qml index 2aaca2c1c8..6b3829f168 100644 --- a/atomic_defi_design/Dex/Components/LinkIcon.qml +++ b/atomic_defi_design/Dex/Components/LinkIcon.qml @@ -11,32 +11,37 @@ Circle Layout.preferredWidth: 50 Layout.preferredHeight: Layout.preferredWidth + Layout.topMargin: 10 + Layout.bottomMargin: 10 + Layout.leftMargin: 5 + Layout.rightMargin: 5 color: Style.colorOnlyIf(mouse_area.containsMouse, Style.colorTheme4) radius: 100 - DefaultImage + DexImage { id: icon + anchors.centerIn: parent width: parent.width * 0.9 height: parent.height * 0.9 + } - anchors.centerIn: parent + DexMouseArea + { + id: mouse_area + anchors.fill: parent + hoverEnabled: true + onClicked: Qt.openUrlExternally(link) + } - DefaultMouseArea - { - id: mouse_area - anchors.fill: parent - hoverEnabled: true - onClicked: Qt.openUrlExternally(link) - } - - DefaultTooltip - { - visible: mouse_area.containsMouse - id: tooltip_text - } + DexTooltip + { + id: tooltip_text + visible: mouse_area.containsMouse + background_visible: false + font.pixelSize: 12 } } diff --git a/atomic_defi_design/Dex/Components/LinksRow.qml b/atomic_defi_design/Dex/Components/LinksRow.qml index 159a8a8664..3dc6e45dcd 100644 --- a/atomic_defi_design/Dex/Components/LinksRow.qml +++ b/atomic_defi_design/Dex/Components/LinksRow.qml @@ -7,11 +7,12 @@ import "../Constants" import App 1.0 //> API RowLayout { - spacing: 10 + spacing: 0 LinkIcon { enabled: API.app_discord_url !== "" visible: enabled + Layout.leftMargin: 0 id: discord_icon link: API.app_discord_url @@ -31,6 +32,7 @@ RowLayout { LinkIcon { enabled: API.app_support_url !== "" visible: enabled + Layout.rightMargin: 0 link: API.app_support_url source: General.image_path + "icon-support.png" diff --git a/atomic_defi_design/Dex/Components/LoaderBusyIndicator.qml b/atomic_defi_design/Dex/Components/LoaderBusyIndicator.qml index 629cbfbb98..2b08124f40 100644 --- a/atomic_defi_design/Dex/Components/LoaderBusyIndicator.qml +++ b/atomic_defi_design/Dex/Components/LoaderBusyIndicator.qml @@ -9,7 +9,7 @@ Item { anchors.fill: parent - DefaultBusyIndicator { + DexBusyIndicator { anchors.centerIn: parent } } diff --git a/atomic_defi_design/Dex/Components/LogoutModal.qml b/atomic_defi_design/Dex/Components/LogoutModal.qml new file mode 100644 index 0000000000..f205e15293 --- /dev/null +++ b/atomic_defi_design/Dex/Components/LogoutModal.qml @@ -0,0 +1,72 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import ModelHelper 0.1 + +import App 1.0 +import Dex.Themes 1.0 as Dex +import "../Constants" +import "../Components" + +MultipageModal { + id: root + + property var orders: API.app.orders_mdl.orders_proxy_mdl.ModelHelper + + MultipageModalContent { + id: modal_content + topMarginAfterTitle: 15 + titleText: qsTr("Exit %1 or go to login menu?").arg(API.app_name) + + // Swap in progress warning + DefaultText + { + visible: orders + font.pixelSize: 14 + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: Text.AlignHCenter + Layout.fillWidth: true + color: Dex.CurrentTheme.noColor + text_value: + { + for (let i = 0; i < orders.count; i++) + { + let status = orders.data(i).order_status + switch (status) { + case "matched": + case "ongoing": + return qsTr("Warning: You currently have a swap in progress.\nLogging out may result in a failed swap.") + case "successful": + case "refunding": + case "failed": + break + default: + return qsTr("Warning: You currently have open maker orders.\nThey will be removed from the orderbook until you log in again.") + } + } + return "" + } + } + + // Buttons + footer: [ + DefaultButton { + text: qsTr("Login menu") + Layout.fillWidth: true + onClicked: + { + return_to_login() + } + }, + DefaultButton { + text: qsTr("Exit") + Layout.fillWidth: true + onClicked: Qt.quit() + }, + DefaultButton { + text: qsTr("Cancel") + Layout.fillWidth: true + onClicked: root.close() + } + ] + } +} diff --git a/atomic_defi_design/Dex/Components/MultipageModal.qml b/atomic_defi_design/Dex/Components/MultipageModal.qml index 8fcfff3e3e..39a0f51d26 100644 --- a/atomic_defi_design/Dex/Components/MultipageModal.qml +++ b/atomic_defi_design/Dex/Components/MultipageModal.qml @@ -1,5 +1,6 @@ import QtQuick 2.15 import QtQuick.Layouts 1.15 + import "../Constants" import App 1.0 import Dex.Themes 1.0 as Dex @@ -8,13 +9,13 @@ DefaultModal { id: root - property alias currentIndex: stack_layout.currentIndex + property alias currentIndex: stackLayout.currentIndex property int targetPageIndex: currentIndex - property alias count: stack_layout.count - default property alias pages: stack_layout.data + property alias count: stackLayout.count + default property alias pages: stackLayout.data - readonly property int _modalWidth: width - readonly property int _modalPadding: padding + readonly property int _modalWidth: width + readonly property int _modalPadding: padding function nextPage() { @@ -38,11 +39,10 @@ DefaultModal } } - //! Appearance width: 676 height: columnLayout.height + verticalPadding * 2 - onOpened: stack_layout.opacity = 1 + onOpened: stackLayout.opacity = 1 SequentialAnimation { @@ -52,7 +52,7 @@ DefaultModal NumberAnimation { target: root; property: "opacity"; to: 1; duration: fadeOut.duration } } - Column + ColumnLayout { id: columnLayout spacing: Style.rowSpacing @@ -62,8 +62,7 @@ DefaultModal Row { visible: root.count > 1 - anchors.horizontalCenter: parent.horizontalCenter - + Layout.alignment: Qt.AlignHCenter layoutDirection: Qt.RightToLeft Repeater @@ -113,9 +112,9 @@ DefaultModal // Inside modal StackLayout { - id: stack_layout - width: parent.width - height: stack_layout.children[stack_layout.currentIndex].height + id: stackLayout + Layout.fillWidth: true + Layout.preferredHeight: children[currentIndex].height } } } diff --git a/atomic_defi_design/Dex/Components/MultipageModalContent.qml b/atomic_defi_design/Dex/Components/MultipageModalContent.qml index 83de4fbc1d..fa900230ff 100644 --- a/atomic_defi_design/Dex/Components/MultipageModalContent.qml +++ b/atomic_defi_design/Dex/Components/MultipageModalContent.qml @@ -1,10 +1,9 @@ -//! Qt Imports import QtQuick 2.15 import QtQuick.Layouts 1.15 -//! Project Imports import "../Constants" import App 1.0 +import Dex.Themes 1.0 as Dex ColumnLayout { @@ -12,14 +11,24 @@ ColumnLayout property alias title: _title property alias titleText: _title.text + property alias subtitle: _subtitle + property alias subtitleText: _subtitle.text property var titleAlignment: Qt.AlignLeft + property var subtitleAlignment: Qt.AlignLeft property int titleTopMargin: 20 property int topMarginAfterTitle: 30 - - default property alias content: _innerLayout.data - property alias footer: _footer.data + + property alias flickable: modal_flickable + property int flickMax: 500 + property alias header: _header.data + default property alias content: _innerLayout.data + property alias contentSpacing: _innerLayout.spacing + property alias footer: _footer.data Layout.fillWidth: true + visible: true + Layout.fillHeight: false + Layout.maximumHeight: window.height - 50 DefaultText { @@ -27,23 +36,45 @@ ColumnLayout Layout.topMargin: root.titleTopMargin Layout.alignment: root.titleAlignment font: DexTypo.head6 + visible: text != '' + } + + DefaultText + { + id: _subtitle + Layout.topMargin: 5 + Layout.alignment: root.subtitleAlignment + color: Dex.CurrentTheme.foregroundColor2 + font.pixelSize: 13 + visible: text != '' + } + + // Header + + ColumnLayout + { + id: _header + spacing: 10 + Layout.topMargin: root.topMarginAfterTitle + Layout.preferredHeight: childrenRect.height + visible: childrenRect.height > 0 } DefaultFlickable { + id: modal_flickable flickableDirection: Flickable.VerticalFlick Layout.topMargin: root.topMarginAfterTitle Layout.fillWidth: true Layout.preferredHeight: contentHeight - Layout.maximumHeight: window.height - 200 - + Layout.maximumHeight: flickMax contentHeight: _innerLayout.height ColumnLayout { id: _innerLayout - anchors.centerIn: parent + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter width: parent.width } } @@ -54,5 +85,7 @@ ColumnLayout id: _footer Layout.topMargin: Style.rowSpacing spacing: Style.buttonSpacing + height: childrenRect.height + visible: childrenRect.height > 0 } } diff --git a/atomic_defi_design/Dex/Components/Pagination.qml b/atomic_defi_design/Dex/Components/Pagination.qml index cacaf7d4c6..7017d7ce82 100644 --- a/atomic_defi_design/Dex/Components/Pagination.qml +++ b/atomic_defi_design/Dex/Components/Pagination.qml @@ -8,6 +8,8 @@ import "../Constants" import App 1.0 import Dex.Themes 1.0 as Dex +// TODO: confirm this component no longer in use; delete. + RowLayout { id: control @@ -67,7 +69,7 @@ RowLayout currentIndex: options.indexOf(item_count) onCurrentValueChanged: API.app.orders_mdl.limit_nb_elements = currentValue mainBackgroundColor: Dex.CurrentTheme.backgroundColor - dropdownBackgroundColor: Dex.CurrentTheme.backgroundColor + popupBackgroundColor: Dex.CurrentTheme.backgroundColor } DefaultText { diff --git a/atomic_defi_design/Dex/Components/PairItemBadge.qml b/atomic_defi_design/Dex/Components/PairItemBadge.qml new file mode 100644 index 0000000000..a256f6a174 --- /dev/null +++ b/atomic_defi_design/Dex/Components/PairItemBadge.qml @@ -0,0 +1,102 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 + +import bignumberjs 1.0 + +import "../Constants" + +DefaultRectangle +{ + id: root + property alias ticker: ticker.text + property alias fullname: fullname.text + property string amount + + width: 260 + height: 66 + radius: 10 + + RowLayout + { + Layout.fillWidth: true + Layout.fillHeight: true + anchors.fill: parent + anchors.margins: 15 + spacing: 8 + + Item { Layout.fillWidth: true } + + DefaultImage + { + id: icon + Layout.preferredWidth: 35 + Layout.preferredHeight: 35 + Layout.alignment: Qt.AlignVCenter + source: General.coinIcon(root.ticker) + } + + Item { Layout.fillWidth: true } + + ColumnLayout + { + Layout.fillWidth: true + Layout.fillHeight: true + Layout.alignment: Qt.AlignVCenter + spacing: 5 + + DefaultText + { + id: ticker + Layout.fillWidth: true + font.pixelSize: 11 + horizontalAlignment: Text.AlignLeft + wrapMode: Text.NoWrap + } + + DefaultText + { + Layout.fillWidth: true + font.pixelSize: 11 + horizontalAlignment: Text.AlignLeft + wrapMode: Text.NoWrap + text: + { + BigNumber.config({ DECIMAL_PLACES: 6 }) + return new BigNumber(root.amount).toString(10) + } + } + } + + Item { Layout.fillWidth: true } + + ColumnLayout + { + Layout.fillWidth: true + Layout.fillHeight: true + Layout.alignment: Qt.AlignVCenter + spacing: 5 + + DefaultText + { + id: fullname + Layout.fillWidth: true + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignLeft + font.pixelSize: 11 + } + + DefaultText + { + id: amount_fiat + visible: text != '' + Layout.fillWidth: true + font.pixelSize: 11 + wrapMode: Text.NoWrap + horizontalAlignment: Text.AlignLeft + elide: Text.ElideRight + } + } + + Item { Layout.fillWidth: true } + } +} diff --git a/atomic_defi_design/Dex/Components/PasswordField.qml b/atomic_defi_design/Dex/Components/PasswordField.qml index a1cc503c18..163d44ac01 100644 --- a/atomic_defi_design/Dex/Components/PasswordField.qml +++ b/atomic_defi_design/Dex/Components/PasswordField.qml @@ -7,6 +7,7 @@ import App 1.0 ColumnLayout { property alias title: pw.title property alias field: pw.field + property int max_pw_len: General.max_std_pw_length property bool hide_hint: false property bool new_password: true property string match_password @@ -58,6 +59,7 @@ ColumnLayout { title: qsTr("Password") field.placeholderText: qsTr("Enter your wallet password") field.validator: RegExpValidator { regExp: General.reg_pass_input } + max_length: max_pw_len } ColumnLayout { @@ -92,7 +94,7 @@ ColumnLayout { } DefaultText { font.pixelSize: Style.textSizeSmall3 - text_value: hintPrefix(hasEnoughCharacters()) + qsTr("At least %n character(s)", "", high_security ? 16 : 1) + text_value: hintPrefix(hasEnoughCharacters()) + qsTr("Between %1 and %2 character(s)").arg(high_security ? 16 : 1).arg(max_pw_len) color: hintColor(hasEnoughCharacters()) } DefaultText { diff --git a/atomic_defi_design/Dex/Components/PopupManager.qml b/atomic_defi_design/Dex/Components/PopupManager.qml index 07325403e2..8d2a3d7f66 100644 --- a/atomic_defi_design/Dex/Components/PopupManager.qml +++ b/atomic_defi_design/Dex/Components/PopupManager.qml @@ -4,6 +4,7 @@ import Qaterial 1.0 as Qaterial import QtQuick.Layouts 1.12 import App 1.0 import Dex.Themes 1.0 as Dex +import "../Constants" Popup { @@ -11,7 +12,7 @@ Popup id: dialog width: 420 - height: _insideColumn.height > dialog.height ? _insideColumn.height + 82 : dialog.height + height: _insideColumn.height > dialog.height ? _insideColumn.height + 82 : dialog.height dim: true modal: true anchors.centerIn: Overlay.overlay @@ -54,11 +55,13 @@ Popup property int standardButtons: Dialog.NoButton property string yesButtonText: "" property string cancelButtonText: "" + property bool showCancelBtn: true property bool getText: false property bool isPassword: false property bool centerAlign: false property color backgroundColor: Dex.CurrentTheme.backgroundColor property bool titleBold: false + property bool forceFocus: false property bool enableAcceptButton: validator === undefined ? true : validator(_insideField.field.text) background: Qaterial.ClipRRect @@ -158,18 +161,23 @@ Popup field.font: DexTypo.body2 placeholderText: dialog.placeholderText field.placeholderText: "" + field.forceFocus: forceFocus + max_length: dialog.isPassword ? General.max_std_pw_length : 40 field.rightPadding: dialog.isPassword ? 55 : 20 field.leftPadding: dialog.isPassword ? 70 : 20 field.echoMode: dialog.isPassword ? TextField.Password : TextField.Normal field.onTextChanged: { - if (validator(field.text)) + if (validator) { - dialog.enableAcceptButton = true - } - else { - dialog.enableAcceptButton = false + if (validator(field.text)) + { + dialog.enableAcceptButton = true + } + else { + dialog.enableAcceptButton = false + } } } field.onAccepted: @@ -249,6 +257,7 @@ Popup DexAppButton { id: cancelBtn + visible: showCancelBtn text: dialog.cancelButtonText !== "" ? dialog.cancelButtonText : "Cancel" height: 40 leftPadding: 20 @@ -268,7 +277,7 @@ Popup { text: dialog.yesButtonText !== "" ? dialog.yesButtonText : "Yes" height: 40 - width: cancelBtn.width + width: showCancelBtn ? cancelBtn.width : 90 leftPadding: 20 rightPadding: 20 radius: 18 diff --git a/atomic_defi_design/Dex/Components/RestartModal.qml b/atomic_defi_design/Dex/Components/RestartModal.qml index c2cef491be..b5907d7a55 100644 --- a/atomic_defi_design/Dex/Components/RestartModal.qml +++ b/atomic_defi_design/Dex/Components/RestartModal.qml @@ -29,7 +29,6 @@ MultipageModal console.log("Restarting the application...") _restartTimer.stop() onTimerEnded() - API.app.restart() } } diff --git a/atomic_defi_design/Dex/Components/RoundComboBox.qml b/atomic_defi_design/Dex/Components/RoundComboBox.qml index a02dff4561..247073ec5b 100644 --- a/atomic_defi_design/Dex/Components/RoundComboBox.qml +++ b/atomic_defi_design/Dex/Components/RoundComboBox.qml @@ -10,33 +10,25 @@ import "../Constants" import App 1.0 import Dex.Themes 1.0 as Dex +// TODO: Confirm not in use; delete + ComboBox { id: control property alias radius: bg_rect.radius - property color lineHoverColor: DexTheme.hoverColor + readonly property bool disabled: !enabled + property int dropDownMaxHeight: 450 property color mainBackgroundColor: Dex.CurrentTheme.floatingBackgroundColor - property int dropDownMaxHeight: 300 - property color dropdownBackgroundColor: Dex.CurrentTheme.floatingBackgroundColor + property color popupBackgroundColor: Dex.CurrentTheme.floatingBackgroundColor + property color highlightedBackgroundColor: Dex.CurrentTheme.comboBoxDropdownItemHighlightedColor + property string mainLineText: control.displayText property var dropdownLineText: m => textRole === "" ? m.modelData : !m.modelData ? m[textRole] : m.modelData[textRole] - property string mainLineText: control.displayText - - readonly property bool disabled: !enabled font.family: Style.font_family - - Behavior on lineHoverColor - { - ColorAnimation - { - duration: Style.animationDuration - } - } - hoverEnabled: true // Main, selected text @@ -53,7 +45,6 @@ ComboBox } } - // Main background background: FloatingBackground { @@ -108,7 +99,7 @@ ComboBox background: Rectangle { radius: control.radius - color: control.dropdownBackgroundColor + color: control.popupBackgroundColor } } diff --git a/atomic_defi_design/Dex/Components/ScrollBarHorizontal.qml b/atomic_defi_design/Dex/Components/ScrollBarHorizontal.qml new file mode 100644 index 0000000000..6b4644cd62 --- /dev/null +++ b/atomic_defi_design/Dex/Components/ScrollBarHorizontal.qml @@ -0,0 +1,42 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 + +import App 1.0 +import Dex.Themes 1.0 as Dex + +ScrollBar +{ + id: control + + anchors.bottom: root.bottom + anchors.bottomMargin: 0 + policy: scrollbar_visible ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff + property bool visibleBackground: true + width: 6 + + contentItem: Item + { + DefaultRectangle + { + width: parent.width + height: parent.height + anchors.horizontalCenter: parent.horizontalCenter + + color: Dex.CurrentTheme.scrollBarIndicatorColor + } + } + + background: Item + { + width: 6 + x: 0 + DefaultRectangle + { + visible: control.visibleBackground + width: parent.width + height: parent.height + anchors.horizontalCenter: parent.horizontalCenter + color: Dex.CurrentTheme.scrollBarBackgroundColor + } + } +} diff --git a/atomic_defi_design/Dex/Components/SearchField.qml b/atomic_defi_design/Dex/Components/SearchField.qml index f4ede557a0..1c18a39086 100644 --- a/atomic_defi_design/Dex/Components/SearchField.qml +++ b/atomic_defi_design/Dex/Components/SearchField.qml @@ -1,16 +1,18 @@ import QtQuick 2.12 import QtQuick.Controls 2.2 +import Qaterial 1.0 as Qaterial + import "../Constants" import Dex.Themes 1.0 as Dex Rectangle { property int searchIconLeftMargin: 13 - property bool forceFocus: false - + property var searchModel: API.app.portfolio_pg.global_cfg_mdl.all_proxy property alias searchIcon: _searchIcon property alias textField: _textField + property alias forceFocus: _textField.forceFocus color: Dex.CurrentTheme.accentColor radius: 18 @@ -27,7 +29,7 @@ Rectangle source: General.image_path + "exchange-search.svg" - DefaultColorOverlay + DexColorOverlay { anchors.fill: parent source: parent @@ -35,24 +37,50 @@ Rectangle } } - TextField + DefaultTextField { id: _textField anchors.left: _searchIcon.right - anchors.verticalCenter: _searchIcon.verticalCenter - anchors.verticalCenterOffset: 1 + anchors.verticalCenter: parent.verticalCenter width: parent.width - x - 5 height: parent.height - background: null + font.pixelSize: 14 placeholderText: qsTr("Search") placeholderTextColor: Dex.CurrentTheme.textPlaceholderColor - font.pixelSize: 14 - Component.onCompleted: + + onTextChanged: searchModel.setFilterFixedString(_textField.text) + Component.onDestruction: searchModel.setFilterFixedString("") + } + + DefaultRectangle + { + id: _clearIcon + visible: _textField.text != "" + anchors.right: parent.right + anchors.rightMargin: searchIconLeftMargin + anchors.verticalCenter: parent.verticalCenter + color: mouseArea.containsMouse ? Dex.CurrentTheme.buttonColorHovered : "transparent" + + width: 20 + height: 20 + + Qaterial.ColorIcon { - if (forceFocus) _textField.forceActiveFocus() + anchors.centerIn: parent + iconSize: 12 + color: Dex.CurrentTheme.textPlaceholderColor + source: Qaterial.Icons.close + } + + DefaultMouseArea + { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + onClicked: _textField.text = "" } } } diff --git a/atomic_defi_design/Dex/Components/SwapIcon.qml b/atomic_defi_design/Dex/Components/SwapIcon.qml index d193b13f66..9fcfdfba11 100644 --- a/atomic_defi_design/Dex/Components/SwapIcon.qml +++ b/atomic_defi_design/Dex/Components/SwapIcon.qml @@ -11,6 +11,7 @@ Item property string top_arrow_ticker property string bottom_arrow_ticker property bool hovered: false + property color color: Dex.CurrentTheme.foregroundColor implicitWidth: 20 implicitHeight: 50 @@ -19,6 +20,6 @@ Item { anchors.centerIn: parent source: Qaterial.Icons.swapHorizontal - color: Dex.CurrentTheme.foregroundColor + color: root.color } } diff --git a/atomic_defi_design/Dex/Components/TextAreaWithTitle.qml b/atomic_defi_design/Dex/Components/TextAreaWithTitle.qml index 9757c9ce6f..38d85520e8 100644 --- a/atomic_defi_design/Dex/Components/TextAreaWithTitle.qml +++ b/atomic_defi_design/Dex/Components/TextAreaWithTitle.qml @@ -15,7 +15,7 @@ ColumnLayout property alias field: input_field property alias save_button: save_button property alias hide_button: hide_button - property alias hide_button_area: hide_button.mouse_area + property alias hide_button_area: hide_button.mouseArea property bool copyable: false property bool hidable: false property var onReturn // function @@ -49,7 +49,7 @@ ColumnLayout icon: Qaterial.Icons.contentCopy color: copyArea.containsMouse ? Dex.CurrentTheme.accentColor : Dex.CurrentTheme.foregroundColor - DefaultMouseArea + DexMouseArea { id: copyArea anchors.fill: parent @@ -76,13 +76,14 @@ ColumnLayout color: Dex.CurrentTheme.accentColor opacity: .7 radius: 8 - border.color: input_field.focus ? Dex.CurrentTheme.accentColor : DexTheme.rectangleBorderColor + border.color: input_field.focus ? Dex.CurrentTheme.accentColor : Dex.CurrentTheme.backgroundColor border.width: input_field.focus ? 2 : 0 } HideFieldButton { id: hide_button } } + DexAppButton { anchors.verticalCenter: parent.verticalCenter id: save_button diff --git a/atomic_defi_design/Dex/Components/TextEditWithCopy.qml b/atomic_defi_design/Dex/Components/TextEditWithCopy.qml new file mode 100644 index 0000000000..859be3bc4b --- /dev/null +++ b/atomic_defi_design/Dex/Components/TextEditWithCopy.qml @@ -0,0 +1,84 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import "../Constants" +import "../Components" +import App 1.0 +import Dex.Themes 1.0 as Dex +import Dex.Components 1.0 as Dex + +RowLayout +{ + id: control + property string text_value: "" + property int font_size: Style.textSize + property int text_box_width: 500 + property bool privacy: false + property bool align_left: false + property string linkURL: "" + property string onCopyNotificationTitle: "" + property string onCopyNotificationMsg: qsTr("copied to clipboard") + Layout.fillWidth: true + + Item { Layout.fillWidth: !align_left } + + Dex.Rectangle + { + width: text_box_width + height: 30 + color: Dex.CurrentTheme.buttonColorEnabled + + RowLayout + { + spacing: 4 + anchors.fill: parent + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: !align_left ? parent.horizontalCenter : undefined + + Item { width: 6 } + + TextEdit + { + font.family: Style.font_family + font.pixelSize: font_size + text: privacy && General.privacy_mode ? General.privacy_text : text_value + wrapMode: Text.WordWrap + selectByMouse: true + readOnly: true + + selectedTextColor: DexTheme.textSelectedColor + selectionColor: DexTheme.textSelectionColor + color: DexTheme.foregroundColor + } + + Item { Layout.fillWidth: true } + + DefaultCopyIcon + { + id: copy_icon + visible: control.onCopyNotificationTitle !== "" + copyText: control.text_value + notifyTitle: control.onCopyNotificationTitle + notifyMsg: control.onCopyNotificationMsg + iconSize: font_size + } + + DefaultLinkIcon + { + visible: control.linkURL !== "" + linkURL: control.linkURL + iconSize: font_size + } + + Item { width: 6 } + } + + DefaultMouseArea + { + anchors.fill: parent + cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor + acceptedButtons: Qt.NoButton + } + } + + Item { Layout.fillWidth: true } +} \ No newline at end of file diff --git a/atomic_defi_design/Dex/Components/TextEditWithTitle.qml b/atomic_defi_design/Dex/Components/TextEditWithTitle.qml index 521bba7526..93a0eba3c6 100644 --- a/atomic_defi_design/Dex/Components/TextEditWithTitle.qml +++ b/atomic_defi_design/Dex/Components/TextEditWithTitle.qml @@ -11,12 +11,14 @@ ComponentWithTitle { id: control - property alias label: text - property alias text: text.text_value - property alias value_color: text.color - property alias privacy: text.privacy + property alias label: _text + property alias text: _text.text_value + property alias value_color: _text.color + property alias privacy: _text.privacy property bool copy: false - property string onCopyNotificationTitle: qsTr("Swap ID") + property bool monospace: false + property string linkURL: "" + property string onCopyNotificationTitle: "" property string onCopyNotificationMsg: qsTr("copied to clipboard") Row @@ -25,39 +27,38 @@ ComponentWithTitle DefaultText { - id: text + id: _text width: implicitWidth > parent.width * 0.9 ? parent.width * 0.9 : implicitWidth clip: true textFormat: TextEdit.AutoText opacity: show_content ? 1 : 0 - wrapMode: Text.WrapAnywhere - + wrapMode: Text.WordWrap + monospace: control.monospace + rightPadding: 5 Behavior on opacity { SmoothedAnimation { duration: expand_animation.duration; velocity: -1 } } Behavior on Layout.preferredHeight { SmoothedAnimation { id: expand_animation; duration: Constants.Style.animationDuration * 2; velocity: -1 } } } - Qaterial.Icon + DefaultCopyIcon { - visible: control.copy - - width: parent.width * 0.1 - size: 16 - icon: Qaterial.Icons.contentCopy - color: copyArea.containsMouse ? Dex.CurrentTheme.foregroundColor2 : Dex.CurrentTheme.foregroundColor - - DefaultMouseArea - { - id: copyArea - anchors.fill: parent - hoverEnabled: true - onClicked: - { - Qaterial.Clipboard.text = control.text - app.notifyCopy(onCopyNotificationTitle, onCopyNotificationMsg) - } - } + id: copyIcon + visible: control.onCopyNotificationTitle !== "" + copyText: control.text + notifyTitle: control.onCopyNotificationTitle + notifyMsg: control.onCopyNotificationMsg + iconSize: 14 } + + DefaultLinkIcon + { + visible: control.linkURL !== "" + linkURL: control.linkURL + x: copyIcon.visible ? _text.width + 18 : _text.width + 28 + iconSize: 14 + } + + Item { Layout.fillWidth: true } } } diff --git a/atomic_defi_design/Dex/Components/TextFieldWithTitle.qml b/atomic_defi_design/Dex/Components/TextFieldWithTitle.qml index ebaf73ff59..e0bd8aae3f 100644 --- a/atomic_defi_design/Dex/Components/TextFieldWithTitle.qml +++ b/atomic_defi_design/Dex/Components/TextFieldWithTitle.qml @@ -9,6 +9,8 @@ import Dex.Themes 1.0 as Dex ColumnLayout { id: control + Layout.fillWidth: true + Layout.fillHeight: true property bool copyable: false property bool hidable: false @@ -17,8 +19,10 @@ ColumnLayout property alias title: title_text.text property alias field: input_field + property alias max_length: input_field.maximumLength + property alias hide_button: hide_button - property alias hide_button_area: hide_button.mouse_area + property alias hide_button_area: hide_button.mouseArea // Local function reset() @@ -38,7 +42,7 @@ ColumnLayout visible: text !== '' } - DexLabel + DefaultText { visible: required && input_field.text === '' font.pixelSize: Style.textSizeSmall2 diff --git a/atomic_defi_design/Dex/Components/TextWithTitle.qml b/atomic_defi_design/Dex/Components/TextWithTitle.qml index 36ceaa778a..48b5ddc8cc 100644 --- a/atomic_defi_design/Dex/Components/TextWithTitle.qml +++ b/atomic_defi_design/Dex/Components/TextWithTitle.qml @@ -5,6 +5,7 @@ import App 1.0 ComponentWithTitle { property alias text: text.text_value + property alias text_font: text.font property alias value_color: text.color property alias privacy: text.privacy diff --git a/atomic_defi_design/Dex/Components/TransactionArrow.qml b/atomic_defi_design/Dex/Components/TransactionArrow.qml new file mode 100644 index 0000000000..edf58a44ec --- /dev/null +++ b/atomic_defi_design/Dex/Components/TransactionArrow.qml @@ -0,0 +1,11 @@ +// Project Imports +import Dex.Themes 1.0 as Dex //> CurrentTheme + +Arrow +{ + id: root + + property alias amISender: root.up + + color: !amISender ? Dex.CurrentTheme.senderColorStart : Dex.CurrentTheme.receiverColorStart +} diff --git a/atomic_defi_design/Dex/Components/UserIcon.qml b/atomic_defi_design/Dex/Components/UserIcon.qml new file mode 100644 index 0000000000..d557228cc7 --- /dev/null +++ b/atomic_defi_design/Dex/Components/UserIcon.qml @@ -0,0 +1,12 @@ +// 3rdParty Imports +import Qaterial 1.0 as Qaterial //> ColorIcon + +// Project Imports +import Dex.Themes 1.0 as Dex //> CurrentTheme + +Qaterial.ColorIcon +{ + color: Dex.CurrentTheme.userIconColorStart + source: Qaterial.Icons.account + iconSize: 28 +} diff --git a/atomic_defi_design/Dex/Components/WalletNameField.qml b/atomic_defi_design/Dex/Components/WalletNameField.qml deleted file mode 100644 index 58c6095598..0000000000 --- a/atomic_defi_design/Dex/Components/WalletNameField.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.15 - -TextFieldWithTitle { - id: input_wallet_name - title: qsTr("Wallet Name") - field.placeholderText: qsTr("Enter the name of your wallet here") - field.validator: RegExpValidator { regExp: /[a-zA-Z0-9]+/ } - - required: true - - function reset() { field.text = '' } -} diff --git a/atomic_defi_design/Dex/Components/Widget.qml b/atomic_defi_design/Dex/Components/Widget.qml new file mode 100644 index 0000000000..6b6c01c908 --- /dev/null +++ b/atomic_defi_design/Dex/Components/Widget.qml @@ -0,0 +1,177 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.12 + +import Qaterial 1.0 as Qaterial + +import Dex.Themes 1.0 as Dex +import "../Constants" + +Item +{ + id: root + + property string title: "Widget" + + property bool collapsable: true + property bool collapsed: false + + property bool resizable: true + + property alias header: headerLoader.sourceComponent + property alias background: backgroundLoader.sourceComponent + + property int margins: 10 + property int spacing: 10 + property int contentSpacing: 10 + + property int collapsedHeight: 70 + property int minHeight: collapsedHeight + property int maxHeight: -1 + property int _previousHeight + + default property alias contentData: content.data + + function isCollapsed() { return collapsed } + + clip: true + + // Background + Loader + { + id: backgroundLoader + anchors.fill: parent + sourceComponent: defaultBackground + } + + // Header + Content + Column + { + id: column + + anchors.fill: parent + anchors.margins: root.margins + + spacing: root.spacing + + // Header + Loader + { + id: headerLoader + sourceComponent: defaultHeader + width: parent.width + } + + // Content + ColumnLayout + { + id: content + + visible: !root.collapsed + + width: parent.width + height: parent.height - y + + spacing: root.contentSpacing + } + } + + // Resize area + MouseArea + { + enabled: resizable && !collapsed + visible: enabled + + anchors.bottom: root.bottom + width: root.width + height: 5 + + cursorShape: Qt.SizeVerCursor + + onMouseYChanged: + { + if (root.parent.objectName === "widgetContainer") + { + if (root.parent.availableHeight === 0 && mouseY > 0) + return + if (root.parent.availableHeight && root.parent.availableHeight < mouseY) + root.height += root.parent.availableHeight + else + root.height += mouseY + } + + if (root.maxHeight >= 0 && root.height > root.maxHeight) + root.height = root.maxHeight + else if (root.minHeight >= 0 && root.height < root.minHeight) + root.height = root.minHeight + } + } + + // Header Component + Component + { + id: defaultHeader + + RowLayout + { + DefaultText { text: root.title; font: DexTypo.subtitle1 } + Item { Layout.fillWidth: true } + Qaterial.Icon + { + visible: root.collapsable + width: 20 + height: 20 + color: collapseButMouseArea.containsMouse ? Dex.CurrentTheme.foregroundColor2 : Dex.CurrentTheme.foregroundColor + icon: root.collapsed ? Qaterial.Icons.chevronUp : Qaterial.Icons.chevronDown + + DefaultMouseArea + { + id: collapseButMouseArea + anchors.fill: parent + hoverEnabled: true + onClicked: + { + let oldHeight = root.height + root.collapsed = !root.collapsed + if (root.collapsed) + { + root._previousHeight = root.height + root.height = root.collapsedHeight + } + else + { + if (root.parent.objectName === "widgetContainer" && root.parent.availableHeight < root._previousHeight) + { + if (root.height + root.parent.availableHeight < minHeight) + { + root.parent.resetSizes() + } + else + { + root.height += root.parent.availableHeight + } + } + else + { + root.height = root._previousHeight + } + root._previousHeight = root.collapsedHeight + } + } + } + } + } + } + + // Background Component + Component + { + id: defaultBackground + + Rectangle + { + radius: 10 + color: Dex.CurrentTheme.floatingBackgroundColor + } + } +} diff --git a/atomic_defi_design/Dex/Components/WidgetContainer.qml b/atomic_defi_design/Dex/Components/WidgetContainer.qml new file mode 100644 index 0000000000..98326b427f --- /dev/null +++ b/atomic_defi_design/Dex/Components/WidgetContainer.qml @@ -0,0 +1,24 @@ +import QtQuick 2.12 + +Column +{ + readonly property string componentName: "widgetContainer" + readonly property int availableHeight: height - (childrenRect.height + (children.length - 1) * spacing) + + function getHeight(ratio) + { + return (height - (children.length - 1) * spacing) * ratio + } + + function resetSizes() + { + for (let i = 0; i < children.length; i++) + { + let child = children[i] + child.height = child.minHeight + } + } + + spacing: 4 + objectName: componentName +} diff --git a/atomic_defi_design/Dex/Components/ZcashParamsModal.qml b/atomic_defi_design/Dex/Components/ZcashParamsModal.qml new file mode 100644 index 0000000000..c32d414c4c --- /dev/null +++ b/atomic_defi_design/Dex/Components/ZcashParamsModal.qml @@ -0,0 +1,125 @@ +// Qt Imports +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 + +// Project Imports +import "../Constants" as Dex +import "../Components" as Dex +import App 1.0 + +Dex.MultipageModal +{ + id: root + readonly property var coins: API.app.zcash_params.get_enable_after_download() + width: 750 + closePolicy: Popup.NoAutoClose + + // Inside modal + Dex.MultipageModalContent + { + titleText: qsTr("%1 Activation Failed!").arg(coins.join(' / ')) + + Dex.DefaultText + { + Layout.fillWidth: true + text: qsTr("To activate ZHTLC coins, you need to download the Zcash Params.\nThis might take a few minutes...") + } + + HorizontalLine + { + Layout.topMargin: 8 + Layout.bottomMargin: 8 + Layout.fillWidth: true + } + + ColumnLayout + { + Dex.DefaultProgressBar + { + id: sapling_output_params + label.text: "sapling-output.params" + bar_width_pct: 0 + pct_value.text: "0.00 %" + } + Dex.DefaultProgressBar + { + id: sapling_spend_params + label.text: "sapling-spend.params" + bar_width_pct: 0 + pct_value.text: "0.00 %" + } + } + + HorizontalLine + { + Layout.topMargin: 8 + Layout.bottomMargin: 8 + Layout.fillWidth: true + } + + footer: + [ + Item { Layout.fillWidth: true }, + Dex.DefaultButton + { + id: download_button + text: qsTr("Download params & enable coins") + enabled: !sapling_output_params.bar_width_pct > 0 || !sapling_spend_params.bar_width_pct > 0 + onClicked: { + download_button.enabled = false + Dex.API.app.zcash_params.download_zcash_params() + } + }, + Item { Layout.fillWidth: true }, + Dex.DefaultButton + { + text: qsTr("More Info") + onClicked: Qt.openUrlExternally("https://www.coinbureau.com/education/zcash-ceremony/") + }, + Item { Layout.fillWidth: true }, + Dex.DefaultButton + { + text: qsTr("Close") + onClicked: close() + }, + Item { Layout.fillWidth: true } + ] + + Connections + { + target: Dex.API.app.zcash_params + + // todo: can be improved. + // put it maybe in the backend ? + function onCombinedDownloadStatusChanged() + { + let combined_progress = 0 + let data = JSON.parse(Dex.API.app.zcash_params.get_combined_download_progress()) + for (let k in data) + { + let v = data[k]; + let pct = Dex.General.formatDouble(v * 100, 2) + combined_progress += parseFloat(v)/Object.keys(data).length + switch(k) + { + case "sapling-output.params": + sapling_output_params.bar_width_pct = pct + sapling_output_params.pct_value.text = pct + "%" + break + case "sapling-spend.params": + sapling_spend_params.bar_width_pct = pct + sapling_spend_params.pct_value.text = pct + "%" + break + } + console.log(combined_progress) + if (combined_progress == 1) + { + console.log("closing") + root.close() + } + } + } + } + } +} diff --git a/atomic_defi_design/Dex/Components/qmldir b/atomic_defi_design/Dex/Components/qmldir new file mode 100644 index 0000000000..bc894bd813 --- /dev/null +++ b/atomic_defi_design/Dex/Components/qmldir @@ -0,0 +1,22 @@ +module Dex.Components + +Button 1.0 DefaultButton.qml +ComboBox 1.0 DefaultComboBox.qml +ComboBoxWithSearchBar 1.0 ComboBoxWithSearchBar.qml +ClickableText 1.0 ClickableText.qml +ElidableText 1.0 ElidableText.qml +GradientButton 1.0 GradientButton.qml +Image 1.0 DefaultImage.qml +ListView 1.0 DefaultListView.qml +MouseArea 1.0 DefaultMouseArea.qml +MultipageModal 1.0 MultipageModal.qml +MultipageModalContent 1.0 MultipageModalContent.qml +Popup 1.0 DefaultPopup.qml +Rectangle 1.0 DefaultRectangle.qml +ScrollView 1.0 DefaultScrollView.qml +SearchField 1.0 SearchField.qml +Text 1.0 DefaultText.qml +TextField 1.0 DefaultTextField.qml +TextFieldWithTitle 1.0 TextFieldWithTitle.qml +ToolTip 1.0 DefaultTooltip.qml +UserIcon 1.0 UserIcon.qml diff --git a/atomic_defi_design/Dex/Constants/DexTheme.qml b/atomic_defi_design/Dex/Constants/DexTheme.qml index 60676c431c..4104684b0b 100644 --- a/atomic_defi_design/Dex/Constants/DexTheme.qml +++ b/atomic_defi_design/Dex/Constants/DexTheme.qml @@ -118,8 +118,8 @@ QtObject { property bool portfolioPieGradient: false - property color arrowUpColor: redColor - property color arrowDownColor: greenColor + property color senderColorStart: redColor + property color receiverColorStart: greenColor @@ -143,6 +143,8 @@ QtObject { property color lineChartColor: accentColor property color chartGridLineColor: Qt.rgba(255,255,255,0.4) + property color busyIndicatorColor: Dex.CurrentTheme.busyIndicatorColor + // Button property color buttonColorDisabled: Dex.CurrentTheme.buttonColorDisabled property color buttonColorHovered: Dex.CurrentTheme.buttonColorHovered @@ -216,15 +218,6 @@ QtObject { readonly property int animationDuration: 125 - readonly property int textSizeVerySmall1: 1 - readonly property int textSizeVerySmall2: 2 - readonly property int textSizeVerySmall3: 3 - readonly property int textSizeVerySmall4: 4 - readonly property int textSizeVerySmall5: 5 - readonly property int textSizeVerySmall6: 6 - readonly property int textSizeVerySmall7: 7 - readonly property int textSizeVerySmall8: 8 - readonly property int textSizeVerySmall9: 9 readonly property int textSizeSmall: 10 readonly property int textSizeSmall1: 11 readonly property int textSizeSmall2: 12 @@ -322,10 +315,6 @@ QtObject { readonly property string colorRectangle: dark_theme ? colorTheme7 : colorTheme7 readonly property string colorInnerBackground: dark_theme ? colorTheme7 : colorTheme7 - readonly property string colorGradient1: dark_theme ? colorTheme9 : colorTheme9 - readonly property string colorGradient2: dark_theme ? colorTheme5 : colorTheme5 - readonly property string colorGradient3: dark_theme ? "#24283D" : "#24283D" - readonly property string colorGradient4: dark_theme ? "#0D0F21" : "#0D0F21" readonly property string colorDropShadowLight: dark_theme ? "#216975a4" : "#21FFFFFF" readonly property string colorDropShadowLight2: dark_theme ? "#606975a4" : "#60FFFFFF" readonly property string colorDropShadowDark: dark_theme ? "#FF050615" : "#BECDE2" @@ -354,59 +343,18 @@ QtObject { readonly property string colorRectangleBorderGradient1: dark_theme ? "#2A2F48" : "#DDDDDD" readonly property string colorRectangleBorderGradient2: dark_theme ? "#0D1021" : "#EFEFEF" - readonly property string colorChartText: dark_theme ? "#405366" : "#B5B9C1" - readonly property string colorChartLegendLine: dark_theme ? "#3F5265" : "#BDC0C8" - readonly property string colorChartGrid: dark_theme ? "#202333" : "#E6E8ED" - readonly property string colorChartLineText: dark_theme ? "#405366" : "#FFFFFF" - - readonly property string colorChartMA1: dark_theme ? "#5BC6FA" : "#5BC6FA" - readonly property string colorChartMA2: dark_theme ? "#F1D17F" : "#F1D17F" - readonly property string colorLineBasic: dark_theme ? "#303344" : "#303344" - readonly property string colorBusyIndicator: dark_theme ? "#405ff9" : "#405ff9" readonly property string colorText: dark_theme ? Style.colorWhite1 : "#405366" readonly property string colorText2: dark_theme ? "#79808C" : "#3C5368" readonly property string colorTextDisabled: dark_theme ? Style.colorWhite8 : "#B5B9C1" - readonly property var colorButtonDisabled: ({ - "default": Style.colorTheme9, - "primary": Style.colorGreen3, - "danger": Style.colorRed3 - }) - readonly property var colorButtonHovered: ({ - "default": Style.colorTheme6, - "primary": Style.colorGreen, - "danger": Style.colorRed - }) - readonly property var colorButtonEnabled: ({ - "default": Style.colorRectangle, - "primary": Style.colorGreen2, - "danger": Style.colorRed2 - }) - readonly property var colorButtonTextDisabled: ({ - "default": Style.colorWhite8, - "primary": Style.colorWhite13, - "danger": Style.colorWhite13 - }) - readonly property var colorButtonTextHovered: ({ - "default": Style.colorText, - "primary": Style.colorWhite11, - "danger": Style.colorWhite11 - }) - readonly property var colorButtonTextEnabled: ({ - "default": Style.colorText, - "primary": Style.colorWhite11, - "danger": Style.colorWhite11 - }) + readonly property string colorPlaceholderText: Style.colorWhite9 readonly property string colorSelectedText: Style.colorTheme9 readonly property string colorSelection: Style.colorGreen2 readonly property string colorTrendingLine: dark_theme ? Style.colorGreen : "#37a6ef" - readonly property string colorTrendingUnderLine: dark_theme ? Style.colorGradient3 : "#e3f2fd" - - readonly property string modalValueColor: colorWhite4 function getValueColor(v) { v = parseFloat(v) @@ -530,6 +478,7 @@ QtObject { "WBTC": "#CCCCCC", "YFI": "#006BE6", "ZRX": "#302C2C", - "UNI": "#FF007A" + "UNI": "#FF007A", + "RUNES": "#336699" }) } diff --git a/atomic_defi_design/Dex/Constants/DexTypo.qml b/atomic_defi_design/Dex/Constants/DexTypo.qml index 8a05b475d7..55f4e4c55e 100644 --- a/atomic_defi_design/Dex/Constants/DexTypo.qml +++ b/atomic_defi_design/Dex/Constants/DexTypo.qml @@ -8,7 +8,9 @@ import App 1.0 as App QtObject { id: _font + property real fontDensity: 1.0 + property real languageDensity: { switch (App.API.app.settings_pg.lang) { case "en": @@ -24,6 +26,7 @@ QtObject { } } property string fontFamily: "Ubuntu" + property font head1: Qt.font({ pixelSize: 96 * fontDensity, letterSpacing: -1.5, @@ -66,6 +69,12 @@ QtObject { family: fontFamily, weight: Font.Medium }) + property font head8: Qt.font({ + pixelSize: 16 * fontDensity, + letterSpacing: 0.15, + family: fontFamily, + weight: Font.Medium + }) property font subtitle1: Qt.font({ pixelSize: 16 * fontDensity, letterSpacing: 0.15, @@ -90,6 +99,25 @@ QtObject { family: fontFamily, weight: Font.Normal }) + property font body3: Qt.font({ + pixelSize: 12 * fontDensity, + letterSpacing: 0.25, + family: fontFamily, + weight: Font.Normal + }) + property font body4: Qt.font({ + pixelSize: 11 * fontDensity, + letterSpacing: 0.2, + family: fontFamily, + weight: Font.Normal + }) + property font underline14: Qt.font({ + pixelSize: 14 * fontDensity, + letterSpacing: 0.25, + family: fontFamily, + weight: Font.Normal, + underline: true + }) property font button: Qt.font({ pixelSize: 16 * fontDensity, letterSpacing: 1.25, @@ -109,10 +137,22 @@ QtObject { family: fontFamily, weight: Font.Normal }) + property font subtitle3: Qt.font({ + pixelSize: 16 * fontDensity, + letterSpacing: 0.1, + family: fontFamily, + weight: 500 + }) property font monoSpace: Qt.font({ pixelSize: 14 * fontDensity, letterSpacing: 0, family: "Courier", weight: Font.Normal }) + property font monoSmall: Qt.font({ + pixelSize: 14 * fontDensity, + letterSpacing: 0.4, + family: "Courier", + weight: Font.Normal + }) } diff --git a/atomic_defi_design/Dex/Constants/General.qml b/atomic_defi_design/Dex/Constants/General.qml index 81f13ef72d..f0d737d380 100644 --- a/atomic_defi_design/Dex/Constants/General.qml +++ b/atomic_defi_design/Dex/Constants/General.qml @@ -8,6 +8,9 @@ QtObject { readonly property int height: 800 readonly property int minimumWidth: 1280 readonly property int minimumHeight: 800 + readonly property int max_camo_pw_length: 256 + readonly property int max_std_pw_length: 256 + readonly property int max_pw_length: max_std_pw_length + max_camo_pw_length readonly property double delta_time: 1000/60 readonly property string os_file_prefix: Qt.platform.os == "windows" ? "file:///" : "file://" @@ -17,11 +20,16 @@ QtObject { readonly property string custom_coin_icons_path: os_file_prefix + API.app.settings_pg.get_custom_coins_icons_path() + "/" readonly property string providerIconsPath: image_path + "providers/" - function coinIcon(ticker) { - if(ticker === "" || ticker === "All" || ticker===undefined) { + function coinIcon(ticker) + { + if (ticker === "" || ticker === "All" || ticker===undefined) + { return "" - } else { - if (['THC-BEP20'].indexOf(ticker) >= 0) { + } + else + { + if (['THC-BEP20'].indexOf(ticker) >= 0) + { return coin_icons_path + ticker.toString().toLowerCase().replace('-', '_') + ".png" } const coin_info = API.app.portfolio_pg.global_cfg_mdl.get_coin_info(ticker) @@ -38,6 +46,80 @@ QtObject { } } + function canSend(ticker, progress=100) + { + if (!API.app.wallet_pg.send_available) return false + if (isZhtlc(ticker) && progress < 100) return false + return true + } + + function isWalletOnly(ticker) + { + return API.app.portfolio_pg.global_cfg_mdl.get_coin_info(ticker).is_wallet_only + } + + function isZhtlc(ticker) + { + const coin_info = API.app.portfolio_pg.global_cfg_mdl.get_coin_info(ticker) + return coin_info.is_zhtlc_family + } + + function isZhtlcReady(ticker) + { + if (!isZhtlc(ticker)) return true + let activation_status = API.app.get_zhtlc_status(ticker) + let progress = zhtlcActivationProgress(activation_status, ticker) + if (progress == 100) return true + return false + } + + function zhtlcActivationProgress(activation_status, coin='ARRR') + { + let progress = 100 + if (!activation_status.hasOwnProperty("result")) return progress + let status = activation_status.result.status + let details = activation_status.result.details + + let block_offset = 0 + if (coin == 'ARRR') block_offset = 1900000 + + // use range from checkpoint block to present + if (status == "Ready") + { + if (details.hasOwnProperty("error")) + console.log("[zhtlcActivationProgress] Error enabling: " + JSON.stringify(details.error)) + } + else if (status == "InProgress") + { + if (details.hasOwnProperty("UpdatingBlocksCache")) + { + let n = details.UpdatingBlocksCache.current_scanned_block - block_offset + let d = details.UpdatingBlocksCache.latest_block - block_offset + progress = 5 + parseInt(n/d*15) + } + else if (details.hasOwnProperty("BuildingWalletDb")) + { + let n = details.BuildingWalletDb.current_scanned_block - block_offset + let d = details.BuildingWalletDb.latest_block - block_offset + progress = 20 + parseInt(n/d*80) + } + else if (details.hasOwnProperty("RequestingBalance")) progress = 98 + else progress = 5 + } + else console.log("[zhtlcActivationProgress] Unexpected status: " + status) + return progress + } + + function getNomicsId(ticker) { + if(ticker === "" || ticker === "All" || ticker===undefined) { + return "" + } else { + const nomics_id = API.app.portfolio_pg.global_cfg_mdl.get_coin_info(ticker).nomics_id + if (nomics_id == 'test-coin') return "" + return nomics_id + } + } + function coinContractAddress(ticker) { var cfg = API.app.trading_pg.get_raw_mm2_coin_cfg(ticker) if (cfg.hasOwnProperty('protocol')) { @@ -102,6 +184,39 @@ QtObject { } } + + function getProtocolText(ticker) { + if(ticker === "" || ticker === "All" || ticker===undefined) { + return "" + } else { + let token_platform = coinPlatform(ticker) + switch(token_platform) { + case "BNB": + return "Binance Smart Chain (BEP20 token)" + case "FTM": + return "Fantom (FTM20 token)" + case "ONE": + return "Harmony (HRC20 token)" + case "ETH": + return "Ethereum (ERC20 token)" + case "KCS": + return "KuCoin (KRC20 token)" + case "MATIC": + return "Polygon (PLG20 token)" + case "AVAX": + return "Avalanche (AVX20 token)" + case "HT": + return "Heco Chain (HCO20 token)" + case "MOVR": + return "Moonriver (MVR20 token)" + case "QTUM": + return "QTUM (QRC20 token)" + default: + return ticker + " (" + token_platform + ")" + } + } + } + function isIDO(ticker) { let IDO_chains = [] return IDO_chains.includes(ticker) @@ -236,6 +351,19 @@ QtObject { return obj } + function getCustomFeeType(ticker_infos) + { + if (["SLP", "ZHTLC", "Moonbeam", "QRC-20"].includes(ticker_infos.type)) return "" + if (!General.isSpecialToken(ticker_infos) && !General.isParentCoin(ticker_infos.ticker) || ["KMD"].includes(ticker_infos.ticker)) + { + return "UTXO" + } + else + { + return "Gas" + } + } + function getFeesDetail(fees) { return [ {"label": qsTr("Taker tx fee: "), "fee": fees.base_transaction_fees, "ticker": fees.base_transaction_fees_ticker}, @@ -246,16 +374,30 @@ QtObject { } function getFeesDetailText(feetype, amount, ticker) { - return qsTr("%1 %2 %3 (%4)" - ).arg( - feetype - ).arg( - formatDouble(amount, 8, false) - ).arg( - ticker - ).arg( - General.getFiatText(amount, ticker, false) - ) + if ([feetype, amount, ticker].includes(undefined)) return "" + let fiat_text = General.getFiatText(amount, ticker, false) + amount = formatDouble(amount, 8, false).toString() + return feetype + " " + amount + " " + ticker + " (" + fiat_text + ")" + } + + function getSimpleFromPlaceholder(selectedTicker, selectedOrder, sell_ticker_balance) { + if (sell_ticker_balance == 0) + { + return qsTr("%1 balance is zero").arg(selectedTicker) + } + if (!isZhtlcReady(selectedTicker)) + { + return qsTr("Activating %1 (%2%)").arg(atomic_qt_utilities.retrieve_main_ticker(selectedTicker)).arg(progress) + } + if (API.app.trading_pg.max_volume == 0) + { + return qsTr("Loading wallet...") + } + if (typeof selectedOrder !== 'undefined') + { + return qsTr("Min: %1").arg(API.app.trading_pg.min_trade_vol) + } + return qsTr("Enter an amount") } function arrayExclude(arr, excl) { @@ -277,18 +419,41 @@ QtObject { return JSON.stringify(j_obj, null, 4) } - function viewTxAtExplorer(ticker, id, add_0x=true) { - if(id !== '') { + function addressTxUri(coin_info) { + if (coin_info.tx_uri == "") return "address/" + return coin_info.address_uri + } + + function getTxUri(coin_info) { + if (coin_info.tx_uri == "") return "tx/" + return coin_info.tx_uri + } + + function getTxExplorerURL(ticker, txid, add_0x=true) { + if(txid !== '') { const coin_info = API.app.portfolio_pg.global_cfg_mdl.get_coin_info(ticker) - const id_prefix = (add_0x && coin_info.is_erc_family) ? '0x' : '' - Qt.openUrlExternally(coin_info.explorer_url + coin_info.tx_uri + id_prefix + id) + const txid_prefix = (add_0x && coin_info.is_erc_family) ? '0x' : '' + return coin_info.explorer_url + getTxUri(coin_info) + txid_prefix + txid } } - function viewAddressAtExplorer(ticker, address) { + function getAddressExplorerURL(ticker, address) { if(address !== '') { const coin_info = API.app.portfolio_pg.global_cfg_mdl.get_coin_info(ticker) - Qt.openUrlExternally(coin_info.explorer_url + coin_info.address_uri + address) + return coin_info.explorer_url + addressTxUri(coin_info) + address + } + return "" + } + + function viewTxAtExplorer(ticker, txid, add_0x=true) { + if(txid !== '') { + Qt.openUrlExternally(getTxExplorerURL(ticker, txid, add_0x)) + } + } + + function viewAddressAtExplorer(ticker, address) { + if(address !== '') { + Qt.openUrlExternally(getAddressExplorerURL(ticker, address)) } } @@ -330,10 +495,10 @@ QtObject { return (num / si[i].value).toFixed(digits).replace(rx, "$1") + si[i].symbol } - function formatFiat(received, amount, fiat) { + function formatFiat(received, amount, fiat, precision=2) { return diffPrefix(received) + (fiat === API.app.settings_pg.current_fiat ? API.app.settings_pg.current_fiat_sign : API.app.settings_pg.current_currency_sign) - + " " + nFormatter(parseFloat(amount), 2) + + " " + (amount < 1E5 ? formatDouble(parseFloat(amount), precision, true) : nFormatter(parseFloat(amount), 2)) } function formatPercent(value, show_prefix=true) { @@ -344,7 +509,7 @@ QtObject { value *= -1 } - return (show_prefix ? prefix : '') + value + ' %' + return (show_prefix ? prefix : '') + parseFloat(value).toFixed(3) + ' %' } readonly property int amountPrecision: 8 @@ -372,8 +537,16 @@ QtObject { return trail_zeros ? full_double : full_double.replace(/\.?0+$/,"") } - function formatCrypto(received, amount, ticker, fiat_amount, fiat) { - return diffPrefix(received) + ticker + " " + formatDouble(amount) + (fiat_amount ? " (" + formatFiat("", fiat_amount, fiat) + ")" : "") + function getComparisonScale(value) { + return Math.min(Math.pow(10, getDigitCount(parseFloat(value))), 1000000000) + } + + function limitDigits(value) { + return parseFloat(formatDouble(value, 2)) + } + + function formatCrypto(received, amount, ticker, fiat_amount, fiat, precision, trail_zeros) { + return diffPrefix(received) + ticker + " " + formatDouble(amount, precision, trail_zeros) + (fiat_amount ? " (" + formatFiat("", fiat_amount, fiat) + ")" : "") } function formatFullCrypto(received, amount, ticker, fiat_amount, fiat, use_full_ticker) { @@ -398,18 +571,15 @@ QtObject { } function getMinTradeAmount() { - /*if (API.app.trading_pg.market_mode == MarketMode.Buy) { - return API.app.trading_pg.orderbook.rel_min_taker_vol - }*/ - return API.app.trading_pg.min_trade_vol + return formatDouble(API.app.trading_pg.min_trade_vol, 8, false).toString() } function getReversedMinTradeAmount() { - if (API.app.trading_pg.market_mode == MarketMode.Buy) { - return API.app.trading_pg.min_trade_vol - } - return API.app.trading_pg.orderbook.rel_min_taker_vol + if (API.app.trading_pg.market_mode == MarketMode.Buy) { + return getMinTradeAmount() } + return formatDouble(API.app.trading_pg.orderbook.rel_min_taker_vol, 8, false).toString() + } function hasEnoughFunds(sell, base, rel, price, volume) { if(sell) { @@ -436,40 +606,78 @@ QtObject { return exists(v) && v !== "" } - function isParentCoinNeeded(ticker, type) { - for(const c of API.app.portfolio_pg.get_all_enabled_coins()) - if(c.type === type && c.ticker !== ticker) return true - + function isParentCoinNeeded(ticker, coin_type) + { + let enabled_coins = API.app.portfolio_pg.get_all_enabled_coins() + for (const coin of enabled_coins) + { + let c_info = API.app.portfolio_pg.global_cfg_mdl.get_coin_info(coin) + if(c_info.type === coin_type && c_info.ticker !== ticker) return true + } return false } property Timer prevent_coin_disabling: Timer { interval: 5000 } function canDisable(ticker) { - if(prevent_coin_disabling.running) - return false - - if(ticker === atomic_app_primary_coin || ticker === atomic_app_secondary_coin) return false - else if(ticker === "ETH") return !General.isParentCoinNeeded("ETH", "ERC-20") - else if(ticker === "QTUM") return !General.isParentCoinNeeded("QTUM", "QRC-20") + 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 === "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") + if (ticker === "ONE") return !General.isParentCoinNeeded("ONE", "HRC-20") + if (ticker === "QTUM") return !General.isParentCoinNeeded("QTUM", "QRC-20") + if (ticker === "KCS") return !General.isParentCoinNeeded("KCS", "KRC-20") + if (ticker === "HT") return !General.isParentCoinNeeded("HT", "HecoChain") + if (ticker === "BCH") return !General.isParentCoinNeeded("BCH", "SLP") + if (ticker === "UBQ") return !General.isParentCoinNeeded("UBQ", "Ubiq") + if (ticker === "MOVR") return !General.isParentCoinNeeded("MOVR", "Moonriver") + if (ticker === "GLMR") return !General.isParentCoinNeeded("GLMR", "Moonbeam") + if (General.isZhtlc(ticker)) + { + let progress = General.zhtlcActivationProgress(API.app.wallet_pg.ticker_infos.activation_status, ticker) + if (progress != 100) return false + } return true } - function tokenUnitName(type) { - return type === "ERC-20" ? "Gwei" : "Satoshi" + function tokenUnitName(type) + { + return type === "QRC-20" ? "Satoshi" : "Gwei" + } + + function isSpecialToken(current_ticker_infos) + { + if (current_ticker_infos.hasOwnProperty("has_parent_fees_ticker")) + return current_ticker_infos.has_parent_fees_ticker + return false + } + + function isERC20(current_ticker_infos) { + return current_ticker_infos.type === "ERC-20" || current_ticker_infos.type === "BEP-20" || current_ticker_infos.type == "Matic" } function isParentCoin(ticker) { - return ticker === "KMD" || ticker === "ETH" || ticker === "QTUM" + return ["KMD", "ETH", "MATIC", "AVAX", "FTM", "QTUM", "BNB", "ONE", "KCS"].includes(ticker) } function isTokenType(type) { - return type === "ERC-20" || type === "QRC-20" + return ["ERC-20", "QRC-20", "PLG-20", "AVX-20", "FTM-20"].includes(type) + } + + function getFeesTicker(coin_info) { + if (coin_info.has_parent_fees_ticker) + return coin_info.fees_ticker } function getParentCoin(type) { if(type === "ERC-20") return "ETH" + else if(type === "PLG-20") return "MATIC" + else if(type === "AVX-20") return "AVAX" + else if(type === "FTM-20") return "FTM" else if(type === "QRC-20") return "QTUM" else if(type === "Smart Chain") return "KMD" return "?" @@ -503,6 +711,15 @@ QtObject { return tx_fee + "\n" + trading_fee +"
"+minimum_amount } + function is_swap_safe(checkbox) + { + if (checkbox.checked == true || checkbox.visible == false) + { + return (!API.app.trading_pg.buy_sell_rpc_busy && API.app.trading_pg.last_trading_error == TradingError.None) + } + return false + } + function validateWallet(wallet_name) { if (wallet_name.length >= 25) return "Wallet name must 25 chars or less" return checkIfWalletExists(wallet_name) @@ -569,7 +786,8 @@ QtObject { +")") } - function checkIfWalletExists(name) { + function checkIfWalletExists(name) + { if(API.app.wallet_mgr.get_wallets().indexOf(name) !== -1) return qsTr("Wallet %1 already exists", "WALLETNAME").arg(name) return "" @@ -579,6 +797,10 @@ QtObject { switch(error) { case TradingError.None: return "" + case TradingError.LeftZhtlcChainNotEnabled: + return qsTr("Please wait for %1 to fully activate").arg(left_ticker) + case TradingError.RightZhtlcChainNotEnabled: + return qsTr("Please wait for %1 to fully activate").arg(right_ticker) case TradingError.TotalFeesNotEnoughFunds: return qsTr("%1 balance is lower than the fees amount: %2 %3").arg(fee_info.error_fees.coin).arg(fee_info.error_fees.required_balance).arg(fee_info.error_fees.coin) case TradingError.BalanceIsLessThanTheMinimalTradingAmount: @@ -604,6 +826,11 @@ QtObject { } } + readonly property var zcash_params_filesize: ({ + "sapling-output.params": 3592860, + "sapling-spend.params": 47958396 + }) + readonly property var supported_pairs: ({ "1INCH/BTC": "BINANCE:1INCHBTC", "1INCH/ETH": "HUOBI:1INCHETH", @@ -633,7 +860,8 @@ QtObject { "ADA/BRZ": "BINANCE:ADABRL", "ADA/CADC": "EIGHTCAP:ADACAD", "ADA/BNB": "BINANCE:ADABNB", - "ADA/BCH": "HITBTC:ADABCH", + "ADA/BCH": "COINEX:ADABCH", + "ADA/KCS": "KUCOIN:ADAKCS", "ADX/BTC": "BINANCE:ADXBTC", "ADX/ETH": "BINANCE:ADXETH", "ADX/USDT": "BINANCE:ADXUSD", @@ -657,6 +885,7 @@ QtObject { "AAVE/PAX": "BINANCE:AAVEUSD", "AAVE/EURS": "KRAKEN:AAVEEUR", "AAVE/JEUR": "KRAKEN:AAVEEUR", + "AAVE/KCS": "KUCOIN:AAVEKCS", "AGIX/BTC": "BINANCE:AGIXBTC", "AGIX/ETH": "KUCOIN:AGIXETH", "AGIX/USDT": "BINANCE:AGIXUSD", @@ -694,6 +923,22 @@ QtObject { "ANT/BNB": "BINANCE:ANTBNB", "ANT/EURS": "KRAKEN:ANTEUR", "ANT/JEUR": "KRAKEN:ANTEUR", + "APE/BTC": "BINANCE:APEBTC", + "APE/ETH": "BINANCE:APEETH", + "APE/USDT": "FTX:APEUSD", + "APE/BUSD": "FTX:APEUSD", + "APE/USDC": "FTX:APEUSD", + "APE/TUSD": "FTX:APEUSD", + "APE/HUSD": "FTX:APEUSD", + "APE/UST": "FTX:APEUSD", + "APE/DAI": "FTX:APEUSD", + "APE/PAX": "FTX:APEUSD", + "APE/EURS": "COINBASE:APEEUR", + "APE/JEUR": "COINBASE:APEEUR", + "APE/JGBP": "BINANCE:APEGBP", + "APE/TRYB": "BINANCE:APETRY", + "APE/BRZ": "MERCADO:APEBRL", + "APE/BNB": "BINANCE:APEBNB", "ARPA/BTC": "BINANCE:ARPABTC", "ARPA/BNB": "BINANCE:ARPABNB", "ARPA/HT": "HUOBI:ARPAHT", @@ -729,7 +974,10 @@ QtObject { "ATOM/EURS": "KRAKEN:ATOMEUR", "ATOM/JEUR": "KRAKEN:ATOMEUR", "ATOM/JGBP": "KRAKEN:ATOMGBP", + "ATOM/TRYB": "BINANCE:ATOMTRY", + "ATOM/BRZ": "BINANCE:ATOMBRL", "ATOM/BCH": "HITBTC:ATOMBCH", + "ATOM/KCS": "KUCOIN:ATOMKCS", "AVA/BTC": "BINANCE:AVABTC", "AVA/ETH": "KUCOIN:AVAETH", "AVA/USDT": "BINANCE:AVAUSD", @@ -757,6 +1005,7 @@ QtObject { "AVAX/BIDR": "BINANCE:AVAXBIDR", "AVAX/BRZ": "BINANCE:AVAXBRL", "AVAX/TRYB": "BINANCE:AVAXTRY", + "AVAX/BCH": "COINEX:AVAXBCH", "AXS/BTC": "BINANCE:AXSBTC", "AXS/ETH": "HUOBI:AXSETH", "AXS/USDT": "BINANCE:AXSUSD", @@ -772,6 +1021,7 @@ QtObject { "AXS/JEUR": "KRAKEN:AXSEUR", "AXS/BRZ": "BINANCE:AXSBRL", "AXS/BIDR": "BINANCE:AXSBIDR", + "AXS/TRYB": "BINANCE:AXSTRY", "BAL/BTC": "BINANCE:BALBTC", "BAL/ETH": "HUOBI:BALETH", "BAL/USDT": "BINANCE:BALUSD", @@ -799,7 +1049,6 @@ QtObject { "BAND/JEUR": "COINBASE:BANDEUR", "BAT/BTC": "BINANCE:BATBTC", "BAT/ETH": "BINANCE:BATETH", - "BAT/BNB": "BINANCE:BATBNB", "BAT/USDT": "BINANCE:BATUSD", "BAT/BUSD": "BINANCE:BATUSD", "BAT/USDC": "BINANCE:BATUSD", @@ -810,6 +1059,8 @@ QtObject { "BAT/PAX": "BINANCE:BATUSD", "BAT/EURS": "KRAKEN:BATEUR", "BAT/JEUR": "KRAKEN:BATEUR", + "BAT/JPYC": "KRAKEN:BATJPY", + "BAT/BRZ": "MERCADO:BATBRL", "BEST/BTC": "BITPANDAPRO:BESTBTC", "BEST/USDT": "HITBTC:BESTUSD", "BEST/BUSD": "HITBTC:BESTUSD", @@ -839,6 +1090,7 @@ QtObject { "BCH/JPYC": "KRAKEN:BCHJPY", "BCH/CADC": "EIGHTCAP:BCHCAD", "BCH/HT": "HUOBI:BCHHT", + "BCH/KCS": "KUCOIN:BCHKCS", "BIDR/USDT": "BINANCE:USDTBIDR", "BIDR/BUSD": "BINANCE:USDTBIDR", "BIDR/USDC": "BINANCE:USDTBIDR", @@ -873,6 +1125,7 @@ QtObject { "BNB/BIDR": "BINANCE:BNBBIDR", "BNB/BRZ": "BINANCE:BNBBRL", "BNB/CADC": "EIGHTCAP:BNBCAD", + "BNB/KCS": "KUCOIN:BNBKCS", "BNT/BTC": "BINANCE:BNTBTC", "BNT/ETH": "BINANCE:BNTETH", "BNT/USDT": "BINANCE:BNTUSD", @@ -1032,6 +1285,7 @@ QtObject { "CHZ/EURS": "BINANCE:CHZEUR", "CHZ/JEUR": "BINANCE:CHZEUR", "CHZ/JGBP": "COINBASE:CHZGBP", + "CHZ/TRYB": "BINANCE:CHZTRY", "CHZ/BRZ": "BINANCE:CHZBRL", "COMP/BTC": "BINANCE:COMPBTC", "COMP/ETH": "KRAKEN:COMPETH", @@ -1108,11 +1362,8 @@ QtObject { "DASH/JEUR": "KRAKEN:DASHEUR", "DASH/JGBP": "EIGHTCAP:DSHGBP", "DASH/CADC": "EIGHTCAP:DSHCAD", - "DASH/TRYB": "BITFINEX:DSHTRY", - "DASH/BIDR": "BITFINEX:DSHIDR", - "DASH/BRZ": "EIGHTCAP:DSHBRL", - "DASH/BCH": "HITBTC:DASHBCH", "DASH/HT": "HUOBI:DASHHT", + "DASH/KCS": "KUCOIN:DASHKCS", "DOGE/BTC": "BINANCE:DOGEBTC", "DOGE/ETH": "HITBTC:DOGEETH", "DOGE/USDT": "BINANCE:DOGEUSD", @@ -1129,6 +1380,8 @@ QtObject { "DOGE/TRYB": "BINANCE:DOGETRY", "DOGE/BIDR": "BINANCE:DOGEBIDR", "DOGE/BRZ": "BINANCE:DOGEBRL", + "DOGE/BCH": "COINEX:DOGEBCH", + "DOGE/KCS": "KUCOIN:DOGEKCS", "DGB/BTC": "BINANCE:DGBBTC", "DGB/ETH": "BITTREX:DGBETH", "DGB/USDT": "BITTREX:DGBUSD", @@ -1139,7 +1392,6 @@ QtObject { "DGB/UST": "BITTREX:DGBUSD", "DGB/DAI": "BITTREX:DGBUSD", "DGB/PAX": "BITTREX:DGBUSD", - "DGB/BNB": "BINANCE:DGBBNB", "DGB/EURS": "BITTREX:DGBEUR", "DGB/JEUR": "BITTREX:DGBEUR", "DIA/BTC": "BINANCE:DIABTC", @@ -1182,8 +1434,17 @@ QtObject { "DOT/BRZ": "BINANCE:DOTBRL", "DOT/CADC": "EIGHTCAP:DOTCAD", "DOT/BNB": "BINANCE:DOTBNB", - "DX/BTC": "KUCOIN:DXBTC", - "DX/ETH": "KUCOIN:DXETH", + "DOT/BCH": "COINEX:DOTBCH", + "DOT/KCS": "KUCOIN:DOTKCS", + "DX/ETH": "SUSHISWAP:DXWETH", + "DX/USDT": "GATEIO:DXUSDT", + "DX/BUSD": "GATEIO:DXUSDT", + "DX/USDC": "GATEIO:DXUSDT", + "DX/TUSD": "GATEIO:DXUSDT", + "DX/HUSD": "GATEIO:DXUSDT", + "DX/UST": "GATEIO:DXUSDT", + "DX/DAI": "GATEIO:DXUSDT", + "DX/PAX": "GATEIO:DXUSDT", "EGLD/BTC": "BINANCE:EGLDBTC", "EGLD/USDT": "BINANCE:EGLDUSD", "EGLD/BUSD": "BINANCE:EGLDUSD", @@ -1207,6 +1468,7 @@ QtObject { "ELF/DAI": "BINANCE:ELFUSD", "ELF/PAX": "BINANCE:ELFUSD", "EMC2/BTC": "BITTREX:EMC2BTC", + "EMC2/ETH": "BITTREX:EMC2ETH", "EMC2/USDT": "BITTREX:EMC2USD", "EMC2/BUSD": "BITTREX:EMC2USD", "EMC2/USDC": "BITTREX:EMC2USD", @@ -1229,6 +1491,7 @@ QtObject { "ENJ/EURS": "BINANCE:ENJEUR", "ENJ/JEUR": "BINANCE:ENJEUR", "ENJ/JGBP": "BINANCE:ENJGBP", + "ENJ/TRYB": "BINANCE:ENJTRY", "ENJ/BRZ": "BINANCE:ENJBRL", "EOS/BTC": "BINANCE:EOSBTC", "EOS/ETH": "BINANCE:EOSETH", @@ -1249,6 +1512,7 @@ QtObject { "EOS/BIDR": "BITFINEX:EOSIDR", "EOS/JPYC": "BITFINEX:EOSJPY", "EOS/CADC": "EIGHTCAP:EOSCAD", + "EOS/KCS": "KUCOIN:EOSKCS", "ETC/BTC": "BINANCE:ETCBTC", "ETC/ETH": "BINANCE:ETCETH", "ETC/USDT": "BINANCE:ETCUSD", @@ -1278,7 +1542,7 @@ QtObject { "ETH/JGBP": "COINBASE:ETHGBP", "ETH/JCHF": "KRAKEN:ETHCHF", "ETH/TRYB": "BINANCE:ETHTRY", - "ETH/BIDR": "BITFINEX:ETHIDR", + "ETH/BIDR": "BINANCE:ETHBIDR", "ETH/BRZ": "BINANCE:ETHBRL", "ETH/JPYC": "BITFLYER:ETHJPY", "ETH/CADC": "KRAKEN:ETHCAD", @@ -1345,16 +1609,17 @@ QtObject { "FIL/BNB": "BINANCE:FILBNB", "FIL/EURS": "COINBASE:FILEUR", "FIL/JEUR": "COINBASE:FILEUR", + "FIL/TRYB": "BINANCE:FILTRY", "FIRO/BTC": "BINANCE:FIROBTC", "FIRO/ETH": "HUOBI:FIROETH", - "FIRO/USDT": "BITTREX:FIROUSD", - "FIRO/BUSD": "BITTREX:FIROUSD", - "FIRO/USDC": "BITTREX:FIROUSD", - "FIRO/TUSD": "BITTREX:FIROUSD", - "FIRO/HUSD": "BITTREX:FIROUSD", - "FIRO/UST": "BITTREX:FIROUSD", - "FIRO/DAI": "BITTREX:FIROUSD", - "FIRO/PAX": "BITTREX:FIROUSD", + "FIRO/USDT": "BINANCE:FIROUSD", + "FIRO/BUSD": "BINANCE:FIROUSD", + "FIRO/USDC": "BINANCE:FIROUSD", + "FIRO/TUSD": "BINANCE:FIROUSD", + "FIRO/HUSD": "BINANCE:FIROUSD", + "FIRO/UST": "BINANCE:FIROUSD", + "FIRO/DAI": "BINANCE:FIROUSD", + "FIRO/PAX": "BINANCE:FIROUSD", "FLOW/BTC": "BINANCE:FLOWBTC", "FLOW/ETH": "KRAKEN:FLOWETH", "FLOW/USDT": "BINANCE:FLOWUSD", @@ -1392,13 +1657,17 @@ QtObject { "FTM/USDT": "BINANCE:FTMUSD", "FTM/BUSD": "BINANCE:FTMUSD", "FTM/USDC": "BINANCE:FTMUSD", - "FTM/FTM": "BINANCE:FTMUSD", + "FTM/TUSD": "BINANCE:FTMUSD", "FTM/HUSD": "BINANCE:FTMUSD", "FTM/UST": "BINANCE:FTMUSD", "FTM/DAI": "BINANCE:FTMUSD", "FTM/PAX": "BINANCE:FTMUSD", + "FTM/EURS": "BITSTAMP:FTMEUR", + "FTM/JEUR": "BITSTAMP:FTMEUR", "FTM/BNB": "BINANCE:FTMBNB", "FTM/BIDR": "BINANCE:FTMBIDR", + "FTM/BRZ": "BINANCE:FTMBRL", + "FTM/TRYB": "BINANCE:FTMTRY", "FUN/BTC": "BINANCE:FUNBTC", "FUN/ETH": "BINANCE:FUNETH", "FUN/USDT": "BINANCE:FUNUSD", @@ -1409,6 +1678,7 @@ QtObject { "FUN/UST": "BINANCE:FUNUSD", "FUN/DAI": "BINANCE:FUNUSD", "FUN/PAX": "BINANCE:FUNUSD", + "FUN/BNB": "BINANCE:FUNBNB", "GALA/BTC": "BINANCE:GALABTC", "GALA/ETH": "BINANCE:GALAETH", "GALA/USDT": "BINANCE:GALAUSD", @@ -1433,6 +1703,34 @@ QtObject { "GLEEC/UST": "BITTREX:GLEECUSD", "GLEEC/DAI": "BITTREX:GLEECUSD", "GLEEC/PAX": "BITTREX:GLEECUSD", + "GLMR/BTC": "BINANCE:GLMRBTC", + "GLMR/USDT": "BINANCE:GLMRUSD", + "GLMR/BUSD": "BINANCE:GLMRUSD", + "GLMR/USDC": "BINANCE:GLMRUSD", + "GLMR/TUSD": "BINANCE:GLMRUSD", + "GLMR/HUSD": "BINANCE:GLMRUSD", + "GLMR/UST": "BINANCE:GLMRUSD", + "GLMR/DAI": "BINANCE:GLMRUSD", + "GLMR/PAX": "BINANCE:GLMRUSD", + "GLMR/EURS": "KRAKEN:GLMREUR", + "GLMR/JEUR": "KRAKEN:GLMREUR", + "GLMR/BNB": "BINANCE:GLMRBNB", + "GMT/BTC": "BINANCE:GMTBTC", + "GMT/ETH": "BINANCE:GMTETH", + "GMT/USDT": "BINANCE:GMTUSD", + "GMT/BUSD": "BINANCE:GMTUSD", + "GMT/USDC": "BINANCE:GMTUSD", + "GMT/TUSD": "BINANCE:GMTUSD", + "GMT/HUSD": "BINANCE:GMTUSD", + "GMT/UST": "BINANCE:GMTUSD", + "GMT/DAI": "BINANCE:GMTUSD", + "GMT/PAX": "BINANCE:GMTUSD", + "GMT/EURS": "BINANCE:GMTEUR", + "GMT/JEUR": "BINANCE:GMTEUR", + "GMT/JGBP": "BINANCE:GMTGBP", + "GMT/TRYB": "BINANCE:GMTTRY", + "GMT/BRZ": "BINANCE:GMTBRL", + "GMT/BNB": "BINANCE:GMTBNB", "GNO/BTC": "BITTREX:GNOBTC", "GNO/ETH": "KRAKEN:GNOETH", "GNO/USDT": "KRAKEN:GNOUSD", @@ -1469,8 +1767,28 @@ QtObject { "GRT/JEUR": "COINBASE:GRTEUR", "GRT/TRYB": "BINANCE:GRTTRY", "GRT/BRZ": "MERCADO:GRTBRL", + "GRT/KCS": "KUCOIN:GRTKCS", + "GST/USDT": "COINBASE:GSTUSD", + "GST/BUSD": "COINBASE:GSTUSD", + "GST/USDC": "COINBASE:GSTUSD", + "GST/TUSD": "COINBASE:GSTUSD", + "GST/HUSD": "COINBASE:GSTUSD", + "GST/UST": "COINBASE:GSTUSD", + "GST/DAI": "COINBASE:GSTUSD", + "GST/PAX": "COINBASE:GSTUSD", + "GST/EURS": "KRAKEN:GSTEUR", + "GST/JEUR": "KRAKEN:GSTEUR", + "GST/TRYB": "FTX:GSTTRY", "HEX/BTC": "HITBTC:HEXBTC", - "HEX/USDC": "UNISWAP:HEXUSDC", + "HEX/ETH": "UNISWAP:HEXWETH", + "HEX/USDT": "POLONIEX:HEXUSDT", + "HEX/BUSD": "POLONIEX:HEXUSDT", + "HEX/USDC": "POLONIEX:HEXUSDT", + "HEX/TUSD": "POLONIEX:HEXUSDT", + "HEX/HUSD": "POLONIEX:HEXUSDT", + "HEX/UST": "POLONIEX:HEXUSDT", + "HEX/DAI": "POLONIEX:HEXUSDT", + "HEX/PAX": "POLONIEX:HEXUSDT", "HOT/BTC": "HITBTC:HOTBTC", "HOT/ETH": "BINANCE:HOTETH", "HOT/USDT": "HITBTC:HOTUSD", @@ -1484,6 +1802,7 @@ QtObject { "HOT/BNB": "BINANCE:HOTBNB", "HOT/EURS": "BINANCE:HOTEUR", "HOT/JEUR": "BINANCE:HOTEUR", + "HOT/TRYB": "BINANCE:HOTTRY", "HT/BTC": "HUOBI:HTBTC", "HT/ETH": "HUOBI:HTETH", "HT/USDT": "FTX:HTUSD", @@ -1504,6 +1823,9 @@ QtObject { "INJ/UST": "BINANCE:INJUSD", "INJ/DAI": "BINANCE:INJUSD", "INJ/PAX": "BINANCE:INJUSD", + "INJ/EURS": "KRAKEN:INJEUR", + "INJ/JEUR": "KRAKEN:INJEUR", + "INJ/TRYB": "BINANCE:INJTRY", "INJ/BNB": "BINANCE:INJBNB", "INK/BTC": "HITBTC:INKBTC", "INK/ETH": "HITBTC:INKETH", @@ -1567,6 +1889,16 @@ QtObject { "JPYC/BRZ": "FX_IDC:JPYBRL", "JPYC/TRYB": "FX_IDC:JPYTRY", "JRT/ETH": "UNISWAP:JRTWETH", + "KCS/BTC": "KUCOIN:KCSBTC", + "KCS/ETH": "KUCOIN:KCSETH", + "KCS/USDT": "KUCOIN:KCSUSDT", + "KCS/BUSD": "KUCOIN:KCSUSDT", + "KCS/USDC": "KUCOIN:KCSUSDT", + "KCS/TUSD": "KUCOIN:KCSUSDT", + "KCS/HUSD": "KUCOIN:KCSUSDT", + "KCS/UST": "KUCOIN:KCSUSDT", + "KCS/DAI": "KUCOIN:KCSUSDT", + "KCS/PAX": "KUCOIN:KCSUSDT", "KMD/BTC": "BINANCE:KMDBTC", "KMD/USDT": "BINANCE:KMDUSD", "KMD/BUSD": "BINANCE:KMDUSD", @@ -1576,8 +1908,6 @@ QtObject { "KMD/UST": "BINANCE:KMDUSD", "KMD/DAI": "BINANCE:KMDUSD", "KMD/PAX": "BINANCE:KMDUSD", - "KMD/TRYB": "BITTREX:KMDTRY", - "KMD/BIDR": "BITTREX:KMDIDR", "KNC/BTC": "BINANCE:KNCBTC", "KNC/ETH": "BINANCE:KNCETH", "KNC/USDT": "COINBASE:KNCUSD", @@ -1651,6 +1981,7 @@ QtObject { "LINK/JGBP": "COINBASE:LINKGBP", "LINK/TRYB": "BINANCE:LINKTRY", "LINK/BRZ": "BINANCE:LINKBRL", + "LINK/KCS": "KUCOIN:LINKKCS", "LRC/BTC": "BINANCE:LRCBTC", "LRC/ETH": "BINANCE:LRCETH", "LRC/USDT": "BINANCE:LRCUSD", @@ -1661,6 +1992,7 @@ QtObject { "LRC/UST": "BINANCE:LRCUSD", "LRC/DAI": "BINANCE:LRCUSD", "LRC/PAX": "BINANCE:LRCUSD", + "LRC/TRYB": "BINANCE:LRCTRY", "LTC/BTC": "BINANCE:LTCBTC", "LTC/ETH": "BINANCE:LTCETH", "LTC/USDT": "COINBASE:LTCUSD", @@ -1675,13 +2007,12 @@ QtObject { "LTC/EURS": "COINBASE:LTCEUR", "LTC/JEUR": "COINBASE:LTCEUR", "LTC/JGBP": "COINBASE:LTCGBP", - "LTC/TRYB": "BITFINEX:LTCTRY", - "LTC/BIDR": "BITFINEX:LTCIDR", "LTC/BRZ": "MERCADO:LTCBRL", "LTC/JPYC": "KRAKEN:LTCJPY", "LTC/CADC": "EIGHTCAP:LTCCAD", - "LTC/BCH": "HITBTC:LTCBCH", + "LTC/BCH": "COINEX:LTCBCH", "LTC/HT": "HUOBI:LTCHT", + "LTC/KCS": "KUCOIN:LTCKCS", "LUNA/BTC": "BINANCE:LUNABTC", "LUNA/ETH": "KUCOIN:LUNAETH", "LUNA/USDT": "BINANCE:LUNAUSD", @@ -1694,8 +2025,11 @@ QtObject { "LUNA/PAX": "BINANCE:LUNAUSD", "LUNA/EURS": "BINANCE:LUNAEUR", "LUNA/JEUR": "BINANCE:LUNAEUR", + "LUNA/TRYB": "BINANCE:LUNATRY", "LUNA/BNB": "BINANCE:LUNABNB", "LUNA/HT": "HUOBI:LUNAHT", + "LUNA/BCH": "COINEX:LUNABCH", + "LUNA/KCS": "KUCOIN:LUNAKCS", "MANA/BTC": "BINANCE:MANABTC", "MANA/ETH": "BINANCE:MANAETH", "MANA/USDT": "BINANCE:MANAUSD", @@ -1708,6 +2042,9 @@ QtObject { "MANA/PAX": "BINANCE:MANAUSD", "MANA/EURS": "KRAKEN:MANAEUR", "MANA/JEUR": "KRAKEN:MANAEUR", + "MANA/TRYB": "BINANCE:MANATRY", + "MANA/BRZ": "BINANCE:MANABRL", + "MANA/BNB": "BINANCE:MANABNB", "MATIC/BTC": "BINANCE:MATICBTC", "MATIC/ETH": "HUOBI:MATICETH", "MATIC/USDT": "BINANCE:MATICUSD", @@ -1739,6 +2076,7 @@ QtObject { "MIR/EURS": "COINBASE:MIREUR", "MIR/JEUR": "COINBASE:MIREUR", "MIR/JGBP": "COINBASE:MIRGBP", + "MIR/KCS": "KUCOIN:MIRKCS", "MKR/BTC": "BINANCE:MKRBTC", "MKR/ETH": "BITFINEX:MKRETH", "MKR/BNB": "BINANCE:MKRBNB", @@ -1764,6 +2102,18 @@ QtObject { "MONA/DAI": "BITTREX:MONAUSD", "MONA/PAX": "BITTREX:MONAUSD", "MONA/JPYC": "BITFLYER:MONAJPY", + "MOVR/BTC": "BINANCE:MOVRBTC", + "MOVR/ETH": "KUCOIN:MOVRETH", + "MOVR/USDT": "KRAKEN:MOVRUSD", + "MOVR/BUSD": "KRAKEN:MOVRUSD", + "MOVR/USDC": "KRAKEN:MOVRUSD", + "MOVR/TUSD": "KRAKEN:MOVRUSD", + "MOVR/HUSD": "KRAKEN:MOVRUSD", + "MOVR/UST": "KRAKEN:MOVRUSD", + "MOVR/DAI": "KRAKEN:MOVRUSD", + "MOVR/PAX": "KRAKEN:MOVRUSD", + "MOVR/EURS": "KRAKEN:MOVREUR", + "MOVR/JEUR": "KRAKEN:MOVREUR", "NAV/BTC": "BINANCE:NAVBTC", "NAV/USDT": "BINANCE:NAVUSD", "NAV/BUSD": "BINANCE:NAVUSD", @@ -1783,6 +2133,7 @@ QtObject { "NEAR/UST": "BINANCE:NEARUSD", "NEAR/DAI": "BINANCE:NEARUSD", "NEAR/PAX": "BINANCE:NEARUSD", + "NEAR/TRYB": "BINANCE:NEARTRY", "NEAR/BNB": "BINANCE:NEARBNB", "NEXO/BTC": "HUOBI:NEXOBTC", "NEXO/ETH": "HUOBI:NEXOETH", @@ -1794,6 +2145,15 @@ QtObject { "NEXO/UST": "BITFINEX:NEXOUSD", "NEXO/DAI": "BITFINEX:NEXOUSD", "NEXO/PAX": "BITFINEX:NEXOUSD", + "NMC/BTC": "COINEX:NMCBTC", + "NMC/USDT": "COINEX:NMCUSDT", + "NMC/BUSD": "COINEX:NMCUSDT", + "NMC/USDC": "COINEX:NMCUSDT", + "NMC/TUSD": "COINEX:NMCUSDT", + "NMC/HUSD": "COINEX:NMCUSDT", + "NMC/UST": "COINEX:NMCUSDT", + "NMC/DAI": "COINEX:NMCUSDT", + "NMC/PAX": "COINEX:NMCUSDT", "NZDS/USDT": "FX:NZDUSD", "NZDS/BUSD": "FX:NZDUSD", "NZDS/USDC": "FX:NZDUSD", @@ -1857,6 +2217,7 @@ QtObject { "ONE/UST": "BINANCE:ONEUSD", "ONE/DAI": "BINANCE:ONEUSD", "ONE/PAX": "BINANCE:ONEUSD", + "ONE/TRYB": "BINANCE:ONETRY", "ONE/BNB": "BINANCE:ONEBNB", "ONE/HT": "HUOBI:ONEHT", "ONT/BTC": "BINANCE:ONTBTC", @@ -2019,7 +2380,17 @@ QtObject { "RSR/PAX": "BINANCE:RSRUSD", "RSR/BNB": "BINANCE:RSRBNB", "RSR/HT": "HUOBI:RSRHT", + "RTM/BTC": "COINEX:RTMBTC", + "RTM/USDT": "COINEX:RTMUSDT", + "RTM/BUSD": "COINEX:RTMUSDT", + "RTM/USDC": "COINEX:RTMUSDT", + "RTM/TUSD": "COINEX:RTMUSDT", + "RTM/HUSD": "COINEX:RTMUSDT", + "RTM/UST": "COINEX:RTMUSDT", + "RTM/DAI": "COINEX:RTMUSDT", + "RTM/PAX": "COINEX:RTMUSDT", "RVN/BTC": "BINANCE:RVNBTC", + "RVN/ETH": "BITTREX:RVNETH", "RVN/USDT": "BINANCE:RVNUSD", "RVN/BUSD": "BINANCE:RVNUSD", "RVN/USDC": "BINANCE:RVNUSD", @@ -2029,7 +2400,6 @@ QtObject { "RVN/DAI": "BINANCE:RVNUSD", "RVN/PAX": "BINANCE:RVNUSD", "RVN/TRYB": "BINANCE:RVNTRY", - "RVN/BNB": "BINANCE:RVNBNB", "RVN/HT": "HUOBI:RVNHT", "SAND/BTC": "BINANCE:SANDBTC", "SAND/ETH": "BINANCE:SANDETH", @@ -2049,6 +2419,20 @@ QtObject { "SAND/BRZ": "BINANCE:SANDBRL", "SAND/BNB": "BINANCE:SANDBNB", "SAND/HT": "HUOBI:SANDHT", + "SHIB/USDT": "FTX:SHIBUSD", + "SHIB/BUSD": "FTX:SHIBUSD", + "SHIB/USDC": "FTX:SHIBUSD", + "SHIB/TUSD": "FTX:SHIBUSD", + "SHIB/HUSD": "FTX:SHIBUSD", + "SHIB/UST": "FTX:SHIBUSD", + "SHIB/DAI": "FTX:SHIBUSD", + "SHIB/PAX": "FTX:SHIBUSD", + "SHIB/EURS": "BINANCE:SHIBEUR", + "SHIB/JEUR": "BINANCE:SHIBEUR", + "SHIB/JGBP": "COINBASE:SHIBGBP", + "SHIB/TRYB": "BINANCE:SHIBTRY", + "SHIB/BRZ": "BINANCE:SHIBBRL", + "SHIB/DOGE": "BINANCE:SHIBDOGE", "SHR/BTC": "KUCOIN:SHRBTC", "SHR/USDT": "BITTREX:SHRUSD", "SHR/BUSD": "BITTREX:SHRUSD", @@ -2111,6 +2495,7 @@ QtObject { "SOL/BRZ": "BINANCE:SOLBRL", "SOL/CADC": "EIGHTCAP:SOLCAD", "SOL/BNB": "BINANCE:SOLBNB", + "SOL/BCH": "COINEX:SOLBCH", "SPC/BTC": "BITTREX:SPCBTC", "SPC/ETH": "HITBTC:SPCETH", "SPC/USDT": "HITBTC:SPCUSDT", @@ -2187,8 +2572,14 @@ QtObject { "TEL/UST": "KUCOIN:TELUSDT", "TEL/DAI": "KUCOIN:TELUSDT", "TEL/PAX": "KUCOIN:TELUSDT", - "TMTG/BTC": "OKEX:TMTGBTC", "TMTG/USDT": "OKEX:TMTGUSDT", + "TMTG/BUSD": "OKEX:TMTGUSDT", + "TMTG/USDC": "OKEX:TMTGUSDT", + "TMTG/TUSD": "OKEX:TMTGUSDT", + "TMTG/HUSD": "OKEX:TMTGUSDT", + "TMTG/UST": "OKEX:TMTGUSDT", + "TMTG/DAI": "OKEX:TMTGUSDT", + "TMTG/PAX": "OKEX:TMTGUSDT", "TRAC/BTC": "KUCOIN:TRACBTC", "TRAC/ETH": "KUCOIN:TRACETH", "TRAC/USDT": "BITTREX:TRACUSD", @@ -2216,6 +2607,7 @@ QtObject { "TRX/TRYB": "BINANCE:TRXTRY", "TRX/CADC": "EIGHTCAP:TRXCAD", "TRX/BCH": "HITBTC:TRXBCH", + "TRX/KCS": "KUCOIN:TRXKCS", "TRYB/USDT": "FX_IDC:TRYUSD", "TRYB/BUSD": "FX_IDC:TRYUSD", "TRYB/USDC": "FX_IDC:TRYUSD", @@ -2259,6 +2651,7 @@ QtObject { "UMA/PAX": "COINBASE:UMAUSD", "UMA/EURS": "COINBASE:UMAEUR", "UMA/JEUR": "COINBASE:UMAEUR", + "UMA/TRYB": "BINANCE:UMATRY", "UNI/BTC": "BINANCE:UNIBTC", "UNI/ETH": "KRAKEN:UNIETH", "UNI/USDT": "COINBASE:UNIUSD", @@ -2274,6 +2667,7 @@ QtObject { "UNI/JEUR": "KRAKEN:UNIEUR", "UNI/JGBP": "EIGHTCAP:UNIGBP", "UNI/CADC": "EIGHTCAP:UNICAD", + "UNI/KCS": "KUCOIN:UNIKCS", "UOS/BTC": "BITFINEX:UOSBTC", "UOS/USDT": "BITFINEX:UOSUSD", "UOS/BUSD": "BITFINEX:UOSUSD", @@ -2312,6 +2706,23 @@ QtObject { "VAL/UST": "BITTREX:VALUSD", "VAL/DAI": "BITTREX:VALUSD", "VAL/PAX": "BITTREX:VALUSD", + "VET/BTC": "BINANCE:VETBTC", + "VET/ETH": "BINANCE:VETETH", + "VET/USDT": "BINANCE:VETUSD", + "VET/BUSD": "BINANCE:VETUSD", + "VET/USDC": "BINANCE:VETUSD", + "VET/TUSD": "BINANCE:VETUSD", + "VET/HUSD": "BINANCE:VETUSD", + "VET/UST": "BINANCE:VETUSD", + "VET/DAI": "BINANCE:VETUSD", + "VET/PAX": "BINANCE:VETUSD", + "VET/EURS": "BINANCE:VETEUR", + "VET/JEUR": "BINANCE:VETEUR", + "VET/JGBP": "BINANCE:VETGBP", + "VET/TRYB": "BINANCE:VETTRY", + "VET/CADC": "EIGHTCAP:VETCAD", + "VET/BNB": "BINANCE:VETBNB", + "VET/KCS": "KUCOIN:VETKCS", "VITE/BTC": "BINANCE:VITEBTC", "VITE/USDT": "BINANCE:VITEUSD", "VITE/BUSD": "BINANCE:VITEUSD", @@ -2330,6 +2741,20 @@ QtObject { "VRA/UST": "BITTREX:VRAUSD", "VRA/DAI": "BITTREX:VRAUSD", "VRA/PAX": "BITTREX:VRAUSD", + "WAVES/BTC": "BINANCE:WAVESBTC", + "WAVES/ETH": "BINANCE:WAVESETH", + "WAVES/USDT": "BINANCE:WAVESUSD", + "WAVES/BUSD": "BINANCE:WAVESUSD", + "WAVES/USDC": "BINANCE:WAVESUSD", + "WAVES/TUSD": "BINANCE:WAVESUSD", + "WAVES/HUSD": "BINANCE:WAVESUSD", + "WAVES/UST": "BINANCE:WAVESUSD", + "WAVES/DAI": "BINANCE:WAVESUSD", + "WAVES/PAX": "BINANCE:WAVESUSD", + "WAVES/EURS": "KRAKEN:WAVESEUR", + "WAVES/JEUR": "KRAKEN:WAVESEUR", + "WAVES/TRYB": "BINANCE:WAVESTRY", + "WAVES/BNB": "BINANCE:WAVESBNB", "WBTC/BTC": "BINANCE:WBTCBTC", "WBTC/ETH": "BINANCE:WBTCETH", "WBTC/USDT": "COINBASE:WBTCUSD", @@ -2348,6 +2773,7 @@ QtObject { "XEC/UST": "BITFINEX:XECUSD", "XEC/DAI": "BITFINEX:XECUSD", "XEC/PAX": "BITFINEX:XECUSD", + "XEC/BCH": "COINEX:XECBCH", "XEP/USDT": "BITTREX:XEPUSDT", "XEP/BUSD": "BITTREX:XEPUSDT", "XEP/USDC": "BITTREX:XEPUSDT", @@ -2373,15 +2799,15 @@ QtObject { "XLM/JPYC": "BITFLYER:XLMJPY", "XLM/CADC": "EIGHTCAP:XLMCAD", "XLM/BCH": "HITBTC:XLMBCH", - "XMY/BTC": "BITTREX:XMYBTC", - "XMY/USDT": "BITTREX:XMYUSD", - "XMY/BUSD": "BITTREX:XMYUSD", - "XMY/USDC": "BITTREX:XMYUSD", - "XMY/TUSD": "BITTREX:XMYUSD", - "XMY/HUSD": "BITTREX:XMYUSD", - "XMY/UST": "BITTREX:XMYUSD", - "XMY/DAI": "BITTREX:XMYUSD", - "XMY/PAX": "BITTREX:XMYUSD", + "XLM/KCS": "KUCOIN:XLMKCS", + "XMY/USDT": "BITTREX:XMYUSDT", + "XMY/BUSD": "BITTREX:XMYUSDT", + "XMY/USDC": "BITTREX:XMYUSDT", + "XMY/TUSD": "BITTREX:XMYUSDT", + "XMY/HUSD": "BITTREX:XMYUSDT", + "XMY/UST": "BITTREX:XMYUSDT", + "XMY/DAI": "BITTREX:XMYUSDT", + "XMY/PAX": "BITTREX:XMYUSDT", "XRP/BTC": "BINANCE:XRPBTC", "XRP/ETH": "BINANCE:XRPETH", "XRP/USDT": "BITSTAMP:XRPUSD", @@ -2402,9 +2828,10 @@ QtObject { "XRP/BRZ": "MERCADO:XRPBRL", "XRP/JPYC": "KRAKEN:XRPJPY", "XRP/CADC": "KRAKEN:XRPCAD", - "XRP/BCH": "HITBTC:XRPBCH", + "XRP/BCH": "COINEX:XRPBCH", "XRP/HT": "HUOBI:XRPHT", "XRP/TRX": "POLONIEX:XRPTRX", + "XRP/KCS": "KUCOIN:XRPKCS", "XSGD/USDT": "FX_IDC:SGDUSD", "XSGD/BUSD": "FX_IDC:SGDUSD", "XSGD/USDC": "FX_IDC:SGDUSD", @@ -2433,7 +2860,9 @@ QtObject { "XTZ/BNB": "BINANCE:XTZBNB", "XTZ/EURS": "KRAKEN:XTZEUR", "XTZ/JEUR": "KRAKEN:XTZEUR", + "XTZ/TRYB": "BINANCE:XTZTRY", "XTZ/TRX": "POLONIEX:XTZTRX", + "XTZ/KCS": "KUCOIN:XTZKCS", "XVS/BTC": "BINANCE:XVSBTC", "XVS/USDT": "BINANCE:XVSUSD", "XVS/BUSD": "BINANCE:XVSUSD", @@ -2481,8 +2910,9 @@ QtObject { "ZEC/BNB": "BINANCE:ZECBNB", "ZEC/EURS": "KRAKEN:ZECEUR", "ZEC/JEUR": "KRAKEN:ZECEUR", - "ZEC/BCH": "HITBTC:ZECBCH", + "ZEC/BCH": "GEMINI:ZECBCH", "ZEC/LTC": "GEMINI:ZECLTC", + "ZEC/KCS": "KUCOIN:ZECKCS", "ZIL/BTC": "BINANCE:ZILBTC", "ZIL/ETH": "BINANCE:ZILETH", "ZIL/USDT": "BINANCE:ZILUSD", @@ -2494,6 +2924,7 @@ QtObject { "ZIL/DAI": "BINANCE:ZILUSD", "ZIL/PAX": "BINANCE:ZILUSD", "ZIL/BIDR": "BINANCE:ZILBIDR", + "ZIL/TRYB": "BINANCE:ZILTRY", "ZIL/BNB": "BINANCE:ZILBNB", "ZRX/BTC": "BINANCE:ZRXBTC", "ZRX/ETH": "BINANCE:ZRXETH", diff --git a/atomic_defi_design/Dex/Constants/Style.qml b/atomic_defi_design/Dex/Constants/Style.qml index 7b0dee74b3..ff2dbd105c 100644 --- a/atomic_defi_design/Dex/Constants/Style.qml +++ b/atomic_defi_design/Dex/Constants/Style.qml @@ -32,15 +32,6 @@ QtObject { readonly property int animationDuration: 125 - readonly property int textSizeVerySmall1: 1 - readonly property int textSizeVerySmall2: 2 - readonly property int textSizeVerySmall3: 3 - readonly property int textSizeVerySmall4: 4 - readonly property int textSizeVerySmall5: 5 - readonly property int textSizeVerySmall6: 6 - readonly property int textSizeVerySmall7: 7 - readonly property int textSizeVerySmall8: 8 - readonly property int textSizeVerySmall9: 9 readonly property int textSizeSmall: 10 readonly property int textSizeSmall1: 11 readonly property int textSizeSmall2: 12 @@ -138,10 +129,6 @@ QtObject { property string colorRectangle: dark_theme ? colorTheme7 : colorTheme7 readonly property string colorInnerBackground: dark_theme ? colorTheme7 : colorTheme7 - readonly property string colorGradient1: dark_theme ? colorTheme9 : colorTheme9 - readonly property string colorGradient2: dark_theme ? colorTheme5 : colorTheme5 - readonly property string colorGradient3: dark_theme ? "#24283D" : "#24283D" - readonly property string colorGradient4: dark_theme ? "#0D0F21" : "#0D0F21" readonly property string colorDropShadowLight: dark_theme ? "#216975a4" : "#21FFFFFF" readonly property string colorDropShadowLight2: dark_theme ? "#606975a4" : "#60FFFFFF" readonly property string colorDropShadowDark: dark_theme ? "#FF050615" : "#BECDE2" @@ -172,58 +159,18 @@ QtObject { readonly property string colorRectangleBorderGradient1: dark_theme ? "#2A2F48" : "#DDDDDD" readonly property string colorRectangleBorderGradient2: dark_theme ? "#0D1021" : "#EFEFEF" - readonly property string colorChartText: dark_theme ? "#405366" : "#B5B9C1" - readonly property string colorChartLegendLine: dark_theme ? "#3F5265" : "#BDC0C8" - readonly property string colorChartGrid: dark_theme ? "#202333" : "#E6E8ED" - readonly property string colorChartLineText: dark_theme ? "#405366" : "#FFFFFF" - - readonly property string colorChartMA1: dark_theme ? "#5BC6FA" : "#5BC6FA" - readonly property string colorChartMA2: dark_theme ? "#F1D17F" : "#F1D17F" - readonly property string colorLineBasic: dark_theme ? "#303344" : "#303344" readonly property string colorText: dark_theme ? Style.colorWhite1 : "#405366" readonly property string colorText2: dark_theme ? "#79808C" : "#3C5368" readonly property string colorTextDisabled: dark_theme ? Style.colorWhite8 : "#B5B9C1" - readonly property var colorButtonDisabled: ({ - "default": Style.colorTheme9, - "primary": Style.colorGreen3, - "danger": Style.colorRed3 - }) - readonly property var colorButtonHovered: ({ - "default": Style.colorTheme6, - "primary": Style.colorGreen, - "danger": Style.colorRed - }) - readonly property var colorButtonEnabled: ({ - "default": Style.colorRectangle, - "primary": Style.colorGreen2, - "danger": Style.colorRed2 - }) - readonly property var colorButtonTextDisabled: ({ - "default": Style.colorWhite8, - "primary": Style.colorWhite13, - "danger": Style.colorWhite13 - }) - readonly property var colorButtonTextHovered: ({ - "default": Style.colorText, - "primary": Style.colorWhite11, - "danger": Style.colorWhite11 - }) - readonly property var colorButtonTextEnabled: ({ - "default": Style.colorText, - "primary": Style.colorWhite11, - "danger": Style.colorWhite11 - }) + readonly property string colorPlaceholderText: Style.colorWhite9 readonly property string colorSelectedText: Style.colorTheme9 readonly property string colorSelection: Style.colorGreen2 readonly property string colorTrendingLine: dark_theme ? Style.colorGreen : "#37a6ef" - readonly property string colorTrendingUnderLine: dark_theme ? Style.colorGradient3 : "#e3f2fd" - - readonly property string modalValueColor: colorWhite4 function getValueColor(v) { v = parseFloat(v) @@ -238,6 +185,7 @@ QtObject { switch (type) { case 'ERC-20': return getCoinColor("ETH") + case 'ZHTLC': return getCoinColor("ARRR") case 'QRC-20': return getCoinColor("QTUM") case 'Smart Chain': return getCoinColor("KMD") case 'WALLET ONLY': return "#4D4D4D" @@ -279,15 +227,18 @@ QtObject { readonly property var colorCoin: ({ "ABY": "#8B0D10", + "ACTN": "#E84142", "ADA": "#214D78", "ADX": "#1B75BC", "ANKR": "#2075E8", + "APE": "#0052F2", "ARPA": "#CCD9E2", "ARRR": "#C7A34C", "ATOM": "#474B6C", "AUR": "#0A6C5E", "AVA": "#5B567F", "AVAX": "#E84142", + "AVN": "#33E0CE", "AXS": "#0055D5", "BAL": "#4D4D4D", "BNB": "#F9D987", @@ -318,11 +269,17 @@ QtObject { "GALA": "#011B36", "GLEEC": "#8C41FF", "GRMS": "#12B690", + "GLM": "#0050E6", "GMS": "#0BFBE2", + "GMT": "#E9CB7B", + "GMX": "#07A9E6", "GRS": "#377E96", "GRT": "#6E54DB", + "GST": "#D7D7D7", "IOTA": "#404040", + "ILNF": "#28873b", "IC": "#72009D", + "JST": "#B41514", "JSTR": "#627EEA", "DOGE": "#C3A634", "ETC": "#328432", @@ -346,6 +303,8 @@ QtObject { "FLUX": "#2B61D1", "FIRO": "#BB2100", "LBC": "#00775C", + "LDO": "#F69988", + "LOOM": "#48BEFF", "LTC": "#BFBBBB", "LUNA": "#FFD83D", "LYNX": "#0071BA", @@ -369,6 +328,7 @@ QtObject { "CRYPTO": "#F58736", "LABS": "#C1F6E1", "LCC": "#068210", + "LNC": "#C3A635", "MESH": "#0098DA", "MGW": "#854F2F", "MONA": "#DEC799", @@ -378,17 +338,21 @@ QtObject { "NZDS": "#1B3044", "RFOX": "#D83331", "BOTS": "#F69B57", + "MC": "#E16428", "MCL": "#EA0000", + "ILNSW": "#28873B", "MM": "#F5B700", "CCL": "#FFE400", "BET": "#F69B57", "JCHF": "#D80027", "JEUR": "#003399", "JGBP": "#C8102E", + "JJPY": "#BC002D", "JRT": "#5EFC84", "SUPERNET": "#F69B57", "REVS": "#F69B57", - "ILN": "#523170", + "EILN": "#1ADEC9", + "ILN": "#814EB1", "VRSC": "#3164D3", "WCN": "#E49F00", "WWCN": "#E49F00", @@ -426,6 +390,7 @@ QtObject { "CEL": "#4055A6", "CELR": "#595959", "CENNZ": "#2E87F1", + "CHTA": "#C3A634", "COMP": "#00DBA3", "CRO": "#243565", "CVC": "#3AB03E", @@ -455,6 +420,7 @@ QtObject { "MKR": "#1BAF9F", "MINDS": "#687DE3", "NEAR": "#595959", + "NENG": "#BFBBBB", "NEXO": "#A3B3D6", "NVC": "#FCF96D", "NYAN": "#008CE7", @@ -462,6 +428,7 @@ QtObject { "OMG": "#595959", "ONE": "#00BEEE", "ONT": "#2692AF", + "PND": "#EBD430", "POWR": "#05BCAA", "PPC": "#46BC60", "PRUX": "#FF8000", @@ -487,6 +454,7 @@ QtObject { "SYS": "#0084C7", "TEL": "#1BD8FF", "TKL": "#536E93", + "TON": "#0088CC", "TRC": "#096432", "TRX": "#F30031", "TSL": "#64B082", @@ -494,11 +462,15 @@ QtObject { "UNO": "#2F87BB", "UST": "#5493F7", "VAL": "#1EEC84", + "VET": "#18C6FF", "VITE": "#007AFF", "VRM": "#586A7A", + "VTC": "#049161", "WSB": "#FEBB84", + "WAVES": "#016BFF", "WBTC": "#CCCCCC", "WHIVE": "#FFCC00", + "WOO": "#595959", "XEC": "#273498", "XEP": "#0277E5", "XLM": "#737373", @@ -512,8 +484,13 @@ QtObject { "YFII": "#FF2A79", "ZET": "#155169", "ZIL": "#42BBB9", + "ZOMBIE": "#72B001", "ZRX": "#302C2C", "UNI": "#FF007A", - "USBL": "#279553" + "VOTE2022": "#7490AA", + "USBL": "#279553", + "RUNES": "#336699", + "SIX": "#ed0909", + "NATURE": "#04cf13" }) } diff --git a/atomic_defi_design/Dex/Dashboard/NewUpdateModal.qml b/atomic_defi_design/Dex/Dashboard/NewUpdateModal.qml deleted file mode 100644 index a79589df4d..0000000000 --- a/atomic_defi_design/Dex/Dashboard/NewUpdateModal.qml +++ /dev/null @@ -1,189 +0,0 @@ -// Qt imports -import QtQml 2.15 //> Component -import QtQuick.Layouts 1.15 //> Layout.fillWidth -import QtQuick.Controls 2.15 //> ProgressBar - -// Project imports -import "../Components" //> MultipageModal -import "../Constants" -import App 1.0 //> API.app.self_update_service - -MultipageModal -{ - id: root - - readonly property var self_update_service: API.app.self_update_service - readonly property string last_release_tag_name: self_update_service.last_release_tag_name - readonly property bool update_needed: self_update_service.update_needed - readonly property bool update_downloading: self_update_service.update_downloading - readonly property real update_download_progress: self_update_service.update_download_progress - readonly property bool update_ready: self_update_service.update_ready - property bool invalid_update_files: self_update_service.invalid_update_files - // Display the good modal section according to current self update service state - function select_index() - { - if (invalid_update_files) - { - invalid_update_files = false - currentIndex = 0 - close() - update_invalid_checksum.open() - } - else if (update_ready) - { - currentIndex = 4 - visible = true - } - else if (update_downloading) - { - currentIndex = 3 - visible = true - } - else if (update_needed) - { - currentIndex = 2 - visible = true - } - else if (currentIndex === 1) - { - currentIndex = 0 - } - else - { - currentIndex = 1 - } - } - - // Fetches latest update info when opening this modal. - onOpened: - { - select_index() - self_update_service.fetch_last_release_info() - } - - onUpdate_neededChanged: select_index() - onUpdate_downloadingChanged: select_index() - onUpdate_readyChanged: select_index() - onInvalid_update_filesChanged: select_index() - - // Section when fetching update - MultipageModalContent - { - titleText: qsTr("Searching new updates...") - titleAlignment: Label.AlignHCenter - - DefaultText - { - horizontalAlignment: Label.AlignHCenter - text: qsTr("Please wait while the application is finding a new update... You can close this modal if you want.") - } - } - - // Section when no new update is found. - MultipageModalContent - { - titleText: qsTr("Already updated") - titleAlignment: Label.AlignHCenter - - - DefaultText - { - horizontalAlignment: Label.AlignHCenter - Layout.fillWidth: true - text: qsTr("%1 is already up-to-date !").arg(API.app_name) - } - footer: - [ - DexAppButton - { - text: qsTr("Close") - Layout.alignment: Qt.AlignHCenter - onClicked: root.visible = false - } - ] - } - - // Second section. Asks user to update its client. - MultipageModalContent - { - titleText: qsTr("New update detected !") - - DefaultText - { - Layout.fillWidth: true - - text: qsTr("Do you want to update %1 from %2 to %3 ?") - .arg(API.app_name).arg(API.current_version).arg(last_release_tag_name) - } - - footer: - [ - PrimaryButton - { - text: qsTr("Download") - - onClicked: self_update_service.download_update() - }, - DefaultButton - { - text: qsTr("Remind me later") - - onClicked: root.visible = false - } - ] - } - - // Download progress bar - MultipageModalContent - { - titleText: qsTr("Download in progress...") - - RowLayout - { - Layout.fillWidth: true - - ProgressBar - { - Layout.fillWidth: true - value: update_download_progress - } - - DefaultText - { - Layout.preferredWidth: 40 - text: "%1 %".arg(Math.round(update_download_progress * 100)) - } - } - } - - // Update download finished... Asks for restart - MultipageModalContent - { - titleText: qsTr("Update downloaded") - - DefaultText - { - text: qsTr("Update has been successfully downloaded. Do you want to restart the application now ?") - } - - footer: - [ - PrimaryButton - { - text: qsTr("Restart now") - - onClicked: - { - self_update_service.perform_update() - root.visible = false - } - }, - DefaultButton - { - text: qsTr("Restart later") - - onClicked: close() - } - ] - } -} diff --git a/atomic_defi_design/Dex/Dashboard/NotificationsModal.qml b/atomic_defi_design/Dex/Dashboard/NotificationsModal.qml index b2fc7f3a94..c6d8fa9e79 100644 --- a/atomic_defi_design/Dex/Dashboard/NotificationsModal.qml +++ b/atomic_defi_design/Dex/Dashboard/NotificationsModal.qml @@ -3,6 +3,7 @@ import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 import Qt.labs.platform 1.0 import Qaterial 1.0 as Qaterial +import ModelHelper 0.1 import Dex.Themes 1.0 as Dex @@ -17,60 +18,26 @@ DexPopup width: 406 height: 526 - property - var default_gradient: Gradient - { - orientation: Qt.Horizontal - GradientStop - { - position: 0.1255 - color: Dex.CurrentTheme.gradientButtonPressedStartColor - } - GradientStop - { - position: 0.933 - color: Dex.CurrentTheme.gradientButtonPressedEndColor - } - } - property - var default_red_gradient: Gradient - { - orientation: Qt.Horizontal - GradientStop - { - position: 0.1255 - color: Dex.CurrentTheme.tradeSellModeSelectorBackgroundColorStart - } - GradientStop - { - position: 0.933 - color: Dex.CurrentTheme.tradeSellModeSelectorBackgroundColorEnd - } - } - property - var notification_map: [ - { - icon: Qaterial.Icons.arrowTopRight, - color: Dex.CurrentTheme.foregroundColor, - gradient: default_red_gradient - }, - { - icon: Qaterial.Icons.arrowBottomRight, - color: Dex.CurrentTheme.foregroundColor, - gradient: default_gradient - }, - { - icon: Qaterial.Icons.messageOutline, - color: DexTheme.foregroundColor, - gradient: default_gradient - }] backgroundColor: Dex.CurrentTheme.floatingBackgroundColor + property var orders: API.app.orders_mdl.orders_proxy_mdl.ModelHelper + + // Notification types. + readonly property string updateSwapStatusNotification: "onUpdateSwapStatus" + readonly property string balanceUpdateStatusNotification: "onBalanceUpdateStatus" + readonly property string enablingZCoinStatusNotification: "onEnablingZCoinStatus" + readonly property string enablingCoinFailedStatusNotification: "onEnablingCoinFailedStatus" + readonly property string disablingCoinFailedStatus: "onDisablingCoinFailedStatus" + readonly property string endpointNonReacheableStatus: "onEndpointNonReacheableStatus" + + readonly property string check_internet_connection_text: qsTr("Please check your internet connection (e.g. VPN service or firewall might block it).") + function reset() { notifications_list = [] root.close() } + enum NotificationKind { Send, @@ -106,70 +73,45 @@ DexPopup root.open() break case "open_wallet_page": - api_wallet_page.ticker = notification.params.ticker - dashboard.switchPage(Dashboard.PageType.Wallet) + API.app.wallet_pg.ticker = notification.params.ticker + app.pageLoader.item.switchPage(Dashboard.PageType.Wallet) break case "open_swaps_page": - dashboard.switchPage(Dashboard.PageType.DEX) - - dashboard.loader.onLoadComplete = () => - { - dashboard.current_component.current_page = dashboard.isSwapDone(notification.params.new_swap_status) ? idx_exchange_history : idx_exchange_orders - } + app.pageLoader.item.switchPage(Dashboard.PageType.DEX) break case "open_log_modal": - showError(notification.title, notification.long_message) + showError(notification.getTitle(), notification.long_message) break default: - console.log("Unknown notification click action", notification.click_action) + console.warn("Unknown notification click action", notification.click_action) break } } - function newNotification(event_name, params, id, title, message, human_date, click_action = "open_notifications", long_message = "") + function newNotification(event_name, params, id, human_date, click_action = "open_notifications", long_message = "") { - - let obj; - if (title.indexOf("You received") !== -1) + let obj = { - obj = { - event_name, - params, - id, - title, - message, - human_date, - click_action, - long_message, - kind: NotificationsModal.NotificationKind.Receive - } + event_name, + params, + id, + human_date, + click_action, + long_message, } - else if (title.indexOf("You sent") !== -1) { - obj = { - event_name, - params, - id, - title, - message, - human_date, - click_action, - long_message, - kind: NotificationsModal.NotificationKind.Send + let notifTitle = getNotificationTitle(obj) + if (notifTitle.indexOf("You received") !== -1) + { + obj.kind = NotificationsModal.NotificationKind.Receive } - } - else - { - obj = { - event_name, - params, - id, - title, - message, - human_date, - click_action, - long_message, - kind: NotificationsModal.NotificationKind.Others + else if (notifTitle.indexOf("You sent") !== -1) + { + obj.kind = NotificationsModal.NotificationKind.Send + } + else + { + obj.kind = NotificationsModal.NotificationKind.Others } } @@ -192,14 +134,14 @@ DexPopup } // Display OS notification - displayMessage(obj.title, obj.message) + if (API.app.settings_pg.notification_enabled) + tray.showMessage(getNotificationTitle(obj), getNotificationMsg(obj)) // Refresh the list if updated an existing one if (updated_existing_one) notifications_list = notifications_list } - function getOrderStatusText(status, short_text = false) { switch (status) @@ -221,10 +163,62 @@ DexPopup } } - // Events + function getNotificationTitle(notification) + { + switch (notification.event_name) + { + case updateSwapStatusNotification: + return notification.params.base_coin + "/" + notification.params.rel_coin + " - " + qsTr("Swap status updated") + case balanceUpdateStatusNotification: + const change = General.formatFullCrypto("", notification.params.amount, notification.params.ticker, "", "", true) + return notification.params.am_i_sender ? qsTr("You sent %1").arg(change) : qsTr("You received %1").arg(change) + case enablingZCoinStatusNotification: + return qsTr(" %1 Enable status", "TICKER").arg(notification.params.coin) + case enablingCoinFailedStatusNotification: + return qsTr("Failed to enable %1", "TICKER").arg(notification.params.coin) + case disablingCoinFailedStatus: + return qsTr("Failed to disable %1", "TICKER").arg(notification.params.coin) + case endpointNonReacheableStatus: + return qsTr("Endpoint not reachable") + } + } + + function getNotificationMsg(notification) + { + switch (notification.event_name) + { + case updateSwapStatusNotification: + return getOrderStatusText(notification.params.old_swap_status) + " " + General.right_arrow_icon + " " + getOrderStatusText(notification.params.new_swap_status) + case balanceUpdateStatusNotification: + return qsTr("Your wallet balance changed") + case enablingZCoinStatusNotification: + return notification.params.msg + case enablingCoinFailedStatusNotification: + return check_internet_connection_text + case disablingCoinFailedStatus: + return "" + case endpointNonReacheableStatus: + return notification.params.base_uri + } + } + + function getNotificationIcon(notification) + { + switch (notification.kind) + { + case NotificationsModal.NotificationKind.Send: + return Qaterial.Icons.arrowTopRight + case NotificationsModal.NotificationKind.Receive: + return Qaterial.Icons.arrowBottomRight + case NotificationsModal.NotificationKind.Others: + return Qaterial.Icons.messageOutline + } + } + function onUpdateSwapStatus(old_swap_status, new_swap_status, swap_uuid, base_coin, rel_coin, human_date) { - newNotification("onUpdateSwapStatus", + newNotification( + updateSwapStatusNotification, { old_swap_status, new_swap_status, @@ -234,30 +228,30 @@ DexPopup human_date }, swap_uuid, - base_coin + "/" + rel_coin + " - " + qsTr("Swap status updated"), - getOrderStatusText(old_swap_status) + " " + General.right_arrow_icon + " " + getOrderStatusText(new_swap_status), human_date, "open_swaps_page") } function onBalanceUpdateStatus(am_i_sender, amount, ticker, human_date, timestamp) { - const change = General.formatFullCrypto("", amount, ticker, "", "", true) + if (!app.segwit_on) { - newNotification("onBalanceUpdateStatus", - { - am_i_sender, - amount, - ticker, + if (amount != 0) + { + newNotification( + balanceUpdateStatusNotification, + { + am_i_sender, + amount, + ticker, + human_date, + timestamp + }, + timestamp, human_date, - timestamp - }, - timestamp, - am_i_sender ? qsTr("You sent %1").arg(change) : qsTr("You received %1").arg(change), - qsTr("Your wallet balance changed"), - human_date, - "open_wallet_page") + "open_wallet_page") + } } else { @@ -265,130 +259,108 @@ DexPopup } } - readonly property string check_internet_connection_text: qsTr("Please check your internet connection (e.g. VPN service or firewall might block it).") - function onEnablingCoinFailedStatus(coin, error, human_date, timestamp) + function onEnablingZCoinStatus(coin, msg, human_date, timestamp) { // Ignore if coin already enabled (e.g. parent chain in batch) - if (error.search("already initialized") > -1) + if (msg.search("already initialized") > -1) { console.trace() return } - // Check if there is mismatch error, ignore this one - for (let n of notifications_list) - { - if (n.event_name === "onMismatchCustomCoinConfiguration" && n.params.asset === coin) - { - console.trace() - return - } - } - - // Display the notification - const title = qsTr("Failed to enable %1", "TICKER").arg(coin) - - error = check_internet_connection_text + "\n\n" + error - - newNotification("onEnablingCoinFailedStatus", + newNotification( + enablingZCoinStatusNotification, { coin, - error, + msg, human_date, timestamp }, timestamp, - title, - check_internet_connection_text, human_date, "open_log_modal", - error) - - toast.show(title, General.time_toast_important_error, error) + msg) } - function onEndpointNonReacheableStatus(base_uri, human_date, timestamp) + function onEnablingCoinFailedStatus(coin, error, human_date, timestamp) { - const title = qsTr("Endpoint not reachable") + // Ignore if coin already enabled (e.g. parent chain in batch) + if (error.search("already initialized") > -1) + { + console.trace() + return + } - const error = qsTr("Could not reach to endpoint") + ". " + check_internet_connection_text + "\n\n" + base_uri + error = check_internet_connection_text + "\n\n" + error - newNotification("onEndpointNonReacheableStatus", + newNotification( + enablingCoinFailedStatusNotification, { - base_uri, + coin, + error, human_date, timestamp }, timestamp, - title, - base_uri, human_date, "open_log_modal", error) - - toast.show(title, General.time_toast_important_error, error) } - function onMismatchCustomCoinConfiguration(asset, human_date, timestamp) + function onDisablingCoinFailedStatus(coin, error, human_date, timestamp) { - const title = qsTr("Mismatch at %1 custom asset configuration", "TICKER").arg(asset) - - newNotification("onMismatchCustomCoinConfiguration", + newNotification( + disablingCoinFailedStatus, { - asset, + coin, + error, human_date, timestamp }, timestamp, - title, - qsTr("Application needs to be restarted for %1 custom asset.", "TICKER").arg(asset), - human_date) - - toast.show(title, General.time_toast_important_error, "", true, true) + human_date, + "open_log_modal", + error) + toast.show(qsTr("Failed to disable %1", "TICKER").arg(coin), General.time_toast_important_error, error) } - function onBatchFailed(reason, from, human_date, timestamp) + function onEndpointNonReacheableStatus(base_uri, human_date, timestamp) { - const title = qsTr("Batch %1 failed. Reason: %2").arg(from).arg(reason) - - newNotification("onBatchFailed", + newNotification( + endpointNonReacheableStatus, { + base_uri, human_date, timestamp }, timestamp, - title, - reason, - human_date) + human_date, + "open_log_modal", + qsTr("Could not reach to endpoint") + ". " + check_internet_connection_text + "\n\n" + base_uri) - toast.show(title, General.time_toast_important_error, reason) + toast.show(qsTr("Endpoint not reachable"), General.time_toast_important_error, error) } - // System Component.onCompleted: { API.app.notification_mgr.updateSwapStatus.connect(onUpdateSwapStatus) API.app.notification_mgr.balanceUpdateStatus.connect(onBalanceUpdateStatus) + API.app.notification_mgr.enablingZCoinStatus.connect(onEnablingZCoinStatus) API.app.notification_mgr.enablingCoinFailedStatus.connect(onEnablingCoinFailedStatus) + API.app.notification_mgr.disablingCoinFailedStatus.connect(onDisablingCoinFailedStatus) API.app.notification_mgr.endpointNonReacheableStatus.connect(onEndpointNonReacheableStatus) - API.app.notification_mgr.mismatchCustomCoinConfiguration.connect(onMismatchCustomCoinConfiguration) - API.app.notification_mgr.batchFailed.connect(onBatchFailed) } + Component.onDestruction: { API.app.notification_mgr.updateSwapStatus.disconnect(onUpdateSwapStatus) API.app.notification_mgr.balanceUpdateStatus.disconnect(onBalanceUpdateStatus) + API.app.notification_mgr.enablingZCoinStatus.disconnect(onEnablingZCoinStatus) API.app.notification_mgr.enablingCoinFailedStatus.disconnect(onEnablingCoinFailedStatus) + API.app.notification_mgr.disablingCoinFailedStatus.disconnect(onDisablingCoinFailedStatus) API.app.notification_mgr.endpointNonReacheableStatus.disconnect(onEndpointNonReacheableStatus) - API.app.notification_mgr.mismatchCustomCoinConfiguration.disconnect(onMismatchCustomCoinConfiguration) - API.app.notification_mgr.batchFailed.disconnect(onBatchFailed) } - function displayMessage(title, message) - { - if (API.app.settings_pg.notification_enabled) - tray.showMessage(title, message) - } SystemTrayIcon { id: tray @@ -396,12 +368,14 @@ DexPopup iconSource: General.image_path + "dex-tray-icon.png" tooltip: API.app_name + onMessageClicked: { if (notifications_list.length > 0) performNotificationAction(notifications_list[0]) showApp() } + menu: Menu { MenuItem @@ -419,7 +393,11 @@ DexPopup MenuItem { text: qsTr("Quit") - onTriggered: Qt.quit() + onTriggered: + { + if (orders.count != 0) logout_modal.open() + else return_to_login() + } } } } @@ -430,7 +408,8 @@ DexPopup anchors.margins: 30 anchors.topMargin: 20 spacing: 24 - DexLabel + + DefaultText { Layout.fillWidth: true font @@ -438,7 +417,7 @@ DexPopup pixelSize: 20 weight: Font.Normal } - text: "Notifications" + text: qsTr("Notifications") } Item @@ -460,7 +439,7 @@ DexPopup { anchors.centerIn: parent visible: !list.visible - text_value: qsTr("There isn't any notification") + text_value: qsTr("There aren't any notifications") font.pixelSize: 14 } @@ -472,13 +451,17 @@ DexPopup height: parent.height anchors.horizontalCenter: parent.horizontalCenter model: notifications_list + delegate: Item { + height: _column.height + 10 + width: list.width Rectangle { anchors.fill: parent opacity: 0.7 + gradient: Gradient { orientation: Qt.Horizontal @@ -500,8 +483,6 @@ DexPopup notifications_list.splice(index, 1) notifications_list = notifications_list } - height: _column.height + 10 - width: list.width RowLayout { @@ -510,29 +491,30 @@ DexPopup { Layout.fillHeight: true Layout.preferredWidth: 60 + Rectangle { width: 23 height: 23 radius: 12 - gradient: notification_map[modelData.kind].gradient - anchors.right: parent.right anchors.rightMargin: -5 y: 13 + Qaterial.Icon { anchors.centerIn: parent size: 16 - icon: notification_map[modelData.kind].icon - + icon: getNotificationIcon(modelData) } } } + Item { Layout.fillHeight: true Layout.fillWidth: true + Column { id: _column @@ -541,28 +523,31 @@ DexPopup topPadding: 10 bottomPadding: 5 spacing: 5 - DexLabel + + DefaultText { - text: modelData.title + text: getNotificationTitle(modelData) font: DexTypo.subtitle1 width: parent.width wrapMode: Label.Wrap } - DexLabel + + DefaultText { - text: modelData.message + text: getNotificationMsg(modelData) font: DexTypo.subtitle2 width: parent.width - 20 wrapMode: Label.Wrap } - DexLabel + + DefaultText { text: modelData.human_date font: DexTypo.caption opacity: 0.7 } - } + Qaterial.AppBarButton { id: action_button @@ -571,19 +556,17 @@ DexPopup anchors.right: parent.right anchors.rightMargin: 5 anchors.bottomMargin: -4 - foregroundColor: DexTheme.foregroundColor + foregroundColor: Dex.CurrentTheme.foregroundColor visible: modelData.event_name !== "check" + icon.source: { let name switch (modelData.event_name) { - case "onEnablingCoinFailedStatus": + case enablingCoinFailedStatusNotification: name = "repeat" break - case "onMismatchCustomCoinConfiguration": - name = "restart-alert" - break default: name = "check" break @@ -606,16 +589,12 @@ DexPopup // Action switch (event_before_removal.event_name) { - case "onEnablingCoinFailedStatus": + case enablingCoinFailedStatusNotification: removeNotification() console.log("Retrying to enable", event_before_removal.params.coin, "asset...") API.app.enable_coins([event_before_removal.params.coin]) break - case "onMismatchCustomCoinConfiguration": - console.log("Restarting for", event_before_removal.params.asset, "custom asset configuration mismatch...") - root.close() - restart_modal.open() - break + default: removeNotification() break @@ -625,12 +604,13 @@ DexPopup } } - DexMouseArea + DefaultMouseArea { id: mouseArea hoverEnabled: true cursorShape: "PointingHandCursor" anchors.fill: parent + onClicked: { performNotificationAction(notifications_list[index]) @@ -639,15 +619,15 @@ DexPopup } } } - } OutlineButton { text: qsTr('Mark all as read') height: 40 + width: 260 Layout.alignment: Qt.AlignHCenter onClicked: root.reset() } } -} \ No newline at end of file +} diff --git a/atomic_defi_design/Dex/Exchange/Exchange.qml b/atomic_defi_design/Dex/Exchange/Exchange.qml index 34d40accf6..fb405c887f 100644 --- a/atomic_defi_design/Dex/Exchange/Exchange.qml +++ b/atomic_defi_design/Dex/Exchange/Exchange.qml @@ -28,24 +28,9 @@ Item Component.onDestruction: API.app.trading_pg.on_gui_leave_dex() - ColumnLayout + Trade { - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - + id: trade anchors.fill: parent - anchors.topMargin: 20 - - spacing: layout_margin - - Trade - { - id: trade - Layout.fillWidth: true - Layout.fillHeight: true - Layout.bottomMargin: layout_margin - Layout.rightMargin: Layout.bottomMargin - } - } } diff --git a/atomic_defi_design/Dex/Exchange/History/History.qml b/atomic_defi_design/Dex/Exchange/History/History.qml deleted file mode 100644 index 8b8cca162c..0000000000 --- a/atomic_defi_design/Dex/Exchange/History/History.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 - -import "../../Components" -import "../../Constants" -import ".." - -OrdersPage { - page_index: idx_exchange_history - - title: qsTr("Recent Swaps") - //empty_text: qsTr("You don't have recent orders.") - is_history: true -} diff --git a/atomic_defi_design/Dex/Exchange/Orders/Orders.qml b/atomic_defi_design/Dex/Exchange/Orders/Orders.qml deleted file mode 100644 index abee954e1b..0000000000 --- a/atomic_defi_design/Dex/Exchange/Orders/Orders.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 - -import "../../Components" -import "../../Constants" -import ".." - -OrdersPage { - page_index: idx_exchange_orders - - title: qsTr("Orders") - //empty_text: qsTr("You don't have any orders.") - is_history: false -} diff --git a/atomic_defi_design/Dex/Exchange/ProView/Chart.qml b/atomic_defi_design/Dex/Exchange/ProView/Chart.qml new file mode 100644 index 0000000000..4dbc9dc49d --- /dev/null +++ b/atomic_defi_design/Dex/Exchange/ProView/Chart.qml @@ -0,0 +1,209 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 +import QtWebEngine 1.8 + +import "../../Components" +import "../../Constants" +import Dex.Themes 1.0 as Dex +import AtomicDEX.MarketMode 1.0 + +Item +{ + id: root + + readonly property string theme: Dex.CurrentTheme.getColorMode() === Dex.CurrentTheme.ColorMode.Dark ? "dark" : "light" + property string loaded_symbol + property bool pair_supported: false + onPair_supportedChanged: if (!pair_supported) webEngineViewPlaceHolder.visible = false + + function loadChart(right_ticker, left_ticker, force = false, source="nomics") + { + let chart_html = "" + let symbol = "" + + if (source == "nomics") + { + let right_ticker_full = General.coinName(right_ticker) + let right_ticker_id = General.getNomicsId(right_ticker) + let left_ticker_id = General.getNomicsId(left_ticker) + + if (right_ticker_id != "" && left_ticker_id != "") + { + symbol = right_ticker_id+"-"+left_ticker_id + + pair_supported = true + if (symbol === loaded_symbol && !force) + { + webEngineViewPlaceHolder.visible = true + return + } + + loaded_symbol = symbol + + chart_html = ` + + + +
+ + ` + } + } + + if (chart_html == "") + { + const pair = atomic_qt_utilities.retrieve_main_ticker(left_ticker) + "/" + atomic_qt_utilities.retrieve_main_ticker(right_ticker) + const pair_reversed = atomic_qt_utilities.retrieve_main_ticker(right_ticker) + "/" + atomic_qt_utilities.retrieve_main_ticker(left_ticker) + + // Try checking if pair/reversed-pair exists + symbol = General.supported_pairs[pair] + if (!symbol) symbol = General.supported_pairs[pair_reversed] + + if (!symbol) + { + pair_supported = false + return + } + + pair_supported = true + + if (symbol === loaded_symbol && !force) + { + webEngineViewPlaceHolder.visible = true + return + } + + loaded_symbol = symbol + + let chart_html = ` + + + +
+
+ + +
+ ` + } + dashboard.webEngineView.loadHtml(chart_html) + } + + Component.onCompleted: + { + try + { + loadChart(left_ticker?? atomic_app_primary_coin, + right_ticker?? atomic_app_secondary_coin) + } + catch (e) { console.error(e) } + } + + RowLayout + { + anchors.fill: parent + visible: !webEngineViewPlaceHolder.visible + + DefaultBusyIndicator + { + visible: pair_supported + Layout.alignment: Qt.AlignHCenter + Layout.leftMargin: -15 + Layout.rightMargin: Layout.leftMargin*0.75 + scale: 0.5 + } + + DefaultText + { + visible: pair_supported + text_value: qsTr("Loading market data") + "..." + } + + DefaultText + { + visible: !pair_supported + text_value: qsTr("There is no chart data for this pair yet") + Layout.topMargin: 30 + Layout.alignment: Qt.AlignCenter + } + } + + Item + { + id: webEngineViewPlaceHolder + anchors.fill: parent + visible: false + + Component.onCompleted: + { + dashboard.webEngineView.parent = webEngineViewPlaceHolder + dashboard.webEngineView.anchors.fill = webEngineViewPlaceHolder + } + Component.onDestruction: + { + dashboard.webEngineView.visible = false + dashboard.webEngineView.stop() + } + onVisibleChanged: dashboard.webEngineView.visible = visible + + Connections + { + target: dashboard.webEngineView + + function onLoadingChanged(webEngineLoadReq) + { + if (webEngineLoadReq.status === WebEngineView.LoadSucceededStatus) + { + webEngineViewPlaceHolder.visible = true + } + else webEngineViewPlaceHolder.visible = false + } + } + } + + Connections + { + target: app + function onPairChanged(left, right) + { + if (API.app.trading_pg.market_mode == MarketMode.Sell) + { + root.loadChart(left, right) + } + else + { + root.loadChart(right, left) + } + } + } + + Connections + { + target: Dex.CurrentTheme + function onThemeChanged() + { + loadChart(left_ticker?? atomic_app_primary_coin, + right_ticker?? atomic_app_secondary_coin, + true) + } + } +} diff --git a/atomic_defi_design/Dex/Exchange/Trade/DexComboBoxLine.qml b/atomic_defi_design/Dex/Exchange/ProView/DexComboBoxLine.qml similarity index 64% rename from atomic_defi_design/Dex/Exchange/Trade/DexComboBoxLine.qml rename to atomic_defi_design/Dex/Exchange/ProView/DexComboBoxLine.qml index 707ac50c63..368bce3c3c 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/DexComboBoxLine.qml +++ b/atomic_defi_design/Dex/Exchange/ProView/DexComboBoxLine.qml @@ -4,9 +4,11 @@ import QtQuick.Controls 2.15 import QtGraphicalEffects 1.0 import QtQuick.Controls.Universal 2.15 +import "../../Constants" as Dex import "../../Components" import App 1.0 import Dex.Themes 1.0 as Dex +import Dex.Components 1.0 as Dex RowLayout { @@ -16,13 +18,14 @@ RowLayout property var details property color color: !details ? "white" : Style.getCoinColor(details.ticker) property alias bottom_text: bottom_line.text_value + property int activation_progress: Dex.General.zhtlcActivationProgress(details.activation_status, details.ticker) Behavior on color { ColorAnimation { duration: Style.animationDuration } } - DefaultImage + Dex.Image { id: icon - source: General.coinIcon(ticker) + source: General.coinIcon(details.ticker) Layout.preferredWidth: 32 Layout.preferredHeight: 45 Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft @@ -30,6 +33,30 @@ RowLayout Layout.topMargin: Layout.leftMargin Layout.bottomMargin: Layout.leftMargin + DexRectangle + { + anchors.centerIn: parent + anchors.fill: parent + radius: 15 + enabled: Dex.General.isZhtlc(details.ticker) ? activation_progress != 100 : false + visible: enabled + opacity: .9 + color: Dex.DexTheme.backgroundColor + } + + DexLabel + { + anchors.centerIn: parent + anchors.fill: parent + enabled: Dex.General.isZhtlc(details.ticker) ? activation_progress != 100 : false + visible: enabled + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + text: activation_progress + "%" + font: Dex.DexTypo.body2 + color: Dex.DexTheme.greenColor + } + ColumnLayout { anchors.left: parent.right @@ -37,19 +64,18 @@ RowLayout anchors.verticalCenter: parent.verticalCenter width: root.width - 40 - DefaultText + Dex.Text { Layout.preferredWidth: parent.width - 15 text_value: !details ? "" : `${details.ticker}   ${details.name}` - color: Style.colorText font.pixelSize: Style.textSizeSmall3 elide: Text.ElideRight wrapMode: Text.NoWrap } - DefaultText + Dex.Text { id: bottom_line @@ -59,7 +85,7 @@ RowLayout text: real_value Layout.fillWidth: true elide: Text.ElideRight - color: DexTheme.foregroundColor + color: Dex.CurrentTheme.foregroundColor font: DexTypo.body2 wrapMode: Label.NoWrap ToolTip.text: real_value diff --git a/atomic_defi_design/Dex/Exchange/ProView/PlaceOrderForm/Main.qml b/atomic_defi_design/Dex/Exchange/ProView/PlaceOrderForm/Main.qml new file mode 100644 index 0000000000..62e2c1675d --- /dev/null +++ b/atomic_defi_design/Dex/Exchange/ProView/PlaceOrderForm/Main.qml @@ -0,0 +1,329 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 + +import Qaterial 1.0 as Qaterial + +import "../../../Components" +import "../../../Constants" +import Dex.Themes 1.0 as Dex +import Dex.Components 1.0 as Dex +import AtomicDEX.MarketMode 1.0 +import AtomicDEX.TradingError 1.0 + +Widget +{ + title: qsTr("Place Order") + property int loop_count: 0 + property bool show_waiting_for_trade_preimage: false; + property var fees: API.app.trading_pg.fees + property var preimage_rpc_busy: API.app.trading_pg.preimage_rpc_busy + property string protocolIcon: General.platformIcon(General.coinPlatform(left_ticker)) + property var trade_preimage_error: fees.hasOwnProperty('error') ? fees["error"].split("] ").slice(-1) : "" + readonly property bool trade_preimage_ready: fees.hasOwnProperty('base_transaction_fees_ticker') + readonly property bool can_submit_trade: last_trading_error === TradingError.None + + margins: 15 + collapsable: false + + Connections { + target: API.app.trading_pg + + function onFeesChanged() { + // console.log("onFeesChanged::fees: " + JSON.stringify(fees)) + } + + function onPreImageRpcStatusChanged(){ + // console.log("onPreImageRpcStatusChanged::preimage_rpc_busy: " + API.app.trading_pg.preimage_rpc_busy) + } + function onPrefferedOrderChanged(){ + reset_fees_state() + } + } + + Connections + { + target: app + function onPairChanged(left, right) + { + reset_fees_state() + } + } + + Connections + { + target: exchange_trade + function onOrderSelected() + { + reset_fees_state() + } + } + + function reset_fees_state() + { + show_waiting_for_trade_preimage = false; + check_trade_preimage.stop() + loop_count = 0 + API.app.trading_pg.reset_fees() + errors.text_value = "" + } + + // Market mode selector + RowLayout + { + Layout.topMargin: 5 + Layout.bottomMargin: 2 + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: parent.width + height: 40 + + MarketModeSelector + { + Layout.alignment: Qt.AlignLeft + Layout.preferredWidth: (parent.width / 100) * 46 + Layout.preferredHeight: 40 + marketMode: MarketMode.Buy + ticker: atomic_qt_utilities.retrieve_main_ticker(left_ticker) + } + + Item { Layout.fillWidth: true } + + MarketModeSelector + { + Layout.alignment: Qt.AlignRight + Layout.preferredWidth: (parent.width / 100) * 46 + Layout.preferredHeight: 40 + ticker: atomic_qt_utilities.retrieve_main_ticker(left_ticker) + } + } + + // Protocol text for platform tokens + Item + { + height: 40 + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: parent.width + visible: protocolIcon != "" + + ColumnLayout + { + spacing: 2 + anchors.fill: parent + anchors.centerIn: parent + + Dex.Text + { + id: protocolTitle + Layout.preferredWidth: parent.width + text_value: "Protocol:" + font.pixelSize: Style.textSizeSmall1 + horizontalAlignment: Text.AlignHCenter + color: Style.colorText2 + } + + RowLayout + { + id: protocol + Layout.alignment: Qt.AlignHCenter + + DefaultImage + { + id: protocolImg + source: protocolIcon + Layout.preferredHeight: 16 + Layout.preferredWidth: Layout.preferredHeight + } + + DexLabel + { + id: protocolText + text_value: General.getProtocolText(left_ticker) + wrapMode: DexLabel.NoWrap + font.pixelSize: Style.textSizeSmall1 + color: Style.colorText2 + } + } + } + } + + // Order selected indicator + Item + { + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: parent.width + height: 40 + + RowLayout + { + id: orderSelection + visible: API.app.trading_pg.preffered_order.price !== undefined + anchors.fill: parent + anchors.verticalCenter: parent.verticalCenter + + DefaultText + { + Layout.leftMargin: 15 + color: Dex.CurrentTheme.noColor + text: qsTr("Order Selected") + } + + Item { Layout.fillWidth: true } + + Qaterial.FlatButton + { + Layout.preferredHeight: parent.height + Layout.preferredWidth: 30 + Layout.rightMargin: 5 + foregroundColor: Dex.CurrentTheme.noColor + onClicked: { + API.app.trading_pg.reset_order() + reset_fees_state() + } + + Qaterial.ColorIcon + { + anchors.centerIn: parent + iconSize: 16 + color: Dex.CurrentTheme.noColor + source: Qaterial.Icons.close + } + } + } + + Rectangle + { + visible: API.app.trading_pg.preffered_order.price !== undefined + anchors.fill: parent + radius: 8 + color: 'transparent' + border.color: Dex.CurrentTheme.noColor + } + } + + OrderForm + { + id: formBase + width: parent.width + height: 340 + Layout.alignment: Qt.AlignHCenter + } + + Item { Layout.fillHeight: true } + + // Error messages + Item + { + height: 60 + Layout.preferredWidth: parent.width + + // Show errors + Dex.Text + { + id: errors + visible: errors.text_value !== "" + anchors.fill: parent + anchors.centerIn: parent + horizontalAlignment: Text.AlignHCenter + font.pixelSize: Style.textSizeSmall4 + color: Dex.CurrentTheme.noColor + text_value: General.getTradingError( + last_trading_error, + curr_fee_info, + base_ticker, + rel_ticker, left_ticker, right_ticker) + elide: Text.ElideRight + } + } + + TotalView + { + height: 80 + Layout.preferredWidth: parent.width + Layout.alignment: Qt.AlignHCenter + } + + DexGradientAppButton + { + id: swap_btn + height: 40 + Layout.preferredWidth: parent.width - 20 + Layout.alignment: Qt.AlignHCenter + + radius: 18 + text: qsTr("START SWAP") + font.weight: Font.Medium + enabled: can_submit_trade && !show_waiting_for_trade_preimage && errors.text_value == "" + onClicked: + { + console.log("Getting fees info...") + API.app.trading_pg.determine_fees() + show_waiting_for_trade_preimage = true; + } + + Item + { + visible: show_waiting_for_trade_preimage + height: parent.height - 10 + width: parent.width - 10 + anchors.fill: parent + anchors.centerIn: parent + + DefaultBusyIndicator + { + id: preimage_BusyIndicator + anchors.fill: parent + anchors.centerIn: parent + indicatorSize: 32 + indicatorDotSize: 5 + } + } + + DexMouseArea + { + id: areaAlert + hoverEnabled: true + anchors.fill: parent + onClicked: + { + console.log("Getting fees info...") + API.app.trading_pg.determine_fees() + show_waiting_for_trade_preimage = true; + check_trade_preimage.start() + } + } + } + + Timer { + id: check_trade_preimage + interval: 500; + running: false; + repeat: true; + triggeredOnStart: true; + onTriggered: { + loop_count++; + console.log("Getting fees info... " + loop_count + "/50") + if (trade_preimage_ready) + { + show_waiting_for_trade_preimage = false + loop_count = 0 + stop() + confirm_trade_modal.open() + } + else if (trade_preimage_error != "") + { + loop_count = 0 + errors.text_value = trade_preimage_error.toString() + show_waiting_for_trade_preimage = false + stop() + + } + else if (loop_count > 50) + { + loop_count = 0 + show_waiting_for_trade_preimage = false + trade_preimage_error = "Trade preimage timed out, try again." + stop() + } + } + } +} diff --git a/atomic_defi_design/Dex/Exchange/ProView/MarketModeSelector.qml b/atomic_defi_design/Dex/Exchange/ProView/PlaceOrderForm/MarketModeSelector.qml similarity index 90% rename from atomic_defi_design/Dex/Exchange/ProView/MarketModeSelector.qml rename to atomic_defi_design/Dex/Exchange/ProView/PlaceOrderForm/MarketModeSelector.qml index 48f7c7713e..6eb535000b 100644 --- a/atomic_defi_design/Dex/Exchange/ProView/MarketModeSelector.qml +++ b/atomic_defi_design/Dex/Exchange/ProView/PlaceOrderForm/MarketModeSelector.qml @@ -3,15 +3,13 @@ import QtQuick 2.12 import App 1.0 import Dex.Themes 1.0 as Dex import AtomicDEX.MarketMode 1.0 as Dex -import "../../Components" +import "../../../Components" Rectangle { property int marketMode: Dex.MarketMode.Sell property string ticker: "" - width: 124 - height: 48 radius: 18 gradient: Gradient @@ -60,7 +58,11 @@ Rectangle { anchors.centerIn: parent color: API.app.trading_pg.market_mode == marketMode ? Dex.CurrentTheme.gradientButtonTextEnabledColor : Dex.CurrentTheme.foregroundColor - text: (marketMode == Dex.MarketMode.Sell ? qsTr("Sell") : qsTr("Buy")) + ` ${ticker}` + text: + { + if (marketMode == Dex.MarketMode.Sell) qsTr("Sell %1", "TICKER").arg(ticker) + else qsTr("Buy %1", "TICKER").arg(ticker) + } } DefaultMouseArea diff --git a/atomic_defi_design/Dex/Exchange/ProView/PlaceOrderForm/OrderForm.qml b/atomic_defi_design/Dex/Exchange/ProView/PlaceOrderForm/OrderForm.qml new file mode 100644 index 0000000000..99f66e762d --- /dev/null +++ b/atomic_defi_design/Dex/Exchange/ProView/PlaceOrderForm/OrderForm.qml @@ -0,0 +1,255 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 +import QtGraphicalEffects 1.0 + +import "../../../Components" +import App 1.0 +import Dex.Themes 1.0 as Dex + +ColumnLayout +{ + id: root + spacing: 8 + + function focusVolumeField() + { + input_volume.forceActiveFocus() + } + + readonly property string total_amount: API.app.trading_pg.total_amount + readonly property int input_height: 70 + readonly property int subfield_margin: 5 + + + // Will move to backend: Minimum Fee + function getMaxBalance() + { + if (General.isFilled(base_ticker)) + return API.app.get_balance(base_ticker) + + return "0" + } + + // Will move to backend: Minimum Fee + function getMaxVolume() + { + // base in this orderbook is always the left side, so when it's buy, we want the right side balance (rel in the backend) + const value = sell_mode ? API.app.trading_pg.orderbook.base_max_taker_vol.decimal : + API.app.trading_pg.orderbook.rel_max_taker_vol.decimal + + if (General.isFilled(value)) + return value + + return getMaxBalance() + } + + function setMinimumAmount(value) { API.app.trading_pg.min_trade_vol = value } + + Connections + { + target: exchange_trade + function onBackend_priceChanged() { input_price.text = exchange_trade.backend_price; } + function onBackend_volumeChanged() { input_volume.text = exchange_trade.backend_volume; } + } + + Item + { + Layout.preferredWidth: parent.width + Layout.preferredHeight: input_height + + AmountField + { + id: input_price + + left_text: qsTr("Price") + right_text: right_ticker + enabled: !(API.app.trading_pg.preffered_order.price !== undefined) + color: enabled ? Dex.CurrentTheme.foregroundColor : Dex.CurrentTheme.foregroundColor2 + text: backend_price ? backend_price : General.formatDouble(API.app.trading_pg.cex_price) + width: parent.width + height: 41 + radius: 18 + + onTextChanged: setPrice(text) + Component.onCompleted: text = General.formatDouble(API.app.trading_pg.cex_price) ? General.formatDouble(API.app.trading_pg.cex_price) : 1 + } + + OrderFormSubfield + { + id: price_usd_value + anchors.top: input_price.bottom + anchors.left: input_price.left + anchors.topMargin: subfield_margin + visible: !API.app.trading_pg.invalid_cex_price + left_btn.onClicked: + { + let price = General.formatDouble(parseFloat(input_price.text) - (General.formatDouble(API.app.trading_pg.cex_price)*0.01)) + if (price < 0) price = 0 + setPrice(String(price)) + } + right_btn.onClicked: + { + let price = General.formatDouble(parseFloat(input_price.text) + (General.formatDouble(API.app.trading_pg.cex_price)*0.01)) + setPrice(String(price)) + } + middle_btn.onClicked: + { + if (input_price.text == "0") setPrice("1") + let price = General.formatDouble(API.app.trading_pg.cex_price) + setPrice(String(price)) + } + fiat_value: General.getFiatText(non_null_price, right_ticker) + left_label: "-1%" + middle_label: "0%" + right_label: "+1%" + left_tooltip_text: qsTr("Reduce 1% relative to CEX market price.") + middle_tooltip_text: qsTr("Use CEX market price.") + right_tooltip_text: qsTr("Increase 1% relative to CEX market price.") + } + } + + Item + { + Layout.preferredWidth: parent.width + Layout.preferredHeight: input_height + + AmountField + { + id: input_volume + width: parent.width + height: 41 + radius: 18 + left_text: qsTr("Volume") + right_text: left_ticker + placeholderText: sell_mode ? qsTr("Amount to sell") : qsTr("Amount to receive") + text: API.app.trading_pg.volume + onTextChanged: setVolume(text) + } + + OrderFormSubfield + { + id: volume_usd_value + anchors.top: input_volume.bottom + anchors.left: input_volume.left + anchors.topMargin: subfield_margin + left_btn.onClicked: + { + let volume = General.formatDouble(API.app.trading_pg.max_volume * 0.25) + setVolume(String(volume)) + } + middle_btn.onClicked: + { + let volume = General.formatDouble(API.app.trading_pg.max_volume * 0.5) + setVolume(String(volume)) + } + right_btn.onClicked: + { + let volume = General.formatDouble(API.app.trading_pg.max_volume) + setVolume(String(volume)) + } + fiat_value: General.getFiatText(non_null_volume, left_ticker) + left_label: "25%" + middle_label: "50%" + right_label: qsTr("Max") + left_tooltip_text: qsTr("Swap 25% of your tradable balance.") + middle_tooltip_text: qsTr("Swap 50% of your tradable balance.") + right_tooltip_text: qsTr("Swap 100% of your tradable balance.") + } + } + + Item + { + visible: _useCustomMinTradeAmountCheckbox.checked + Layout.preferredWidth: parent.width + Layout.preferredHeight: input_height + + AmountField + { + id: input_minvolume + width: parent.width + height: 41 + radius: 18 + left_text: qsTr("Min Volume") + right_text: left_ticker + placeholderText: sell_mode ? qsTr("Min amount to sell") : qsTr("Min amount to receive") + text: API.app.trading_pg.min_trade_vol + onTextChanged: if (API.app.trading_pg.min_trade_vol != text) setMinimumAmount(text) + } + + OrderFormSubfield + { + id: minvolume_usd_value + anchors.top: input_minvolume.bottom + anchors.left: input_minvolume.left + anchors.topMargin: subfield_margin + left_btn.onClicked: + { + let volume = input_volume.text * 0.10 + setMinimumAmount(General.formatDouble(volume)) + } + middle_btn.onClicked: + { + let volume = input_volume.text * 0.25 + setMinimumAmount(General.formatDouble(volume)) + } + right_btn.onClicked: + { + let volume = input_volume.text * 0.50 + setMinimumAmount(General.formatDouble(volume)) + } + fiat_value: General.getFiatText(API.app.trading_pg.min_trade_vol, left_ticker) + left_label: "10%" + middle_label: "25%" + right_label: "50%" + left_tooltip_text: qsTr("Minimum accepted trade equals 10% of order volume.") + middle_tooltip_text: qsTr("Minimum accepted trade equals 25% of order volume.") + right_tooltip_text: qsTr("Minimum accepted trade equals 50% of order volume.") + } + } + + Item + { + Layout.preferredWidth: parent.width + Layout.preferredHeight: 30 + visible: !_useCustomMinTradeAmountCheckbox.checked + + DefaultText + { + id: minVolLabel + anchors.horizontalCenter: parent.horizontalCenter + font.pixelSize: 13 + text: qsTr("Min volume: ") + API.app.trading_pg.min_trade_vol + } + } + + RowLayout + { + Layout.rightMargin: 2 + Layout.leftMargin: 2 + Layout.preferredWidth: parent.width + Layout.preferredHeight: 30 + spacing: 5 + + DefaultCheckBox + { + id: _useCustomMinTradeAmountCheckbox + boxWidth: 20 + boxHeight: 20 + labelWidth: 0 + onToggled: setMinimumAmount(0) + } + + DefaultText + { + Layout.fillWidth: true + height: _useCustomMinTradeAmountCheckbox.height + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + wrapMode: Label.WordWrap + text: qsTr("Use custom minimum trade amount") + color: Dex.CurrentTheme.foregroundColor3 + font.pixelSize: 13 + } + } +} \ No newline at end of file diff --git a/atomic_defi_design/Dex/Exchange/ProView/PlaceOrderForm/OrderFormSubfield.qml b/atomic_defi_design/Dex/Exchange/ProView/PlaceOrderForm/OrderFormSubfield.qml new file mode 100644 index 0000000000..1370518b6a --- /dev/null +++ b/atomic_defi_design/Dex/Exchange/ProView/PlaceOrderForm/OrderFormSubfield.qml @@ -0,0 +1,224 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 +import QtGraphicalEffects 1.0 + +import "../../../Constants" as Dex +import "../../../Components" +import App 1.0 +import Dex.Themes 1.0 as Dex + +// todo: coding style is wrong, use camelCase. +RowLayout +{ + id: control + property alias fiat_value: _fiat_label.text_value + property alias left_label: _left_label.text + property alias middle_label: _middle_label.text + property alias right_label: _right_label.text + property string left_tooltip_text: "" + property string middle_tooltip_text: "" + property string right_tooltip_text: "" + property alias left_btn: _left_btn + property alias middle_btn: _middle_btn + property alias right_btn: _right_btn + property int pixel_size: 12 + property int btn_width: 33 + spacing: 2 + height: 20 + width: parent.width + + Item + { + width: btn_width + height: parent.height + + // Background when market mode is different + DefaultRectangle + { + anchors.centerIn: parent + width: parent.width + height: parent.height + color: Dex.CurrentTheme.tradeMarketModeSelectorNotSelectedBackgroundColor + } + + DefaultText + { + id: _left_label + anchors.centerIn: parent + font.pixelSize: pixel_size + color: Dex.CurrentTheme.foregroundColor2 + text: "-1%" + } + + DexTooltip + { + id: _left_tooltip + visible: _left_btn.containsMouse && left_tooltip_text != "" + + contentItem: FloatingBackground + { + anchors.top: parent.bottom + anchors.topMargin: 30 + color: Dex.CurrentTheme.accentColor + + DefaultText + { + text: left_tooltip_text + font: Dex.DexTypo.caption + leftPadding: 10 + rightPadding: 10 + topPadding: 6 + bottomPadding: 6 + } + } + + background: Rectangle { + width: 0 + height: 0 + color: "transparent" + } + } + + DefaultMouseArea + { + id: _left_btn + anchors.fill: parent + hoverEnabled: true + } + } + + Item + { + + width: btn_width + height: parent.height + + // Background when market mode is different + DefaultRectangle + { + anchors.centerIn: parent + width: parent.width + height: parent.height + color: Dex.CurrentTheme.tradeMarketModeSelectorNotSelectedBackgroundColor + + DefaultMouseArea + { + id: _middle_btn + anchors.fill: parent + hoverEnabled: true + } + + DefaultText + { + id: _middle_label + anchors.centerIn: parent + font.pixelSize: pixel_size + color: Dex.CurrentTheme.foregroundColor2 + text: "0%" + } + + DexTooltip + { + id: _middle_tooltip + visible: _middle_btn.containsMouse && middle_tooltip_text != "" + + contentItem: FloatingBackground + { + anchors.top: parent.bottom + anchors.topMargin: 30 + color: Dex.CurrentTheme.accentColor + + DefaultText + { + text: middle_tooltip_text + font: Dex.DexTypo.caption + leftPadding: 10 + rightPadding: 10 + topPadding: 6 + bottomPadding: 6 + } + } + + background: Rectangle { + width: 0 + height: 0 + color: "transparent" + } + } + } + } + + Item + { + + width: btn_width + height: parent.height + + // Background when market mode is different + DefaultRectangle + { + id: right_rect + anchors.centerIn: parent + width: parent.width + height: parent.height + color: Dex.CurrentTheme.tradeMarketModeSelectorNotSelectedBackgroundColor + } + + DefaultText + { + id: _right_label + anchors.centerIn: parent + font.pixelSize: pixel_size + color: Dex.CurrentTheme.foregroundColor2 + text: "+1%" + } + + DexTooltip + { + id: _right_tooltip + visible: _right_btn.containsMouse && right_tooltip_text != "" + + + contentItem: FloatingBackground + { + anchors.top: parent.bottom + anchors.topMargin: 30 + color: Dex.CurrentTheme.accentColor + + DefaultText + { + text: right_tooltip_text + font: Dex.DexTypo.caption + leftPadding: 10 + rightPadding: 10 + topPadding: 6 + bottomPadding: 6 + } + } + + background: Rectangle { + width: 0 + height: 0 + color: "transparent" + } + } + + DefaultMouseArea + { + id: _right_btn + anchors.fill: parent + hoverEnabled: true + } + } + + Item { Layout.fillWidth: true } + + DefaultText + { + id: _fiat_label + font.pixelSize: pixel_size + color: Dex.CurrentTheme.foregroundColor2 + DefaultInfoTrigger { triggerModal: cex_info_modal } + } +} \ No newline at end of file diff --git a/atomic_defi_design/Dex/Exchange/ProView/PlaceOrderForm/TotalView.qml b/atomic_defi_design/Dex/Exchange/ProView/PlaceOrderForm/TotalView.qml new file mode 100644 index 0000000000..588c1a054b --- /dev/null +++ b/atomic_defi_design/Dex/Exchange/ProView/PlaceOrderForm/TotalView.qml @@ -0,0 +1,79 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 +import QtQuick.Controls.Material 2.15 + +import Qaterial 1.0 as Qaterial +import Qt.labs.settings 1.0 + +import "../../../Components" +import "../../../Constants" +import Dex.Themes 1.0 as Dex + +ColumnLayout +{ + spacing: 3 + + RowLayout + { + Layout.preferredWidth: parent.width + Layout.preferredHeight: 30 + + DefaultText + { + Layout.fillWidth: true + Layout.alignment: Qt.AlignLeft + color: Dex.CurrentTheme.foregroundColor3 + text: "Total " + API.app.settings_pg.current_fiat + " " + General.cex_icon + font.pixelSize: 14 + font.weight: Font.Normal + opacity: .6 + DefaultInfoTrigger { triggerModal: cex_info_modal } + } + + DefaultText + { + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + font.weight: Font.DemiBold + font.pixelSize: 16 + font.family: 'lato' + text_value: General.getFiatText(total_amount, right_ticker).replace(General.cex_icon, "") + } + } + + HorizontalLine + { + color: Dex.CurrentTheme.lineSeparatorColor + Layout.preferredWidth: parent.width + Layout.preferredHeight: 1 + Layout.alignment: Qt.AlignHCenter + } + + RowLayout + { + Layout.preferredWidth: parent.width + Layout.preferredHeight: 30 + + DefaultText + { + Layout.fillWidth: true + color: Dex.CurrentTheme.foregroundColor3 + Layout.preferredWidth: parent.width * 0.3 + text: "Total " + right_ticker + font.pixelSize: 14 + opacity: .6 + font.weight: Font.Normal + } + + DefaultText + { + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + font.weight: Font.DemiBold + font.pixelSize: 16 + font.family: 'lato' + text_value: General.formatCrypto("", total_amount, right_ticker).replace(right_ticker, "") + } + } +} diff --git a/atomic_defi_design/Dex/Exchange/ProView/SearchableTickerSelector.qml b/atomic_defi_design/Dex/Exchange/ProView/SearchableTickerSelector.qml new file mode 100644 index 0000000000..de90ed3f2d --- /dev/null +++ b/atomic_defi_design/Dex/Exchange/ProView/SearchableTickerSelector.qml @@ -0,0 +1,105 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.3 + +import Qaterial 1.0 as Qaterial + +import Dex.Themes 1.0 as Dex +import Dex.Components 1.0 as Dex +import "../../Components" as Dex +import "../../Constants" as Dex + +Dex.ComboBoxWithSearchBar +{ + id: control + + property var currentItem: model.index(currentIndex, 0) + property bool left_side: false + property string ticker + property bool index_changed: false + + height: 60 + enabled: !block_everything + + textRole: "ticker" + valueRole: "ticker" + + popupMaxHeight: Math.min(model.rowCount() * 70 + 70, 600) + popupForceMaxHeight: true + + searchBar.visible: true + searchBar.searchModel: model + + delegate: ItemDelegate + { + id: _delegate + width: control.width + height: visible ? 60 : 0 + highlighted: control.highlightedIndex === index + + contentItem: DexComboBoxLine { details: model } + background: Dex.DexRectangle + { + anchors.fill: _delegate + color: _delegate.highlighted ? Dex.CurrentTheme.comboBoxDropdownItemHighlightedColor : Dex.CurrentTheme.comboBoxBackgroundColor + } + } + + contentItem: DexComboBoxLine + { + id: _contentRow + + property int update_count: 0 + property var prev_details + + padding: 10 + + function forceUpdateDetails() + { + console.log("Portfolio item data changed, force-updating the selected ticker details!") + ++update_count + } + + details: + { + const idx = currentIndex + if (idx === -1) return prev_details + + const new_details = { + update_count: _contentRow.update_count, + ticker: model.data(model.index(idx, 0), 257), + name: model.data(model.index(idx, 0), 259), + balance: model.data(model.index(idx, 0), 260), + main_currency_balance: model.data(model.index(idx, 0), 261), + activation_status: model.data(model.index(idx, 0), 266) + } + + prev_details = new_details + return new_details + } + Component.onCompleted: portfolio_mdl.portfolioItemDataChanged.connect(forceUpdateDetails) + Component.onDestruction: portfolio_mdl.portfolioItemDataChanged.disconnect(forceUpdateDetails) + } + + onCurrentIndexChanged: control.index_changed = true + onCurrentValueChanged: + { + if (control.index_changed) + { + control.index_changed = false + if (currentValue !== undefined) + setPair(left_side, currentValue) + } + else + { + if (currentText.indexOf(ticker) === -1) + { + const target_index = indexOfValue(ticker) + if (currentIndex !== target_index) + currentIndex = target_index + } + } + } + searchBar.onVisibleChanged: if (!visible) { searchBar.textField.text = "" } + searchBar.textField.onTextChanged: control.model.setFilterFixedString(searchBar.textField.text) +} diff --git a/atomic_defi_design/Dex/Exchange/ProView/TickerSelectors.qml b/atomic_defi_design/Dex/Exchange/ProView/TickerSelectors.qml new file mode 100644 index 0000000000..86df283110 --- /dev/null +++ b/atomic_defi_design/Dex/Exchange/ProView/TickerSelectors.qml @@ -0,0 +1,81 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 + +import "../../Components" +import "../../Constants" + +// Ticker selectors. +Row +{ + id: selectors + + function renewIndex() + { + selectorLeft.currentIndex = selectorLeft.indexOfValue(selectorLeft.ticker) + selectorRight.currentIndex = selectorRight.indexOfValue(selectorRight.ticker) + selectorLeft.searchBar.textField.text = "" + selectorRight.searchBar.textField.text = "" + } + + SearchableTickerSelector + { + id: selectorLeft + + width: parent.width * 0.45 + height: parent.height + + left_side: true + model: API.app.trading_pg.market_pairs_mdl.left_selection_box + ticker: left_ticker + onTickerChanged: renewIndex() + Component.onCompleted: renewIndex() + Component.onDestruction: searchBar.textField.text = "" + onVisibleChanged: + { + renewIndex() + model.with_balance = false + } + } + + SwapIcon + { + width: parent.width * 0.1 + anchors.verticalCenter: parent.verticalCenter + top_arrow_ticker: selectorLeft.ticker + bottom_arrow_ticker: selectorRight.ticker + hovered: swap_button.containsMouse + + DefaultMouseArea + { + id: swap_button + anchors.fill: parent + hoverEnabled: true + onClicked: + { + if (!block_everything) + setPair(true, right_ticker) + } + } + } + + SearchableTickerSelector + { + id: selectorRight + + width: parent.width * 0.45 + height: parent.height + + left_side: false + model: API.app.trading_pg.market_pairs_mdl.right_selection_box + ticker: right_ticker + onTickerChanged: renewIndex() + Component.onCompleted: renewIndex() + Component.onDestruction: searchBar.textField.text = "" + onVisibleChanged: + { + renewIndex() + model.with_balance = false + } + } +} diff --git a/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/Main.qml b/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/Main.qml new file mode 100644 index 0000000000..b08a691dcf --- /dev/null +++ b/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/Main.qml @@ -0,0 +1,120 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 + +import Qaterial 1.0 as Qaterial + +import Dex.Themes 1.0 as Dex +import "../../../Constants" +import "../../../Components" +import "../../Trade" +import "../../ProView" + +Widget +{ + property alias currentIndex: tabView.currentIndex + + title: qsTr("Trading Information") + + background: null + margins: 0 + + Connections + { + target: exchange_trade + function onOrderSelected() { tabView.currentIndex = 0; } + } + + Qaterial.LatoTabBar + { + id: tabView + property int pair_chart_idx: 0 + property int order_idx: 1 + property int history_idx: 2 + + background: null + Layout.leftMargin: 6 + + Qaterial.LatoTabButton + { + text: qsTr("Chart") + font.pixelSize: 14 + textColor: checked ? Dex.CurrentTheme.foregroundColor : Dex.CurrentTheme.foregroundColor2 + textSecondaryColor: Dex.CurrentTheme.foregroundColor2 + indicatorColor: Dex.CurrentTheme.foregroundColor + } + Qaterial.LatoTabButton + { + text: qsTr("Orders") + font.pixelSize: 14 + textColor: checked ? Dex.CurrentTheme.foregroundColor : Dex.CurrentTheme.foregroundColor2 + textSecondaryColor: Dex.CurrentTheme.foregroundColor2 + indicatorColor: Dex.CurrentTheme.foregroundColor + } + Qaterial.LatoTabButton + { + text: qsTr("History") + font.pixelSize: 14 + textColor: checked ? Dex.CurrentTheme.foregroundColor : Dex.CurrentTheme.foregroundColor2 + textSecondaryColor: Dex.CurrentTheme.foregroundColor2 + indicatorColor: Dex.CurrentTheme.foregroundColor + } + } + + Rectangle + { + Layout.fillWidth: true + Layout.fillHeight: true + color: Dex.CurrentTheme.floatingBackgroundColor + radius: 10 + + Qaterial.SwipeView + { + id: swipeView + clip: true + interactive: false + currentIndex: tabView.currentIndex + anchors.fill: parent + + ColumnLayout + { + Layout.fillHeight: true + spacing: 10 + // Chart + Chart + { + id: chart + Layout.topMargin: 20 + Layout.leftMargin: 28 + Layout.rightMargin: 28 + Layout.fillWidth: true + Layout.preferredHeight: 310 + + } + + PriceLineSimplified + { + id: price_line + Layout.bottomMargin: 20 + Layout.leftMargin: 28 + Layout.rightMargin: 28 + Layout.fillWidth: true + Layout.fillHeight: true + } + } + + onCurrentIndexChanged: + { + swipeView.currentItem.update(); + } + + OrdersPage { clip: true } + + OrdersPage + { + is_history: true + clip: true + } + } + } +} diff --git a/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/OrderLine.qml b/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/OrderLine.qml new file mode 100644 index 0000000000..fc880aa0ea --- /dev/null +++ b/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/OrderLine.qml @@ -0,0 +1,306 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 +import Qaterial 1.0 as Qaterial + +import QtGraphicalEffects 1.0 + +import bignumberjs 1.0 + +import App 1.0 + +import "../../../Components" +import Dex.Themes 1.0 as Dex + +FloatingBackground +{ + Layout.fillWidth: true + + property var details + property alias clickable: mouseArea.enabled + readonly property bool is_placed_order: !details ? false : details.order_id !== '' + + height: 50 + + color: mouseArea.containsMouse ? Dex.CurrentTheme.accentColor : Dex.CurrentTheme.floatingBackgroundColor + radius: 0 + + DefaultMouseArea + { + id: mouseArea + anchors.fill: parent + hoverEnabled: enabled + onClicked: + { + order_modal.open() + order_modal.item.details = details + } + } + + RowLayout + { + anchors.fill: parent + anchors.verticalCenter: parent.verticalCenter + spacing: 4 + + Item + { + Layout.fillHeight: true + Layout.preferredWidth: 24 + Layout.alignment: Qt.AlignCenter + + DefaultText + { + id: statusText + anchors.centerIn: parent + + visible: clickable ? !details ? false : (details.is_swap || !details.is_maker) : false + font.pixelSize: getStatusFontSize(details.order_status) + color: !details ? Dex.CurrentTheme.foregroundColor : getStatusColor(details.order_status) + text_value: !details ? "" : visible ? getStatusStep(details.order_status) : '' + } + + Qaterial.ColorIcon + { + anchors.centerIn: parent + + visible: !statusText.visible ? clickable ? true : false : false + iconSize: 16 + color: Dex.CurrentTheme.foregroundColor + source: Qaterial.Icons.clipboardTextSearchOutline + } + } + + + ColumnLayout + { + Layout.fillHeight: true + Layout.fillWidth: true + Layout.alignment: Qt.AlignCenter + spacing: 0 + + Item + { + Layout.fillWidth: true + Layout.preferredHeight: childrenRect.height + + clip: true + + DefaultText + { + id: baseAmountLabel + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + + font.pixelSize: 12 + text: + { + if (!details) return + + BigNumber.config({ DECIMAL_PLACES: 6 }) + return new BigNumber(details.base_amount).toString(10) + } + privacy: is_placed_order + elide: Text.ElideRight + maximumLineCount: 1 + } + + DefaultText + { + anchors.left: baseAmountLabel.right + anchors.leftMargin: 3 + anchors.verticalCenter: parent.verticalCenter + + font.pixelSize: 12 + text: !details ? "" : "(%1 %2)".arg(details.base_amount_current_currency).arg(API.app.settings_pg.current_fiat_sign) + privacy: is_placed_order + elide: Text.ElideRight + maximumLineCount: 1 + } + + Qaterial.ColorIcon + { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + + source: Qaterial.Icons.swapHorizontal + color: Dex.CurrentTheme.foregroundColor + iconSize: 18 + } + + DefaultText + { + anchors.right: relAmountInCurrCurrency.left + anchors.rightMargin: 3 + anchors.verticalCenter: parent.verticalCenter + + font.pixelSize: 12 + text: + { + if (!details) return + + BigNumber.config({ DECIMAL_PLACES: 6 }) + return new BigNumber(details.rel_amount).toString(10) + } + + privacy: is_placed_order + elide: Text.ElideRight + maximumLineCount: 1 + } + + DefaultText + { + id: relAmountInCurrCurrency + + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + + font.pixelSize: 12 + text: !details ? "" : "(%1 %2)".arg(details.rel_amount_current_currency).arg(API.app.settings_pg.current_fiat_sign) + privacy: is_placed_order + elide: Text.ElideRight + maximumLineCount: 1 + } + } + + Item + { + Layout.fillWidth: true + Layout.preferredHeight: childrenRect.height + + DefaultImage + { + id: baseIcon + + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + + width: 15 + height: 15 + + source: General.coinIcon(!details ? atomic_app_primary_coin : details.base_coin ?? atomic_app_primary_coin) + } + + DefaultText + { + anchors.left: baseIcon.right + anchors.leftMargin: 2 + anchors.verticalCenter: parent.verticalCenter + + font.weight: Font.Bold + font.pixelSize: 12 + text: !details ? "" : details.base_coin + privacy: is_placed_order + elide: Text.ElideRight + maximumLineCount: 1 + } + + DefaultText + { + visible: clickable + + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + + font.pixelSize: 11 + text_value: !details ? "" : details.date ?? "" + elide: Text.ElideRight + maximumLineCount: 1 + color: Dex.CurrentTheme.foregroundColor2 + } + + DefaultText + { + anchors.right: relCoin.left + anchors.rightMargin: 2 + anchors.verticalCenter: parent.verticalCenter + + font.weight: Font.Bold + font.pixelSize: 12 + text: !details ? "" : details.rel_coin + privacy: is_placed_order + elide: Text.ElideRight + maximumLineCount: 1 + } + + DefaultImage + { + id: relCoin + + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + + width: 15 + height: 15 + + source: General.coinIcon(!details ? atomic_app_primary_coin : details.rel_coin ?? atomic_app_secondary_coin) + } + } + } + + Item + { + Layout.fillHeight: true + Layout.preferredWidth: 24 + Layout.alignment: Qt.AlignCenter + + DefaultText + { + anchors.centerIn: parent + + visible: !details || details.recoverable === undefined ? false : details.recoverable && details.order_status !== "refunding" + font.pixelSize: baseAmountLabel.font.pixelSize + text_value: Style.warningCharacter + color: Style.colorYellow + + DefaultTooltip + { + contentItem: DefaultText + { + text_value: qsTr("Funds are recoverable") + font.pixelSize: Style.textSizeSmall4 + } + + visible: (parent.visible && mouseArea.containsMouse) ?? false + } + } + + Qaterial.FlatButton + { + id: cancel_button_text + anchors.centerIn: parent + anchors.fill: parent + + visible: (!is_history ? details.cancellable ?? false : false) === true ? (mouseArea.containsMouse || hovered) ? true : false : false + + outlinedColor: Dex.CurrentTheme.noColor + hoverEnabled: true + + onClicked: if (details) cancelOrder(details.order_id) + + Behavior on scale + { + NumberAnimation + { + duration: 200 + } + } + Qaterial.ColorIcon + { + anchors.centerIn: parent + iconSize: 16 + color: Dex.CurrentTheme.noColor + source: Qaterial.Icons.close + scale: parent.visible ? 1 : 0 + } + } + } + } + // Separator + HorizontalLine + { + width: parent.width + height: 2 + anchors.bottom: parent.bottom + } +} diff --git a/atomic_defi_design/Dex/Exchange/Trade/Orders/OrderList.qml b/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/OrderList.qml similarity index 88% rename from atomic_defi_design/Dex/Exchange/Trade/Orders/OrderList.qml rename to atomic_defi_design/Dex/Exchange/ProView/TradingInfo/OrderList.qml index 3c26cc341d..7a5a4aa007 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/Orders/OrderList.qml +++ b/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/OrderList.qml @@ -3,25 +3,28 @@ import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 import App 1.0 - import "../../../Components" import "../../../" +import Dex.Themes 1.0 as Dex Item { + id: root + property string title property var items property bool is_history: false ColumnLayout { - width: parent.width - 10 + width: parent.width height: parent.height anchors.horizontalCenter: parent.horizontalCenter HorizontalLine { Layout.fillWidth: true + Layout.maximumWidth: 511 } DefaultListView @@ -47,6 +50,7 @@ Item details: model opacity: anim_time + width: root.width * 0.985 } populate: Transition @@ -93,6 +97,8 @@ Item Layout.maximumHeight: 70 Layout.preferredWidth: parent.width Layout.bottomMargin: 10 + itemsPerPageComboBox.mainBackgroundColor: Dex.CurrentTheme.comboBoxBackgroundColor + itemsPerPageComboBox.popupBackgroundColor: Dex.CurrentTheme.comboBoxBackgroundColor } } diff --git a/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/OrderModal.qml b/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/OrderModal.qml new file mode 100644 index 0000000000..381a7d7bc0 --- /dev/null +++ b/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/OrderModal.qml @@ -0,0 +1,311 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 + +import Qaterial 1.0 as Qaterial + +import Dex.Themes 1.0 as Dex +import "../../../Components" +import "../../../Constants" +import App 1.0 + +MultipageModal +{ + id: root + + property var details + horizontalPadding: 60 + verticalPadding: 40 + + onDetailsChanged: { if (!details) root.close() } + onOpened: + { + swapProgress.updateSimulatedTime() + swapProgress.updateCountdownTime() + } + onClosed: details = undefined + + MultipageModalContent + { + titleText: !details ? "" : details.is_swap ? qsTr("Swap Details") : qsTr("Order Details") + title.font.pixelSize: Style.textSize2 + titleAlignment: Qt.AlignHCenter + titleTopMargin: 10 + topMarginAfterTitle: 10 + flickMax: window.height - 450 + + header: [ + // Complete image + DefaultImage + { + visible: !details ? false : details.is_swap && details.order_status === "successful" + Layout.alignment: Qt.AlignHCenter + source: General.image_path + "exchange-trade-complete.png" + height: 100 + }, + + // Loading symbol + DefaultBusyIndicator + { + visible: !details ? false : + details.is_swap && !["successful", "failed"].includes(details.order_status) + running: visible && Qt.platform.os != "osx" + Layout.alignment: Qt.AlignHCenter + height: 100 + }, + + RowLayout + { + Layout.topMargin: 10 + height: 70 + + PairItemBadge + { + ticker: details ? details.base_coin : "" + fullname: details ? General.coinName(details.base_coin) : "" + amount: details ? details.base_amount : "" + } + + Qaterial.Icon + { + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter + + color: Dex.CurrentTheme.foregroundColor + icon: Qaterial.Icons.swapHorizontal + } + + PairItemBadge + { + ticker: details ? details.rel_coin : "" + fullname: details ? General.coinName(details.rel_coin) : "" + amount: details ? details.rel_amount : "" + } + }, + + // Status Text + DefaultText + { + id: statusText + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: 5 + font.pixelSize: Style.textSizeMid1 + font.bold: true + visible: !details ? false : details.is_swap || !details.is_maker + text_value: !details ? "" : visible ? getStatusText(details.order_status) : '' + height: 25 + }, + + DefaultText + { + Layout.alignment: Qt.AlignHCenter + visible: text_value != "" + font.pixelSize: Style.textSizeSmall2 + text_value: !details ? "" : details.order_status === "refunding" ? swapProgress.getRefundText() : "" + height: 25 + } + ] + + ColumnLayout + { + id: details_column + Layout.fillWidth: true + spacing: 12 + + // Maker/Taker + TextEditWithTitle + { + Layout.fillWidth: true + title: qsTr("Order Type") + text: !details ? "" : details.is_maker ? qsTr("Maker Order") : qsTr("Taker Order") + label.font.pixelSize: 13 + } + + // Refund state + TextEditWithTitle + { + Layout.fillWidth: true + title: qsTr("Refund State") + text: !details ? "" : details.order_status === "refunding" ? qsTr("Your swap failed but the auto-refund process for your payment started already. Please wait and keep application opened until you receive your payment back") : "" + label.font.pixelSize: 13 + visible: text !== '' + } + + // Date + TextEditWithTitle + { + Layout.fillWidth: true + title: qsTr("Date") + text: !details ? "" : details.date.replace(" ", " ") + label.font.pixelSize: 13 + visible: text !== '' + } + + // ID + TextEditWithTitle + { + Layout.fillWidth: true + title: qsTr("Swap ID") + text: !details ? "" : details.order_id + label.font.pixelSize: 13 + visible: text !== '' + copy: true + privacy: true + onCopyNotificationTitle: qsTr("Swap ID") + } + + // Payment ID + TextEditWithTitle + { + Layout.fillWidth: true + title: !details ? "" : details.is_maker ? qsTr("Maker Payment Sent Transaction ID") : qsTr("Maker Payment Spent Transaction ID") + text: !details ? "" : details.maker_payment_id + label.font.pixelSize: 12 + visible: text !== '' + copy: true + linkURL: text !== '' ? General.getTxExplorerURL(details.is_maker ? details.base_coin : details.rel_coin, details.maker_payment_id) : '' + privacy: true + onCopyNotificationTitle: qsTr("Maker Payment TXID") + } + + // Payment ID + TextEditWithTitle + { + Layout.fillWidth: true + title: !details ? "" : details.is_maker ? qsTr("Taker Payment Spent Transaction ID") : qsTr("Taker Payment Sent Transaction ID") + text: !details ? "" : details.taker_payment_id + label.font.pixelSize: 12 + visible: text !== '' + copy: true + privacy: true + onCopyNotificationTitle: qsTr("Taker Payment TXID") + linkURL: text !== '' ? General.getTxExplorerURL(details.is_maker ? details.rel_coin : details.base_coin, details.taker_payment_id) : '' + } + + // Error ID + TextEditWithTitle + { + Layout.fillWidth: true + title: qsTr("Error ID") + text: !details ? "" : details.order_error_state + label.font.pixelSize: 13 + visible: text !== '' + } + + // Error Details + TextEditWithTitle + { + Layout.fillWidth: true + title: qsTr("Error Log") + text: !details ? "" : details.order_error_message + label.font.pixelSize: 13 + visible: text !== '' + copy: true + onCopyNotificationTitle: qsTr("Error Log") + } + + HorizontalLine + { + visible: swapProgress.visible + Layout.fillWidth: true + Layout.topMargin: 10 + } + + SwapProgress + { + id: swapProgress + Layout.fillWidth: true + visible: General.exists(details) && details.order_status !== "matching" + details: root.details + } + } + + // Buttons + footer: + [ + Item + { + visible: refund_button.visible || cancel_order_button.visible + Layout.fillWidth: true + }, + + // Recover Funds button + DefaultButton + { + id: refund_button + leftPadding: 15 + rightPadding: 15 + radius: 18 + enabled: !API.app.orders_mdl.recover_fund_busy + visible: !details ? false : + details.recoverable && details.order_status !== "refunding" + text: enabled ? qsTr("Recover Funds") : qsTr("Refunding...") + font: DexTypo.body2 + onClicked: API.app.orders_mdl.recover_fund(details.order_id) + Layout.preferredHeight: 50 + }, + + // Cancel button + DexAppOutlineButton + { + id: cancel_order_button + visible: !details ? false : details.cancellable + leftPadding: 15 + rightPadding: 15 + radius: 18 + text: qsTr("Cancel Order") + font: DexTypo.body2 + onClicked: cancelOrder(details.order_id) + Layout.preferredHeight: 50 + }, + + Item { Layout.fillWidth: true }, + + DexAppOutlineButton + { + id: explorer_button + text: qsTr("View on Explorer") + font: DexTypo.body2 + Layout.preferredHeight: 50 + leftPadding: 15 + rightPadding: 15 + radius: 18 + visible: !details ? false : details.maker_payment_id !== '' || details.taker_payment_id !== '' + onClicked: + { + if (!details) return + + const maker_id = details.maker_payment_id + const taker_id = details.taker_payment_id + + if (maker_id !== '') General.viewTxAtExplorer(details.is_maker ? details.base_coin : details.rel_coin, maker_id) + if (taker_id !== '') General.viewTxAtExplorer(details.is_maker ? details.rel_coin : details.base_coin, taker_id) + } + }, + + Item + { + visible: close_order_button.visible && explorer_button.visible + Layout.fillWidth: true + }, + + DefaultButton + { + id: close_order_button + text: qsTr("Close") + font: DexTypo.body2 + leftPadding: 15 + rightPadding: 15 + radius: 18 + onClicked: root.close() + Layout.preferredHeight: 50 + }, + + Item + { + visible: close_order_button.visible || explorer_button.visible + Layout.fillWidth: true + } + ] + } +} diff --git a/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/OrdersPage.qml b/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/OrdersPage.qml new file mode 100644 index 0000000000..5ff799eda8 --- /dev/null +++ b/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/OrdersPage.qml @@ -0,0 +1,279 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 +import Qt.labs.platform 1.1 + +import Qaterial 1.0 as Qaterial + +import App 1.0 +import "../../../Components" +import "../../../Constants" +import "../../.." +import Dex.Themes 1.0 as Dex + +Item { + id: root + + readonly property date default_min_date: new Date("2019-01-01") + readonly property date default_max_date: new Date(new Date().setDate(new Date().getDate() + 30)) + + property var list_model: API.app.orders_mdl + property var list_model_proxy: API.app.orders_mdl.orders_proxy_mdl + property int page_index + + property alias title: order_list.title + property alias items: order_list.items + + property bool is_history: false + + function update() + { + reset() + if (combo_base.currentTicker !== "All" | combo_rel.currentTicker !== "All") { + buttonDelay.start() + } + } + + function reset() { + list_model_proxy.is_history = !is_history + applyFilter() + list_model_proxy.apply_all_filtering() + list_model_proxy.is_history = is_history + } + + Component.onDestruction: reset() + + Timer { + id: buttonDelay + interval: 200 + onTriggered: { + applyFilter() + list_model_proxy.apply_all_filtering() + } + } + + function applyDateFilter() { + list_model_proxy.filter_minimum_date = min_date.selectedDate + + if (max_date.selectedDate < min_date.selectedDate) + max_date.selectedDate = min_date.selectedDate + + list_model_proxy.filter_maximum_date = max_date.selectedDate + } + + function applyTickerFilter() { + list_model_proxy.set_coin_filter(combo_base.currentValue + "/" + combo_rel.currentValue) + } + + function applyTickerFilter2(ticker1, ticker2) { + list_model_proxy.set_coin_filter(ticker1 + "/" + ticker2) + } + + function applyFilter() { + applyDateFilter() + applyTickerFilter2(combo_base.currentTicker, combo_rel.currentTicker) + } + + Component.onCompleted: { + list_model_proxy.is_history = root.is_history + applyFilter() + list_model_proxy.apply_all_filtering() + } + + ColumnLayout + { + anchors.horizontalCenter: parent.horizontalCenter + anchors.fill: parent + anchors.margins: 28 + anchors.bottomMargin: is_history ? 0 : 10 + spacing: 15 + + RowLayout + { + spacing: 10 + DefaultButton + { + Layout.preferredHeight: 29 + radius: 7 + label.font: DexTypo.body2 + text: qsTr("Filter") + iconSource: Qaterial.Icons.filter + onClicked: settings.visible = !settings.visible + } + + DefaultButton + { + visible: root.is_history + Layout.preferredHeight: 29 + radius: 7 + label.font: DexTypo.body2 + text: qsTr("Export CSV") + onClicked: + { + export_csv_dialog.folder = General.os_file_prefix + API.app.settings_pg.get_export_folder() + export_csv_dialog.open() + } + } + + DefaultText + { + color: Dex.CurrentTheme.foregroundColor2 + font: DexTypo.caption + visible: !settings.visible + text: qsTr("Filter") + ": %1 / %2
%3: %4 - %5".arg(combo_base.currentTicker).arg(combo_rel.currentTicker).arg(qsTr("Date")).arg(min_date.selectedDate.toLocaleDateString(Locale.ShortFormat, "yyyy-MM-dd")).arg(max_date.selectedDate.toLocaleDateString(Locale.ShortFormat, "yyyy-MM-dd")) + } + } + + ColumnLayout + { + id: settings + visible: false + spacing: 8 + + RowLayout + { + spacing: 10 + DefaultButton + { + visible: root.is_history + enabled: list_model_proxy.can_i_apply_filtering + Layout.preferredHeight: 29 + radius: 7 + label.font: DexTypo.body2 + text: qsTr("Apply Filter") + onClicked: list_model_proxy.apply_all_filtering() + } + + DefaultButton + { + visible: !root.is_history + enabled: API.app.orders_mdl.length > 0 + Layout.preferredHeight: 29 + radius: 7 + label.font: DexTypo.body2 + text: qsTr("Cancel All") + iconSource: Qaterial.Icons.close + onClicked: API.app.trading_pg.orders.cancel_order(list_model_proxy.get_filtered_ids()) + } + } + + RowLayout + { + Layout.alignment: Qt.AlignHCenter + + DefaultSweetComboBox + { + id: combo_base + Layout.preferredWidth: parent.width / 2 - swapCoinFilterIcon.width + model: API.app.portfolio_pg.global_cfg_mdl.all_proxy + valueRole: "ticker" + textRole: 'ticker' + mainBackgroundColor: Dex.CurrentTheme.backgroundColor + popupBackgroundColor: Dex.CurrentTheme.backgroundColor + onCurrentTickerChanged: applyFilter() + } + + Qaterial.ColorIcon + { + id: swapCoinFilterIcon + source: Qaterial.Icons.swapHorizontal + color: Dex.CurrentTheme.foregroundColor + + DefaultMouseArea + { + id: swap_button + anchors.fill: parent + hoverEnabled: true + onClicked: + { + const base_idx = combo_base.currentTicker + combo_base.currentTicker = combo_rel.currentTicker + combo_rel.currentTicker = base_idx + } + } + } + + DefaultSweetComboBox + { + id: combo_rel + Layout.fillWidth: true + model: API.app.portfolio_pg.global_cfg_mdl.all_proxy + valueRole: "ticker" + textRole: 'ticker' + mainBackgroundColor: Dex.CurrentTheme.backgroundColor + popupBackgroundColor: Dex.CurrentTheme.backgroundColor + onCurrentTickerChanged: applyFilter() + } + } + + Row + { + Layout.fillWidth: true + DatePicker + { + id: min_date + width: parent.width * 0.45 + titleText: qsTr("From") + minimumDate: default_min_date + maximumDate: default_max_date + selectedDate: default_min_date + onAccepted: applyDateFilter() + } + + Item { width: parent.width * 0.1; height: 1 } + + DatePicker + { + id: max_date + width: parent.width * 0.45 + titleText: qsTr("To") + minimumDate: default_min_date + maximumDate: default_max_date + selectedDate: default_max_date + onAccepted: applyDateFilter() + } + } + } + + OrderList + { + id: order_list + items: list_model + is_history: root.is_history + Layout.fillHeight: true + Layout.fillWidth: true + } + } + + ModalLoader + { + id: order_modal + sourceComponent: OrderModal {} + } + + FileDialog + { + id: export_csv_dialog + + title: qsTr("Please choose the CSV export name and location") + fileMode: FileDialog.SaveFile + + defaultSuffix: "csv" + nameFilters: ["CSV files (*.csv)", "All files (*)"] + + onAccepted: { + const path = currentFile.toString() + + // Export + console.log("Exporting to CSV: " + path) + API.app.exporter_service.export_swaps_history_to_csv(path.replace(General.os_file_prefix, "")) + + // Open the save folder + const folder_path = path.substring(0, path.lastIndexOf("/")) + Qt.openUrlExternally(folder_path) + } + onRejected: { + console.log("CSV export cancelled") + } + } +} diff --git a/atomic_defi_design/Dex/Exchange/Trade/PriceLine.qml b/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/PriceLine.qml similarity index 79% rename from atomic_defi_design/Dex/Exchange/Trade/PriceLine.qml rename to atomic_defi_design/Dex/Exchange/ProView/TradingInfo/PriceLine.qml index ee566c2381..63cbdaf723 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/PriceLine.qml +++ b/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/PriceLine.qml @@ -2,8 +2,8 @@ import QtQuick 2.15 import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 -import "../../Components" -import "../../Constants" +import "../../../Components" +import "../../../Constants" import Dex.Themes 1.0 as Dex ColumnLayout @@ -12,21 +12,13 @@ ColumnLayout readonly property string price_reversed: API.app.trading_pg.price_reversed readonly property string cex_price: API.app.trading_pg.cex_price readonly property string cex_price_reversed: API.app.trading_pg.cex_price_reversed - readonly property string cex_price_diff: API.app.trading_pg.cex_price_diff + readonly property string cexPriceDiff: API.app.trading_pg.cex_price_diff readonly property bool invalid_cex_price: API.app.trading_pg.invalid_cex_price readonly property bool price_entered: !General.isZero(non_null_price) readonly property int fontSize: Style.textSizeSmall1 readonly property int fontSizeBigger: Style.textSizeSmall2 - readonly property int line_scale: getComparisonScale(cex_price_diff) - - function getComparisonScale(value) { - return Math.min(Math.pow(10, General.getDigitCount(parseFloat(value))), 1000000000) - } - - function limitDigits(value) { - return parseFloat(General.formatDouble(value, 2)) - } + readonly property int lineScale: General.getComparisonScale(cexPriceDiff) spacing: 20 @@ -80,8 +72,8 @@ ColumnLayout Layout.topMargin: 10 Layout.bottomMargin: Layout.topMargin Layout.alignment: Qt.AlignHCenter - color: parseFloat(cex_price_diff) <= 0 ? Dex.CurrentTheme.okColor : Dex.CurrentTheme.noColor - text_value: (parseFloat(cex_price_diff) > 0 ? qsTr("Expensive") : qsTr("Expedient")) + ":    " + qsTr("%1 compared to CEX", "PRICE_DIFF%").arg("" + General.formatPercent(limitDigits(cex_price_diff)) + "") + color: parseFloat(cexPriceDiff) <= 0 ? Dex.CurrentTheme.okColor : Dex.CurrentTheme.noColor + text_value: (parseFloat(cexPriceDiff) > 0 ? qsTr("Expensive") : qsTr("Expedient")) + ":    " + qsTr("%1 compared to CEX", "PRICE_DIFF%").arg("" + General.formatPercent(General.limitDigits(cexPriceDiff)) + "") font.pixelSize: fontSize } @@ -90,7 +82,7 @@ ColumnLayout Layout.alignment: Qt.AlignHCenter DefaultText { - text_value: General.formatPercent(line_scale) + text_value: General.formatPercent(lineScale) font.pixelSize: fontSize } @@ -107,13 +99,13 @@ ColumnLayout height: parent.height * 2 anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter - anchors.horizontalCenterOffset: 0.5 * parent.width * Math.min(Math.max(parseFloat(cex_price_diff) / line_scale, -1), 1) + anchors.horizontalCenterOffset: 0.5 * parent.width * Math.min(Math.max(parseFloat(cexPriceDiff) / lineScale, -1), 1) } } DefaultText { - text_value: General.formatPercent(-line_scale) + text_value: General.formatPercent(-lineScale) font.pixelSize: fontSize } } @@ -129,8 +121,7 @@ ColumnLayout Layout.alignment: Qt.AlignHCenter text_value: General.cex_icon + " " + qsTr("CEXchange rate") font.pixelSize: fontSize - - CexInfoTrigger {} + DefaultInfoTrigger { triggerModal: cex_info_modal } } // Price reversed diff --git a/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/SwapProgress.qml b/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/SwapProgress.qml new file mode 100644 index 0000000000..ad019be3da --- /dev/null +++ b/atomic_defi_design/Dex/Exchange/ProView/TradingInfo/SwapProgress.qml @@ -0,0 +1,312 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 + +import Dex.Themes 1.0 as Dex +import App 1.0 + +import "../../../Components" +import "../../../Constants" + +// Content +ColumnLayout +{ + id: root + + property var details + property var lastEvent + + readonly property var all_events: !details + ? [] : has_error_event + ? details.events.map(e => e.state) : details.success_events + + // Is there error in swap json? + readonly property bool has_error_event: + { + if (!details) return false + + const events = details.events + + for (let i = events.length - 1; i >= 0; --i) + if (details.error_events.indexOf(events[i].state) !== -1) + return true + + return false + } + + // Total swaptime from sum of events duration + readonly property double totalTimePassed: + { + if (!details) return 0 + + const events = details.events + + let sum = 0 + for (let i = 0; i < events.length; ++i) + sum += events[i].time_diff + + return sum + } + + + // Total swap duration estimate + readonly property double totalTimePassedEstimated: + { + const events = all_events + + let sum = 0 + for (let i = 0; i < events.length; ++i) + sum += API.app.orders_mdl.average_events_time_registry[events[i]] + + return sum + } + + // Current Event index + readonly property int current_event_idx: + { + if (!details) return -1 + const events = details.events + if (events.length === 0) return -1 + if (all_events.length === 0) return -1 + + const last_state = events[events.length - 1].state + if (last_state === "Finished") return -1 + + const idx = all_events.indexOf(last_state) + if (idx === -1) return -1 + + return idx + 1 + } + + // Simulated time of the running event + property double simulatedTime: 0 + function updateSimulatedTime() + { + if (!details) + { + simulatedTime = 0 + return + } + + const events = details.events + if (!events || events.length === 0) + { + simulatedTime = 0 + return + } + + lastEvent = events[events.length - 1] + if (!lastEvent.timestamp) + { + simulatedTime = 0 + return + } + + if (current_event_idx !== -1) + { + const diff = Date.now() - lastEvent.timestamp + simulatedTime = diff - (diff % 1000) + + } else simulatedTime = 0 + } + + Timer + { + running: current_event_idx !== -1 + interval: 1000 + repeat: true + onTriggered: updateSimulatedTime() + } + + // Simulated countdown time until refund unlocked + property double paymentLockCountdownTime: -1 // First we wait for locktime expiry + property double waitUntilCountdownTime: -1 // Then we count down to 'wait_until' time + function updateCountdownTime() + { + if (current_event_idx == -1 || !details) + { + paymentLockCountdownTime = -1 + return + } + + const events = details.events + + if (events[current_event_idx - 1].hasOwnProperty('data')) + { + if (events[current_event_idx - 1]['data'].hasOwnProperty('wait_until')) + { + const diff = events[current_event_idx - 1]['data']['wait_until'] * 1000 - Date.now() + waitUntilCountdownTime = diff - (diff % 1000) + + if (waitUntilCountdownTime <= 0) + { + waitUntilCountdownTime = 0 + } + } + } + + else + { + waitUntilCountdownTime = -1 + } + + if (details.hasOwnProperty('paymentLock')) + { + const lock_diff = details.paymentLock - Date.now() + paymentLockCountdownTime = lock_diff - (lock_diff % 1000) + + if (paymentLockCountdownTime <= 0) + { + paymentLockCountdownTime = 0 + } + } + + else + { + paymentLockCountdownTime = -1 + } + } + + Timer + { + running: !has_error_event ? false : details.events[details.events.length - 1].state == "Finished" ? false : true + interval: 1000 + repeat: true + onTriggered: updateCountdownTime() + } + + function getTimeText(duration, estimated) + { + return `` + qsTr("act", "SHORT FOR ACTUAL TIME") + ": " + `` + + `` + General.durationTextShort(duration) + `` + + ` | ` + qsTr("est", "SHORT FOR ESTIMATED") + ": " + + General.durationTextShort(estimated) + `` + } + + function getRefundText() + { + if ((paymentLockCountdownTime > 0) && (waitUntilCountdownTime == -1)) + { + return `` + qsTr(General.durationTextShort(paymentLockCountdownTime) + " until refund lock is released.") + `` + } + else if (waitUntilCountdownTime > 0) { + if (lastEvent.state !== "Finished") { + return `` + qsTr(General.durationTextShort(waitUntilCountdownTime) + " until refund completed.") + `` + } + } + return "" + } + + // Title + DefaultText + { + Layout.fillWidth: true + text_value: `` + qsTr("Progress details") + `` + + ` | ` + + getTimeText(totalTimePassed + simulatedTime, totalTimePassedEstimated) + font.pixelSize: Style.textSize1 + Layout.bottomMargin: 10 + } + + Repeater + { + Layout.fillHeight: true + model: all_events + + delegate: Item + { + readonly property + var event: + { + if (!details) return undefined + const idx = details.events.map(e => e.state).indexOf(modelData) + if (idx === -1) return undefined + + return details.events[idx] + } + + readonly property bool is_current_event: index === current_event_idx + + readonly property bool is_active: General.exists(event) || is_current_event + + readonly property double time_passed: event ? event.time_diff : is_current_event ? simulatedTime : 0 + + width: root.width + height: 50 + + DefaultText { + id: icon + + text_value: is_active ? "●" : "○" + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.verticalCenter: col_layout.verticalCenter + + color: + { + // Already exists, completed event + if (event) + { + // Red for the Finished if swap failed + if (event.state === "Finished" && details.order_status === "failed") return Dex.CurrentTheme.noColor + + // Red for error event, green for the others + return details.error_events.indexOf(event.state) === -1 ? Dex.CurrentTheme.okColor : Dex.CurrentTheme.noColor + } + + // In progress one is orange + if (is_current_event) + return Style.colorOrange + + // Passive color for the rest + return Dex.CurrentTheme.foregroundColor3 + } + } + + ColumnLayout + { + id: col_layout + + anchors.left: icon.right + anchors.leftMargin: icon.anchors.leftMargin + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + + DefaultText + { + id: name + + font.pixelSize: Style.textSizeSmall4 + + text_value: getEventText(modelData) + color: event ? Dex.CurrentTheme.foregroundColor : is_current_event ? Dex.CurrentTheme.foregroundColor : Dex.CurrentTheme.foregroundColor3 + } + + AnimatedRectangle + { + id: bar + visible: is_active + width: parent.width + height: 2 + + color: Dex.CurrentTheme.foregroundColor2 + + AnimatedRectangle + { + width: parent.width * (totalTimePassed > 0 ? (time_passed / (totalTimePassed + simulatedTime)) : 0) + height: parent.height + color: Dex.CurrentTheme.okColor + } + } + + DefaultText + { + visible: bar.visible + font.pixelSize: Style.textSizeSmall2 + + text_value: !is_active ? '' : getTimeText(time_passed, API.app.orders_mdl.average_events_time_registry[modelData]) + } + } + } + } +} \ No newline at end of file diff --git a/atomic_defi_design/Dex/Exchange/Trade/BestOrder/Header.qml b/atomic_defi_design/Dex/Exchange/Trade/BestOrder/Header.qml index e3d4890f47..6582c909a7 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/BestOrder/Header.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/BestOrder/Header.qml @@ -3,55 +3,53 @@ import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 import Qaterial 1.0 as Qaterial - import App 1.0 - import "../../../Components" +import Dex.Components 1.0 as Dex -Item { - property bool is_horizontal: false - height: 40 +RowLayout +{ + height: 24 width: parent.width - z: 2 + spacing: 0 - RowLayout + Dex.Text { - width: parent.width - 30 - height: parent.height - anchors.horizontalCenter: parent.horizontalCenter - DefaultText - { - Layout.alignment: Qt.AlignVCenter - Layout.preferredWidth: 130 - text: sell_mode? qsTr("You get") : qsTr("You send") - font.family: Style.font_family - font.pixelSize: 12 - font.bold: true - font.weight: Font.Black - } - DefaultText - { - Layout.alignment: Qt.AlignVCenter - Layout.preferredWidth: 70 + Layout.preferredWidth: 140 + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text_value: sell_mode ? qsTr("You get") : qsTr("You send") + font.family: Style.font_family + font.bold: true + font.pixelSize: 12 + font.weight: Font.Black + } - text: qsTr("Fiat Price") - font.family: Style.font_family - font.pixelSize: 12 - font.bold: true - font.weight: Font.Black - horizontalAlignment: Label.AlignRight + Item { Layout.preferredWidth: (parent.width - 300) / 2 } - } - DefaultText - { - Layout.alignment: Qt.AlignVCenter - text: qsTr("CEX rate") - horizontalAlignment: Label.AlignRight - font.family: Style.font_family - font.pixelSize: 12 - font.bold: true - font.weight: Font.Black - } + Dex.Text + { + Layout.preferredWidth: 80 + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignRight + text_value: qsTr("Fiat Price") + font.family: Style.font_family + font.bold: true + font.pixelSize: 12 + font.weight: Font.Black } + Item { Layout.preferredWidth: (parent.width - 300) / 2 } + + Dex.Text + { + Layout.preferredWidth: 80 + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignRight + text_value: qsTr("CEX rate") + font.family: Style.font_family + font.bold: true + font.pixelSize: 12 + font.weight: Font.Black + } } diff --git a/atomic_defi_design/Dex/Exchange/Trade/BestOrder/List.qml b/atomic_defi_design/Dex/Exchange/Trade/BestOrder/List.qml index db66934273..695385521e 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/BestOrder/List.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/BestOrder/List.qml @@ -4,20 +4,62 @@ import QtQuick.Controls 2.15 import Qaterial 1.0 as Qaterial -import App 1.0 +import "../../../Constants" +import "../../../Components" +import App 1.0 as App +import AtomicDEX.MarketMode 1.0 +import Dex.Themes 1.0 as Dex +import Dex.Components 1.0 as Dex - -Item { +Widget +{ id: _control - Header {} + title: qsTr("Best Orders") + margins: 20 + spacing: 20 + + Header + { + visible: !warning_text.visible + } + + Item + { + id: warning_text + visible: API.app.trading_pg.volume == 0 + Layout.preferredWidth: parent.width + Layout.preferredHeight: parent.height + + DefaultText + { + text_value: qsTr("Enter volume to see best orders.") + anchors.fill: parent + anchors.centerIn: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.pixelSize: Style.textSizeSmall4 + color: Dex.CurrentTheme.foregroundColor2 + } + } + + Dex.ListView + { + id: _listView + Layout.fillWidth: true + Layout.fillHeight: true + visible: !warning_text.visible + spacing: 6 - ListView { - id: list - anchors.topMargin: 40 - anchors.fill: parent model: API.app.trading_pg.orderbook.best_orders.proxy_mdl + clip: true reuseItems: true - delegate: ListDelegate {} + scrollbar_visible: false + + delegate: ListDelegate + { + width: _listView.width + height: 30 + } } } diff --git a/atomic_defi_design/Dex/Exchange/Trade/BestOrder/ListDelegate.qml b/atomic_defi_design/Dex/Exchange/Trade/BestOrder/ListDelegate.qml index 073030ba62..a1189a5540 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/BestOrder/ListDelegate.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/BestOrder/ListDelegate.qml @@ -2,161 +2,184 @@ import QtQuick 2.15 import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 - import Qaterial 1.0 as Qaterial import "../../../Components" -import "../../../Constants" as Constants - +import "../../../Constants" import App 1.0 as App +import Dex.Themes 1.0 as Dex +import Dex.Components 1.0 as Dex +import AtomicDEX.MarketMode 1.0 -Item { +Item +{ id: _control - property bool coinEnable: Constants.API.app.portfolio_pg.global_cfg_mdl.get_coin_info(coin).is_enabled - property var isAsk: { - if(parseInt(cex_rates)>0){ - false - }else if(parseInt(cex_rates)<0) { - true - }else { - undefined - } - } - width: visible? list.width : 0 - height: 36 + property bool coinEnable: API.app.portfolio_pg.global_cfg_mdl.get_coin_info(coin).is_enabled + property bool isAsk - AnimatedRectangle { + AnimatedRectangle + { visible: mouse_are.containsMouse width: parent.width height: parent.height - color: App.DexTheme.foregroundColor + color: Dex.CurrentTheme.foregroundColor opacity: 0.1 } - RowLayout { + RowLayout + { id: row - width: parent.width - 30 + width: parent.width height: parent.height - anchors.horizontalCenter: parent.horizontalCenter - spacing: 10 - Row { - Layout.alignment: Qt.AlignVCenter - Layout.preferredWidth: 130 - leftPadding: -10 - spacing: 5 - DefaultImage { - source: Constants.General.coinIcon(coin) - width: 20 - height: 20 - smooth: true - antialiasing: true - opacity: !_control.coinEnable? .1 : 1 + spacing: 0 + + Item + { + Layout.fillHeight: true + Layout.preferredWidth: 140 + + DexImage + { + id: asset_image + width: 24 + height: 24 anchors.verticalCenter: parent.verticalCenter + source: General.coinIcon(coin) + opacity: !_control.coinEnable? .1 : 1 } - DefaultText { - anchors.verticalCenter: parent.verticalCenter - leftPadding: 2 - text: send + " " + atomic_qt_utilities.retrieve_main_ticker(coin) + + Dex.Text + { + anchors.top: parent.top + anchors.left: asset_image.right + horizontalAlignment: Text.AlignLeft + anchors.leftMargin: 5 + text: send font.family: App.DexTypo.fontFamily font.pixelSize: 12 - } - } - DefaultTooltip { - id: _tooltip - dim: true - modal: true - closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside - - width: 250 - contentItem: DexLabelUnlinked { - text_value: qsTr(" %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?
Yes - No").arg(coin).arg(coin) - wrapMode: DefaultText.Wrap - width: 250 - onLinkActivated: { - if(link==="#no") { - _tooltip.close() - }else { - if (Constants.API.app.enable_coins([coin]) === true) { - _control.coinEnable = true - _tooltip.close() - } - else { - cannot_enable_coin_modal.open() - } - } - } - ModalLoader { - property string coin_to_enable_ticker: coin - id: cannot_enable_coin_modal - sourceComponent: CannotEnableCoinModal { coin_to_enable_ticker: cannot_enable_coin_modal.coin_to_enable_ticker } - } + Dex.Text + { + anchors.bottom: parent.bottom + anchors.left: asset_image.right + horizontalAlignment: Text.AlignLeft + anchors.leftMargin: 5 + text: coin + font.family: App.DexTypo.fontFamily + font.pixelSize: 12 } - delay: 200 } - DexLabel { - Layout.alignment: Qt.AlignVCenter - Layout.preferredWidth: 70 - text: price_fiat + Constants.API.app.settings_pg.current_fiat_sign + Item { Layout.preferredWidth: (parent.width - 300) / 2 } + + Dex.Text + { + Layout.preferredWidth: 80 + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + text: price_fiat + API.app.settings_pg.current_fiat_sign font.family: App.DexTypo.fontFamily font.pixelSize: 12 - horizontalAlignment: Label.AlignRight - opacity: 1 - } - DexLabel { - Layout.alignment: Qt.AlignVCenter - - text: cex_rates==="0"? "N/A" : parseFloat(cex_rates)>0? "+"+parseFloat(cex_rates).toFixed(2)+"%" : parseFloat(cex_rates).toFixed(2)+"%" + + Item { Layout.preferredWidth: (parent.width - 300) / 2 } + + Dex.Text + { + Layout.preferredWidth: 80 + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + wrapMode: Text.NoWrap font.family: App.DexTypo.fontFamily font.pixelSize: 12 - Behavior on rightPadding { - NumberAnimation { + text: cex_rates === "0" ? "N/A" : + parseFloat(cex_rates) > 0 ? "+" + parseFloat(cex_rates).toFixed(2) + "%" : + parseFloat(cex_rates).toFixed(2) + "%" + color: cex_rates === "0" ? Qt.darker(Dex.CurrentTheme.foregroundColor) : + parseFloat(cex_rates) < 0 ? Dex.CurrentTheme.okColor : + Dex.CurrentTheme.noColor + + Behavior on rightPadding + { + NumberAnimation + { duration: 150 } } + } + } - color:cex_rates==="0"? Qt.darker(App.DexTheme.foregroundColor) : parseFloat(cex_rates)<0? App.DexTheme.greenColor : App.DexTheme.redColor - horizontalAlignment: Label.AlignRight - opacity: 1 + DefaultTooltip + { + id: _tooltip + dim: true + modal: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + width: 250 + + contentItem: DexLabelUnlinked + { + text_value: !General.isZhtlc(coin) ? + qsTr(" %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?
Yes - No").arg(coin).arg(coin) : + qsTr(" %1 is not enabled - Please enable it through the coin activation menu").arg(coin) + wrapMode: DefaultText.Wrap + width: 250 + onLinkActivated: + { + if (link === "#no") + { + _tooltip.close(); + } + else + { + if (API.app.enable_coins([coin]) === true) + { + _control.coinEnable = true; + _tooltip.close(); + } + else { + cannot_enable_coin_modal.open(); + } + } + } + ModalLoader { + property string coin_to_enable_ticker: coin + id: cannot_enable_coin_modal + sourceComponent: CannotEnableCoinModal { coin_to_enable_ticker: cannot_enable_coin_modal.coin_to_enable_ticker } + } } + delay: 200 } - - DefaultMouseArea { + DefaultMouseArea + { id: mouse_are anchors.fill: parent hoverEnabled: true - onClicked: { - console.log(order_form.visible) - if(!Constants.API.app.portfolio_pg.global_cfg_mdl.get_coin_info(coin).is_enabled){ + + onClicked: + { + if (!API.app.portfolio_pg.global_cfg_mdl.get_coin_info(coin).is_enabled) + { _tooltip.open() - }else { - app.pairChanged(base_ticker, coin) - Constants.API.app.trading_pg.orderbook.select_best_order(uuid) - if(order_form.visible === false) { - order_form.visible = true + } + else + { + placeOrderForm.visible = General.flipFalse(placeOrderForm.visible) + if (API.app.trading_pg.market_mode == MarketMode.Buy) + { + app.pairChanged(coin, rel_ticker) } - if(order_form.hidden === true) { - order_form.hidden = false - if(order_form.contentVisible === false) { - order_form.contentVisible = true - } + else + { + app.pairChanged(base_ticker, coin) } + API.app.trading_pg.orderbook.select_best_order(uuid) } - - //if(is_mine) return - //isAsk? selectOrder(true, coin, price, quantity, price_denom, price_numer, quantity_denom, quantity_numer, min_volume) : selectOrder(false, coin, price, quantity, price_denom, price_numer, quantity_denom, quantity_numer, min_volume) } } - HorizontalLine { - width: parent.width - opacity: .4 - } - } diff --git a/atomic_defi_design/Dex/Exchange/Trade/CandleStickChart.qml b/atomic_defi_design/Dex/Exchange/Trade/CandleStickChart.qml deleted file mode 100644 index 185906b2fa..0000000000 --- a/atomic_defi_design/Dex/Exchange/Trade/CandleStickChart.qml +++ /dev/null @@ -1,143 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 - -import QtCharts 2.3 -import QtWebEngine 1.8 - -import "../../Components" - -import App 1.0 -import Dex.Themes 1.0 as Dex - -// List - -DexBox { - id: graph_bg - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - - - content: Item { - id: root - - width: graph_bg.width - height: graph_bg.height - - property bool pair_supported: false - readonly property bool is_fetching: dashboard.webEngineView.loadProgress < 100 - - onIs_fetchingChanged: dashboard.webEngineView.visible = !is_fetching && pair_supported - - RowLayout { - visible: pair_supported && !dashboard.webEngineView.visible - anchors.centerIn: parent - - DefaultBusyIndicator { - Layout.alignment: Qt.AlignHCenter - Layout.leftMargin: -15 - Layout.rightMargin: Layout.leftMargin*0.75 - scale: 0.5 - } - - DefaultText { - text_value: qsTr("Loading market data") + "..." - } - } - - DefaultText { - visible: !pair_supported - onVisibleChanged: if(visible) { - dex_chart.visible = false - } - text_value: qsTr("There is no chart data for this pair yet") - anchors.centerIn: parent - } - - Component.onCompleted: try{loadChart(left_ticker?? atomic_app_primary_coin, right_ticker?? atomic_app_secondary_coin)}catch(e){} - - Connections { - target: app - function onPairChanged(base, rel) { - root.loadChart(base, rel) - } - } - - readonly property string theme: Dex.CurrentTheme.getColorMode() === Dex.CurrentTheme.ColorMode.Dark ? "dark" : "light" - - Connections - { - target: Dex.CurrentTheme - function onThemeChanged() - { - loadChart(left_ticker?? atomic_app_primary_coin, right_ticker?? atomic_app_secondary_coin, true) - } - } - - property string chart_base - property string chart_rel - property string loaded_symbol - function loadChart(base, rel, force=false) { - const pair = atomic_qt_utilities.retrieve_main_ticker(base) + "/" + atomic_qt_utilities.retrieve_main_ticker(rel) - const pair_reversed = atomic_qt_utilities.retrieve_main_ticker(rel) + "/" + atomic_qt_utilities.retrieve_main_ticker(base) - - console.log("Will try to load TradingView chart", pair) - - // Normal pair - let symbol = General.supported_pairs[pair] - if(!symbol) { - console.log("Symbol not found for", pair) - symbol = General.supported_pairs[pair_reversed] - } - - // Reversed pair - if(!symbol) { - console.log("Symbol not found for", pair_reversed) - pair_supported = false - return - } - - pair_supported = true - - // Load HTML - if(!force && symbol === loaded_symbol) { - console.log("Chart is already loaded,", symbol) - return - } - - loaded_symbol = symbol - console.log("Loading TradingView chart", symbol, " theme: ", theme) - - chart_base = atomic_qt_utilities.retrieve_main_ticker(base) - chart_rel = atomic_qt_utilities.retrieve_main_ticker(rel) - - dashboard.webEngineView.loadHtml(` - - - -
-
- - -
- `); - } - } -} diff --git a/atomic_defi_design/Dex/Exchange/Trade/ConfirmTradeModal.qml b/atomic_defi_design/Dex/Exchange/Trade/ConfirmTradeModal.qml index f315edd17f..8a4f6bf1ea 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/ConfirmTradeModal.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/ConfirmTradeModal.qml @@ -1,6 +1,7 @@ import QtQuick 2.15 import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 +import Qaterial 1.0 as Qaterial import AtomicDEX.TradingError 1.0 import "../../Components" @@ -10,276 +11,406 @@ import "Orders/" import App 1.0 import Dex.Themes 1.0 as Dex + MultipageModal { id: root - - width: 650 - readonly property var fees: API.app.trading_pg.fees + width: 720 + horizontalPadding: 30 + verticalPadding: 30 + closePolicy: Popup.NoAutoClose MultipageModalContent { titleText: qsTr("Confirm Exchange Details") - - OrderContent - { - Layout.fillWidth: true - details: - ({ - base_coin: base_ticker, - rel_coin: rel_ticker, - base_amount: base_amount, - rel_amount: rel_amount, - order_id: '', - date: '', - }) - } - - PriceLineSimplified { Layout.fillWidth: true } - - HorizontalLine - { - Layout.fillWidth: true - } - - ColumnLayout - { - Layout.fillWidth: true - - DefaultText + title.font.pixelSize: Style.textSize2 + titleAlignment: Qt.AlignHCenter + titleTopMargin: 0 + topMarginAfterTitle: 10 + flickMax: window.height - 480 + + header: [ + RowLayout { - Layout.alignment: Qt.AlignLeft - text_value: qsTr("This swap request can not be undone and is a final event!") - } + id: dex_pair_badges - DefaultText - { - Layout.alignment: Qt.AlignLeft - text_value: qsTr("This transaction can take up to 60 mins - DO NOT close this application!") - font.pixelSize: Style.textSizeSmall4 - } - } - - Item - { - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - Layout.preferredHeight: fees_detail.height + 10 - opacity: .7 - Column - { - id: fees_detail - anchors.verticalCenter: parent.verticalCenter - visible: fees.base_transaction_fees_ticker && !API.app.trading_pg.preimage_rpc_busy - - Repeater - { - model: fees.base_transaction_fees_ticker && !API.app.trading_pg.preimage_rpc_busy ? General.getFeesDetail(fees) : [] - delegate: DefaultText - { - font.pixelSize: Style.textSizeSmall1 - text: General.getFeesDetailText(modelData.label, modelData.fee, modelData.ticker) - } - anchors.horizontalCenter: parent.horizontalCenter - } - Item {width: 1; height: 10} - Repeater + PairItemBadge { - model: fees.base_transaction_fees_ticker ? fees.total_fees : [] - delegate: DefaultText - { - text: General.getFeesDetailText( - qsTr("Total %1 fees:").arg(modelData.coin), - modelData.required_balance, - modelData.coin) - } - anchors.horizontalCenter: parent.horizontalCenter + ticker: base_ticker + fullname: General.coinName(base_ticker) + amount: base_amount } - Item {width: 1; height: 10} - } - DefaultText - { - id: errors - anchors.horizontalCenter: parent.horizontalCenter - width: parent.width - horizontalAlignment: DefaultText.AlignHCenter - font: DexTypo.caption - color: Dex.CurrentTheme.noColor - text_value: General.getTradingError( - last_trading_error, - curr_fee_info, - base_ticker, - rel_ticker, left_ticker, right_ticker) - } - } - ColumnLayout - { - id: config_section + Qaterial.Icon + { + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter - readonly property var default_config: API.app.trading_pg.get_raw_mm2_coin_cfg(rel_ticker) + color: Dex.CurrentTheme.foregroundColor + icon: Qaterial.Icons.swapHorizontal + } - readonly property bool is_dpow_configurable: config_section.default_config.requires_notarization || false + PairItemBadge + { + ticker: rel_ticker + fullname: General.coinName(rel_ticker) + amount: rel_amount + } + }, - Layout.bottomMargin: 10 - Layout.alignment: Qt.AlignHCenter + PriceLineSimplified + { + id: price_line + Layout.fillWidth: true + }, ColumnLayout { + id: warnings_text + Layout.fillWidth: true Layout.alignment: Qt.AlignHCenter - visible: !enable_custom_config.checked - DefaultText + // Large margin warning + FloatingBackground { - Layout.alignment: Qt.AlignHCenter - text_value: qsTr("Security configuration") - font.weight: Font.Medium + Layout.alignment: Qt.AlignCenter + width: childrenRect.width + height: childrenRect.height + color: Style.colorRed2 + visible: Math.abs(parseFloat(API.app.trading_pg.cex_price_diff)) >= 50 + + RowLayout + { + Layout.fillWidth: true + + Item { width: 3 } + + DefaultCheckBox + { + id: allow_bad_trade + Layout.alignment: Qt.AlignCenter + textColor: Style.colorWhite0 + visible: Math.abs(parseFloat(API.app.trading_pg.cex_price_diff)) >= 50 + spacing: 2 + boxWidth: 16 + boxHeight: 16 + label.wrapMode: Label.NoWrap + text: qsTr("Trade price is more than 50% different to CEX! Confirm?") + font: DexTypo.caption + } + } } DefaultText { Layout.alignment: Qt.AlignHCenter - text_value: "✅ " + (config_section.is_dpow_configurable ? qsTr("dPoW protected") : - qsTr("%1 confirmations for incoming %2 transactions").arg(config_section.default_config.required_confirmations || 1).arg(rel_ticker)) + text_value: qsTr("This swap request can not be undone and is a final event!") } DefaultText { - visible: config_section.is_dpow_configurable + id: warnings_tx_time_text Layout.alignment: Qt.AlignHCenter - text_value: General.cex_icon + ' ' + qsTr('Read more about dPoW') + '' - font.pixelSize: Style.textSizeSmall2 + text_value: qsTr("This transaction can take up to 60 mins - DO NOT close this application!") + font.pixelSize: Style.textSizeSmall4 } } + ] - // Enable custom config - DexCheckBox - { - Layout.alignment: Qt.AlignHCenter - Layout.fillWidth: true - Layout.maximumWidth: config_section.width + ColumnLayout + { + id: config_section - id: enable_custom_config + readonly property var default_config: API.app.trading_pg.get_raw_mm2_coin_cfg(rel_ticker) + readonly property bool is_dpow_configurable: config_section.default_config.requires_notarization || false - spacing: 2 - text: qsTr("Use custom protection settings for incoming %1 transactions", "TICKER").arg(rel_ticker) - boxWidth: 24 - boxHeight: 24 - label.horizontalAlignment: Text.AlignHCenter - } + width: dex_pair_badges.width - 20 + Layout.alignment: Qt.AlignCenter + Layout.topMargin: 8 - // Configuration settings - ColumnLayout - { - id: custom_config - visible: enable_custom_config.checked + spacing: 5 - Layout.alignment: Qt.AlignHCenter + // Fees Area + DefaultRectangle { + Layout.alignment: Qt.AlignCenter + Layout.preferredHeight: 150 + Layout.preferredWidth: parent.width - 40 + color: DexTheme.contentColorTop + visible: !buy_sell_rpc_busy - // dPoW configuration switch - DefaultSwitch + ColumnLayout { - id: enable_dpow_confs - Layout.alignment: Qt.AlignHCenter + anchors.centerIn: parent + visible: !fees_detail.visible - visible: config_section.is_dpow_configurable - checked: true - text: qsTr("Enable Komodo dPoW security") + DefaultBusyIndicator + { + Layout.preferredHeight: 100 + Layout.preferredWidth: 100 + Layout.alignment: Qt.AlignHCenter + Layout.leftMargin: -15 + Layout.rightMargin: Layout.leftMargin * 0.75 + scale: 0.8 + } + + DefaultText + { + text_value: qsTr("Loading fees...") + Layout.bottomMargin: 8 + } } - DefaultText + ColumnLayout { - visible: enable_dpow_confs.visible && enable_dpow_confs.enabled - Layout.alignment: Qt.AlignHCenter - text_value: General.cex_icon + ' ' + qsTr('Read more about dPoW') + '' - font.pixelSize: Style.textSizeSmall2 + id: fees_error + width: parent.width - 20 + anchors.centerIn: parent + visible: root.fees.hasOwnProperty('error') // Should be handled before this modal, but leaving here as a fallback + + DefaultText + { + width: parent.width + text_value: root.fees.hasOwnProperty('error') ? root.fees["error"].split("] ").slice(-1) : "" + Layout.bottomMargin: 8 + } } - // Normal configuration settings ColumnLayout { - Layout.alignment: Qt.AlignHCenter - visible: !config_section.is_dpow_configurable || !enable_dpow_confs.checked - enabled: !config_section.is_dpow_configurable || !enable_dpow_confs.checked + id: fees_detail + width: parent.width - 20 + anchors.centerIn: parent + spacing: 6 + visible: root.fees.hasOwnProperty('base_transaction_fees_ticker') && !API.app.trading_pg.preimage_rpc_busy - HorizontalLine + Repeater { - Layout.topMargin: 10 - Layout.bottomMargin: 10 - Layout.fillWidth: true + model: root.fees.hasOwnProperty('base_transaction_fees_ticker') && !API.app.trading_pg.preimage_rpc_busy ? General.getFeesDetail(root.fees) : [] + delegate: DefaultText + { + font.pixelSize: Style.textSizeSmall1 + text: General.getFeesDetailText(modelData.label, modelData.fee, modelData.ticker) + } } - DefaultText + Repeater { - Layout.preferredHeight: 10 + model: root.fees.hasOwnProperty('base_transaction_fees_ticker') && !API.app.trading_pg.preimage_rpc_busy ? root.fees.total_fees : [] + delegate: DefaultText + { + text: General.getFeesDetailText( + qsTr("Total %1 fees:").arg(modelData.coin), + modelData.required_balance, + modelData.coin) + } Layout.alignment: Qt.AlignHCenter - text_value: qsTr("Required Confirmations") + ": " + required_confirmation_count.value - color: DexTheme.foregroundColor - opacity: parent.enabled ? 1 : .6 } - DexSlider + DefaultText { - id: required_confirmation_count - readonly property int default_confirmation_count: 3 + id: errors + visible: text_value != '' Layout.alignment: Qt.AlignHCenter - stepSize: 1 - from: 1 - to: 5 - live: true - snapMode: Slider.SnapAlways - value: default_confirmation_count + width: parent.width + horizontalAlignment: DefaultText.AlignHCenter + font: DexTypo.caption + color: Dex.CurrentTheme.noColor + text_value: General.getTradingError( + last_trading_error, + curr_fee_info, + base_ticker, + rel_ticker, left_ticker, right_ticker) } + } } - FloatingBackground + // Custom config checkbox + Item { - visible: enable_custom_config.visible && enable_custom_config.enabled && enable_custom_config.checked && - (config_section.is_dpow_configurable && !enable_dpow_confs.checked) - Layout.alignment: Qt.AlignHCenter - Layout.bottomMargin: 10 + Layout.alignment: Qt.AlignCenter + Layout.preferredWidth: parent.width - 10 + height: childrenRect.height + visible: !buy_sell_rpc_busy - color: Style.colorRed2 + ColumnLayout + { + id: use_custom + anchors.horizontalCenter: parent.horizontalCenter + + spacing: 5 - width: dpow_off_warning.width + 20 - height: dpow_off_warning.height + 20 + DefaultCheckBox + { + id: enable_custom_config + Layout.alignment: Qt.AlignCenter + spacing: 2 + boxWidth: 20 + boxHeight: 20 + height: 50 + label.wrapMode: Label.NoWrap + + text: qsTr("Use custom protection settings for incoming %1 transactions", "TICKER").arg(rel_ticker) + } + + DefaultSwitch + { + id: enable_dpow_confs + visible: enable_custom_config.checked && config_section.is_dpow_configurable + checked: true + Layout.preferredWidth: 260 + Layout.alignment: Qt.AlignCenter + mouseArea.hoverEnabled: true + labelWidth: 200 + label.wrapMode: Label.NoWrap + label.text: qsTr("Enable Komodo dPoW security") + label2.text: General.cex_icon + ' ' + qsTr('Read more about dPoW') + '' + } + + ColumnLayout + { + height: 50 + Layout.alignment: Qt.AlignCenter + spacing: 5 + + DefaultText + { + height: 16 + Layout.alignment: Qt.AlignCenter + visible: !enable_custom_config.checked + text_value: qsTr("Security configuration") + font.weight: Font.Medium + } + + DefaultText + { + height: 12 + font: DexTypo.caption + Layout.alignment: Qt.AlignCenter + horizontalAlignment: Text.AlignHCenter + visible: !enable_custom_config.checked + text_value: "✅ " + ( + config_section.is_dpow_configurable + ? '' + + qsTr("dPoW protected ") + General.cex_icon + '' + : qsTr("%1 confirmations for incoming %2 transactions") + .arg(config_section.default_config.required_confirmations || 1).arg(rel_ticker) + ) + } + } + } + } + + // Configuration settings + Item + { + Layout.alignment: Qt.AlignCenter + Layout.preferredWidth: parent.width - 10 + Layout.preferredHeight: 90 + height: childrenRect.height + visible: !buy_sell_rpc_busy ColumnLayout { - id: dpow_off_warning - anchors.centerIn: parent + id: security_config + anchors.horizontalCenter: parent.horizontalCenter + height: 60 + spacing: 3 - DefaultText + ColumnLayout { - Layout.alignment: Qt.AlignHCenter - text_value: Style.warningCharacter + " " + qsTr("Warning, this atomic swap is not dPoW protected!") + Layout.alignment: Qt.AlignCenter + spacing: 3 + + DefaultText + { + height: 30 + Layout.alignment: Qt.AlignCenter + horizontalAlignment: Text.AlignHCenter + visible: required_confirmation_count.visible + text_value: qsTr("Required Confirmations") + ": " + required_confirmation_count.value + color: Dex.CurrentTheme.foregroundColor + opacity: parent.enabled ? 1 : .6 + } + + DefaultSlider + { + id: required_confirmation_count + height: 24 + + Layout.alignment: Qt.AlignCenter + + visible: enable_custom_config.checked && (!config_section.is_dpow_configurable || !enable_dpow_confs.checked) + readonly property int default_confirmation_count: 3 + stepSize: 1 + from: 1 + to: 5 + live: true + snapMode: Slider.SnapAlways + value: default_confirmation_count + } + } + + // No dPoW Warning + FloatingBackground + { + Layout.alignment: Qt.AlignCenter + width: dpow_off_warning.implicitWidth + 30 + height: dpow_off_warning.implicitHeight + 10 + color: Style.colorRed2 + visible: { + enable_custom_config.checked && (config_section.is_dpow_configurable && !enable_dpow_confs.checked) + } + + DefaultText + { + id: dpow_off_warning + anchors.fill: parent + font: DexTypo.body2 + color: Style.colorWhite0 + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + text_value: Style.warningCharacter + " " + qsTr("Warning, this atomic swap is not dPoW protected!") + } } } } - DefaultBusyIndicator + + Item { visible: buy_sell_rpc_busy - Layout.alignment: Qt.AlignCenter + height: config_section.height + width: config_section.width + + DefaultBusyIndicator + { + id: rpcBusyIndicator + anchors.fill: parent + anchors.centerIn: parent + } } } - HorizontalLine { Layout.fillWidth: true } - footer: [ Item { Layout.fillWidth: true }, - DexAppButton + + DefaultButton { text: qsTr("Cancel") padding: 10 leftPadding: 45 rightPadding: 45 radius: 10 - onClicked: root.close() + onClicked: { + root.close() + API.app.trading_pg.reset_fees() + } }, + Item { Layout.fillWidth: true }, + DexGradientAppButton { text: qsTr("Confirm") @@ -287,16 +418,18 @@ MultipageModal leftPadding: 45 rightPadding: 45 radius: 10 - enabled: !buy_sell_rpc_busy && last_trading_error === TradingError.None + enabled: General.is_swap_safe(allow_bad_trade) onClicked: { trade({ enable_custom_config: enable_custom_config.checked, is_dpow_configurable: config_section.is_dpow_configurable, enable_dpow_confs: enable_dpow_confs.checked, required_confirmation_count: required_confirmation_count.value, }, - config_section.default_config) + config_section.default_config) + API.app.trading_pg.reset_fees() } }, + Item { Layout.fillWidth: true } ] } diff --git a/atomic_defi_design/Dex/Exchange/Trade/DefaultSweetModal.qml b/atomic_defi_design/Dex/Exchange/Trade/DefaultSweetModal.qml deleted file mode 100644 index e0af2164c5..0000000000 --- a/atomic_defi_design/Dex/Exchange/Trade/DefaultSweetModal.qml +++ /dev/null @@ -1,34 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 - -import "../../Components" -import "../../Constants" -import ".." - -import "Orders/" - -DefaultModal { - id: root - - width: API.app.trading_pg.preimage_rpc_busy? 300 : 1100 - - onOpened: reset() - - function reset() { - API.app.trading_pg.determine_fees() - - } - Connections { - target: API.app.trading_pg - function onFeesChanged() { - console.log(JSON.stringify(API.app.trading_pg.fees)) - } - } - Connections { - target: API.app.trading_pg - function onPreImageRpcStatusChanged(){ - console.log(API.app.trading_pg.preimage_rpc_busy) - } - } -} diff --git a/atomic_defi_design/Dex/Exchange/Trade/OrderBook/Header.qml b/atomic_defi_design/Dex/Exchange/Trade/OrderBook/Header.qml index 9839e5f7cc..05fb44c836 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/OrderBook/Header.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/OrderBook/Header.qml @@ -4,46 +4,52 @@ import QtQuick.Controls 2.15 import Qaterial 1.0 as Qaterial -import App 1.0 +import "../../../Constants" +import Dex.Components 1.0 as Dex -import "../../../Components" - -Item +Row { - property bool is_ask: false - RowLayout + width: parent.width + height: 24 + spacing: 0 + + Dex.Text + { + width: parent.width * 0.31 + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignRight + text: qsTr("Price") + " (" + atomic_qt_utilities.retrieve_main_ticker(right_ticker) + ")" + font.family: DexTypo.fontFamily + font.pixelSize: 12 + font.bold: true + font.weight: Font.Black + } + + Item { width: parent.width * 0.01 } + + Dex.Text + { + width: parent.width * 0.37 + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignRight + text: qsTr("Quantity") + " (" + atomic_qt_utilities.retrieve_main_ticker(left_ticker) + ")" + font.family: DexTypo.fontFamily + font.pixelSize: 12 + font.bold: true + font.weight: Font.Black + } + + Item { width: parent.width * 0.01 } + + Dex.Text { - anchors.fill: parent - DefaultText - { - Layout.preferredWidth: (parent.width / 100) * 33 - text: is_ask ? qsTr("Price") + " (" + atomic_qt_utilities.retrieve_main_ticker(right_ticker) + ")" : - qsTr("Price") + " (" + atomic_qt_utilities.retrieve_main_ticker(right_ticker) + ")" - font.family: DexTypo.fontFamily - font.pixelSize: 12 - font.bold: true - font.weight: Font.Black - horizontalAlignment: Text.AlignRight - } - DefaultText - { - Layout.preferredWidth: (parent.width / 100) * 30 - text: qsTr("Quantity") + " (" + atomic_qt_utilities.retrieve_main_ticker(left_ticker) + ")" - font.family: DexTypo.fontFamily - font.pixelSize: 12 - font.bold: true - font.weight: Font.Black - horizontalAlignment: Text.AlignRight - } - DefaultText - { - Layout.preferredWidth: (parent.width / 100) * 30 - text: qsTr("Total") + " (" + atomic_qt_utilities.retrieve_main_ticker(right_ticker) + ")" - font.family: DexTypo.fontFamily - font.pixelSize: 12 - font.bold: true - font.weight: Font.Black - horizontalAlignment: Text.AlignRight - } + width: parent.width * 0.30 + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignRight + text: qsTr("Total") + " (" + atomic_qt_utilities.retrieve_main_ticker(right_ticker) + ")" + font.family: DexTypo.fontFamily + font.pixelSize: 12 + font.bold: true + font.weight: Font.Black } } diff --git a/atomic_defi_design/Dex/Exchange/Trade/OrderBook/Horizontal.qml b/atomic_defi_design/Dex/Exchange/Trade/OrderBook/Horizontal.qml index 4d0417fe49..e451935079 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/OrderBook/Horizontal.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/OrderBook/Horizontal.qml @@ -20,14 +20,17 @@ Item { anchors.verticalCenter: parent.verticalCenter radius: 6 color: "transparent" + RowLayout { anchors.fill: parent spacing: 0 + List { isAsk: false Layout.fillHeight: true Layout.fillWidth: true } + List { isAsk: true Layout.fillHeight: true diff --git a/atomic_defi_design/Dex/Exchange/Trade/OrderBook/List.qml b/atomic_defi_design/Dex/Exchange/Trade/OrderBook/List.qml index e5a4d45b2f..23e54d6606 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/OrderBook/List.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/OrderBook/List.qml @@ -13,28 +13,31 @@ Item property bool isAsk property bool isVertical: false + width: parent.width + height: parent.height ListView { - id: orderList - anchors.fill: parent + id: orderbook_list + width: parent.width + height: parent.height model: isAsk ? API.app.trading_pg.orderbook.asks.proxy_mdl : API.app.trading_pg.orderbook.bids.proxy_mdl clip: true reuseItems: true spacing: 8 - onContentHeightChanged : + onContentHeightChanged: { if (isVertical) _tm.start(); } delegate: Item { - width: orderList.width + width: orderbook_list.width height: 24 + ListDelegate { - anchors.centerIn: parent width: parent.width height: parent.height isAsk: _control.isAsk ? true : false @@ -47,8 +50,8 @@ Item interval: 2000 onTriggered: { - orderList.positionViewAtEnd() + orderbook_list.positionViewAtEnd() } } } -} +} \ No newline at end of file diff --git a/atomic_defi_design/Dex/Exchange/Trade/OrderBook/ListDelegate.qml b/atomic_defi_design/Dex/Exchange/Trade/OrderBook/ListDelegate.qml index bdf48a04ab..20239d25d2 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/OrderBook/ListDelegate.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/OrderBook/ListDelegate.qml @@ -7,36 +7,115 @@ import Qaterial 1.0 as Qaterial import "../../../Components" import "../../../Constants" import App 1.0 -import Dex.Themes 1.0 as Dex import bignumberjs 1.0 +import Dex.Themes 1.0 as Dex +import Dex.Components 1.0 as Dex +import AtomicDEX.MarketMode 1.0 +import AtomicDEX.TradingError 1.0 + Item { property bool isAsk + DefaultTooltip + { + visible: mouse_area.containsMouse && (tooltip_text.text_value != "") + width: 300 + + contentItem: RowLayout + { + width: 290 + + Qaterial.ColorIcon + { + Layout.fillHeight: true + Layout.alignment: Qt.AlignVCenter + source: Qaterial.Icons.alert + color: Qaterial.Colors.amber + } + + DexLabel + { + id: tooltip_text + Layout.fillWidth: true + + text_value: + { + if (mouse_area.containsMouse) + { + let relMaxTakerVol = parseFloat(API.app.trading_pg.orderbook.rel_max_taker_vol.decimal); + let baseMaxTakerVol = parseFloat(API.app.trading_pg.orderbook.base_max_taker_vol.decimal); + + if (!enough_funds_to_pay_min_volume) + { + return qsTr("This order requires a minimum amount of %1 %2
You don't have enough funds.
%3") + .arg(parseFloat(min_volume).toFixed(8)) + .arg(isAsk ? right_ticker : left_ticker) + .arg(relMaxTakerVol > 0 || baseMaxTakerVol > 0 ? + "Your max balance after fees is: %1".arg(isAsk ? + relMaxTakerVol.toFixed(8) : baseMaxTakerVol.toFixed(8)) : "") + } + + if ([TradingError.LeftParentChainNotEnoughBalance, TradingError.RightParentChainNotEnoughBalance, + TradingError.LeftParentChainNotEnabled, TradingError.RightParentChainNotEnabled].includes(last_trading_error)) + { + return General.getTradingError( + last_trading_error, curr_fee_info, + base_ticker, rel_ticker, left_ticker, + right_ticker) + } + + if (!([TradingError.None, TradingError.PriceFieldNotFilled, TradingError.VolumeFieldNotFilled].includes(last_trading_error))) + { + if (isAsk && API.app.trading_pg.market_mode == MarketMode.Buy) + { + return General.getTradingError( + last_trading_error, curr_fee_info, + base_ticker, rel_ticker, left_ticker, + right_ticker) + } + + if (!isAsk && API.app.trading_pg.market_mode == MarketMode.Sell) + { + return General.getTradingError( + last_trading_error, curr_fee_info, + base_ticker, rel_ticker, left_ticker, + right_ticker) + } + return "" + } + return "" + } + return "" + } + wrapMode: Text.WordWrap + } + } + delay: 200 + } + DefaultMouseArea { id: mouse_area anchors.fill: parent hoverEnabled: true + onClicked: { - if(is_mine) return + if (is_mine) return - if(enough_funds_to_pay_min_volume) + if (enough_funds_to_pay_min_volume ) { - exchange_trade.orderSelected = true - orderList.currentIndex = index + orderbook_list.currentIndex = index - selectOrder(isAsk, coin, price, quantity, price_denom, - price_numer, quantity_denom, quantity_numer, - min_volume, base_min_volume, base_max_volume, + selectOrder(isAsk, coin, price, price_denom, + price_numer, min_volume, base_min_volume, base_max_volume, rel_min_volume, rel_max_volume, base_max_volume_denom, base_max_volume_numer, uuid) - order_form.visible = General.flipFalse(order_form.visible) - order_form.hidden = General.flipTrue(order_form.hidden) - if (!order_form.hidden) order_form.contentVisible = General.flipFalse(order_form.contentVisible) + placeOrderForm.visible = General.flipFalse(placeOrderForm.visible) + orderSelected() } } @@ -82,65 +161,54 @@ Item } } - RowLayout + Row { id: row anchors.fill: parent anchors.horizontalCenter: parent.horizontalCenter onWidthChanged: progress.width = ((depth * 100) * (width + 40)) / 100 + spacing: 0 - // error icon - DefaultAlertIcon + Dex.ElidableText { - visible: !enough_funds_to_pay_min_volume - iconSize: 12 - - tooltipText: - { - let relMaxTakerVol = parseFloat(API.app.trading_pg.orderbook.rel_max_taker_vol.decimal); - let baseMaxTakerVol = parseFloat(API.app.trading_pg.orderbook.base_max_taker_vol.decimal); - - qsTr("This order requires a minimum amount of %1 %2. %3") - .arg(parseFloat(min_volume).toFixed(8)) - .arg(isAsk ? API.app.trading_pg.market_pairs_mdl.right_selected_coin : API.app.trading_pg.market_pairs_mdl.left_selected_coin) - .arg(relMaxTakerVol > 0 || baseMaxTakerVol > 0 ? "Your max balance after fees is: %1".arg(isAsk ? relMaxTakerVol.toFixed(8) : baseMaxTakerVol.toFixed(8)) : "") - } - } - - // Price - DefaultText - { - Layout.preferredWidth: (parent.width / 100) * 33 + anchors.verticalCenter: parent.verticalCenter + width: parent.width * 0.31 text: { new BigNumber(price).toFixed(8) } font.family: DexTypo.fontFamily font.pixelSize: 12 color: isAsk ? Dex.CurrentTheme.noColor : Dex.CurrentTheme.okColor - elide: Text.ElideRight horizontalAlignment: Text.AlignRight + wrapMode: Text.NoWrap } + Item { width: parent.width * 0.01 } + // Quantity - DefaultText + Dex.ElidableText { - Layout.preferredWidth: (parent.width / 100) * 30 - text: { new BigNumber(quantity).toFixed(6) } + anchors.verticalCenter: parent.verticalCenter + width: parent.width * 0.37 + text: { new BigNumber(base_max_volume).toFixed(6) } font.family: DexTypo.fontFamily font.pixelSize: 12 - elide: Text.ElideRight horizontalAlignment: Text.AlignRight onTextChanged: depth_bar.width = ((depth * 100) * (mouse_area.width + 40)) / 100 + wrapMode: Text.NoWrap } + Item { width: parent.width * 0.01 } + // Total - DefaultText + Dex.ElidableText { - Layout.preferredWidth: (parent.width / 100) * 30 + anchors.verticalCenter: parent.verticalCenter + width: parent.width * 0.30 rightPadding: (is_mine) && (mouse_area.containsMouse || cancel_button.containsMouse) ? 30 : 0 font.family: DexTypo.fontFamily font.pixelSize: 12 text: { new BigNumber(total).toFixed(6) } - elide: Text.ElideRight horizontalAlignment: Text.AlignRight + wrapMode: Text.NoWrap Behavior on rightPadding { NumberAnimation { duration: 150 } } } @@ -151,13 +219,14 @@ Item { id: cancel_button_text property bool requested_cancel: false + visible: is_mine && !requested_cancel - source: Qaterial.Icons.close anchors.verticalCenter: parent.verticalCenter anchors.verticalCenterOffset: 1 anchors.right: parent.right anchors.rightMargin: mouse_area.containsMouse || cancel_button.containsMouse ? 12 : 6 + Behavior on iconSize { NumberAnimation @@ -178,10 +247,9 @@ Item anchors.fill: parent hoverEnabled: true - onClicked: { - if(!is_mine) return + if (!is_mine) return cancel_button_text.requested_cancel = true cancelOrder(uuid) diff --git a/atomic_defi_design/Dex/Exchange/Trade/OrderBook/Vertical.qml b/atomic_defi_design/Dex/Exchange/Trade/OrderBook/Vertical.qml index 8c9790f61e..9c5e4c9d74 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/OrderBook/Vertical.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/OrderBook/Vertical.qml @@ -5,46 +5,48 @@ import QtQuick.Controls 2.15 import Qaterial 1.0 as Qaterial import "../../../Components" +import "../../../Constants" import App 1.0 import Dex.Themes 1.0 as Dex -FloatingBackground +Widget { - visible: isUltraLarge - Layout.fillWidth: true - Layout.fillHeight: true - radius: 10 + title: qsTr("Order Book") - ColumnLayout + margins: 20 + spacing: 20 + + Header { - anchors.fill: parent - anchors.margins: 20 - spacing: 12 + Layout.preferredHeight: 30 + Layout.fillWidth: true + } - Header - { - Layout.fillWidth: true - Layout.preferredHeight: 30 - } + List + { + isAsk: true + isVertical: true + Layout.fillHeight: true + Layout.fillWidth: true + } - List - { - isAsk: true - isVertical: true - Layout.fillHeight: true - Layout.fillWidth: true - } - Item + Item + { + Layout.preferredHeight: 4 + Layout.fillWidth: true + Rectangle { - Layout.preferredHeight: 8 - Layout.fillWidth: true + width: parent.width + height: parent.height + anchors.horizontalCenter: parent.horizontalCenter + color: Dex.CurrentTheme.floatingBackgroundColor } + } - List - { - isAsk: false - Layout.fillHeight: true - Layout.fillWidth: true - } + List + { + isAsk: false + Layout.fillHeight: true + Layout.fillWidth: true } } diff --git a/atomic_defi_design/Dex/Exchange/Trade/Orders/OrderLine.qml b/atomic_defi_design/Dex/Exchange/Trade/Orders/OrderLine.qml deleted file mode 100644 index 80b7af29bc..0000000000 --- a/atomic_defi_design/Dex/Exchange/Trade/Orders/OrderLine.qml +++ /dev/null @@ -1,207 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 -import Qaterial 1.0 as Qaterial - -import QtGraphicalEffects 1.0 - -import App 1.0 - -import "../../../Components" -import Dex.Themes 1.0 as Dex - -Rectangle -{ - property var details - property alias clickable: mouse_area.enabled - readonly property bool is_placed_order: !details ? false : details.order_id !== '' - - width: list.model.count > 6 ? list.width - 15 : list.width - 8 - height: 40 - color: mouse_area.containsMouse? DexTheme.hightlightColor : "transparent" - - DefaultMouseArea - { - id: mouse_area - anchors.fill: parent - hoverEnabled: enabled - onClicked: - { - order_modal.open() - order_modal.item.details = details - } - } - - RowLayout - { - anchors.fill: parent - anchors.leftMargin: 10 - anchors.rightMargin: 10 - - DefaultText - { - id: status_text - Layout.preferredWidth: (parent.width / 100) * 4 - Layout.alignment: Qt.AlignVCenter - visible: clickable ? !details ? false : - (details.is_swap || !details.is_maker) : false - - font.pixelSize: getStatusFontSize(details.order_status) - color: !details ? Dex.CurrentTheme.foregroundColor : getStatusColor(details.order_status) - text_value: !details ? "" : visible ? getStatusStep(details.order_status) : '' - } - - Item - { - Layout.fillHeight: true - Layout.preferredWidth: (parent.width / 100) * 4 - Layout.alignment: Qt.AlignVCenter - visible: !status_text.visible ? clickable ? true : false : false - - Qaterial.ColorIcon - { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - iconSize: 17 - color: Dex.CurrentTheme.foregroundColor - source: Qaterial.Icons.clipboardTextSearchOutline - } - } - - DefaultText - { - visible: clickable - font.pixelSize: base_amount.font.pixelSize - text_value: !details ? "" : details.date ?? "" - Layout.fillHeight: true - Layout.preferredWidth: (parent.width / 100) * 10 - verticalAlignment: Label.AlignVCenter - horizontalAlignment: Text.AlignHCenter - } - - DefaultImage - { - id: base_icon - source: General.coinIcon(!details ? atomic_app_primary_coin : - details.base_coin ?? atomic_app_primary_coin) - Layout.preferredWidth: Style.textSize1 - Layout.preferredHeight: Style.textSize1 - Layout.alignment: Qt.AlignVCenter - Layout.leftMargin: 2 - } - - DefaultText - { - id: base_amount - text_value: !details ? "" : General.formatCrypto("", details.base_amount, details.base_coin, details.base_amount_current_currency, API.app.settings_pg.current_currency) - font.pixelSize: 10 - Layout.fillHeight: true - Layout.preferredWidth: (parent.width / 100) * 33 - verticalAlignment: Label.AlignVCenter - privacy: is_placed_order - } - - Item - { - Layout.fillHeight: true - Layout.fillWidth: true - SwapIcon - { - visible: !status_text.visible - anchors.fill: parent - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - top_arrow_ticker: !details ? atomic_app_primary_coin : details.base_coin ?? "" - bottom_arrow_ticker: !details ? atomic_app_primary_coin : details.rel_coin ?? "" - } - } - - DefaultText - { - id: rel_amount - text_value: !details ? "" : General.formatCrypto("", details.rel_amount, details.rel_coin, details.rel_amount_current_currency, API.app.settings_pg.current_currency) - font.pixelSize: base_amount.font.pixelSize - Layout.fillHeight: true - Layout.preferredWidth: (parent.width / 100) * 33 - verticalAlignment: Label.AlignVCenter - horizontalAlignment: Label.AlignRight - privacy: is_placed_order - } - - DefaultImage - { - id: rel_icon - source: General.coinIcon(!details ? atomic_app_primary_coin : - details.rel_coin ?? atomic_app_secondary_coin) - - width: base_icon.width - Layout.preferredWidth: Style.textSize1 - Layout.preferredHeight: Style.textSize1 - Layout.alignment: Qt.AlignVCenter - } - - DefaultText - { - font.pixelSize: base_amount.font.pixelSize - visible: !details || details.recoverable === undefined ? false : - details.recoverable && details.order_status !== "refunding" - Layout.fillHeight: true - Layout.preferredWidth: (parent.width / 100) * 5 - verticalAlignment: Label.AlignVCenter - horizontalAlignment: Label.AlignHCenter - text_value: Style.warningCharacter - color: Style.colorYellow - - DefaultTooltip - { - contentItem: DefaultText - { - text_value: qsTr("Funds are recoverable") - font.pixelSize: Style.textSizeSmall4 - } - - visible: (parent.visible && mouse_area.containsMouse) ?? false - } - } - - Qaterial.FlatButton - { - id: cancel_button_text - - visible: (!is_history ? details.cancellable ?? false : false) === true ? (mouse_area.containsMouse || hovered) ? true : false : false - - Layout.fillHeight: true - Layout.preferredWidth: (parent.width / 100) * 3 - Layout.alignment: Qt.AlignVCenter - - outlinedColor: Dex.CurrentTheme.noColor - hoverEnabled: true - - onClicked: if (details) cancelOrder(details.order_id) - - Behavior on scale - { - NumberAnimation - { - duration: 200 - } - } - Qaterial.ColorIcon - { - anchors.centerIn: parent - iconSize: 13 - color: Dex.CurrentTheme.noColor - source: Qaterial.Icons.close - scale: parent.visible ? 1 : 0 - } - - } - } - - // Separator - HorizontalLine - { - width: parent.width - anchors.bottom: parent.bottom - } -} diff --git a/atomic_defi_design/Dex/Exchange/Trade/Orders/OrderModal.qml b/atomic_defi_design/Dex/Exchange/Trade/Orders/OrderModal.qml deleted file mode 100644 index 256d6f89fb..0000000000 --- a/atomic_defi_design/Dex/Exchange/Trade/Orders/OrderModal.qml +++ /dev/null @@ -1,370 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 - -import Qaterial 1.0 as Qaterial - -import "../../../Components" -import "../../../Constants" -import Dex.Themes 1.0 as Dex -import App 1.0 - -MultipageModal -{ - id: root - - property var details - - onDetailsChanged: { if (!details) root.close() } - onOpened: swap_progress.updateSimulatedTime() - onClosed: details = undefined - - MultipageModalContent - { - titleText: !details ? "" : details.is_swap ? qsTr("Swap Details") : qsTr("Order Details") - titleAlignment: Qt.AlignHCenter - - // Complete image - DefaultImage - { - visible: !details ? false : details.is_swap && details.order_status === "successful" - Layout.alignment: Qt.AlignHCenter - source: General.image_path + "exchange-trade-complete.png" - } - - // Loading symbol - DefaultBusyIndicator - { - visible: !details ? false : details.is_swap && details.order_status !== "successful" - running: (!details ? false : - details.is_swap && - details.order_status !== "successful" && - details.order_status !== "failed") && Qt.platform.os != "osx" - Layout.alignment: Qt.AlignHCenter - } - - // Status Text - DefaultText - { - Layout.alignment: Qt.AlignHCenter - Layout.topMargin: 5 - font.pixelSize: Style.textSize1 - font.bold: true - visible: !details ? false : details.is_swap || !details.is_maker - text_value: !details ? "" : visible ? getStatusText(details.order_status) : '' - } - - RowLayout - { - Layout.topMargin: 22 - - DefaultRectangle - { - Layout.preferredWidth: 226 - Layout.preferredHeight: 66 - radius: 10 - - RowLayout - { - anchors.fill: parent - anchors.margins: 14 - spacing: 23 - - DefaultImage - { - Layout.preferredWidth: 35 - Layout.preferredHeight: 35 - Layout.alignment: Qt.AlignVCenter - - source: General.coinIcon(!details ? atomic_app_primary_coin : details.base_coin) - } - - ColumnLayout - { - Layout.fillWidth: true - RowLayout - { - Layout.fillWidth: true - spacing: 5 - DefaultText - { - Layout.fillWidth: true - text: details ? details.base_coin : "" - } - - DefaultText - { - Layout.fillWidth: true - text: details ? General.coinName(details.base_coin) : "" - wrapMode: Text.NoWrap - elide: Text.ElideRight - font.pixelSize: 11 - } - } - - DefaultText - { - Layout.fillWidth: true - text: details ? details.base_amount : "" - font.pixelSize: 11 - wrapMode: Text.NoWrap - elide: Text.ElideRight - } - } - } - } - - Qaterial.Icon - { - Layout.fillWidth: true - Layout.alignment: Qt.AlignVCenter - - color: Dex.CurrentTheme.foregroundColor - icon: Qaterial.Icons.swapHorizontal - } - - DefaultRectangle - { - Layout.preferredWidth: 226 - Layout.preferredHeight: 66 - radius: 10 - - RowLayout - { - anchors.fill: parent - anchors.margins: 14 - spacing: 23 - - DefaultImage - { - Layout.preferredWidth: 35 - Layout.preferredHeight: 35 - Layout.alignment: Qt.AlignVCenter - - source: General.coinIcon(!details ? atomic_app_primary_coin : details.rel_coin) - } - - ColumnLayout - { - Layout.fillWidth: true - RowLayout - { - Layout.fillWidth: true - spacing: 5 - DefaultText - { - Layout.fillWidth: true - text: details ? details.rel_coin : "" - } - - DefaultText - { - Layout.fillWidth: true - text: details ? General.coinName(details.rel_coin) : "" - wrapMode: Text.NoWrap - elide: Text.ElideRight - font.pixelSize: 11 - } - } - - DefaultText - { - Layout.fillWidth: true - text: details ? details.rel_amount : "" - font.pixelSize: 11 - wrapMode: Text.NoWrap - elide: Text.ElideRight - } - } - } - } - } - - DefaultScrollView - { - Layout.topMargin: 20 - Layout.fillWidth: true - Layout.preferredHeight: 300 - - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff - - ColumnLayout - { - width: 400 - height: parent.height - 30 - spacing: 12 - - // Maker/Taker - TextEditWithTitle - { - Layout.fillWidth: true - title: qsTr("Order Type") - text: !details ? "" : details.is_maker ? qsTr("Maker Order") : qsTr("Taker Order") - label.font.pixelSize: 13 - } - - // Refund state - TextFieldWithTitle - { - Layout.fillWidth: true - title: qsTr("Refund State") - field.text: !details ? "" : details.order_status === "refunding" ? qsTr("Your swap failed but the auto-refund process for your payment started already. Please wait and keep application opened until you receive your payment back") : "" - field.readOnly: true - field.font.pixelSize: 13 - visible: field.text !== '' - } - - // Date - TextEditWithTitle - { - Layout.fillWidth: true - title: qsTr("Date") - text: !details ? "" : details.date - label.font.pixelSize: 13 - visible: text !== '' - } - - // ID - TextEditWithTitle - { - Layout.fillWidth: true - title: qsTr("ID") - text: !details ? "" : details.order_id - label.font.pixelSize: 13 - visible: text !== '' - copy: true - privacy: true - } - - // Payment ID - TextEditWithTitle - { - Layout.fillWidth: true - title: !details ? "" : details.is_maker ? qsTr("Maker Payment Sent ID") : qsTr("Maker Payment Spent ID") - text: !details ? "" : details.maker_payment_id - label.font.pixelSize: 13 - visible: text !== '' - privacy: true - } - - // Payment ID - TextEditWithTitle - { - Layout.fillWidth: true - title: !details ? "" : details.is_maker ? qsTr("Taker Payment Spent ID") : qsTr("Taker Payment Sent ID") - text: !details ? "" : details.taker_payment_id - label.font.pixelSize: 13 - visible: text !== '' - privacy: true - } - - // Error ID - TextEditWithTitle - { - Layout.fillWidth: true - title: qsTr("Error ID") - text: !details ? "" : details.order_error_state - label.font.pixelSize: 13 - visible: text !== '' - } - - // Error Details - TextEditWithTitle - { - Layout.fillWidth: true - title: qsTr("Error Log") - text: !details ? "" : details.order_error_message - label.font.pixelSize: 13 - visible: text !== '' - copy: true - onCopyNotificationTitle: qsTr("Error Log") - } - - HorizontalLine - { - visible: swap_progress.visible - Layout.fillWidth: true - Layout.topMargin: 10 - } - - SwapProgress - { - id: swap_progress - visible: General.exists(details) && details.order_status !== "matching" - Layout.fillWidth: true - details: root.details - } - } - } - - // Buttons - footer: - [ - DexAppButton - { - text: qsTr("Close") - leftPadding: 20 - rightPadding: 20 - radius: 18 - onClicked: root.close() - }, - - // Cancel button - DexAppOutlineButton - { - id: cancelOrderButton - visible: !details ? false : details.cancellable - leftPadding: 20 - rightPadding: 20 - radius: 18 - text: qsTr("Cancel Order") - onClicked: cancelOrder(details.order_id) - }, - - Item - { - visible: !cancelOrderButton.visible - Layout.fillWidth: true - }, - - // Recover Funds button - DexAppButton - { - id: refundButton - leftPadding: 20 - rightPadding: 20 - radius: 18 - enabled: !API.app.orders_mdl.recover_fund_busy - visible: !details ? false : - details.recoverable && details.order_status !== "refunding" - text: enabled ? qsTr("Recover Funds") : qsTr("Refunding...") - onClicked: API.app.orders_mdl.recover_fund(details.order_id) - }, - - Item - { - visible: !refundButton.visible & !cancelOrderButton.visible - Layout.fillWidth: true - }, - - DexAppOutlineButton - { - text: qsTr("View on Explorer") - leftPadding: 20 - rightPadding: 20 - radius: 18 - visible: !details ? false : details.maker_payment_id !== '' || details.taker_payment_id !== '' - onClicked: - { - if (!details) return - - const maker_id = details.maker_payment_id - const taker_id = details.taker_payment_id - - if (maker_id !== '') General.viewTxAtExplorer(details.is_maker ? details.base_coin : details.rel_coin, maker_id) - if (taker_id !== '') General.viewTxAtExplorer(details.is_maker ? details.rel_coin : details.base_coin, taker_id) - } - } - ] - } -} diff --git a/atomic_defi_design/Dex/Exchange/Trade/Orders/OrdersPage.qml b/atomic_defi_design/Dex/Exchange/Trade/Orders/OrdersPage.qml deleted file mode 100644 index 198dfa9c52..0000000000 --- a/atomic_defi_design/Dex/Exchange/Trade/Orders/OrdersPage.qml +++ /dev/null @@ -1,361 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 -import Qt.labs.platform 1.1 - -import Qaterial 1.0 as Qaterial - -import App 1.0 -import "../../../Components" -import "../../.." -import Dex.Themes 1.0 as Dex - -Item { - id: root - - readonly property date default_min_date: new Date("2019-01-01") - readonly property date default_max_date: new Date(new Date().setDate(new Date().getDate() + 30)) - - property var list_model: API.app.orders_mdl - property var list_model_proxy: API.app.orders_mdl.orders_proxy_mdl - property int page_index - - property alias title: order_list.title - property alias items: order_list.items - - property bool is_history: false - - function update() - { - reset() - if (combo_base.currentTicker !== "All" | combo_rel.currentTicker !== "All") { - buttonDelay.start() - } - } - - function reset() { - list_model_proxy.is_history = !is_history - applyFilter() - list_model_proxy.apply_all_filtering() - list_model_proxy.is_history = is_history - } - - Component.onDestruction: reset() - - Timer { - id: buttonDelay - interval: 200 - onTriggered: { - applyFilter() - list_model_proxy.apply_all_filtering() - } - } - - function applyDateFilter() { - list_model_proxy.filter_minimum_date = min_date.date - - if (max_date.date < min_date.date) - max_date.date = min_date.date - - list_model_proxy.filter_maximum_date = max_date.date - } - - function applyTickerFilter() { - list_model_proxy.set_coin_filter(combo_base.currentValue + "/" + combo_rel.currentValue) - } - - function applyTickerFilter2(ticker1, ticker2) { - list_model_proxy.set_coin_filter(ticker1 + "/" + ticker2) - } - - function applyFilter() { - applyDateFilter() - applyTickerFilter2(combo_base.currentTicker, combo_rel.currentTicker) - } - - Component.onCompleted: { - list_model_proxy.is_history = root.is_history - applyFilter() - list_model_proxy.apply_all_filtering() - } - - ColumnLayout - { - anchors.horizontalCenter: parent.horizontalCenter - - anchors.fill: parent - anchors.bottomMargin: is_history ? 0 : 10 - spacing: 15 - - // Bottom part - Item - { - id: orders_settings - - property bool displaySetting: false - - Layout.fillWidth: true - Layout.preferredHeight: displaySetting ? 150 : 30 - - Behavior on Layout.preferredHeight - { - NumberAnimation - { - duration: 150 - } - } - - Rectangle - { - width: parent.width - height: orders_settings.displaySetting ? 50 : 10 - anchors.bottom: parent.bottom - anchors.bottomMargin: -15 - visible: false - color: Dex.CurrentTheme.foregroundColor - - Behavior on height - { - NumberAnimation - { - duration: 150 - } - } - } - - Row - { - x: 5 - y: 0 - spacing: 5 - Qaterial.OutlineButton - { - icon.source: Qaterial.Icons.filter - text: qsTr("Filter") - anchors.verticalCenter: parent.verticalCenter - outlinedColor: Dex.CurrentTheme.foregroundColor - foregroundColor: Dex.CurrentTheme.foregroundColor - onClicked: orders_settings.displaySetting = !orders_settings.displaySetting - } - - DefaultText - { - color: Dex.CurrentTheme.foregroundColor2 - visible: !orders_settings.displaySetting - anchors.verticalCenter: parent.verticalCenter - text: qsTr("Filter") + ": %1 / %2
%3: %4 - %5" - .arg(combo_base.currentTicker) - .arg(combo_rel.currentTicker) - .arg(qsTr("Date")) - .arg(min_date.date.toLocaleDateString(Locale.ShortFormat, "yyyy-MM-dd")) - .arg(max_date.date.toLocaleDateString(Locale.ShortFormat, "yyyy-MM-dd")) - } - - Qaterial.OutlineButton - { - visible: root.is_history && orders_settings.displaySetting - foregroundColor: Dex.CurrentTheme.foregroundColor - outlinedColor: Dex.CurrentTheme.foregroundColor - anchors.verticalCenter: parent.verticalCenter - text: qsTr("Export CSV") - enabled: list_model.length > 0 - onClicked: - { - export_csv_dialog.folder = General.os_file_prefix + API.app.settings_pg.get_export_folder() - export_csv_dialog.open() - } - } - } - - Row - { - anchors.right: parent.right - y: 0 - rightPadding: 5 - Qaterial.OutlineButton - { - visible: root.is_history & orders_settings.displaySetting - Layout.leftMargin: 30 - text: qsTr("Apply Filter") - foregroundColor: enabled ? Dex.CurrentTheme.okColor : Dex.CurrentTheme.buttonColorDisabled - outlinedColor: enabled ? Dex.CurrentTheme.okColor : Dex.CurrentTheme.buttonColorDisabled - enabled: list_model_proxy.can_i_apply_filtering - onClicked: list_model_proxy.apply_all_filtering() - anchors.verticalCenter: parent.verticalCenter - } - Qaterial.OutlineButton - { - icon.source: Qaterial.Icons.close - text: "Cancel All" - visible: !is_history && API.app.orders_mdl.length > 0 - anchors.verticalCenter: parent.verticalCenter - outlinedColor: Dex.CurrentTheme.noColor - foregroundColor: Dex.CurrentTheme.noColor - onClicked: API.app.trading_pg.orders.cancel_order(list_model_proxy.get_filtered_ids()) - } - } - - ColumnLayout - { - visible: orders_settings.height > 75 - width: parent.width - 20 - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottom: parent.bottom - anchors.bottomMargin: -15 - spacing: 10 - - RowLayout - { - Layout.fillWidth: true - Layout.preferredHeight: 50 - Item - { - Layout.fillWidth: true - Layout.fillHeight: true - DefaultSweetComboBox - { - id: combo_base - - anchors.fill: parent - - model: API.app.portfolio_pg.global_cfg_mdl.all_proxy - onCurrentTickerChanged: applyFilter() - - valueRole: "ticker" - textRole: 'ticker' - - backgroundColor: Dex.CurrentTheme.backgroundColor - popupBackgroundColor: Dex.CurrentTheme.backgroundColor - } - } - - - Qaterial.ColorIcon - { - source: Qaterial.Icons.swapHorizontal - color: Dex.CurrentTheme.foregroundColor - DefaultMouseArea - { - id: swap_button - anchors.fill: parent - hoverEnabled: true - onClicked: - { - const base_idx = combo_base.currentTicker - combo_base.currentTicker = combo_rel.currentTicker - combo_rel.currentTicker = base_idx - } - } - } - - Item - { - Layout.fillWidth: true - Layout.fillHeight: true - - DefaultSweetComboBox - { - id: combo_rel - - anchors.fill: parent - - model: API.app.portfolio_pg.global_cfg_mdl.all_proxy - onCurrentTickerChanged: applyFilter() - Layout.fillWidth: true - valueRole: "ticker" - textRole: 'ticker' - - backgroundColor: Dex.CurrentTheme.backgroundColor - popupBackgroundColor: Dex.CurrentTheme.backgroundColor - } - } - - - } - - RowLayout - { - Qaterial.TextFieldDatePicker - { - id: min_date - title: qsTr("From") - from: default_min_date - to: default_max_date - date: default_min_date - font.pixelSize: 13 - opacity: .8 - color: Dex.CurrentTheme.foregroundColor - backgroundColor: DexTheme.portfolioPieGradient ? '#FFFFFF' : 'transparent' - onAccepted: applyDateFilter() - Layout.fillWidth: true - } - - Qaterial.TextFieldDatePicker - { - id: max_date - enabled: min_date.enabled - title: qsTr("To") - from: min_date.date - to: default_max_date - date: default_max_date - font.pixelSize: 13 - opacity: .8 - color: Dex.CurrentTheme.foregroundColor - backgroundColor: DexTheme.portfolioPieGradient ? '#FFFFFF' : 'transparent' - onAccepted: applyDateFilter() - Layout.fillWidth: true - } - } - } - } - - RowLayout - { - Layout.fillWidth: true - Layout.fillHeight: true - - spacing: parent.spacing - - OrderList - { - id: order_list - items: list_model - is_history: root.is_history - Layout.fillHeight: true - Layout.fillWidth: true - } - - } - } - ModalLoader - { - id: order_modal - sourceComponent: OrderModal {} - } - - FileDialog - { - id: export_csv_dialog - - title: qsTr("Please choose the CSV export name and location") - fileMode: FileDialog.SaveFile - - defaultSuffix: "csv" - nameFilters: ["CSV files (*.csv)", "All files (*)"] - - onAccepted: { - const path = currentFile.toString() - - // Export - console.log("Exporting to CSV: " + path) - API.app.exporter_service.export_swaps_history_to_csv(path.replace(General.os_file_prefix, "")) - - // Open the save folder - const folder_path = path.substring(0, path.lastIndexOf("/")) - Qt.openUrlExternally(folder_path) - } - onRejected: { - console.log("CSV export cancelled") - } - } -} diff --git a/atomic_defi_design/Dex/Exchange/Trade/Orders/SwapProgress.qml b/atomic_defi_design/Dex/Exchange/Trade/Orders/SwapProgress.qml deleted file mode 100644 index 5861f09635..0000000000 --- a/atomic_defi_design/Dex/Exchange/Trade/Orders/SwapProgress.qml +++ /dev/null @@ -1,210 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 - -import App 1.0 - -import "../../../Components" - -// Content -ColumnLayout { - id: root - - property - var details - - readonly property - var all_events: !details ? [] : has_error_event ? details.events.map(e => e.state) : details.success_events - - readonly property bool has_error_event: { - if (!details) return false - - const events = details.events - - for (let i = events.length - 1; i >= 0; --i) - if (details.error_events.indexOf(events[i].state) !== -1) - return true - - return false - } - - readonly property double total_time_passed: { - if (!details) return 0 - - const events = details.events - - let sum = 0 - for (let i = 0; i < events.length; ++i) - sum += events[i].time_diff - - return sum - } - - readonly property double total_time_passed_estimated: { - const events = all_events - - let sum = 0 - for (let i = 0; i < events.length; ++i) - sum += API.app.orders_mdl.average_events_time_registry[events[i]] - - return sum - } - - readonly property int current_event_idx: { - if (!details) return -1 - const events = details.events - if (events.length === 0) return -1 - if (all_events.length === 0) return -1 - - const last_state = events[events.length - 1].state - if (last_state === "Finished") return -1 - - const idx = all_events.indexOf(last_state) - if (idx === -1) return -1 - - return idx + 1 - } - - // Simulated time of the running event - property double simulated_time: 0 - function updateSimulatedTime() { - if (!details) { - simulated_time = 0 - return - } - - const events = details.events - if (!events || events.length === 0) { - simulated_time = 0 - return - } - - const last_event = events[events.length - 1] - if (!last_event.timestamp) { - simulated_time = 0 - return - } - - if (current_event_idx !== -1) { - const diff = Date.now() - last_event.timestamp - simulated_time = diff - (diff % 1000) - } else simulated_time = 0 - } - - Timer { - running: current_event_idx !== -1 - interval: 1000 - repeat: true - onTriggered: updateSimulatedTime() - } - - function getTimeText(duration, estimated) { - return `` + qsTr("act", "SHORT FOR ACTUAL TIME") + ": " + `` + - `` + General.durationTextShort(duration) + `` + - ` | ` + qsTr("est", "SHORT FOR ESTIMATED") + ": " + - General.durationTextShort(estimated) + `` - } - - onTotal_time_passedChanged: updateSimulatedTime() - - // Title - DefaultText { - text_value: `` + qsTr("Progress details") + `` + - ` | ` + - getTimeText(total_time_passed + simulated_time, total_time_passed_estimated) - font.pixelSize: Style.textSize1 - Layout.bottomMargin: 10 - } - - Repeater { - Layout.fillWidth: true - Layout.fillHeight: true - model: all_events - - delegate: Item { - readonly property - var event: { - if (!details) return undefined - const idx = details.events.map(e => e.state).indexOf(modelData) - if (idx === -1) return undefined - - return details.events[idx] - } - - readonly property bool is_current_event: index === current_event_idx - - readonly property bool is_active: General.exists(event) || is_current_event - - readonly property double time_passed: event ? event.time_diff : is_current_event ? simulated_time : 0 - - width: root.width - height: 50 - - DefaultText { - id: icon - - text_value: is_active ? "●" : "○" - anchors.left: parent.left - anchors.leftMargin: 10 - anchors.verticalCenter: col_layout.verticalCenter - color: { - // Already exists, completed event - if (event) { - // Red for the Finished if swap failed - if (event.state === "Finished" && details.order_status === "failed") return DexTheme.redColor - - // Red for error event, green for the others - return details.error_events.indexOf(event.state) === -1 ? DexTheme.greenColor : DexTheme.redColor - } - - // In progress one is orange - if (is_current_event) - return Style.colorOrange - - // Passive color for the rest - return DexTheme.foregroundColorLightColor2 - } - } - - ColumnLayout { - id: col_layout - - anchors.left: icon.right - anchors.leftMargin: icon.anchors.leftMargin - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - - DefaultText { - id: name - - font.pixelSize: Style.textSizeSmall4 - - text_value: getEventText(modelData) - color: event ? DexTheme.foregroundColor : is_current_event ? DexTheme.foregroundColorLightColor0 : DexTheme.foregroundColorLightColor2 - } - - AnimatedRectangle { - id: bar - visible: is_active - width: 300 - height: 2 - - color: DexTheme.foregroundColorDarkColor3 - - AnimatedRectangle { - width: parent.width * (total_time_passed > 0 ? (time_passed / (total_time_passed + simulated_time)) : 0) - height: parent.height - color: DexTheme.greenColor - } - } - - DefaultText { - visible: bar.visible - font.pixelSize: Style.textSizeSmall2 - - text_value: !is_active ? '' : getTimeText(time_passed, API.app.orders_mdl.average_events_time_registry[modelData]) - } - } - } - } -} \ No newline at end of file diff --git a/atomic_defi_design/Dex/Exchange/Trade/PriceLineSimplified.qml b/atomic_defi_design/Dex/Exchange/Trade/PriceLineSimplified.qml index 3dbe24e2d0..a9c257204d 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/PriceLineSimplified.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/PriceLineSimplified.qml @@ -9,47 +9,34 @@ import Dex.Themes 1.0 as Dex ColumnLayout { + Layout.fillWidth: true readonly property string price: non_null_price readonly property string price_reversed: API.app.trading_pg.price_reversed readonly property string cex_price: API.app.trading_pg.cex_price readonly property string cex_price_reversed: API.app.trading_pg.cex_price_reversed - readonly property string cex_price_diff: API.app.trading_pg.cex_price_diff + readonly property string cexPriceDiff: API.app.trading_pg.cex_price_diff readonly property bool invalid_cex_price: API.app.trading_pg.invalid_cex_price readonly property bool price_entered: !General.isZero(non_null_price) readonly property int fontSize: Style.textSizeSmall1 readonly property int fontSizeBigger: Style.textSizeSmall2 - readonly property int line_scale: getComparisonScale(cex_price_diff) - - function getComparisonScale(value) - { - return Math.min(Math.pow(10, General.getDigitCount(parseFloat(value))), 1000000000) - } - - function limitDigits(value) - { - return parseFloat(General.formatDouble(value, 2)) - } + readonly property int lineScale: General.getComparisonScale(cexPriceDiff) spacing: 35 - DefaultText - { - visible: !price_entered && invalid_cex_price - Layout.alignment: Qt.AlignHCenter - text_value: qsTr("Set swap price for evaluation") - font.pixelSize: fontSizeBigger - } - RowLayout { - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter + Layout.fillWidth: true + ColumnLayout { visible: price_entered + Layout.fillWidth: true + DefaultText { + Layout.fillWidth: true + horizontalAlignment: invalid_cex_price ? Text.AlignHCenter : Text.AlignLeft text_value: qsTr("Exchange rate") + (preffered_order.price !== undefined ? (" (" + qsTr("Selected") + ")") : "") font.pixelSize: fontSize } @@ -57,53 +44,56 @@ ColumnLayout // Price reversed DefaultText { + Layout.fillWidth: true + horizontalAlignment: invalid_cex_price ? Text.AlignHCenter : Text.AlignLeft text_value: General.formatCrypto("", "1", right_ticker) + " = " + General.formatCrypto("", price_reversed, left_ticker) - font.pixelSize: fontSizeBigger - font.weight: Font.Medium + font.pixelSize: fontSize } // Price DefaultText { + visible: price != 1 + Layout.fillWidth: true + horizontalAlignment: invalid_cex_price ? Text.AlignHCenter : Text.AlignLeft text_value: General.formatCrypto("", price, right_ticker) + " = " + General.formatCrypto("", "1", left_ticker) font.pixelSize: fontSize } } - Item { Layout.fillWidth: true } - ColumnLayout { visible: !invalid_cex_price + Layout.fillWidth: true DefaultText { - Layout.alignment: Qt.AlignRight + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight text_value: General.cex_icon + " " + qsTr("CEXchange rate") font.pixelSize: fontSize - - CexInfoTrigger {} + DefaultInfoTrigger { triggerModal: cex_info_modal } } // Price reversed DefaultText { - Layout.alignment: Qt.AlignRight + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight text_value: General.formatCrypto("", "1", right_ticker) + " = " + General.formatCrypto("", cex_price_reversed, left_ticker) - font.pixelSize: fontSizeBigger - font.weight: Font.Medium + font.pixelSize: fontSize } // Price DefaultText { - Layout.alignment: Qt.AlignRight + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight text_value: General.formatCrypto("", cex_price, right_ticker) + " = " + General.formatCrypto("", "1", left_ticker) font.pixelSize: fontSize } } } - // Price Comparison ColumnLayout @@ -129,12 +119,12 @@ ColumnLayout height: parent.height * 2 anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter - anchors.horizontalCenterOffset: 0.5 * parent.width * Math.min(Math.max(parseFloat(cex_price_diff) / line_scale, -1), 1) + anchors.horizontalCenterOffset: 0.5 * parent.width * Math.min(Math.max(parseFloat(cexPriceDiff) / lineScale, -1), 1) } DefaultText { - text_value: General.formatPercent(line_scale) + text_value: General.formatPercent(lineScale) font.pixelSize: fontSize anchors.top: parent.top anchors.topMargin: -15 @@ -142,7 +132,7 @@ ColumnLayout DefaultText { - text_value: General.formatPercent(-line_scale) + text_value: General.formatPercent(-lineScale) font.pixelSize: fontSize anchors.top: parent.top anchors.topMargin: -15 @@ -156,8 +146,8 @@ ColumnLayout id: price_diff_text Layout.topMargin: 10 Layout.alignment: Qt.AlignHCenter - color: parseFloat(cex_price_diff) <= 0 ? Dex.CurrentTheme.okColor : Dex.CurrentTheme.noColor - text_value: (parseFloat(cex_price_diff) > 0 ? qsTr("Expensive") : qsTr("Expedient")) + ":    " + qsTr("%1 compared to CEX", "PRICE_DIFF%").arg("" + General.formatPercent(limitDigits(cex_price_diff)) + "") + color: parseFloat(cexPriceDiff) <= 0 ? Dex.CurrentTheme.okColor : Dex.CurrentTheme.noColor + text_value: (parseFloat(cexPriceDiff) > 0 ? qsTr("Expensive") : qsTr("Expedient")) + ":    " + qsTr("%1 compared to CEX", "PRICE_DIFF%").arg("" + General.formatPercent(General.limitDigits(cexPriceDiff)) + "") font.pixelSize: fontSize } } diff --git a/atomic_defi_design/Dex/Exchange/Trade/ProView.qml b/atomic_defi_design/Dex/Exchange/Trade/ProView.qml index f5a9b3f377..f5b7252082 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/ProView.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/ProView.qml @@ -11,12 +11,12 @@ import AtomicDEX.MarketMode 1.0 import AtomicDEX.TradingError 1.0 import "../../Components" +import "../../Constants" import "../../Wallet" import App 1.0 // Trade Form / Component import -import "TradeBox/" import "Trading/" import "Trading/Items/" @@ -33,27 +33,32 @@ import "../../Screens" import Dex.Themes 1.0 as Dex import "../ProView" +import "../ProView/PlaceOrderForm" as PlaceOrderForm +import "../ProView/TradingInfo" as TradingInfo -ColumnLayout +RowLayout { id: form - property alias dexConfig: dex_config_popup - function selectOrder(is_asks, coin, price, quantity, price_denom, - price_numer, quantity_denom, quantity_numer, - min_volume, base_min_volume, base_max_volume, - rel_min_volume, rel_max_volume, base_max_volume_denom, - base_max_volume_numer, uuid) + + property alias tickerSelectors: selectors + property alias trInfo: tradingInfo + property alias orderBook: orderBook + property alias bestOrders: bestOrders + property alias placeOrderForm: placeOrderForm + + function selectOrder( + is_asks, coin, price, price_denom, + price_numer, min_volume, base_min_volume, base_max_volume, + rel_min_volume, rel_max_volume, base_max_volume_denom, + base_max_volume_numer, uuid) { setMarketMode(!is_asks ? MarketMode.Sell : MarketMode.Buy) API.app.trading_pg.preffered_order = { "coin": coin, "price": price, - "quantity": quantity, "price_denom": price_denom, "price_numer": price_numer, - "quantity_denom": quantity_denom, - "quantity_numer": quantity_numer, "min_volume": min_volume, "base_min_volume": base_min_volume, "base_max_volume": base_max_volume, @@ -64,19 +69,20 @@ ColumnLayout "uuid": uuid } - form_base.focusVolumeField() + // Shows place order form in case it has been hidden in the settings. + placeOrderForm.visible = true } Connections { target: exchange_trade + enabled: form.enabled function onBuy_sell_rpc_busyChanged() { if (buy_sell_rpc_busy) return const response = General.clone(buy_sell_last_rpc_data) - if (response.error_code) { confirm_trade_modal.close() @@ -96,671 +102,95 @@ ColumnLayout General.prettifyJSON(response.result), false) General.prevent_coin_disabling.restart() - tabView.currentIndex = 1 + tradingInfo.currentIndex = 1 } } } - Connections + ColumnLayout { - target: app - function onPairChanged(base, rel) - { - dex_chart.visible = true - } - } - - spacing: 10 - anchors.topMargin: 20 - anchors.leftMargin: 10 - anchors.fill: parent + Layout.alignment: Qt.AlignTop - DexBoxManager - { - id: splitView + Layout.minimumWidth: selectors.visible || tradingInfo.visible ? 480 : -1 + Layout.maximumWidth: (!orderBook.visible && !bestOrders.visible) || (!placeOrderForm.visible) ? -1 : 735 Layout.fillWidth: true - Layout.fillHeight: true - itemLists: [left_section, order_form] - spacing: 15 - handle: Item { - implicitWidth: 2 - implicitHeight: 4 + Layout.fillHeight: true - Rectangle - { - implicitWidth: 2 - implicitHeight: 4 - anchors.centerIn: parent - opacity: 0 - color: 'transparent' - } - } + spacing: 10 - DexTradeBox + // Ticker selectors. + TickerSelectors { - id: left_section - minimumWidth: 500 - defaultWidth: 520 - expandedHort: true - hideHeader: true - SplitView.fillHeight: true - color: 'transparent' - - DexBoxManager - { - anchors.fill: parent - anchors.margins: 0 - anchors.rightMargin: 0 - orientation: Qt.Vertical - handle: Item { - implicitWidth: 40 - implicitHeight: 6 - InnerBackground { - implicitWidth: 40 - implicitHeight: 6 - anchors.centerIn: parent - opacity: 0.4 - } - } - - itemLists: [dex_chart, optionBox] - - DexTradeBox - { - id: dex_chart - title: qsTr("Chart") - expandedVert: dex_chart.visible? true : false - onVisibleChanged: - { - if(visible) - { - expandedVert = true - } - } - canBeFull: true - onFullScreenChanged: - { - if(fullScreen) - { - _best_order_box.visible = false - _orderbook_box.visible = false - optionBox.visible = false - order_form.visible = false - } - else - { - _best_order_box.visible = true - _orderbook_box.visible = true - optionBox.visible = true - order_form.visible = true - } - } - - Item - { - id: chart_view - anchors.fill: parent - anchors.topMargin: 40 - - CandleStickChart - { - id: candleChart - color: 'transparent' - anchors.fill: parent - } - - Component.onCompleted: - { - dashboard.webEngineView.parent = chart_view; - dashboard.webEngineView.anchors.fill = chart_view; - } - - Component.onDestruction: - { - dashboard.webEngineView.visible = false; - dashboard.webEngineView.stop(); - } - } - } - - DexTradeBox - { - canBeFull: true - hideHeader: true - maximumHeight: 80 - minimumHeight: 75 - color: 'transparent' - - RowLayout - { - id: selectors - spacing: 20 - anchors.fill: parent - anchors.rightMargin: 10 - anchors.leftMargin: 10 - - TickerSelector - { - id: selector_left - left_side: true - ticker_list: API.app.trading_pg.market_pairs_mdl.left_selection_box - ticker: left_ticker - Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter - Layout.fillWidth: true - } - - SwapIcon - { - Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter - Layout.preferredHeight: selector_left.height * 0.65 - - top_arrow_ticker: selector_left.ticker - bottom_arrow_ticker: selector_right.ticker - hovered: swap_button.containsMouse - - DefaultMouseArea - { - id: swap_button - anchors.fill: parent - hoverEnabled: true - onClicked: - { - if (!block_everything) - setPair(true, right_ticker) - } - } - } - - TickerSelector - { - id: selector_right - left_side: false - ticker_list: API.app.trading_pg.market_pairs_mdl.right_selection_box - ticker: right_ticker - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - Layout.fillWidth: true - } - } - - } - - - DexTradeBox - { - id: optionBox - expandedVert: dex_chart.visible? false : true - expandable: true - defaultHeight: tabView.currentIndex === 0 ? 200 : isUltraLarge? 400 : 270 - closable: true - title: qsTr("Trading Information") - - Connections - { - target: tabView - function onCurrentIndexChanged() { - if (tabView.currentIndex !== 0) { - optionBox.setHeight(isUltraLarge? 400 : 270) - } else { - optionBox.setHeight(200) - } - } - } - - Column - { - topPadding: 40 - width: parent.width - height: parent.height - clip: !parent.contentVisible - anchors.horizontalCenter: parent.horizontalCenter - - Qaterial.LatoTabBar - { - property int taux_exchange: 0 - property int order_idx: 1 - property int history_idx: 2 - - z: 4 - id: tabView - width: parent.width - currentIndex: tabView.currentIndex - anchors.horizontalCenter: parent.horizontalCenter - Material.foreground: DexTheme.foregroundColor - background: null - y: 5 - leftPadding: 15 - - Qaterial.LatoTabButton - { - width: 150 - text: qsTr("Exchange Rates") - font.pixelSize: 14 - textColor: checked ? Dex.CurrentTheme.foregroundColor2 : Dex.CurrentTheme.foregroundColor - textSecondaryColor: Dex.CurrentTheme.foregroundColor2 - indicatorColor: Dex.CurrentTheme.tabSelectedColor - opacity: checked ? 1 : .6 - } - - Qaterial.LatoTabButton - { - width: 120 - text: qsTr("Orders") - font.pixelSize: 14 - textColor: checked ? Dex.CurrentTheme.foregroundColor2 : Dex.CurrentTheme.foregroundColor - textSecondaryColor: Dex.CurrentTheme.foregroundColor2 - indicatorColor: Dex.CurrentTheme.tabSelectedColor - opacity: checked ? 1 : .6 - } - - Qaterial.LatoTabButton - { - width: 120 - text: qsTr("History") - font.pixelSize: 14 - textColor: checked ? Dex.CurrentTheme.foregroundColor2 : Dex.CurrentTheme.foregroundColor - textSecondaryColor: Dex.CurrentTheme.foregroundColor2 - indicatorColor: Dex.CurrentTheme.tabSelectedColor - opacity: checked ? 1 : .6 - } - } - - Item - { - id: swipeContainer - anchors.horizontalCenter: parent.horizontalCenter - width: parent.width - height: optionBox.height - (tabView.height + 40) - - SwipeView - { - id: swipeView - clip: true - interactive: false - currentIndex: tabView.currentIndex - anchors.fill: parent - - onCurrentIndexChanged: - { - swipeView.currentItem.update(); - if (currentIndex === 2) history_component.list_model_proxy.is_history = true; - else history_component.list_model_proxy.is_history = false; - } - - Qaterial.ScrollView - { - clip: true - - PriceLine { width: swipeContainer.width; height: swipeContainer.height; id: price_line_obj; } - } - - OrdersView.OrdersPage { id: order_component; clip: true } - - OrdersView.OrdersPage - { - id: history_component - is_history: true - clip: true - } - } - } - } - } - Item { SplitView.maximumHeight: 1 } - } - } + id: selectors - Item - { - id: _book_and_best - property bool showing: (_best_order_box.visible || _orderbook_box.visible) - SplitView.minimumWidth: showing ? 390 : 0 - SplitView.maximumWidth: showing ? 430 : 0 - SplitView.preferredWidth: showing ? 390 : 0 - clip: true - DexBoxManager - { - anchors.fill: parent - orientation: Qt.Vertical - handle: Item - { - implicitWidth: 40 - implicitHeight: 6 - InnerBackground { - implicitWidth: 40 - implicitHeight: 6 - anchors.centerIn: parent - opacity: 0.4 - } - } - - itemLists: [_orderbook_box, _best_order_box] - - DexTradeBox - { - id: _orderbook_box - SplitView.fillWidth: true - closable: true - title: qsTr("Order Book") - expandedVert: true - - Behavior on SplitView.preferredWidth - { - NumberAnimation - { - duration: 100 - } - } - - OrderBook.Vertical - { - clip: !parent.contentVisible - visible: parent.contentVisible - anchors.topMargin: 40 - anchors.fill: parent - } - } - - DexTradeBox - { - id: _best_order_box - - defaultHeight: 250 - minimumHeight: 130 - closable: true - title: qsTr("Best Orders") - reloadable: true - onReload: API.app.trading_pg.orderbook.refresh_best_orders() - - Behavior on SplitView.preferredWidth - { - NumberAnimation - { - duration: 100 - } - } - - BestOrder.List - { - clip: !parent.contentVisible - id: best_order_list - visible: parent.contentVisible - y: 40 - width: parent.width - height: parent.height-40 - } - } - } + Layout.fillWidth: true + Layout.preferredHeight: 70 } - DexTradeBox + // Trading Informations + TradingInfo.Main { - id: order_form - closable: true - title: qsTr("Place Order") - defaultWidth: isBigScreen ? 300 : 280 - maximumWidth: isBigScreen ? 310 : 280 - minimumWidth: isBigScreen ? 290 : 280 - expandable: false - SplitView.fillHeight: true - - ColumnLayout - { - visible: parent.contentVisible - anchors.topMargin: 60 - anchors.fill: parent - - Row - { - width: parent.width - spacing: 10 - Layout.alignment: Qt.AlignHCenter - - MarketModeSelector - { - marketMode: MarketMode.Buy - ticker: atomic_qt_utilities.retrieve_main_ticker(left_ticker) - } - - MarketModeSelector - { - ticker: atomic_qt_utilities.retrieve_main_ticker(left_ticker) - } - } - - Item - { - Layout.fillWidth: true - Layout.fillHeight: true - - ColumnLayout - { - property int space: 10 - anchors.fill: parent - anchors.topMargin: 5 - spacing: 10 - - Item - { - Layout.fillWidth: true - Layout.preferredHeight: 40 - visible: API.app.trading_pg.preffered_order.price !== undefined - - Rectangle - { - width: parent.width - 20 - height: 40 - radius: 8 - color: 'transparent' - border.color: Dex.CurrentTheme.noColor - anchors.horizontalCenter: parent.horizontalCenter - y: 5 - - DefaultText - { - anchors.verticalCenter: parent.verticalCenter - leftPadding: 15 - color: Dex.CurrentTheme.noColor - text: qsTr("Order Selected") - } - - Qaterial.FlatButton - { - foregroundColor: Dex.CurrentTheme.noColor - icon.source: Qaterial.Icons.close - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - height: 40 - width: 40 - anchors.rightMargin: 15 - onClicked: API.app.trading_pg.reset_order() - } - } - } - - OrderForm - { - id: form_base - Layout.fillWidth: true - Layout.leftMargin: 10 - Layout.rightMargin: 10 - Layout.preferredHeight: 270 - Layout.alignment: Qt.AlignHCenter - } - - Item - { - Layout.preferredHeight: 90 - Layout.fillWidth: true - TotalView {} - } - - Item - { - Layout.fillHeight: true - Layout.fillWidth: true - Layout.leftMargin: 10 - Layout.rightMargin: 10 - Column - { - anchors.fill: parent - anchors.leftMargin: 5 - anchors.rightMargin: 5 - FeeInfo - { - id: bg - visible: false - } - spacing: 15 - - // Trade button - DexGradientAppButton - { - anchors.horizontalCenter: parent.horizontalCenter - width: 262 - height: 44 - radius: 18 - - text: qsTr("START SWAP") - font.weight: Font.Medium - enabled: form_base.can_submit_trade - onClicked: confirm_trade_modal.open() - } - - Column - { - spacing: parent.spacing - visible: errors.text_value !== "" - width: parent.width - bottomPadding: 10 - HorizontalLine - { - Layout.fillWidth: true - Layout.bottomMargin: layout_margin - } - - // Show errors - DefaultText - { - id: errors - anchors.horizontalCenter: parent.horizontalCenter - width: parent.width - horizontalAlignment: DefaultText.AlignHCenter - font.pixelSize: Style.textSizeSmall4 - color: DexTheme.redColor - - text_value: General.getTradingError( - last_trading_error, - curr_fee_info, - base_ticker, - rel_ticker, left_ticker, right_ticker) - } - } - } - } - Item {} - } - } - } + id: tradingInfo + + Layout.fillWidth: true + Layout.fillHeight: true + + resizable: false } } - ModalLoader + WidgetContainer { - id: confirm_trade_modal - sourceComponent: ConfirmTradeModal {} - } + property real _orderBookHeightRatio: 0.65 + property real _bestOrdersHeightRatio: 0.35 - DexPopup - { - id: dex_config_popup - spacing: 8 - padding: 4 - arrowXDecalage: 75 - backgroundColor: Dex.CurrentTheme.floatingBackgroundColor + Layout.minimumWidth: orderBook.visible || bestOrders.visible ? 353 : -1 + Layout.fillWidth: true + Layout.fillHeight: true + Layout.alignment: Qt.AlignTop + spacing: 4 - Settings + onHeightChanged: { - id: proview_settings - property bool chart_visibility: true - property bool option_visibility: true - property bool orderbook_visibility: true - property bool best_order_visibility: false - property bool form_visibility: true + orderBook.height = getHeight(_orderBookHeightRatio); + bestOrders.height = getHeight(_bestOrdersHeightRatio); } - contentItem: Item + OrderBook.Vertical { - implicitWidth: 320 - implicitHeight: 190 + id: orderBook - Column - { - anchors.fill: parent - rightPadding: 20 - padding: 10 - spacing: 8 - DefaultText - { - text: "Display Settings" - font: DexTypo.body2 - } - - HorizontalLine { width: parent.width-20;anchors.horizontalCenter: parent.horizontalCenter;opacity: .4 } - - DexCheckEye - { - text: "Trading Information" - targetProperty: "visible" - target: optionBox - } - - HorizontalLine { width: parent.width-20;anchors.horizontalCenter: parent.horizontalCenter;opacity: .4 } - - DexCheckEye - { - text: "Order Book" - targetProperty: "visible" - target: _orderbook_box - } - - HorizontalLine { width: parent.width-20;anchors.horizontalCenter: parent.horizontalCenter;opacity: .4 } - - DexCheckEye - { - text: "Best Order" - targetProperty: "visible" - target: _best_order_box - } - - HorizontalLine { width: parent.width-20;anchors.horizontalCenter: parent.horizontalCenter;opacity: .4 } - - DexCheckEye - { - id: place_visibility - text: "Place Order" - targetProperty: "visible" - target: order_form - } - } + width: parent.width + minHeight: 320 + } - Component.onCompleted: - { - dex_chart.visible = proview_settings.chart_visibility - optionBox.visible = proview_settings.option_visibility - _orderbook_box.visible = proview_settings.orderbook_visibility - _best_order_box.visible = proview_settings.best_order_visibility - order_form.visible = proview_settings.form_visibility - } + // Best Orders + BestOrder.List + { + id: bestOrders - Component.onDestruction: - { - proview_settings.form_visibility = order_form.visible - proview_settings.chart_visibility = dex_chart.visible - proview_settings.option_visibility = optionBox.visible - proview_settings.orderbook_visibility = _orderbook_box.visible - proview_settings.best_order_visibility = _best_order_box.visible - } + width: parent.width + minHeight: 140 } } + + // Place order form. + PlaceOrderForm.Main + { + id: placeOrderForm + + Layout.minimumWidth: visible ? 302 : -1 + Layout.maximumWidth: 350 + Layout.fillWidth: true + Layout.fillHeight: true + + resizable: false + } + + ModalLoader + { + id: confirm_trade_modal + sourceComponent: ConfirmTradeModal {} + } } diff --git a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Main.qml b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Main.qml index 4880ce3c64..ee73c2f269 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Main.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Main.qml @@ -9,7 +9,7 @@ import Qaterial 1.0 as Qaterial //! Project Imports import "../../../Components" import "../../../Constants" as Constants -import "../Orders" as Orders +import "../../ProView/TradingInfo" as Orders import "Main.js" as Main import App 1.0 import Dex.Themes 1.0 as Dex diff --git a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubBestOrder.qml b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubBestOrder.qml index d785923592..7cd7d5552c 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubBestOrder.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubBestOrder.qml @@ -3,6 +3,9 @@ import QtQuick 2.15 //> Item import QtQuick.Layouts 1.15 //> RowLayout import QtQuick.Controls 2.15 //> ItemDelegate +// 3rdParty +import Qaterial 1.0 as Qaterial + import App 1.0 //! Project Imports @@ -10,165 +13,204 @@ import "../../../Components" //> MultipageModal import "../../../Constants" as Constants //> API import Dex.Themes 1.0 as Dex -DefaultListView +DexListView { id: _listBestOrdersView + model: Constants.API.app.trading_pg.orderbook.best_orders.proxy_mdl + enabled: !Constants.API.app.trading_pg.orderbook.best_orders_busy + onVisibleChanged: currentLeftToken = _tradeCard.selectedTicker property var tradeCard property var selectedOrder property bool best: true property string currentLeftToken // The token we wanna sell - property int _rowWidth: width - 20 - property int _rowHeight: 50 - property int _tokenColumnSize: 60 - property int _quantityColumnSize: 100 - property int _quantityInBaseColumnSize: 100 - property int _fiatVolumeColumnSize: 50 - property int _cexRateColumnSize: 50 + property int _rowWidth: width + property int _rowHeight: 40 + property int _tokenColumnSize: 90 + property int _quantityColumnSize: 90 + property int _quantityInBaseColumnSize: 120 + property int _fiatVolumeColumnSize: 80 + property int _cexRateColumnSize: 60 - enabled: !Constants.API.app.trading_pg.orderbook.best_orders_busy - model: Constants.API.app.trading_pg.orderbook.best_orders.proxy_mdl headerPositioning: ListView.OverlayHeader reuseItems: true cacheBuffer: 40 clip: true - Connections - { - target: _tradeCard - function onBestChanged() - { - Constants.API.app.trading_pg.orderbook.best_orders.proxy_mdl.setFilterFixedString("") - positionViewAtBeginning() - } - } - - onVisibleChanged: currentLeftToken = _tradeCard.selectedTicker - - header: DefaultRectangle // Best orders list header + header: DexRectangle // Best orders list header { + id: header_row width: _rowWidth height: _rowHeight z: 2 + radius: 0 + border.width: 0 color: Dex.CurrentTheme.floatingBackgroundColor - MouseArea { anchors.fill: parent } RowLayout // Order Columns Name { - anchors.verticalCenter: parent.verticalCenter anchors.fill: parent - spacing: 2 - DefaultText // "Token" Header + anchors.margins: 5 + anchors.verticalCenter: parent.verticalCenter + + DexLabel // "Token" Header { Layout.preferredWidth: _tokenColumnSize - text: qsTr("Token") + horizontalAlignment: Text.AlignLeft + + text_value: qsTr("Token") font.family: Constants.Style.font_family font.bold: true font.pixelSize: 12 font.weight: Font.Bold } - DefaultText // "Available Quantity" Header + + DexLabel // "Available Quantity" Header { + id: qty_header + Layout.preferredWidth: _quantityColumnSize - text: qsTr("Available Quantity") + horizontalAlignment: Text.AlignRight + + text_value: qsTr("Available Quantity") font.family: Constants.Style.font_family font.bold: true font.pixelSize: 12 font.weight: Font.Bold } - DefaultText // "Available Quantity (in BASE)" header + + DexLabel // "Available Quantity (in BASE)" header { + id: base_qty_header + Layout.preferredWidth: _quantityInBaseColumnSize - text: qsTr("Available Quantity (in %1)").arg(currentLeftToken) + horizontalAlignment: Text.AlignRight + + text_value: qsTr("Available Quantity (in %1)").arg(currentLeftToken) font.family: Constants.Style.font_family font.bold: true font.pixelSize: 12 font.weight: Font.Bold } - DefaultText // "Fiat Volume" column header + + DexLabel // "Fiat Volume" column header { Layout.preferredWidth: _fiatVolumeColumnSize - text: qsTr("Fiat Volume") + horizontalAlignment: Text.AlignRight + + text_value: qsTr("Fiat Volume") font.family: Constants.Style.font_family font.bold: true font.pixelSize: 12 font.weight: Font.Bold } - DefaultText // "CEX Rate" column header + + DexLabel // "CEX Rate" column header { Layout.preferredWidth: _cexRateColumnSize - text: qsTr("CEX Rate") + horizontalAlignment: Text.AlignRight + + text_value: qsTr("CEX Rate") font.family: Constants.Style.font_family font.bold: true font.pixelSize: 12 font.weight: Font.Bold } } + + MouseArea { anchors.fill: parent } } - delegate: ItemDelegate // Order Line + delegate: DexRectangle // Order Line { property bool _isCoinEnabled: Constants.API.app.portfolio_pg.global_cfg_mdl.get_coin_info(coin).is_enabled width: _rowWidth height: _rowHeight + radius: 0 + border.width: 0 + colorAnimation: false + color: mouse_area.containsMouse ? Dex.CurrentTheme.buttonColorHovered : 'transparent' + + DexMouseArea + { + id: mouse_area + anchors.fill: parent + hoverEnabled: true + onClicked: + { + if (!Constants.API.app.portfolio_pg.global_cfg_mdl.get_coin_info(coin).is_enabled) + { + _tooltip.open() + } + else + { + _listBestOrdersView.tradeCard.best = false + _listBestOrdersView.selectedOrder = { "coin": coin, "uuid": uuid, "price": price, "base_min_volume": base_min_volume, "base_max_volume": base_max_volume, "from_best_order": true } + } + } + } HorizontalLine { width: parent.width; opacity: .5 } RowLayout // Order Info { - anchors.verticalCenter: parent.verticalCenter anchors.fill: parent + RowLayout // Order Token { property int _iconWidth: 24 - Layout.preferredWidth: _tokenColumnSize - DefaultImage // Order Token Icon + + DexImage // Order Token Icon { Layout.preferredWidth: parent._iconWidth Layout.preferredHeight: 24 - source: General.coinIcon(coin) - opacity: !_isCoinEnabled? .1 : 1 + opacity: !_isCoinEnabled? .3 : 1 } - DefaultText // Order Token Name + + DexLabel // Order Token Name { - id: _tokenName Layout.preferredWidth: _tokenColumnSize - parent._iconWidth - text: coin + text_value: coin font.pixelSize: 14 } } - DefaultText // Order Available Quantity + DexLabel // Order Available Quantity { Layout.preferredWidth: _quantityColumnSize - text: parseFloat(General.formatDouble(quantity, General.amountPrecision, true)).toFixed(8) + horizontalAlignment: Text.AlignRight + text_value: parseFloat(General.formatDouble(rel_max_volume, General.amountPrecision, true)).toFixed(8) font.pixelSize: 14 } - DefaultText // Order Available Quantity In BASE + DexLabel // Order Available Quantity In BASE { Layout.preferredWidth: _quantityInBaseColumnSize - text: parseFloat(General.formatDouble(base_max_volume, General.amountPrecision, true)).toFixed(8) + horizontalAlignment: Text.AlignRight + text_value: parseFloat(General.formatDouble(base_max_volume, General.amountPrecision, true)).toFixed(8) font.pixelSize: 14 } - DefaultText // Order Fiat Volume + DexLabel // Order Fiat Volume { Layout.preferredWidth: _fiatVolumeColumnSize - text: price_fiat+Constants.API.app.settings_pg.current_fiat_sign + horizontalAlignment: Text.AlignRight + text_value: parseFloat(price_fiat).toFixed(2)+Constants.API.app.settings_pg.current_fiat_sign } - DefaultText + DexLabel { Layout.preferredWidth: _cexRateColumnSize + horizontalAlignment: Text.AlignRight color: cex_rates=== "0" ? Qt.darker(DexTheme.foregroundColor) : parseFloat(cex_rates)>0? DexTheme.redColor : DexTheme.greenColor - text: cex_rates=== "0" ? "N/A" : parseFloat(cex_rates)>0? "+"+parseFloat(cex_rates).toFixed(2)+"%" : parseFloat(cex_rates).toFixed(2)+"%" + text_value: cex_rates=== "0" ? "N/A" : parseFloat(cex_rates)>0? "+"+parseFloat(cex_rates).toFixed(2)+"%" : parseFloat(cex_rates).toFixed(2)+"%" } - DefaultTooltip + + DexTooltip { id: _tooltip @@ -180,8 +222,10 @@ DefaultListView contentItem: DexLabelUnlinked { - text_value: qsTr(" %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?
Yes - No").arg(coin).arg(coin) - wrapMode: DefaultText.Wrap + text_value: !General.isZhtlc(coin) ? + qsTr(" %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?
Yes - No").arg(coin).arg(coin) : + qsTr(" %1 is not enabled - Please enable it through the coin activation menu").arg(coin) + wrapMode: DexLabel.Wrap width: 250 onLinkActivated: { @@ -230,17 +274,15 @@ DefaultListView delay: 200 } } - onClicked: + } + + Connections + { + target: _tradeCard + function onBestChanged() { - if (!Constants.API.app.portfolio_pg.global_cfg_mdl.get_coin_info(coin).is_enabled) - { - _tooltip.open() - } - else - { - _listBestOrdersView.tradeCard.best = false - _listBestOrdersView.selectedOrder = { "coin": coin, "uuid": uuid, "price": price, "base_min_volume": base_min_volume, "base_max_volume": base_max_volume, "from_best_order": true } - } + Constants.API.app.trading_pg.orderbook.best_orders.proxy_mdl.setFilterFixedString("") + positionViewAtBeginning() } } } diff --git a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubCoinSelector.qml b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubCoinSelector.qml index da89721846..5a89dd366d 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubCoinSelector.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubCoinSelector.qml @@ -13,61 +13,72 @@ import "../../../Components" //> MultipageModal import "../../../Constants" as Constants //> API import Dex.Themes 1.0 as Dex -DefaultListView +DexListView { id: _listCoinView + model: Constants.API.app.trading_pg.market_pairs_mdl.left_selection_box + signal tickerSelected(var ticker) - property int _rowWidth: width - 20 - property int _rowHeight: 50 - property int _tokenColumnSize: 160 - - signal tickerSelected(var ticker) + property real _rowWidth: width + property real _rowHeight: 40 + property real _tokenColumnWidth: 150 + property real _balanceColumnWidth: 120 + property real _fiatColumnWidth: 120 - model: Constants.API.app.trading_pg.market_pairs_mdl.left_selection_box headerPositioning: ListView.OverlayHeader reuseItems: true cacheBuffer: 40 clip: true - header: DefaultRectangle + header: DexRectangle { + id: header_row width: _rowWidth height: _rowHeight z: 2 + radius: 0 + border.width: 0 color: Dex.CurrentTheme.floatingBackgroundColor - RowLayout // Coins Columns Name + RowLayout { - anchors.verticalCenter: parent.verticalCenter + anchors.margins: 5 anchors.fill: parent - spacing: 2 - DefaultText // "Token" Header + anchors.verticalCenter: parent.verticalCenter + + DexLabel // "Token" Header { - property bool asc: true + property bool asc: true + + Layout.preferredWidth: _tokenColumnWidth + horizontalAlignment: Text.AlignLeft - Layout.preferredWidth: _tokenColumnSize - text: qsTr("Token") + text_value: qsTr("Token") font.family: Constants.Style.font_family font.bold: true font.pixelSize: 12 font.weight: Font.Bold + DexMouseArea { - anchors.fill: parent - hoverEnabled: true + anchors.fill: parent + hoverEnabled: true onClicked: { - parent.asc = !parent.asc - _listCoinView.model.sort_by_name(parent.asc) - } + parent.asc = !parent.asc + _listCoinView.model.sort_by_name(parent.asc) + } } } - DefaultText // "Balance" Header + + DexLabel // "Balance" Header { - property bool asc: true + property bool asc: true + + Layout.preferredWidth: _balanceColumnWidth + horizontalAlignment: Text.AlignRight - Layout.fillWidth: true - text: qsTr("Balance") + text_value: qsTr("Balance") font.family: Constants.Style.font_family font.bold: true font.pixelSize: 12 @@ -75,20 +86,24 @@ DefaultListView DexMouseArea { - anchors.fill: parent - hoverEnabled: true + anchors.fill: parent + hoverEnabled: true onClicked: { - parent.asc = !parent.asc - _listCoinView.model.sort_by_currency_balance(parent.asc) - } + parent.asc = !parent.asc + _listCoinView.model.sort_by_currency_balance(parent.asc) + } } } - DefaultText // Fiat Balance Header + + DexLabel // Fiat Balance Header { - property bool asc: true + property bool asc: true + + Layout.preferredWidth: _fiatColumnWidth + horizontalAlignment: Text.AlignRight - text: qsTr("Balance Fiat") + text_value: qsTr("Balance Fiat") font.family: Constants.Style.font_family font.bold: true font.pixelSize: 12 @@ -96,88 +111,80 @@ DefaultListView DexMouseArea { - anchors.fill: parent - hoverEnabled: true + anchors.fill: parent + hoverEnabled: true onClicked: { - parent.asc = !parent.asc - _listCoinView.model.sort_by_currency_balance(parent.asc) - } + parent.asc = !parent.asc + _listCoinView.model.sort_by_currency_balance(parent.asc) + } } } } } - delegate: ItemDelegate + delegate: DexRectangle { - width: _listCoinView._rowWidth - height: 40 + width: _rowWidth + height: _rowHeight + radius: 0 + border.width: 0 + colorAnimation: false + color: mouse_area.containsMouse ? Dex.CurrentTheme.buttonColorHovered : 'transparent' + + DexMouseArea + { + id: mouse_area + anchors.fill: parent + hoverEnabled: true + onClicked: tickerSelected(model.ticker) + } + + HorizontalLine { width: parent.width; opacity: .5 } + RowLayout { - anchors.fill: parent - spacing: 2 - Item - { - Layout.preferredWidth: _tokenColumnSize - height: 40 - Row - { - anchors.verticalCenter: parent.verticalCenter - spacing: 10 - DefaultImage - { - id: _coinIcon - width: 20 - height: 20 - source: General.coinIcon(model.ticker) - anchors.verticalCenter: parent.verticalCenterv - } - DefaultText - { - anchors.verticalCenter: parent.verticalCenter - text: model.ticker - - } - } - Qaterial.DebugRectangle + anchors.fill: parent + + RowLayout { + property int _iconWidth: 24 + Layout.preferredWidth: _tokenColumnWidth + + DexImage { - anchors.fill: parent - visible: false + id: _coinIcon + Layout.preferredWidth: parent._iconWidth + Layout.preferredHeight: 24 + source: General.coinIcon(model.ticker) } - } - Item - { - Layout.fillWidth: true - height: 40 - DexLabel - { - anchors.verticalCenter: parent.verticalCenter - text: model.balance.replace(" ","") - horizontalAlignment: Label.AlignLeft - - } - Qaterial.DebugRectangle + + DexLabel { - anchors.fill: parent - visible: false + Layout.preferredWidth: _tokenColumnWidth - parent._iconWidth + text_value: model.ticker + font.pixelSize: 14 + wrapMode: Text.NoWrap } - } + } + DexLabel { - Layout.alignment: Qt.AlignVCenter - text: "%1".arg(General.getFiatText(model.balance, model.ticker, false)) - Qaterial.DebugRectangle - { - anchors.fill: parent - visible: false - } + Layout.preferredWidth: _balanceColumnWidth + horizontalAlignment: Text.AlignRight + text_value: model.balance.replace(" ","") + font.pixelSize: 14 + wrapMode: Text.NoWrap + } + + DexLabel + { + Layout.preferredWidth: _fiatColumnWidth + Layout.rightMargin: 8 + horizontalAlignment: Text.AlignRight + text_value: "%1".arg(General.getFiatText(model.balance, model.ticker, false)) + font.pixelSize: 14 + wrapMode: Text.NoWrap } - } - - MouseArea - { - anchors.fill: parent - onClicked: tickerSelected(model.ticker) } } diff --git a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubHistory.qml b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubHistory.qml index 93481e3786..b6171ada9c 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubHistory.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubHistory.qml @@ -48,12 +48,12 @@ Item } function applyDateFilter() { - list_model_proxy.filter_minimum_date = min_date.date + list_model_proxy.filter_minimum_date = min_date.selectedDate - if(max_date.date < min_date.date) - max_date.date = min_date.date + if(max_date.selectedDate < min_date.selectedDate) + max_date.selectedDate = min_date.selectedDate - list_model_proxy.filter_maximum_date = max_date.date + list_model_proxy.filter_maximum_date = max_date.selectedDate } function applyFilter() { @@ -105,8 +105,8 @@ Item .arg(combo_base.currentTicker) .arg(combo_rel.currentTicker) .arg(qsTr("Date")) - .arg(min_date.date.toLocaleDateString(Locale.ShortFormat, "yyyy.MM.dd")) - .arg(max_date.date.toLocaleDateString(Locale.ShortFormat, "yyyy.MM.dd")) + .arg(min_date.selectedDate.toLocaleDateString(Locale.ShortFormat, "yyyy.MM.dd")) + .arg(max_date.selectedDate.toLocaleDateString(Locale.ShortFormat, "yyyy.MM.dd")) } DexAppButton @@ -209,42 +209,33 @@ Item spacing: 10 - RowLayout + Row { width: main_order.width - 40 height: 50 anchors.horizontalCenter: parent.horizontalCenter - spacing: 5 - Qaterial.TextFieldDatePicker + DatePicker { id: min_date - title: qsTr("From") - from: default_min_date - to: default_max_date - date: default_min_date + width: parent.width * 0.45 + titleText: qsTr("From") + minimumDate: default_min_date + maximumDate: default_max_date + selectedDate: default_min_date onAccepted: applyDateFilter() - Layout.fillWidth: true - Layout.fillHeight: true - opacity: .8 - color: DexTheme.foregroundColor - backgroundColor: DexTheme.portfolioPieGradient ? '#FFFFFF' : 'transparent' } - Qaterial.TextFieldDatePicker + Item { width: parent.width * 0.1; height: 1 } + + DatePicker { id: max_date - enabled: min_date.enabled - title: qsTr("To") - from: min_date.date - to: default_max_date - date: default_max_date + width: parent.width * 0.45 + titleText: qsTr("To") + minimumDate: default_min_date + maximumDate: default_max_date + selectedDate: default_max_date onAccepted: applyDateFilter() - Layout.fillWidth: true - Layout.fillHeight: true - rightInset: 0 - opacity: .8 - color: DexTheme.foregroundColor - backgroundColor: DexTheme.portfolioPieGradient ? '#FFFFFF' : 'transparent' } } } diff --git a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubOrders.qml b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubOrders.qml index 4f9520eed2..680331ad66 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubOrders.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/SubOrders.qml @@ -49,12 +49,12 @@ Item } function applyDateFilter() { - list_model_proxy.filter_minimum_date = min_date.date + list_model_proxy.filter_minimum_date = min_date.selectedDate - if(max_date.date < min_date.date) - max_date.date = min_date.date + if(max_date.selectedDate < min_date.selectedDate) + max_date.selectedDate = min_date.selectedDate - list_model_proxy.filter_maximum_date = max_date.date + list_model_proxy.filter_maximum_date = max_date.selectedDate } function applyFilter() { @@ -91,15 +91,14 @@ Item width: _subOrdersRoot.width - 40 anchors.topMargin: 12 font.pixelSize: Constants.Style.textSizeSmall4 - //text: _filterApplied? "" : qsTr("Finished orders") DexLabel { opacity: .4 text: qsTr("Filter") + " %1 / %2
%3 %4 - %5" .arg(combo_base.currentTicker) .arg(combo_rel.currentTicker) .arg(qsTr("Date")) - .arg(min_date.date.toLocaleDateString(Locale.ShortFormat, "yyyy.MM.dd")) - .arg(max_date.date.toLocaleDateString(Locale.ShortFormat, "yyyy.MM.dd")) + .arg(min_date.selectedDate.toLocaleDateString(Locale.ShortFormat, "yyyy.MM.dd")) + .arg(max_date.selectedDate.toLocaleDateString(Locale.ShortFormat, "yyyy.MM.dd")) } DexAppButton { @@ -204,44 +203,34 @@ Item } } - RowLayout + Row { width: main_order.width - 40 height: 50 anchors.horizontalCenter: parent.horizontalCenter - spacing: 5 - Qaterial.TextFieldDatePicker + DatePicker { id: min_date - title: qsTr("From") - from: default_min_date - to: default_max_date - date: default_min_date + width: parent.width * 0.45 + titleText: qsTr("From") + minimumDate: default_min_date + maximumDate: default_max_date + selectedDate: default_min_date onAccepted: applyDateFilter() - Layout.fillWidth: true - Layout.fillHeight: true - opacity: .8 - color: DexTheme.foregroundColor - backgroundColor: DexTheme.portfolioPieGradient ? '#FFFFFF' : 'transparent' } - Qaterial.TextFieldDatePicker + Item { width: parent.width * 0.1; height: 1 } + + DatePicker { id: max_date - enabled: min_date.enabled - title: qsTr("To") - from: min_date.date - to: default_max_date - date: default_max_date + width: parent.width * 0.45 + titleText: qsTr("To") + minimumDate: default_min_date + maximumDate: default_max_date + selectedDate: default_max_date onAccepted: applyDateFilter() - Layout.fillWidth: true - Layout.fillHeight: true - rightInset: 0 - opacity: .8 - color: Dex.CurrentTheme.foregroundColor - backgroundColor: DexTheme.portfolioPieGradient ? '#FFFFFF' : 'transparent' } - } spacing: 10 } diff --git a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Trade.qml b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Trade.qml index a4a8d89cec..480c041971 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Trade.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/SimpleView/Trade.qml @@ -19,7 +19,14 @@ ClipRRect // Trade Card { id: _tradeCard - property string selectedTicker: API.app.get_balance(left_ticker) > 0 ? left_ticker : "" + readonly property var fees: Constants.API.app.trading_pg.fees + readonly property var max_trade_volume: Constants.API.app.trading_pg.max_volume + readonly property var min_trade_volume: Constants.API.app.trading_pg.min_trade_vol + readonly property var sell_ticker_balance: parseFloat(API.app.get_balance(left_ticker)) + readonly property bool coin_tradable: selectedTicker !== "" && sell_ticker_balance > 0 + readonly property bool waiting_for_sell_coin_info: (max_trade_volume == 0 || !Constants.General.isZhtlcReady(left_ticker)) && sell_ticker_balance != 0 + + property string selectedTicker: sell_ticker_balance > 0 ? left_ticker : "" property var selectedOrder: undefined property bool best: false property bool coinSelection: false @@ -32,7 +39,6 @@ ClipRRect // Trade Card if (typeof selectedOrder !== 'undefined' && selectedOrder.from_best_order) Constants.API.app.trading_pg.orderbook.select_best_order(selectedOrder.uuid) else if (typeof selectedOrder !== 'undefined') Constants.API.app.trading_pg.preffered_order = selectedOrder else Constants.API.app.trading_pg.reset_order() - Constants.API.app.trading_pg.determine_fees() } @@ -42,7 +48,7 @@ ClipRRect // Trade Card onBestChanged: if (best) Constants.API.app.trading_pg.orderbook.refresh_best_orders() width: bestOrderSimplified.visible ? 600 : coinSelection ? 450 : 380 - height: col.height + 15 + height: swap_card_content.height + 15 radius: 20 Connections // Catches C++ `trading_page` class signals. @@ -63,8 +69,9 @@ ClipRRect // Trade Card { if (typeof selectedOrder === 'undefined') return - if (parseFloat(_fromValue.text) > Constants.API.app.trading_pg.max_volume) - _fromValue.text = Constants.API.app.trading_pg.max_volume + if (parseFloat(_fromValue.text) > max_trade_volume) + _fromValue.text = max_trade_volume + Constants.API.app.trading_pg.determine_fees() } function onVolumeChanged() @@ -75,10 +82,12 @@ ClipRRect // Trade Card Connections { + enabled: parent.enabled target: Constants.API.app.trading_pg.orderbook.bids function onBetterOrderDetected(newOrder) { + if (!selectedOrder) return // We shoould rename SelectedOrderStatus enum to OrderbookNotification. if (Constants.API.app.trading_pg.selected_order_status == SelectedOrderStatus.BetterPriceAvailable) { @@ -131,10 +140,9 @@ ClipRRect // Trade Card Column // Swap Card Content { - id: col + id: swap_card_content width: parent.width - spacing: 20 Column // Header { id: _swapCardHeader @@ -142,6 +150,7 @@ ClipRRect // Trade Card width: parent.width - 20 leftPadding: 20 topPadding: 20 + bottomPadding: 20 spacing: 15 DexLabel // Title @@ -153,7 +162,7 @@ ClipRRect // Trade Card DefaultText // Description { - anchors.topMargin: 12 + anchors.topMargin: 10 font.pixelSize: Constants.Style.textSizeSmall4 text: qsTr("Instant trading with best orders") @@ -163,7 +172,7 @@ ClipRRect // Trade Card visible: enabled anchors.left: parent.right - anchors.leftMargin: 100 + anchors.leftMargin: 80 anchors.bottom: parent.bottom anchors.bottomMargin: -8 @@ -187,14 +196,14 @@ ClipRRect // Trade Card delay: 500 timeout: 5000 visible: parent.hovered - text: qsTr("Reset form.") + text: qsTr("Reset form") } } } DexLabel // Title { - text: qsTr("You have no tradable assets.") + text: qsTr("You have no tradable assets") font: DexTypo.head6 opacity: .85 visible: !has_coins_with_balance @@ -243,7 +252,7 @@ ClipRRect // Trade Card anchors.verticalCenter: _fromTitle.verticalCenter anchors.right: parent.right anchors.rightMargin: 17 - text: qsTr("%1").arg(Constants.API.app.trading_pg.max_volume) + text: qsTr("%1").arg(max_trade_volume) // This is slow to appear font.pixelSize: Constants.Style.textSizeSmall2 elide: Text.ElideRight color: DexTheme.foregroundColorLightColor1 @@ -286,16 +295,13 @@ ClipRRect // Trade Card AmountField // Amount { id: _fromValue - enabled: selectedTicker !== "" - visible: enabled + enabled: sell_ticker_balance == 0 ? false : waiting_for_sell_coin_info ? false : true anchors.bottom: parent.bottom anchors.bottomMargin: 19 anchors.left: parent.left anchors.leftMargin: 2 - placeholderText: Constants.API.app.trading_pg.max_volume == 0 ? - "Loading wallet..." : typeof selectedOrder !== 'undefined' ? - qsTr("Min: %1").arg(Constants.API.app.trading_pg.min_trade_vol) : qsTr("Enter an amount") - font.pixelSize: Constants.Style.textSizeSmall5 + placeholderText: Constants.General.getSimpleFromPlaceholder(selectedTicker, selectedOrder, sell_ticker_balance) + font.pixelSize: Constants.Style.textSizeSmall3 background: Rectangle { color: swap_from_card.color} onTextChanged: @@ -310,9 +316,9 @@ ClipRRect // Trade Card onFocusChanged: { - if (!focus && parseFloat(text) < parseFloat(Constants.API.app.trading_pg.min_trade_vol)) + if (!focus && parseFloat(text) < parseFloat(min_trade_volume)) { - text = Constants.API.app.trading_pg.min_trade_vol + text = min_trade_volume } } Component.onCompleted: text = "" @@ -413,7 +419,6 @@ ClipRRect // Trade Card anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right anchors.rightMargin: 5 - color: DexTheme.foregroundColor up: false } @@ -432,13 +437,13 @@ ClipRRect // Trade Card text: qsTr("MAX") color: Dex.CurrentTheme.foregroundColor2 - onClicked: _fromValue.text = Constants.API.app.trading_pg.max_volume + onClicked: _fromValue.text = max_trade_volume } DefaultBusyIndicator { anchors.centerIn: parent - visible: selectedTicker !== "" && Constants.API.app.trading_pg.max_volume == 0 + visible: waiting_for_sell_coin_info } } @@ -447,7 +452,7 @@ ClipRRect // Trade Card Layout.preferredWidth: _tradeCard.width - 20 Layout.preferredHeight: 90 Layout.alignment: Qt.AlignHCenter - Layout.topMargin: 15 + Layout.topMargin: 10 radius: 20 color: DexTheme.tradeFieldBoxBackgroundColor visible: !bestOrderSimplified.visible @@ -479,7 +484,7 @@ ClipRRect // Trade Card DefaultText // Amount In Fiat { - enabled: parseFloat(_toValue.text) > 0 + enabled: parseFloat(_toValue.text) > 0 && _toValue.text != "" anchors.top: _toValue.bottom anchors.topMargin: -3 anchors.left: _toValue.left @@ -593,8 +598,6 @@ ClipRRect // Trade Card anchors.right: parent.right anchors.rightMargin: 5 - color: DexTheme.foregroundColor - up: false } } @@ -634,9 +637,10 @@ ClipRRect // Trade Card } } - Item + Item // Swap Button { Layout.topMargin: 10 + Layout.bottomMargin: 10 Layout.alignment: Qt.AlignHCenter Layout.preferredWidth: _tradeCard.width - 30 Layout.preferredHeight: 50 @@ -646,7 +650,7 @@ ClipRRect // Trade Card DexGradientAppButton { - enabled: !Constants.API.app.trading_pg.preimage_rpc_busy && !_swapAlert.visible + enabled: parent.enabled && !Constants.API.app.trading_pg.preimage_rpc_busy && !_swapAlert.visible opacity: enabled ? 1 : .6 radius: 10 anchors.fill: parent @@ -661,6 +665,7 @@ ClipRRect // Trade Card Connections { + enabled: parent.enabled target: exchange_trade function onBuy_sell_rpc_busyChanged() { @@ -704,35 +709,16 @@ ClipRRect // Trade Card function getAlert() { - var left_ticker = Constants.API.app.trading_pg.market_pairs_mdl.left_selected_coin + console.log("_fromValue.text: " + _fromValue.text) var right_ticker = Constants.API.app.trading_pg.market_pairs_mdl.right_selected_coin - var right_parent = Constants.API.app.portfolio_pg.global_cfg_mdl.get_parent_coin(right_ticker) - var left_parent = Constants.API.app.portfolio_pg.global_cfg_mdl.get_parent_coin(left_ticker) - var last_trading_error = Constants.API.app.trading_pg.last_trading_error - var fees_error = Constants.API.app.trading_pg.fees.error + var base_ticker = Constants.API.app.trading_pg.market_pairs_mdl.base_selected_coin + var rel_ticker = Constants.API.app.trading_pg.market_pairs_mdl.rel_selected_coin if (_fromValue.text === "" || parseFloat(_fromValue.text) === 0) - return qsTr("Entered amount must be superior than 0.") + return qsTr("Entered amount must be higher than 0.") if (typeof selectedOrder === 'undefined') - return qsTr("You must select an order.") - if (last_trading_error == TradingError.VolumeIsLowerThanTheMinimum) - return qsTr("Entered amount is below the minimum required by this order: %1").arg(selectedOrder.base_min_volume) - if (last_trading_error == TradingError.LeftParentChainNotEnabled) - return qsTr("%1 needs to be enabled in order to use %2").arg(Constants.API.app.portfolio_pg.global_cfg_mdl.get_parent_coin(left_ticker)).arg(left_ticker) - if (last_trading_error == TradingError.LeftParentChainNotEnoughBalance) - return qsTr("%1 balance needs to be funded, a non-zero balance is required to pay the gas of %2 transactions").arg(left_parent).arg(left_ticker) - if (last_trading_error == TradingError.RightParentChainNotEnabled) - return qsTr("%1 needs to be enabled in order to use %2").arg(Constants.API.app.portfolio_pg.global_cfg_mdl.get_parent_coin(right_ticker)).arg(right_ticker) - if (last_trading_error == TradingError.RightParentChainNotEnoughBalance) - return qsTr("%1 balance needs to be funded, a non-zero balance is required to pay the gas of %2 transactions").arg(right_parent).arg(right_ticker) - if (fees_error) { - let coin = right_ticker - if (fees_error.search(Constants.API.app.portfolio_pg.global_cfg_mdl.get_parent_coin(left_ticker)) > -1) { - coin = left_ticker - } - return qsTr("%1 balance does not have enough funds to pay the gas of %2 transactions").arg(Constants.API.app.portfolio_pg.global_cfg_mdl.get_parent_coin(coin)).arg(coin) - } - return "" + return qsTr("Select an order.") + return Constants.General.getTradingError(last_trading_error, fees, base_ticker, rel_ticker, left_ticker, right_ticker) } tooltipText: _swapAlert.getAlert() @@ -741,134 +727,92 @@ ClipRRect // Trade Card } } + Item + { + height: 35 + width: 150 + visible: coinSelectorSimplified.visible + + SearchField + { + id: _coinSearchField + height: 35 + anchors.fill: parent + anchors.leftMargin: 20 + forceFocus: true + textField.onTextChanged: _coinList.model.setFilterFixedString(textField.text) + Component.onDestruction: _coinList.model.setFilterFixedString("") + } + } + Item { id: coinSelectorSimplified - width: parent.width + width: parent.width - 40 + anchors.horizontalCenter: parent.horizontalCenter height: 300 visible: _tradeCard.coinSelection && has_coins_with_balance - Item + SubCoinSelector { - width: parent.width - height: 50 - - Qaterial.ColorIcon - { - anchors.verticalCenter: parent.verticalCenter - source: Qaterial.Icons.magnify - color: DexTheme.foregroundColor - x: 25 - opacity: .7 - } - - DexTextField + id: _coinList + anchors.fill: parent + anchors.topMargin: 10 + onTickerSelected: { - id: _coinSearchField - width: parent.width-70 - height: parent.height - font.pixelSize: 16 - x: 45 - placeholderText: qsTr("Search") - - background: DexRectangle - { - border.width: 0 - color: 'transparent' - } - - onTextChanged: - { - _coinList.model.setFilterFixedString(text) - } + _tradeCard.selectedTicker = ticker + _tradeCard.coinSelection = false + _fromValue.forceActiveFocus() } } Connections { target: _tradeCard function onCoinSelectionChanged() { - _coinSearchField.text = "" + _coinSearchField.textField.text = "" } } + } - SubCoinSelector - { - id: _coinList - - onTickerSelected: - { - _tradeCard.selectedTicker = ticker - _tradeCard.coinSelection = false - _fromValue.forceActiveFocus() - } + Item + { + height: 45 + width: 150 + visible: bestOrderSimplified.visible && (_bestOrderList.count > 0 || _bestOrderSearchField.textField.text != "") + SearchField + { + id: _bestOrderSearchField + anchors.topMargin: 10 + height: 35 anchors.fill: parent - anchors.rightMargin: 10 anchors.leftMargin: 20 - anchors.bottomMargin: 10 - anchors.topMargin: 50 + forceFocus: true + textField.onTextChanged: Constants.API.app.trading_pg.orderbook.best_orders.proxy_mdl.setFilterFixedString(textField.text) + Component.onDestruction: Constants.API.app.trading_pg.orderbook.best_orders.proxy_mdl.setFilterFixedString("") } } Item { id: bestOrderSimplified - width: parent.width + width: parent.width - 40 + anchors.horizontalCenter: parent.horizontalCenter height: 300 visible: _tradeCard.best && has_coins_with_balance - Item - { - width: parent.width - height: 50 - - Qaterial.ColorIcon - { - anchors.verticalCenter: parent.verticalCenter - source: Qaterial.Icons.magnify - x: 25 - opacity: .7 - color: Dex.CurrentTheme.textPlaceholderColor - } - - DexTextField - { - id: _bestOrderSearchField - width: parent.width-70 - height: parent.height - font.pixelSize: 16 - x: 45 - placeholderText: qsTr("Search") - - background: DexRectangle - { - border.width: 0 - color: 'transparent' - } - - onTextChanged: - { - Constants.API.app.trading_pg.orderbook.best_orders.proxy_mdl.setFilterFixedString(text) - } - } - } - - Connections { - target: _tradeCard - function onBestChanged() { - _bestOrderSearchField.text = "" - } - } - SubBestOrder { id: _bestOrderList tradeCard: _tradeCard + anchors.fill: parent + anchors.topMargin: 10 + visible: _tradeCard.width == 600 onSelectedOrderChanged: { _tradeCard.selectedOrder = selectedOrder - _bestOrderSearchField.text = "" + _bestOrderSearchField.textField.text = "" _fromValue.forceActiveFocus() } @@ -879,13 +823,13 @@ ClipRRect // Trade Card _tradeCard.best = false } } + } - anchors.fill: parent - anchors.rightMargin: 10 - anchors.leftMargin: 20 - anchors.bottomMargin: 10 - anchors.topMargin: 50 - visible: _tradeCard.width == 600 + Connections { + target: _tradeCard + function onBestChanged() { + _bestOrderSearchField.textField.text = "" + } } DefaultBusyIndicator @@ -915,9 +859,10 @@ ClipRRect // Trade Card } } - Item // Swap Info - Details + Item // Fees Info - Details { id: _feesCard + anchors.topMargin: 10 anchors.horizontalCenter: parent.horizontalCenter width: 350 height: 50 @@ -954,7 +899,7 @@ ClipRRect // Trade Card } enabled: parent.enabled - model: Constants.API.app.trading_pg.fees.total_fees + model: _tradeCard.fees.hasOwnProperty('base_transaction_fees_ticker') ? _tradeCard.fees.total_fees : [] delegate: RowLayout { @@ -986,9 +931,10 @@ ClipRRect // Trade Card DefaultBusyIndicator { id: fees_busy - width: 30 - height: 30 + anchors.fill: parent anchors.centerIn: parent + indicatorSize: 32 + indicatorDotSize: 5 visible: Constants.API.app.trading_pg.preimage_rpc_busy || _feesList.count == 0 } } diff --git a/atomic_defi_design/Dex/Exchange/Trade/SweetDexComboBox.qml b/atomic_defi_design/Dex/Exchange/Trade/SweetDexComboBox.qml deleted file mode 100644 index 28b9319ec2..0000000000 --- a/atomic_defi_design/Dex/Exchange/Trade/SweetDexComboBox.qml +++ /dev/null @@ -1,200 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtGraphicalEffects 1.0 -import QtQuick.Window 2.15 -import QtQuick.Controls 2.15 -import QtQuick.Controls.impl 2.15 -import QtQuick.Controls.Universal 2.15 - -import Qaterial 1.0 as Qaterial - -import "../../Components" -import App 1.0 -import Dex.Themes 1.0 as Dex - -ComboBox -{ - id: control - - contentItem: DexComboBoxLine - { - id: line - - property int update_count: 0 - property var prev_details - - function forceUpdateDetails() - { - console.log("Portfolio item data changed, force-updating the selected ticker details!") - ++update_count - } - - padding: 10 - details: - { - const idx = combo.currentIndex - - if(idx === -1) return prev_details - - // Update count triggers the change for auto-update - const new_details = - { - update_count: line.update_count, - ticker: model.data(model.index(idx, 0), 257), - name: model.data(model.index(idx, 0), 259), - balance: model.data(model.index(idx, 0), 260), - main_currency_balance: model.data(model.index(idx, 0), 261) - } - - prev_details = new_details - - return new_details - } - - Component.onCompleted: portfolio_mdl.portfolioItemDataChanged.connect(forceUpdateDetails) - Component.onDestruction: portfolio_mdl.portfolioItemDataChanged.disconnect(forceUpdateDetails) - } - - height: 80 - - background: DefaultRectangle - { - color: Dex.CurrentTheme.floatingBackgroundColor - radius: 10 - } - - // Each dropdown item - delegate: ItemDelegate - { - Universal.accent: control.lineHoverColor - width: control.width - highlighted: control.highlightedIndex === index - contentItem: DexComboBoxLine { details: model } - z: 5 - } - - // Dropdown itself - popup: Popup - { - id: popup - - readonly property double max_height: 450//control.Window.height - bottomMargin - mapToItem(control.Window.contentItem, x, y).y - - width: control.width - height: Math.min(contentItem.implicitHeight, popup.max_height) - z: 4 - y: control.height - 1 - bottomMargin: 20 - padding: 1 - rightMargin: 5 - - contentItem: ColumnLayout - { - anchors.rightMargin: 5 - - // Search input - DefaultTextField - { - id: input_coin_filter - background: Item - { - DefaultRectangle - { - anchors.fill: parent - anchors.rightMargin: 2 - } - } - - function reset() - { - text = "" - renewIndex() - } - - placeholderText: qsTr("Search") - - font.pixelSize: 16 - - Layout.fillWidth: true - Layout.leftMargin: 0 - Layout.preferredHeight: 60 - Layout.rightMargin: 2 - Layout.topMargin: Layout.leftMargin - - onTextChanged: - { - ticker_list.setFilterFixedString(text) - renewIndex() - } - - Keys.onDownPressed: control.incrementCurrentIndex() - Keys.onUpPressed: control.decrementCurrentIndex() - Keys.onPressed: - { - if (event.key === Qt.Key_Return) - { - if (control.count > 0) control.currentIndex = 0; - popup.close(); - event.accepted = true; - } - } - - Connections - { - target: popup - function onOpened() - { - input_coin_filter.reset(); - input_coin_filter.forceActiveFocus(); - } - function onClosed() { input_coin_filter.reset() } - } - } - Item - { - Layout.maximumHeight: popup.max_height - 100 - Layout.fillWidth: true - implicitHeight: popup_list_view.contentHeight + 5 - DefaultListView - { - id: popup_list_view - // Scrollbar appears if this extra space is not added - model: control.popup.visible ? control.delegateModel : null - currentIndex: control.highlightedIndex - anchors.fill: parent - anchors.rightMargin: 2 - - DefaultMouseArea - { - anchors.fill: parent - acceptedButtons: Qt.NoButton - } - } - } - } - - background: DefaultRectangle - { - width: parent.width - y: -5 - height: parent.height + 10 - border.width: 1 - } - } - - indicator: Column - { - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: 8 - spacing: -12 - - Qaterial.Icon - { - width: 30 - height: 30 - color: Dex.CurrentTheme.comboBoxArrowsColor - icon: Qaterial.Icons.chevronDown - } - } -} diff --git a/atomic_defi_design/Dex/Exchange/Trade/TickerSelector.qml b/atomic_defi_design/Dex/Exchange/Trade/TickerSelector.qml deleted file mode 100644 index 797137caf8..0000000000 --- a/atomic_defi_design/Dex/Exchange/Trade/TickerSelector.qml +++ /dev/null @@ -1,56 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 -import QtGraphicalEffects 1.0 - -import "../../Components" -import "../../Constants" - -SweetDexComboBox -{ - id: combo - - function renewIndex() - { - combo.currentIndex = combo.indexOfValue(ticker) - } - - property bool left_side: false - property var ticker_list - property string ticker - - // Indicates user input, when list changes, index stays the same so we know it's not user input - property bool index_changed: false - - enabled: !block_everything - - model: ticker_list - valueRole: "ticker" - - onTickerChanged: renewIndex() - Component.onCompleted: renewIndex() - - onCurrentIndexChanged: combo.index_changed = true - onCurrentValueChanged: - { - // User input - if(combo.index_changed) - { - combo.index_changed = false - // Set the ticker - if (currentValue !== undefined) - setPair(left_side, currentValue) - } - // List change - else - { - // Correct the index - if (currentText.indexOf(ticker) === -1) - { - const target_index = indexOfValue(ticker) - if(currentIndex !== target_index) - currentIndex = target_index - } - } - } -} diff --git a/atomic_defi_design/Dex/Exchange/Trade/Trade.qml b/atomic_defi_design/Dex/Exchange/Trade/Trade.qml index 9c8c345c8d..9b334ac34f 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/Trade.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/Trade.qml @@ -21,13 +21,9 @@ Item id: exchange_trade readonly property string total_amount: API.app.trading_pg.total_amount - property bool orderSelected: false - property bool isUltraLarge: true // width > 1400 - property bool isBigScreen: width > 1400 Component.onCompleted: { - API.app.trading_pg.on_gui_enter_dex() if (dashboard.current_ticker!==undefined) { onOpened(dashboard.current_ticker) @@ -39,19 +35,6 @@ Item dashboard.current_ticker = undefined } - Component.onDestruction: API.app.trading_pg.on_gui_leave_dex() - - onIsUltraLargeChanged: - { - if (isUltraLarge) { - API.app.trading_pg.orderbook.asks.proxy_mdl.qml_sort( - 0, Qt.DescendingOrder) - } else { - API.app.trading_pg.orderbook.asks.proxy_mdl.qml_sort( - 0, Qt.AscendingOrder) - } - } - readonly property bool block_everything: swap_cooldown.running || fetching_multi_ticker_fees_busy @@ -110,19 +93,28 @@ Item { if (!General.initialized_orderbook_pair) { - General.initialized_orderbook_pair = true - API.app.trading_pg.set_current_orderbook(General.default_base, + if (API.app.trading_pg.current_trading_mode == TradingMode.Pro) + { + API.app.trading_pg.set_current_orderbook(General.default_base, General.default_rel) + } + else + { + API.app.trading_pg.set_current_orderbook(General.default_rel, + General.default_base) + } + General.initialized_orderbook_pair = true } setPair(true, ticker) - app.pairChanged(base_ticker, rel_ticker) + // triggers chart reload (why the duplication?) + // app.pairChanged(base_ticker, rel_ticker) } - function setPair(is_left_side, changed_ticker) { + function setPair(is_left_side, changed_ticker, is_swap=false) { swap_cooldown.restart() - - if (API.app.trading_pg.set_pair(is_left_side, changed_ticker)) - pairChanged(base_ticker, rel_ticker) + if (API.app.trading_pg.set_pair(is_left_side, changed_ticker, is_swap)) + // triggers chart reload + app.pairChanged(base_ticker, rel_ticker) } function trade(options, default_config) { @@ -157,17 +149,46 @@ Item orderPlaced() } + signal orderSelected() signal orderPlaced() readonly property bool buy_sell_rpc_busy: API.app.trading_pg.buy_sell_rpc_busy readonly property var buy_sell_last_rpc_data: API.app.trading_pg.buy_sell_last_rpc_data - Loader + Column { - id: _viewLoader anchors.fill: parent - source: API.app.trading_pg.current_trading_mode == TradingMode.Pro ? "ProView.qml" : "SimpleView/Main.qml" - } + spacing: 15 + anchors.leftMargin: 20 + anchors.rightMargin: 20 + + TradeViewHeader + { + id: header + width: parent.width + height: parent.height * 0.06 + + proViewTickerSelectors: proView.tickerSelectors + proViewTrInfo: proView.trInfo + proViewOrderBook: proView.orderBook + proViewBestOrders: proView.bestOrders + proViewPlaceOrderForm: proView.placeOrderForm + } + + ProView + { + id: proView + width: parent.width + height: parent.height * 0.90 + visible: API.app.trading_pg.current_trading_mode == TradingMode.Pro + enabled: visible + } - TradeViewHeader { } + SimpleView.Main + { + anchors.horizontalCenter: parent.horizontalCenter + visible: API.app.trading_pg.current_trading_mode == TradingMode.Simple + enabled: visible + } + } } diff --git a/atomic_defi_design/Dex/Exchange/Trade/TradeBox/BuyBox.qml b/atomic_defi_design/Dex/Exchange/Trade/TradeBox/BuyBox.qml deleted file mode 100644 index d0049c04d9..0000000000 --- a/atomic_defi_design/Dex/Exchange/Trade/TradeBox/BuyBox.qml +++ /dev/null @@ -1,60 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 - -import Qt.labs.settings 1.0 -import AtomicDEX.MarketMode 1.0 - -import "../../../Components" -import "../../../Wallet" - -import App 1.0 - -FloatingBackground { - property alias can_submit_trade: form_base.can_submit_trade - property alias formBase: form_base - Layout.preferredHeight: !sell_mode ? 350 : 45 - Behavior on Layout.preferredHeight { - NumberAnimation { - duration: 200 - } - } - Layout.fillWidth: true - radius: sell_mode ? 3 : 4 - border.color: Style.colorGreen - color: Style.colorTheme9 - opacity: mouse_area2.containsMouse ? 1 : !sell_mode ? 1 : .2 - Rectangle { - width: parent.width - height: 45 - color: Style.colorGreen - radius: 2 - DefaultText { - anchors.centerIn: parent - text: qsTr("Buy") + " " + atomic_qt_utilities.retrieve_main_ticker(left_ticker) - color: Style.colorTheme9 - font.pixelSize: Style.textSize2 - } - } - - OrderForm { - id: form_base - y: 45 - width: parent.width - 25 - height: parent.height - 45 - clip: true - visible: !sell_mode - border.color: 'transparent' - color: 'transparent' - anchors.horizontalCenter: parent.horizontalCenter - - } - - DefaultMouseArea { - anchors.fill: parent - id: mouse_area2 - visible: sell_mode - hoverEnabled: true - onClicked: setMarketMode(MarketMode.Buy) - } -} \ No newline at end of file diff --git a/atomic_defi_design/Dex/Exchange/Trade/TradeBox/OrderForm.qml b/atomic_defi_design/Dex/Exchange/Trade/TradeBox/OrderForm.qml deleted file mode 100644 index e293049b11..0000000000 --- a/atomic_defi_design/Dex/Exchange/Trade/TradeBox/OrderForm.qml +++ /dev/null @@ -1,213 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 -import QtGraphicalEffects 1.0 - -import AtomicDEX.MarketMode 1.0 -import AtomicDEX.TradingError 1.0 -import "../../../Components" -import App 1.0 -import Dex.Themes 1.0 as Dex - -FloatingBackground -{ - id: root - radius: 10 - - function focusVolumeField() - { - input_volume.forceActiveFocus() - } - - readonly property string total_amount: API.app.trading_pg.total_amount - - readonly property bool can_submit_trade: last_trading_error === TradingError.None - - // Will move to backend: Minimum Fee - function getMaxBalance() - { - if (General.isFilled(base_ticker)) - return API.app.get_balance(base_ticker) - - return "0" - } - - // Will move to backend: Minimum Fee - function getMaxVolume() - { - // base in this orderbook is always the left side, so when it's buy, we want the right side balance (rel in the backend) - const value = sell_mode ? API.app.trading_pg.orderbook.base_max_taker_vol.decimal : - API.app.trading_pg.orderbook.rel_max_taker_vol.decimal - - if (General.isFilled(value)) - return value - - return getMaxBalance() - } - - function setMinimumAmount(value) { API.app.trading_pg.min_trade_vol = value } - - Connections - { - target: exchange_trade - function onBackend_priceChanged() { input_price.text = exchange_trade.backend_price; } - function onBackend_volumeChanged() { input_volume.text = exchange_trade.backend_volume; } - } - - ColumnLayout - { - id: form_layout - width: parent.width - - ColumnLayout - { - Layout.alignment: Qt.AlignTop - Layout.fillWidth: true - Layout.topMargin: 12 - - Item - { - Layout.fillWidth: true - height: input_price.height + price_usd_value.height + price_usd_value.anchors.topMargin - - AmountField - { - id: input_price - - left_text: qsTr("Price") - right_text: atomic_qt_utilities.retrieve_main_ticker(right_ticker) - enabled: !(API.app.trading_pg.preffered_order.price !== undefined) - text: backend_price - width: 261 - height: 41 - radius: 18 - - onTextChanged: setPrice(text) - } - - DefaultText - { - id: price_usd_value - anchors.right: input_price.right - anchors.top: input_price.bottom - anchors.topMargin: 7 - - text_value: General.getFiatText(non_null_price, right_ticker) - font.pixelSize: input_price.font.pixelSize - color: Dex.CurrentTheme.foregroundColor2 - - CexInfoTrigger {} - } - } - - - Item - { - Layout.fillWidth: true - Layout.topMargin: 10 - height: input_volume.height + inputVolumePrice.height + inputVolumePrice.anchors.topMargin - - AmountField - { - id: input_volume - width: 261 - height: 41 - radius: 18 - left_text: qsTr("Volume") - right_text: atomic_qt_utilities.retrieve_main_ticker(left_ticker) - placeholderText: sell_mode ? qsTr("Amount to sell") : qsTr("Amount to receive") - text: API.app.trading_pg.volume - onTextChanged: setVolume(text) - } - - DefaultText - { - id: inputVolumePrice - anchors.right: input_volume.right - anchors.top: input_volume.bottom - anchors.topMargin: price_usd_value.anchors.topMargin - - text_value: General.getFiatText(non_null_volume, left_ticker) - font.pixelSize: input_volume.font.pixelSize - color: Dex.CurrentTheme.foregroundColor2 - - CexInfoTrigger {} - } - } - - DefaultText - { - Layout.alignment: Qt.AlignHCenter - Layout.topMargin: 6 - font.pixelSize: 13 - text: qsTr("Min volume: ") + API.app.trading_pg.min_trade_vol - - DefaultText - { - anchors.left: parent.right - anchors.leftMargin: 8 - anchors.verticalCenter: parent.verticalCenter - - text: General.cex_icon - color: Dex.CurrentTheme.foregroundColor3 - - DefaultMouseArea - { - anchors.fill: parent - onClicked: _sliderHelpModal.open() - } - - ModalLoader - { - id: _sliderHelpModal - sourceComponent: HelpModal - { - title: qsTr("How to use the pro-view slider ?") - helpSentence: qsTr("This slider is used to setup the order requirements you need.\nLeft slider: Sets the minimum amount required to process a trade.\nRight slider: Sets the volume you want to trade.") - } - } - } - } - - DefaultRangeSlider - { - id: _volumeRange - - function getRealValue() { return first.position * (first.to - first.from); } - function getRealValue2() { return second.position * (second.to - second.from); } - - enabled: input_volume.enabled && !(!sell_mode && General.isZero(non_null_price)) && to > 0 - - Layout.alignment: Qt.AlignHCenter - Layout.preferredWidth: parent.width - 20 - - from: API.app.trading_pg.orderbook.current_min_taker_vol - to: Math.max(0, parseFloat(max_volume)) - - first.value: parseFloat(API.app.trading_pg.min_trade_vol) - - firstDisabled: !_useCustomMinTradeAmountCheckbox.checked - - second.value: parseFloat(non_null_volume) - - first.onValueChanged: if (first.pressed) setMinimumAmount(General.formatDouble(first.value)) - second.onValueChanged: if (second.pressed) setVolume(General.formatDouble(second.value)) - } - - DexCheckBox - { - id: _useCustomMinTradeAmountCheckbox - - Layout.topMargin: 15 - Layout.alignment: Qt.AlignHCenter - - boxWidth: 20.76 - boxHeight: 20.76 - text: qsTr("Use custom minimum trade amount") - textColor: Dex.CurrentTheme.foregroundColor3 - font.pixelSize: 13 - spacing: 3 - } - } - } -} diff --git a/atomic_defi_design/Dex/Exchange/Trade/TradeBox/SellBox.qml b/atomic_defi_design/Dex/Exchange/Trade/TradeBox/SellBox.qml deleted file mode 100644 index 665bc6c070..0000000000 --- a/atomic_defi_design/Dex/Exchange/Trade/TradeBox/SellBox.qml +++ /dev/null @@ -1,76 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 - -import Qaterial 1.0 as Qaterial -import Qt.labs.settings 1.0 -import AtomicDEX.MarketMode 1.0 - -import "../../../Components" -import "../../../Wallet" - -import App 1.0 - -Item { - property alias can_submit_trade: form_base.can_submit_trade - property alias formBase: form_base - Layout.preferredHeight: sell_mode ? 350 : 45 - Behavior on Layout.preferredHeight { - NumberAnimation { - duration: 200 - } - } - //color: Style.colorTheme - Layout.fillWidth: true - //radius: sell_mode? 4 : 3 - //border.color: Style.colorRed - //color: Style.colorTheme6 - opacity: mouse_area.containsMouse ? 1 : sell_mode ? 1 : .35 - - Rectangle { - visible: false - width: parent.width - height: 45 - color: Style.colorRed - radius: 6 - Rectangle { - anchors.bottom: parent.bottom - width: parent.width - height: parent.radius - color: Style.colorTheme6 - } - - DefaultText { - anchors.centerIn: parent - anchors.verticalCenterOffset: -2 - text: qsTr("Sell") + " " + atomic_qt_utilities.retrieve_main_ticker(left_ticker) - color: Qaterial.Colors.gray200 - font.pixelSize: Style.textSize1 - } - } - OrderForm { - id: form_base - y: 45 - width: parent.width - 25 - height: parent.height - 45 - //clip: true - visible: sell_mode - border.color: 'transparent' - color: 'transparent' - anchors.horizontalCenter: parent.horizontalCenter - - } - - - - - - - DefaultMouseArea { - anchors.fill: parent - id: mouse_area - visible: !sell_mode - hoverEnabled: true - onClicked: setMarketMode(MarketMode.Sell) - } -} \ No newline at end of file diff --git a/atomic_defi_design/Dex/Exchange/Trade/Trading/Items/FeeInfo.qml b/atomic_defi_design/Dex/Exchange/Trade/Trading/Items/FeeInfo.qml index 4b80814b12..f8ce4d8bc7 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/Trading/Items/FeeInfo.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/Trading/Items/FeeInfo.qml @@ -15,16 +15,17 @@ import "../../../../Constants" import "../../../../Wallet" -Column { +Column +{ id: bg - width: parent.width - - Row { + Row + { width: bg.width height: tx_fee_text.implicitHeight+25 visible: false - ColumnLayout { + ColumnLayout + { id: fees visible: valid_fee_info && !General.isZero(non_null_volume) @@ -32,18 +33,20 @@ Column { Layout.rightMargin: Layout.leftMargin Layout.alignment: Qt.AlignLeft - DefaultText { + DefaultText + { id: tx_fee_text text_value: General.feeText(curr_fee_info, base_ticker, true, true) font.pixelSize: Style.textSizeSmall1 width: parent.width wrapMode: Text.Wrap - CexInfoTrigger {} + DefaultInfoTrigger { triggerModal: cex_info_modal } } } - DefaultText { + DefaultText + { //visible: !fees.visible visible: false text_value: !visible ? "" : diff --git a/atomic_defi_design/Dex/Exchange/Trade/Trading/Items/TotalView.qml b/atomic_defi_design/Dex/Exchange/Trade/Trading/Items/TotalView.qml deleted file mode 100644 index df3539bd8d..0000000000 --- a/atomic_defi_design/Dex/Exchange/Trade/Trading/Items/TotalView.qml +++ /dev/null @@ -1,95 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 -import QtQuick.Controls.Material 2.15 - -import Qaterial 1.0 as Qaterial -import Qt.labs.settings 1.0 - -import "../../../../Components" -import "../../../../Constants" -import Dex.Themes 1.0 as Dex - -Item -{ - anchors.fill: parent - anchors.topMargin: 0 - Item - { - width: parent.width - height: 140 - Column - { - width: parent.width-15 - anchors.horizontalCenter: parent.horizontalCenter - spacing: 5 - leftPadding: 10 - rightPadding: 10 - RowLayout - { - width: parent.width - height: 30 - DefaultText - { - color: Dex.CurrentTheme.foregroundColor3 - text: "Total " + API.app.settings_pg.current_fiat + " " + General.cex_icon - font.pixelSize: 14 - font.weight: Font.Normal - opacity: .6 - CexInfoTrigger {} - } - Item - { - height: 30 - Layout.fillWidth: true - DefaultText - { - anchors.verticalCenter: parent.verticalCenter - anchors.rightMargin: 20 - anchors.right: parent.right - font.weight: Font.DemiBold - font.pixelSize: 16 - font.family: 'lato' - text_value: General.getFiatText(total_amount, right_ticker).replace(General.cex_icon, "") - } - } - } - - HorizontalLine - { - color: Dex.CurrentTheme.lineSeparatorColor - width: parent.width - 20 - anchors.horizontalCenter: parent.horizontalCenter - } - - RowLayout - { - width: parent.width - height: 30 - DexLabel - { - color: Dex.CurrentTheme.foregroundColor3 - text: "Total " + atomic_qt_utilities.retrieve_main_ticker(right_ticker) - font.pixelSize: 14 - opacity: .6 - font.weight: Font.Normal - } - Item - { - height: 30 - Layout.fillWidth: true - DefaultText - { - anchors.verticalCenter: parent.verticalCenter - anchors.rightMargin: 20 - anchors.right: parent.right - font.weight: Font.DemiBold - font.pixelSize: 16 - font.family: 'lato' - text_value: General.formatCrypto("", total_amount, right_ticker).replace(right_ticker, "") - } - } - } - } - } -} diff --git a/atomic_defi_design/Dex/Exchange/Trade/Trading/TradeViewHeader.qml b/atomic_defi_design/Dex/Exchange/Trade/Trading/TradeViewHeader.qml index 80ebe2e2c9..15755c1920 100644 --- a/atomic_defi_design/Dex/Exchange/Trade/Trading/TradeViewHeader.qml +++ b/atomic_defi_design/Dex/Exchange/Trade/Trading/TradeViewHeader.qml @@ -3,124 +3,142 @@ import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 import QtQuick.Controls.Material 2.15 -import Qaterial 1.0 as Qaterial import Qt.labs.settings 1.0 +import Qaterial 1.0 as Qaterial + import AtomicDEX.MarketMode 1.0 import AtomicDEX.TradingError 1.0 import AtomicDEX.TradingMode 1.0 -import "../../../Components" import App 1.0 import Dex.Themes 1.0 as Dex +import "../../../Components" +import "../../../Constants" +// Simple/Pro toggle group Item { - width: parent.width - 5 - anchors.horizontalCenter: parent.horizontalCenter + // property var proViewChart + property var proViewTickerSelectors + property var proViewTrInfo + property var proViewOrderBook + property var proViewBestOrders + property var proViewPlaceOrderForm - ColumnLayout + Item { - anchors.fill: parent - spacing: 50 + width: 350 + height: parent.height - // Simple/Pro toggle group - Item + // Simple/Pro select cursor + Rectangle { - Layout.leftMargin: 30 - Layout.preferredWidth: 120 + id: cursorRect + width: _simpleLabel.width + 28 + height: _simpleLabel.height + 14 + radius: 16 + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: API.app.trading_pg.current_trading_mode == TradingMode.Simple ? _simpleLabel.horizontalCenter : _proLabel.horizontalCenter + color: Dex.CurrentTheme.tabSelectedColor + } - // Simple/Pro select cursor - Rectangle - { - width: 84 - height: 32 - radius: 18 - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: API.app.trading_pg.current_trading_mode == TradingMode.Simple ? _simpleLabel.horizontalCenter : _proLabel.horizontalCenter - color: Dex.CurrentTheme.tabSelectedColor - } + DexLabel + { + id: _simpleLabel + text: "Simple" + color: API.app.trading_pg.current_trading_mode == TradingMode.Simple ? Dex.CurrentTheme.foregroundColor : Dex.CurrentTheme.foregroundColor2 + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + font.pixelSize: 14 + font.weight: Font.Bold - DexLabel + DexMouseArea { - id: _simpleLabel - text: "Simple" - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - font.bold: true - DexMouseArea - { - id: simple_area - hoverEnabled: true - anchors.fill: parent - onClicked: API.app.trading_pg.current_trading_mode = TradingMode.Simple - } + id: simple_area + hoverEnabled: true + anchors.fill: parent + onClicked: API.app.trading_pg.current_trading_mode = TradingMode.Simple } + } - DexLabel + DexLabel + { + id: _proLabel + text: "Pro" + color: API.app.trading_pg.current_trading_mode == TradingMode.Pro ? Dex.CurrentTheme.foregroundColor : Dex.CurrentTheme.foregroundColor2 + anchors.left: _simpleLabel.right + anchors.leftMargin: 10 + cursorRect.width / 2 + anchors.verticalCenter: parent.verticalCenter + font.pixelSize: 14 + font.weight: Font.Bold + + DexMouseArea { - id: _proLabel - text: "Pro" - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - font.bold: true - DexMouseArea - { - id: pro_area - hoverEnabled: true - anchors.fill: parent - onClicked: API.app.trading_pg.current_trading_mode = TradingMode.Pro - } + id: pro_area + hoverEnabled: true + anchors.fill: parent + onClicked: API.app.trading_pg.current_trading_mode = TradingMode.Pro } } - - Item - { - Layout.fillHeight: true - Layout.fillWidth: true - } } - // Options menu present in pro mode. - Rectangle + Qaterial.OutlineButton { + visible: API.app.trading_pg.current_trading_mode == TradingMode.Pro + anchors.right: parent.right - y: -10 - width: 40 - height: 25 - enabled: API.app.trading_pg.current_trading_mode == TradingMode.Pro - visible: enabled - radius: height / 2 - color: !enabled ? 'transparent' : cog_area.containsMouse || _viewLoader.item.dexConfig.visible ? - Dex.CurrentTheme.floatingBackgroundColor : Dex.CurrentTheme.accentColor - - Behavior on color { ColorAnimation { duration: 150 } } - - Qaterial.ColorIcon + + outlined: false + highlighted: false + + foregroundColor: Dex.CurrentTheme.foregroundColor + icon.source: Qaterial.Icons.cog + text: qsTr("Pro View Settings") + font: DexTypo.subtitle1 + + onClicked: { - source: Qaterial.Icons.cog - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - iconSize: 15 - color: !parent.enabled ? 'transparent' : cog_area.containsMouse || _viewLoader.item.dexConfig.visible ? - Dex.CurrentTheme.foregroundColor2 : Dex.CurrentTheme.foregroundColor + proViewCfgMenu.openAt(mapToItem(Overlay.overlay, width / 2, height), Item.Top) } - DexMouseArea + DexPopup { - id: cog_area - hoverEnabled: true - anchors.fill: parent - onClicked: { - if (API.app.trading_pg.current_trading_mode == TradingMode.Pro) + id: proViewCfgMenu + + backgroundColor: Dex.CurrentTheme.floatingBackgroundColor + + contentItem: Item + { + implicitWidth: 200 + implicitHeight: 240 + + Column { - if (_viewLoader.item.dexConfig.visible) - { - _viewLoader.item.dexConfig.close() - } - else - { - _viewLoader.item.dexConfig.openAt(mapToItem(Overlay.overlay, width / 2, height), Item.Top) - } + anchors.fill: parent + padding: 10 + spacing: 8 + + DefaultText { text: qsTr("Display Settings"); font: DexTypo.body2 } + + HorizontalLine { width: parent.width - 20; anchors.horizontalCenter: parent.horizontalCenter; opacity: .4 } + + CheckEye { text: qsTr("Ticker Selectors"); target: proViewTickerSelectors } + + HorizontalLine { width: parent.width - 20; anchors.horizontalCenter: parent.horizontalCenter; opacity: .4 } + + CheckEye { text: qsTr("Trading Information"); target: proViewTrInfo } + + HorizontalLine { width: parent.width - 20; anchors.horizontalCenter: parent.horizontalCenter; opacity: .4 } + + CheckEye { text: qsTr("Order Book"); target: proViewOrderBook } + + HorizontalLine { width: parent.width - 20; anchors.horizontalCenter: parent.horizontalCenter; opacity: .4 } + + CheckEye { text: qsTr("Best Orders"); target: proViewBestOrders } + + HorizontalLine { width: parent.width - 20; anchors.horizontalCenter: parent.horizontalCenter; opacity: .4 } + + CheckEye { text: qsTr("Place Order"); target: proViewPlaceOrderForm } } } } diff --git a/atomic_defi_design/Dex/Graphics/Color.js b/atomic_defi_design/Dex/Graphics/Color.js index 2926e4933e..ea42e4522d 100644 --- a/atomic_defi_design/Dex/Graphics/Color.js +++ b/atomic_defi_design/Dex/Graphics/Color.js @@ -13,13 +13,14 @@ // Returned ARGB string: "#AARRGGBB" function argbStrFromRgbaStr(rgbaString) { - if (rgbaString.length === 7) + let tempRgbaString = rgbaString + if (tempRgbaString.length === 7) { console.warn("Dex.Graphics.Color.argbStrFromRgbaStr: %1 is not an RGBA color" - .arg(rgbaString)); - return rgbaString; + .arg(tempRgbaString)); + return tempRgbaString; } // # A RGB - return "#" + rgbaString.substr(7, 2) + rgbaString.substr(1, 6); + return "#" + tempRgbaString.substr(7, 2) + tempRgbaString.substr(1, 6); } diff --git a/atomic_defi_design/Dex/NewUpdateModal.qml b/atomic_defi_design/Dex/NewUpdateModal.qml new file mode 100644 index 0000000000..4f9d7e3907 --- /dev/null +++ b/atomic_defi_design/Dex/NewUpdateModal.qml @@ -0,0 +1,165 @@ +import QtQuick 2.12 +import QtQuick.Layouts 1.12 +import QtQml 2.15 //> Qt.exit +import QtQuick.Controls 2.15 //> Popup.NoAutoClose + +import "Components" as Dex +import "Constants" as Dex + +Dex.MultipageModal +{ + id: root + + currentIndex: + { + if (Dex.API.app.updateCheckerService.isFetching) + return 0 + else if (Dex.API.app.updateCheckerService.updateInfo.rpcCode !== 200) + return 1 + else if (Dex.API.app.updateCheckerService.updateInfo.updateNeeded) + return 2 + return 3 + } + + Component.onCompleted: + { + if (Dex.API.app.updateCheckerService.updateInfo.status === "recommended" || + Dex.API.app.updateCheckerService.updateInfo.status === "required" ) + { + root.open() + } + } + + closePolicy: Popup.NoAutoClose + + Dex.MultipageModalContent + { + titleText: qsTr("Searching new updates") + titleAlignment: Qt.AlignHCenter + spacing: 16 + + Dex.DefaultText + { + Layout.alignment: Qt.AlignHCenter + text: qsTr("Fetching...") + } + + Dex.DefaultBusyIndicator + { + Layout.topMargin: 12 + Layout.alignment: Qt.AlignHCenter + } + + footer: + [ + Item { Layout.fillWidth: true }, + Dex.DefaultButton + { + text: qsTr("Close") + onClicked: close() + } + ] + } + + Dex.MultipageModalContent + { + titleText: qsTr("Searching new updates") + titleAlignment: Qt.AlignHCenter + spacing: 16 + + Dex.DefaultText + { + text: qsTr("Could not check new updates for the following reason: \n%1").arg(Dex.API.app.updateCheckerService.updateInfo.status) + } + + footer: + [ + Item { Layout.fillWidth: true }, + Dex.DefaultButton + { + text: qsTr("Close") + onClicked: close() + } + ] + } + + Dex.MultipageModalContent + { + titleText: Dex.API.app.updateCheckerService.updateInfo.status === "required" ? qsTr("Mandatory version found") : qsTr("New version found") + titleAlignment: Qt.AlignHCenter + spacing: 16 + + Dex.DefaultText + { + Layout.alignment: Qt.AlignHCenter + text: qsTr("%1 %2 is available !").arg(Dex.API.app_name).arg(Dex.API.app.updateCheckerService.updateInfo.newVersion) + } + + Dex.DefaultText + { + visible: Dex.API.app.updateCheckerService.updateInfo.status === "required" + Layout.alignment: Qt.AlignHCenter + text: qsTr("This update is mandatory to continue using the application") + } + + footer: + [ + Item { Layout.fillWidth: true }, + Dex.DefaultButton + { + Layout.preferredWidth: 120 + text: qsTr("Download") + onClicked: { Qt.openUrlExternally(Dex.API.app.updateCheckerService.updateInfo.downloadUrl); if (Dex.API.app.updateCheckerService.updateInfo.status !== "required") close() } + }, + Dex.DefaultButton + { + Layout.preferredWidth: 120 + text: Dex.API.app.updateCheckerService.updateInfo.status === "required" ? qsTr("Close Dex") : qsTr("Close") + onClicked: Dex.API.app.updateCheckerService.updateInfo.status === "required" ? Qt.exit(0) : close() + } + ] + } + + Dex.MultipageModalContent + { + titleText: qsTr("Searching new updates") + titleAlignment: Qt.AlignHCenter + spacing: 16 + + Dex.DefaultText + { + text: qsTr("Your application is updated.") + } + + footer: + [ + Item { Layout.fillWidth: true }, + Dex.DefaultButton + { + text: qsTr("Close") + onClicked: close() + } + ] + } + + Connections + { + target: Dex.API.app.updateCheckerService + + function onUpdateInfoChanged() + { + if (Dex.API.app.updateCheckerService.updateInfo) + { + if (Dex.API.app.updateCheckerService.updateInfo.status === "recommended" || + Dex.API.app.updateCheckerService.updateInfo.status === "required" ) + { + root.open() + } + else + { + console.error(Dex.API.app.updateCheckerService.updateInfo.status) + } + } + } + } +} diff --git a/atomic_defi_design/Dex/Portfolio/AssetsList.qml b/atomic_defi_design/Dex/Portfolio/AssetsList.qml index 3cd23b0f11..ded8fd3eda 100644 --- a/atomic_defi_design/Dex/Portfolio/AssetsList.qml +++ b/atomic_defi_design/Dex/Portfolio/AssetsList.qml @@ -1,4 +1,4 @@ -import QtQuick 2.12 +import QtQuick 2.15 import QtQuick.Layouts 1.12 import "../Constants" as Dex @@ -8,7 +8,7 @@ import "../Screens" import App 1.0 as Dex import Dex.Themes 1.0 as Dex -Dex.DefaultListView +Dex.DexListView { id: list interactive: false @@ -16,100 +16,93 @@ Dex.DefaultListView model: Dex.API.app.portfolio_pg.portfolio_mdl.portfolio_proxy_mdl property real _assetRowHeight: 46 - property real _assetNameColumnWidth: 160 - property real _assetNameColumnLeftMargin: 15 - property real _assetBalanceColumnWidth: 380 - property real _assetChange24hColumnWidth: 120 - property real _assetPriceColumWidth: 140 - property real _assetProviderColumnWidth: 42 - - width: _assetNameColumnWidth + _assetNameColumnLeftMargin + _assetBalanceColumnWidth + _assetChange24hColumnWidth + _assetPriceColumWidth + _assetProviderColumnWidth + property real _assetNameColumnWidth: 180 + property real _assetBalanceColumnWidth: 190 + property real _fiatBalanceColumnWidth: 180 + property real _assetChange24hColumnWidth: 160 + property real _assetPriceColumWidth: 180 + property real _assetProviderColumnWidth: 90 + + width: _assetNameColumnWidth + _assetBalanceColumnWidth + _fiatBalanceColumnWidth + _assetChange24hColumnWidth + _assetPriceColumWidth + _assetProviderColumnWidth height: (count * _assetRowHeight) + 46 + // Header - header: RowLayout + header: Item { - id: columnsHeader width: list.width height: 40 - Dex.ColumnHeader + RowLayout { - Layout.preferredWidth: _assetNameColumnWidth - _assetNameColumnLeftMargin - Layout.leftMargin: _assetNameColumnLeftMargin - icon_at_left: true - sort_type: sort_by_name - text: qsTr("Asset") - } + id: columnsHeader + anchors.fill: parent - Dex.ColumnHeader - { - Layout.preferredWidth: _assetBalanceColumnWidth - icon_at_left: true - sort_type: sort_by_value - text: qsTr("Balance") - } + Dex.ColumnHeader + { + Layout.preferredWidth: _assetNameColumnWidth + Layout.fillHeight: true + Layout.leftMargin: 15 + h_align: Text.AlignLeft + sort_type: sort_by_name + text: qsTr("Asset") + } - Dex.ColumnHeader - { - Layout.preferredWidth: _assetChange24hColumnWidth - icon_at_left: true - sort_type: sort_by_change - text: qsTr("Change 24h") - } + Dex.ColumnHeader + { + Layout.preferredWidth: _assetBalanceColumnWidth + Layout.fillHeight: true + h_align: Text.AlignRight + sort_type: sort_by_value + text: qsTr("Balance") + } - Dex.ColumnHeader - { - Layout.preferredWidth: _assetPriceColumWidth - icon_at_left: true - sort_type: sort_by_price - text: qsTr("Price") - } + Dex.ColumnHeader + { + Layout.preferredWidth: _fiatBalanceColumnWidth + Layout.fillHeight: true + h_align: Text.AlignRight + sort_type: sort_by_value + text: qsTr("Fiat Balance") + } - Dex.DexLabel - { - Layout.preferredWidth: _assetProviderColumnWidth - text: qsTr("Source") + Dex.ColumnHeader + { + Layout.preferredWidth: _assetChange24hColumnWidth + Layout.fillHeight: true + h_align: Text.AlignRight + sort_type: sort_by_change + text: qsTr("Change 24h") + } + + Dex.ColumnHeader + { + Layout.preferredWidth: _assetPriceColumWidth + Layout.fillHeight: true + h_align: Text.AlignRight + sort_type: sort_by_price + text: qsTr("Price") + } + + Dex.ColumnHeader + { + Layout.preferredWidth: _assetProviderColumnWidth + Layout.fillHeight: true + h_align: Text.AlignHCenter + text: qsTr("Source") + } } } delegate: Rectangle { property color _idleColor: index % 2 === 1 ? Dex.CurrentTheme.backgroundColor : Dex.CurrentTheme.innerBackgroundColor + property int activation_progress: Dex.General.zhtlcActivationProgress(activation_status, ticker) width: list.width height: _assetRowHeight - color: mouseArea.containsMouse ? Dex.CurrentTheme.buttonColorHovered : _idleColor - Dex.DefaultMouseArea - { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - acceptedButtons: Qt.LeftButton | Qt.RightButton - - onClicked: - { - if (!can_change_ticker) - return - if (mouse.button === Qt.RightButton) - contextMenu.popup() - else - { - api_wallet_page.ticker = ticker - dashboard.switchPage(Dashboard.PageType.Wallet) - } - } - - onPressAndHold: - { - if (!can_change_ticker) - return - - if (mouse.source === Qt.MouseEventNotSynthesized) - contextMenu.popup() - } - } + color: mouseArea.containsMouse ? Dex.CurrentTheme.buttonColorHovered : _idleColor RowLayout { @@ -117,16 +110,40 @@ Dex.DefaultListView Item // Asset Column. { + Layout.fillHeight: true Layout.preferredWidth: _assetNameColumnWidth + Layout.leftMargin: 15 - Dex.DefaultImage { + Dex.DexImage { id: assetImage anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: 15 source: Dex.General.coinIcon(ticker) width: 30 height: 30 + + Dex.DexRectangle + { + anchors.centerIn: parent + anchors.fill: parent + radius: 15 + enabled: Dex.General.isZhtlc(ticker) ? activation_progress != 100 : false + visible: enabled + opacity: .9 + color: Dex.DexTheme.backgroundColor + } + + Dex.DexLabel + { + anchors.centerIn: parent + anchors.fill: parent + enabled: Dex.General.isZhtlc(ticker) ? activation_progress != 100 : false + visible: enabled + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + text: activation_progress + "%" + font: Dex.DexTypo.head8 + color: Dex.DexTheme.greenColor + } } Dex.DexLabel @@ -134,7 +151,7 @@ Dex.DefaultListView id: assetNameLabel anchors.top: assetImage.top anchors.left: assetImage.right - anchors.leftMargin: _assetNameColumnLeftMargin + anchors.leftMargin: 15 text: model.ticker } @@ -163,24 +180,58 @@ Dex.DefaultListView color: Dex.DexTheme.redColor } } - } Dex.DexLabel // Balance Column. { id: assetBalanceLabel + Layout.fillHeight: true Layout.preferredWidth: _assetBalanceColumnWidth + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + font: Dex.DexTypo.body2 - text_value: Dex.General.formatCrypto("", balance, ticker, main_currency_balance, - Dex.API.app.settings_pg.current_currency) + text_value: + { + if (Dex.General.isZhtlc(ticker)) + { + if (activation_progress != 100) + { + return qsTr("Activating: ") + activation_progress + "%" + } + } + return parseFloat(balance).toFixed(8) + } + + color: text_value == parseFloat(balance).toFixed(8) ? Qt.darker(Dex.DexTheme.foregroundColor, 0.8) : Dex.DexTheme.redColor + privacy: true + } + + Dex.DexLabel // Fiat Balance + { + id: fiatBalanceLabel + Layout.fillHeight: true + Layout.preferredWidth: _fiatBalanceColumnWidth + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + + font: Dex.DexTypo.body2 + text_value: Dex.General.formatFiat("", main_currency_balance, Dex.API.app.settings_pg.current_currency) + color: Qt.darker(Dex.DexTheme.foregroundColor, 0.8) privacy: true } Dex.DexLabel // Change 24h. { + id: assetChange24hLabel + Layout.fillHeight: true Layout.preferredWidth: _assetChange24hColumnWidth + font: Dex.DexTypo.body2 + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + text_value: { const v = parseFloat(change_24h) @@ -191,18 +242,25 @@ Dex.DefaultListView Dex.DexLabel // Price Column. { + id: price24hLabe + Layout.fillHeight: true Layout.preferredWidth: _assetPriceColumWidth + font: Dex.DexTypo.body2 + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + text_value: Dex.General.formatFiat('', main_currency_price_for_one_unit, - Dex.API.app.settings_pg.current_currency) + Dex.API.app.settings_pg.current_currency, 6) color: Dex.DexTheme.colorThemeDarkLight } Item // Price Provider { + Layout.fillHeight: true Layout.preferredWidth: _assetProviderColumnWidth - Dex.DefaultImage { + Dex.DexImage { id: priceProviderIcon enabled: priceProvider !== "unknown" visible: enabled @@ -233,5 +291,38 @@ Dex.DefaultListView Dex.CoinMenu { id: contextMenu } } + + Dex.DefaultMouseArea + { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + acceptedButtons: Qt.LeftButton | Qt.RightButton + + onClicked: + { + if (!can_change_ticker) + return + if (mouse.button === Qt.RightButton) + { + contextMenu.can_disable = Dex.General.canDisable(ticker) + contextMenu.popup() + } + else + { + api_wallet_page.ticker = ticker + dashboard.switchPage(Dashboard.PageType.Wallet) + } + } + + onPressAndHold: + { + if (!can_change_ticker) return + + if (mouse.source === Qt.MouseEventNotSynthesized) + contextMenu.can_disable = Dex.General.canDisable(ticker) + contextMenu.popup() + } + } } } diff --git a/atomic_defi_design/Dex/Portfolio/Portfolio.qml b/atomic_defi_design/Dex/Portfolio/Portfolio.qml index 38b6f6a9b2..cac69abde3 100644 --- a/atomic_defi_design/Dex/Portfolio/Portfolio.qml +++ b/atomic_defi_design/Dex/Portfolio/Portfolio.qml @@ -122,7 +122,7 @@ Item { Layout.fillWidth: true Layout.fillHeight: true - DexLabel + DefaultText { font: DexTypo.head6 anchors.verticalCenter: parent.verticalCenter @@ -143,11 +143,11 @@ Item { DexGradientAppButton { - width: 150 height: 40 iconSource: Qaterial.Icons.plus radius: 15 - padding: 5 + padding: 25 + font: DexTypo.body2 text: qsTr("ADD ASSET") onClicked: enable_coin_modal.open() } @@ -211,14 +211,13 @@ Item { // Filters (search and balance) Item { - width: parent.width + width: parent.parent.width - 80 + anchors.horizontalCenter: parent.horizontalCenter height: 30 visible: true Item { anchors.fill: parent - anchors.leftMargin: 40 - anchors.rightMargin: 40 anchors.topMargin: 5 RowLayout { @@ -226,6 +225,7 @@ Item { SearchField { + id: coinSearchField Layout.alignment: Qt.AlignVCenter Layout.preferredWidth: 206 Layout.preferredHeight: 42 @@ -240,12 +240,17 @@ Item { Layout.fillWidth: true } - DexCheckBox + DefaultCheckBox { - Layout.alignment: Qt.AlignVCenter + id: hide_zero_balance_checkbox + + spacing: 2 + + label.wrapMode: Label.NoWrap + label.font.pixelSize: 14 text: qsTr("Show only coins with balance") + " %1".arg(qsTr("(%1/%2)").arg(coinsList.count).arg(portfolio_mdl.length)) textColor: Dex.CurrentTheme.foregroundColor2 - label.font.pixelSize: 14 + checked: portfolio_coins.with_balance onCheckedChanged: portfolio_coins.with_balance = checked Component.onDestruction: portfolio_coins.with_balance = false diff --git a/atomic_defi_design/Dex/Screens/Dashboard.qml b/atomic_defi_design/Dex/Screens/Dashboard.qml index a42197895a..95595a6206 100644 --- a/atomic_defi_design/Dex/Screens/Dashboard.qml +++ b/atomic_defi_design/Dex/Screens/Dashboard.qml @@ -16,12 +16,13 @@ import "../Support" import "../Sidebar" as Sidebar import "../Fiat" import "../Settings" as SettingsPage +import "../Support" as SupportPage import "../Screens" +import "../Addressbook" as Addressbook import Dex.Themes 1.0 as Dex -//import Dex.Sidebar 1.0 as Dex - -Item { +Item +{ id: dashboard enum PageType @@ -29,12 +30,11 @@ Item { Portfolio, Wallet, DEX, // DEX == Trading page - Addressbook, - Support + Addressbook } property var currentPage: Dashboard.PageType.Portfolio - property var availablePages: [portfolio, wallet, exchange, addressbook, support] + property var availablePages: [portfolio, wallet, exchange, addressbook] property alias webEngineView: webEngineView @@ -73,8 +73,6 @@ Item { console.warn("Tried to switch to page %1 when loader is not ready yet.".arg(page)) } - function resetCoinFilter() { portfolio_coins.setFilterFixedString("") } - function openTradeViewWithTicker() { dashboard.loader.onLoadComplete = () => { @@ -84,7 +82,22 @@ Item { Layout.fillWidth: true - onCurrentPageChanged: sidebar.currentLineType = currentPage + onCurrentPageChanged: { + sidebar.currentLineType = currentPage + if (currentPage == Dashboard.PageType.DEX) + { + if (API.app.trading_pg.current_trading_mode == TradingMode.Pro) + { + API.app.trading_pg.set_pair(false, api_wallet_page.ticker) + } + else + { + API.app.trading_pg.set_pair(true, api_wallet_page.ticker) + } + } + } + + SupportPage.SupportModal { id: support_modal } // Al settings depends this modal SettingsPage.SettingModal { id: setting_modal } @@ -96,7 +109,7 @@ Item { if (API.app.portfolio_pg.portfolio_mdl.length > atomic_settings2.value("MaximumNbCoinsEnabled")) { open() onTimerEnded = () => { - API.app.settings_pg.reset_coin_cfg() + API.app.reset_coin_cfg() } } } @@ -145,27 +158,7 @@ Item { { id: addressbook - AddressBook {} - } - - Component - { - id: settings - - Settings - { - Layout.alignment: Qt.AlignCenter - } - } - - Component - { - id: support - - Support - { - Layout.alignment: Qt.AlignCenter - } + Addressbook.Main { } } WebEngineView @@ -197,6 +190,78 @@ Item { running: !loader.visible } } + + // Status bar + DefaultRectangle + { + id: status_bar + visible: API.app.zcash_params.is_downloading() + width: parent.width + height: 24 + anchors.bottom: parent.bottom + color: 'transparent' + + DefaultRectangle + { + color: Dex.CurrentTheme.accentColor + width: 380 + height: parent.height + anchors.right: parent.right + radius: 0 + + DefaultProgressBar + { + id: download_progress + anchors.fill: parent + anchors.centerIn: parent + width: parent.width - 10 + height: parent.height + bar_width_pct: 0 + label.text: "Zcash params downloading:" + label.font.family: 'Montserrat' + label.font.pixelSize: 11 + label_width: 180 + pct_value.text: "0.00 %" + pct_value.font.family: 'lato' + pct_value.font.pixelSize: 11 + } + + DexMouseArea + { + id: download_mouse_area + anchors.fill: parent + hoverEnabled: true + onClicked: zcash_params_modal.open() + } + } + Connections + { + target: API.app.zcash_params + function onCombinedDownloadStatusChanged() + { + const filesizes = General.zcash_params_filesize + let combined_sum = Object.values(filesizes).reduce((total, v) => total + v, 0); + + let donwloaded_sum = 0 + let data = JSON.parse(API.app.zcash_params.get_combined_download_progress()) + for (let k in data) { + let v = data[k]; + donwloaded_sum += v * filesizes[k] + } + + let pct = General.formatDouble(donwloaded_sum / combined_sum * 100, 2) + if (pct == 100) + { + API.app.enable_coins(API.app.zcash_params.get_enable_after_download()) + status_bar.visible = false + API.app.zcash_params.clear_enable_after_download() + } + else status_bar.visible = true + download_progress.bar_width_pct = pct + download_progress.pct_value.text = pct + "%" + } + } + } } // Sidebar, left side @@ -208,6 +273,7 @@ Item { onLineSelected: currentPage = lineType; onSettingsClicked: setting_modal.open() + onSupportClicked: support_modal.open() } ModalLoader @@ -219,9 +285,16 @@ Item { // CEX Rates info ModalLoader { - id: cex_rates_modal + id: cex_info_modal sourceComponent: CexInfoModal {} } + + ModalLoader + { + id: gas_info_modal + sourceComponent: GasInfoModal {} + } + ModalLoader { id: min_trade_modal @@ -234,35 +307,66 @@ Item { sourceComponent: RestartModal {} } - function getStatusColor(status) + // Download Zcash Params + property alias zcash_params: zcash_params_modal.item + ModalLoader + { + id: zcash_params_modal + sourceComponent: ZcashParamsModal + { + } + } + + function onEnablingZCoinStatus(coin, msg, human_date, timestamp) + { + // Ignore if coin already enabled (e.g. parent chain in batch) + console.log(msg) + if (msg.search("ZCashParamsNotFound") > -1) + { + console.log(coin) + API.app.zcash_params.enable_after_download(coin) + zcash_params_modal.open() + } + } + + Component.onCompleted: + { + API.app.notification_mgr.enablingZCoinStatus.connect(onEnablingZCoinStatus) + } + Component.onDestruction: + { + API.app.notification_mgr.enablingZCoinStatus.disconnect(onEnablingZCoinStatus) + } + + function isSwapDone(status) { switch (status) { case "matching": - return Style.colorYellow case "matched": case "ongoing": - case "refunding": - return Style.colorOrange + return false case "successful": - return Dex.CurrentTheme.sidebarLineTextHovered + case "refunding": case "failed": default: - return DexTheme.redColor + return true } } - function isSwapDone(status) + function getStatusColor(status) { switch (status) { case "matching": + return Style.colorYellow case "matched": case "ongoing": - return false - case "successful": case "refunding": + return Style.colorOrange + case "successful": + return Dex.CurrentTheme.sidebarLineTextHovered case "failed": default: - return true + return DexTheme.redColor } } @@ -289,18 +393,15 @@ Item { function getStatusFontSize(status) { switch (status) { - case "matching": - return 9 - case "matched": - return 9 - case "ongoing": - return 9 case "successful": return 16 case "refunding": return 16 case "failed": return 12 + case "matching": + case "matched": + case "ongoing": default: return 9 } diff --git a/atomic_defi_design/Dex/Screens/Startup/ImportWallet.qml b/atomic_defi_design/Dex/Screens/Startup/ImportWallet.qml index 1177f81d5d..acb83d2be4 100644 --- a/atomic_defi_design/Dex/Screens/Startup/ImportWallet.qml +++ b/atomic_defi_design/Dex/Screens/Startup/ImportWallet.qml @@ -19,6 +19,8 @@ SetupPage signal backClicked() signal postConfirmSuccess(string walletName) + image_scale: 0.7 + function reset() { text_error = ""; @@ -38,14 +40,13 @@ SetupPage } } - image_scale: 0.7 - - content: DexRectangle + content: DefaultRectangle { color: Dex.CurrentTheme.floatingBackgroundColor width: column_layout.width + 50 height: column_layout.height + 60 radius: 18 + function reset() { recover_seed.reset(); @@ -85,14 +86,14 @@ SetupPage ColumnLayout { id: column_layout - anchors.centerIn: parent - spacing: Style.rowSpacing + RowLayout { Layout.fillWidth: true spacing: 10 + SquareButton { icon.source: Qaterial.Icons.chevronLeft @@ -125,8 +126,6 @@ SetupPage } - - ModalLoader { id: eula_modal @@ -139,6 +138,7 @@ SetupPage } } } + ColumnLayout { visible: currentStep === 0 @@ -158,6 +158,8 @@ SetupPage field.placeholderText: qsTr("Wallet Name") field.onAccepted: tryPassLevel1() field.onTextChanged: text_error = General.validateWallet(input_wallet_name.field.text) + field.forceFocus: true + DefaultRectangle { x: 5 @@ -180,6 +182,7 @@ SetupPage { id: _seedField Layout.fillWidth: true + max_length: General.max_pw_length Layout.preferredHeight: 50 leftIcon: Qaterial.Icons.fileKey field.font: DexTypo.body2 @@ -197,7 +200,7 @@ SetupPage } } - DexLabel + DefaultText { id: _seedError visible: _seedField.error @@ -210,8 +213,16 @@ SetupPage DefaultCheckBox { id: allow_custom_seed + Layout.fillWidth: true + + boxWidth: 20 + boxHeight: 20 + leftPadding: 6 + labelWidth: 120 + label.wrapMode: Label.NoWrap + text: qsTr("Allow custom seed") - leftPadding: 15 + onToggled: { if (allow_custom_seed.checked) @@ -222,10 +233,11 @@ SetupPage closePolicy: Popup.NoAutoClose, text: qsTr("Custom seed phrases might be less secure and easier to crack than a generated BIP39 compliant seed phrase or private key (WIF).

To confirm you understand the risk and know what you are doing, type 'I understand' in the box below."), placeholderText: qsTr("I understand"), + forceFocus: true, standardButtons: Dialog.Yes | Dialog.Cancel, validator: (text) => { - if (text.toLowerCase() === qsTr("i understand")) + if ([qsTr("i understand"), qsTr("я согласен"), qsTr("je comprends"), qsTr("entiendo"), qsTr("anladım"), qsTr("ich verstehe"), ].includes(text.toLowerCase())) { allow_custom_seed.checked = true; } @@ -233,7 +245,7 @@ SetupPage { allow_custom_seed.checked = false; } - return text.toLowerCase() === qsTr("i understand") + return [qsTr("i understand"), qsTr("я согласен"), qsTr("je comprends"), qsTr("entiendo"), qsTr("anladım"), qsTr("ich verstehe"), ].includes(text.toLowerCase()) }, yesButtonText: qsTr("Ok") }) @@ -290,6 +302,7 @@ SetupPage Layout.preferredWidth: 460 Layout.rightMargin: 5 spacing: Style.rowSpacing + DexAppPasswordField { id: _inputPassword @@ -332,7 +345,6 @@ SetupPage Layout.preferredHeight: 10 } - DexGradientAppButton { id: submit_button diff --git a/atomic_defi_design/Dex/Screens/Startup/Login.qml b/atomic_defi_design/Dex/Screens/Startup/Login.qml index 98870b9473..299c505ea2 100644 --- a/atomic_defi_design/Dex/Screens/Startup/Login.qml +++ b/atomic_defi_design/Dex/Screens/Startup/Login.qml @@ -15,17 +15,15 @@ SetupPage property string text_error property string walletName - property bool _isPasswordWrong: false + image_scale: 1 + image_path: Dex.CurrentTheme.bigLogoPath + backgroundColor: 'transparent' + signal backClicked() signal loginSucceeded() - function reset() - { - text_error = "" - } - function onClickedLogin(password) { if (API.app.wallet_mgr.login(password, walletName)) @@ -38,20 +36,13 @@ SetupPage else { console.info("Failed: Login"); - _isPasswordWrong = true; return false; } } - - image_scale: 1 - backgroundColor: 'transparent' - image_path: Dex.CurrentTheme.bigLogoPath - content: ColumnLayout { id: content - spacing: 10 DexLabel @@ -73,20 +64,28 @@ SetupPage { id: _inputPassword Layout.alignment: Qt.AlignHCenter + max_length: General.max_pw_length height: 50 width: 300 background.color: Dex.CurrentTheme.floatingBackgroundColor forceFocus: true + field.onTextChanged: { _isPasswordWrong = false } field.onAccepted: { if (_keyChecker.isValid()) { - onClickedLogin(field.text) + if (!onClickedLogin(field.text)) + { + _inputPassword.error = true; + _isPasswordWrong = true; + } + return true } else { - _inputPassword.error = true - _keyChecker.visible = true + _inputPassword.error = true; + _isPasswordWrong = true; + return false; } } @@ -94,34 +93,20 @@ SetupPage hideFieldButton.icon.color: Dex.CurrentTheme.foregroundColor } - DexKeyChecker - { - id: _passwordChecker - visible: false - field: _inputPassword.field - } - - DefaultText + DexLabel { Layout.alignment: Qt.AlignHCenter - visible: _isPasswordWrong - text: qsTr("Incorrect Password") + height: 14 + text: _isPasswordWrong ? qsTr("Incorrect Password") : "" color: Dex.CurrentTheme.noColor } - Item - { - height: 1 - width: 1 - } - GradientButton { Layout.alignment: Qt.AlignHCenter radius: width width: 200 text: qsTr("Log In") - enabled: _passwordChecker.isValid() onClicked: _inputPassword.field.accepted() } @@ -129,6 +114,7 @@ SetupPage { Layout.alignment: Qt.AlignHCenter id: _keyChecker + max_pw_len: General.max_pw_length field: _inputPassword.field visible: false } diff --git a/atomic_defi_design/Dex/Screens/Startup/NewWallet.qml b/atomic_defi_design/Dex/Screens/Startup/NewWallet.qml index 53ec7078ca..2a2f30e59a 100644 --- a/atomic_defi_design/Dex/Screens/Startup/NewWallet.qml +++ b/atomic_defi_design/Dex/Screens/Startup/NewWallet.qml @@ -8,6 +8,7 @@ import "../../Components" import "../../Constants" import App 1.0 import Dex.Themes 1.0 as Dex +import Dex.Components 1.0 as Dex SetupPage { @@ -158,7 +159,7 @@ SetupPage image_scale: 0.7 - content: DexRectangle + content: Dex.Rectangle { color: Dex.CurrentTheme.floatingBackgroundColor width: column_layout.width + 50 @@ -210,6 +211,7 @@ SetupPage } mmo.model = getRandomWords(4) } + ColumnLayout { id: column_layout @@ -249,7 +251,7 @@ SetupPage } } - DexLabel + Dex.Text { font: DexTypo.head6 text_value: if (currentStep === 0) @@ -274,8 +276,6 @@ SetupPage Layout.fillWidth: true } - - ModalLoader { id: eula_modal @@ -293,6 +293,7 @@ SetupPage ColumnLayout { visible: currentStep === 0 + enabled: visible Layout.preferredWidth: 450 spacing: Style.rowSpacing @@ -309,8 +310,9 @@ SetupPage field.leftPadding: 75 field.placeholderText: "Wallet Name" field.onTextChanged: text_error = General.validateWallet(input_wallet_name.field.text) + field.forceFocus: true - DexRectangle + Dex.Rectangle { x: 5 height: 40 @@ -366,6 +368,7 @@ SetupPage } } } + TextField { id: input_generated_seed @@ -496,11 +499,11 @@ SetupPage } } - // Second page, write the seed word ColumnLayout { visible: currentStep === 1 + enabled: visible DefaultRectangle { @@ -672,6 +675,8 @@ SetupPage ColumnLayout { visible: currentStep === 2 + enabled: visible + Layout.preferredWidth: 450 spacing: Style.rowSpacing diff --git a/atomic_defi_design/Dex/Screens/Startup/WalletsView.qml b/atomic_defi_design/Dex/Screens/Startup/WalletsView.qml index 36de794adc..6d21be4af2 100644 --- a/atomic_defi_design/Dex/Screens/Startup/WalletsView.qml +++ b/atomic_defi_design/Dex/Screens/Startup/WalletsView.qml @@ -87,6 +87,7 @@ SetupPage Layout.fillWidth: true Layout.preferredHeight: 40 placeholderText: qsTr("Search your wallets...") + forceFocus: true onTextChanged: { wallets = API.app.wallet_mgr.get_wallets(text) @@ -186,12 +187,12 @@ SetupPage width: 30 height: width radius: 18 - color: mouse_area.containsMouse ? Dex.CurrentTheme.floatingBackgroundColor : 'transparent' + color: Dex.CurrentTheme.floatingBackgroundColor Qaterial.ColorIcon { anchors.fill: parent - color: Dex.CurrentTheme.loginWalletIconColorStart + color: Dex.CurrentTheme.userIconColorStart source: Qaterial.Icons.account iconSize: 28 } @@ -251,23 +252,25 @@ SetupPage if (API.app.wallet_mgr.confirm_password(wallet_name, text)) { API.app.wallet_mgr.delete_wallet(wallet_name); - app.showText( + app.showDialog( { title: qsTr("Wallet status"), text: "%1 ".arg(wallet_name) + qsTr("wallet deleted successfully"), yesButtonText: qsTr("Ok"), titleBold: true, + showCancelBtn: false, standardButtons: Dialog.Ok }) wallets = API.app.wallet_mgr.get_wallets() } else { - app.showText( + app.showDialog( { title: qsTr("Wallet status"), text: "%1 ".arg(wallet_name) + qsTr("wallet password is incorrect"), warning: true, standardButtons: Dialog.Ok, titleBold: true, + showCancelBtn: false, yesButtonText: qsTr("Ok"), }) } diff --git a/atomic_defi_design/Dex/Settings/AddCustomCoinModal.qml b/atomic_defi_design/Dex/Settings/AddCustomCoinModal.qml index 53016cd6d3..da91a1695a 100644 --- a/atomic_defi_design/Dex/Settings/AddCustomCoinModal.qml +++ b/atomic_defi_design/Dex/Settings/AddCustomCoinModal.qml @@ -4,25 +4,28 @@ import QtQuick.Controls 2.15 import QtQuick.Dialogs 1.3 import AtomicDEX.CoinType 1.0 - import "../Components" import "../Constants" import App 1.0 +import Dex.Themes 1.0 as Dex -MultipageModal { +MultipageModal +{ id: root width: 700 - onClosed: { - // reset all + onClosed: + { currentIndex = 0 reset() } property var config_fields: ({}) - readonly property bool fetching_custom_token_data_busy: API.app.settings_pg.fetching_custom_token_data_busy + property var typeList: ["ERC-20", "QRC-20","BEP-20"] 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 function fetchAssetData() { const fields = General.clone(config_fields) @@ -62,7 +65,7 @@ MultipageModal { addToConfig(input_ticker, "ticker", input_ticker.field.text.toUpperCase()) addToConfig(input_logo, "image_path", input_logo.path.replace(General.os_file_prefix, "")) addToConfig(input_name, "name", input_name.field.text) - addToConfig(input_contract_address, "contract_address", input_contract_address.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) fields['coinType'] = currentType.coinType @@ -74,17 +77,17 @@ MultipageModal { input_ticker.field.text = "" input_logo.path = "" input_name.field.text = "" - input_contract_address.field.text = "" + input_contract_address.text = "" input_active.checked = false input_coingecko_id.field.text = "test-coin" } - property var typeList: ["ERC-20", "QRC-20","BEP-20"] - readonly property string general_message: qsTr('Get the contract address from') - ListModel { + ListModel + { id: type_model - dynamicRoles: true - ListElement { + + ListElement + { text: "ERC-20" prefix: "" image: "erc" @@ -92,7 +95,9 @@ MultipageModal { name: 'Etherscan' coinType: CoinType.ERC20 } - ListElement { + + ListElement + { text: "QRC-20" prefix: "0x" image: "qrc" @@ -100,7 +105,9 @@ MultipageModal { name: 'QTUM Insight' coinType: CoinType.QRC20 } - ListElement { + + ListElement + { text: "BEP-20" prefix: "" url: "https://bscscan.com/tokens" @@ -114,30 +121,50 @@ MultipageModal { property var currentType: type_model.get(input_type.currentIndex) // Type page - MultipageModalContent { + MultipageModalContent + { titleText: qsTr("Choose the asset type") + height: 450 - ComboBoxWithTitle { + DefaultComboBox + { id: input_type Layout.fillWidth: true - title: qsTr("Type") + Layout.preferredHeight: 50 textRole: "text" - model: type_model//, "UTXO", "Smart Chain"] + valueRole: "text" + model: type_model currentIndex: 0 + comboBoxBackgroundColor: Dex.CurrentTheme.comboBoxBackgroundColor + mainBackgroundColor: Dex.CurrentTheme.innerBackgroundColor + popupBackgroundColor: Dex.CurrentTheme.innerBackgroundColor + highlightedBackgroundColor: Dex.CurrentTheme.comboBoxDropdownItemHighlightedColor } + Item { Layout.preferredHeight: 50 } + // Buttons - footer: [ - DefaultButton { + footer: + [ + DefaultButton + { text: qsTr("Cancel") - Layout.fillWidth: true + Layout.preferredWidth: 220 + Layout.preferredHeight: 50 + radius: 18 onClicked: root.previousPage() }, - PrimaryButton { + Item { Layout.fillWidth: true }, + + DefaultButton + { text: qsTr("Next") - Layout.fillWidth: true - onClicked: { + Layout.preferredWidth: 220 + Layout.preferredHeight: 50 + radius: 18 + onClicked: + { root.reset() root.nextPage() } @@ -146,10 +173,12 @@ MultipageModal { } // Ticker page - MultipageModalContent { - titleText: has_contract_address ? qsTr("Enter the contract address") : qsTr("Choose the asset ticker") + MultipageModalContent + { + titleText: has_contract_address ? qsTr("Contract address") : qsTr("Choose the asset ticker") - TextFieldWithTitle { + TextFieldWithTitle + { id: input_ticker enabled: !has_contract_address visible: enabled @@ -158,26 +187,31 @@ MultipageModal { field.placeholderText: qsTr("Enter the ticker") } - AddressFieldWithTitle { + AddressField + { id: input_contract_address enabled: has_contract_address visible: enabled Layout.fillWidth: true - title: qsTr("Contract Address") - field.placeholderText: qsTr("Enter the contract address") - field.left_text: currentType.prefix + placeholderText: qsTr("Enter the contract address") + left_text: currentType.prefix } - DefaultText { + DefaultText + { visible: input_contract_address.visible Layout.fillWidth: true text_value: General.cex_icon + (' ' + qsTr('Get the contract address from ') +currentType.name+ '') } - - InnerBackground { + InnerBackground + { Layout.alignment: Qt.AlignHCenter - content: DefaultAnimatedImage { + Layout.fillWidth: true + color: 'transparent' + + content: DefaultAnimatedImage + { visible: input_contract_address.visible playing: root.visible && visible source: General.image_path + "guide_contract_address_" + currentType.image + ".gif" @@ -185,58 +219,65 @@ MultipageModal { } // Buttons - footer: [ - DefaultButton { + footer: + [ + DefaultButton + { text: qsTr("Previous") - Layout.fillWidth: true + Layout.preferredWidth: 220 + radius: 18 onClicked: root.previousPage() }, - PrimaryButton { + Item { Layout.fillWidth: true }, + + DefaultButton + { text: qsTr("Next") - Layout.fillWidth: true + Layout.preferredWidth: 220 + radius: 18 enabled: (!input_ticker.enabled || input_ticker.field.text !== "") && - (!input_contract_address.enabled || input_contract_address.field.text !== "") + (!input_contract_address.enabled || input_contract_address.text !== "") onClicked: root.nextPage() } ] } // Logo page - MultipageModalContent { + MultipageModalContent + { titleText: qsTr("Choose the asset logo") - DefaultButton { + DefaultButton + { Layout.fillWidth: true text: qsTr("Browse") + "..." onClicked: input_logo.open() } - FileDialog { + FileDialog + { id: input_logo property string path - onFileUrlChanged: path = input_logo.fileUrl.toString() - readonly property bool enabled: true // Config preparation function searches for this title: qsTr("Please choose the asset logo") folder: shortcuts.pictures selectMultiple: false - onAccepted: { - console.log("Image chosen: " + input_logo.path) - } - onRejected: { - console.log("Image choice canceled") - } - - nameFilters: ["Image files (*.png)"]//["Image files (*.jpg *.png)"] + nameFilters: ["Image files (*.png)"] + onFileUrlChanged: path = input_logo.fileUrl.toString() } - InnerBackground { + InnerBackground + { + Layout.fillWidth: true Layout.alignment: Qt.AlignHCenter - content: DefaultImage { + color: 'transparent' + + content: DefaultImage + { width: 300 height: width source: input_logo.path @@ -244,16 +285,21 @@ MultipageModal { } // Buttons - footer: [ - DefaultButton { + footer: + [ + DefaultButton + { text: qsTr("Previous") - Layout.fillWidth: true + Layout.preferredWidth: 220 onClicked: root.previousPage() }, - PrimaryButton { + Item { Layout.fillWidth: true }, + + PrimaryButton + { text: qsTr("Next") - Layout.fillWidth: true + Layout.preferredWidth: 220 enabled: input_logo.path !== "" onClicked: root.nextPage() } @@ -261,16 +307,19 @@ MultipageModal { } // Configuration - MultipageModalContent { + MultipageModalContent + { titleText: qsTr("Configuration") - DefaultText { + DefaultText + { visible: has_contract_address Layout.fillWidth: true text_value: qsTr("All configuration fields will be fetched using the contract address you provided.") } - TextFieldWithTitle { + TextFieldWithTitle + { id: input_name enabled: !has_contract_address visible: enabled @@ -279,22 +328,29 @@ MultipageModal { field.placeholderText: qsTr("Enter the name") } - TextFieldWithTitle { + TextFieldWithTitle + { id: input_coingecko_id Layout.fillWidth: true title: qsTr("Coingecko ID") field.placeholderText: qsTr("Enter the Coingecko ID") } - DefaultText { + DefaultText + { visible: input_coingecko_id.visible Layout.fillWidth: true text_value: General.cex_icon + ' ' + qsTr('Get the Coingecko ID') + '' } - InnerBackground { + InnerBackground + { + Layout.fillWidth: true Layout.alignment: Qt.AlignHCenter - content: DefaultAnimatedImage { + color: 'transparent' + + content: DefaultAnimatedImage + { id: guide_coingecko_id visible: input_coingecko_id.visible playing: root.visible && visible @@ -302,27 +358,33 @@ MultipageModal { } } - DefaultCheckBox { + DefaultCheckBox + { id: input_active enabled: !has_contract_address visible: enabled text: qsTr("Active") } - DefaultBusyIndicator { + DefaultBusyIndicator + { visible: root.fetching_custom_token_data_busy Layout.alignment: Qt.AlignCenter } - // Buttons - footer: [ - DefaultButton { + footer: + [ + DefaultButton + { text: qsTr("Previous") - Layout.fillWidth: true + Layout.preferredWidth: 220 onClicked: root.previousPage() }, - PrimaryButton { + Item { Layout.fillWidth: true }, + + DefaultButton + { text: qsTr("Preview") Layout.fillWidth: true enabled: !root.fetching_custom_token_data_busy && @@ -413,13 +475,15 @@ MultipageModal { footer: [ DefaultButton { text: qsTr("Previous") - Layout.fillWidth: true + Layout.preferredWidth: 220 onClicked: root.previousPage() }, + Item { Layout.fillWidth: true }, + PrimaryButton { text: qsTr("Submit & Restart") - Layout.fillWidth: true + Layout.preferredWidth: 220 enabled: !error_text.visible onClicked: { API.app.settings_pg.submit() diff --git a/atomic_defi_design/Dex/Settings/CamouflagePasswordModal.qml b/atomic_defi_design/Dex/Settings/CamouflagePasswordModal.qml index 52900bb6fe..e0f83cd7a3 100644 --- a/atomic_defi_design/Dex/Settings/CamouflagePasswordModal.qml +++ b/atomic_defi_design/Dex/Settings/CamouflagePasswordModal.qml @@ -6,19 +6,20 @@ import "../Components" import "../Constants" import App 1.0 -MultipageModal { +MultipageModal +{ id: root width: 800 - onClosed: { - input_password_suffix.reset() - } + onClosed: input_password_suffix.reset() - MultipageModalContent { + MultipageModalContent + { titleText: qsTr("Setup Camouflage Password") - FloatingBackground { + FloatingBackground + { id: warning_bg Layout.alignment: Qt.AlignHCenter Layout.bottomMargin: 10 @@ -26,22 +27,25 @@ MultipageModal { width: parent.width - 5 height: warning_texts.height + 20 - Column { + Column + { id: warning_texts anchors.centerIn: parent width: parent.width spacing: 10 - DefaultText { + DefaultText + { width: parent.width - 40 horizontalAlignment: Text.AlignHCenter anchors.horizontalCenter: parent.horizontalCenter text_value: qsTr("Camouflage Password is a secret password for emergency situations.") - font: DexTypo.head6 + font: DexTypo.subtitle2 } - DefaultText { + DefaultText + { width: parent.width - 40 horizontalAlignment: Text.AlignHCenter anchors.horizontalCenter: parent.horizontalCenter @@ -49,7 +53,8 @@ MultipageModal { text_value: qsTr("Using it to login will display your balance lower than it actually is.") } - DefaultText { + DefaultText + { width: parent.width - 40 horizontalAlignment: Text.AlignHCenter anchors.horizontalCenter: parent.horizontalCenter @@ -59,7 +64,8 @@ MultipageModal { } } - PasswordForm { + PasswordForm + { id: input_password_suffix Layout.fillWidth: true field_title: qsTr("Password suffix") @@ -70,24 +76,26 @@ MultipageModal { } // Buttons - footer: [ - DexAppButton { + footer: + [ + DexAppButton + { text: qsTr("Cancel") leftPadding: 40 rightPadding: 40 radius: 20 onClicked: root.close() }, - Item { - Layout.fillWidth: true - }, - DexAppOutlineButton { + Item { Layout.fillWidth: true }, + DexAppOutlineButton + { text: qsTr("Save") leftPadding: 40 rightPadding: 40 radius: 20 enabled: input_password_suffix.isValid() - onClicked: { + onClicked: + { API.app.wallet_mgr.set_emergency_password(input_password_suffix.field.text) root.close() } diff --git a/atomic_defi_design/Dex/Settings/Combo_fiat.qml b/atomic_defi_design/Dex/Settings/Combo_fiat.qml index 8154bfc7c8..0842bb41ef 100644 --- a/atomic_defi_design/Dex/Settings/Combo_fiat.qml +++ b/atomic_defi_design/Dex/Settings/Combo_fiat.qml @@ -13,67 +13,130 @@ import Qaterial 1.0 as Qaterial import "../Components" import "../Constants" import App 1.0 +Item +{ + anchors.margins: 10 + + Column + { + anchors.fill: parent + topPadding: 10 + spacing: 15 + + RowLayout + { + width: parent.width - 30 + anchors.horizontalCenter: parent.horizontalCenter + height: 50 + spacing: 10 + + DexLabel + { + Layout.alignment: Qt.AlignVCenter + font: DexTypo.subtitle1 + text: qsTr("Language") + ":" + } + + Item { Layout.fillWidth: true } + Languages + { + Layout.alignment: Qt.AlignVCenter + } + } -ComboBoxWithTitle { - id: combo_fiat - title: qsTr("Fiat") - width: parent.width-30 - anchors.horizontalCenter: parent.horizontalCenter + RowLayout + { + Layout.topMargin: 10 + width: parent.width - 30 + anchors.horizontalCenter: parent.horizontalCenter + height: 50 + + DexLabel + { + Layout.alignment: Qt.AlignVCenter + Layout.fillWidth: true + font: DexTypo.subtitle1 + text: qsTr("Fiat") + } - model: fiats + Item { Layout.fillWidth: true } + + DexComboBox + { + id: combo_fiat + width: 100 + height: 30 + model: fiats + property bool initialized: false + + onCurrentIndexChanged: + { + if(initialized) + { + const new_fiat = fiats[currentIndex] + API.app.settings_pg.current_fiat = new_fiat + API.app.settings_pg.current_currency = new_fiat + } + } - property bool initialized: false - onCurrentIndexChanged: { - if(initialized) { - const new_fiat = fiats[currentIndex] - API.app.settings_pg.current_fiat = new_fiat - API.app.settings_pg.current_currency = new_fiat + Component.onCompleted: + { + currentIndex = model.indexOf(API.app.settings_pg.current_fiat) + initialized = true + } + } } - } - Component.onCompleted: { - currentIndex = model.indexOf(API.app.settings_pg.current_fiat) - initialized = true - } - RowLayout { - Layout.topMargin: 5 - Layout.fillWidth: true - Layout.leftMargin: 2 - Layout.rightMargin: Layout.leftMargin + RowLayout + { + Layout.topMargin: 10 + width: parent.width - 30 + anchors.horizontalCenter: parent.horizontalCenter + height: 50 + + DexText + { + text: qsTr("Recommended: ") + font.pixelSize: Style.textSizeSmall4 + } - DefaultText { - text: qsTr("Recommended: ") - font.pixelSize: Style.textSizeSmall4 - } + Item { Layout.fillWidth: true } + + Grid + { + Layout.leftMargin: 30 + Layout.alignment: Qt.AlignVCenter - Grid { - Layout.leftMargin: 30 - Layout.alignment: Qt.AlignVCenter + clip: true - clip: true + columns: 6 + spacing: 25 - columns: 6 - spacing: 25 + layoutDirection: Qt.LeftToRight - layoutDirection: Qt.LeftToRight + Repeater + { + model: recommended_fiats - Repeater { - model: recommended_fiats + delegate: DexText + { + text: modelData + color: DexTheme.foregroundColor + opacity: fiats_mouse_area.containsMouse ? .7 : 1 - delegate: DefaultText { - text: modelData - color: DexTheme.foregroundColor - opacity: fiats_mouse_area.containsMouse ? .7 : 1 + DexMouseArea + { + id: fiats_mouse_area + anchors.fill: parent + hoverEnabled: true - DefaultMouseArea { - id: fiats_mouse_area - anchors.fill: parent - hoverEnabled: true - onClicked: { - API.app.settings_pg.current_fiat = modelData - API.app.settings_pg.current_currency = modelData - combo_fiat.currentIndex = combo_fiat.model.indexOf(API.app.settings_pg.current_fiat) + onClicked: + { + API.app.settings_pg.current_fiat = modelData + API.app.settings_pg.current_currency = modelData + combo_fiat.currentIndex = combo_fiat.model.indexOf(API.app.settings_pg.current_fiat) + } } } } @@ -81,3 +144,4 @@ ComboBoxWithTitle { } } } + diff --git a/atomic_defi_design/Dex/Settings/Languages.qml b/atomic_defi_design/Dex/Settings/Languages.qml index eba03ea097..d90a521f49 100644 --- a/atomic_defi_design/Dex/Settings/Languages.qml +++ b/atomic_defi_design/Dex/Settings/Languages.qml @@ -5,57 +5,54 @@ import QtQuick.Controls 2.15 import QtGraphicalEffects 1.0 import "../Components" import "../Constants" +import "../Screens" import App 1.0 -ColumnLayout { - property alias show_label: label.visible - RowLayout { - Layout.alignment: Qt.AlignVCenter - spacing: 5 - DexLabel { - id: label - visible: false - Layout.alignment: Qt.AlignVCenter - font: DexTypo.subtitle1 - text_value: qsTr("Language") + ":" - } - - Grid { - Layout.alignment: Qt.AlignVCenter - Layout.fillWidth: true - - clip: true - - columns: 8 - spacing: 10 - - Repeater { - model: API.app.settings_pg.get_available_langs() - delegate: ClipRRect { - width: 30 // Current icons have too much space around them - height: 30 - radius: 15 - //color: API.app.settings_pg.lang === model.modelData ? Style.colorTheme11 : mouse_area.containsMouse ? Style.colorTheme4 : Style.applyOpacity(Style.colorTheme4) - - DefaultImage { - id: image - anchors.centerIn: parent - source: General.image_path + "lang/" + model.modelData + ".png" - width: 40 - height: 40 - opacity: model.modelData === API.app.settings_pg.lang ? 1 : mouse_area.containsMouse ? 0.85 : 0.7 - // Click area - DefaultMouseArea { - id: mouse_area - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton - hoverEnabled: true - onClicked: { - API.app.settings_pg.lang = model.modelData; - console.info("Switched language to %1".arg(API.app.settings_pg.lang)); - } - } +Grid +{ + Layout.alignment: Qt.AlignVCenter + + clip: true + + columns: 8 + spacing: 10 + + Repeater + { + model: API.app.settings_pg.get_available_langs() + + delegate: ClipRRect + { + width: 30 // Current icons have too much space around them + height: 30 + radius: 15 + //color: API.app.settings_pg.lang === model.modelData ? Style.colorTheme11 : mouse_area.containsMouse ? Style.colorTheme4 : Style.applyOpacity(Style.colorTheme4) + + DexImage + { + id: image + anchors.centerIn: parent + source: General.image_path + "lang/" + model.modelData + ".png" + width: 40 + height: 40 + opacity: model.modelData === API.app.settings_pg.lang ? 1 : mouse_area.containsMouse ? 0.85 : 0.7 + + // Click area + DexMouseArea + { + id: mouse_area + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + hoverEnabled: true + + onClicked: + { + API.app.settings_pg.lang = model.modelData; + console.info("Switched language to %1".arg(API.app.settings_pg.lang)); + menu_list.update() + app.update() + app.pageLoader.item.switchPage(Dashboard.PageType.Portfolio) } } } diff --git a/atomic_defi_design/Dex/Settings/RecoverSeedModal.qml b/atomic_defi_design/Dex/Settings/RecoverSeedModal.qml index 288de4af12..09ec5b13a6 100644 --- a/atomic_defi_design/Dex/Settings/RecoverSeedModal.qml +++ b/atomic_defi_design/Dex/Settings/RecoverSeedModal.qml @@ -16,34 +16,36 @@ MultipageModal property var portfolio_model: API.app.portfolio_pg.portfolio_mdl property var settings_page: API.app.settings_pg - property bool wrongPassword: false + property bool _isPasswordWrong: false function tryViewKeysAndSeed() { if (!submitButton.enabled) return - const result = API.app.settings_pg.retrieve_seed(API.app.wallet_mgr.wallet_default_name, inputPassword.field.text) + const result = API.app.settings_pg.retrieve_seed(API.app.wallet_mgr.wallet_default_name, _inputPassword.field.text) if (result.length === 2) { seedLabel.text = result[0] rpcPwLabel.text = result[1] - wrongPassword = false + _isPasswordWrong = false root.nextPage() loading.running = true } else { - wrongPassword = true + _inputPassword.error = true; + _isPasswordWrong = true; + return false; } } - width: 820 + width: 900 onClosed: { - wrongPassword = false - inputPassword.reset() + _isPasswordWrong = false + _inputPassword.reset() seedLabel.text = "" rpcPwLabel.text = "" portfolio_model.clean_priv_keys() @@ -61,15 +63,26 @@ MultipageModal DexAppPasswordField { - id: inputPassword - Layout.fillWidth: true + id: _inputPassword forceFocus: true + Layout.fillWidth: true + Layout.margins: 20 + Layout.alignment: Qt.AlignHCenter field.onAccepted: tryViewKeysAndSeed() - background.color: Dex.CurrentTheme.floatingBackgroundColor leftIconColor: Dex.CurrentTheme.foregroundColor + field.onTextChanged: { _isPasswordWrong = false } + background.color: Dex.CurrentTheme.accentColor hideFieldButton.icon.color: Dex.CurrentTheme.foregroundColor } + DexLabel + { + Layout.alignment: Qt.AlignHCenter + height: 14 + text: _isPasswordWrong ? qsTr("Incorrect Password") : "" + color: Dex.CurrentTheme.noColor + } + // Footer RowLayout { @@ -86,7 +99,7 @@ MultipageModal { id: submitButton Layout.preferredWidth: parent.width / 100 * 48 - enabled: inputPassword.field.length > 0 + enabled: _inputPassword.field.length > 0 text: qsTr("View") onClicked: tryViewKeysAndSeed() } @@ -96,6 +109,8 @@ MultipageModal MultipageModalContent { titleText: qsTr("View seed and private keys") + titleTopMargin: 15 + topMarginAfterTitle: 15 Timer { @@ -124,23 +139,22 @@ MultipageModal id: seedContainer visible: false enabled: false - spacing: 10 + spacing: 5 + width: parent.width + height: 150 // Logo - ColumnLayout + DefaultImage { - DefaultImage - { - source: Dex.CurrentTheme.bigLogoPath - Layout.alignment: Qt.AlignHCenter - Layout.preferredWidth: 144 - Layout.preferredHeight: 144 - } + source: Dex.CurrentTheme.bigLogoPath + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: 144 + Layout.preferredHeight: 144 } ColumnLayout { - spacing: 10 + spacing: 5 // Seed RowLayout @@ -149,11 +163,11 @@ MultipageModal Qaterial.RawMaterialButton { - backgroundImplicitWidth: 40 + backgroundImplicitWidth: 30 backgroundImplicitHeight: 30 backgroundColor: "transparent" icon.source: Qaterial.Icons.qrcodeScan - icon.color: Dex.CurrentTheme.foregroundColor + icon.color: Dex.CurrentTheme.foregroundColor2 onClicked: { qrcodeModal.qrcodeSvg = API.qt_utilities.get_qrcode_svg_from_string(seedLabel.text) @@ -163,11 +177,11 @@ MultipageModal Qaterial.RawMaterialButton { - backgroundImplicitWidth: 40 + backgroundImplicitWidth: 30 backgroundImplicitHeight: 30 backgroundColor: "transparent" icon.source: Qaterial.Icons.contentCopy - icon.color: Dex.CurrentTheme.foregroundColor + icon.color: Dex.CurrentTheme.foregroundColor2 onClicked: { API.qt_utilities.copy_text_to_clipboard(seedLabel.text) @@ -177,8 +191,21 @@ MultipageModal ColumnLayout { - DefaultText { text: qsTr("Backup Seed"); font.pixelSize: Style.textSizeSmall2 } - DefaultText { id: seedLabel; Layout.fillWidth: true; font.pixelSize: Style.textSizeSmall1; maximumLineCount: 4; wrapMode: Text.Wrap } + DefaultText + { + text: qsTr("Backup Seed") + font.pixelSize: Style.textSizeSmall2 + color: Dex.CurrentTheme.foregroundColor2 + } + + DefaultText + { + id: seedLabel + Layout.fillWidth: true + font.pixelSize: Style.textSizeSmall2 + maximumLineCount: 4 + wrapMode: Text.Wrap + } } } @@ -189,11 +216,11 @@ MultipageModal Qaterial.RawMaterialButton { - backgroundImplicitWidth: 40 + backgroundImplicitWidth: 30 backgroundImplicitHeight: 30 backgroundColor: "transparent" icon.source: Qaterial.Icons.qrcodeScan - icon.color: Dex.CurrentTheme.foregroundColor + icon.color: Dex.CurrentTheme.foregroundColor2 onClicked: { qrcodeModal.qrcodeSvg = API.qt_utilities.get_qrcode_svg_from_string(rpcPwLabel.text) @@ -203,11 +230,11 @@ MultipageModal Qaterial.RawMaterialButton { - backgroundImplicitWidth: 40 + backgroundImplicitWidth: 30 backgroundImplicitHeight: 30 backgroundColor: "transparent" icon.source: Qaterial.Icons.contentCopy - icon.color: Dex.CurrentTheme.foregroundColor + icon.color: Dex.CurrentTheme.foregroundColor2 onClicked: { API.qt_utilities.copy_text_to_clipboard(rpcPwLabel.text) @@ -217,20 +244,33 @@ MultipageModal ColumnLayout { - DefaultText { text: qsTr("RPC Password"); font.pixelSize: Style.textSizeSmall2 } - DefaultText { id: rpcPwLabel; Layout.fillWidth: true; font.pixelSize: Style.textSizeSmall1; maximumLineCount: 4; wrapMode: Text.WrapAnywhere } + DefaultText + { + text: qsTr("RPC Password") + font.pixelSize: Style.textSizeSmall2 + color: Dex.CurrentTheme.foregroundColor2 + } + DefaultText + { + id: rpcPwLabel + Layout.fillWidth: true + font.pixelSize: Style.textSizeSmall2 + maximumLineCount: 4 + wrapMode: Text.WrapAnywhere + } } } } } - HorizontalLine { Layout.topMargin: 10; Layout.fillWidth: true } + HorizontalLine { Layout.fillWidth: true } DefaultTextField { visible: coinsList.visible enabled: coinsList.enabled - Layout.topMargin: 10 + Layout.topMargin: 5 + Layout.bottomMargin: 5 Layout.preferredWidth: parent.width / 3 placeholderText: qsTr("Search a coin.") onTextChanged: portfolio_model.portfolio_proxy_mdl.setFilterFixedString(text) @@ -242,7 +282,6 @@ MultipageModal id: coinsList visible: false enabled: false - Layout.topMargin: 10 Layout.preferredWidth: parent.width Layout.preferredHeight: 300 Layout.alignment: Qt.AlignHCenter @@ -261,32 +300,36 @@ MultipageModal RowLayout { + spacing: 5 Layout.fillWidth: true Layout.leftMargin: 5 ColumnLayout { + spacing: 5 Layout.fillWidth: true DefaultImage { source: General.coinIcon(model.ticker) - Layout.preferredWidth: 30 - Layout.preferredHeight: 30 + Layout.preferredWidth: 40 + Layout.preferredHeight: 40 Layout.alignment: Qt.AlignCenter } DefaultText { text: model.name - font.pixelSize: Style.textSizeSmall5 + font.pixelSize: Style.textSizeSmall4 + color: Dex.CurrentTheme.foregroundColor2 horizontalAlignment: Text.AlignHCenter - Layout.preferredWidth: 100 + Layout.preferredWidth: 90 } } ColumnLayout { + spacing: 5 // Public Address RowLayout { @@ -296,7 +339,7 @@ MultipageModal backgroundImplicitHeight: 30 backgroundColor: "transparent" icon.source: Qaterial.Icons.qrcodeScan - icon.color: Dex.CurrentTheme.foregroundColor + icon.color: Dex.CurrentTheme.foregroundColor2 onClicked: { qrcodeModal.qrcodeSvg = API.qt_utilities.get_qrcode_svg_from_string(publicAddress.text) @@ -310,7 +353,7 @@ MultipageModal backgroundImplicitHeight: 30 backgroundColor: "transparent" icon.source: Qaterial.Icons.contentCopy - icon.color: Dex.CurrentTheme.foregroundColor + icon.color: Dex.CurrentTheme.foregroundColor2 onClicked: { API.qt_utilities.copy_text_to_clipboard(publicAddress.text) @@ -320,20 +363,20 @@ MultipageModal ColumnLayout { + spacing: 5 Layout.fillWidth: true - DefaultText { text: qsTr("Public Address") font.pixelSize: Style.textSizeSmall2 + color: Dex.CurrentTheme.foregroundColor2 } DefaultText { id: publicAddress - text: model.public_address - font.pixelSize: Style.textSizeSmall1 - maximumLineCount: 4; wrapMode: Text.WrapAnywhere + text: model.public_address != 'Invalid Ticker' ? model.public_address : "Please wait for " + model.name + " to fully activate..." + font: model.public_address.length > 70 ? DexTypo.body4 : DexTypo.body3 } } } @@ -341,13 +384,14 @@ MultipageModal // Private Key RowLayout { + spacing: 5 Qaterial.RawMaterialButton { backgroundImplicitWidth: 40 backgroundImplicitHeight: 30 backgroundColor: "transparent" icon.source: Qaterial.Icons.qrcodeScan - icon.color: Dex.CurrentTheme.foregroundColor + icon.color: Dex.CurrentTheme.foregroundColor2 onClicked: { qrcodeModal.qrcodeSvg = API.qt_utilities.get_qrcode_svg_from_string(privateKey.text) @@ -361,30 +405,38 @@ MultipageModal backgroundImplicitHeight: 30 backgroundColor: "transparent" icon.source: Qaterial.Icons.contentCopy - icon.color: Dex.CurrentTheme.foregroundColor + icon.color: Dex.CurrentTheme.foregroundColor2 onClicked: { - API.qt_utilities.copy_text_to_clipboard(privateKey.text) + API.qt_utilities.copy_text_to_clipboard(model.priv_key) app.notifyCopy(model.name, qsTr("Private Key copied to clipboard")) } } ColumnLayout { + spacing: 5 Layout.fillWidth: true DefaultText { text: qsTr("Private Key") font.pixelSize: Style.textSizeSmall2 + color: Dex.CurrentTheme.foregroundColor2 } DefaultText { id: privateKey + font: DexTypo.body3 + text: textMetrics.elidedText + } + TextMetrics { + id: textMetrics + elide: Text.ElideMiddle + font.family: DexTypo.fontFamily + elideWidth: 560 text: model.priv_key - font.pixelSize: Style.textSizeSmall1 - maximumLineCount: 4; wrapMode: Text.WrapAnywhere } } } diff --git a/atomic_defi_design/Dex/Settings/SettingModal.qml b/atomic_defi_design/Dex/Settings/SettingModal.qml index 13e95cd3fc..a600817bec 100644 --- a/atomic_defi_design/Dex/Settings/SettingModal.qml +++ b/atomic_defi_design/Dex/Settings/SettingModal.qml @@ -1,4 +1,3 @@ -//! Qt Imports import QtQuick 2.15 import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 @@ -8,64 +7,40 @@ import QtQml 2.12 import QtQuick.Window 2.12 import QtQuick.Controls.Universal 2.12 -//! 3rdParty Imports import Qaterial 1.0 as Qaterial +import ModelHelper 0.1 -//! Project Imports import "../Components" import "../Constants" -as Constants import App 1.0 - import Dex.Themes 1.0 as Dex - +import Dex.Components 1.0 as Dex Qaterial.Dialog { + id: setting_modal property alias selectedMenuIndex: menu_list.currentIndex - - function disconnect() - { - let dialog = app.showText( - { - "title": qsTr("Confirm Logout"), - text: qsTr("Are you sure you want to log out?"), - standardButtons: Dialog.Yes | Dialog.Cancel, - warning: true, - yesButtonText: qsTr("Yes"), - cancelButtonText: qsTr("Cancel"), - onAccepted: function(text) - { - app.notifications_list = [] - app.currentWalletName = "" - API.app.disconnect() - onDisconnect() - window.logged = false - dialog.close() - dialog.destroy() - } - }) - - } - 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 + 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 + property var orders: API.app.orders_mdl.orders_proxy_mdl.ModelHelper - - id: setting_modal width: 950 height: 650 + padding: 20 + topPadding: 30 + bottomPadding: 30 anchors.centerIn: parent + dim: true modal: true title: "Settings" + + header: Item {} + Overlay.modal: Item { Rectangle @@ -75,19 +50,19 @@ Qaterial.Dialog opacity: .7 } } + background: DexRectangle { color: DexTheme.backgroundColor border.width: 0 radius: 16 } - padding: 20 - topPadding: 30 - bottomPadding: 30 + Item { width: parent.width height: 60 + DexIconButton { anchors.right: parent.right @@ -97,15 +72,18 @@ Qaterial.Dialog anchors.verticalCenter: parent.verticalCenter onClicked: setting_modal.close() } + Row { anchors.verticalCenter: parent.verticalCenter leftPadding: 60 + DexLabel { id: settingLabel anchors.verticalCenter: parent.verticalCenter text: qsTr("Settings") + font: Qt.font( { pixelSize: 20, @@ -122,18 +100,22 @@ Qaterial.Dialog visible: false } } + Item { width: parent.width height: parent.height - 110 y: 60 + RowLayout { anchors.fill: parent + Item { Layout.fillHeight: true Layout.preferredWidth: 280 + ListView { id: menu_list @@ -144,20 +126,24 @@ Qaterial.Dialog spacing: 5 currentIndex: 0 model: [qsTr("General"), qsTr("Language"), qsTr("User Interface"), qsTr("Security"), qsTr("About & Version")] + delegate: DexRectangle { width: parent.width height: 60 radius: 22 border.width: 0 + gradient: Gradient { orientation: Qt.Horizontal + GradientStop { position: 0.0 color: delegateMouseArea.containsMouse ? DexTheme.buttonColorEnabled : menu_list.currentIndex === index ? DexTheme.buttonColorHovered : 'transparent' } + GradientStop { position: 1 @@ -190,34 +176,41 @@ Qaterial.Dialog } } } - Rectangle + + DexRectangle { Layout.fillHeight: true width: 1 color: DexTheme.foregroundColor opacity: .10 } + Item { Layout.fillHeight: true Layout.fillWidth: true + StackLayout { anchors.fill: parent currentIndex: menu_list.currentIndex + Item { anchors.margins: 10 + Column { anchors.fill: parent topPadding: 10 spacing: 15 + RowLayout { width: parent.width - 30 anchors.horizontalCenter: parent.horizontalCenter - height: 30 + height: 50 + DexLabel { Layout.alignment: Qt.AlignVCenter @@ -225,34 +218,46 @@ Qaterial.Dialog font: DexTypo.subtitle1 text: qsTr("Enable Desktop Notifications") } - DefaultSwitch + + Item { Layout.fillWidth: true } + + DexSwitch { Layout.alignment: Qt.AlignVCenter Component.onCompleted: checked = API.app.settings_pg.notification_enabled onCheckedChanged: API.app.settings_pg.notification_enabled = checked } } + RowLayout { width: parent.width - 30 anchors.horizontalCenter: parent.horizontalCenter height: 50 + DexLabel { Layout.alignment: Qt.AlignVCenter - Layout.fillWidth: true font: DexTypo.subtitle1 text: qsTr("Maximum number of enabled coins") } - DefaultComboBox + + Item { Layout.fillWidth: true } + + DexComboBox { id: enableable_coins_count_combo_box - Layout.preferredWidth: 62 - Layout.preferredHeight: 35 - radius: 18 + Layout.alignment: Qt.AlignVCenter + width: 140 + height: 45 + dropDownMaxHeight: 600 model: [10, 20, 50, 75, 100, 150, 200] currentIndex: model.indexOf(parseInt(atomic_settings2.value("MaximumNbCoinsEnabled"))) onCurrentIndexChanged: atomic_settings2.setValue("MaximumNbCoinsEnabled", model[currentIndex]) + Component.onCompleted: + { + currentIndex: model.indexOf(parseInt(atomic_settings2.value("MaximumNbCoinsEnabled"))) + } } } @@ -272,9 +277,10 @@ Qaterial.Dialog height: 50 title: qsTr("Reset wallet configuration") buttonText: qsTr("Reset") + onClicked: { - dialog = app.showText( + reset_dialog = app.showDialog( { title: qsTr("Reset wallet configuration"), text: qsTr("This will restart your wallet with default settings"), @@ -286,124 +292,106 @@ Qaterial.Dialog restart_modal.open() restart_modal.item.onTimerEnded = () => { - API.app.settings_pg.reset_coin_cfg() + API.app.reset_coin_cfg() } } }) - dialog.close() + reset_dialog.close() } } } } - Item - { - Column - { - anchors.fill: parent - topPadding: 10 - spacing: 15 - RowLayout - { - width: parent.width - 30 - anchors.horizontalCenter: parent.horizontalCenter - height: 30 - spacing: 10 - DexLabel - { - Layout.alignment: Qt.AlignVCenter - font: DexTypo.subtitle1 - text: qsTr("Language") + ":" - } - Languages - { - Layout.alignment: Qt.AlignVCenter - } - } - Combo_fiat - { - id: combo_fiat - } - } + Combo_fiat + { + anchors.margins: 10 } Item { + anchors.margins: 10 + Column { anchors.fill: parent topPadding: 10 spacing: 15 + RowLayout { width: parent.width - 30 anchors.horizontalCenter: parent.horizontalCenter - height: 30 - DexLabel + height: 50 + + Dex.Text { Layout.alignment: Qt.AlignVCenter Layout.fillWidth: true font: DexTypo.subtitle1 text: qsTr("Current Font") } - } - DexComboBox - { - editable: true - width: parent.width - 200 - model: ["Ubuntu", "Montserrat", "Roboto"] - onCurrentTextChanged: - { - DexTypo.fontFamily = currentText - console.info(qsTr("Current font changed to %1.").arg(currentText)) - } + Item { Layout.fillWidth: true } - Component.onCompleted: + Dex.ComboBox { - let current = DexTypo.fontFamily - currentIndex = model.indexOf(current) + Layout.alignment: Qt.AlignVCenter + editable: true + model: ["Ubuntu", "Montserrat", "Roboto"] + + onCurrentTextChanged: + { + DexTypo.fontFamily = currentText + console.info(qsTr("Current font changed to %1.").arg(currentText)) + } + + Component.onCompleted: + { + let current = DexTypo.fontFamily + currentIndex = model.indexOf(current) + } } } RowLayout { + Layout.topMargin: 20 width: parent.width - 30 anchors.horizontalCenter: parent.horizontalCenter - height: 30 + height: 50 - DexLabel + Dex.Text { Layout.alignment: Qt.AlignVCenter Layout.fillWidth: true font: DexTypo.subtitle1 text: qsTr("Theme") } - } - DexComboBox - { - width: parent.width - 200 - - model: API.qt_utilities.get_themes_list() + Item { Layout.fillWidth: true } - currentIndex: model.indexOf(atomic_settings2.value("CurrentTheme")) - - onActivated: + Dex.ComboBox { - let chosenTheme = model[index]; + Layout.alignment: Qt.AlignVCenter + model: API.qt_utilities.get_themes_list() + currentIndex: model.indexOf(atomic_settings2.value("CurrentTheme")) - console.info(qsTr("Changing theme to %1").arg(chosenTheme)); - atomic_settings2.setValue("CurrentTheme", chosenTheme); - atomic_settings2.sync(); - Dex.CurrentTheme.loadFromFilesystem(chosenTheme); - } + onActivated: + { + let chosenTheme = model[index]; - Component.onCompleted: - { - let current = atomic_settings2.value("CurrentTheme") - currentIndex = model.indexOf(current) + console.info(qsTr("Changing theme to %1").arg(chosenTheme)); + atomic_settings2.setValue("CurrentTheme", chosenTheme); + atomic_settings2.sync(); + Dex.CurrentTheme.loadFromFilesystem(chosenTheme); + } + + Component.onCompleted: + { + let current = atomic_settings2.value("CurrentTheme") + currentIndex = model.indexOf(current) + } } } } @@ -447,6 +435,7 @@ Qaterial.Dialog width: parent.width - 30 anchors.horizontalCenter: parent.horizontalCenter height: 60 + DexLabel { Layout.fillWidth: true @@ -454,16 +443,69 @@ Qaterial.Dialog font: DexTypo.subtitle1 text: qsTr("Ask system's password before sending coins ? (2FA)") } - DexSwitch + + DefaultSwitch { checked: parseInt(atomic_settings2.value("2FA")) === 1 onCheckedChanged: { - if (checked) + if (checked) { atomic_settings2.setValue("2FA", 1) - else - atomic_settings2.setValue("2FA", 0) - atomic_settings2.sync() + atomic_settings2.sync() + } + else { + var wallet_name = API.app.wallet_mgr.wallet_default_name + let dialog = app.getText( + { + "title": qsTr("Disable 2FA?"), + text: qsTr("Enter your wallet password to confirm"), + standardButtons: Dialog.Yes | Dialog.Cancel, + closePolicy: Popup.NoAutoClose, + warning: true, + iconColor: Dex.CurrentTheme.noColor, + isPassword: true, + placeholderText: qsTr("Type password"), + yesButtonText: qsTr("Confirm"), + cancelButtonText: qsTr("Cancel"), + onRejected: function() + { + checked = true + }, + onAccepted: function(text) + { + if (API.app.wallet_mgr.confirm_password(wallet_name, text)) + { + app.showDialog( + { + title: qsTr("2FA status"), + text: qsTr("2FA disabled successfully"), + yesButtonText: qsTr("Ok"), + titleBold: true, + showCancelBtn: false, + standardButtons: Dialog.Ok + }) + atomic_settings2.setValue("2FA", 0) + atomic_settings2.sync() + } + else + { + app.showDialog( + { + title: qsTr("Wrong password!"), + text: "%1 ".arg(wallet_name) + qsTr("Wallet password is incorrect"), + warning: true, + standardButtons: Dialog.Ok, + titleBold: true, + showCancelBtn: false, + yesButtonText: qsTr("Ok"), + }) + checked = true + } + dialog.close() + dialog.destroy() + } + }); + } } } } @@ -496,6 +538,7 @@ Qaterial.Dialog anchors.fill: parent topPadding: 10 spacing: 15 + ModalLoader { id: delete_wallet_modal @@ -517,6 +560,7 @@ Qaterial.Dialog width: parent.width - 30 anchors.horizontalCenter: parent.horizontalCenter height: 60 + DexLabel { Layout.alignment: Qt.AlignVCenter @@ -531,17 +575,20 @@ Qaterial.Dialog onCopyNotificationMsg: qsTr("copied to clipboard") } } + RowLayout { width: parent.width - 30 anchors.horizontalCenter: parent.horizontalCenter height: 60 + DexLabel { Layout.alignment: Qt.AlignVCenter Layout.fillWidth: true text: qsTr("MM2 version") } + DexCopyableLabel { Layout.alignment: Qt.AlignVCenter @@ -550,17 +597,20 @@ Qaterial.Dialog onCopyNotificationMsg: qsTr("MM2 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("Qt version") } + DexCopyableLabel { Layout.alignment: Qt.AlignVCenter @@ -575,6 +625,7 @@ Qaterial.Dialog } } } + Item { width: parent.width @@ -602,7 +653,7 @@ Qaterial.Dialog family: DexTypo.fontFamily, weight: Font.Normal }) - onClicked: new_update_modal.open() + onClicked: newUpdateModal.open() } DexAppButton @@ -621,11 +672,11 @@ Qaterial.Dialog iconSource: Qaterial.Icons.logout onClicked: { - disconnect() setting_modal.close() + if (orders.count != 0) logout_modal.open() + else return_to_login() } } } - } -} \ No newline at end of file +} diff --git a/atomic_defi_design/Dex/Settings/Settings.qml b/atomic_defi_design/Dex/Settings/Settings.qml deleted file mode 100644 index bfc2f2d838..0000000000 --- a/atomic_defi_design/Dex/Settings/Settings.qml +++ /dev/null @@ -1,263 +0,0 @@ -// Qt Imports -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 -import QtGraphicalEffects 1.0 -import Qt.labs.settings 1.0 - - -// Project Imports -import "../Components" -import "../Constants" -import App 1.0 - -Item { - id: root - function disconnect() { - API.app.disconnect() - onDisconnect() - } - - 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() - - - - InnerBackground { - id: layout_background - anchors.centerIn: parent - Layout.alignment: Qt.AlignHCenter - - width: 650 - height: 750 - - content: ColumnLayout { - width: layout_background.width - height: layout_background.height - - ComboBoxWithTitle - { - id: combo_fiat - - property bool initialized: false - - title: qsTr("Fiat") - Layout.fillWidth: true - Layout.leftMargin: 30 - Layout.rightMargin: Layout.leftMargin - - model: fiats - - onCurrentIndexChanged: - { - if (initialized) - { - const new_fiat = fiats[currentIndex] - API.app.settings_pg.current_fiat = new_fiat - API.app.settings_pg.current_currency = new_fiat - } - } - Component.onCompleted: - { - currentIndex = model.indexOf(API.app.settings_pg.current_fiat) - initialized = true - } - - RowLayout { - Layout.topMargin: 5 - Layout.fillWidth: true - Layout.leftMargin: 2 - Layout.rightMargin: Layout.leftMargin - - DefaultText { - text: qsTr("Recommended: ") - font.pixelSize: Style.textSizeSmall4 - } - - Grid { - Layout.leftMargin: 30 - Layout.alignment: Qt.AlignVCenter - - clip: true - - columns: 6 - spacing: 25 - - layoutDirection: Qt.LeftToRight - - Repeater { - model: recommended_fiats - - delegate: DefaultText { - text: modelData - color: fiats_mouse_area.containsMouse ? Style.colorText : Style.colorText2 - - DefaultMouseArea { - id: fiats_mouse_area - anchors.fill: parent - hoverEnabled: true - onClicked: { - API.app.settings_pg.current_fiat = modelData - API.app.settings_pg.current_currency = modelData - combo_fiat.currentIndex = combo_fiat.model.indexOf(API.app.settings_pg.current_fiat) - } - } - } - } - } - } - } - - HorizontalLine { - Layout.fillWidth: true - Layout.leftMargin: combo_fiat.Layout.leftMargin - Layout.rightMargin: Layout.leftMargin - Layout.topMargin: 10 - } - - Languages { - Layout.alignment: Qt.AlignHCenter - Layout.leftMargin: combo_fiat.Layout.leftMargin - Layout.rightMargin: Layout.leftMargin - } - - HorizontalLine { - Layout.fillWidth: true - Layout.leftMargin: combo_fiat.Layout.leftMargin - Layout.rightMargin: Layout.leftMargin - Layout.topMargin: 10 - } - - DefaultSwitch { - Layout.alignment: Qt.AlignHCenter - Layout.leftMargin: combo_fiat.Layout.leftMargin - Layout.rightMargin: Layout.leftMargin - text: qsTr("Enable Desktop Notifications") - Component.onCompleted: checked = API.app.settings_pg.notification_enabled - onCheckedChanged: API.app.settings_pg.notification_enabled = checked - } - DefaultSwitch { - property bool firstTime: true - Layout.alignment: Qt.AlignHCenter - Layout.leftMargin: combo_fiat.Layout.leftMargin - Layout.rightMargin: Layout.leftMargin - checked: parseInt(atomic_settings2.value("FontMode")) === 1 - text: qsTr("Use QtTextRendering Or NativeTextRendering") - onCheckedChanged: { - if(checked){ - atomic_settings2.setValue("FontMode", 1) - }else { - atomic_settings2.setValue("FontMode", 0) - } - if(firstTime) { - firstTime = false - }else { - restart_modal.open() - } - - } - } - - DefaultButton { - Layout.fillWidth: true - Layout.leftMargin: combo_fiat.Layout.leftMargin - Layout.rightMargin: Layout.leftMargin - text: qsTr("Open Logs Folder") - onClicked: openLogsFolder() - } - - DefaultButton { - Layout.fillWidth: true - Layout.leftMargin: combo_fiat.Layout.leftMargin - Layout.rightMargin: Layout.leftMargin - text: qsTr("View seed and private keys") - onClicked: view_seed_modal.open() - } - - - - HorizontalLine { - Layout.fillWidth: true - Layout.leftMargin: combo_fiat.Layout.leftMargin - Layout.rightMargin: Layout.leftMargin - } - - DefaultButton { - Layout.fillWidth: true - Layout.leftMargin: combo_fiat.Layout.leftMargin - Layout.rightMargin: Layout.leftMargin - text: qsTr("Disclaimer and ToS") - onClicked: eula_modal.open() - } - - ModalLoader { - id: eula_modal - sourceComponent: EulaModal { - close_only: true - } - } - - HorizontalLine { - Layout.fillWidth: true - Layout.leftMargin: combo_fiat.Layout.leftMargin - Layout.rightMargin: Layout.leftMargin - } - - DefaultButton { - visible: !API.app.is_pin_cfg_enabled() - text: qsTr("Setup Camouflage Password") - Layout.fillWidth: true - Layout.leftMargin: combo_fiat.Layout.leftMargin - Layout.rightMargin: Layout.leftMargin - onClicked: camouflage_password_modal.open() - } - - ModalLoader { - id: camouflage_password_modal - sourceComponent: CamouflagePasswordModal {} - } - - DangerButton { - Layout.fillWidth: true - Layout.leftMargin: combo_fiat.Layout.leftMargin - Layout.rightMargin: Layout.leftMargin - text: qsTr("Reset wallet configuration") - onClicked: { - restart_modal.open() - restart_modal.item.onTimerEnded = () => { API.app.settings_pg.reset_coin_cfg() } - } - } - - DangerButton { - text: qsTr("Delete Wallet") - Layout.fillWidth: true - Layout.leftMargin: combo_fiat.Layout.leftMargin - Layout.rightMargin: Layout.leftMargin - onClicked: delete_wallet_modal.open() - } - - ModalLoader { - id: delete_wallet_modal - sourceComponent: DeleteWalletModal {} - } - - DefaultButton { - Layout.fillWidth: true - Layout.leftMargin: combo_fiat.Layout.leftMargin - Layout.rightMargin: Layout.leftMargin - text: qsTr("Log out") - onClicked: disconnect() - } - } - } - - DefaultText { - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.bottomMargin: 10 - anchors.rightMargin: anchors.bottomMargin - text_value: qsTr("mm2 version") + ": " + mm2_version - font.pixelSize: Style.textSizeSmall - } -} diff --git a/atomic_defi_design/Dex/Settings/SettingsButton.qml b/atomic_defi_design/Dex/Settings/SettingsButton.qml index 6224c6eef4..8e53b8cb1d 100644 --- a/atomic_defi_design/Dex/Settings/SettingsButton.qml +++ b/atomic_defi_design/Dex/Settings/SettingsButton.qml @@ -1,9 +1,11 @@ import QtQuick 2.15 import "../Components/" import App 1.0 +import QtQuick.Layouts 1.15 import Qaterial 1.0 as Qaterial -Item { +RowLayout +{ id: control property bool noBackground: false @@ -14,39 +16,50 @@ Item { anchors.horizontalCenter: parent.horizontalCenter - DexLabel { - anchors.verticalCenter: parent.verticalCenter + DexLabel + { + Layout.alignment: Qt.AlignVCenter font: DexTypo.subtitle1 - text: control.title // qsTr("Logs") + text: control.title } - DexAppButton { - visible: control.noBackground - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - text: control.buttonText - color: containsMouse ? DexTheme.buttonColorHovered : 'transparent' - height: 48 - radius: 20 - font: Qt.font({ - pixelSize: 19 , - letterSpacing: 0.15, - family: DexTypo.fontFamily, - underline: true, - weight: Font.Normal - }) - iconSource: Qaterial.Icons.logout - onClicked: control.clicked() - } + Item { Layout.fillWidth: true } + + + Item + { + width: 120 + Layout.alignment: Qt.AlignVCenter + Layout.preferredWidth: 200 + + Row + { + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + + DexAppButton + { + visible: control.noBackground + text: control.buttonText + color: containsMouse ? DexTheme.buttonColorHovered : 'transparent' + height: 40 + radius: 20 + padding: 20 + font: DexTypo.body1 + iconSource: Qaterial.Icons.logout + onClicked: control.clicked() + } - DexAppOutlineButton { - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - leftPadding: 20 - rightPadding: 20 - radius: 20 - visible: !control.noBackground - text: control.buttonText //qsTr("Open Folder") - onClicked: control.clicked() + DexAppOutlineButton + { + height: 40 + padding: 20 + radius: 20 + font: DexTypo.body1 + visible: !control.noBackground + text: control.buttonText + onClicked: control.clicked() + } + } } } diff --git a/atomic_defi_design/Dex/Sidebar/Bottom.qml b/atomic_defi_design/Dex/Sidebar/Bottom.qml index 44411e5da6..18067aba60 100644 --- a/atomic_defi_design/Dex/Sidebar/Bottom.qml +++ b/atomic_defi_design/Dex/Sidebar/Bottom.qml @@ -1,5 +1,8 @@ import QtQuick 2.12 import QtQuick.Layouts 1.2 +import QtQuick.Controls 2.15 +import App 1.0 +import Dex.Themes 1.0 as Dex import "../Components" import "../Constants" @@ -8,7 +11,7 @@ MouseArea { id: root - signal supportLineSelected(var lineType) + signal supportClicked() signal settingsClicked() height: lineHeight * 3 @@ -72,8 +75,7 @@ MouseArea Layout.fillWidth: true label.text: isExpanded ? qsTr("Support") : "" icon.source: General.image_path + "menu-support-white.png" - type: Main.LineType.Support - onClicked: supportLineSelected(type) + onClicked: supportClicked(type) } Line @@ -86,8 +88,59 @@ MouseArea onClicked: { - General.privacy_mode = !General.privacy_mode; - privacySwitch.checked = General.privacy_mode; + if (General.privacy_mode) { + privacySwitch.checked = true + var wallet_name = API.app.wallet_mgr.wallet_default_name + + let dialog = app.getText( + { + title: qsTr("Disable Privacy?"), + text: qsTr("Enter wallet password to confirm"), + standardButtons: Dialog.Yes | Dialog.Cancel, + closePolicy: Popup.NoAutoClose, + warning: true, + iconColor: Dex.CurrentTheme.noColor, + isPassword: true, + placeholderText: qsTr("Type password"), + yesButtonText: qsTr("Confirm"), + cancelButtonText: qsTr("Cancel"), + + onAccepted: function(text) + { + if (API.app.wallet_mgr.confirm_password(wallet_name, text)) + { + General.privacy_mode = false; + privacySwitch.checked = false + app.showDialog( + { + title: qsTr("Privacy status"), + text: qsTr("Privacy mode disabled successfully"), + yesButtonText: qsTr("Ok"), titleBold: true, + showCancelBtn: false, + standardButtons: Dialog.Ok + }) + } + else + { + app.showDialog( + { + title: qsTr("Wrong password!"), + text: "%1 ".arg(wallet_name) + qsTr("wallet password is incorrect"), + warning: true, + showCancelBtn: false, + standardButtons: Dialog.Ok, titleBold: true, + yesButtonText: qsTr("Ok"), + }) + } + dialog.close() + dialog.destroy() + } + }) + } + else { + General.privacy_mode = true; + privacySwitch.checked = true + } } DefaultSwitch @@ -99,7 +152,6 @@ MouseArea anchors.verticalCenter: parent.verticalCenter scale: 0.75 mouseArea.hoverEnabled: true - onClicked: parent.clicked() } } diff --git a/atomic_defi_design/Dex/Sidebar/Main.qml b/atomic_defi_design/Dex/Sidebar/Main.qml index 0db5960726..d4a47b7d38 100644 --- a/atomic_defi_design/Dex/Sidebar/Main.qml +++ b/atomic_defi_design/Dex/Sidebar/Main.qml @@ -25,6 +25,7 @@ Item signal lineSelected(var lineType) signal settingsClicked() + signal supportClicked() signal privacySwitched(var checked) signal expanded(var isExpanded) signal expandStarted(var isExpanding) @@ -114,14 +115,8 @@ Item anchors.bottom: parent.bottom anchors.bottomMargin: 62 - onSupportLineSelected: - { - if (currentLineType === lineType) - return; - currentLineType = lineType; - root.lineSelected(lineType); - } onSettingsClicked: root.settingsClicked() + onSupportClicked: root.supportClicked() } VerticalLine diff --git a/atomic_defi_design/Dex/Support/FAQLine.qml b/atomic_defi_design/Dex/Support/FAQLine.qml index 6ca1d25975..3c9e7a2c7c 100644 --- a/atomic_defi_design/Dex/Support/FAQLine.qml +++ b/atomic_defi_design/Dex/Support/FAQLine.qml @@ -11,4 +11,6 @@ TextWithTitle { expandable: true Layout.fillWidth: true Layout.rightMargin: 10 + text_font.pixelSize: 14 + title_font.pixelSize: 18 } diff --git a/atomic_defi_design/Dex/Support/Support.qml b/atomic_defi_design/Dex/Support/Support.qml deleted file mode 100644 index 256d48dc81..0000000000 --- a/atomic_defi_design/Dex/Support/Support.qml +++ /dev/null @@ -1,179 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 - -import QtGraphicalEffects 1.0 -import "../Components" -import "../Constants" - -import App 1.0 - -Item { - id: root - - readonly property bool update_needed: API.app.self_update_service.update_needed - - DexFlickable { - id: layout_background - - width: parent.width - 20 - height: parent.height - 20 - y: 10 - x: 20 - contentWidth: width - 20 - contentHeight: content_layout.height - - ColumnLayout { - id: content_layout - width: parent.width - spacing: 40 - - Item { - Layout.topMargin: parent.spacing - Layout.fillWidth: true - Layout.preferredHeight: 80 - - LinksRow { - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - } - - DefaultMouseArea { - id: changelog_button - - anchors.centerIn: parent - width: column_layout.width - height: column_layout.height - hoverEnabled: true - - onClicked: update_modal.open() - - ColumnLayout { - id: column_layout - RowLayout { - Layout.alignment: Qt.AlignHCenter - - Circle { - Layout.alignment: Qt.AlignVCenter - - color: Qt.lighter(update_needed ? Style.colorOrange : Style.colorGreen, changelog_button.containsMouse ? Style.hoverLightMultiplier : 1.0) - } - - DefaultText { - Layout.alignment: Qt.AlignVCenter - text_value: update_needed ? qsTr("Update available") : qsTr("Up to date") - color: changelog_text.color - } - } - - DefaultText { - Layout.alignment: Qt.AlignHCenter - text_value: General.version_string - font.pixelSize: Style.textSizeSmall3 - color: changelog_text.color - } - - DefaultText { - id: changelog_text - Layout.alignment: Qt.AlignHCenter - text_value: General.cex_icon + ' ' + qsTr('Changelog') - font.pixelSize: Style.textSizeSmall2 - - color: Qt.lighter(Style.colorWhite4, changelog_button.containsMouse ? Style.hoverLightMultiplier : 1.0) - } - } - } - - DefaultButton { - anchors.right: parent.right - anchors.rightMargin: 20 - anchors.verticalCenter: parent.verticalCenter - text: qsTr("Open Logs Folder") - onClicked: openLogsFolder() - } - } - - HorizontalLine { - Layout.fillWidth: true - } - - DefaultText { - Layout.alignment: Qt.AlignHCenter - text_value: qsTr("Frequently Asked Questions") - font.pixelSize: Style.textSize2 - } - - - - - - - - - - - - // FAQ Lines - FAQLine { - title: qsTr("Do you store my private keys?") - text: qsTr("No! %1 is non-custodial. We never store any sensitive data, including your private keys, seed phrases, or PIN. This data is only stored on the user’s device and never leaves it. You are in full control of your assets.").arg(API.app_name) - } - - FAQLine { - title: qsTr("How is trading on %1 different from trading on other DEXs?").arg(API.app_name) - text: qsTr("Other DEXs generally only allow you to trade assets that are based on a single blockchain network, use proxy tokens, and only allow placing a single order with the same funds. - -%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("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) - } - - 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. -The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. -If you go offline, so will your orders, and any that are in progress will fail, leading to potential loss of trade / transaction fees, and a wait for the swap to timeout and issue a refund. It may also negatively affect your wallet's reputation score for future trade matching. -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.").arg(API.app_name) - } - - FAQLine { - title: qsTr("How are the fees on %1 calculated?").arg(API.app_name) - text: qsTr("There are two fee categories to consider when trading on %1. - -1. %1 charges approximately 0.13% (1/777 of trading volume but not lower than 0.0001) as the trading fee for taker orders, and maker orders have zero fees. -2. Both makers and takers will need to pay normal network fees to the involved blockchains when making atomic swap transactions. - -Network fees can vary greatly depending on your selected trading pair.").arg(API.app_name) - } - - FAQLine { - title: qsTr("Do you provide user support?") - text: qsTr('Yes! %1 offers support through the %1 Discord server. The team and the community are always happy to help!').arg(API.app_name).arg(API.app_discord_url) - } - - FAQLine { - title: qsTr("Who is behind %1?").arg(API.app_name) - text: qsTr("%1 is developed by the Komodo team. Komodo is one of the most established blockchain projects working on innovative solutions like atomic swaps, Delayed Proof of Work, and an interoperable multi-chain architecture.").arg(API.app_name) - } - - FAQLine { - title: qsTr("Is it possible to develop my own white-label exchange on %1?").arg(API.app_name) - text: qsTr("Absolutely! You can read our developer documentation for more details or contact us with your partnership inquiries. Have a specific technical question? The %1 developer community is always ready to help!").arg(API.app_name) - } - - FAQLine { - title: qsTr("Which devices can I use %1 on?").arg(API.app_name) - text: qsTr('%1 is available for mobile on both Android and iPhone, and for desktop on Windows, Mac, and Linux operating systems.').arg(API.app_name).arg(API.app_website_url) - } - - FAQLine { - title: qsTr("Compliance Info") - text: qsTr("Due to regulatory and legal circumstances the citizens of certain jurisdictions including, but not limited to, the United States of America, Canada, Hong Kong, Israel, Singapore, Sudan, Austria, Iran and any other state, country or other jurisdiction that is embargoed by the United States of America or the European Union are not allowed to use this application.") - } - } - } -} diff --git a/atomic_defi_design/Dex/Support/SupportModal.qml b/atomic_defi_design/Dex/Support/SupportModal.qml new file mode 100644 index 0000000000..3c197c9b4f --- /dev/null +++ b/atomic_defi_design/Dex/Support/SupportModal.qml @@ -0,0 +1,250 @@ +//! Qt Imports +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 +import QtGraphicalEffects 1.0 +import Qt.labs.settings 1.0 +import QtQml 2.12 +import QtQuick.Window 2.12 +import QtQuick.Controls.Universal 2.12 + +//! 3rdParty Imports +import Qaterial 1.0 as Qaterial + +//! Project Imports +import "../Components" +import "../Constants" +import App 1.0 +import Dex.Themes 1.0 as Dex + + +Qaterial.Dialog +{ + id: support_modal + //readonly property bool update_needed: API.app.self_update_service.update_needed + + width: 950 + height: 650 + padding: 20 + topPadding: 30 + bottomPadding: 30 + anchors.centerIn: parent + + dim: true + modal: true + title: "Support" + + header: Item + {} + + Overlay.modal: Item + { + DexRectangle + { + anchors.fill: parent + color: 'black' + opacity: .7 + } + } + + background: DexRectangle + { + color: DexTheme.backgroundColor + border.width: 0 + radius: 16 + } + + ColumnLayout + { + id: support_layout + width: support_modal.width - 100 + Layout.alignment: Qt.AlignHCenter + + RowLayout + { + id: faq_title + height: 30 + Layout.preferredWidth: faq_column.width + Layout.topMargin: 20 + Layout.bottomMargin: 20 + Layout.leftMargin: 42 + DexLabel + { + id: faq_label + Layout.preferredWidth: faq_title.width + text_value: qsTr("Frequently Asked Questions") + font.pixelSize: Style.textSize2 + horizontalAlignment: Text.AlignHCenter + } + } + + DexFlickable + { + id: faq_flickable + + width: support_modal.width - 100 + height: support_modal.height - 220 + contentWidth: width - 20 + contentHeight: faq_column.height + Layout.leftMargin: 32 + + ColumnLayout + { + id: faq_column + width: parent.width - 5 + spacing: 12 + + + // FAQ Lines + FAQLine + { + title: qsTr("Do you store my private keys?") + text: qsTr("No! %1 is non-custodial. We never store any sensitive data, including your private keys, seed phrases, or PIN. This data is only stored on the user’s device and never leaves it. You are in full control of your assets.").arg(API.app_name) + } + + FAQLine + { + title: qsTr("How is trading on %1 different from trading on other DEXs?").arg(API.app_name) + text: qsTr("Other DEXs generally only allow you to trade assets that are based on a single blockchain network, use proxy tokens, and only allow placing a single order with the same funds. + +%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("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) + } + + 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. + +The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. + +If you go offline, so will your orders, and any that are in progress will fail, leading to potential loss of trade / transaction fees, and a wait for the swap to timeout and issue a refund. It may also negatively affect your wallet's reputation score for future trade matching. + +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.").arg(API.app_name) + } + + FAQLine + { + title: qsTr("How are the fees on %1 calculated?").arg(API.app_name) + text: qsTr("There are two fee categories to consider when trading on %1. + +1. %1 charges approximately 0.13% (1/777 of trading volume but not lower than 0.0001) as the trading fee for taker orders, and maker orders have zero fees. + +2. Both makers and takers will need to pay normal network fees to the involved blockchains when making atomic swap transactions. + +Network fees can vary greatly depending on your selected trading pair.").arg(API.app_name) + } + + FAQLine + { + title: qsTr("Do you provide user support?") + text: qsTr('Yes! %1 offers support through the %1 Discord server. The team and the community are always happy to help!').arg(API.app_name).arg(API.app_discord_url) + } + + FAQLine + { + title: qsTr("Who is behind %1?").arg(API.app_name) + text: qsTr("%1 is developed by the Komodo team. Komodo is one of the most established blockchain projects working on innovative solutions like atomic swaps, Delayed Proof of Work, and an interoperable multi-chain architecture.").arg(API.app_name) + } + + FAQLine + { + title: qsTr("Is it possible to develop my own white-label exchange on %1?").arg(API.app_name) + text: qsTr("Absolutely! You can read our developer documentation for more details or contact us with your partnership inquiries. Have a specific technical question? The %1 developer community is always ready to help!").arg(API.app_name) + } + + FAQLine + { + title: qsTr("Which devices can I use %1 on?").arg(API.app_name) + text: qsTr('%1 is available for mobile on both Android and iPhone, and for desktop on Windows, Mac, and Linux operating systems.').arg(API.app_name).arg(API.app_website_url) + } + + FAQLine + { + title: qsTr("Compliance Info") + text: qsTr("Due to regulatory and legal circumstances the citizens of certain jurisdictions including, but not limited to, the United States of America, Canada, Hong Kong, Israel, Singapore, Sudan, Austria, Iran and any other state, country or other jurisdiction that is embargoed by the United States of America or the European Union are not allowed to use this application.") + } + } + } + + RowLayout + { + id: bottom_row + Layout.topMargin: 20 + Layout.preferredHeight: 70 + Layout.preferredWidth: faq_title.width + Layout.leftMargin: 32 + property var filler_width: (parent.width - links_row.width - changelog_button.width - logs_btn.width) / 2 - 14 + + LinksRow { id: links_row } + + Item { Layout.preferredWidth: bottom_row.filler_width } + + DexMouseArea + { + id: changelog_button + + Layout.preferredWidth: column_layout.width + Layout.preferredHeight: column_layout.height + hoverEnabled: true + + onClicked: update_modal.open() + + ColumnLayout + { + id: column_layout + RowLayout + { + Layout.alignment: Qt.AlignHCenter + + Circle + { + Layout.alignment: Qt.AlignVCenter + //color: Qt.lighter(update_needed ? Style.colorOrange : Style.colorGreen, changelog_button.containsMouse ? Style.hoverLightMultiplier : 1.0) + } + + DexLabel + { + Layout.alignment: Qt.AlignVCenter + //text_value: //update_needed ? qsTr("Update available") : qsTr("Up to date") + color: changelog_text.color + } + } + + DexLabel + { + Layout.alignment: Qt.AlignHCenter + text_value: General.version_string + font.pixelSize: Style.textSizeSmall3 + color: changelog_text.color + } + + DexLabel + { + id: changelog_text + Layout.alignment: Qt.AlignHCenter + text_value: General.cex_icon + ' ' + qsTr('Changelog') + font.pixelSize: Style.textSizeSmall2 + } + } + } + + Item { Layout.preferredWidth: bottom_row.filler_width } + + DexAppButton + { + id: logs_btn + width: 200 + text: qsTr("Open Logs Folder") + onClicked: openLogsFolder() + } + } + } +} diff --git a/atomic_defi_design/Dex/Tests/ThemeTest.qml b/atomic_defi_design/Dex/Tests/ThemeTest.qml deleted file mode 100644 index 49ce86ac4e..0000000000 --- a/atomic_defi_design/Dex/Tests/ThemeTest.qml +++ /dev/null @@ -1,44 +0,0 @@ -import QtQuick 2.15 -import Qaterial 1.0 as Qaterial - -import Dex.Themes 1.0 as Dex - - -Item -{ - id: root - Column - { - padding: 10 - spacing: 10 - Repeater - { - model: 20 - Rectangle - { - width: 200 - height: 10 - color: Dex.CurrentTheme.backgroundColor - } - } - - } - - function listProperty(item) - { - for (var p in item) - { - if (typeof item[p] != "function") - if (p != "objectName") - console.log(p + ":" + item[p]); - } - - } - Component.onCompleted: - { - - listProperty(root) - - } - -} \ No newline at end of file diff --git a/atomic_defi_design/Dex/Themes/CurrentTheme.qml b/atomic_defi_design/Dex/Themes/CurrentTheme.qml index 06fafacb7b..a39439456c 100644 --- a/atomic_defi_design/Dex/Themes/CurrentTheme.qml +++ b/atomic_defi_design/Dex/Themes/CurrentTheme.qml @@ -94,6 +94,8 @@ ThemeData backgroundColor = Dex.Color.argbStrFromRgbaStr(themeData.backgroundColor || defaultTheme.backgroundColor); backgroundColorDeep = Dex.Color.argbStrFromRgbaStr(themeData.backgroundColorDeep || defaultTheme.backgroundColorDeep); + busyIndicatorColor = Dex.Color.argbStrFromRgbaStr(themeData.busyIndicatorColor || defaultTheme.busyIndicatorColor); + buttonColorDisabled = Dex.Color.argbStrFromRgbaStr(themeData.buttonColorDisabled || defaultTheme.buttonColorDisabled); buttonColorEnabled = Dex.Color.argbStrFromRgbaStr(themeData.buttonColorEnabled || defaultTheme.buttonColorEnabled); buttonColorHovered = Dex.Color.argbStrFromRgbaStr(themeData.buttonColorHovered || defaultTheme.buttonColorHovered); @@ -116,6 +118,7 @@ ThemeData gradientButtonTextHoveredColor = Dex.Color.argbStrFromRgbaStr(themeData.gradientButtonTextHoveredColor || defaultTheme.gradientButtonTextHoveredColor); gradientButtonTextPressedColor = Dex.Color.argbStrFromRgbaStr(themeData.gradientButtonTextPressedColor || defaultTheme.gradientButtonTextPressedColor); + checkBoxTickColor = Dex.Color.argbStrFromRgbaStr(themeData.checkBoxTickColor || defaultTheme.checkBoxTickColor); checkBoxGradientStartColor = Dex.Color.argbStrFromRgbaStr(themeData.checkBoxGradientStartColor || defaultTheme.checkBoxGradientStartColor); checkBoxGradientEndColor = Dex.Color.argbStrFromRgbaStr(themeData.checkBoxGradientEndColor || defaultTheme.checkBoxGradientEndColor); @@ -165,8 +168,8 @@ ThemeData rangeSliderIndicatorBackgroundStartColor = Dex.Color.argbStrFromRgbaStr(themeData.rangeSliderIndicatorBackgroundStartColor || defaultTheme.rangeSliderIndicatorBackgroundStartColor); rangeSliderIndicatorBackgroundEndColor = Dex.Color.argbStrFromRgbaStr(themeData.rangeSliderIndicatorBackgroundEndColor || defaultTheme.rangeSliderIndicatorBackgroundEndColor); - loginWalletIconColorStart = Dex.Color.argbStrFromRgbaStr(themeData.loginWalletIconColorStart || defaultTheme.loginWalletIconColorStart) - loginWalletIconColorEnd = Dex.Color.argbStrFromRgbaStr(themeData.loginWalletIconColorEnd || defaultTheme.loginWalletIconColorEnd) + userIconColorStart = Dex.Color.argbStrFromRgbaStr(themeData.userIconColorStart || defaultTheme.userIconColorStart) + userIconColorEnd = Dex.Color.argbStrFromRgbaStr(themeData.userIconColorEnd || defaultTheme.userIconColorEnd) sidebarBgColor = Dex.Color.argbStrFromRgbaStr(themeData.sidebarBgColor || defaultTheme.sidebarBgColor); sidebarVersionTextColor = Dex.Color.argbStrFromRgbaStr(themeData.sidebarVersionTextColor || defaultTheme.sidebarVersionTextColor); @@ -181,11 +184,17 @@ ThemeData tradeSellModeSelectorBackgroundColorEnd = Dex.Color.argbStrFromRgbaStr(themeData.tradeSellModeSelectorBackgroundColorEnd || defaultTheme.tradeSellModeSelectorBackgroundColorEnd); tradeMarketModeSelectorNotSelectedBackgroundColor = Dex.Color.argbStrFromRgbaStr(themeData.tradeMarketModeSelectorNotSelectedBackgroundColor || defaultTheme.tradeMarketModeSelectorNotSelectedBackgroundColor); + addressBookTagColors = themeData.addressBookTagColors || defaultTheme.addressBookTagColors + for (var i = 0; i < addressBookTagColors.length; i++) + { + addressBookTagColors[i] = Dex.Color.argbStrFromRgbaStr(addressBookTagColors[i]) + } + okColor = Dex.Color.argbStrFromRgbaStr(themeData.okColor || defaultTheme.okColor); noColor = Dex.Color.argbStrFromRgbaStr(themeData.noColor || defaultTheme.noColor); - arrowUpColor = Dex.Color.argbStrFromRgbaStr(themeData.arrowUpColor || defaultTheme.arrowUpColor); - arrowDownColor = Dex.Color.argbStrFromRgbaStr(themeData.arrowDownColor || defaultTheme.arrowDownColor); + senderColorStart = Dex.Color.argbStrFromRgbaStr(themeData.senderColorStart || defaultTheme.senderColorStart); + receiverColorStart = Dex.Color.argbStrFromRgbaStr(themeData.receiverColorStart || defaultTheme.receiverColorStart); lineSeparatorColor = Dex.Color.argbStrFromRgbaStr(themeData.lineSeparatorColor || defaultTheme.lineSeparatorColor); } @@ -208,6 +217,8 @@ ThemeData console.info("Dex.Themes.CurrentTheme.printValues.backgroundColor : %1".arg(backgroundColor)); console.info("Dex.Themes.CurrentTheme.printValues.backgroundColorDeep : %1".arg(backgroundColorDeep)); + console.info("Dex.Themes.CurrentTheme.printValues.busyIndicatorColor : %1".arg(busyIndicatorColor)); + console.info("Dex.Themes.CurrentTheme.printValues.buttonColorDisabled : %1".arg(buttonColorDisabled)); console.info("Dex.Themes.CurrentTheme.printValues.buttonColorEnabled : %1".arg(buttonColorEnabled)); console.info("Dex.Themes.CurrentTheme.printValues.buttonColorHovered : %1".arg(buttonColorHovered)); @@ -230,6 +241,7 @@ ThemeData console.info("Dex.Themes.CurrentTheme.printValues.gradientButtonTextHoveredColor : %1".arg(gradientButtonTextHoveredColor)); console.info("Dex.Themes.CurrentTheme.printValues.gradientButtonTextPressedColor : %1".arg(gradientButtonTextPressedColor)); + console.info("Dex.Themes.CurrentTheme.printValues.checkBoxTickColor : %1".arg(checkBoxTickColor)); console.info("Dex.Themes.CurrentTheme.printValues.checkBoxGradientStartColor : %1".arg(checkBoxGradientStartColor)); console.info("Dex.Themes.CurrentTheme.printValues.checkBoxGradientEndColor : %1".arg(checkBoxGradientEndColor)); @@ -278,8 +290,8 @@ ThemeData console.info("Dex.Themes.CurrentTheme.printValues.rangeSliderIndicatorBackgroundStartColor : %1".arg(rangeSliderIndicatorBackgroundStartColor)); console.info("Dex.Themes.CurrentTheme.printValues.rangeSliderIndicatorBackgroundEndColor : %1".arg(rangeSliderIndicatorBackgroundEndColor)); - console.info("Dex.Themes.CurrentTheme.printValues.loginWalletIconColorStart : %1".arg(loginWalletIconColorStart)); - console.info("Dex.Themes.CurrentTheme.printValues.loginWalletIconColorEnd : %1".arg(loginWalletIconColorEnd)); + console.info("Dex.Themes.CurrentTheme.printValues.userIconColorStart : %1".arg(userIconColorStart)); + console.info("Dex.Themes.CurrentTheme.printValues.userIconColorEnd : %1".arg(userIconColorEnd)); console.info("Dex.Themes.CurrentTheme.printValues.sidebarBgColor : %1".arg(sidebarBgColor)); console.info("Dex.Themes.CurrentTheme.printValues.sidebarVersionTextColor : %1".arg(sidebarVersionTextColor)); @@ -294,11 +306,13 @@ ThemeData console.info("Dex.Themes.CurrentTheme.printValues.tradeSellModeSelectorBackgroundColorEnd : %1".arg(tradeSellModeSelectorBackgroundColorEnd)); console.info("Dex.Themes.CurrentTheme.printValues.tradeMarketModeSelectorNotSelectedBackgroundColor : %1".arg(tradeMarketModeSelectorNotSelectedBackgroundColor)); + console.info("Dex.Themes.CurrentTheme.printValues.addressBookTagColors : %1".arg(addressBookTagColors)); + console.info("Dex.Themes.CurrentTheme.printValues.okColor : %1".arg(okColor)); console.info("Dex.Themes.CurrentTheme.printValues.noColor : %1".arg(noColor)); - console.info("Dex.Themes.CurrentTheme.printValues.arrowUpColor : %1".arg(arrowUpColor)); - console.info("Dex.Themes.CurrentTheme.printValues.arrowDownColor : %1".arg(arrowDownColor)); + console.info("Dex.Themes.CurrentTheme.printValues.senderColorStart : %1".arg(senderColorStart)); + console.info("Dex.Themes.CurrentTheme.printValues.receiverColorStart : %1".arg(receiverColorStart)); console.info("Dex.Themes.CurrentTheme.printValues.lineSeparatorColor : %1".arg(lineSeparatorColor)); diff --git a/atomic_defi_design/Dex/Themes/DefaultTheme.js b/atomic_defi_design/Dex/Themes/DefaultTheme.js index 80fccc522b..bc44012fd8 100644 --- a/atomic_defi_design/Dex/Themes/DefaultTheme.js +++ b/atomic_defi_design/Dex/Themes/DefaultTheme.js @@ -3,49 +3,52 @@ function getHardcoded() { return { - accentColor: "#F0F2FF", - foregroundColor: "#456078", - foregroundColor2: "#7A8EA1", + accentColor: "#F0F2FFFF", + foregroundColor: "#456078FF", + foregroundColor2: "#7A8EA1FF", foregroundColor3: "#8FA0B1B2", - backgroundColor: "#FCFCFC", - backgroundColorDeep: "#FCFCFC", - - buttonColorDisabled: "#D8E3F8", - buttonColorEnabled: "#F0F6FF", - buttonColorHovered: "#D7E7FF", - buttonColorPressed: "#B8D2F9", - buttonTextDisabledColor: "#000000", - buttonTextEnabledColor: "#000000", - buttonTextHoveredColor: "#000000", - buttonTextPressedColor: "#000000", - - gradientButtonStartColor: "#5A68E6", + backgroundColor: "#FCFCFCFF", + backgroundColorDeep: "#FCFCFCFF", + + busyIndicatorColor: "#4986EAFF", + + buttonColorDisabled: "#D8E3F8FF", + buttonColorEnabled: "#F0F6FFFF", + buttonColorHovered: "#D7E7FFFF", + buttonColorPressed: "#B8D2F9FF", + buttonTextDisabledColor: "#000000FF", + buttonTextEnabledColor: "#000000FF", + buttonTextHoveredColor: "#000000FF", + buttonTextPressedColor: "#000000FF", + + gradientButtonStartColor: "#5A68E6FF", gradientButtonEndColor: "#4986EAAB", - gradientButtonDisabledStartColor: "#CDD0F6", - gradientButtonDisabledEndColor: "#DAE5F9", - gradientButtonHoveredStartColor: "#5A68E6", - gradientButtonHoveredEndColor: "#5A68E6", - gradientButtonPressedStartColor: "#6A4DE3", - gradientButtonPressedEndColor: "#6A4DE3", - gradientButtonTextEnabledColor: "#FFF", - gradientButtonTextDisabledColor: "#FFF", - gradientButtonTextHoveredColor: "#FFF", - gradientButtonTextPressedColor: "#FFF", - - checkBoxGradientStartColor: "#8892EB", - checkBoxGradientEndColor: "#9DD4F3", - - switchGradientStartColor: "#8892EB", - switchGradientEndColor: "#9DD4F3", - switchGradientStartColor2: "#FFF", - switchGradientEndColor2: "#FFF", + gradientButtonDisabledStartColor: "#CDD0F6FF", + gradientButtonDisabledEndColor: "#DAE5F9FF", + gradientButtonHoveredStartColor: "#5A68E6FF", + gradientButtonHoveredEndColor: "#5A68E6FF", + gradientButtonPressedStartColor: "#6A4DE3FF", + gradientButtonPressedEndColor: "#6A4DE3FF", + gradientButtonTextEnabledColor: "#FFFFFFFF", + gradientButtonTextDisabledColor: "#FFFFFFFF", + gradientButtonTextHoveredColor: "#FFFFFFFF", + gradientButtonTextPressedColor: "#FFFFFFFF", + + checkBoxTickColor: "#000000FF", + checkBoxGradientStartColor: "#8892EBFF", + checkBoxGradientEndColor: "#9DD4F3FF", + + switchGradientStartColor: "#8892EBFF", + switchGradientEndColor: "#9DD4F3FF", + switchGradientStartColor2: "#FFFFFFFF", + switchGradientEndColor2: "#FFFFFFFF", comboBoxBackgroundColor: "#FFFFFFFF", comboBoxArrowsColor: "#456078FF", comboBoxDropdownItemHighlightedColor: "#456078FF", - modalPageCounterGradientStartColor: "#9DD4F3", - modalPageCounterGradientEndColor: "#9DD4F3", + modalPageCounterGradientStartColor: "#9DD4F3FF", + modalPageCounterGradientEndColor: "#9DD4F3FF", notifPopupBackgroundColor: "#EDF4FFFF", notifPopupTextColor: "#456078FF", @@ -57,38 +60,38 @@ function getHardcoded() scrollBarIndicatorColor: "#DBE0E4FF", scrollBarBackgroundColor: "#93A3B1FF", - tabSelectedColor: "#DCE8FD", + tabSelectedColor: "#DCE8FDFF", - textDisabledColor: "#C5CFD8", - textSelectionColor: "#14BCA6FF", - textPlaceholderColor: "#91A8E8", - textSelectedColor: "#f9f9fb", + textDisabledColor: "#C5CFD8FF", + textSelectionColor: "#4986EAFF", + textPlaceholderColor: "#91A8E8FF", + textSelectedColor: "#f9f9fbFF", textFieldBackgroundColor: "#F3F5F6FF", textFieldActiveBackgroundColor: "#F3F5F6CC", textFieldPrefixColor: "#45607894", textFieldSuffixColor: "#456078FF", - chartTradingLineBackgroundColor: "#C5F2EF", - chartTradingLineColor: "#53EBD7", + chartTradingLineBackgroundColor: "#C5F2EFFF", + chartTradingLineColor: "#53EBD7FF", - innerBackgroundColor: "#edf4ff", + innerBackgroundColor: "#EDF4FFFF", - floatingBackgroundColor: "#edf4ff", + floatingBackgroundColor: "#EDF4FFFF", rangeSliderBackgroundColor: "#5A68E6FF", rangeSliderDistanceColor: "#4986EA3B", rangeSliderIndicatorBackgroundStartColor: "#5A68E6FF", rangeSliderIndicatorBackgroundEndColor: "#4986EAAD", - loginWalletIconColorStart: "#5A68E6FF", - loginWalletIconColorEnd: "#4986EAAD", + userIconColorStart: "#5A68E6FF", + userIconColorEnd: "#4986EAAD", - sidebarBgColor: "#FCFCFC", - sidebarVersionTextColor: "#456078", - sidebarCursorStartColor: "#5A68E6", - sidebarCursorEndColor: "#2CB9F000", - sidebarLineTextHovered: "#2C87B9", + sidebarBgColor: "#FCFCFCFF", + sidebarVersionTextColor: "#456078FF", + sidebarCursorStartColor: "#5A68E6FF", + sidebarCursorEndColor: "#2CB9F000FF", + sidebarLineTextHovered: "#2C87B9FF", sidebarLineTextSelected: "#FFFFFFFF", tradeBuyModeSelectorBackgroundColorStart: "#6A4DE3FF", @@ -97,12 +100,17 @@ function getHardcoded() tradeSellModeSelectorBackgroundColorEnd: "#E216A9FF", tradeMarketModeSelectorNotSelectedBackgroundColor: "#89B6FF21", - okColor: "#00C058", - noColor: "#E52167", + addressBookTagColors: ["#627EEAFF", "#FFD87AFF", "#F7931AFF"], + + okColor: "#00C058FF", + noColor: "#E52167FF", + + senderColorStart: "#F85757FF", + receiverColorStart: "#845FEFFF", - arrowUpColor: "#F85757", - arrowDownColor: "#845FEF", + arrowUpColor: "#F85757FF", + arrowDownColor: "#845FEFFF", - lineSeparatorColor: "#CDD3DC" + lineSeparatorColor: "#CDD3DCFF" } } diff --git a/atomic_defi_design/Dex/Themes/ThemeData.qml b/atomic_defi_design/Dex/Themes/ThemeData.qml index 9bef9da0fa..43cd03337d 100644 --- a/atomic_defi_design/Dex/Themes/ThemeData.qml +++ b/atomic_defi_design/Dex/Themes/ThemeData.qml @@ -9,6 +9,8 @@ QtObject property color backgroundColor property color backgroundColorDeep + property color busyIndicatorColor + property color buttonColorDisabled property color buttonColorEnabled property color buttonColorHovered @@ -31,6 +33,7 @@ QtObject property color gradientButtonTextHoveredColor property color gradientButtonTextPressedColor + property color checkBoxTickColor property color checkBoxGradientStartColor property color checkBoxGradientEndColor @@ -81,8 +84,8 @@ QtObject property color rangeSliderIndicatorBackgroundEndColor // Login page related - property color loginWalletIconColorStart - property color loginWalletIconColorEnd // Property not yet used. + property color userIconColorStart + property color userIconColorEnd // Property not yet used. // Sidebar related property color sidebarBgColor @@ -99,12 +102,15 @@ QtObject property color tradeSellModeSelectorBackgroundColorEnd property color tradeMarketModeSelectorNotSelectedBackgroundColor + // Address book page related + property var addressBookTagColors + // Colors used to tell when something is good or wrong. property color okColor property color noColor - property color arrowUpColor - property color arrowDownColor + property color senderColorStart + property color receiverColorStart property color lineSeparatorColor diff --git a/atomic_defi_design/Dex/Wallet/AddressBook.qml b/atomic_defi_design/Dex/Wallet/AddressBook.qml deleted file mode 100644 index a901b762b8..0000000000 --- a/atomic_defi_design/Dex/Wallet/AddressBook.qml +++ /dev/null @@ -1,292 +0,0 @@ -// Qt Imports -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 -import QtGraphicalEffects 1.0 - -// Deps Imports -import Qaterial 1.0 as Qaterial - -// Project Imports -import "../Components" -import "../Constants" -import App 1.0 - -ColumnLayout { - id: root - Layout.fillWidth: true - Layout.fillHeight: true - //spacing: 20 - - Layout.rightMargin: 10 - Layout.leftMargin: 10 - readonly property var addressbook_pg: API.app.addressbook_pg - - // Page header - Item { - Layout.fillWidth: true - Layout.preferredHeight: 80 - - - DexLabel { // Title - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: 10 - text_value: qsTr("Address Book") - font: DexTypo.head6 - } - - DexGradientAppButton { - - anchors.right: parent.right - anchors.rightMargin: 10 - anchors.verticalCenter: parent.verticalCenter - iconSource: Qaterial.Icons.textBoxPlus - radius: 40 - leftPadding: 5 - rightPadding: 5 - padding: 16 - text: qsTr("New Contact") - onClicked: new_contact_modal.open() - } - } - - Item { - Layout.fillWidth: true - Layout.preferredHeight: 60 - DexRectangle { - anchors.verticalCenter: parent.verticalCenter - width: 300 - opacity: enabled ? 1 : .5 - height: 50 - radius: 20 - x: 10 - color: DexTheme.contentColorTop - DefaultTextField { - id: searchbar - anchors.fill: parent - anchors.margins: 2 - function reset() { - searchbar.text = "" - } - Qaterial.Icon { - icon: Qaterial.Icons.magnify - color: searchbar.color - anchors.verticalCenter: parent.verticalCenter - x: 5 - } - leftPadding: 40 - placeholderText: qsTr("Search a contact by name or tags") - - font: DexTypo.body2 - onTextChanged: addressbook_pg.model.proxy.search_exp = text - Component.onDestruction: addressbook_pg.model.proxy.search_exp = "" - background: null - } - } - } - - // Contact List Header - Item { - Layout.fillWidth: true - Layout.preferredHeight: 40 - Layout.rightMargin: 10 - Layout.leftMargin: 10 - - - DexLabel { - id: header_name_column - anchors.left: parent.left - anchors.leftMargin: 20 - anchors.verticalCenter: parent.verticalCenter - font.bold: true - text: qsTr("Name") - } - - DexLabel { - id: header_tags_column - anchors.left: header_name_column.right - anchors.leftMargin: 180 - anchors.verticalCenter: parent.verticalCenter - font.bold: true - text: qsTr("Tags (first 6)") - } - - DexLabel { - anchors.right: parent.right - anchors.rightMargin: parent.width * 0.138 - anchors.verticalCenter: parent.verticalCenter - font.bold: true - text: qsTr("Actions") - } - - HorizontalLine { - width: parent.width - color: Style.colorWhite5 - anchors.bottom: parent.bottom - } - } - - // Contact List - DefaultListView { - id: contact_list - Layout.fillWidth: true - Layout.fillHeight: true - - Layout.rightMargin: 10 - Layout.leftMargin: 10 - - model: addressbook_pg.model.proxy - - // Contact Card - delegate: AnimatedRectangle { - id: contact_card - - property var contact: modelData - - color: Qt.lighter(index % 2 == 0 ? DexTheme.backgroundColor : DexTheme.surfaceColor, 1.0) - width: root.width - height: 55 - - DefaultText { // Contact Name - id: contact_name - anchors.left: parent.left - anchors.leftMargin: 20 - anchors.verticalCenter: parent.verticalCenter - - width: 160 - - text: modelData.name - elide: Text.ElideRight - } - - VerticalLine { - anchors.left: contact_name.right - anchors.leftMargin: 25 - height: parent.height - width: 1 - } - - Flow { // Contact First 6 Tags - id: contact_tags_list - flow: GridLayout.LeftToRight - - readonly property int length: 6 // Number of displayed tags - readonly property int tagButtonWidth: 150 // Width of a tag button - - width: length * tagButtonWidth - - anchors.left: contact_name.right - anchors.leftMargin: 50 - anchors.verticalCenter: parent.verticalCenter - - Repeater { - model: contact_card.contact.categories - - delegate: Qaterial.OutlineButton { - width: contact_tags_list.tagButtonWidth - visible: index < contact_tags_list.length && index < contact_card.contact.categories.length - outlined: false - text: modelData - icon.source: Qaterial.Icons.tag - //elide: Text.ElideRight - - onClicked: searchbar.text = modelData - } - } - } - - VerticalLine { - anchors.right: edit_contact_button.left - anchors.rightMargin: 30 - height: parent.height - width: 1 - } - - DefaultButton { // Edit Button - id: edit_contact_button - - anchors.right: remove_contact_button.left - anchors.rightMargin: 5 - anchors.verticalCenter: parent.verticalCenter - - text: qsTr("Edit") - font.pixelSize: Style.textSizeSmall3 - width: 120 - - onClicked: { - edit_contact_modal.contactModel = modelData - edit_contact_modal.open() - } - } - - DangerButton { // Remove Button - id: remove_contact_button - - anchors.right: parent.right - anchors.rightMargin: 30 - anchors.verticalCenter: parent.verticalCenter - - text: qsTr("Remove") - font.pixelSize: Style.textSizeSmall3 - width: 120 - - onClicked: { - remove_contact_modal.contactName = modelData.name - remove_contact_modal.open() - } - } - } - - - // Create Contact Modal - ModalLoader { - id: new_contact_modal - sourceComponent: AddressBookNewContactModal {} - } - - // Edit Contact Modal - ModalLoader { - id: edit_contact_modal - - property var contactModel - - onLoaded: item.contactModel = contactModel - - sourceComponent: AddressBookEditContactModal {} - } - - // Delete Contact Modal - ModalLoader { - property string contactName - - id: remove_contact_modal - - sourceComponent: MultipageModal { - width: 500 - - MultipageModalContent { - Layout.fillWidth: true - titleText: qsTr("Do you want to remove this contact ?") - - RowLayout { - DangerButton { - text: qsTr("Yes") - - onClicked: { - remove_contact_modal.close() - addressbook_pg.model.remove_contact(contactName) - } - } - - DefaultButton { - text: qsTr("No") - - onClicked: remove_contact_modal.close() - } - } - } - } - } - } -} diff --git a/atomic_defi_design/Dex/Wallet/AddressBookAddContactAddressModal.qml b/atomic_defi_design/Dex/Wallet/AddressBookAddContactAddressModal.qml deleted file mode 100644 index adb9f3629f..0000000000 --- a/atomic_defi_design/Dex/Wallet/AddressBookAddContactAddressModal.qml +++ /dev/null @@ -1,211 +0,0 @@ -// Qt Imports -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 //> ToolTip - -// Project Imports -import "../Constants" -import App 1.0 -import "../Components" -import Dex.Themes 1.0 as Dex - -// Contact address entry creation/edition modal -MultipageModal -{ - id: root - - property var contactModel - - // Address Creation (false) or Edition (true) mode. - property bool isEdition: false - - property alias walletType: wallet_type_list_modal.selected_wallet_type // The selected wallet type that will be associated this new address entry. - property alias key: contact_new_address_key.text // The entered key that will be associated to this new address entry. - property alias value: contact_new_address_value.text // The entered address value that will be associated to this new address entry. - - // These properties are required in edition mode since we need to wipe out old address entry. - property string oldWalletType - property string oldKey - property string oldValue - - function retrieveWalletTypeTicker() - { - switch (walletType) - { - case "QRC-20": return "QTUM"; - case "BEP-20": return "BNB"; - case "ERC-20": return "ETH"; - case "Smart Chain": return "KMD"; - case "SLP": return "BCH"; - } - - let coinInfo = API.app.portfolio_pg.global_cfg_mdl.get_coin_info(walletType); - if (coinInfo.has_parent_fees_ticker) - return coinInfo.fees_ticker; - return walletType - } - - width: 600 - - Component.onCompleted: API.app.wallet_pg.validate_address_data = {} - Component.onDestruction: API.app.wallet_pg.validate_address_data = {} - - MultipageModalContent - { - Layout.topMargin: 5 - Layout.fillWidth: true - - titleText: isEdition ? qsTr("Edit address entry") : qsTr("Create a new address") - - // Wallet Type Selector - DefaultButton - { - Layout.fillWidth: true - text: qsTr("Selected wallet: %1").arg(walletType !== "" ? walletType : qsTr("NONE")) - onClicked: wallet_type_list_modal.open() - } - - // Address Key Field - DefaultTextField - { - id: contact_new_address_key - - Layout.topMargin: 5 - Layout.fillWidth: true - - placeholderText: qsTr("Enter a name") - - onTextChanged: - { - const max_length = 30 - if (text.length > max_length) - text = text.substring(0, max_length) - } - - // Error tooltip when key already exists. - DefaultTooltip - { - id: key_already_exists_tooltip - visible: false - contentItem: DefaultText { text_value: qsTr("This key already exists.") } - } - } - - // Address Value Field - DefaultTextField - { - id: contact_new_address_value - - Layout.topMargin: 5 - implicitWidth: parent.width - - placeholderText: qsTr("Enter the address") - - onTextChanged: - { - const max_length = 50 - if (text.length > max_length) - text = text.substring(0, max_length) - } - } - - DefaultText - { - id: invalidAddressMsgLabel - Layout.fillWidth: true - color: Dex.CurrentTheme.noColor - wrapMode: DexLabel.Wrap - } - - HorizontalLine { Layout.fillWidth: true; Layout.topMargin: 32 } - - footer: - [ - DefaultButton - { - Layout.preferredWidth: 120 - visible: !API.app.wallet_pg.convert_address_busy && API.app.wallet_pg.validate_address_data.convertible ? API.app.wallet_pg.validate_address_data.convertible : false - text: qsTr("Convert") - onClicked: API.app.wallet_pg.convert_address(contact_new_address_value.text, retrieveWalletTypeTicker(), API.app.wallet_pg.validate_address_data.to_address_format); - }, - - DefaultButton - { - id: validateButton - enabled: key.length > 0 && value.length > 0 && walletType !== "" && !API.app.wallet_pg.validate_address_busy - text: qsTr("Validate") - onClicked: API.app.wallet_pg.validate_address(contact_new_address_value.text, retrieveWalletTypeTicker()) - }, - - DefaultButton - { - text: qsTr("Cancel") - onClicked: root.close() - } - ] - - Connections - { - target: API.app.wallet_pg - - function onConvertAddressBusyChanged() - { - if (API.app.wallet_pg.convert_address_busy) // Currently converting entered address - { - return; - } - - contact_new_address_value.text = API.app.wallet_pg.converted_address - API.app.wallet_pg.validate_address_data = {} - invalidAddressMsgLabel.text = "" - } - - function onValidateAddressBusyChanged() - { - if (API.app.wallet_pg.validate_address_busy) // Currently checking entered address - { - return; - } - - if (!API.app.wallet_pg.validate_address_data.is_valid) // Entered address is invalid. - { - invalidAddressMsgLabel.text = API.app.wallet_pg.validate_address_data.reason - return; - } - - if (isEdition) // Removes old address entry before if we are in edition mode. - { - console.debug("AddressBook: Replacing address %1:%2:%3 of contact %4" - .arg(oldWalletType).arg(oldKey).arg(oldValue).arg(contactModel.name)) - contactModel.remove_address_entry(oldWalletType, oldKey); - } - - var create_address_result = contactModel.add_address_entry(walletType, key, value); - if (create_address_result === true) - { - console.debug("AddressBook: Address %1:%2:%3 created for contact %4" - .arg(walletType).arg(key).arg(value).arg(contactModel.name)) - root.close() - } - else - { - console.debug("AddressBook: Failed to create address for contact %1: %2 key already exists" - .arg(contactModel.name).arg(key)) - key_already_exists_tooltip.visible = true - } - } - } - - ModalLoader - { - id: wallet_type_list_modal - - property string selected_wallet_type: "" - - sourceComponent: AddressBookWalletTypeListModal - { - onSelected_wallet_typeChanged: wallet_type_list_modal.selected_wallet_type = selected_wallet_type - } - } - } -} diff --git a/atomic_defi_design/Dex/Wallet/AddressBookEditContactModal.qml b/atomic_defi_design/Dex/Wallet/AddressBookEditContactModal.qml deleted file mode 100644 index 20c6cbb610..0000000000 --- a/atomic_defi_design/Dex/Wallet/AddressBookEditContactModal.qml +++ /dev/null @@ -1,601 +0,0 @@ -// Qt Imports -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 -import QtQuick.Controls.Universal 2.15 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -// Deps Imports -import Qaterial 1.0 as Qaterial - -// Project Imports -import "../Components" -import "../Constants" -import App 1.0 -import Dex.Themes 1.0 as Dex - -MultipageModal -{ - id: root - - property var contactModel - - function trySend(wallet_type, address) - { - // Checks if the selected wallet type is a coin type instead of a coin. - if (API.app.portfolio_pg.global_cfg_mdl.is_coin_type(wallet_type)) - { - send_selector.coin_type = wallet_type - send_selector.address = address - send_selector.open() - } - - // Checks if the coin is currently enabled. - else if (!API.app.portfolio_pg.is_coin_enabled(wallet_type)) - { - enable_coin_modal.coin_name = wallet_type - enable_coin_modal.open() - } - - // Checks if the coin has balance. - else if (parseFloat(API.app.get_balance(wallet_type)) === 0) cannot_send_modal.open() - - // If the coin has balance and is enabled, opens the send modal. - else - { - API.app.wallet_pg.ticker = wallet_type - send_modal.address = address - send_modal.open() - } - } - - width: 760 - - onClosed: contactModel.reload() - - MultipageModalContent - { - titleText: qsTr("Edit contact") - - // Contact name section - TextFieldWithTitle - { - id: name_input - Layout.fillWidth: true - title: qsTr("Contact Name") - field.placeholderText: qsTr("Enter a contact name") - field.text: contactModel.name - field.onTextChanged: - { - const max_length = 50 - if (field.text.length > max_length) - field.text = field.text.substring(0, max_length) - } - } - - HorizontalLine { Layout.fillWidth: true } - - // Wallets Information - ColumnLayout - { - Layout.topMargin: 10 - Layout.fillWidth: true - - // Title - TitleText { text: qsTr("Address List") } - - DefaultTextField - { - Layout.topMargin: 10 - Layout.fillWidth: true - - placeholderText: qsTr("Search for an address entry.") - - onTextChanged: contactModel.proxy_filter.search_expression = text - Component.onDestruction: contactModel.proxy_filter.search_expression = "" - } - - // Addresses Table - TableView - { - id: walletInfoTable - - property int _typeColWidth: 90 - property int _keyColWidth: 70 - property int _addressColWidth: 320 - property int _actionsColWidth: 100 - - model: contactModel.proxy_filter - - Layout.topMargin: 15 - Layout.fillWidth: true - - backgroundVisible: false - frameVisible: false - - headerDelegate: RowLayout - { - Layout.preferredWidth: styleData.column === 0 ? walletInfoTable._typeColWidth : - styleData.column === 1 ? walletInfoTable._keyColWidth : - styleData.column === 2 ? walletInfoTable._addressColWidth : - walletInfoTable._actionsColWidth - - Item - { - Layout.fillWidth: true - height: 20 - - DefaultText - { - anchors.verticalCenter: parent.verticalCenter - text: styleData.value - } - - VerticalLine - { - visible: styleData.column !== 3 - Layout.alignment: Qt.AlignRight - Layout.fillHeight: true - } - } - } - - rowDelegate: DefaultRectangle - { - height: 37; radius: 0 - color: styleData.selected ? Dex.CurrentTheme.accentColor: styleData.alternate ? Dex.CurrentTheme.backgroundColor : Dex.CurrentTheme.backgroundColorDeep - } - - TableViewColumn // Type Column - { - width: walletInfoTable._typeColWidth - - role: "address_type" - title: qsTr("Type") - - resizable: false - movable: false - - delegate: RowLayout - { - width: walletInfoTable._typeColWidth - DexLabel - { - Layout.preferredWidth: parent.width - 10 - Layout.leftMargin: 3 - text: styleData.row >= 0 ? styleData.value : "" - font.pixelSize: Style.textSizeSmall3 - elide: Text.ElideRight - } - - VerticalLine - { - Layout.alignment: Qt.AlignRight - Layout.fillHeight: true - } - } - } - - TableViewColumn // Key Column - { - width: walletInfoTable._keyColWidth - - role: "address_key" - title: qsTr("Key") - - resizable: false - movable: false - - delegate: RowLayout - { - width: walletInfoTable._keyColWidth - DefaultText - { - Layout.preferredWidth: parent.width - 10 - Layout.leftMargin: 3 - text: styleData.row >= 0 ? styleData.value : "" - font.pixelSize: Style.textSizeSmall3 - elide: Text.ElideRight - } - - VerticalLine - { - Layout.alignment: Qt.AlignRight - Layout.fillHeight: true - } - } - } - - TableViewColumn - { - width: walletInfoTable._addressColWidth - - role: "address_value" - title: qsTr("Address") - - resizable: false - movable: false - - delegate: RowLayout - { - width: walletInfoTable._addressColWidth - DexLabel - { - Layout.preferredWidth: parent.width - 10 - Layout.leftMargin: 3 - text: styleData.row >= 0 ? styleData.value : "" - font.pixelSize: Style.textSizeSmall3 - elide: Text.ElideRight - } - - VerticalLine - { - Layout.alignment: Qt.AlignRight - Layout.fillHeight: true - } - } - } - - TableViewColumn // Actions Column - { - width: walletInfoTable._actionsColWidth - title: qsTr("Actions") - - resizable: false - movable: false - - delegate: RowLayout - { - spacing: 4 - width: walletInfoTable._actionsColWidth - - Qaterial.OutlineButton // Edit Address Button - { - Layout.leftMargin: 2 - implicitHeight: 20 - implicitWidth: 20 - outlined: false - - Qaterial.ColorIcon - { - anchors.centerIn: parent - iconSize: 20 - source: Qaterial.Icons.leadPencil - color: Dex.CurrentTheme.foregroundColor - } - - onClicked: - { - address_edition_modal.walletType = model.address_type; - address_edition_modal.key = model.address_key; - address_edition_modal.value = model.address_value; - address_edition_modal.open(); - } - } - - Qaterial.OutlineButton // Delete Button - { - implicitHeight: 20 - implicitWidth: 20 - outlined: false - - onClicked: - { - removeAddressEntryModal.addressKey = model.address_key; - removeAddressEntryModal.addressType = model.address_type; - removeAddressEntryModal.contactModel = contactModel; - removeAddressEntryModal.open(); - } - - Qaterial.ColorIcon - { - anchors.centerIn: parent - iconSize: 20 - source: Qaterial.Icons.trashCan - color: Dex.CurrentTheme.noColor - } - } - - Qaterial.OutlineButton // Copy Clipboard Button - { - implicitHeight: 20 - implicitWidth: 20 - outlined: false - - onClicked: API.qt_utilities.copy_text_to_clipboard(model.address_value) - - Qaterial.ColorIcon - { - anchors.centerIn: parent - iconSize: 20 - source: Qaterial.Icons.contentCopy - color: Dex.CurrentTheme.foregroundColor - } - } - - Qaterial.OutlineButton // Send Button - { - implicitHeight: 20 - implicitWidth: 20 - outlined: false - - onClicked: trySend(model.address_type, model.address_value) - - Qaterial.ColorIcon - { - anchors.centerIn: parent - iconSize: 20 - source: Qaterial.Icons.send - color: Dex.CurrentTheme.foregroundColor - } - } - } - } - } - - // New Address Button - DefaultButton - { - Layout.preferredWidth: 140 - text: qsTr("Add Address") - onClicked: address_creation_modal.open(); - } - - ModalLoader { - id: address_creation_modal - sourceComponent: AddressBookAddContactAddressModal { - contactModel: root.contactModel - } - } - - ModalLoader { - id: address_edition_modal - - property string walletType - property string key - property string value - - onLoaded: { - item.oldWalletType = walletType - item.walletType = walletType - - item.oldKey = key - item.key = key - - item.oldValue = value - item.value = value - } - - sourceComponent: AddressBookAddContactAddressModal { - contactModel: root.contactModel - isEdition: true - } - } - } - - HorizontalLine - { - Layout.fillWidth: true - } - - // Categories Section Title - TitleText - { - Layout.topMargin: 10 - text: qsTr("Tags") - } - - // Categories (Tags) List - Flow - { - Layout.fillWidth: true - spacing: 10 - Repeater - { - id: category_repeater - model: contactModel.categories - - DexAppButton - { - Layout.alignment: Qt.AlignLeft - Layout.leftMargin: 4 - border.width: 0 - iconSource: Qaterial.Icons.closeOctagon - text: modelData - onClicked: contactModel.remove_category(modelData); - } - } - - // Category adding form opening button - DexAppButton - { - Layout.leftMargin: 10 - width: height - text: qsTr("+") - - onClicked: add_category_modal.open() - } - } - - HorizontalLine { Layout.fillWidth: true } - - // Actions on current contact - RowLayout - { - Layout.alignment: Qt.AlignBottom | Qt.AlignRight - Layout.rightMargin: 15 - - // Validate (Save) Changes - DefaultButton - { - text: qsTr("Confirm") - onClicked: - { - contactModel.name = name_input.field.text - contactModel.save() - root.close(); - } - } - - // Cancel Changes - DefaultButton - { - text: qsTr("Cancel") - onClicked: root.close() - } - } - - // Wallet Type List Modal - ModalLoader - { - id: wallet_type_list_modal - - property string selected_wallet_type: "" - - sourceComponent: AddressBookWalletTypeListModal - { - onSelected_wallet_typeChanged: wallet_type_list_modal.selected_wallet_type = selected_wallet_type - } - } - - // Enable Coin Modal - ModalLoader - { - property string coin_name - - id: enable_coin_modal - - sourceComponent: MultipageModal - { - MultipageModalContent - { - Layout.fillWidth: true - titleText: qsTr("Enable " + coin_name) - - DefaultText - { - text: qsTr("The selected address belongs to a disabled coin, you need to enabled it before sending.") - } - - Row - { - // Enable button - PrimaryButton - { - text: qsTr("Enable") - - onClicked: - { - API.app.enable_coin(coin_name) - enable_coin_modal.close() - } - } - - // Cancel button - DefaultButton - { - Layout.rightMargin: 5 - text: qsTr("Cancel") - - onClicked: enable_coin_modal.close() - } - } - } - } - } - - // Send Selector modal - ModalLoader - { - id: send_selector - - property string coin_type - property string address - - onLoaded: - { - item.coin_type = coin_type - item.address = address - } - - sourceComponent: AddressBookSendWalletSelector {} - } - - // Send Modal - ModalLoader - { - property string address - - id: send_modal - - onLoaded: item.address_field.text = address - - sourceComponent: SendModal - { - address_field.enabled: false - } - } - - // Cannot Send Modal - ModalLoader - { - id: cannot_send_modal - - sourceComponent: MultipageModal - { - MultipageModalContent - { - titleText: qsTr("Cannot send to this address") - - DefaultText - { - text: qsTr("Your balance is empty") - } - - DefaultButton - { - text: qsTr("Ok") - - onClicked: cannot_send_modal.close() - } - } - } - } - - // Remove address entry modal - ModalLoader - { - id: removeAddressEntryModal - - property var contactModel - property string addressKey - property string addressType - - sourceComponent: MultipageModal - { - width: 250 - MultipageModalContent - { - titleText: qsTr("Remove address ?") - - RowLayout - { - DexButton { text: qsTr("Yes"); onClicked: { contactModel.remove_address_entry(addressType, addressKey); close(); } } - DexButton { text: qsTr("No"); onClicked: close() } - } - } - } - } - - // Category (Tag) Adding Modal - ModalLoader - { - id: add_category_modal - - onLoaded: item.contactModel = root.contactModel - - sourceComponent: AddressBookNewContactCategoryModal {} - } - } -} diff --git a/atomic_defi_design/Dex/Wallet/AddressBookNewContactCategoryModal.qml b/atomic_defi_design/Dex/Wallet/AddressBookNewContactCategoryModal.qml deleted file mode 100644 index ba09b631db..0000000000 --- a/atomic_defi_design/Dex/Wallet/AddressBookNewContactCategoryModal.qml +++ /dev/null @@ -1,77 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 - -import "../Components" -import "../Constants" -import App 1.0 - -//! New category form -MultipageModal -{ - id: root - width: 500 - - property var contactModel - - MultipageModalContent - { - titleText: qsTr("Add a new tag") - - DefaultTextField - { - id: name_input - - Layout.fillWidth: true - - placeholderText: qsTr("Enter the tag name") - onTextChanged: - { - const max_length = 14 - if(text.length > max_length) - text = text.substring(0, max_length) - } - - // Error tooltip when category name already exists. - DefaultTooltip - { - id: alrady_exists_tooltip - visible: false - contentItem: DefaultText - { - text_value: qsTr("This contact already has this tag") - } - } - } - - footer: - [ - DefaultButton - { - Layout.preferredWidth: 90 - Layout.preferredHeight: 40 - text: qsTr("Add") - onClicked: - { - if (!contactModel.add_category(name_input.text)) alrady_exists_tooltip.visible = true - else - { - name_input.text = "" - add_category_modal.close() - } - } - }, - - DefaultButton - { - Layout.preferredWidth: 90 - Layout.preferredHeight: 40 - text: qsTr("Cancel") - onClicked: { - name_input.text = "" - add_category_modal.close() - } - } - ] - } -} diff --git a/atomic_defi_design/Dex/Wallet/AddressBookNewContactModal.qml b/atomic_defi_design/Dex/Wallet/AddressBookNewContactModal.qml deleted file mode 100644 index 4ecd0096c6..0000000000 --- a/atomic_defi_design/Dex/Wallet/AddressBookNewContactModal.qml +++ /dev/null @@ -1,81 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 - -import "../Components" -import "../Constants" -import App 1.0 - -MultipageModal { - id: root - width: 500 - - MultipageModalContent { - Layout.topMargin: 5 - - titleText: qsTr("Create a new contact") - - // Contact name input. - DefaultTextField { - id: name_input - placeholderText: qsTr("Enter the contact name") - width: 150 - onTextChanged: { - const max_length = 50 - if(text.length > max_length) - text = text.substring(0, max_length) - } - - // Error tooltip when contact name already exists. - DefaultTooltip { - id: contact_alrady_exists_tooltip - visible: false - contentItem: DefaultText { - text_value: qsTr("This contact name already exists.") - } - } - } - - HorizontalLine { - Layout.fillWidth: true - color: Style.colorWhite8 - } - - // Footer - RowLayout { - Layout.alignment: Qt.AlignBottom | Qt.AlignRight - - // Validate button. - PrimaryButton { - text: qsTr("Confirm") - enabled: name_input.text.length > 0 - onClicked: { - if (name_input.text.length == 0) - { - return; - } - - var create_contact_result = API.app.addressbook_pg.model.add_contact(name_input.text.toString()); - - if (create_contact_result === false) - { - contact_alrady_exists_tooltip.visible = true; - } - else - { - root.close(); - } - } - } - - // Cancel button. - DefaultButton { - text: qsTr("Cancel") - - onClicked: root.close() - } - } - } - - onClosed: name_input.text = "" -} diff --git a/atomic_defi_design/Dex/Wallet/AddressBookSendWalletSelector.qml b/atomic_defi_design/Dex/Wallet/AddressBookSendWalletSelector.qml deleted file mode 100644 index b6135e2894..0000000000 --- a/atomic_defi_design/Dex/Wallet/AddressBookSendWalletSelector.qml +++ /dev/null @@ -1,42 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 - -import "../Components" -import "../Constants" -import App 1.0 - -MultipageModal { - id: root - - property string coin_type - property string address - - width: 400 - - MultipageModalContent { - Layout.fillWidth: true - titleText: qsTr("Choose a valid ") + coin_type + qsTr(" coin") - - Repeater { - model: coin_type == "QRC-20" ? API.app.portfolio_pg.global_cfg_mdl.all_qrc20_proxy : - coin_type == "ERC-20" ? API.app.portfolio_pg.global_cfg_mdl.all_erc20_proxy : - coin_type == "BEP-20" ? API.app.portfolio_pg.global_cfg_mdl.all_bep20_proxy : - API.app.portfolio_pg.global_cfg_mdl.all_smartchains_proxy - - delegate: AddressBookWalletTypeListRow { - Layout.preferredHeight: height - Layout.rightMargin: 30 - Layout.fillWidth: true - - ticker: model.ticker - name: model.name - - onClicked: { - trySend(model.ticker, address) - close() - } - } - } - } -} diff --git a/atomic_defi_design/Dex/Wallet/AddressBookWalletTypeList.qml b/atomic_defi_design/Dex/Wallet/AddressBookWalletTypeList.qml deleted file mode 100644 index 8f6b749f1b..0000000000 --- a/atomic_defi_design/Dex/Wallet/AddressBookWalletTypeList.qml +++ /dev/null @@ -1,143 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 -import QtQuick.Controls.impl 2.15 -import QtQuick.Controls.Universal 2.15 - -import Qaterial 1.0 as Qaterial - -import "../Components" -import "../Constants" -import App 1.0 -import Dex.Themes 1.0 as Dex - -Qaterial.Expandable -{ - id: _root - - property string title - - property string type_title - property string type: "" - property string typeIcon: type - - property var model - - header: Qaterial.ItemDelegate - { - id: _header - - icon.source: General.image_path + "arrow_down.svg" - - onClicked: () => _root.expanded = !_root.expanded - - TitleText - { - anchors.verticalCenter: parent.verticalCenter - leftPadding: 75 - text: title - font.bold: true - } - } - - delegate: Column - { - AddressBookWalletTypeListRow - { - enabled: type !== "" - visible: type !== "" - - icon_source: General.coinTypeIcon(typeIcon) - - width: _root.width - - name: type_title - ticker: type_title - - onClicked: onTypeSelect(type) - } - - Repeater - { - model: _root.model - - delegate: AddressBookWalletTypeListRow - { - width: _root.width - - name: model.name - ticker: model.ticker - - onClicked: - { - if (!API.app.portfolio_pg.global_cfg_mdl.get_coin_info(model.ticker).is_enabled) - _tooltip.open() - else - onTypeSelect(ticker) - } - - DefaultTooltip - { - id: _tooltip - - width: 250 - anchors.centerIn: parent - - dim: true - modal: true - closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside - - contentItem: DexLabelUnlinked - { - text_value: qsTr("%1 is not enabled - You need to enable it before adding an address. Enable it ?
Yes - No").arg(model.ticker) - wrapMode: DefaultText.Wrap - width: 350 - onLinkActivated: - { - if (link === "#no") _tooltip.close() - else - { - if (API.app.enable_coins([model.ticker]) === false) - cannot_enable_coin_modal.open() - else - { - color = Dex.CurrentTheme.buttonTextDisabledColor - opacity = 0.8 - _coinIsEnabling.visible = true - } - } - } - } - - BusyIndicator - { - id: _coinIsEnabling - - visible: false - enabled: visible - anchors.fill: parent - - Connections - { - target: API.app.portfolio_pg.global_cfg_mdl.all_disabled_proxy - - function onLengthChanged() - { - _tooltip.close() - } - } - } - - ModalLoader - { - property string coin_to_enable_ticker: model.ticker - id: cannot_enable_coin_modal - sourceComponent: CannotEnableCoinModal { coin_to_enable_ticker: cannot_enable_coin_modal.coin_to_enable_ticker } - } - - delay: 200 - } - } - } - } -} diff --git a/atomic_defi_design/Dex/Wallet/AddressBookWalletTypeListModal.qml b/atomic_defi_design/Dex/Wallet/AddressBookWalletTypeListModal.qml deleted file mode 100644 index 5590cd3689..0000000000 --- a/atomic_defi_design/Dex/Wallet/AddressBookWalletTypeListModal.qml +++ /dev/null @@ -1,137 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 - -import Qaterial 1.0 as Qaterial - -import "../Components" -import "../Constants" -import App 1.0 - -MultipageModal -{ - readonly property var glbCoinsCfgModel: API.app.portfolio_pg.global_cfg_mdl - property alias selected_wallet_type: wallet_list.selected_wallet_type - - function resetModal() - { - _searchbar.text = "" - filterWallets(_searchbar.text) - } - - function filterWallets(text) - { - _qrc20Expandable.model.setFilterFixedString(text) - _erc20Expandable.model.setFilterFixedString(text) - _bep20Expandable.model.setFilterFixedString(text) - _scExpandable.model.setFilterFixedString(text) - _utxoExpandable.model.setFilterFixedString(text) - - // Expands type lists if searchbar is not empty - _qrc20Expandable.expanded = text !== "" - _erc20Expandable.expanded = text !== "" - _bep20Expandable.expanded = text !== "" - _scExpandable.expanded = text !== "" - _utxoExpandable.expanded = text !== "" - } - - function onTypeSelect(type_or_ticker) - { - selected_wallet_type = type_or_ticker - close() - } - - width: 600 - - onOpened: _searchbar.forceActiveFocus() - onClosed: resetModal() - - MultipageModalContent - { - id: wallet_list - - property string selected_wallet_type: "" - - titleText: qsTr("Select wallet type") - - // Search input - DefaultTextField - { - Layout.rightMargin: 10 - id: _searchbar - - Layout.fillWidth: true - placeholderText: qsTr("Search") - - onTextChanged: filterWallets(text) - } - - AddressBookWalletTypeList - { - id: _qrc20Expandable - - Layout.topMargin: 20 - Layout.rightMargin: 10 - Layout.fillWidth: true - Layout.fillHeight: true - - title: "QRC-20 coins" - type_title: "QRC-20" - type: "QRC-20" - - model: glbCoinsCfgModel.all_qrc20_proxy - } - - AddressBookWalletTypeList - { - id: _erc20Expandable - Layout.rightMargin: 10 - Layout.fillWidth: true - - title: "ERC-20 coins" - type_title: "ERC-20" - type: "ERC-20" - - model: glbCoinsCfgModel.all_erc20_proxy - } - - AddressBookWalletTypeList - { - id: _bep20Expandable - Layout.rightMargin: 10 - Layout.fillWidth: true - - title: "BEP-20 coins" - type_title: "BEP-20" - type: "BEP-20" - typeIcon: "BNB" - - model: glbCoinsCfgModel.all_bep20_proxy - } - - AddressBookWalletTypeList - { - id: _scExpandable - Layout.rightMargin: 10 - Layout.fillWidth: true - - title: "Smart Chain coins" - type_title: "Smart Chain" - type: "Smart Chain" - - model: glbCoinsCfgModel.all_smartchains_proxy - } - - AddressBookWalletTypeList - { - id: _utxoExpandable - - Layout.rightMargin: 10 - Layout.fillWidth: true - - title: "UTXO coins" - type_title: "UTXO" - - model: glbCoinsCfgModel.all_utxo_proxy - } - } -} diff --git a/atomic_defi_design/Dex/Wallet/AddressBookWalletTypeListRow.qml b/atomic_defi_design/Dex/Wallet/AddressBookWalletTypeListRow.qml deleted file mode 100644 index 5b9c597a63..0000000000 --- a/atomic_defi_design/Dex/Wallet/AddressBookWalletTypeListRow.qml +++ /dev/null @@ -1,34 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 - -import "../Components" -import "../Constants" -import App 1.0 - -ItemDelegate { - property string ticker - property string name - - property alias icon_source: icon.source - - height: 50 - - RowLayout { - DefaultImage { - id: icon - Layout.topMargin: 10 - Layout.leftMargin: 30 - Layout.alignment: Qt.AlignVCenter - source: General.coinIcon(ticker) - Layout.preferredWidth: 32 - Layout.preferredHeight: 32 - } - - DexLabel { - Layout.topMargin: 10 - text: " " + name + " (" + ticker + ")" - } - } - -} diff --git a/atomic_defi_design/Dex/Wallet/AddressList.qml b/atomic_defi_design/Dex/Wallet/AddressList.qml index dd0067b367..d272ba604e 100644 --- a/atomic_defi_design/Dex/Wallet/AddressList.qml +++ b/atomic_defi_design/Dex/Wallet/AddressList.qml @@ -10,9 +10,11 @@ import Dex.Themes 1.0 as Dex ColumnLayout { id: root + property string linkURL: "" + property string onCopyNotificationTitle: "" property alias title: title.text property alias model: list.model - property real addressFontSize: DefaultText.font.pixelSize + property real addressFontSize: 12 TitleText { @@ -29,11 +31,16 @@ ColumnLayout clip: true - delegate: DefaultText + delegate: TextEditWithCopy { + id: address_text text_value: model.modelData privacy: true - font.pixelSize: root.addressFontSize + font_size: 13 + align_left: true + text_box_width: 600 + linkURL: root.linkURL + onCopyNotificationTitle: root.onCopyNotificationTitle } } } diff --git a/atomic_defi_design/Dex/Wallet/ClaimFaucetResultModal.qml b/atomic_defi_design/Dex/Wallet/ClaimFaucetResultModal.qml index fd01e04aaf..7e74f78fd2 100644 --- a/atomic_defi_design/Dex/Wallet/ClaimFaucetResultModal.qml +++ b/atomic_defi_design/Dex/Wallet/ClaimFaucetResultModal.qml @@ -20,7 +20,7 @@ MultipageModal { DefaultText { id: message - + width: parent.width text_value: claiming_faucet_rpc_result && claiming_faucet_rpc_result.message ? claiming_faucet_rpc_result.message : "" } diff --git a/atomic_defi_design/Dex/Wallet/ClaimRewardsModal.qml b/atomic_defi_design/Dex/Wallet/ClaimRewardsModal.qml index 9647f72f7b..4222e0189f 100644 --- a/atomic_defi_design/Dex/Wallet/ClaimRewardsModal.qml +++ b/atomic_defi_design/Dex/Wallet/ClaimRewardsModal.qml @@ -5,6 +5,7 @@ import QtQuick.Controls 2.15 import "../Components" import "../Constants" import App 1.0 +import Dex.Components 1.0 as Dex MultipageModal { @@ -85,9 +86,12 @@ MultipageModal if(root.visible && broadcast_result !== "") { root.currentIndex = 1 postClaim() + root.width = 750 } } + Behavior on width { NumberAnimation { duration: 300 } } + function prepareClaimRewards() { if(!can_claim) return @@ -107,19 +111,24 @@ MultipageModal // Inside modal width: 1200 - MultipageModalContent { + + MultipageModalContent + { titleText: qsTr("Claim your %1 reward?", "TICKER").arg(api_wallet_page.ticker) - DefaultBusyIndicator { + DefaultBusyIndicator + { visible: !can_claim || is_broadcast_busy Layout.alignment: Qt.AlignCenter } - RowLayout { + RowLayout + { visible: can_claim - Layout.fillWidth: true - DexLabel { + + Dex.Text + { Layout.fillWidth: true text_value: { @@ -137,62 +146,56 @@ MultipageModal } } - PrimaryButton { + Dex.Button + { text: qsTr("Refresh") - onClicked: prepareClaimRewards() - enabled: can_claim + onClicked: prepareClaimRewards() } } - DefaultText { + Dex.Text + { text_value: General.cex_icon + ' ' + qsTr('Read more about KMD active users rewards') + '' font.pixelSize: Style.textSizeSmall2 } // List header - Item { + Row + { visible: can_claim Layout.topMargin: 25 Layout.fillWidth: true - - height: 40 + Layout.preferredHeight: 40 // Price - DefaultText { + Dex.Text + { id: utxo_header font.pixelSize: Style.textSizeSmall4 - text_value: qsTr("UTXO") - font.weight: Font.Medium horizontalAlignment: Text.AlignLeft - - anchors.left: parent.left - anchors.leftMargin: parent.width * 0.000 - + width: parent.width * 0.060 anchors.verticalCenter: parent.verticalCenter } // Amount - DefaultText { + Dex.Text + { id: amount_header - text_value: qsTr("Amount") - font.pixelSize: utxo_header.font.pixelSize font.weight: utxo_header.font.weight horizontalAlignment: utxo_header.horizontalAlignment - - anchors.left: parent.left - anchors.leftMargin: parent.width * 0.060 - + width: parent.width * 0.165 anchors.verticalCenter: parent.verticalCenter } // Reward - DefaultText { + Dex.Text + { id: reward_header text_value: qsTr("Reward") @@ -200,15 +203,13 @@ MultipageModal font.pixelSize: utxo_header.font.pixelSize font.weight: utxo_header.font.weight horizontalAlignment: Text.AlignLeft - - anchors.left: parent.left - anchors.leftMargin: parent.width * 0.225 - + width: parent.width * 0.235 anchors.verticalCenter: parent.verticalCenter } // Accruing start - DefaultText { + Dex.Text + { id: accruing_start_header text_value: qsTr("Accruing Start") @@ -216,15 +217,13 @@ MultipageModal font.pixelSize: utxo_header.font.pixelSize font.weight: utxo_header.font.weight horizontalAlignment: Text.AlignLeft - - anchors.left: parent.left - anchors.leftMargin: parent.width * 0.400 - + width: parent.width * 0.150 anchors.verticalCenter: parent.verticalCenter } // Accruing Stop - DefaultText { + Dex.Text + { id: accruing_stop_header text_value: qsTr("Accruing Stop") @@ -232,15 +231,13 @@ MultipageModal font.pixelSize: utxo_header.font.pixelSize font.weight: utxo_header.font.weight horizontalAlignment: Text.AlignLeft - - anchors.left: parent.left - anchors.leftMargin: parent.width * 0.550 - + width: parent.width * 0.150 anchors.verticalCenter: parent.verticalCenter } // Time Left - DefaultText { + Dex.Text + { id: time_left_header text_value: qsTr("Time Left") @@ -248,15 +245,13 @@ MultipageModal font.pixelSize: utxo_header.font.pixelSize font.weight: utxo_header.font.weight horizontalAlignment: Text.AlignLeft - - anchors.left: parent.left - anchors.leftMargin: parent.width * 0.700 - + width: parent.width * 0.120 anchors.verticalCenter: parent.verticalCenter } // Error - DefaultText { + Dex.Text + { id: error_header text_value: qsTr("Error") @@ -264,166 +259,154 @@ MultipageModal font.pixelSize: utxo_header.font.pixelSize font.weight: utxo_header.font.weight horizontalAlignment: Text.AlignLeft - - anchors.left: parent.left - anchors.leftMargin: parent.width * 0.820 - anchors.verticalCenter: parent.verticalCenter } - - // Line - HorizontalLine { - width: parent.width - color: Style.colorWhite5 - anchors.bottom: parent.bottom - } } - DefaultListView { - visible: can_claim + // Separator + HorizontalLine + { + Layout.fillWidth: true + } + Dex.ListView + { id: list + visible: can_claim Layout.fillWidth: true Layout.fillHeight: true Layout.maximumHeight: 500 clip: true - model: empty_data ? [] : - prepare_claim_rewards_result.kmd_rewards_info.result - - delegate: Item { - width: root.width - height: utxo_value.font.pixelSize * 1.5 - - // UTXO - DefaultText { - id: utxo_value - - anchors.left: parent.left - anchors.leftMargin: utxo_header.anchors.leftMargin + model: empty_data ? [] : prepare_claim_rewards_result.kmd_rewards_info.result - font.pixelSize: utxo_header.font.pixelSize - - text_value: "#" + (index + 1) - anchors.verticalCenter: parent.verticalCenter - } - - // Amount - DefaultText { - id: amount_value + delegate: Column + { + width: list.width - anchors.left: parent.left - anchors.leftMargin: amount_header.anchors.leftMargin + Row + { + width: list.width - font.pixelSize: utxo_value.font.pixelSize + // UTXO + Dex.Text + { + id: utxo_value - text_value: modelData.amount - anchors.verticalCenter: parent.verticalCenter - } + anchors.verticalCenter: parent.verticalCenter + width: parent.width * 0.06 - // Reward - DefaultText { - id: reward_value + text: "#" + (index + 1) + font.pixelSize: utxo_header.font.pixelSize + } - anchors.left: parent.left - anchors.leftMargin: reward_header.anchors.leftMargin + // Amount + Dex.Text + { + id: amount_value - font.pixelSize: utxo_value.font.pixelSize + anchors.verticalCenter: parent.verticalCenter + width: parent.width * 0.165 - text_value: modelData.accrued_rewards.Accrued || "-" - anchors.verticalCenter: parent.verticalCenter - } + font.pixelSize: utxo_value.font.pixelSize + text: modelData.amount + } - // Accruing Start - DefaultText { - id: accruing_start_value + // Reward + Dex.Text + { + id: reward_value - anchors.left: parent.left - anchors.leftMargin: accruing_start_header.anchors.leftMargin + anchors.verticalCenter: parent.verticalCenter + width: parent.width * 0.235 - font.pixelSize: utxo_value.font.pixelSize + font.pixelSize: utxo_value.font.pixelSize + text: modelData.accrued_rewards.Accrued || "-" + } - text_value: modelData.accrue_start_at_human_date || "-" - anchors.verticalCenter: parent.verticalCenter - } + // Accruing Start + Dex.Text + { + id: accruing_start_value - // Accruing Stop - DefaultText { - id: accruing_stop_value + anchors.verticalCenter: parent.verticalCenter + width: parent.width * 0.150 - anchors.left: parent.left - anchors.leftMargin: accruing_stop_header.anchors.leftMargin + font.pixelSize: utxo_value.font.pixelSize + text: modelData.accrue_start_at_human_date || "-" + } - font.pixelSize: utxo_value.font.pixelSize + // Accruing Stop + Dex.Text + { + id: accruing_stop_value - text_value: modelData.accrue_stop_at_human_date || "-" - anchors.verticalCenter: parent.verticalCenter - } + anchors.verticalCenter: parent.verticalCenter + width: parent.width * 0.150 - // Time Left - DefaultText { - id: time_left_value + font.pixelSize: utxo_value.font.pixelSize + text: modelData.accrue_stop_at_human_date || "-" + } - anchors.left: parent.left - anchors.leftMargin: time_left_header.anchors.leftMargin + // Time Left + Dex.Text + { + id: time_left_value - font.pixelSize: utxo_value.font.pixelSize + anchors.verticalCenter: parent.verticalCenter + width: parent.width * 0.120 - text_value: modelData.accrue_stop_at ? General.secondsToTimeLeft(Date.now()/1000, modelData.accrue_stop_at) : '-' - anchors.verticalCenter: parent.verticalCenter - } + font.pixelSize: utxo_value.font.pixelSize + text: modelData.accrue_stop_at ? General.secondsToTimeLeft(Date.now()/1000, modelData.accrue_stop_at) : '-' + } - // Error - DefaultText { - id: error_value - - anchors.left: parent.left - anchors.leftMargin: error_header.anchors.leftMargin - - font.pixelSize: utxo_value.font.pixelSize - - text_value: { - let val = modelData.accrued_rewards.NotAccruedReason - if(val === null || val === undefined) return "-" - - switch(val) { - case "LocktimeNotSet": - val = qsTr("Locktime is not set") - break - case "LocktimeLessThanThreshold": - val = qsTr("Locktime is less than the threshold") - break - case "UtxoHeightGreaterThanEndOfEra": - val = qsTr("UTXO height is greater than end of the era") - break - case "UtxoAmountLessThanTen": - val = qsTr("UTXO amount is less than 10") - break - case "OneHourNotPassedYet": - val = qsTr("One hour did not pass yet") - break - case "TransactionInMempool": - val = qsTr("Transaction is in mempool") - break - default: - val = qsTr("Unknown problem") - break + // Error + Dex.Text + { + id: error_value + + anchors.verticalCenter: parent.verticalCenter + width: parent.width * 0.12 + + font.pixelSize: utxo_value.font.pixelSize + text: + { + let val = modelData.accrued_rewards.NotAccruedReason + if (val === null || val === undefined) return "-" + + switch (val) + { + case "LocktimeNotSet": + val = qsTr("Locktime is not set") + break + case "LocktimeLessThanThreshold": + val = qsTr("Locktime is less than the threshold") + break + case "UtxoHeightGreaterThanEndOfEra": + val = qsTr("UTXO height is greater than end of the era") + break + case "UtxoAmountLessThanTen": + val = qsTr("UTXO amount is less than 10") + break + case "OneHourNotPassedYet": + val = qsTr("One hour did not pass yet") + break + case "TransactionInMempool": + val = qsTr("Transaction is in mempool") + break + default: + val = qsTr("Unknown problem") + break + } + + return "❌ " + val } - - return "❌ " + val } - - anchors.verticalCenter: parent.verticalCenter } - // Line - HorizontalLine { - visible: empty_data ? false : - prepare_claim_rewards_result.kmd_rewards_info.result && - index !== prepare_claim_rewards_result.kmd_rewards_info.result.length - 1 + HorizontalLine + { width: parent.width - color: Style.colorWhite9 - anchors.bottom: parent.bottom } } } @@ -461,9 +444,9 @@ MultipageModal // Result Page SendResult { + address: current_ticker_infos.address result: prepare_claim_rewards_result tx_hash: broadcast_result - function onClose() { root.close() } } } diff --git a/atomic_defi_design/Dex/Wallet/EnableCoinModal.qml b/atomic_defi_design/Dex/Wallet/EnableCoinModal.qml index 7f4abe2327..332f7049b0 100644 --- a/atomic_defi_design/Dex/Wallet/EnableCoinModal.qml +++ b/atomic_defi_design/Dex/Wallet/EnableCoinModal.qml @@ -36,7 +36,6 @@ MultipageModal filterCoins(""); setCheckState(false); coin_cfg_model.checked_nb = 0; - input_coin_filter.forceActiveFocus(); } onClosed: @@ -50,6 +49,8 @@ MultipageModal { titleText: qsTr("Enable assets") titleAlignment: Qt.AlignHCenter + titleTopMargin: 15 + topMarginAfterTitle: 15 // Search input SearchField @@ -62,41 +63,33 @@ MultipageModal Layout.fillWidth: true Layout.preferredHeight: 44 textField.placeholderText: qsTr("Search asset") - + textField.forceFocus: true textField.onTextChanged: filterCoins() } - Item + RowLayout { - Layout.alignment: Qt.AlignHCenter - Layout.topMargin: 5 + spacing: 0 + Layout.topMargin: 10 Layout.fillWidth: true - Layout.preferredHeight: 25 + Layout.preferredHeight: 24 - DexCheckBox + DefaultCheckBox { id: _selectAllCheckBox + Layout.fillWidth: true - visible: list.visible - checked: coin_cfg_model.checked_nb === setting_modal.enableable_coins_count - API.app.portfolio_pg.portfolio_mdl.length - anchors.left: parent.left + spacing: 0 boxWidth: 20 boxHeight: 20 - width: 20 + labelWidth: parent.width - 40 + label.wrapMode: Label.NoWrap + label.leftPadding: 24 - DefaultMouseArea - { - anchors.fill: parent - onClicked: setCheckState(!parent.checked) - } + text: qsTr("Select all assets") + visible: list.visible - DefaultText - { - anchors.left: parent.right - anchors.leftMargin: 5 - anchors.verticalCenter: parent.verticalCenter - text: qsTr("Select all assets") - } + onToggled: root.setCheckState(checked) } } @@ -113,75 +106,100 @@ MultipageModal Layout.preferredHeight: 300 Layout.fillWidth: true - delegate: DexCheckBox + delegate: Item { - readonly property bool backend_checked: model.checked + height: 30 + width: list.width - enabled: _selectAllCheckBox.checked ? checked : true - boxWidth: 20 - boxHeight: 20 - spacing: 0 - - onBackend_checkedChanged: if (checked !== backend_checked) checked = backend_checked - onCheckStateChanged: + RowLayout { - if (checked !== backend_checked) + spacing: 0 + Layout.topMargin: 10 + Layout.fillWidth: true + Layout.preferredHeight: 24 + + DefaultCheckBox { - var data_index = coin_cfg_model.all_disabled_proxy.index(index, 0) - if ((coin_cfg_model.all_disabled_proxy.setData(data_index, checked, Qt.UserRole + 11)) === false) - { - checked = false - } - } - } + id: listInnerRowCheckbox + readonly property bool backend_checked: model.checked - RowLayout { - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.right - spacing:6 + Layout.fillWidth: true - // Icon - DefaultImage - { - id: icon - Layout.leftMargin: 8 - Layout.alignment: Qt.AlignVCenter - source: General.coinIcon(model.ticker) - Layout.preferredWidth: 18 - Layout.preferredHeight: 18 - } - DefaultText - { - Layout.leftMargin: 4 - Layout.alignment: Qt.AlignVCenter - text: model.name + " (" + model.ticker + ")" - } - CoinTypeTag - { - id: typeTag - Layout.leftMargin: 6 - Layout.alignment: Qt.AlignVCenter - type: model.type - } + spacing: 0 + boxWidth: 20 + boxHeight: 20 + labelWidth: parent.width - 40 - CoinTypeTag - { - Layout.leftMargin: 6 - Layout.alignment: Qt.AlignVCenter - enabled: General.isIDO(model.ticker) - visible: enabled - type: "IDO" - } + onBackend_checkedChanged: if (checked !== backend_checked) checked = backend_checked + onCheckStateChanged: + { + if (checked !== backend_checked) + { + var data_index = coin_cfg_model.all_disabled_proxy.index(index, 0) + if ((coin_cfg_model.all_disabled_proxy.setData(data_index, checked, Qt.UserRole + 11)) === false) + { + checked = false + } + } + } - CoinTypeTag - { - Layout.leftMargin: 6 - Layout.alignment: Qt.AlignVCenter - enabled: API.app.portfolio_pg.global_cfg_mdl.get_coin_info(model.ticker).is_wallet_only - visible: enabled - type: "WALLET ONLY" + contentItem: RowLayout + { + Layout.alignment: Qt.AlignVCenter + spacing: 0 + + // Icon + DefaultImage + { + id: icon + Layout.leftMargin: 24 + Layout.alignment: Qt.AlignVCenter + source: General.coinIcon(model.ticker) + Layout.preferredWidth: 18 + Layout.preferredHeight: 18 + } + + DefaultText + { + Layout.leftMargin: 4 + Layout.alignment: Qt.AlignVCenter + text: model.name + " (" + model.ticker + ")" + } + + CoinTypeTag + { + id: typeTag + Layout.leftMargin: 6 + Layout.alignment: Qt.AlignVCenter + type: model.type + } + + CoinTypeTag + { + Layout.leftMargin: 6 + Layout.alignment: Qt.AlignVCenter + enabled: General.isIDO(model.ticker) + visible: enabled + type: "IDO" + } + + CoinTypeTag + { + Layout.leftMargin: 6 + Layout.alignment: Qt.AlignVCenter + enabled: API.app.portfolio_pg.global_cfg_mdl.get_coin_info(model.ticker).is_wallet_only + visible: enabled + type: "WALLET ONLY" + } + } } } + + DefaultMouseArea + { + anchors.fill: parent + onClicked: listInnerRowCheckbox.checked = !listInnerRowCheckbox.checked + } } } @@ -191,7 +209,7 @@ MultipageModal Layout.fillWidth: true Layout.alignment: Qt.AlignHCenter - DexLabel + DefaultText { anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter @@ -211,7 +229,8 @@ MultipageModal { Layout.alignment: Qt.AlignHCenter Layout.fillWidth: true - Layout.preferredHeight: 40 + Layout.topMargin: 10 + Layout.preferredHeight: 60 DexTransparentButton { @@ -226,10 +245,11 @@ MultipageModal setting_modal.open() } } + DexTransparentButton { anchors.right: parent.right - text: qsTr("Add a custom asset to the list") + text: qsTr("Add a custom asset") topPadding: 5 bottomPadding: 5 Layout.preferredHeight: 35 @@ -241,17 +261,17 @@ MultipageModal } } - RowLayout - { - Layout.fillWidth: true + footer: + [ DefaultButton { Layout.preferredWidth: 199 - text: qsTr("Close") + text: qsTr("Cancel") radius: 20 onClicked: root.close() - } - Item { Layout.fillWidth: true } + }, + Item { Layout.fillWidth: true }, + DexGradientAppButton { Layout.preferredWidth: 199 @@ -259,14 +279,15 @@ MultipageModal enabled: coin_cfg_model.checked_nb > 0 text: qsTr("Enable") radius: 20 + onClicked: { - API.app.enable_coins(coin_cfg_model.get_checked_coins()) - setCheckState(false) + API.app.enable_coins(coin_cfg_model.get_checked_coins()); + root.setCheckState(false); coin_cfg_model.checked_nb = 0 root.close() } } - } + ] } } diff --git a/atomic_defi_design/Dex/Wallet/Main.qml b/atomic_defi_design/Dex/Wallet/Main.qml index 2609058a28..f046780849 100644 --- a/atomic_defi_design/Dex/Wallet/Main.qml +++ b/atomic_defi_design/Dex/Wallet/Main.qml @@ -20,19 +20,24 @@ Item { id: root property alias send_modal: send_modal - readonly property int layout_margin: 20 - readonly property string headerTitleColor: Style.colorText2 - readonly property string headerTitleFont: Style.textSizeMid1 - readonly property string headerTextColor: Dex.CurrentTheme.foregroundColor - readonly property string headerTextFont: Style.textSize - readonly property string headerSmallTitleFont: Style.textSizeSmall4 - readonly property string headerSmallFont: Style.textSizeSmall2 - - function loadingPercentage(remaining) { + + readonly property int layout_margin: 20 + readonly property string headerTitleColor: Style.colorText2 + readonly property string headerTitleFont: Style.textSizeMid1 + readonly property string headerTextColor: Dex.CurrentTheme.foregroundColor + readonly property string headerTextFont: Style.textSize + readonly property string headerSmallTitleFont: Style.textSizeSmall4 + readonly property string headerSmallFont: Style.textSizeSmall2 + readonly property string addressURL: General.getAddressExplorerURL(api_wallet_page.ticker, current_ticker_infos.address) + + function loadingPercentage(remaining) + { return General.formatPercent((100 * (1 - parseFloat(remaining)/parseFloat(current_ticker_infos.current_block))).toFixed(3), false) } readonly property var transactions_mdl: api_wallet_page.transactions_mdl + readonly property var activation_status: current_ticker_infos.activation_status + readonly property var activation_progress: General.isZhtlc(api_wallet_page.ticker) ? General.zhtlcActivationProgress(current_ticker_infos.activation_status, api_wallet_page.ticker) : 100 Layout.fillHeight: true Layout.fillWidth: true @@ -85,9 +90,33 @@ Item Layout.preferredHeight: 60 Layout.preferredWidth: Layout.preferredHeight Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + + DexRectangle + { + anchors.centerIn: parent + anchors.fill: parent + radius: 30 + enabled: activation_progress != 100 + visible: enabled + opacity: .9 + color: DexTheme.backgroundColor + } + + DexLabel + { + anchors.centerIn: parent + anchors.fill: parent + enabled: activation_progress != 100 + visible: enabled + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + text: activation_progress + "%" + font: DexTypo.head8 + color: DexTheme.greenColor + } } - DexLabel + DefaultText { id: ticker_name Layout.topMargin: 0 @@ -106,7 +135,7 @@ Item Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter spacing: 2 - DexLabel + DefaultText { id: balance_title Layout.alignment: Qt.AlignHCenter @@ -115,7 +144,7 @@ Item color: headerTitleColor } - DexLabel + DefaultText { id: name_value Layout.alignment: Qt.AlignHCenter @@ -142,17 +171,20 @@ Item visible: false //current_ticker_infos.segwit_supported Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter spacing: 2 - DexLabel + + DefaultText { text_value: qsTr("Segwit") Layout.alignment: Qt.AlignLeft font.pixelSize: headerTitleFont color: headerTitleColor } + DefaultSwitch { id: segwitSwitch Layout.alignment: Qt.AlignVCenter + onToggled: { if(parseFloat(current_ticker_infos.balance) > 0) { @@ -180,6 +212,7 @@ Item } } }, + onRejected: function () { app.segwit_on = true API.app.wallet_pg.post_switch_address_mode(!current_ticker_infos.is_segwit_on) @@ -212,7 +245,7 @@ Item Layout.rightMargin: 10 spacing: 5 - DexLabel + DefaultText { id: price text_value: qsTr("Price") @@ -221,7 +254,7 @@ Item font.pixelSize: headerTitleFont } - DexLabel + DefaultText { text_value: { @@ -242,7 +275,7 @@ Item Layout.rightMargin: 10 spacing: 5 - DexLabel + DefaultText { id: change_24hr text_value: qsTr("Change 24hr") @@ -251,7 +284,7 @@ Item font.pixelSize: headerTitleFont } - DexLabel + DefaultText { id: change_24hr_value Layout.alignment: Qt.AlignHCenter @@ -273,7 +306,7 @@ Item Layout.rightMargin: 10 spacing: 5 - DexLabel + DefaultText { id: portfolio_title text_value: qsTr("Porfolio") @@ -282,7 +315,7 @@ Item font.pixelSize: headerTitleFont } - DexLabel + DefaultText { Layout.alignment: Qt.AlignHCenter text_value: @@ -316,10 +349,12 @@ Item ColumnLayout { visible: General.coinContractAddress(api_wallet_page.ticker) !== "" + RowLayout { Layout.alignment: Qt.AlignLeft id: contract_title_row_layout + DefaultImage { id: protocol_img @@ -327,7 +362,8 @@ Item Layout.preferredHeight: 18 Layout.preferredWidth: Layout.preferredHeight } - DexLabel + + DefaultText { id: contract_address_title text_value: General.coinPlatform(api_wallet_page.ticker) + qsTr(" Contract Address") @@ -343,7 +379,8 @@ Item Layout.alignment: Qt.AlignLeft Layout.preferredHeight: General.coinContractAddress(api_wallet_page.ticker) ? headerSmallFont : 0 visible: General.coinContractAddress(api_wallet_page.ticker) !== "" - DexLabel + + DefaultText { id: contract_address text_value: General.coinContractAddress(api_wallet_page.ticker) @@ -353,12 +390,14 @@ Item elide: Text.ElideMiddle wrapMode: Text.NoWrap } + Qaterial.Icon { size: headerTextFont icon: Qaterial.Icons.linkVariant color: contract_linkArea.containsMouse ? headerTextColor : headerTitleColor visible: General.contractURL(api_wallet_page.ticker) != "" - DexMouseArea { + + DefaultMouseArea { id: contract_linkArea anchors.fill: parent hoverEnabled: true @@ -388,10 +427,9 @@ Item Layout.preferredHeight: 48 // Send Button - DexAppButton + DefaultButton { - enabled: API.app.wallet_pg.send_available - + enabled: General.canSend(api_wallet_page.ticker, activation_progress) anchors.fill: parent radius: 18 @@ -406,10 +444,10 @@ Item else enable_fees_coin_modal.open() } - Arrow + TransactionArrow { id: arrow_send - up: true + amISender: true anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right anchors.rightMargin: 19 @@ -419,8 +457,10 @@ Item // Send button error icon DefaultAlertIcon { - visible: API.app.wallet_pg.send_availability_state !== "" - tooltipText: API.app.wallet_pg.send_availability_state + visible: activation_progress != 100 || api_wallet_page.send_availability_state !== "" + tooltipText: General.isZhtlc(api_wallet_page.ticker) && activation_progress != 100 + ? api_wallet_page.ticker + qsTr(" Activation: " + activation_progress + "%") + : api_wallet_page.send_availability_state } } @@ -433,10 +473,12 @@ Item Component { id: enable_fees_coin_comp + MultipageModal { id: root width: 300 + MultipageModalContent { titleText: qsTr("Enable %1 ?").arg(coin_to_enable_ticker) @@ -447,6 +489,7 @@ Item { Layout.fillWidth: true text: qsTr("Yes") + onClicked: { if (API.app.enable_coin(coin_to_enable_ticker) === false) @@ -456,6 +499,7 @@ Item close() } } + DefaultButton { Layout.fillWidth: true @@ -480,26 +524,40 @@ Item sourceComponent: CannotEnableCoinModal { coin_to_enable_ticker: API.app.wallet_pg.ticker_infos.fee_ticker } } - // Receive Button - DexAppButton + Item { Layout.preferredWidth: 180 Layout.preferredHeight: 48 - radius: 18 - label.text: qsTr("Receive") - label.font.pixelSize: 16 - content.anchors.left: content.parent.left - content.anchors.leftMargin: 23 + // Receive Button + DefaultButton + { + // Address wont display until activated + enabled: General.isZhtlcReady(api_wallet_page.ticker) + anchors.fill: parent + radius: 18 + + label.text: qsTr("Receive") + label.font.pixelSize: 16 + content.anchors.left: content.parent.left + content.anchors.leftMargin: enabled ? 23 : 48 - onClicked: receive_modal.open() + onClicked: receive_modal.open() + + TransactionArrow + { + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 19 + amISender: false + } + } - Arrow + // Receive button error icon + DefaultAlertIcon { - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: arrow_send.anchors.rightMargin - up: false + visible: !General.isZhtlcReady(api_wallet_page.ticker) + tooltipText: api_wallet_page.ticker + qsTr(" Activation: " + activation_progress + "%") } } @@ -516,9 +574,9 @@ Item Layout.preferredWidth: 180 Layout.preferredHeight: 48 - DexAppButton + DefaultButton { - enabled: !API.app.portfolio_pg.global_cfg_mdl.get_coin_info(api_wallet_page.ticker).is_wallet_only + enabled: !General.isWalletOnly(api_wallet_page.ticker) && activation_progress == 100 anchors.fill: parent radius: 18 @@ -537,15 +595,15 @@ Item anchors.rightMargin: arrow_send.anchors.rightMargin spacing: 2 - Arrow + TransactionArrow { - up: true + amISender: true anchors.verticalCenter: parent.verticalCenter } - Arrow + TransactionArrow { - up: false + amISender: false anchors.verticalCenter: parent.verticalCenter } } @@ -554,8 +612,10 @@ Item // Swap button error icon DefaultAlertIcon { - visible: API.app.portfolio_pg.global_cfg_mdl.get_coin_info(api_wallet_page.ticker).is_wallet_only - tooltipText: api_wallet_page.ticker + qsTr(" is wallet only") + visible: General.isWalletOnly(api_wallet_page.ticker) || activation_progress != 100 + tooltipText: General.isWalletOnly(api_wallet_page.ticker) + ? api_wallet_page.ticker + qsTr(" is wallet only") + : api_wallet_page.ticker + qsTr(" Activation: " + activation_progress + "%") } } @@ -570,7 +630,7 @@ Item Item { Layout.fillWidth: true } - DexAppButton + DefaultButton { text: qsTr("Rewards") radius: 18 @@ -596,15 +656,51 @@ Item { Layout.preferredWidth: 180 Layout.preferredHeight: 48 - visible: enabled && current_ticker_infos.is_smartchain_test_coin + visible: current_ticker_infos.is_smartchain_test_coin - DexAppButton + DefaultButton { - text: qsTr("Faucet") - radius: 18 - font.pixelSize: 16 + enabled: activation_progress == 100 anchors.fill: parent + radius: 18 + label.text: qsTr("Faucet") + label.font.pixelSize: 16 + content.anchors.left: content.parent.left + content.anchors.leftMargin: enabled ? 23 : 48 + content.anchors.rightMargin: 23 + onClicked: api_wallet_page.claim_faucet() + + Row + { + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: arrow_send.anchors.rightMargin + + Qaterial.Icon + { + icon: Qaterial.Icons.water + size: 24 + anchors.right: parent.right + anchors.leftMargin: iconSize / 2 + anchors.rightMargin: iconSize / 2 + anchors.verticalCenter: parent.verticalCenter + color: "cyan" + + DefaultTooltip + { + visible: alertArea.containsMouse && tooltipText != "" + text: "" + } + } + } + } + + // Faucet button error icon + DefaultAlertIcon + { + visible: activation_progress != 100 + tooltipText: api_wallet_page.ticker + qsTr(" Activation: " + activation_progress + "%") } } @@ -626,9 +722,9 @@ Item Layout.fillWidth: true Layout.preferredHeight: 48 - visible: current_ticker_infos.name === "Tokel" + visible: current_ticker_infos.name === "Tokel" || current_ticker_infos.name === "Marmara Credit Loops" - DexAppButton + DefaultButton { text: qsTr("Public Key") radius: 18 @@ -721,7 +817,8 @@ Item radius: 18 - onTickerChanged: loadChart() + // Chart disabled + // onTickerChanged: loadChart() function loadChart() { @@ -775,28 +872,28 @@ Item console.debug("Wallet: Loading chart for %1".arg(symbol)) -// webEngineView.loadHtml(` -// -//
-//
-// -//
-// `.arg(Dex.CurrentTheme.floatingBackgroundColor).arg(Dex.CurrentTheme.textSelectionColor)) + webEngineView.loadHtml(` + +
+
+ +
+ `.arg(Dex.CurrentTheme.floatingBackgroundColor).arg(Dex.CurrentTheme.textSelectionColor)) } WebEngineView @@ -811,7 +908,8 @@ Item target: Dex.CurrentTheme function onThemeChanged() { - loadChart(); + // Chart disabled + // loadChart(); } } @@ -828,13 +926,13 @@ Item scale: 0.5 } - DexLabel + DefaultText { text_value: qsTr("Loading market data") + "..." } } - DexLabel + DefaultText { visible: !parent.ticker_supported text_value: qsTr("There is no chart data for this ticker yet") @@ -857,11 +955,12 @@ Item ClipRRect { + id: clip_rect radius: parent.radius width: transactions_bg.width height: transactions_bg.height - DexRectangle + DefaultRectangle { anchors.fill: parent gradient: Gradient @@ -872,50 +971,73 @@ Item } } - DefaultText - { - anchors.centerIn: parent - visible: current_ticker_infos.tx_state !== "InProgress" && transactions_mdl.length === 0 - text_value: api_wallet_page.tx_fetching_busy ? (qsTr("Refreshing") + "...") : qsTr("No transactions") - font.pixelSize: Style.textSize - } - Transactions { width: parent.width height: parent.height - model: transactions_mdl.proxy_mdl } - } - } - RowLayout - { - id: fetching_text_row - visible: api_wallet_page.tx_fetching_busy - Layout.preferredHeight: fetching_text.font.pixelSize * 1.5 + ColumnLayout + { + visible: current_ticker_infos.tx_state !== "InProgress" && transactions_mdl.length === 0 + anchors.fill: parent + anchors.centerIn: parent + spacing: 24 - Layout.topMargin: -layout_margin*0.5 - Layout.bottomMargin: layout_margin*0.5 + DefaultText + { + id: fetching_text_row + Layout.topMargin: 24 + Layout.alignment: Qt.AlignHCenter + font.pixelSize: Style.textSize + text_value: + { + if (api_wallet_page.tx_fetching_busy) return qsTr("Fetching transactions...") + if (General.isZhtlc(api_wallet_page.ticker)) + { + if (activation_progress != 100) return qsTr("Please wait, %1 is %2").arg(api_wallet_page.ticker).arg(activation_progress) + qsTr("% activated...") + } + return qsTr('No transactions available') + } + } - Layout.alignment: Qt.AlignHCenter - spacing: 10 - DefaultBusyIndicator - { - Layout.alignment: Qt.AlignVCenter - Layout.preferredWidth: Style.textSizeSmall3 - Layout.preferredHeight: Layout.preferredWidth - } + DefaultBusyIndicator + { + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Layout.preferredWidth: Style.textSizeSmall3 + Layout.preferredHeight: Layout.preferredWidth + indicatorSize: 32 + indicatorDotSize: 5 + visible: api_wallet_page.tx_fetching_busy + } - DefaultText - { - id: fetching_text - Layout.alignment: Qt.AlignVCenter - text_value: qsTr("Fetching transactions") + "..." - font.pixelSize: Style.textSizeSmall3 + DefaultText + { + id: explorerLink + Layout.topMargin: 24 + Layout.alignment: Qt.AlignHCenter + visible: + { + if (activation_progress != 100) return false + return api_wallet_page.tx_fetching_busy ? false : addressURL == "" ? false : api_wallet_page.tx_fetching_failed + } + text_value: qsTr("Click to view your address on %1 (%2) block explorer").arg(current_ticker_infos.name).arg(api_wallet_page.ticker) + font.pixelSize: Style.textSize + color: explorer_mouseArea.containsMouse ? Dex.CurrentTheme.textSelectionColor : Dex.CurrentTheme.foregroundColor + + DefaultMouseArea + { + id: explorer_mouseArea + cursorShape: Qt.PointingHandCursor + anchors.fill: parent + hoverEnabled: true + onClicked: Qt.openUrlExternally(addressURL) + } + } + + Item { Layout.fillHeight: true } + } } } - - implicitHeight: Math.min(contentItem.childrenRect.height, wallet.height*0.5) } } diff --git a/atomic_defi_design/Dex/Wallet/ReceiveModal.qml b/atomic_defi_design/Dex/Wallet/ReceiveModal.qml index 71a1fb38a0..cb91aded2d 100644 --- a/atomic_defi_design/Dex/Wallet/ReceiveModal.qml +++ b/atomic_defi_design/Dex/Wallet/ReceiveModal.qml @@ -12,32 +12,43 @@ MultipageModal function reset() { } - width: 600 + width: 800 MultipageModalContent { - titleText: qsTr("Receive") + titleText: qsTr("Receive %1", "TICKER").arg(api_wallet_page.ticker) + subtitleText: qsTr("Only send %1 to this address", "TICKER").arg(api_wallet_page.ticker) + titleAlignment: Qt.AlignHCenter + subtitleAlignment: Qt.AlignHCenter + topMarginAfterTitle: 15 - TextEditWithTitle + TextEditWithCopy { - title: qsTr("Only send %1 to this address:", "TICKER").arg(api_wallet_page.ticker) - text: current_ticker_infos.address - label.font.pixelSize: 13 - copy: true - privacy: true - onCopyNotificationTitle: qsTr("%1 address".arg(api_wallet_page.ticker)) + text_value: current_ticker_infos.address + font_size: 13 + text_box_width: + { + let char_len = current_ticker_infos.address.length + if (char_len > 70) return 560 + if (char_len > 50) return 450 + if (char_len > 40) return 400 + return 300 + } + onCopyNotificationTitle: qsTr("%1 address", "TICKER").arg(api_wallet_page.ticker) onCopyNotificationMsg: qsTr("copied to clipboard.") + privacy: true } DefaultImage { - Layout.topMargin: 20 + Layout.topMargin: 15 + Layout.bottomMargin: 15 Layout.alignment: Qt.AlignHCenter source: current_ticker_infos.qrcode_address - sourceSize.width: 300 - sourceSize.height: 300 + sourceSize.width: 350 + sourceSize.height: 350 } // Buttons diff --git a/atomic_defi_design/Dex/Wallet/SendModal.qml b/atomic_defi_design/Dex/Wallet/SendModal.qml index 225b2f5af4..e48aefb716 100644 --- a/atomic_defi_design/Dex/Wallet/SendModal.qml +++ b/atomic_defi_design/Dex/Wallet/SendModal.qml @@ -35,6 +35,7 @@ MultipageModal readonly property bool is_validate_address_busy: api_wallet_page.validate_address_busy readonly property bool is_convert_address_busy: api_wallet_page.convert_address_busy readonly property string address: api_wallet_page.converted_address + readonly property string withdraw_status: api_wallet_page.withdraw_status readonly property bool auth_succeeded: api_wallet_page.auth_succeeded @@ -68,16 +69,9 @@ MultipageModal api_wallet_page.broadcast(send_result.withdraw_answer.tx_hex, false, send_result.withdraw_answer.max, input_amount.text) } - function isSpecialToken() { - return General.isTokenType(current_ticker_infos.type) - } - - function isERC20() { - return current_ticker_infos.type === "ERC-20" || current_ticker_infos.type === "BEP-20" || current_ticker_infos.type == "Matic" - } function hasErc20CaseIssue(addr) { - if(!isERC20()) return false + if(!General.isERC20(current_ticker_infos)) return false if(addr.length <= 2) return false addr = addr.substring(2) // Remove 0x @@ -96,53 +90,49 @@ MultipageModal } function feeIsHigherThanAmount() { - if(!custom_fees_switch.checked) return false - const amt = parseFloat(getCryptoAmount()) - const fee_amt = parseFloat(input_custom_fees.text) + if (!custom_fees_switch.checked) return false - return amt < fee_amt - } + if (input_amount.text === "") return false - function hasFunds() { - if(!General.hasEnoughFunds(true, api_wallet_page.ticker, "", "", _preparePage.cryptoSendMode ? input_amount.text : equivalentAmount.value)) - return false + const amount = parseFloat(getCryptoAmount()) - if(custom_fees_switch.checked) { - if(isSpecialToken()) { - const gas_limit = parseFloat(input_custom_fees_gas.text) - const gas_price = parseFloat(input_custom_fees_gas_price.text) + if (General.isSpecialToken(current_ticker_infos)) { + const parent_ticker = General.getFeesTicker(current_ticker_infos) + const gas_limit = parseFloat(input_custom_fees_gas.text) + const gas_price = parseFloat(input_custom_fees_gas_price.text) + if (isNaN(gas_price) || isNaN(gas_limit)) return false - const unit = current_ticker_infos.type === "ERC-20" ? 1000000000 : 100000000 - const fee_parent_token = (gas_limit * gas_price)/unit + const unit = current_ticker_infos.type === "ERC-20" ? 1000000000 : 100000000 + const fee_parent_token = (gas_limit * gas_price)/unit - const parent_ticker = current_ticker_infos.type === "ERC-20" ? "ETH" : "QTUM" - if(api_wallet_page.ticker === parent_ticker) { - const amount = parseFloat(getCryptoAmount()) - const total_needed = amount + fee_parent_token - if(!General.hasEnoughFunds(true, parent_ticker, "", "", total_needed.toString())) - return false - } - else { - if(!General.hasEnoughFunds(true, parent_ticker, "", "", fee_parent_token.toString())) - return false - } + if(api_wallet_page.ticker === parent_ticker) { + const total_needed = amount + fee_parent_token + if(General.hasEnoughFunds(true, parent_ticker, "", "", total_needed.toString())) + return false } else { - if(feeIsHigherThanAmount()) return false - - if(!General.hasEnoughFunds(true, api_wallet_page.ticker, "", "", input_custom_fees.text)) + if(General.hasEnoughFunds(true, parent_ticker, "", "", fee_parent_token.toString())) return false } + return true + } + else { + const fee_amt = parseFloat(input_custom_fees.text) + return amount < fee_amt } + } - return true + function hasFunds() { + if(!General.hasEnoughFunds(true, api_wallet_page.ticker, "", "", _preparePage.cryptoSendMode ? input_amount.text : equivalentAmount.value)) + return false + return true } function feesAreFilled() { return (!custom_fees_switch.checked || ( - (!isSpecialToken() && input_custom_fees.acceptableInput) || - (isSpecialToken() && input_custom_fees_gas.acceptableInput && input_custom_fees_gas_price.acceptableInput && + (!General.isSpecialToken(current_ticker_infos) && input_custom_fees.acceptableInput) || + (General.isSpecialToken(current_ticker_infos) && input_custom_fees_gas.acceptableInput && input_custom_fees_gas_price.acceptableInput && parseFloat(input_custom_fees_gas.text) > 0 && parseFloat(input_custom_fees_gas_price.text) > 0) ) ) @@ -158,7 +148,7 @@ MultipageModal input_amount.text = current_ticker_infos.balance } - width: 650 + width: 750 closePolicy: Popup.NoAutoClose @@ -172,21 +162,25 @@ MultipageModal reset() } - onSend_rpc_resultChanged: { - if (is_send_busy === false) { + onSend_rpc_resultChanged: + { + if (is_send_busy === false) + { return } // Local var, faster const result = General.clone(send_rpc_result) - if(result.error_code) { + if (result.error_code) + { root.close() - console.log("Send Error:", result.error_code, " Message:", result.error_message) toast.show(qsTr("Failed to send"), General.time_toast_important_error, result.error_message) } - else { - if(!result || !result.withdraw_answer) { + else + { + if (!result || !result.withdraw_answer) + { reset() return } @@ -203,15 +197,6 @@ MultipageModal send_result = result } - onAuth_succeededChanged: { - if (!auth_succeeded) { - console.log("Double verification failed, cannot confirm sending.") - } - else { - console.log("Double verification succeeded, validate sending."); - } - } - onBroadcast_resultChanged: { if (is_broadcast_busy === false) { return @@ -220,7 +205,7 @@ MultipageModal if(root.visible && broadcast_result !== "") { if(broadcast_result.indexOf("error") !== -1) { reset() - showError(qsTr("Failed to Send"), General.prettifyJSON(broadcast_result)) + showError(qsTr("Failed to Broadcast"), General.prettifyJSON(broadcast_result)) } else { root.currentIndex = 2 @@ -232,6 +217,7 @@ MultipageModal { if (!is_validate_address_busy) { + needFix = false address_data = api_wallet_page.validate_address_data if (address_data.reason !== "") { @@ -244,7 +230,7 @@ MultipageModal } if (address_data.convertible) { - reason.text = address_data.reason; + reason.text = address_data.reason; if (needFix!==true) needFix = true; } } @@ -267,17 +253,16 @@ MultipageModal { id: _preparePage + property bool cryptoSendMode: true + titleText: qsTr("Prepare to send ") + current_ticker_infos.name titleAlignment: Qt.AlignHCenter - property bool cryptoSendMode: true - DefaultRectangle { - enabled: !root.segwit && !root.is_send_busy - Layout.preferredWidth: 420 + Layout.preferredWidth: 500 Layout.preferredHeight: 44 Layout.alignment: Qt.AlignHCenter @@ -288,12 +273,16 @@ MultipageModal { id: input_address - width: 390 + width: 470 height: 44 - placeholderText: qsTr("Address of the recipient") - onTextChanged: api_wallet_page.validate_address(text) forceFocus: true + font: General.isZhtlc(api_wallet_page.ticker) ? DexTypo.body3 : DexTypo.body2 + onTextChanged: + { + text = text.replace(/(\r\n|\n|\r)/gm,"").replace(" ", "") + api_wallet_page.validate_address(text) + } } Rectangle @@ -340,16 +329,19 @@ MultipageModal { visible: errorView && input_address.text !== "" Layout.alignment: Qt.AlignHCenter - Layout.fillWidth: true + Layout.preferredWidth: 380 + spacing: 4 + + Item { Layout.fillWidth: true } DefaultText { id: reason Layout.alignment: Qt.AlignVCenter - Layout.fillWidth: true + Layout.preferredWidth: 320 - wrapMode: Text.WrapAtWordBoundaryOrAnywhere + wrapMode: Label.Wrap color: Dex.CurrentTheme.noColor text_value: qsTr("The address has to be mixed case.") } @@ -358,16 +350,15 @@ MultipageModal { enabled: !root.is_send_busy visible: needFix - Layout.alignment: Qt.AlignVCenter Layout.leftMargin: 10 Layout.preferredWidth: 50 Layout.preferredHeight: 28 - text: qsTr("Fix") - onClicked: api_wallet_page.convert_address(input_address.text, address_data.to_address_format) } + + Item { Layout.fillWidth: true } } // Amount to send @@ -378,7 +369,7 @@ MultipageModal enabled: !root.is_send_busy Layout.alignment: Qt.AlignHCenter - Layout.preferredWidth: 420 + Layout.preferredWidth: 500 Layout.preferredHeight: 44 Layout.topMargin: 32 @@ -429,11 +420,11 @@ MultipageModal { if (_preparePage.cryptoSendMode) { - input_amount.text = current_ticker_infos.balance; + input_amount.text = API.app.get_balance(api_wallet_page.ticker); } else { - let cryptoBalance = new BigNumber(current_ticker_infos.balance); + let cryptoBalance = new BigNumber(API.app.get_balance(api_wallet_page.ticker)); input_amount.text = cryptoBalance.multipliedBy(current_ticker_infos.current_currency_ticker_price).toFixed(8); } } @@ -569,23 +560,59 @@ MultipageModal } } - // Custom fees switch - DexSwitch + ColumnLayout { - id: custom_fees_switch - enabled: !root.is_send_busy + visible: General.getCustomFeeType(current_ticker_infos) + Layout.preferredWidth: 380 + Layout.alignment: Qt.AlignHCenter Layout.topMargin: 32 - text: qsTr("Enable Custom Fees") - onCheckedChanged: input_custom_fees.text = "" - } - // Custom fees warning - DefaultText - { - visible: custom_fees_switch.checked - font.pixelSize: 14 - color: Dex.CurrentTheme.noColor - text_value: qsTr("Only use custom fees if you know what you are doing!") + // Custom fees switch + DefaultSwitch + { + id: custom_fees_switch + visible: !General.isZhtlc(api_wallet_page.ticker) + enabled: !root.is_send_busy + Layout.preferredWidth: 260 + onCheckedChanged: input_custom_fees.text = "" + labelWidth: 200 + label.text: qsTr("Enable Custom Fees") + label.wrapMode: Label.NoWrap + } + + RowLayout + { + visible: custom_fees_switch.checked + // Custom fees warning + DefaultText + { + font.pixelSize: 14 + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: DefaultText.AlignHCenter + color: Dex.CurrentTheme.noColor + } + + DefaultText + { + visible: input_custom_fees.visible + font.pixelSize: 14 + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: DefaultText.AlignHCenter + color: Dex.CurrentTheme.noColor + text_value: qsTr("Only use custom fees if you know what you are doing! ") + } + + DefaultText + { + visible: input_custom_fees_gas.visible + font.pixelSize: 14 + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: DefaultText.AlignHCenter + color: Dex.CurrentTheme.noColor + text_value: qsTr("Only use custom fees if you know what you are doing! ") + General.cex_icon + DefaultInfoTrigger { triggerModal: gas_info_modal } + } + } } // Custom Fees section @@ -594,12 +621,13 @@ MultipageModal visible: custom_fees_switch.checked Layout.preferredWidth: parent.width + Layout.alignment: Qt.AlignHCenter Layout.topMargin: 8 // Normal coins, Custom fees input AmountField { - visible: !isSpecialToken() + visible: General.getCustomFeeType(current_ticker_infos) == "UTXO" id: input_custom_fees @@ -615,7 +643,8 @@ MultipageModal // Token coins ColumnLayout { - visible: isSpecialToken() + visible: General.getCustomFeeType(current_ticker_infos) == "Gas" + Layout.alignment: Qt.AlignHCenter // Gas input @@ -628,7 +657,7 @@ MultipageModal Layout.preferredWidth: 380 Layout.preferredHeight: 38 - placeholderText: qsTr("Gas Limit") + " [" + General.tokenUnitName(current_ticker_infos.type) + "]" + placeholderText: qsTr("Gas Limit") } // Gas price input @@ -652,10 +681,12 @@ MultipageModal visible: feeIsHigherThanAmount() Layout.alignment: Qt.AlignHCenter + horizontalAlignment: DefaultText.AlignHCenter - wrapMode: Text.Wrap + wrapMode: Label.Wrap color: Style.colorRed - text_value: qsTr("Custom Fee can't be higher than the amount") + text_value: qsTr("Custom Fee can't be higher than the amount") + "\n" + + qsTr("You have %1", "AMT TICKER").arg(General.formatCrypto("", API.app.get_balance(General.getFeesTicker(current_ticker_infos)), General.getFeesTicker(current_ticker_infos))) } } @@ -663,15 +694,38 @@ MultipageModal DefaultText { Layout.topMargin: 16 - wrapMode: Text.Wrap + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: DefaultText.AlignHCenter + wrapMode: Label.Wrap visible: !fee_error.visible && !hasFunds() color: Dex.CurrentTheme.noColor - text_value: qsTr("Not enough funds.") + "\n" + qsTr("You have %1", "AMT TICKER").arg(General.formatCrypto("", API.app.get_balance(api_wallet_page.ticker), api_wallet_page.ticker)) + text_value: qsTr("Not enough funds.") + "\n" + + qsTr("You have %1", "AMT TICKER").arg(General.formatCrypto("", API.app.get_balance(api_wallet_page.ticker), api_wallet_page.ticker)) + } + + DefaultBusyIndicator { + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Layout.preferredWidth: 32 + Layout.preferredHeight: Layout.preferredWidth + indicatorSize: Layout.preferredWidth + indicatorDotSize: 5 + visible: root.is_send_busy + } + + // Withdraw status + DefaultText + { + Layout.topMargin: 16 + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: DefaultText.AlignHCenter + wrapMode: Label.Wrap + visible: General.isZhtlc(api_wallet_page.ticker) && withdraw_status != "Complete" + color: Dex.CurrentTheme.foregroundColor + text_value: withdraw_status } - DefaultBusyIndicator { visible: root.is_send_busy } // Footer RowLayout @@ -681,7 +735,7 @@ MultipageModal DefaultButton { - text: qsTr("Close") + text: qsTr("Cancel") Layout.alignment: Qt.AlignLeft Layout.preferredWidth: parent.width / 100 * 48 @@ -705,7 +759,7 @@ MultipageModal text: qsTr("Prepare") onClicked: prepareSendCoin(input_address.text, getCryptoAmount(), custom_fees_switch.checked, input_custom_fees.text, - isSpecialToken(), input_custom_fees_gas.text, input_custom_fees_gas_price.text) + General.isSpecialToken(current_ticker_infos), input_custom_fees_gas.text, input_custom_fees_gas_price.text) } } @@ -721,7 +775,6 @@ MultipageModal input_address.text = selected_address selected_address = "" - console.debug("SendModal: Selected %1 address from addressbook.".arg(input_address.text)) } } } @@ -731,12 +784,32 @@ MultipageModal MultipageModalContent { titleText: qsTr("Send") + titleAlignment: Qt.AlignHCenter // Address - TextEditWithTitle + TitleText { - title: qsTr("Recipient's address") - text: input_address.text + text: qsTr("Recipient's address") + Layout.fillWidth: true + color: Dex.CurrentTheme.foregroundColor2 + } + + TextEditWithCopy + { + text_value: input_address.text + font_size: 13 + align_left: true + text_box_width: + { + let char_len = current_ticker_infos.address.length + if (char_len > 70) return 560 + if (char_len > 50) return 450 + if (char_len > 40) return 400 + return 300 + } + onCopyNotificationTitle: qsTr("%1 address", "TICKER").arg(api_wallet_page.ticker) + onCopyNotificationMsg: qsTr("copied to clipboard.") + privacy: true } // Amount @@ -784,17 +857,20 @@ MultipageModal DefaultBusyIndicator { + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Layout.preferredWidth: 32 + Layout.preferredHeight: Layout.preferredWidth + indicatorSize: Layout.preferredWidth + indicatorDotSize: 5 visible: root.is_broadcast_busy } // Buttons footer: [ - Item - { - Layout.fillWidth: true - }, - DexAppButton + Item { Layout.fillWidth: true }, + + DefaultButton { text: qsTr("Back") leftPadding: 40 @@ -803,10 +879,9 @@ MultipageModal onClicked: root.currentIndex = 0 enabled: !root.is_broadcast_busy }, - Item - { - Layout.fillWidth: true - }, + + Item { Layout.fillWidth: true }, + DexAppOutlineButton { text: qsTr("Send") @@ -816,10 +891,8 @@ MultipageModal radius: 18 enabled: !root.is_broadcast_busy }, - Item - { - Layout.fillWidth: true - } + + Item { Layout.fillWidth: true } ] } diff --git a/atomic_defi_design/Dex/Wallet/SendModalContactList.qml b/atomic_defi_design/Dex/Wallet/SendModalContactList.qml index 20984b8dd2..9e9bbd58aa 100644 --- a/atomic_defi_design/Dex/Wallet/SendModalContactList.qml +++ b/atomic_defi_design/Dex/Wallet/SendModalContactList.qml @@ -18,6 +18,9 @@ MultipageModal property string ticker: api_wallet_page.ticker property var selected_address: "" + Component.onCompleted: API.app.addressbookPg.model.proxy.typeFilter = ticker + Component.onDestruction: API.app.addressbookPg.model.proxy.typeFilter = "" + MultipageModalContent { titleText: qsTr("Select a contact with an %1 address").arg(ticker) @@ -28,8 +31,8 @@ MultipageModal Layout.alignment: Qt.AlignHCenter Layout.fillWidth: true placeholderText: qsTr("Search for contacts...") - onTextChanged: API.app.addressbook_pg.model.proxy.search_exp = text - Component.onDestruction: API.app.addressbook_pg.model.proxy.search_exp = "" + onTextChanged: API.app.addressbookPg.model.proxy.searchExp = text + Component.onDestruction: API.app.addressbookPg.model.proxy.searchExp = "" } // Contact List @@ -39,7 +42,7 @@ MultipageModal Layout.fillWidth: true - model: API.app.addressbook_pg.model.proxy + model: API.app.addressbookPg.model.proxy delegate: DefaultRectangle { property int addressesCount @@ -51,10 +54,10 @@ MultipageModal Component.onCompleted: { - modelData.proxy_filter.filter_type = ticker - addressesCount = modelData.proxy_filter.rowCount() + modelData.proxyFilter.filterType = ticker + addressesCount = modelData.proxyFilter.rowCount() } - Component.onDestruction: contactModel.proxy_filter.filter_type = "" + Component.onDestruction: contactModel.proxyFilter.typeFilter = "" DefaultMouseArea { @@ -95,9 +98,6 @@ MultipageModal anchors.bottom: parent.bottom } } - - Component.onCompleted: API.app.addressbook_pg.model.proxy.type_filter = ticker - Component.onDestruction: API.app.addressbook_pg.model.proxy.type_filter = "" } footer: @@ -120,9 +120,9 @@ MultipageModal readonly property var defaultContactModel: { - "proxy_filter": + "proxyFilter": { - "filter_type": "" + "filterType": "" }, "name": "" } @@ -131,7 +131,7 @@ MultipageModal property int columnsMargin: 10 property int nameColumnWidth: width * 0.3 - titleText: qsTr("Choose an %1 address of %2").arg(contactModel.proxy_filter.filter_type).arg(contactModel.name) + titleText: qsTr("Choose an %1 address of %2").arg(contactModel.proxyFilter.filterType).arg(contactModel.name) RowLayout { @@ -160,7 +160,7 @@ MultipageModal Layout.fillWidth: true - model: addressesView.contactModel.proxy_filter + model: addressesView.contactModel.proxyFilter delegate: DefaultRectangle { width: addressListView.width diff --git a/atomic_defi_design/Dex/Wallet/SendResult.qml b/atomic_defi_design/Dex/Wallet/SendResult.qml index 0c7e070d10..41b06be0cb 100644 --- a/atomic_defi_design/Dex/Wallet/SendResult.qml +++ b/atomic_defi_design/Dex/Wallet/SendResult.qml @@ -5,24 +5,57 @@ import QtQuick.Controls 2.15 import "../Components" import "../Constants" import App 1.0 +import Dex.Themes 1.0 as Dex MultipageModalContent { id: root property var result - property alias address: address.text + property alias address: address.text_value property string custom_amount - property alias tx_hash: tx_hash.text + property alias tx_hash: tx_hash.text_value titleText: qsTr("Transaction Complete!") + // Transaction Hash + TitleText + { + text: qsTr("Transaction Hash") + Layout.fillWidth: true + visible: text !== "" + color: Dex.CurrentTheme.foregroundColor2 + } + + TextEditWithCopy + { + id: tx_hash + font_size: 13 + align_left: true + text_box_width: 560 + onCopyNotificationTitle: qsTr("%1 txid", "TICKER").arg(api_wallet_page.ticker) + onCopyNotificationMsg: qsTr("copied to clipboard.") + privacy: true + } + // Address - TextEditWithTitle + TitleText { - id: address - title: qsTr("Recipient's address") + text: qsTr("Recipient's address") + Layout.fillWidth: true visible: text !== "" + color: Dex.CurrentTheme.foregroundColor2 + } + + TextEditWithCopy + { + id: address + font_size: 13 + align_left: true + text_box_width: 560 + onCopyNotificationTitle: qsTr("%1 address", "TICKER").arg(api_wallet_page.ticker) + onCopyNotificationMsg: qsTr("copied to clipboard.") + privacy: true } // Amount @@ -68,13 +101,6 @@ MultipageModalContent text: result.withdraw_answer.date } - // Transaction Hash - TextEditWithTitle - { - id: tx_hash - Layout.fillWidth: true - title: qsTr("Transaction Hash") - } // Buttons footer: @@ -91,7 +117,7 @@ MultipageModalContent Layout.fillWidth: true text: qsTr("View on Explorer") radius: 18 - onClicked: General.viewTxAtExplorer(api_wallet_page.ticker, tx_hash.text) + onClicked: General.viewTxAtExplorer(api_wallet_page.ticker, tx_hash.text_value) } ] } diff --git a/atomic_defi_design/Dex/Wallet/Sidebar.qml b/atomic_defi_design/Dex/Wallet/Sidebar.qml index fefe8f9179..4df9424272 100644 --- a/atomic_defi_design/Dex/Wallet/Sidebar.qml +++ b/atomic_defi_design/Dex/Wallet/Sidebar.qml @@ -9,6 +9,7 @@ import "../Components" import "../Constants" as Constants import App 1.0 import Dex.Themes 1.0 as Dex +import Dex.Components 1.0 as Dex // Coins bar at left side Item @@ -58,21 +59,9 @@ Item Layout.preferredWidth: 150 Layout.preferredHeight: 38 - textField.placeholderText: qsTr("Search coin") + textField.placeholderText: qsTr("Search") forceFocus: true - textField.onTextChanged: portfolio_coins.setFilterFixedString(textField.text) - Component.onDestruction: portfolio_coins.setFilterFixedString("") - - Connections - { - target: root - - function onResetted() - { - if (searchCoinField.textField.text === "") resetCoinFilter() - else searchCoinField.textField.text = "" - } - } + searchModel: portfolio_coins } // Coins list @@ -83,14 +72,21 @@ Item Layout.fillHeight: true Layout.alignment: Qt.AlignHCenter color: 'transparent' - content: DexListView { + content: Dex.ListView + { id: list height: list_bg.height model: portfolio_coins topMargin: 5 bottomMargin: 5 scrollbar_visible: false - DexRectangle { + + reuseItems: true + + delegate: SidebarItemDelegate { } + + Dex.Rectangle + { anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter width: parent.width + 4 @@ -106,23 +102,21 @@ Item } } - DexRectangle { + Dex.Rectangle + { anchors.horizontalCenter: parent.horizontalCenter width: parent.width + 4 height: 30 radius: 8 opacity: .5 visible: list.position > 0 ? true : false - Qaterial.Icon { + Qaterial.Icon + { anchors.centerIn: parent - color: DexTheme.foregroundColor + color: Dex.CurrentTheme.foregroundColor icon: Qaterial.Icons.arrowUpCircleOutline } } - - reuseItems: true - - delegate: SidebarItemDelegate { } } } diff --git a/atomic_defi_design/Dex/Wallet/SidebarItemDelegate.qml b/atomic_defi_design/Dex/Wallet/SidebarItemDelegate.qml index 408a48545d..8d3a1ad757 100644 --- a/atomic_defi_design/Dex/Wallet/SidebarItemDelegate.qml +++ b/atomic_defi_design/Dex/Wallet/SidebarItemDelegate.qml @@ -6,15 +6,18 @@ import Qaterial 1.0 as Qaterial import QtGraphicalEffects 1.0 import "../Components" -import "../Constants" as Constants +import "../Constants" as Dex import App 1.0 -GradientRectangle { +GradientRectangle +{ + property int activation_progress: Dex.General.zhtlcActivationProgress(activation_status, ticker) + width: list_bg.width - list_bg.border.width*2 - 6 height: 44 - radius: Constants.Style.rectangleCornerRadius + 4 + radius: Dex.Style.rectangleCornerRadius + 4 - start_color: api_wallet_page.ticker === ticker ? DexTheme.buttonColorEnabled : mouse_area.containsMouse ? DexTheme.buttonColorHovered : 'transparent' + start_color: api_wallet_page.ticker === ticker ? Dex.DexTheme.buttonColorEnabled : mouse_area.containsMouse ? Dex.DexTheme.buttonColorHovered : 'transparent' end_color: 'transparent' // Click area @@ -24,23 +27,23 @@ GradientRectangle { hoverEnabled: true acceptedButtons: Qt.LeftButton | Qt.RightButton - onClicked: { - if(!can_change_ticker) return - - if (mouse.button === Qt.RightButton) context_menu.popup() - else api_wallet_page.ticker = ticker - } - onPressAndHold: { - if(!can_change_ticker) return - - if (mouse.source === Qt.MouseEventNotSynthesized) context_menu.popup() + onClicked: + { + if (mouse.button === Qt.RightButton) + { + context_menu.can_disable = General.canDisable(ticker) + context_menu.popup() + } + else + { + api_wallet_page.ticker = ticker + } } + onPressAndHold: if (mouse.source === Qt.MouseEventNotSynthesized) context_menu.popup() } // Right click menu - CoinMenu { - id: context_menu - } + CoinMenu { id: context_menu } readonly property double side_margin: 16 @@ -50,9 +53,33 @@ GradientRectangle { anchors.left: parent.left anchors.leftMargin: side_margin - scrollbar_margin - source: Constants.General.coinIcon(ticker) - width: Constants.Style.textSizeSmall4*2 + source: Dex.General.coinIcon(ticker) + width: Dex.Style.textSizeSmall4*2 anchors.verticalCenter: parent.verticalCenter + + DexRectangle + { + anchors.centerIn: parent + anchors.fill: parent + radius: 15 + enabled: Dex.General.isZhtlc(ticker) ? activation_progress != 100 : false + visible: enabled + opacity: .9 + color: Dex.DexTheme.backgroundColor + } + + DexLabel + { + anchors.centerIn: parent + anchors.fill: parent + enabled: Dex.General.isZhtlc(ticker) ? activation_progress != 100 : false + visible: enabled + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + text: activation_progress + "%" + font: Dex.DexTypo.head8 + color: Dex.DexTheme.greenColor + } } ColumnLayout { @@ -64,10 +91,10 @@ GradientRectangle { DexLabel { Layout.alignment: Qt.AlignLeft Layout.preferredWidth: 80 - font: DexTypo.caption - wrapMode: DexLabel.WordWrap + font: Dex.DexTypo.caption + wrapMode: Text.WordWrap text_value: mouse_area.containsMouse ? name.replace(" (TESTCOIN)", "") : ticker - color: DexTheme.foregroundColor + color: Dex.DexTheme.foregroundColor } } } diff --git a/atomic_defi_design/Dex/Wallet/TransactionDetailsModal.qml b/atomic_defi_design/Dex/Wallet/TransactionDetailsModal.qml index f6e8e37855..25380f302a 100644 --- a/atomic_defi_design/Dex/Wallet/TransactionDetailsModal.qml +++ b/atomic_defi_design/Dex/Wallet/TransactionDetailsModal.qml @@ -13,6 +13,7 @@ import Dex.Themes 1.0 as Dex MultipageModal { id: root + width: 780 function reset() { } @@ -28,12 +29,34 @@ MultipageModal { titleText: qsTr("Transaction Details") + // Transaction Hash + TitleText + { + text: qsTr("Transaction Hash") + Layout.fillWidth: true + visible: text !== "" + color: Dex.CurrentTheme.foregroundColor2 + } + + TextEditWithCopy + { + id: tx_hash + font_size: 13 + align_left: true + text_box_width: 600 + text_value: !details ? "" : details.tx_hash + linkURL: !details ? "" :General.getTxExplorerURL(api_wallet_page.ticker, details.tx_hash, false) + onCopyNotificationTitle: qsTr("%1 txid", "TICKER").arg(api_wallet_page.ticker) + onCopyNotificationMsg: qsTr("copied to clipboard.") + privacy: true + } + // Amount TextEditWithTitle { title: qsTr("Amount") text: !details ? "" : General.formatCrypto(!details.am_i_sender, details.amount, api_wallet_page.ticker, details.amount_fiat, API.app.settings_pg.current_currency) - value_color: !details ? "white" : details.am_i_sender ? DexTheme.redColor : DexTheme.greenColor + value_color: !details ? "white" : details.am_i_sender ? Dex.CurrentTheme.noColor : Dex.CurrentTheme.okColor privacy: true label.font.pixelSize: 13 } @@ -43,11 +66,35 @@ MultipageModal { title: qsTr("Fees") text: !details ? "" : General.formatCrypto(parseFloat(details.fees) < 0, Math.abs(parseFloat(details.fees)), current_ticker_infos.fee_ticker, details.fees_amount_fiat, API.app.settings_pg.current_currency) - value_color: !details ? "white" : parseFloat(details.fees) > 0 ? DexTheme.redColor : DexTheme.greenColor + value_color: !details ? "white" : parseFloat(details.fees) > 0 ? Dex.CurrentTheme.noColor : Dex.CurrentTheme.okColor privacy: true label.font.pixelSize: 13 } + AddressList + { + width: parent.width + title: qsTr("From") + model: !details ? [] : + details.from + linkURL: !details ? "" :General.getAddressExplorerURL(api_wallet_page.ticker, details.from) + onCopyNotificationTitle: qsTr("From address") + } + + AddressList + { + width: parent.width + title: qsTr("To") + model: !details ? + [] : details.to.length > 1 ? + General.arrayExclude(details.to, details.from[0]) : details.to + linkURL: !details ? "" + : details.to.length > 1 + ? General.getAddressExplorerURL(api_wallet_page.ticker, General.arrayExclude(details.to, details.from[0])) + : General.getAddressExplorerURL(api_wallet_page.ticker, details.to) + onCopyNotificationTitle: qsTr("To address") + } + // Date TextEditWithTitle { @@ -56,19 +103,6 @@ MultipageModal label.font.pixelSize: 13 } - // Transaction Hash - TextEditWithTitle - { - id: txHash - title: qsTr("Transaction Hash") - text: !details ? "" : details.tx_hash - label.font.pixelSize: 13 - privacy: true - copy: true - - onCopyNotificationTitle: qsTr("Transactions") - onCopyNotificationMsg: qsTr("txid copied to clipboard") - } // Confirmations TextEditWithTitle @@ -86,32 +120,6 @@ MultipageModal label.font.pixelSize: 13 } - DexRectangle { - Layout.fillWidth: true - Layout.preferredHeight: addressColumn.height + 10 - color: DexTheme.contentColorTop - - Column { - id: addressColumn - width: parent.width - 10 - anchors.centerIn: parent - - AddressList { - width: parent.width - title: qsTr("From") - model: !details ? [] : - details.from - } - - AddressList { - width: parent.width - title: qsTr("To") - model: !details ? - [] : details.to.length > 1 ? - General.arrayExclude(details.to, details.from[0]) : details.to - } - } - } // Notes TextAreaWithTitle @@ -124,6 +132,7 @@ MultipageModal titleColor: Dex.CurrentTheme.foregroundColor2 remove_newline: false field.text: !details ? "" : details.transaction_note + field.rightPadding: 0 saveable: true field.onTextChanged: @@ -138,7 +147,7 @@ MultipageModal // Buttons footer: [ - DexButton + DefaultButton { Layout.fillWidth: true text: qsTr("Close") @@ -147,6 +156,7 @@ MultipageModal radius: 18 onClicked: root.close() }, + DexAppOutlineButton { Layout.fillWidth: true diff --git a/atomic_defi_design/Dex/Wallet/Transactions.qml b/atomic_defi_design/Dex/Wallet/Transactions.qml index 9ad085c5d5..30e94fa2b8 100644 --- a/atomic_defi_design/Dex/Wallet/Transactions.qml +++ b/atomic_defi_design/Dex/Wallet/Transactions.qml @@ -5,31 +5,34 @@ import QtQuick.Controls 2.15 import "../Components" import "../Constants" import Dex.Themes 1.0 as Dex +import Dex.Components 1.0 as Dex -DefaultListView +Dex.ListView { id: list readonly property int row_height: 45 - ModalLoader - { - id: tx_details_modal - sourceComponent: TransactionDetailsModal {} - } + property real _categoryColumnWidth: 140 + property real _cryptoColumnWidth: 170 + property real _fiatColumnWidth: 170 + property real _feeColumnWidth: 225 + property real _dateColumnWidth: 170 + + model: transactions_mdl.proxy_mdl // Row - delegate: DexRectangle + delegate: Dex.Rectangle { id: rectangle - implicitWidth: list.width + width: list.width height: row_height radius: 0 border.width: 0 colorAnimation: false color: mouse_area.containsMouse ? Dex.CurrentTheme.buttonColorHovered : 'transparent' - DexMouseArea + Dex.MouseArea { id: mouse_area anchors.fill: parent @@ -41,84 +44,96 @@ DefaultListView } } - Circle + RowLayout { - id: note_tag - width: 6 - color: Style.colorOrange - anchors.left: parent.left - anchors.leftMargin: 15 - anchors.verticalCenter: parent.verticalCenter - visible: transaction_note !== "" - } + id: tx_row + anchors.fill: parent + anchors.margins: 15 - Arrow - { - id: received_icon - up: am_i_sender ? true : false - color: !am_i_sender ? Dex.CurrentTheme.arrowUpColor : Dex.CurrentTheme.arrowDownColor - anchors.verticalCenter: parent.verticalCenter - anchors.left: note_tag.right - anchors.leftMargin: 10 - } + RowLayout + { + spacing: 3 + Layout.preferredWidth: _categoryColumnWidth - // Description - DefaultText - { - id: description - text_value: am_i_sender ? qsTr("Sent") : qsTr("Received") - font.pixelSize: Style.textSizeSmall3 - anchors.verticalCenter: parent.verticalCenter - anchors.left: received_icon.right - anchors.leftMargin: 10 - } + Circle + { + id: note_tag + width: 6 + color: Style.colorOrange + visible: transaction_note !== "" + } - // Crypto - DefaultText - { - id: crypto_amount - text_value: General.formatCrypto(!am_i_sender, amount, api_wallet_page.ticker) - font.pixelSize: description.font.pixelSize - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: parent.width * 0.2 - color: am_i_sender ? Dex.CurrentTheme.noColor : Dex.CurrentTheme.okColor - privacy: true - } + TransactionArrow + { + id: received_icon + amISender: am_i_sender ? true : false + } - // Fiat - DefaultText - { - text_value: General.formatFiat(!am_i_sender, amount_fiat, API.app.settings_pg.current_currency) - font.pixelSize: description.font.pixelSize - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: parent.width * 0.4 - color: crypto_amount.color - privacy: true - } + // Description + Dex.Text + { + id: description + horizontalAlignment: Qt.AlignLeft + text_value: am_i_sender ? qsTr("Sent") : qsTr("Received") + font.pixelSize: Style.textSizeSmall3 + } + } - // Fee - DefaultText - { - text_value: General.formatCrypto(!(parseFloat(fees) > 0), Math.abs(parseFloat(fees)), - current_ticker_infos.fee_ticker + " " + qsTr("fees")) - font.pixelSize: description.font.pixelSize - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: parent.width * 0.575 - privacy: true - } + // Crypto + Dex.Text + { + id: crypto_amount + Layout.preferredWidth: _cryptoColumnWidth + horizontalAlignment: Text.AlignRight + text_value: + { + api_wallet_page.ticker.length > 6 + ? General.formatCrypto(!am_i_sender, amount, '', false, false, 6, true) + : General.formatCrypto(!am_i_sender, amount, api_wallet_page.ticker, false, false, 6, true) - // Date - DefaultText - { - font.pixelSize: description.font.pixelSize - text_value: !date || unconfirmed ? qsTr("Unconfirmed") : date - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: 20 - privacy: true + } + font.pixelSize: description.font.pixelSize + color: am_i_sender ? Dex.CurrentTheme.noColor : Dex.CurrentTheme.okColor + privacy: true + } + + // Fiat + Dex.Text + { + Layout.preferredWidth: _fiatColumnWidth + horizontalAlignment: Text.AlignRight + text_value: General.formatFiat(!am_i_sender, amount_fiat, API.app.settings_pg.current_currency) + font.pixelSize: description.font.pixelSize + color: crypto_amount.color + privacy: true + } + + // Fee + Dex.Text + { + Layout.preferredWidth: _feeColumnWidth + horizontalAlignment: Text.AlignRight + text_value: General.formatCrypto(!(parseFloat(fees) > 0), Math.abs(parseFloat(fees)), + current_ticker_infos.fee_ticker + " " + qsTr("fees")) + font.pixelSize: description.font.pixelSize + privacy: true + } + + // Date + Dex.Text + { + Layout.preferredWidth: _dateColumnWidth + horizontalAlignment: Text.AlignRight + font.pixelSize: description.font.pixelSize + text_value: !date || unconfirmed ? qsTr("Unconfirmed") : date + privacy: true + } } } + + ModalLoader + { + id: tx_details_modal + sourceComponent: TransactionDetailsModal {} + } } diff --git a/atomic_defi_design/Dex/main.qml b/atomic_defi_design/Dex/main.qml index 4e33fed379..546f406a79 100644 --- a/atomic_defi_design/Dex/main.qml +++ b/atomic_defi_design/Dex/main.qml @@ -1,14 +1,12 @@ -//! Qt Imports import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Controls.Universal 2.15 import QtQuick.Layouts 1.12 import Qt.labs.settings 1.0 +import ModelHelper 0.1 -//! 3rdParty Imports import Qaterial 1.0 as Qaterial -//! Project Imports import App 1.0 import "Components" import Dex.Themes 1.0 as Dex @@ -17,11 +15,12 @@ DexWindow { id: window - property int previousX: 0 - property int previousY: 0 - property int real_visibility + property int previousX: 0 + property int previousY: 0 + property int real_visibility property bool isOsx: Qt.platform.os == "osx" property bool logged: false + property var orders: API.app.orders_mdl.orders_proxy_mdl.ModelHelper title: API.app_name visible: true @@ -108,32 +107,8 @@ DexWindow anchors.fill: parent onClicked: { - let dialog = app.showText( - { - "title": qsTr("Confirm Logout"), - text: qsTr("Are you sure you want to log out?"), - standardButtons: Dialog.Yes | Dialog.Cancel, - warning: true, - height: 230, - centerAlign: true, - yesButtonText: qsTr("Yes"), - cancelButtonText: qsTr("Cancel"), - onAccepted: function(text) - { - app.notifications_list = [] - userMenu.close() - app.currentWalletName = "" - API.app.disconnect() - app.onDisconnect() - window.logged = false - dialog.close() - dialog.destroy() - }, - onRejected: function() - { - userMenu.close() - } - }) + if (orders.count != 0) app.logout_confirm_modal.open() + else app.return_to_login() } } } @@ -199,11 +174,14 @@ DexWindow anchors.verticalCenter: parent.verticalCenter layoutDirection: Qt.RightToLeft spacing: 6 + Item { width: 15 height: 1 } + + // User / logout Rectangle { width: __row.width + 10 @@ -211,6 +189,7 @@ DexWindow anchors.verticalCenter: parent.verticalCenter radius: 3 color: _area.containsMouse ? Dex.CurrentTheme.floatingBackgroundColor : "transparent" + Row { id: __row @@ -247,6 +226,7 @@ DexWindow anchors.verticalCenter: parent.verticalCenter } } + DexMouseArea { id: _area @@ -264,11 +244,14 @@ DexWindow } } } + Item { width: 10 height: 1 } + + // Wallet Balance Row { anchors.verticalCenter: parent.verticalCenter @@ -283,6 +266,7 @@ DexWindow visible: _label.visible anchors.verticalCenter: parent.verticalCenter } + DexLabel { text_value: General.formatFiat("", API.app.portfolio_pg.balance_fiat_all, API.app.settings_pg.current_currency) @@ -315,6 +299,7 @@ DexWindow height: 1 } + // Notifications DexIconButton { color: containsMouse ? Dex.CurrentTheme.gradientButtonPressedStartColor : Dex.CurrentTheme.foregroundColor @@ -357,6 +342,7 @@ DexWindow fileName: atomic_cfg_file } + // Theme toggle DexIconButton { id: themeSwitchBut diff --git a/atomic_defi_design/assets/.gitignore b/atomic_defi_design/assets/.gitignore new file mode 100644 index 0000000000..90d1f28b17 --- /dev/null +++ b/atomic_defi_design/assets/.gitignore @@ -0,0 +1 @@ +qml.qrc \ No newline at end of file diff --git a/atomic_defi_design/assets/images/.gitignore b/atomic_defi_design/assets/images/.gitignore index b26d4d3b95..3dd82ff7a3 100644 --- a/atomic_defi_design/assets/images/.gitignore +++ b/atomic_defi_design/assets/images/.gitignore @@ -2,4 +2,5 @@ dex-logo-big.png dex-logo-big.svg dex-logo.svg dex-logo.png -dex-tray-icon.png \ No newline at end of file +dex-tray-icon.png +coins/ diff --git a/atomic_defi_design/assets/images/coins/$pac.png b/atomic_defi_design/assets/images/coins/$pac.png deleted file mode 100644 index 89e6e84543..0000000000 Binary files a/atomic_defi_design/assets/images/coins/$pac.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/0xbtc.png b/atomic_defi_design/assets/images/coins/0xbtc.png deleted file mode 100644 index 0da0826d25..0000000000 Binary files a/atomic_defi_design/assets/images/coins/0xbtc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/1inch.png b/atomic_defi_design/assets/images/coins/1inch.png deleted file mode 100644 index 4807411a3e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/1inch.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/2give.png b/atomic_defi_design/assets/images/coins/2give.png deleted file mode 100644 index d2fd035f2b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/2give.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/aave.png b/atomic_defi_design/assets/images/coins/aave.png deleted file mode 100644 index 8976df01d9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/aave.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/abt.png b/atomic_defi_design/assets/images/coins/abt.png deleted file mode 100644 index ae3420900c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/abt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/aby.png b/atomic_defi_design/assets/images/coins/aby.png deleted file mode 100644 index bfe2a54a74..0000000000 Binary files a/atomic_defi_design/assets/images/coins/aby.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/act.png b/atomic_defi_design/assets/images/coins/act.png deleted file mode 100644 index fdf60fa1a6..0000000000 Binary files a/atomic_defi_design/assets/images/coins/act.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/actn.png b/atomic_defi_design/assets/images/coins/actn.png deleted file mode 100644 index 740e6b6d85..0000000000 Binary files a/atomic_defi_design/assets/images/coins/actn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ada.png b/atomic_defi_design/assets/images/coins/ada.png deleted file mode 100644 index 875d0f686c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ada.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/add.png b/atomic_defi_design/assets/images/coins/add.png deleted file mode 100644 index 2c3b9ffdb5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/add.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/adx.png b/atomic_defi_design/assets/images/coins/adx.png deleted file mode 100644 index 5785df5076..0000000000 Binary files a/atomic_defi_design/assets/images/coins/adx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ae.png b/atomic_defi_design/assets/images/coins/ae.png deleted file mode 100644 index 0836d135e5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ae.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/aeon.png b/atomic_defi_design/assets/images/coins/aeon.png deleted file mode 100644 index b9bb37d5c8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/aeon.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/aeur.png b/atomic_defi_design/assets/images/coins/aeur.png deleted file mode 100644 index f86b004c98..0000000000 Binary files a/atomic_defi_design/assets/images/coins/aeur.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/agix.png b/atomic_defi_design/assets/images/coins/agix.png deleted file mode 100644 index 2a92e7c4c3..0000000000 Binary files a/atomic_defi_design/assets/images/coins/agix.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/agrs.png b/atomic_defi_design/assets/images/coins/agrs.png deleted file mode 100644 index 5ae0640b32..0000000000 Binary files a/atomic_defi_design/assets/images/coins/agrs.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/aion.png b/atomic_defi_design/assets/images/coins/aion.png deleted file mode 100644 index b67ab9a22c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/aion.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/algo.png b/atomic_defi_design/assets/images/coins/algo.png deleted file mode 100644 index f1400485d3..0000000000 Binary files a/atomic_defi_design/assets/images/coins/algo.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/amb.png b/atomic_defi_design/assets/images/coins/amb.png deleted file mode 100644 index a585755e2d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/amb.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/amp.png b/atomic_defi_design/assets/images/coins/amp.png deleted file mode 100644 index 1a6b586343..0000000000 Binary files a/atomic_defi_design/assets/images/coins/amp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ampl.png b/atomic_defi_design/assets/images/coins/ampl.png deleted file mode 100644 index c76e501a0d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ampl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ankr.png b/atomic_defi_design/assets/images/coins/ankr.png deleted file mode 100644 index f3fd779e67..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ankr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ant.png b/atomic_defi_design/assets/images/coins/ant.png deleted file mode 100644 index ec0e75f05c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ant.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/apex.png b/atomic_defi_design/assets/images/coins/apex.png deleted file mode 100644 index 0066bc5f0a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/apex.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/appc.png b/atomic_defi_design/assets/images/coins/appc.png deleted file mode 100644 index 31cf8497a2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/appc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ardr.png b/atomic_defi_design/assets/images/coins/ardr.png deleted file mode 100644 index 3b40f740ec..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ardr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/arg.png b/atomic_defi_design/assets/images/coins/arg.png deleted file mode 100644 index e34528e593..0000000000 Binary files a/atomic_defi_design/assets/images/coins/arg.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ark.png b/atomic_defi_design/assets/images/coins/ark.png deleted file mode 100644 index a166991779..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ark.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/arn.png b/atomic_defi_design/assets/images/coins/arn.png deleted file mode 100644 index 2d9e6c2090..0000000000 Binary files a/atomic_defi_design/assets/images/coins/arn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/arnx.png b/atomic_defi_design/assets/images/coins/arnx.png deleted file mode 100644 index c234fa6f6d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/arnx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/arpa.png b/atomic_defi_design/assets/images/coins/arpa.png deleted file mode 100644 index 911504e2aa..0000000000 Binary files a/atomic_defi_design/assets/images/coins/arpa.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/arrr.png b/atomic_defi_design/assets/images/coins/arrr.png deleted file mode 100644 index 7f18e9f74c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/arrr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ary.png b/atomic_defi_design/assets/images/coins/ary.png deleted file mode 100644 index 456a94db30..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ary.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ast.png b/atomic_defi_design/assets/images/coins/ast.png deleted file mode 100644 index bd422e51d8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ast.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/atm.png b/atomic_defi_design/assets/images/coins/atm.png deleted file mode 100644 index 038c5e7f2a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/atm.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/atom.png b/atomic_defi_design/assets/images/coins/atom.png deleted file mode 100644 index 7ecb202caf..0000000000 Binary files a/atomic_defi_design/assets/images/coins/atom.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/audr.png b/atomic_defi_design/assets/images/coins/audr.png deleted file mode 100644 index 69b9ecb123..0000000000 Binary files a/atomic_defi_design/assets/images/coins/audr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/aur.png b/atomic_defi_design/assets/images/coins/aur.png deleted file mode 100644 index f41638720c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/aur.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/auto.png b/atomic_defi_design/assets/images/coins/auto.png deleted file mode 100644 index 918985a2bd..0000000000 Binary files a/atomic_defi_design/assets/images/coins/auto.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ava.png b/atomic_defi_design/assets/images/coins/ava.png deleted file mode 100644 index 79bc6460f2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ava.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/avax.png b/atomic_defi_design/assets/images/coins/avax.png deleted file mode 100644 index b7239eee89..0000000000 Binary files a/atomic_defi_design/assets/images/coins/avax.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/avaxt.png b/atomic_defi_design/assets/images/coins/avaxt.png deleted file mode 100644 index b7239eee89..0000000000 Binary files a/atomic_defi_design/assets/images/coins/avaxt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/awc.png b/atomic_defi_design/assets/images/coins/awc.png deleted file mode 100644 index 10da211c76..0000000000 Binary files a/atomic_defi_design/assets/images/coins/awc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/axe.png b/atomic_defi_design/assets/images/coins/axe.png deleted file mode 100644 index f62c2a3c1d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/axe.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/axs.png b/atomic_defi_design/assets/images/coins/axs.png deleted file mode 100644 index c07db42c22..0000000000 Binary files a/atomic_defi_design/assets/images/coins/axs.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/aywa.png b/atomic_defi_design/assets/images/coins/aywa.png deleted file mode 100644 index 694127bf79..0000000000 Binary files a/atomic_defi_design/assets/images/coins/aywa.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bab.png b/atomic_defi_design/assets/images/coins/bab.png deleted file mode 100644 index ccb28183cb..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bab.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/babydoge.png b/atomic_defi_design/assets/images/coins/babydoge.png deleted file mode 100644 index 74338c78e9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/babydoge.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bal.png b/atomic_defi_design/assets/images/coins/bal.png deleted file mode 100644 index 59a2564cb7..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bal.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/banano.png b/atomic_defi_design/assets/images/coins/banano.png deleted file mode 100644 index 9485eaddaa..0000000000 Binary files a/atomic_defi_design/assets/images/coins/banano.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/band.png b/atomic_defi_design/assets/images/coins/band.png deleted file mode 100644 index 12a589c9d4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/band.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bat.png b/atomic_defi_design/assets/images/coins/bat.png deleted file mode 100644 index 654b092033..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bat.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bay.png b/atomic_defi_design/assets/images/coins/bay.png deleted file mode 100644 index fac7c53db2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bay.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bcbc.png b/atomic_defi_design/assets/images/coins/bcbc.png deleted file mode 100644 index 0a4fbaedde..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bcbc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bcc.png b/atomic_defi_design/assets/images/coins/bcc.png deleted file mode 100644 index 7f4f42dc35..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bcc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bcd.png b/atomic_defi_design/assets/images/coins/bcd.png deleted file mode 100644 index 68ba61b601..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bcd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bch.png b/atomic_defi_design/assets/images/coins/bch.png deleted file mode 100644 index c0e65ffd61..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bch.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bcio.png b/atomic_defi_design/assets/images/coins/bcio.png deleted file mode 100644 index aeb4f784f7..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bcio.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bcn.png b/atomic_defi_design/assets/images/coins/bcn.png deleted file mode 100644 index f2a93aab77..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bcn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bco.png b/atomic_defi_design/assets/images/coins/bco.png deleted file mode 100644 index b041065559..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bco.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bcpt.png b/atomic_defi_design/assets/images/coins/bcpt.png deleted file mode 100644 index ef7d4a97d8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bcpt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bdl.png b/atomic_defi_design/assets/images/coins/bdl.png deleted file mode 100644 index 72f857a36a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bdl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/beam.png b/atomic_defi_design/assets/images/coins/beam.png deleted file mode 100644 index d43b416e43..0000000000 Binary files a/atomic_defi_design/assets/images/coins/beam.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bela.png b/atomic_defi_design/assets/images/coins/bela.png deleted file mode 100644 index 7c437e9a6f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bela.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/best.png b/atomic_defi_design/assets/images/coins/best.png deleted file mode 100644 index ef85a0faa7..0000000000 Binary files a/atomic_defi_design/assets/images/coins/best.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bet.png b/atomic_defi_design/assets/images/coins/bet.png deleted file mode 100644 index 31e8668e6f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bet.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bidr.png b/atomic_defi_design/assets/images/coins/bidr.png deleted file mode 100644 index 54b82608d8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bidr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bix.png b/atomic_defi_design/assets/images/coins/bix.png deleted file mode 100644 index 7f1b942f35..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bix.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/blcn.png b/atomic_defi_design/assets/images/coins/blcn.png deleted file mode 100644 index 38e5ef14b0..0000000000 Binary files a/atomic_defi_design/assets/images/coins/blcn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/blk.png b/atomic_defi_design/assets/images/coins/blk.png deleted file mode 100644 index 49294ebfa3..0000000000 Binary files a/atomic_defi_design/assets/images/coins/blk.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/block.png b/atomic_defi_design/assets/images/coins/block.png deleted file mode 100644 index cb17399831..0000000000 Binary files a/atomic_defi_design/assets/images/coins/block.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/blz.png b/atomic_defi_design/assets/images/coins/blz.png deleted file mode 100644 index 0a7ee0a911..0000000000 Binary files a/atomic_defi_design/assets/images/coins/blz.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bnb.png b/atomic_defi_design/assets/images/coins/bnb.png deleted file mode 100644 index bc0dd1f115..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bnb.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bnbt.png b/atomic_defi_design/assets/images/coins/bnbt.png deleted file mode 100644 index 19cbc2b10c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bnbt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bnt.png b/atomic_defi_design/assets/images/coins/bnt.png deleted file mode 100644 index d53a04c692..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bnt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bnty.png b/atomic_defi_design/assets/images/coins/bnty.png deleted file mode 100644 index e3cb309d24..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bnty.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bone.png b/atomic_defi_design/assets/images/coins/bone.png deleted file mode 100644 index d25472be2c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bone.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/booty.png b/atomic_defi_design/assets/images/coins/booty.png deleted file mode 100644 index bc32d91de9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/booty.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bos.png b/atomic_defi_design/assets/images/coins/bos.png deleted file mode 100644 index 095d1dbcd8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bos.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bots.png b/atomic_defi_design/assets/images/coins/bots.png deleted file mode 100644 index 944685aae2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bots.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bpt.png b/atomic_defi_design/assets/images/coins/bpt.png deleted file mode 100644 index a48ec84793..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bpt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bq.png b/atomic_defi_design/assets/images/coins/bq.png deleted file mode 100644 index 3abe9ff776..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bq.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/brd.png b/atomic_defi_design/assets/images/coins/brd.png deleted file mode 100644 index e33376f18b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/brd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/brz.png b/atomic_defi_design/assets/images/coins/brz.png deleted file mode 100644 index 6bcf1a9f77..0000000000 Binary files a/atomic_defi_design/assets/images/coins/brz.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bsd.png b/atomic_defi_design/assets/images/coins/bsd.png deleted file mode 100644 index 766bb9e16e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bsd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bsty.png b/atomic_defi_design/assets/images/coins/bsty.png deleted file mode 100644 index 3e4e227f28..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bsty.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bsv.png b/atomic_defi_design/assets/images/coins/bsv.png deleted file mode 100644 index 5dc9f6bd10..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bsv.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/btc.png b/atomic_defi_design/assets/images/coins/btc.png deleted file mode 100644 index 784b8f359a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/btc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/btcd.png b/atomic_defi_design/assets/images/coins/btcd.png deleted file mode 100644 index c1eaff6109..0000000000 Binary files a/atomic_defi_design/assets/images/coins/btcd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/btcp.png b/atomic_defi_design/assets/images/coins/btcp.png deleted file mode 100644 index a1a799cfd4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/btcp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/btcz.png b/atomic_defi_design/assets/images/coins/btcz.png deleted file mode 100644 index 230d756f65..0000000000 Binary files a/atomic_defi_design/assets/images/coins/btcz.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/btdx.png b/atomic_defi_design/assets/images/coins/btdx.png deleted file mode 100644 index b0aafa7379..0000000000 Binary files a/atomic_defi_design/assets/images/coins/btdx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bte.png b/atomic_defi_design/assets/images/coins/bte.png deleted file mode 100644 index 97087c4098..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bte.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/btg.png b/atomic_defi_design/assets/images/coins/btg.png deleted file mode 100644 index 0d4c627f85..0000000000 Binary files a/atomic_defi_design/assets/images/coins/btg.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/btm.png b/atomic_defi_design/assets/images/coins/btm.png deleted file mode 100644 index 62892c7536..0000000000 Binary files a/atomic_defi_design/assets/images/coins/btm.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bts.png b/atomic_defi_design/assets/images/coins/bts.png deleted file mode 100644 index 6b1397cf4a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bts.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/btt.png b/atomic_defi_design/assets/images/coins/btt.png deleted file mode 100644 index d734b54991..0000000000 Binary files a/atomic_defi_design/assets/images/coins/btt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bttc.png b/atomic_defi_design/assets/images/coins/bttc.png deleted file mode 100644 index d734b54991..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bttc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/btu.png b/atomic_defi_design/assets/images/coins/btu.png deleted file mode 100644 index 5c748b8e63..0000000000 Binary files a/atomic_defi_design/assets/images/coins/btu.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/btx.png b/atomic_defi_design/assets/images/coins/btx.png deleted file mode 100644 index 639cb07b3e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/btx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/burst.png b/atomic_defi_design/assets/images/coins/burst.png deleted file mode 100644 index 05aaad235c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/burst.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/busd.png b/atomic_defi_design/assets/images/coins/busd.png deleted file mode 100644 index 76d02e370b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/busd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/bze.png b/atomic_defi_design/assets/images/coins/bze.png deleted file mode 100644 index 0f6254f82a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/bze.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cadc.png b/atomic_defi_design/assets/images/coins/cadc.png deleted file mode 100644 index ecd7fe0129..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cadc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cake.png b/atomic_defi_design/assets/images/coins/cake.png deleted file mode 100644 index ab7e5927bd..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cake.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/call.png b/atomic_defi_design/assets/images/coins/call.png deleted file mode 100644 index e7cfc2d226..0000000000 Binary files a/atomic_defi_design/assets/images/coins/call.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/case.png b/atomic_defi_design/assets/images/coins/case.png deleted file mode 100644 index b54172b7f3..0000000000 Binary files a/atomic_defi_design/assets/images/coins/case.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cc.png b/atomic_defi_design/assets/images/coins/cc.png deleted file mode 100644 index 04e84b37c2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ccl.png b/atomic_defi_design/assets/images/coins/ccl.png deleted file mode 100644 index a717809115..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ccl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cdn.png b/atomic_defi_design/assets/images/coins/cdn.png deleted file mode 100644 index cd00b8dd40..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cdn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cdt.png b/atomic_defi_design/assets/images/coins/cdt.png deleted file mode 100644 index f44b306509..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cdt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cel.png b/atomic_defi_design/assets/images/coins/cel.png deleted file mode 100644 index 4f9c14d978..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cel.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/celr.png b/atomic_defi_design/assets/images/coins/celr.png deleted file mode 100644 index 111cf70adf..0000000000 Binary files a/atomic_defi_design/assets/images/coins/celr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cennz.png b/atomic_defi_design/assets/images/coins/cennz.png deleted file mode 100644 index f79d10bd89..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cennz.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cenz.png b/atomic_defi_design/assets/images/coins/cenz.png deleted file mode 100644 index f79d10bd89..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cenz.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cfi.png b/atomic_defi_design/assets/images/coins/cfi.png deleted file mode 100644 index 3040d82598..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cfi.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/chain.png b/atomic_defi_design/assets/images/coins/chain.png deleted file mode 100644 index f43a08ba9e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/chain.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/chat.png b/atomic_defi_design/assets/images/coins/chat.png deleted file mode 100644 index 378d1cddd5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/chat.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/chips.png b/atomic_defi_design/assets/images/coins/chips.png deleted file mode 100644 index 74009f413b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/chips.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/chsb.png b/atomic_defi_design/assets/images/coins/chsb.png deleted file mode 100644 index 0a345530d7..0000000000 Binary files a/atomic_defi_design/assets/images/coins/chsb.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/chz.png b/atomic_defi_design/assets/images/coins/chz.png deleted file mode 100644 index ab2b98edda..0000000000 Binary files a/atomic_defi_design/assets/images/coins/chz.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ciphs.png b/atomic_defi_design/assets/images/coins/ciphs.png deleted file mode 100644 index 5b3b3f15d5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ciphs.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cix.png b/atomic_defi_design/assets/images/coins/cix.png deleted file mode 100644 index ee5c028174..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cix.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/clam.png b/atomic_defi_design/assets/images/coins/clam.png deleted file mode 100644 index c4ff987e35..0000000000 Binary files a/atomic_defi_design/assets/images/coins/clam.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/clc.png b/atomic_defi_design/assets/images/coins/clc.png deleted file mode 100644 index 2821a9a9f7..0000000000 Binary files a/atomic_defi_design/assets/images/coins/clc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cloak.png b/atomic_defi_design/assets/images/coins/cloak.png deleted file mode 100644 index aa31d016ba..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cloak.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cmm.png b/atomic_defi_design/assets/images/coins/cmm.png deleted file mode 100644 index 65c6169ca7..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cmm.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cmt.png b/atomic_defi_design/assets/images/coins/cmt.png deleted file mode 100644 index 48f573912d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cmt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cnd.png b/atomic_defi_design/assets/images/coins/cnd.png deleted file mode 100644 index 07592cd277..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cnd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cnx.png b/atomic_defi_design/assets/images/coins/cnx.png deleted file mode 100644 index 017f7f881b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cnx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cny.png b/atomic_defi_design/assets/images/coins/cny.png deleted file mode 100644 index ce1002b8b3..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cny.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cob.png b/atomic_defi_design/assets/images/coins/cob.png deleted file mode 100644 index 3f2bc762a9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cob.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/colx.png b/atomic_defi_design/assets/images/coins/colx.png deleted file mode 100644 index a71e50f2b1..0000000000 Binary files a/atomic_defi_design/assets/images/coins/colx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/comp.png b/atomic_defi_design/assets/images/coins/comp.png deleted file mode 100644 index 27e2558107..0000000000 Binary files a/atomic_defi_design/assets/images/coins/comp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cred.png b/atomic_defi_design/assets/images/coins/cred.png deleted file mode 100644 index fef004a647..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cred.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cro.png b/atomic_defi_design/assets/images/coins/cro.png deleted file mode 100644 index f65a8814f2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cro.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/crpt.png b/atomic_defi_design/assets/images/coins/crpt.png deleted file mode 100644 index 272e97db61..0000000000 Binary files a/atomic_defi_design/assets/images/coins/crpt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/crv.png b/atomic_defi_design/assets/images/coins/crv.png deleted file mode 100644 index e723c7d9b6..0000000000 Binary files a/atomic_defi_design/assets/images/coins/crv.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/crw.png b/atomic_defi_design/assets/images/coins/crw.png deleted file mode 100644 index fca0b48f67..0000000000 Binary files a/atomic_defi_design/assets/images/coins/crw.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/crypto.png b/atomic_defi_design/assets/images/coins/crypto.png deleted file mode 100644 index 063ce6db62..0000000000 Binary files a/atomic_defi_design/assets/images/coins/crypto.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cs.png b/atomic_defi_design/assets/images/coins/cs.png deleted file mode 100644 index ca3b0b353f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cs.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ctr.png b/atomic_defi_design/assets/images/coins/ctr.png deleted file mode 100644 index d985a2c268..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ctr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ctxc.png b/atomic_defi_design/assets/images/coins/ctxc.png deleted file mode 100644 index 7ece6b9f38..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ctxc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cummies.png b/atomic_defi_design/assets/images/coins/cummies.png deleted file mode 100644 index 1e6a9e3d3a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cummies.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cvc.png b/atomic_defi_design/assets/images/coins/cvc.png deleted file mode 100644 index ed3376c0c2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cvc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/cvt.png b/atomic_defi_design/assets/images/coins/cvt.png deleted file mode 100644 index d5daa67276..0000000000 Binary files a/atomic_defi_design/assets/images/coins/cvt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/d.png b/atomic_defi_design/assets/images/coins/d.png deleted file mode 100644 index 7fa63b4f84..0000000000 Binary files a/atomic_defi_design/assets/images/coins/d.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dai.png b/atomic_defi_design/assets/images/coins/dai.png deleted file mode 100644 index 715a7411b2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dai.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dash.png b/atomic_defi_design/assets/images/coins/dash.png deleted file mode 100644 index f67fe04a1a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dash.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dat.png b/atomic_defi_design/assets/images/coins/dat.png deleted file mode 100644 index 3be121b4a1..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dat.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/data.png b/atomic_defi_design/assets/images/coins/data.png deleted file mode 100644 index 455929c4ef..0000000000 Binary files a/atomic_defi_design/assets/images/coins/data.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dbc.png b/atomic_defi_design/assets/images/coins/dbc.png deleted file mode 100644 index 0ed2596242..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dbc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dcn.png b/atomic_defi_design/assets/images/coins/dcn.png deleted file mode 100644 index 3d291a930c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dcn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dcr.png b/atomic_defi_design/assets/images/coins/dcr.png deleted file mode 100644 index 398c6c3b8b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dcr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/deez.png b/atomic_defi_design/assets/images/coins/deez.png deleted file mode 100644 index 63f8c9b80f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/deez.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dent.png b/atomic_defi_design/assets/images/coins/dent.png deleted file mode 100644 index 575c580646..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dent.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dew.png b/atomic_defi_design/assets/images/coins/dew.png deleted file mode 100644 index edca0eee11..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dew.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dex.png b/atomic_defi_design/assets/images/coins/dex.png deleted file mode 100644 index de71f65460..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dex.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dgb.png b/atomic_defi_design/assets/images/coins/dgb.png deleted file mode 100644 index d94fbc1fb4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dgb.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dgc.png b/atomic_defi_design/assets/images/coins/dgc.png deleted file mode 100644 index 2ae3b2b180..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dgc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dgd.png b/atomic_defi_design/assets/images/coins/dgd.png deleted file mode 100644 index 74be4db8ab..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dgd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dia.png b/atomic_defi_design/assets/images/coins/dia.png deleted file mode 100644 index cf40550575..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dia.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dimi.png b/atomic_defi_design/assets/images/coins/dimi.png deleted file mode 100644 index 595639cb63..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dimi.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dlt.png b/atomic_defi_design/assets/images/coins/dlt.png deleted file mode 100644 index 8314133300..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dlt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dnt.png b/atomic_defi_design/assets/images/coins/dnt.png deleted file mode 100644 index 5cc3c2b665..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dnt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dock.png b/atomic_defi_design/assets/images/coins/dock.png deleted file mode 100644 index 7e27c3de0c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dock.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dodo.png b/atomic_defi_design/assets/images/coins/dodo.png deleted file mode 100644 index 3e5c749672..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dodo.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/doge.png b/atomic_defi_design/assets/images/coins/doge.png deleted file mode 100644 index aff116bf44..0000000000 Binary files a/atomic_defi_design/assets/images/coins/doge.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dogedash.png b/atomic_defi_design/assets/images/coins/dogedash.png deleted file mode 100644 index a25a55ab34..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dogedash.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/doggy.png b/atomic_defi_design/assets/images/coins/doggy.png deleted file mode 100644 index e8745e19d5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/doggy.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/doi.png b/atomic_defi_design/assets/images/coins/doi.png deleted file mode 100644 index 141dd63208..0000000000 Binary files a/atomic_defi_design/assets/images/coins/doi.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dot.png b/atomic_defi_design/assets/images/coins/dot.png deleted file mode 100644 index 0f998dc7d5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dot.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dp.png b/atomic_defi_design/assets/images/coins/dp.png deleted file mode 100644 index 8c3146131e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/drgn.png b/atomic_defi_design/assets/images/coins/drgn.png deleted file mode 100644 index ed642328f1..0000000000 Binary files a/atomic_defi_design/assets/images/coins/drgn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/drop.png b/atomic_defi_design/assets/images/coins/drop.png deleted file mode 100644 index 206d4394d2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/drop.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dta.png b/atomic_defi_design/assets/images/coins/dta.png deleted file mode 100644 index 149f095849..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dta.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dth.png b/atomic_defi_design/assets/images/coins/dth.png deleted file mode 100644 index b957588ee4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dth.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dtr.png b/atomic_defi_design/assets/images/coins/dtr.png deleted file mode 100644 index bdea3ba2a3..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dtr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dust.png b/atomic_defi_design/assets/images/coins/dust.png deleted file mode 100644 index 96f0eac59d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dust.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/dx.png b/atomic_defi_design/assets/images/coins/dx.png deleted file mode 100644 index 13cba15bf5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/dx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ebst.png b/atomic_defi_design/assets/images/coins/ebst.png deleted file mode 100644 index aa29c9b738..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ebst.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/eca.png b/atomic_defi_design/assets/images/coins/eca.png deleted file mode 100644 index 1e80a6de89..0000000000 Binary files a/atomic_defi_design/assets/images/coins/eca.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/edg.png b/atomic_defi_design/assets/images/coins/edg.png deleted file mode 100644 index bc86de5820..0000000000 Binary files a/atomic_defi_design/assets/images/coins/edg.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/edo.png b/atomic_defi_design/assets/images/coins/edo.png deleted file mode 100644 index 88290dda68..0000000000 Binary files a/atomic_defi_design/assets/images/coins/edo.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/edoge.png b/atomic_defi_design/assets/images/coins/edoge.png deleted file mode 100644 index c0ce51c878..0000000000 Binary files a/atomic_defi_design/assets/images/coins/edoge.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/efl.png b/atomic_defi_design/assets/images/coins/efl.png deleted file mode 100644 index 97ec975111..0000000000 Binary files a/atomic_defi_design/assets/images/coins/efl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/egld.png b/atomic_defi_design/assets/images/coins/egld.png deleted file mode 100644 index b9b53a4920..0000000000 Binary files a/atomic_defi_design/assets/images/coins/egld.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ela.png b/atomic_defi_design/assets/images/coins/ela.png deleted file mode 100644 index 0159d84e12..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ela.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/elec.png b/atomic_defi_design/assets/images/coins/elec.png deleted file mode 100644 index b299d8149a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/elec.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/elf.png b/atomic_defi_design/assets/images/coins/elf.png deleted file mode 100644 index 087f6f5686..0000000000 Binary files a/atomic_defi_design/assets/images/coins/elf.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/elix.png b/atomic_defi_design/assets/images/coins/elix.png deleted file mode 100644 index 798f8e8d31..0000000000 Binary files a/atomic_defi_design/assets/images/coins/elix.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ella.png b/atomic_defi_design/assets/images/coins/ella.png deleted file mode 100644 index 0afa2e4b3a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ella.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/emc.png b/atomic_defi_design/assets/images/coins/emc.png deleted file mode 100644 index ae753f7cc0..0000000000 Binary files a/atomic_defi_design/assets/images/coins/emc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/emc2.png b/atomic_defi_design/assets/images/coins/emc2.png deleted file mode 100644 index 5017a8e90e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/emc2.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/eng.png b/atomic_defi_design/assets/images/coins/eng.png deleted file mode 100644 index 590d518fd6..0000000000 Binary files a/atomic_defi_design/assets/images/coins/eng.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/enj.png b/atomic_defi_design/assets/images/coins/enj.png deleted file mode 100644 index c1390a1d85..0000000000 Binary files a/atomic_defi_design/assets/images/coins/enj.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/entrp.png b/atomic_defi_design/assets/images/coins/entrp.png deleted file mode 100644 index ad39e0d066..0000000000 Binary files a/atomic_defi_design/assets/images/coins/entrp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/eon.png b/atomic_defi_design/assets/images/coins/eon.png deleted file mode 100644 index e05fd3c55e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/eon.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/eop.png b/atomic_defi_design/assets/images/coins/eop.png deleted file mode 100644 index 557f3c5685..0000000000 Binary files a/atomic_defi_design/assets/images/coins/eop.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/eos.png b/atomic_defi_design/assets/images/coins/eos.png deleted file mode 100644 index 7b4d4e720e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/eos.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/eqli.png b/atomic_defi_design/assets/images/coins/eqli.png deleted file mode 100644 index 026b5f98e8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/eqli.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/equa.png b/atomic_defi_design/assets/images/coins/equa.png deleted file mode 100644 index 3158e1f1e5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/equa.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/erc-20.png b/atomic_defi_design/assets/images/coins/erc-20.png deleted file mode 100644 index db654a890c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/erc-20.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/etc.png b/atomic_defi_design/assets/images/coins/etc.png deleted file mode 100644 index 5f0339b263..0000000000 Binary files a/atomic_defi_design/assets/images/coins/etc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/eth.png b/atomic_defi_design/assets/images/coins/eth.png deleted file mode 100644 index c0f1de796f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/eth.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ethk.png b/atomic_defi_design/assets/images/coins/ethk.png deleted file mode 100644 index c0f1de796f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ethk.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ethos.png b/atomic_defi_design/assets/images/coins/ethos.png deleted file mode 100644 index 42667c6064..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ethos.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ethr.png b/atomic_defi_design/assets/images/coins/ethr.png deleted file mode 100644 index c0f1de796f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ethr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/etn.png b/atomic_defi_design/assets/images/coins/etn.png deleted file mode 100644 index 38788c65d6..0000000000 Binary files a/atomic_defi_design/assets/images/coins/etn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/etp.png b/atomic_defi_design/assets/images/coins/etp.png deleted file mode 100644 index 936f586356..0000000000 Binary files a/atomic_defi_design/assets/images/coins/etp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/eur.png b/atomic_defi_design/assets/images/coins/eur.png deleted file mode 100644 index 818b85c77d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/eur.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/eurs.png b/atomic_defi_design/assets/images/coins/eurs.png deleted file mode 100644 index 4133471471..0000000000 Binary files a/atomic_defi_design/assets/images/coins/eurs.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/evx.png b/atomic_defi_design/assets/images/coins/evx.png deleted file mode 100644 index d6f2fd73c4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/evx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/exmo.png b/atomic_defi_design/assets/images/coins/exmo.png deleted file mode 100644 index 0073470fff..0000000000 Binary files a/atomic_defi_design/assets/images/coins/exmo.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/exp.png b/atomic_defi_design/assets/images/coins/exp.png deleted file mode 100644 index 198f690c2e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/exp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/fair.png b/atomic_defi_design/assets/images/coins/fair.png deleted file mode 100644 index 2071df144c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/fair.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/fct.png b/atomic_defi_design/assets/images/coins/fct.png deleted file mode 100644 index 527ff428d5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/fct.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/fet.png b/atomic_defi_design/assets/images/coins/fet.png deleted file mode 100644 index 0dab67ece4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/fet.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/fil.png b/atomic_defi_design/assets/images/coins/fil.png deleted file mode 100644 index 0cf5b9155b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/fil.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/firo.png b/atomic_defi_design/assets/images/coins/firo.png deleted file mode 100644 index b9eb8f9d2b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/firo.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/fjc.png b/atomic_defi_design/assets/images/coins/fjc.png deleted file mode 100644 index b24dd6716e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/fjc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/fjcb.png b/atomic_defi_design/assets/images/coins/fjcb.png deleted file mode 100644 index 7c7ce06036..0000000000 Binary files a/atomic_defi_design/assets/images/coins/fjcb.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/fldc.png b/atomic_defi_design/assets/images/coins/fldc.png deleted file mode 100644 index a758a99904..0000000000 Binary files a/atomic_defi_design/assets/images/coins/fldc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/flo.png b/atomic_defi_design/assets/images/coins/flo.png deleted file mode 100644 index 349495c6bf..0000000000 Binary files a/atomic_defi_design/assets/images/coins/flo.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/floki.png b/atomic_defi_design/assets/images/coins/floki.png deleted file mode 100644 index 896d275d64..0000000000 Binary files a/atomic_defi_design/assets/images/coins/floki.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/flow.png b/atomic_defi_design/assets/images/coins/flow.png deleted file mode 100644 index 98acc76f69..0000000000 Binary files a/atomic_defi_design/assets/images/coins/flow.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/flux.png b/atomic_defi_design/assets/images/coins/flux.png deleted file mode 100644 index 80a7711a43..0000000000 Binary files a/atomic_defi_design/assets/images/coins/flux.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/fsn.png b/atomic_defi_design/assets/images/coins/fsn.png deleted file mode 100644 index de7202890e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/fsn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ftc.png b/atomic_defi_design/assets/images/coins/ftc.png deleted file mode 100644 index da62fcc2c1..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ftc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ftm.png b/atomic_defi_design/assets/images/coins/ftm.png deleted file mode 100644 index 27d47f2eba..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ftm.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ftmt.png b/atomic_defi_design/assets/images/coins/ftmt.png deleted file mode 100644 index 27d47f2eba..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ftmt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/fuel.png b/atomic_defi_design/assets/images/coins/fuel.png deleted file mode 100644 index f0cd35a21b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/fuel.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/fun.png b/atomic_defi_design/assets/images/coins/fun.png deleted file mode 100644 index 73609d6bf8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/fun.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gala.png b/atomic_defi_design/assets/images/coins/gala.png deleted file mode 100644 index 0c097c4dfa..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gala.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/game.png b/atomic_defi_design/assets/images/coins/game.png deleted file mode 100644 index fd3c95c6e9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/game.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gas.png b/atomic_defi_design/assets/images/coins/gas.png deleted file mode 100644 index 102c36f3e6..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gas.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gbp.png b/atomic_defi_design/assets/images/coins/gbp.png deleted file mode 100644 index cb7236540d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gbp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gbx.png b/atomic_defi_design/assets/images/coins/gbx.png deleted file mode 100644 index 0c86293886..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gbx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gbyte.png b/atomic_defi_design/assets/images/coins/gbyte.png deleted file mode 100644 index 5079d51a7f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gbyte.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/generic.png b/atomic_defi_design/assets/images/coins/generic.png deleted file mode 100644 index 5edf855df0..0000000000 Binary files a/atomic_defi_design/assets/images/coins/generic.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gin.png b/atomic_defi_design/assets/images/coins/gin.png deleted file mode 100644 index 80742cfe0b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gin.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gleec.png b/atomic_defi_design/assets/images/coins/gleec.png deleted file mode 100644 index b245f67f57..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gleec.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/glmr.png b/atomic_defi_design/assets/images/coins/glmr.png deleted file mode 100644 index d449d08ba1..0000000000 Binary files a/atomic_defi_design/assets/images/coins/glmr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/glxt.png b/atomic_defi_design/assets/images/coins/glxt.png deleted file mode 100644 index 44794a0902..0000000000 Binary files a/atomic_defi_design/assets/images/coins/glxt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gm.png b/atomic_defi_design/assets/images/coins/gm.png deleted file mode 100644 index ca6c15963d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gm.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gmr.png b/atomic_defi_design/assets/images/coins/gmr.png deleted file mode 100644 index d660e3cc0f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gmr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gms.png b/atomic_defi_design/assets/images/coins/gms.png deleted file mode 100644 index 3877c3a974..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gms.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gno.png b/atomic_defi_design/assets/images/coins/gno.png deleted file mode 100644 index ccc0709cbe..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gno.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gnt.png b/atomic_defi_design/assets/images/coins/gnt.png deleted file mode 100644 index 2596892e04..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gnt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gold.png b/atomic_defi_design/assets/images/coins/gold.png deleted file mode 100644 index 82102961f0..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gold.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/grc.png b/atomic_defi_design/assets/images/coins/grc.png deleted file mode 100644 index 93a552e904..0000000000 Binary files a/atomic_defi_design/assets/images/coins/grc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/grin.png b/atomic_defi_design/assets/images/coins/grin.png deleted file mode 100644 index 87d85d5a62..0000000000 Binary files a/atomic_defi_design/assets/images/coins/grin.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/grms.png b/atomic_defi_design/assets/images/coins/grms.png deleted file mode 100644 index 11c316c475..0000000000 Binary files a/atomic_defi_design/assets/images/coins/grms.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/grs.png b/atomic_defi_design/assets/images/coins/grs.png deleted file mode 100644 index 460d60e788..0000000000 Binary files a/atomic_defi_design/assets/images/coins/grs.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/grt.png b/atomic_defi_design/assets/images/coins/grt.png deleted file mode 100644 index d0d8cfd8f2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/grt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gsc.png b/atomic_defi_design/assets/images/coins/gsc.png deleted file mode 100644 index 0ca0260344..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gsc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gto.png b/atomic_defi_design/assets/images/coins/gto.png deleted file mode 100644 index e12ec1f2f3..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gto.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gup.png b/atomic_defi_design/assets/images/coins/gup.png deleted file mode 100644 index ce119bab69..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gup.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gusd.png b/atomic_defi_design/assets/images/coins/gusd.png deleted file mode 100644 index 626b699006..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gusd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gvt.png b/atomic_defi_design/assets/images/coins/gvt.png deleted file mode 100644 index f49384de44..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gvt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gxs.png b/atomic_defi_design/assets/images/coins/gxs.png deleted file mode 100644 index 506484a980..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gxs.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/gzr.png b/atomic_defi_design/assets/images/coins/gzr.png deleted file mode 100644 index 9410fae0ad..0000000000 Binary files a/atomic_defi_design/assets/images/coins/gzr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/hex.png b/atomic_defi_design/assets/images/coins/hex.png deleted file mode 100644 index 4800833945..0000000000 Binary files a/atomic_defi_design/assets/images/coins/hex.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/hight.png b/atomic_defi_design/assets/images/coins/hight.png deleted file mode 100644 index 2fd050d80e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/hight.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/hlc.png b/atomic_defi_design/assets/images/coins/hlc.png deleted file mode 100644 index 69ae83b3a5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/hlc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/hodl.png b/atomic_defi_design/assets/images/coins/hodl.png deleted file mode 100644 index 7289d2e029..0000000000 Binary files a/atomic_defi_design/assets/images/coins/hodl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/hot.png b/atomic_defi_design/assets/images/coins/hot.png deleted file mode 100644 index 91f73719be..0000000000 Binary files a/atomic_defi_design/assets/images/coins/hot.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/hpb.png b/atomic_defi_design/assets/images/coins/hpb.png deleted file mode 100644 index 2143dbf1b8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/hpb.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/hpy.png b/atomic_defi_design/assets/images/coins/hpy.png deleted file mode 100644 index 1a0252566e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/hpy.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/hsr.png b/atomic_defi_design/assets/images/coins/hsr.png deleted file mode 100644 index 42dd58fab2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/hsr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ht.png b/atomic_defi_design/assets/images/coins/ht.png deleted file mode 100644 index b1e4f5279e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ht.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/html.png b/atomic_defi_design/assets/images/coins/html.png deleted file mode 100644 index 1e32954405..0000000000 Binary files a/atomic_defi_design/assets/images/coins/html.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/huc.png b/atomic_defi_design/assets/images/coins/huc.png deleted file mode 100644 index ab28b30690..0000000000 Binary files a/atomic_defi_design/assets/images/coins/huc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/husd.png b/atomic_defi_design/assets/images/coins/husd.png deleted file mode 100644 index a7879e7f56..0000000000 Binary files a/atomic_defi_design/assets/images/coins/husd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/hyn.png b/atomic_defi_design/assets/images/coins/hyn.png deleted file mode 100644 index cdebf2aca0..0000000000 Binary files a/atomic_defi_design/assets/images/coins/hyn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ic.png b/atomic_defi_design/assets/images/coins/ic.png deleted file mode 100644 index 87cfc008e3..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ic.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/icn.png b/atomic_defi_design/assets/images/coins/icn.png deleted file mode 100644 index 01692deb6c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/icn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/icx.png b/atomic_defi_design/assets/images/coins/icx.png deleted file mode 100644 index 406945b828..0000000000 Binary files a/atomic_defi_design/assets/images/coins/icx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ignis.png b/atomic_defi_design/assets/images/coins/ignis.png deleted file mode 100644 index 99241a8300..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ignis.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/il8p.png b/atomic_defi_design/assets/images/coins/il8p.png deleted file mode 100644 index afe0e94fc9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/il8p.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ilk.png b/atomic_defi_design/assets/images/coins/ilk.png deleted file mode 100644 index 6e52bb5d40..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ilk.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/iln.png b/atomic_defi_design/assets/images/coins/iln.png deleted file mode 100644 index 9a3939a9b6..0000000000 Binary files a/atomic_defi_design/assets/images/coins/iln.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/inj.png b/atomic_defi_design/assets/images/coins/inj.png deleted file mode 100644 index c53eb7e695..0000000000 Binary files a/atomic_defi_design/assets/images/coins/inj.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ink.png b/atomic_defi_design/assets/images/coins/ink.png deleted file mode 100644 index 259f8eea4b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ink.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ins.png b/atomic_defi_design/assets/images/coins/ins.png deleted file mode 100644 index b237f8b011..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ins.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ion.png b/atomic_defi_design/assets/images/coins/ion.png deleted file mode 100644 index 99bebde91c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ion.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/iop.png b/atomic_defi_design/assets/images/coins/iop.png deleted file mode 100644 index c0e840a50f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/iop.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/iost.png b/atomic_defi_design/assets/images/coins/iost.png deleted file mode 100644 index b9c02093c9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/iost.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/iota.png b/atomic_defi_design/assets/images/coins/iota.png deleted file mode 100644 index 748f6bd3e1..0000000000 Binary files a/atomic_defi_design/assets/images/coins/iota.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/iotx.png b/atomic_defi_design/assets/images/coins/iotx.png deleted file mode 100644 index faae68e8f4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/iotx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/iq.png b/atomic_defi_design/assets/images/coins/iq.png deleted file mode 100644 index 64200cf5c7..0000000000 Binary files a/atomic_defi_design/assets/images/coins/iq.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/itc.png b/atomic_defi_design/assets/images/coins/itc.png deleted file mode 100644 index 98ef335586..0000000000 Binary files a/atomic_defi_design/assets/images/coins/itc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/jchf.png b/atomic_defi_design/assets/images/coins/jchf.png deleted file mode 100644 index f3ac683a56..0000000000 Binary files a/atomic_defi_design/assets/images/coins/jchf.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/jeur.png b/atomic_defi_design/assets/images/coins/jeur.png deleted file mode 100644 index 28d9220178..0000000000 Binary files a/atomic_defi_design/assets/images/coins/jeur.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/jgbp.png b/atomic_defi_design/assets/images/coins/jgbp.png deleted file mode 100644 index 898dce1310..0000000000 Binary files a/atomic_defi_design/assets/images/coins/jgbp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/jnt.png b/atomic_defi_design/assets/images/coins/jnt.png deleted file mode 100644 index 50559b89e3..0000000000 Binary files a/atomic_defi_design/assets/images/coins/jnt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/jpy.png b/atomic_defi_design/assets/images/coins/jpy.png deleted file mode 100644 index e5603416e0..0000000000 Binary files a/atomic_defi_design/assets/images/coins/jpy.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/jpyc.png b/atomic_defi_design/assets/images/coins/jpyc.png deleted file mode 100644 index 010a69bc6c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/jpyc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/jrt.png b/atomic_defi_design/assets/images/coins/jrt.png deleted file mode 100644 index 875bcc8118..0000000000 Binary files a/atomic_defi_design/assets/images/coins/jrt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/jstr.png b/atomic_defi_design/assets/images/coins/jstr.png deleted file mode 100644 index 3e6aa1ad9a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/jstr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/jumblr.png b/atomic_defi_design/assets/images/coins/jumblr.png deleted file mode 100644 index e39127b022..0000000000 Binary files a/atomic_defi_design/assets/images/coins/jumblr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/kcs.png b/atomic_defi_design/assets/images/coins/kcs.png deleted file mode 100644 index 74eae3db4a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/kcs.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/kin.png b/atomic_defi_design/assets/images/coins/kin.png deleted file mode 100644 index a263faa887..0000000000 Binary files a/atomic_defi_design/assets/images/coins/kin.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/klown.png b/atomic_defi_design/assets/images/coins/klown.png deleted file mode 100644 index 092fcc2580..0000000000 Binary files a/atomic_defi_design/assets/images/coins/klown.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/kmd.png b/atomic_defi_design/assets/images/coins/kmd.png deleted file mode 100644 index 30e111f31d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/kmd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/knc.png b/atomic_defi_design/assets/images/coins/knc.png deleted file mode 100644 index 018ee72e3d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/knc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/koin.png b/atomic_defi_design/assets/images/coins/koin.png deleted file mode 100644 index b7eb57168f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/koin.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/krb.png b/atomic_defi_design/assets/images/coins/krb.png deleted file mode 100644 index 38a18b9c48..0000000000 Binary files a/atomic_defi_design/assets/images/coins/krb.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ksm.png b/atomic_defi_design/assets/images/coins/ksm.png deleted file mode 100644 index 01577aa4d7..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ksm.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/labs.png b/atomic_defi_design/assets/images/coins/labs.png deleted file mode 100644 index cd04e64ca4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/labs.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/lbc.png b/atomic_defi_design/assets/images/coins/lbc.png deleted file mode 100644 index e0797af91c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/lbc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/lcc.png b/atomic_defi_design/assets/images/coins/lcc.png deleted file mode 100644 index 7891d45e26..0000000000 Binary files a/atomic_defi_design/assets/images/coins/lcc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/leash.png b/atomic_defi_design/assets/images/coins/leash.png deleted file mode 100644 index 69c8c3451d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/leash.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/lend.png b/atomic_defi_design/assets/images/coins/lend.png deleted file mode 100644 index 4105045b0d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/lend.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/leo.png b/atomic_defi_design/assets/images/coins/leo.png deleted file mode 100644 index d62f88b1b8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/leo.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/link.png b/atomic_defi_design/assets/images/coins/link.png deleted file mode 100644 index 5b5447020e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/link.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/lkk.png b/atomic_defi_design/assets/images/coins/lkk.png deleted file mode 100644 index a11a7622e4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/lkk.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/loom.png b/atomic_defi_design/assets/images/coins/loom.png deleted file mode 100644 index defb6fac46..0000000000 Binary files a/atomic_defi_design/assets/images/coins/loom.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/lpt.png b/atomic_defi_design/assets/images/coins/lpt.png deleted file mode 100644 index a8a70c7db0..0000000000 Binary files a/atomic_defi_design/assets/images/coins/lpt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/lrc.png b/atomic_defi_design/assets/images/coins/lrc.png deleted file mode 100644 index c982e9b616..0000000000 Binary files a/atomic_defi_design/assets/images/coins/lrc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/lsk.png b/atomic_defi_design/assets/images/coins/lsk.png deleted file mode 100644 index 7783201c5d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/lsk.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/lstr.png b/atomic_defi_design/assets/images/coins/lstr.png deleted file mode 100644 index 7c50bb68de..0000000000 Binary files a/atomic_defi_design/assets/images/coins/lstr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ltc.png b/atomic_defi_design/assets/images/coins/ltc.png deleted file mode 100644 index b18e701b9c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ltc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ltfn.png b/atomic_defi_design/assets/images/coins/ltfn.png deleted file mode 100644 index 182dc057b1..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ltfn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/lun.png b/atomic_defi_design/assets/images/coins/lun.png deleted file mode 100644 index 368e83efce..0000000000 Binary files a/atomic_defi_design/assets/images/coins/lun.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/luna.png b/atomic_defi_design/assets/images/coins/luna.png deleted file mode 100644 index 368a86bdc9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/luna.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/lynx.png b/atomic_defi_design/assets/images/coins/lynx.png deleted file mode 100644 index 44cfdb1bb4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/lynx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/maid.png b/atomic_defi_design/assets/images/coins/maid.png deleted file mode 100644 index d32f7aa280..0000000000 Binary files a/atomic_defi_design/assets/images/coins/maid.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mana.png b/atomic_defi_design/assets/images/coins/mana.png deleted file mode 100644 index 6179c4e299..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mana.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/matic.png b/atomic_defi_design/assets/images/coins/matic.png deleted file mode 100644 index 29d881e8bd..0000000000 Binary files a/atomic_defi_design/assets/images/coins/matic.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/matictest.png b/atomic_defi_design/assets/images/coins/matictest.png deleted file mode 100644 index 29d881e8bd..0000000000 Binary files a/atomic_defi_design/assets/images/coins/matictest.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mcap.png b/atomic_defi_design/assets/images/coins/mcap.png deleted file mode 100644 index 3129276a23..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mcap.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mcl.png b/atomic_defi_design/assets/images/coins/mcl.png deleted file mode 100644 index 99680c3c0e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mcl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mco.png b/atomic_defi_design/assets/images/coins/mco.png deleted file mode 100644 index 3a348e297b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mco.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mda.png b/atomic_defi_design/assets/images/coins/mda.png deleted file mode 100644 index 78876179cb..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mda.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mds.png b/atomic_defi_design/assets/images/coins/mds.png deleted file mode 100644 index cbc7b14d84..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mds.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/meetone.png b/atomic_defi_design/assets/images/coins/meetone.png deleted file mode 100644 index 6a1a040818..0000000000 Binary files a/atomic_defi_design/assets/images/coins/meetone.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mesh.png b/atomic_defi_design/assets/images/coins/mesh.png deleted file mode 100644 index 890199eaac..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mesh.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mft.png b/atomic_defi_design/assets/images/coins/mft.png deleted file mode 100644 index 8fd5bdbec9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mft.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mgw.png b/atomic_defi_design/assets/images/coins/mgw.png deleted file mode 100644 index dfd2951397..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mgw.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/minds.png b/atomic_defi_design/assets/images/coins/minds.png deleted file mode 100644 index 5c2f78087c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/minds.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/miota.png b/atomic_defi_design/assets/images/coins/miota.png deleted file mode 100644 index 748f6bd3e1..0000000000 Binary files a/atomic_defi_design/assets/images/coins/miota.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mir.png b/atomic_defi_design/assets/images/coins/mir.png deleted file mode 100644 index 9240909251..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mir.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mith.png b/atomic_defi_design/assets/images/coins/mith.png deleted file mode 100644 index bf8deaa4d7..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mith.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mkr.png b/atomic_defi_design/assets/images/coins/mkr.png deleted file mode 100644 index 9cf32ba433..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mkr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mln.png b/atomic_defi_design/assets/images/coins/mln.png deleted file mode 100644 index a463015794..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mln.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mm.png b/atomic_defi_design/assets/images/coins/mm.png deleted file mode 100644 index 441f461948..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mm.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mnx.png b/atomic_defi_design/assets/images/coins/mnx.png deleted file mode 100644 index 8401efb9e4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mnx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mnz.png b/atomic_defi_design/assets/images/coins/mnz.png deleted file mode 100644 index c45c6307ea..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mnz.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/moac.png b/atomic_defi_design/assets/images/coins/moac.png deleted file mode 100644 index 00d76cc9ac..0000000000 Binary files a/atomic_defi_design/assets/images/coins/moac.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mod.png b/atomic_defi_design/assets/images/coins/mod.png deleted file mode 100644 index af7fdeef8f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mod.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mona.png b/atomic_defi_design/assets/images/coins/mona.png deleted file mode 100644 index 4fa8b305c2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mona.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/morty.png b/atomic_defi_design/assets/images/coins/morty.png deleted file mode 100644 index de30d88fcc..0000000000 Binary files a/atomic_defi_design/assets/images/coins/morty.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/movr.png b/atomic_defi_design/assets/images/coins/movr.png deleted file mode 100644 index fefc768f00..0000000000 Binary files a/atomic_defi_design/assets/images/coins/movr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mshark.png b/atomic_defi_design/assets/images/coins/mshark.png deleted file mode 100644 index f321f3c63b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mshark.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/msr.png b/atomic_defi_design/assets/images/coins/msr.png deleted file mode 100644 index 98bbeacbfe..0000000000 Binary files a/atomic_defi_design/assets/images/coins/msr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mth.png b/atomic_defi_design/assets/images/coins/mth.png deleted file mode 100644 index 06b34ab5aa..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mth.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mtl.png b/atomic_defi_design/assets/images/coins/mtl.png deleted file mode 100644 index f4c69b7d5c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mtl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/music.png b/atomic_defi_design/assets/images/coins/music.png deleted file mode 100644 index 96c0a0d720..0000000000 Binary files a/atomic_defi_design/assets/images/coins/music.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/mzc.png b/atomic_defi_design/assets/images/coins/mzc.png deleted file mode 100644 index fa440d3204..0000000000 Binary files a/atomic_defi_design/assets/images/coins/mzc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nano.png b/atomic_defi_design/assets/images/coins/nano.png deleted file mode 100644 index 8755c9cd4a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nano.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nas.png b/atomic_defi_design/assets/images/coins/nas.png deleted file mode 100644 index 1215d39e02..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nas.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nav.png b/atomic_defi_design/assets/images/coins/nav.png deleted file mode 100644 index 141a29d274..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nav.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ncash.png b/atomic_defi_design/assets/images/coins/ncash.png deleted file mode 100644 index eb83cb6004..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ncash.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ndz.png b/atomic_defi_design/assets/images/coins/ndz.png deleted file mode 100644 index 09107a0e41..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ndz.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/near.png b/atomic_defi_design/assets/images/coins/near.png deleted file mode 100644 index 962d2448d0..0000000000 Binary files a/atomic_defi_design/assets/images/coins/near.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nebl.png b/atomic_defi_design/assets/images/coins/nebl.png deleted file mode 100644 index 696f916743..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nebl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/neo.png b/atomic_defi_design/assets/images/coins/neo.png deleted file mode 100644 index 102c36f3e6..0000000000 Binary files a/atomic_defi_design/assets/images/coins/neo.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/neos.png b/atomic_defi_design/assets/images/coins/neos.png deleted file mode 100644 index 13ea0acfaf..0000000000 Binary files a/atomic_defi_design/assets/images/coins/neos.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/neu.png b/atomic_defi_design/assets/images/coins/neu.png deleted file mode 100644 index 0735bb8cfe..0000000000 Binary files a/atomic_defi_design/assets/images/coins/neu.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nexo.png b/atomic_defi_design/assets/images/coins/nexo.png deleted file mode 100644 index adb8da295c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nexo.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ngc.png b/atomic_defi_design/assets/images/coins/ngc.png deleted file mode 100644 index 91bb104b55..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ngc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nio.png b/atomic_defi_design/assets/images/coins/nio.png deleted file mode 100644 index 8673da7cfc..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nio.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nlc2.png b/atomic_defi_design/assets/images/coins/nlc2.png deleted file mode 100644 index 94decd5ac2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nlc2.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nlg.png b/atomic_defi_design/assets/images/coins/nlg.png deleted file mode 100644 index 46427330eb..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nlg.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nmc.png b/atomic_defi_design/assets/images/coins/nmc.png deleted file mode 100644 index bf0a8eeb15..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nmc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nmr.png b/atomic_defi_design/assets/images/coins/nmr.png deleted file mode 100644 index 8e4d933d83..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nmr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nuls.png b/atomic_defi_design/assets/images/coins/nuls.png deleted file mode 100644 index 607e3d8982..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nuls.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nvc.png b/atomic_defi_design/assets/images/coins/nvc.png deleted file mode 100644 index 50c69ad557..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nvc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nxs.png b/atomic_defi_design/assets/images/coins/nxs.png deleted file mode 100644 index ab97c9d7e2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nxs.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nxt.png b/atomic_defi_design/assets/images/coins/nxt.png deleted file mode 100644 index b4007bb769..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nxt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nyan.png b/atomic_defi_design/assets/images/coins/nyan.png deleted file mode 100644 index 81c76572f4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nyan.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/nzds.png b/atomic_defi_design/assets/images/coins/nzds.png deleted file mode 100644 index 5d437c48e8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/nzds.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/oax.png b/atomic_defi_design/assets/images/coins/oax.png deleted file mode 100644 index 332501fa1b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/oax.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/oc.png b/atomic_defi_design/assets/images/coins/oc.png deleted file mode 100644 index 8bd25c9858..0000000000 Binary files a/atomic_defi_design/assets/images/coins/oc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ocean.png b/atomic_defi_design/assets/images/coins/ocean.png deleted file mode 100644 index 621e81633a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ocean.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ok.png b/atomic_defi_design/assets/images/coins/ok.png deleted file mode 100644 index e872ea69dc..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ok.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/okb.png b/atomic_defi_design/assets/images/coins/okb.png deleted file mode 100644 index eaaa88f47e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/okb.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/omg.png b/atomic_defi_design/assets/images/coins/omg.png deleted file mode 100644 index ce9d6b838d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/omg.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/omni.png b/atomic_defi_design/assets/images/coins/omni.png deleted file mode 100644 index 5e6892eac2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/omni.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/one.png b/atomic_defi_design/assets/images/coins/one.png deleted file mode 100644 index a5204bc4ec..0000000000 Binary files a/atomic_defi_design/assets/images/coins/one.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ong.png b/atomic_defi_design/assets/images/coins/ong.png deleted file mode 100644 index 3240fddca8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ong.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ont.png b/atomic_defi_design/assets/images/coins/ont.png deleted file mode 100644 index 593b96a936..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ont.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ost.png b/atomic_defi_design/assets/images/coins/ost.png deleted file mode 100644 index 960e3a1c87..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ost.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ox.png b/atomic_defi_design/assets/images/coins/ox.png deleted file mode 100644 index 7e6466cde4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ox.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/oxt.png b/atomic_defi_design/assets/images/coins/oxt.png deleted file mode 100644 index 2cb2016383..0000000000 Binary files a/atomic_defi_design/assets/images/coins/oxt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pangea.png b/atomic_defi_design/assets/images/coins/pangea.png deleted file mode 100644 index 45cc04a884..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pangea.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/part.png b/atomic_defi_design/assets/images/coins/part.png deleted file mode 100644 index f4ac11d6e2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/part.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pasc.png b/atomic_defi_design/assets/images/coins/pasc.png deleted file mode 100644 index 3a67d49cf4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pasc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pasl.png b/atomic_defi_design/assets/images/coins/pasl.png deleted file mode 100644 index 049a0abda9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pasl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pax.png b/atomic_defi_design/assets/images/coins/pax.png deleted file mode 100644 index c2bd51774b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pax.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/paxg.png b/atomic_defi_design/assets/images/coins/paxg.png deleted file mode 100644 index 3ddb6d7ea6..0000000000 Binary files a/atomic_defi_design/assets/images/coins/paxg.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pay.png b/atomic_defi_design/assets/images/coins/pay.png deleted file mode 100644 index cc5e150d5a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pay.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/payx.png b/atomic_defi_design/assets/images/coins/payx.png deleted file mode 100644 index 04a0cda654..0000000000 Binary files a/atomic_defi_design/assets/images/coins/payx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pbc.png b/atomic_defi_design/assets/images/coins/pbc.png deleted file mode 100644 index 6bc763f1de..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pbc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pgx.png b/atomic_defi_design/assets/images/coins/pgx.png deleted file mode 100644 index ff7baf214e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pgx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pic.png b/atomic_defi_design/assets/images/coins/pic.png deleted file mode 100644 index 13f34adb17..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pic.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pink.png b/atomic_defi_design/assets/images/coins/pink.png deleted file mode 100644 index ab6542cdbe..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pink.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pirl.png b/atomic_defi_design/assets/images/coins/pirl.png deleted file mode 100644 index 1dd0036176..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pirl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pivx.png b/atomic_defi_design/assets/images/coins/pivx.png deleted file mode 100644 index fab1eae460..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pivx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/plr.png b/atomic_defi_design/assets/images/coins/plr.png deleted file mode 100644 index 29873e1ce4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/plr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pnk.png b/atomic_defi_design/assets/images/coins/pnk.png deleted file mode 100644 index d73e4f5b52..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pnk.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/poa.png b/atomic_defi_design/assets/images/coins/poa.png deleted file mode 100644 index ff3eca5057..0000000000 Binary files a/atomic_defi_design/assets/images/coins/poa.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/poe.png b/atomic_defi_design/assets/images/coins/poe.png deleted file mode 100644 index dc831da0c4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/poe.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/polis.png b/atomic_defi_design/assets/images/coins/polis.png deleted file mode 100644 index 71d8820bbd..0000000000 Binary files a/atomic_defi_design/assets/images/coins/polis.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/poly.png b/atomic_defi_design/assets/images/coins/poly.png deleted file mode 100644 index bd0dcad9c3..0000000000 Binary files a/atomic_defi_design/assets/images/coins/poly.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pot.png b/atomic_defi_design/assets/images/coins/pot.png deleted file mode 100644 index 3d5f01d6c3..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pot.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/powr.png b/atomic_defi_design/assets/images/coins/powr.png deleted file mode 100644 index 107826f050..0000000000 Binary files a/atomic_defi_design/assets/images/coins/powr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ppc.png b/atomic_defi_design/assets/images/coins/ppc.png deleted file mode 100644 index 95f60eb536..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ppc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ppp.png b/atomic_defi_design/assets/images/coins/ppp.png deleted file mode 100644 index 6165ba00dc..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ppp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ppt.png b/atomic_defi_design/assets/images/coins/ppt.png deleted file mode 100644 index 4b45a9794e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ppt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/prcy.png b/atomic_defi_design/assets/images/coins/prcy.png deleted file mode 100644 index 198e8f77cc..0000000000 Binary files a/atomic_defi_design/assets/images/coins/prcy.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pre.png b/atomic_defi_design/assets/images/coins/pre.png deleted file mode 100644 index add0ccebc4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pre.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/prl.png b/atomic_defi_design/assets/images/coins/prl.png deleted file mode 100644 index deedccac1a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/prl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/prux.png b/atomic_defi_design/assets/images/coins/prux.png deleted file mode 100644 index 95e65aa507..0000000000 Binary files a/atomic_defi_design/assets/images/coins/prux.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pungo.png b/atomic_defi_design/assets/images/coins/pungo.png deleted file mode 100644 index 79e746626f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pungo.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/pura.png b/atomic_defi_design/assets/images/coins/pura.png deleted file mode 100644 index d4bc8e507d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/pura.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/put.png b/atomic_defi_design/assets/images/coins/put.png deleted file mode 100644 index c2db5e6345..0000000000 Binary files a/atomic_defi_design/assets/images/coins/put.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/qash.png b/atomic_defi_design/assets/images/coins/qash.png deleted file mode 100644 index 7e8568fe9d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/qash.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/qbt.png b/atomic_defi_design/assets/images/coins/qbt.png deleted file mode 100644 index 5eaafe9285..0000000000 Binary files a/atomic_defi_design/assets/images/coins/qbt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/qc.png b/atomic_defi_design/assets/images/coins/qc.png deleted file mode 100644 index 87b12c7fb8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/qc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/qi.png b/atomic_defi_design/assets/images/coins/qi.png deleted file mode 100644 index 848d19a555..0000000000 Binary files a/atomic_defi_design/assets/images/coins/qi.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/qiair.png b/atomic_defi_design/assets/images/coins/qiair.png deleted file mode 100644 index 848d19a555..0000000000 Binary files a/atomic_defi_design/assets/images/coins/qiair.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/qiwi.png b/atomic_defi_design/assets/images/coins/qiwi.png deleted file mode 100644 index 3c1c557cb2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/qiwi.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/qkc.png b/atomic_defi_design/assets/images/coins/qkc.png deleted file mode 100644 index 4154df891c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/qkc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/qlc.png b/atomic_defi_design/assets/images/coins/qlc.png deleted file mode 100644 index 70a42fa21a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/qlc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/qnt.png b/atomic_defi_design/assets/images/coins/qnt.png deleted file mode 100644 index 1496985fee..0000000000 Binary files a/atomic_defi_design/assets/images/coins/qnt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/qrc-20.png b/atomic_defi_design/assets/images/coins/qrc-20.png deleted file mode 100644 index 656a8d04fb..0000000000 Binary files a/atomic_defi_design/assets/images/coins/qrc-20.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/qrc20.png b/atomic_defi_design/assets/images/coins/qrc20.png deleted file mode 100644 index 9a23d89aa3..0000000000 Binary files a/atomic_defi_design/assets/images/coins/qrc20.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/qrl.png b/atomic_defi_design/assets/images/coins/qrl.png deleted file mode 100644 index 581b7fd463..0000000000 Binary files a/atomic_defi_design/assets/images/coins/qrl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/qsp.png b/atomic_defi_design/assets/images/coins/qsp.png deleted file mode 100644 index cdbec73b7c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/qsp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/qtum.png b/atomic_defi_design/assets/images/coins/qtum.png deleted file mode 100644 index 9a23d89aa3..0000000000 Binary files a/atomic_defi_design/assets/images/coins/qtum.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/r.png b/atomic_defi_design/assets/images/coins/r.png deleted file mode 100644 index 0f51bb2ea0..0000000000 Binary files a/atomic_defi_design/assets/images/coins/r.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rads.png b/atomic_defi_design/assets/images/coins/rads.png deleted file mode 100644 index 121d47f9b7..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rads.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rap.png b/atomic_defi_design/assets/images/coins/rap.png deleted file mode 100644 index 36ad560c39..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rap.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rbtc.png b/atomic_defi_design/assets/images/coins/rbtc.png deleted file mode 100644 index 784b8f359a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rbtc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rcn.png b/atomic_defi_design/assets/images/coins/rcn.png deleted file mode 100644 index 59aa572ce5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rcn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rdd.png b/atomic_defi_design/assets/images/coins/rdd.png deleted file mode 100644 index 7328667f2e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rdd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rdn.png b/atomic_defi_design/assets/images/coins/rdn.png deleted file mode 100644 index cc4091e188..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rdn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ren.png b/atomic_defi_design/assets/images/coins/ren.png deleted file mode 100644 index d32cea165b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ren.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rep.png b/atomic_defi_design/assets/images/coins/rep.png deleted file mode 100644 index 8171355364..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rep.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/repv2.png b/atomic_defi_design/assets/images/coins/repv2.png deleted file mode 100644 index 04b29acf68..0000000000 Binary files a/atomic_defi_design/assets/images/coins/repv2.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/req.png b/atomic_defi_design/assets/images/coins/req.png deleted file mode 100644 index 66d74466bf..0000000000 Binary files a/atomic_defi_design/assets/images/coins/req.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rev.png b/atomic_defi_design/assets/images/coins/rev.png deleted file mode 100644 index adb8cdbe91..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rev.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/revs.png b/atomic_defi_design/assets/images/coins/revs.png deleted file mode 100644 index ccd857af7d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/revs.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rfox.png b/atomic_defi_design/assets/images/coins/rfox.png deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/atomic_defi_design/assets/images/coins/rhoc.png b/atomic_defi_design/assets/images/coins/rhoc.png deleted file mode 100644 index b6553fd838..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rhoc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ric.png b/atomic_defi_design/assets/images/coins/ric.png deleted file mode 100644 index dc06842599..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ric.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rick.png b/atomic_defi_design/assets/images/coins/rick.png deleted file mode 100644 index 2d32ff7976..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rick.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rise.png b/atomic_defi_design/assets/images/coins/rise.png deleted file mode 100644 index fee2f5f814..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rise.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rlc.png b/atomic_defi_design/assets/images/coins/rlc.png deleted file mode 100644 index 11b0f1abdc..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rlc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rpx.png b/atomic_defi_design/assets/images/coins/rpx.png deleted file mode 100644 index a106c26650..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rpx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rsr.png b/atomic_defi_design/assets/images/coins/rsr.png deleted file mode 100644 index dba8513fe2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rsr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rtm.png b/atomic_defi_design/assets/images/coins/rtm.png deleted file mode 100644 index 9beb18531f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rtm.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rub.png b/atomic_defi_design/assets/images/coins/rub.png deleted file mode 100644 index a2915d3179..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rub.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/rvn.png b/atomic_defi_design/assets/images/coins/rvn.png deleted file mode 100644 index 886b94b612..0000000000 Binary files a/atomic_defi_design/assets/images/coins/rvn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ryo.png b/atomic_defi_design/assets/images/coins/ryo.png deleted file mode 100644 index 973c5fe7b9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ryo.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/s4f.png b/atomic_defi_design/assets/images/coins/s4f.png deleted file mode 100644 index 43c7c7cfde..0000000000 Binary files a/atomic_defi_design/assets/images/coins/s4f.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/safe.png b/atomic_defi_design/assets/images/coins/safe.png deleted file mode 100644 index 2600e6e6c6..0000000000 Binary files a/atomic_defi_design/assets/images/coins/safe.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sai.png b/atomic_defi_design/assets/images/coins/sai.png deleted file mode 100644 index 08d4842396..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sai.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/salt.png b/atomic_defi_design/assets/images/coins/salt.png deleted file mode 100644 index aeacd05554..0000000000 Binary files a/atomic_defi_design/assets/images/coins/salt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/san.png b/atomic_defi_design/assets/images/coins/san.png deleted file mode 100644 index 1bb3e3cf29..0000000000 Binary files a/atomic_defi_design/assets/images/coins/san.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sand.png b/atomic_defi_design/assets/images/coins/sand.png deleted file mode 100644 index f836bb3f62..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sand.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sbch.png b/atomic_defi_design/assets/images/coins/sbch.png deleted file mode 100644 index 10aa0665c4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sbch.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sbd.png b/atomic_defi_design/assets/images/coins/sbd.png deleted file mode 100644 index e33d5d2de5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sbd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sberbank.png b/atomic_defi_design/assets/images/coins/sberbank.png deleted file mode 100644 index ace70f1d0a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sberbank.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sc.png b/atomic_defi_design/assets/images/coins/sc.png deleted file mode 100644 index e518cc13ff..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sca.png b/atomic_defi_design/assets/images/coins/sca.png deleted file mode 100644 index 0620e8e48e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sca.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sfusd.png b/atomic_defi_design/assets/images/coins/sfusd.png deleted file mode 100644 index e5ae4d672e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sfusd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/shib.png b/atomic_defi_design/assets/images/coins/shib.png deleted file mode 100644 index 37f06ca576..0000000000 Binary files a/atomic_defi_design/assets/images/coins/shib.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/shift.png b/atomic_defi_design/assets/images/coins/shift.png deleted file mode 100644 index 8942a14873..0000000000 Binary files a/atomic_defi_design/assets/images/coins/shift.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/shr.png b/atomic_defi_design/assets/images/coins/shr.png deleted file mode 100644 index 0765877e04..0000000000 Binary files a/atomic_defi_design/assets/images/coins/shr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sib.png b/atomic_defi_design/assets/images/coins/sib.png deleted file mode 100644 index 975722dbf9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sib.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sibm.png b/atomic_defi_design/assets/images/coins/sibm.png deleted file mode 100644 index f6ab63d7c2..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sibm.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sin.png b/atomic_defi_design/assets/images/coins/sin.png deleted file mode 100644 index 3abf7ef109..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sin.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/skl.png b/atomic_defi_design/assets/images/coins/skl.png deleted file mode 100644 index 9adc6ddacc..0000000000 Binary files a/atomic_defi_design/assets/images/coins/skl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sky.png b/atomic_defi_design/assets/images/coins/sky.png deleted file mode 100644 index a6e6de1c55..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sky.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/slr.png b/atomic_defi_design/assets/images/coins/slr.png deleted file mode 100644 index 05e6da3a56..0000000000 Binary files a/atomic_defi_design/assets/images/coins/slr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sls.png b/atomic_defi_design/assets/images/coins/sls.png deleted file mode 100644 index 2ba628f677..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sls.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/smart-chain.png b/atomic_defi_design/assets/images/coins/smart-chain.png deleted file mode 100644 index 10d8011ce4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/smart-chain.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/smart.png b/atomic_defi_design/assets/images/coins/smart.png deleted file mode 100644 index b464b7323a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/smart.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/smtf.png b/atomic_defi_design/assets/images/coins/smtf.png deleted file mode 100644 index 9c1c14c6de..0000000000 Binary files a/atomic_defi_design/assets/images/coins/smtf.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sngls.png b/atomic_defi_design/assets/images/coins/sngls.png deleted file mode 100644 index 30728ce9cd..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sngls.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/snm.png b/atomic_defi_design/assets/images/coins/snm.png deleted file mode 100644 index 134ea71328..0000000000 Binary files a/atomic_defi_design/assets/images/coins/snm.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/snt.png b/atomic_defi_design/assets/images/coins/snt.png deleted file mode 100644 index e856e10859..0000000000 Binary files a/atomic_defi_design/assets/images/coins/snt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/snx.png b/atomic_defi_design/assets/images/coins/snx.png deleted file mode 100644 index 636a9bc977..0000000000 Binary files a/atomic_defi_design/assets/images/coins/snx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/soc.png b/atomic_defi_design/assets/images/coins/soc.png deleted file mode 100644 index de8edeb0d4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/soc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sol.png b/atomic_defi_design/assets/images/coins/sol.png deleted file mode 100644 index 3106cc0443..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sol.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/soulja.png b/atomic_defi_design/assets/images/coins/soulja.png deleted file mode 100644 index e60218a2e5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/soulja.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/space.png b/atomic_defi_design/assets/images/coins/space.png deleted file mode 100644 index e6c20cc13e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/space.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/spank.png b/atomic_defi_design/assets/images/coins/spank.png deleted file mode 100644 index c190cd0157..0000000000 Binary files a/atomic_defi_design/assets/images/coins/spank.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/spc.png b/atomic_defi_design/assets/images/coins/spc.png deleted file mode 100644 index f21ae96d03..0000000000 Binary files a/atomic_defi_design/assets/images/coins/spc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sphtx.png b/atomic_defi_design/assets/images/coins/sphtx.png deleted file mode 100644 index 325d75bead..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sphtx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/srm.png b/atomic_defi_design/assets/images/coins/srm.png deleted file mode 100644 index 4aed91f9a6..0000000000 Binary files a/atomic_defi_design/assets/images/coins/srm.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/srn.png b/atomic_defi_design/assets/images/coins/srn.png deleted file mode 100644 index 49ac71ed17..0000000000 Binary files a/atomic_defi_design/assets/images/coins/srn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/stak.png b/atomic_defi_design/assets/images/coins/stak.png deleted file mode 100644 index d1ee90992a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/stak.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/start.png b/atomic_defi_design/assets/images/coins/start.png deleted file mode 100644 index f7b4a28e91..0000000000 Binary files a/atomic_defi_design/assets/images/coins/start.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/steem.png b/atomic_defi_design/assets/images/coins/steem.png deleted file mode 100644 index e33d5d2de5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/steem.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/stfiro.png b/atomic_defi_design/assets/images/coins/stfiro.png deleted file mode 100644 index ea325e0cd5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/stfiro.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/storj.png b/atomic_defi_design/assets/images/coins/storj.png deleted file mode 100644 index fe1cb0b392..0000000000 Binary files a/atomic_defi_design/assets/images/coins/storj.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/storm.png b/atomic_defi_design/assets/images/coins/storm.png deleted file mode 100644 index 5cc06a2e13..0000000000 Binary files a/atomic_defi_design/assets/images/coins/storm.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/stq.png b/atomic_defi_design/assets/images/coins/stq.png deleted file mode 100644 index b86da90c9f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/stq.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/strat.png b/atomic_defi_design/assets/images/coins/strat.png deleted file mode 100644 index c06eea949a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/strat.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/stx.png b/atomic_defi_design/assets/images/coins/stx.png deleted file mode 100644 index 8c7a8cc938..0000000000 Binary files a/atomic_defi_design/assets/images/coins/stx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sub.png b/atomic_defi_design/assets/images/coins/sub.png deleted file mode 100644 index 00dbf0d10c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sub.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sumo.png b/atomic_defi_design/assets/images/coins/sumo.png deleted file mode 100644 index a31ee14d91..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sumo.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/supernet.png b/atomic_defi_design/assets/images/coins/supernet.png deleted file mode 100644 index 1a4b4f1f11..0000000000 Binary files a/atomic_defi_design/assets/images/coins/supernet.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sushi.png b/atomic_defi_design/assets/images/coins/sushi.png deleted file mode 100644 index 01d56e87d5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sushi.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sxp.png b/atomic_defi_design/assets/images/coins/sxp.png deleted file mode 100644 index d3c9933a2e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sxp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/sys.png b/atomic_defi_design/assets/images/coins/sys.png deleted file mode 100644 index 1be9cca04d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/sys.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/taas.png b/atomic_defi_design/assets/images/coins/taas.png deleted file mode 100644 index 01060ba24a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/taas.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tau.png b/atomic_defi_design/assets/images/coins/tau.png deleted file mode 100644 index b94df236b0..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tau.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tblk.png b/atomic_defi_design/assets/images/coins/tblk.png deleted file mode 100644 index 22f5c90fb8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tblk.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tbtc.png b/atomic_defi_design/assets/images/coins/tbtc.png deleted file mode 100644 index 784b8f359a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tbtc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tbx.png b/atomic_defi_design/assets/images/coins/tbx.png deleted file mode 100644 index 5af22e62f1..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tbx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tel.png b/atomic_defi_design/assets/images/coins/tel.png deleted file mode 100644 index 453dac21c1..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tel.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ten.png b/atomic_defi_design/assets/images/coins/ten.png deleted file mode 100644 index ee88f6c23e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ten.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tern.png b/atomic_defi_design/assets/images/coins/tern.png deleted file mode 100644 index 5aefc007b4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tern.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tft.png b/atomic_defi_design/assets/images/coins/tft.png deleted file mode 100644 index 370e2110fd..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tft.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tgch.png b/atomic_defi_design/assets/images/coins/tgch.png deleted file mode 100644 index 01b0fb77f9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tgch.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/thc.png b/atomic_defi_design/assets/images/coins/thc.png deleted file mode 100644 index 7c536e8ecb..0000000000 Binary files a/atomic_defi_design/assets/images/coins/thc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/thc_bep20.png b/atomic_defi_design/assets/images/coins/thc_bep20.png deleted file mode 100644 index 544bd93b4f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/thc_bep20.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/theta.png b/atomic_defi_design/assets/images/coins/theta.png deleted file mode 100644 index 569801369a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/theta.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/thx.png b/atomic_defi_design/assets/images/coins/thx.png deleted file mode 100644 index cde6c321a9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/thx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tix.png b/atomic_defi_design/assets/images/coins/tix.png deleted file mode 100644 index 3b2aa9e739..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tix.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tkl.png b/atomic_defi_design/assets/images/coins/tkl.png deleted file mode 100644 index abb685c1a1..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tkl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tkn.png b/atomic_defi_design/assets/images/coins/tkn.png deleted file mode 100644 index deb2a9df3b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tkn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tks.png b/atomic_defi_design/assets/images/coins/tks.png deleted file mode 100644 index f82600fd4c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tks.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tmtg.png b/atomic_defi_design/assets/images/coins/tmtg.png deleted file mode 100644 index aed51a902b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tmtg.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tnb.png b/atomic_defi_design/assets/images/coins/tnb.png deleted file mode 100644 index 0e193c95f5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tnb.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tnc.png b/atomic_defi_design/assets/images/coins/tnc.png deleted file mode 100644 index 9d5fbc4fc4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tnc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tnt.png b/atomic_defi_design/assets/images/coins/tnt.png deleted file mode 100644 index 350626adab..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tnt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tomo.png b/atomic_defi_design/assets/images/coins/tomo.png deleted file mode 100644 index 41014ef45d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tomo.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tpay.png b/atomic_defi_design/assets/images/coins/tpay.png deleted file mode 100644 index 8a08b1203a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tpay.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tqtum.png b/atomic_defi_design/assets/images/coins/tqtum.png deleted file mode 100644 index 9a23d89aa3..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tqtum.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/trac.png b/atomic_defi_design/assets/images/coins/trac.png deleted file mode 100644 index 49bab9185c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/trac.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/trb.png b/atomic_defi_design/assets/images/coins/trb.png deleted file mode 100644 index ec5a4360d9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/trb.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/trc.png b/atomic_defi_design/assets/images/coins/trc.png deleted file mode 100644 index f3f68ba2a5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/trc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/trig.png b/atomic_defi_design/assets/images/coins/trig.png deleted file mode 100644 index ca037070d8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/trig.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/trtl.png b/atomic_defi_design/assets/images/coins/trtl.png deleted file mode 100644 index 3f4b4f5d06..0000000000 Binary files a/atomic_defi_design/assets/images/coins/trtl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/trx.png b/atomic_defi_design/assets/images/coins/trx.png deleted file mode 100644 index 3df9610eb0..0000000000 Binary files a/atomic_defi_design/assets/images/coins/trx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tryb.png b/atomic_defi_design/assets/images/coins/tryb.png deleted file mode 100644 index 1544f84ed5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tryb.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tsl.png b/atomic_defi_design/assets/images/coins/tsl.png deleted file mode 100644 index aa5aad77d5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tsl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ttt.png b/atomic_defi_design/assets/images/coins/ttt.png deleted file mode 100644 index 2f90f6bd97..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ttt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tusd.png b/atomic_defi_design/assets/images/coins/tusd.png deleted file mode 100644 index a315574d48..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tusd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/tzc.png b/atomic_defi_design/assets/images/coins/tzc.png deleted file mode 100644 index 62ae87ff65..0000000000 Binary files a/atomic_defi_design/assets/images/coins/tzc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ubq.png b/atomic_defi_design/assets/images/coins/ubq.png deleted file mode 100644 index 2ea970b949..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ubq.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ubt.png b/atomic_defi_design/assets/images/coins/ubt.png deleted file mode 100644 index e9c9f22a30..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ubt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/uis.png b/atomic_defi_design/assets/images/coins/uis.png deleted file mode 100644 index 2334146661..0000000000 Binary files a/atomic_defi_design/assets/images/coins/uis.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/uma.png b/atomic_defi_design/assets/images/coins/uma.png deleted file mode 100644 index 6e2c6aa7e9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/uma.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/uni.png b/atomic_defi_design/assets/images/coins/uni.png deleted file mode 100644 index 02ab8562ca..0000000000 Binary files a/atomic_defi_design/assets/images/coins/uni.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/unity.png b/atomic_defi_design/assets/images/coins/unity.png deleted file mode 100644 index 3a4b79e550..0000000000 Binary files a/atomic_defi_design/assets/images/coins/unity.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/uno.png b/atomic_defi_design/assets/images/coins/uno.png deleted file mode 100644 index 8db98dc6dd..0000000000 Binary files a/atomic_defi_design/assets/images/coins/uno.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/uos.png b/atomic_defi_design/assets/images/coins/uos.png deleted file mode 100644 index 20ef7e4a4e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/uos.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/uqc.png b/atomic_defi_design/assets/images/coins/uqc.png deleted file mode 100644 index c079fa6a42..0000000000 Binary files a/atomic_defi_design/assets/images/coins/uqc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/usbl.png b/atomic_defi_design/assets/images/coins/usbl.png deleted file mode 100644 index a77d949c9a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/usbl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/usd.png b/atomic_defi_design/assets/images/coins/usd.png deleted file mode 100644 index 2a49b5adc9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/usd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/usdc.png b/atomic_defi_design/assets/images/coins/usdc.png deleted file mode 100644 index 2b8467ccf0..0000000000 Binary files a/atomic_defi_design/assets/images/coins/usdc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/usdi.png b/atomic_defi_design/assets/images/coins/usdi.png deleted file mode 100644 index be035d8d39..0000000000 Binary files a/atomic_defi_design/assets/images/coins/usdi.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/usdt.png b/atomic_defi_design/assets/images/coins/usdt.png deleted file mode 100644 index b6b6a612fb..0000000000 Binary files a/atomic_defi_design/assets/images/coins/usdt.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/ust.png b/atomic_defi_design/assets/images/coins/ust.png deleted file mode 100644 index e5e60ed8cc..0000000000 Binary files a/atomic_defi_design/assets/images/coins/ust.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/utk.png b/atomic_defi_design/assets/images/coins/utk.png deleted file mode 100644 index e54a67b8b0..0000000000 Binary files a/atomic_defi_design/assets/images/coins/utk.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/val.png b/atomic_defi_design/assets/images/coins/val.png deleted file mode 100644 index dfc69aecf8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/val.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/veri.png b/atomic_defi_design/assets/images/coins/veri.png deleted file mode 100644 index 75c3bb7c64..0000000000 Binary files a/atomic_defi_design/assets/images/coins/veri.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/vet.png b/atomic_defi_design/assets/images/coins/vet.png deleted file mode 100644 index dd483a0be6..0000000000 Binary files a/atomic_defi_design/assets/images/coins/vet.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/vgx.png b/atomic_defi_design/assets/images/coins/vgx.png deleted file mode 100644 index 443426909a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/vgx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/via.png b/atomic_defi_design/assets/images/coins/via.png deleted file mode 100644 index 46ae8fd539..0000000000 Binary files a/atomic_defi_design/assets/images/coins/via.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/vib.png b/atomic_defi_design/assets/images/coins/vib.png deleted file mode 100644 index d1a1c38f6f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/vib.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/vibe.png b/atomic_defi_design/assets/images/coins/vibe.png deleted file mode 100644 index 9b1674a491..0000000000 Binary files a/atomic_defi_design/assets/images/coins/vibe.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/vite.png b/atomic_defi_design/assets/images/coins/vite.png deleted file mode 100644 index 6a6d150350..0000000000 Binary files a/atomic_defi_design/assets/images/coins/vite.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/vivo.png b/atomic_defi_design/assets/images/coins/vivo.png deleted file mode 100644 index 40a8fb2e8f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/vivo.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/vote2021.png b/atomic_defi_design/assets/images/coins/vote2021.png deleted file mode 100644 index e26a95e66d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/vote2021.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/vra.png b/atomic_defi_design/assets/images/coins/vra.png deleted file mode 100644 index ab92e43e98..0000000000 Binary files a/atomic_defi_design/assets/images/coins/vra.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/vrc.png b/atomic_defi_design/assets/images/coins/vrc.png deleted file mode 100644 index c19602b012..0000000000 Binary files a/atomic_defi_design/assets/images/coins/vrc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/vrm.png b/atomic_defi_design/assets/images/coins/vrm.png deleted file mode 100644 index ae6c3957da..0000000000 Binary files a/atomic_defi_design/assets/images/coins/vrm.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/vrsc.png b/atomic_defi_design/assets/images/coins/vrsc.png deleted file mode 100644 index 98c981e350..0000000000 Binary files a/atomic_defi_design/assets/images/coins/vrsc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/vtc.png b/atomic_defi_design/assets/images/coins/vtc.png deleted file mode 100644 index 7255699eb6..0000000000 Binary files a/atomic_defi_design/assets/images/coins/vtc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/vtho.png b/atomic_defi_design/assets/images/coins/vtho.png deleted file mode 100644 index 1f10acff99..0000000000 Binary files a/atomic_defi_design/assets/images/coins/vtho.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/wabi.png b/atomic_defi_design/assets/images/coins/wabi.png deleted file mode 100644 index bc67f7859d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/wabi.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/wan.png b/atomic_defi_design/assets/images/coins/wan.png deleted file mode 100644 index 1425526345..0000000000 Binary files a/atomic_defi_design/assets/images/coins/wan.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/waves.png b/atomic_defi_design/assets/images/coins/waves.png deleted file mode 100644 index 266eb3d0d9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/waves.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/wax.png b/atomic_defi_design/assets/images/coins/wax.png deleted file mode 100644 index 2c52fa616c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/wax.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/wbtc.png b/atomic_defi_design/assets/images/coins/wbtc.png deleted file mode 100644 index 879ec2d322..0000000000 Binary files a/atomic_defi_design/assets/images/coins/wbtc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/wcn.png b/atomic_defi_design/assets/images/coins/wcn.png deleted file mode 100644 index 535e23e2c1..0000000000 Binary files a/atomic_defi_design/assets/images/coins/wcn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/wgr.png b/atomic_defi_design/assets/images/coins/wgr.png deleted file mode 100644 index 5e0729aaf8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/wgr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/whive.png b/atomic_defi_design/assets/images/coins/whive.png deleted file mode 100644 index d61ce54f16..0000000000 Binary files a/atomic_defi_design/assets/images/coins/whive.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/wicc.png b/atomic_defi_design/assets/images/coins/wicc.png deleted file mode 100644 index d70a5bb6a6..0000000000 Binary files a/atomic_defi_design/assets/images/coins/wicc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/wings.png b/atomic_defi_design/assets/images/coins/wings.png deleted file mode 100644 index 950828c789..0000000000 Binary files a/atomic_defi_design/assets/images/coins/wings.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/wpr.png b/atomic_defi_design/assets/images/coins/wpr.png deleted file mode 100644 index 9974a02ab4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/wpr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/wsb.png b/atomic_defi_design/assets/images/coins/wsb.png deleted file mode 100644 index c556281fa7..0000000000 Binary files a/atomic_defi_design/assets/images/coins/wsb.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/wtc.png b/atomic_defi_design/assets/images/coins/wtc.png deleted file mode 100644 index 9932eb8a53..0000000000 Binary files a/atomic_defi_design/assets/images/coins/wtc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/wwcn.png b/atomic_defi_design/assets/images/coins/wwcn.png deleted file mode 100644 index bac60e9168..0000000000 Binary files a/atomic_defi_design/assets/images/coins/wwcn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/x.png b/atomic_defi_design/assets/images/coins/x.png deleted file mode 100644 index 60cd6a1b07..0000000000 Binary files a/atomic_defi_design/assets/images/coins/x.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xas.png b/atomic_defi_design/assets/images/coins/xas.png deleted file mode 100644 index c1db3ce55f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xas.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xbc.png b/atomic_defi_design/assets/images/coins/xbc.png deleted file mode 100644 index e3bdd56cb5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xbc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xbp.png b/atomic_defi_design/assets/images/coins/xbp.png deleted file mode 100644 index f17afaa51b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xbp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xby.png b/atomic_defi_design/assets/images/coins/xby.png deleted file mode 100644 index 87e2731c66..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xby.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xcp.png b/atomic_defi_design/assets/images/coins/xcp.png deleted file mode 100644 index fc732ccaeb..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xcp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xdn.png b/atomic_defi_design/assets/images/coins/xdn.png deleted file mode 100644 index 8bff070e3f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xdn.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xec.png b/atomic_defi_design/assets/images/coins/xec.png deleted file mode 100644 index 01fae8f8bf..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xec.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xem.png b/atomic_defi_design/assets/images/coins/xem.png deleted file mode 100644 index 16b9e8cebd..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xem.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xep.png b/atomic_defi_design/assets/images/coins/xep.png deleted file mode 100644 index c779f5b59e..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xep.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xin.png b/atomic_defi_design/assets/images/coins/xin.png deleted file mode 100644 index 29a48c0d1c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xin.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xlm.png b/atomic_defi_design/assets/images/coins/xlm.png deleted file mode 100644 index ab10cad49a..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xlm.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xmcc.png b/atomic_defi_design/assets/images/coins/xmcc.png deleted file mode 100644 index 2281991ac9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xmcc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xmg.png b/atomic_defi_design/assets/images/coins/xmg.png deleted file mode 100644 index ee37ceb6f6..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xmg.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xmo.png b/atomic_defi_design/assets/images/coins/xmo.png deleted file mode 100644 index 98e82d2f70..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xmo.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xmr.png b/atomic_defi_design/assets/images/coins/xmr.png deleted file mode 100644 index ce409524c4..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xmr.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xmy.png b/atomic_defi_design/assets/images/coins/xmy.png deleted file mode 100644 index a2d32ff59f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xmy.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xor.png b/atomic_defi_design/assets/images/coins/xor.png deleted file mode 100644 index 74c4cf014d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xor.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xp.png b/atomic_defi_design/assets/images/coins/xp.png deleted file mode 100644 index 9478a855a8..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xpa.png b/atomic_defi_design/assets/images/coins/xpa.png deleted file mode 100644 index f49910b5cb..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xpa.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xpm.png b/atomic_defi_design/assets/images/coins/xpm.png deleted file mode 100644 index f32e349dbf..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xpm.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xrg.png b/atomic_defi_design/assets/images/coins/xrg.png deleted file mode 100644 index 0545067a7c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xrg.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xrp.png b/atomic_defi_design/assets/images/coins/xrp.png deleted file mode 100644 index f24cf25963..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xrp.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xsg.png b/atomic_defi_design/assets/images/coins/xsg.png deleted file mode 100644 index 5747b31134..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xsg.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xsgd.png b/atomic_defi_design/assets/images/coins/xsgd.png deleted file mode 100644 index 67f0438af9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xsgd.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xtz.png b/atomic_defi_design/assets/images/coins/xtz.png deleted file mode 100644 index 79ecc75f3f..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xtz.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xuc.png b/atomic_defi_design/assets/images/coins/xuc.png deleted file mode 100644 index 82dc953964..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xuc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xvc.png b/atomic_defi_design/assets/images/coins/xvc.png deleted file mode 100644 index 1b25554709..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xvc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xvg.png b/atomic_defi_design/assets/images/coins/xvg.png deleted file mode 100644 index 0de5ce45b5..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xvg.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xvs.png b/atomic_defi_design/assets/images/coins/xvs.png deleted file mode 100644 index b802ff87ea..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xvs.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/xzc.png b/atomic_defi_design/assets/images/coins/xzc.png deleted file mode 100644 index 926bed0313..0000000000 Binary files a/atomic_defi_design/assets/images/coins/xzc.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/yfi.png b/atomic_defi_design/assets/images/coins/yfi.png deleted file mode 100644 index 856678403b..0000000000 Binary files a/atomic_defi_design/assets/images/coins/yfi.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/yfii.png b/atomic_defi_design/assets/images/coins/yfii.png deleted file mode 100644 index 8b38b93190..0000000000 Binary files a/atomic_defi_design/assets/images/coins/yfii.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/yoyow.png b/atomic_defi_design/assets/images/coins/yoyow.png deleted file mode 100644 index 121fa343d7..0000000000 Binary files a/atomic_defi_design/assets/images/coins/yoyow.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/zb.png b/atomic_defi_design/assets/images/coins/zb.png deleted file mode 100644 index 0abf5cb2ba..0000000000 Binary files a/atomic_defi_design/assets/images/coins/zb.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/zcl.png b/atomic_defi_design/assets/images/coins/zcl.png deleted file mode 100644 index cdc675a7dc..0000000000 Binary files a/atomic_defi_design/assets/images/coins/zcl.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/zec.png b/atomic_defi_design/assets/images/coins/zec.png deleted file mode 100644 index 9327fc65d1..0000000000 Binary files a/atomic_defi_design/assets/images/coins/zec.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/zel.png b/atomic_defi_design/assets/images/coins/zel.png deleted file mode 100644 index 5900bcda93..0000000000 Binary files a/atomic_defi_design/assets/images/coins/zel.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/zen.png b/atomic_defi_design/assets/images/coins/zen.png deleted file mode 100644 index aaf63d8cf9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/zen.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/zer.png b/atomic_defi_design/assets/images/coins/zer.png deleted file mode 100644 index 848c885401..0000000000 Binary files a/atomic_defi_design/assets/images/coins/zer.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/zest.png b/atomic_defi_design/assets/images/coins/zest.png deleted file mode 100644 index eb57167ccb..0000000000 Binary files a/atomic_defi_design/assets/images/coins/zest.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/zet.png b/atomic_defi_design/assets/images/coins/zet.png deleted file mode 100644 index b107a81f4d..0000000000 Binary files a/atomic_defi_design/assets/images/coins/zet.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/zil.png b/atomic_defi_design/assets/images/coins/zil.png deleted file mode 100644 index e49147f507..0000000000 Binary files a/atomic_defi_design/assets/images/coins/zil.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/zilla.png b/atomic_defi_design/assets/images/coins/zilla.png deleted file mode 100644 index 03f5c545b6..0000000000 Binary files a/atomic_defi_design/assets/images/coins/zilla.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/zinu.png b/atomic_defi_design/assets/images/coins/zinu.png deleted file mode 100644 index 30f2e8d12c..0000000000 Binary files a/atomic_defi_design/assets/images/coins/zinu.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/coins/zrx.png b/atomic_defi_design/assets/images/coins/zrx.png deleted file mode 100644 index d4baae5fc9..0000000000 Binary files a/atomic_defi_design/assets/images/coins/zrx.png and /dev/null differ diff --git a/atomic_defi_design/assets/images/lang/de.png b/atomic_defi_design/assets/images/lang/de.png new file mode 100644 index 0000000000..c4b7c4335b Binary files /dev/null and b/atomic_defi_design/assets/images/lang/de.png differ diff --git a/atomic_defi_design/assets/images/lang/es.png b/atomic_defi_design/assets/images/lang/es.png new file mode 100755 index 0000000000..5fdf39bb75 Binary files /dev/null and b/atomic_defi_design/assets/images/lang/es.png differ diff --git a/atomic_defi_design/assets/images/white_check.svg b/atomic_defi_design/assets/images/white_check.svg new file mode 100644 index 0000000000..927f9bf9a2 --- /dev/null +++ b/atomic_defi_design/assets/images/white_check.svg @@ -0,0 +1,40 @@ + + diff --git a/atomic_defi_design/assets/languages/atomic_defi_de.ts b/atomic_defi_design/assets/languages/atomic_defi_de.ts new file mode 100644 index 0000000000..06dad49822 --- /dev/null +++ b/atomic_defi_design/assets/languages/atomic_defi_de.ts @@ -0,0 +1,4553 @@ + + + + + AddAddressForm + + + Use standard network address + Standard-Netzwerkadresse verwenden + + + + Label + Bezeichnung + + + + This key already exists. + Dieser Schlüssel existiert bereits. + + + + Address + Adresse + + + + + Cancel + Abbrechen + + + + Convert + Umwandeln + + + + Edit + Bearbeiten + + + + Add + Hinzufügen + + + + You need to enable %1 before adding this kind of address. + Sie müssen %1 aktivieren, bevor Sie diese Art von Adresse hinzufügen. + + + + Enable + Aktivieren + + + + 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! + + + + 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 + + + + AddTagPopup + + + Tag name + Schlagwort + + + + Contact already has this tag. + Der Kontakt hat bereits dieses Schlagwort. + + + + + ADD + + HINZUFÜGEN + + + + AmountChart + + + Work in progress + In Arbeit + + + + App + + + Recover Funds Result + Ergebnis der Rückerstattung der Geldmittel + + + + AssetFromStandardSelector + + + Choose a valid + Wählen Sie eine gültige + + + + asset + Asset + + + + Search an asset + Asset suchen + + + + Disabled + Deaktiviert + + + + AssetPieChart + + + Assets + Assets + + + + AssetsList + + + Asset + Asset + + + + Balance + Balance + + + + Fiat Balance + Fiat Balance + + + + Change 24h + 24h Veränderung + + + + Price + Preis + + + + Source + Quelle + + + + Activating: + + + + + Price provider is: %1 + Preisanbieter ist: %1 + + + + Bottom + + + Settings + Einstellungen + + + + Support + Support + + + + Privacy + Datenschutz + + + + Disable Privacy? + Datenschutz deaktivieren? + + + + Enter wallet password to confirm + Geben Sie zur Bestätigung das Kennwort der Brieftasche ein + + + + Type password + Kennwort eingeben + + + + Confirm + Bestätigen + + + + Cancel + Abbrechen + + + + Privacy status + Status Datenschutz + + + + Privacy mode disabled successfully + Der Datenschutzmodus wurde erfolgreich deaktiviert + + + + + Ok + Ok + + + + Wrong password! + Falsches Kennwort! + + + + wallet password is incorrect + Kennwort der Brieftasche ist falsch + + + + CamouflagePasswordModal + + + Setup Camouflage Password + Tarnkennwort einrichten + + + + Camouflage Password is a secret password for emergency situations. + Das Tarnkennwort (Camouflage Password) ist ein geheimes Passwort für Notsituationen. + + + + Using it to login will display your balance lower than it actually is. + Wenn Sie sich damit anmelden, wird Ihr Guthaben niedriger angezeigt, als es tatsächlich ist. + + + + Here you enter the suffix and at login you need to enter {real_password}{suffix} + Hier geben Sie den Zusatz ein und beim Einloggen benötigen Sie {echtes Kennwort}{suffix} +Beispiel: Kennwort = 1234 Suffix=56 Eingabe beim Login=123456 + + + + Password suffix + Kennwort-Zusatz + + + + Confirm pasword suffix + Kennwort-Zusatz bestätigen + + + + Enter a password suffix + Geben Sie einen Kennwort-Zusatz ein + + + + Enter the same password suffix to confirm + Geben Sie zur Bestätigung denselben Kennwort-Zusatz ein + + + + Cancel + Abbrechen + + + + Save + Speichern + + + + CannotEnableCoinModal + + + Failed to enable %1 + Aktivierung von %1 fehlgeschlagen + + + + Enabling %1 did not succeed. Limit of enabled coins might have been reached. + Das Aktivieren von %1 war nicht erfolgreich. Das Limit der aktivierten Coins wurde möglicherweise erreicht. + + + + Change limit in settings + Limit in den Einstellungen ändern + + + + Cancel + Abbrechen + + + + Center + + + Portfolio + Portfolio + + + + Wallet + Brieftasche + + + + DEX + DEX + + + + Address Book + Adressbuch + + + + Fiat + Fiat + + + + CexInfoModal + + + Market Data + Marktdaten + + + + Market data (prices, charts, etc.) marked with the ⓘ icon originates from third-party sources.<br><br>Data is sourced via <a href="https://bandprotocol.com/">Band Decentralized Oracle</a> and <a href="https://coingecko.com">CoinGecko</a>.<br><br><b>Oracle Supported Pairs:</b><br>%1<br><br><b>Last reference (Band Oracle):</b><br><a href="%2">%2</a> + Mit dem Symbol ⓘ gekennzeichnete Marktdaten (Kurse, Charts etc.) stammen aus Drittquellen.<br><br>Die Daten stammen von <a href="https://bandprotocol.com/">Band Decentralized Oracle</a> und <a href="https://coingecko.com">CoinGecko</a>.<br><br><b>Oracle unterstützte Paare:</b><br>%1<br><br><b>Letzte Referenz (Band Oracle):</b><br><a href="%2">%2</a> + + + + Chart + + + Loading market data + Laden von Marktdaten + + + + There is no chart data for this pair yet + Für dieses Paar liegen noch keine Chartdaten vor + + + + ClaimRewardsModal + + + Failed to prepare to claim rewards + Vorbereitung zum Einfordern von Belohnungen fehlgeschlagen + + + + Claim your %1 reward? + TICKER + %1 Belohnung beantragen? + + + + No UTXOs eligible for claiming + Keine beanspruchungsberechtigten UTXOs vorhanden + + + + Transaction fee is higher than the reward! + Die Transaktionsgebühr ist höher als die Belohnung! + + + + You will receive + Sie erhalten + + + + Refresh + Aktualisieren + + + + Read more about KMD active users rewards + Lesen Sie mehr über die Belohnungen für aktive KMD-Benutzer + + + + UTXO + UTXO + + + + Amount + Menge + + + + Reward + Belohnung + + + + Accruing Start + Anfallender Start + + + + Accruing Stop + Anfallender Stopp + + + + Time Left + Verbleibende Zeit + + + + Error + Fehler + + + + Locktime is not set + Die Sperrzeit ist nicht eingestellt + + + + Locktime is less than the threshold + Die Sperrzeit liegt unter dem Schwellenwert + + + + UTXO height is greater than end of the era + UTXO-Höhe ist größer als Ende der Ära + + + + UTXO amount is less than 10 + UTXO-Menge ist kleiner als 10 + + + + One hour did not pass yet + Eine Stunde ist noch nicht vergangen + + + + Transaction is in mempool + Die Transaktion befindet sich in Mempool + + + + Unknown problem + Unbekanntes Problem + + + + Cancel + Abbrechen + + + + Confirm + Bestätigen + + + + CoinMenu + + + Disable %1 + TICKER + %1 deaktivieren + + + + Disable and Delete %1 + TICKER + %1 deaktivieren und löschen + + + + Disable all %1 assets + Alle %1 Assets deaktivieren + + + + Disable all assets + Alle Assets deaktivieren + + + + Disable 0 balance assets + Alle Assets mit der Balance 0 deaktivieren + + + + ComboBoxWithSearchBar + + + Search + Suchen + + + + Combo_fiat + + + Language + Sprache + + + + Fiat + Fiat + + + + Recommended: + Empfohlen: + + + + ConfirmMultiOrderTradeModal + + + Confirm Multi Order Details + Bestätigen Sie die Details der Mehrfachorder + + + + These swaps requests can not be undone and this is the final event! + Diese Tauschanfragen können nicht rückgängig gemacht werden und dies ist das endgültige Ereignis! + + + + These transactions can take up to 60 mins - DO NOT close this application! + Diese Transaktionen können bis zu 60 Minuten dauern - schließen Sie diese Anwendung NICHT! + + + + Same funds will be used until an order matches. + Die gleichen Geldmittel werden verwendet, bis eine Bestellung übereinstimmt. + + + + Note that if one order is filled other will not be cancelled. + Beachten Sie, dass, wenn eine Bestellung ausgeführt wird, andere nicht storniert werden. + + + + Cancel + Abbrechen + + + + Confirm + Bestätigen + + + + Placed multiple orders + Mehrere Aufrtäge aufgegeben + + + + ConfirmTradeModal + + + Confirm Exchange Details + Bestätigen Sie die Austausch-Details + + + + Trade price is more than 50% different to CEX! Confirm? + Der Handelspreis unterscheidet sich um mehr als 50% vom CEX-Preis. Bestätigen? + + + + This swap request can not be undone and is a final event! + Diese Tauschanfrage kann nicht rückgängig gemacht werden und ist ein endgültiges Ereignis! + + + + This transaction can take up to 60 mins - DO NOT close this application! + Diese Transaktion kann bis zu 60 Minuten dauern - schließen Sie diese Anwendung NICHT! + + + + Loading fees... + Lade Gebühren... + + + + <b>Total %1 fees:</b> + <b>Gesamt %1 Gebühren:</b> + + + + Security configuration + Sicherheitskonfiguration + + + + %1 confirmations for incoming %2 transactions + %1 Bestätigungen für eingehende %2 Transaktionen + + + + Read more about dPoW + Lesen Sie mehr über dPoW + + + + Use custom protection settings for incoming %1 transactions + TICKER + Benutzerdefinierte Schutzeinstellungen für eingehende %1 Transaktionen verwenden + + + + Enable Komodo dPoW security + Komodo dPoW-Sicherheit aktivieren + + + + dPoW protected + dPoW-gesichert + + + + Required Confirmations + Erforderliche Bestätigungen + + + + Warning, this atomic swap is not dPoW protected! + Achtung, dieser Atomic Swap ist nicht dPoW-geschützt! + + + + Cancel + Abbrechen + + + + Confirm + Bestätigen + + + + CopyFieldButton + + + Copied to Clipboard + In die Zwischenablage kopiert + + + + Dashboard + + + The current number of enabled coins does not match your configuration specification. Your assets configuration will be reset. + Die aktuelle Anzahl aktivierter Coins stimmt nicht mit Ihrer Konfigurationsvorgabe überein. Die Konfiguration der Assets wird zurückgesetzt. + + + + Matching + Zusammenführung + + + + Order Matching + Order wird zusammengeführt + + + + Matched + Zusammengeführt + + + + Order Matched + Order wurde zusammengeführt + + + + Ongoing + Laufend + + + + Swap Ongoing + Austausch läuft + + + + Successful + Erfolgreich + + + + Swap Successful + Tausch erfolgreich + + + + Refunding + Rückzahlung + + + + Failed + Fehlgeschlagen + + + + Swap Failed + Tausch fehlgeschlagen + + + + Unknown + Unbekannt + + + + Unknown State + Unbekannter Status + + + + Started + Gestartet + + + + Negotiated + Ausgehandelt + + + + Taker fee sent + Taker-Gebühr gesendet + + + + Maker payment received + Maker-Zahlung erhalten + + + + Maker payment wait confirm started + Warten auf die Zahlungsbestätigung des Makers gestartet + + + + Maker payment validated and confirmed + Maker-Zahlung validiert und bestätigt + + + + Taker payment sent + Taker-Zahlung gesendet + + + + Taker payment spent + Taker-Zahlung ausgegeben + + + + Maker payment spent + Maker-Zahlung ausgegeben + + + + Finished + Fertig + + + + Start failed + Start fehlgeschlagen + + + + Negotiate failed + Verhandeln fehlgeschlagen + + + + Taker fee validate failed + Validierung der Abnehmergebühr fehlgeschlagen + + + + Maker payment transaction failed + Maker-Zahlungstransaktion fehlgeschlagen + + + + Maker payment Data send failed + Fehler beim Senden der Maker-Zahlungsdaten + + + + Maker payment wait confirm failed + Warten auf die Zahlungsbestätigung des Makers fehlgeschlagen + + + + Taker payment validate failed + Validierung der Taker-Zahlung fehlgeschlagen + + + + Taker payment wait confirm failed + Warten auf die Zahlungsbestätigung des Takers fehlgeschlagen + + + + Taker payment spend failed + Zahlungsausgabe des Takers fehlgeschlagen + + + + Maker payment wait refund started + Countdown für die Rückerstattung der Maker-Zahlung hat begonnen + + + + Maker payment refunded + Maker-Zahlung zurückerstattet + + + + Maker payment refund failed + Rückerstattung der Maker-Zahlung fehlgeschlagen + + + + DatePicker + + + Date + Datum + + + + DefaultCopyIcon + + + copied to clipboard + In die Zwischenablage kopiert + + + + DefaultRangeSlider + + + Min + Min + + + + Max + Max + + + + DefaultTextEdit + + + copied to clipboard + In die Zwischenablage kopiert + + + + DeleteWalletModal + + + Delete Wallet + Brieftasche löschen + + + + Are you sure you want to delete %1 wallet? + WALLET_NAME + Sind Sie sicher, dass Sie die %1 Brieftasche löschen möchten? + + + + If so, make sure you record your seed phrase in order to restore your wallet in the future. + Wenn ja, stellen Sie sicher, dass Sie Ihre Seed-Phrase notieren, um Ihre Brieftasche in Zukunft wiederherzustellen. + + + + Enter your wallet password + Geben Sie das Kennwort für ihre Brieftasche ein + + + + Wrong Password + Falsches Kennwort + + + + Cancel + Abbrechen + + + + Delete + Löschen + + + + DexAppPasswordField + + + Type password + Kennwort eingeben + + + + DexKeyChecker + + + At least 1 lowercase alphabetical character + Mindestens 1 Kleinbuchstabe + + + + At least 1 uppercase alphabetical character + Mindestens 1 Großbuchstabe + + + + At least 1 numeric character + Mindestens 1 Ziffer + + + + At least 1 special character (eg. !@#$%) + Mindestens 1 Sonderzeichen (z. B. ! @ # $ %) + + + + Between %1 and %2 character(s) + + + + + Password and Confirm Password have to be same + Kennwort und Kennwortbestätigung müssen identisch sein + + + + DexPaginator + + + items per page + Elemente pro Seite + + + + DexRangeSlider + + + Min + Min + + + + Half + Halb + + + + Max + Max + + + + DexSweetComboBox + + + Search + Suchen + + + + EditContactModal + + + Edit contact + Kontakt bearbeiten + + + + Contact name + Kontaktname + + + + Enter a contact name + Geben Sie einen Kontaktnamen ein + + + + Address list + Adressliste + + + + Address Book + Adressbuch + + + + address copied to clipboard + Adresse in die Zwischenablage kopiert + + + + Edit + Bearbeiten + + + + + Add + + Hinzufügen + + + + Tags + Schlagworte + + + + Add tag + Schlagwort hinzufügen + + + + Cancel + Abbrechen + + + + Confirm + Bestätigen + + + + EnableAssetModal + + + The selected address belongs to a disabled asset, you need to enabled it before sending. + Die ausgewählte Adresse gehört zu einem deaktivierten Asset, Sie müssen es vor dem Senden aktivieren. + + + + Enable + Aktivieren + + + + Cancel + Abbrechen + + + + EnableCoinModal + + + Enable assets + Assets aktivieren + + + + Select all assets + Alle Assets auswählen + + + + All assets are already enabled! + Alle Assets sind bereits aktiviert! + + + + You can still enable %1 assets. Selected: %2. + Sie können weiterhin %1 Assets aktivieren. Ausgewählt: %2. + + + + Search asset + Asset suchen + + + + Change assets limit + Asset-Limit ändern + + + + Add a custom asset + Benutzerdefiniertes Asset hinzufügen + + + + Cancel + Abbrechen + + + + Enable + Aktivieren + + + + EulaModal + + + Disclaimer & Terms of Service + Haftungsausschluss & Nutzungsbedingungen + + + + Accept EULA + EULA akzeptieren + + + + Accept Terms and Conditions + Allgemeine Geschäftsbedingungen akzeptieren + + + + Close + Schließen + + + + Cancel + Abbrechen + + + + Confirm + Bestätigen + + + + FatalErrorModal + + + Fatal Error + Schwerwiegender Fehler + + + + Connection has been lost. You have been disconnected. + Die Verbindung wurde unterbrochen. Ihre Verbindung wurde getrennt. + + + + Close + Schließen + + + + FeeInfo + + + Minimum fee + Mindestgebühr + + + + Fees will be calculated + Gebühren werden berechnet + + + + GasInfoModal + + + How do I calculate gas? + + + + + Gas is measured in gwei. Gwei is just a unit of Ether, and is equal to 0.000000001 ETH (or the equivalent platform coin such as AVAX or BNB). The gas price varies over time depending on network congestion. + + + + + The gas limit is how many units of gas (maximum) you allocate to pay for a transaction. The gas required depending on the size of the transaction & data being transmitted. + + + + + A standard transaction not involving contracts uses 21,000 gas units, with any of the limit remaining returned to the source address. + + + + + Transactions involving contracts may result in the whole limit being consumed, so be careful not to set it too high. + + + + + For more information, read the article at <a href="https://support.mycrypto.com/how-to/sending/how-to-know-what-gas-limit-to-use">https://support.mycrypto.com/how-to/sending/how-to-know-what-gas-limit-to-use</a> + + + + + General + + + %n day(s) + + %n Tag + %n Tage + + + + + %nd + day + + + + + + + + %nh + hours + + + + + + + + %nm + minutes + + + + + + + + %ns + seconds + + + + + + + + %nms + milliseconds + + + + + + + + - + - + + + + <b>Taker tx fee:</b> + <b>Taker tx Gebühren:</b> + + + + <b>Dex tx fee:</b> + <b>Dex tx Gebühren:</b> + + + + <b>Dex fee:</b> + <b>Dex Gebühren:</b> + + + + <b>Maker tx fee:</b> + <b>Maker tx Gebühren:</b> + + + + 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 + + + + Header + + + You get + Du erhältst + + + + You send + Sie senden + + + + Fiat Price + Fiat Preis + + + + CEX rate + CEX-Kurs + + + + Price + Preis + + + + Quantity + Menge + + + + Total + Gesamt + + + + ImportWallet + + + Failed to Import the wallet + Fehler beim Importieren der Brieftasche + + + + Import wallet - Setup + Brieftasche importieren - Einrichtung + + + + Import wallet - Choose password + Brieftasche importieren - Kennwort wählen + + + + Wallet Name + Name der Brieftasche + + + + Enter seed + Geben Sie den Seed ein + + + + Your seed is not BIP39 compliant. +Try again or select 'Allow custom seed' to continue. + Ihr Seed ist nicht BIP39-konform. Versuchen Sie es erneut oder wählen Sie "benutzerdefinierten Seed erlauben" um fortzufahren + + + + + i understand + Ich verstehe + + + + + я согласен + + + + + + je comprends + + + + + + entiendo + + + + + + anladım + + + + + + ich verstehe + + + + + Ok + Ok + + + + Allow custom seed + Benutzerdefinierten Seed zulassen + + + + <strong>Allow custom seed</strong> + <strong>Benutzerdefinierten Seed zulassen</strong> + + + + Custom seed phrases might be less secure and easier to crack than a generated BIP39 compliant seed phrase or private key (WIF).<br><br>To confirm you understand the risk and know what you are doing, type <strong>'I understand'</strong> in the box below. + Benutzerdefinierte Seed-Phrasen sind möglicherweise weniger sicher und leichter zu knacken als eine generierte BIP39-konforme Seed-Phrase oder ein privater Schlüssel (WIF).<br><br>Um zu bestätigen, dass Sie das Risiko verstehen und wissen, was Sie tun, geben Sie bitte <strong>'Ich verstehe'</strong> in das Feld unten ein. + + + + I understand + Ich verstehe + + + + Next + Weiter + + + + Enter the same password to confirm + Geben Sie zur Bestätigung dasselbe Kennwort ein + + + + Continue + Fortsetzen + + + + LinksRow + + + Join our Discord server + Tritt unserem Discord-Server bei + + + + Follow us on Twitter + Folge uns auf Twitter + + + + Go to Support Guides + Zu den Support-Leitfäden + + + + List + + + Funds are recoverable + Geldmittel sind erstattungsfähig + + + + Best Orders + Die günstigsten Order + + + + Enter volume to see best orders. + + + + + ListDelegate + + + %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?<br><a href='#'>Yes</a> - <a href='#no'>No</a> + %1 ist nicht aktiviert - Möchten Sie es aktivieren, um die günstigsten Order von %2 auswählen zu können? <br><a href='#'>Ja</a> - <a href='#no'>Nein</a> + + + + This order requires a minimum amount of %1 %2 <br>You don't have enough funds.<br> %3 + Für diese Order ist ein Mindestbetrag von %1 %2 erforderlich. <br>Ihr Guthaben reicht nicht aus.<br> %3 + + + + LogModal + + + Close + Schließen + + + + Logging + + + Loading, please wait + Lädt, bitte warten + + + + Initializing MM2 + MM2 initialisieren + + + + Enabling assets + Assets ermöglichen + + + + Getting ready + Fertig werden + + + + Login + + + Incorrect Password + Falsches Kennwort + + + + Log In + Anmelden + + + + Cancel + Abbrechen + + + + LogoutModal + + + Exit %1 or go to login menu? + + + + + Warning: You currently have a swap in progress. +Logging out may result in a failed swap. + + + + + Warning: You currently have open maker orders. +They will be removed from the orderbook until you log in again. + + + + + Login menu + + + + + Exit + + + + + Cancel + Abbrechen + + + + Main + + + Segwit + Segwit + + + + Confirmation + Bestätigung + + + + Do you want to send your %1 funds to %2 wallet first? + Möchten Sie Ihr %1-Guthaben zuerst an die %2-Brieftasche senden? + + + + Success + Erfolg + + + + Your transaction is send, may take some time to arrive + Ihre Transaktion wird gesendet, es kann einige Zeit dauern, bis sie ankommt + + + + Price + Preis + + + + Change 24hr + 24h Veränderung + + + + Porfolio + Portfolio + + + + Contract Address + Vertragsadresse + + + + Send + Senden + + + + Enable %1 ? + %1 aktivieren? + + + + Yes + Ja + + + + No + Nein + + + + Receive + Empfangen + + + + Swap + Tausch + + + + is wallet only + nur Brieftasche (kein DEX möglich) + + + + Rewards + Belohnungen + + + + Faucet + Faucet + + + + + + Public Key + Öffentlicher Schlüssel + + + + Copied to Clipboard + In die Zwischenablage kopiert + + + + Loading market data + Laden von Marktdaten + + + + There is no chart data for this ticker yet + Für diesen Ticker liegen noch keine Chartdaten vor + + + + Fetching transactions... + Transaktionen werden abgerufen... + + + + Please wait, %1 is %2 + + + + + % activated... + + + + + No transactions available + Keine Transaktionen verfügbar + + + + Click to view your address on %1 (%2) block explorer + Klicken Sie hier, um Ihre Adresse im %1 (%2) Block-Explorer anzuzeigen + + + + Trade + Handeln + + + + Trading Information + Handelsinformationen + + + + Chart + Chart + + + + + Orders + Order + + + + + History + Historie + + + + Place Order + Order platzieren + + + + Order Selected + Order ausgewählt + + + + START SWAP + TAUSCH STARTEN + + + + + Address Book + Adressbuch + + + + Search contact + Kontakt suchen + + + + + NEW CONTACT + + Neuer Kontakt + + + + Name + Name + + + + Tags + Schlagworte + + + + Edit + Bearbeiten + + + + Delete + Löschen + + + + address copied to clipboard + Adresse in die Zwischenablage kopiert + + + + This contact does not have any registered address. + Dieser Kontakt hat keine registrierte Adresse. + + + + MarketModeSelector + + + Sell %1 + TICKER + %1 Verkaufen + + + + Buy %1 + TICKER + %1 Kaufen + + + + MinTradeModal + + + Minimum Trading Amount + Mindesthandelsbetrag + + + + the minimum amount of %1 coin available for the order; the min_volume must be greater than or equal to %2; it must be also less or equal than volume param; default is %3 + die Mindestmenge von %1 Coin, die für die Bestellung verfügbar ist; das min_volume muss größer oder gleich %2 sein; es muss auch kleiner oder gleich als volume param sein; Standard ist %3 + + + + MultiOrder + + + %1 price is zero! + TICKER + %1 Preis ist null! + + + + %1 receive volume is lower than minimum trade amount + TICKER + %1 Empfangsvolumen ist niedriger als der Mindesthandelsbetrag + + + + Error: + Fehler: + + + + You'll receive %1 + AMOUNT TICKER + Sie erhalten %1 + + + + Price + Preis + + + + NewContactPopup + + + Contact name + Kontaktname + + + + This contact name already exists. + Dieser Kontaktname existiert bereits. + + + + + ADD + + HINZUFÜGEN + + + + NewUpdateModal + + + + + Searching new updates + Suche nach neuen Updates + + + + Fetching... + Abrufen… + + + + + + + Close + Schließen + + + + Could not check new updates for the following reason: +%1 + Neue Updates konnten aus folgendem Grund nicht überprüft werden: %1 + + + + New version found + Neue Version gefunden + + + + Mandatory version found + Zwingend notwendige Version gefunden + + + + %1 %2 is available ! + %1 %2 ist verfügbar ! + + + + This update is mandatory to continue using the application + Dieses Update ist zwingend erforderlich, um die Anwendung weiterhin verwenden zu können + + + + Close Dex + Dex schließen + + + + Your application is updated. + Ihre Anwendung ist auf dem neuesten Stand. + + + + Download + Herunterladen + + + + NewWallet + + + Wrong word, please check again + Falsches Wort, bitte überprüfen Sie es erneut + + + + st + . + + + + nd + . + + + + rd + . + + + + th + . + + + + Failed to create a wallet + Anlegen einer Brieftasche ist fehlgeschlagen + + + + New Wallet + Neue Brieftasche + + + + Confirm Seed + Seed bestätigen + + + + Choose Password + Wählen sie ein Kennwort + + + + Important: Back up your seed phrase before proceeding! + Wichtig: Sichern Sie Ihre Seed-Phrase, bevor Sie fortfahren! + + + + We recommend storing it offline. + Wir empfehlen, sie offline zu speichern. + + + + Generated Seed + Generierter Seed + + + + Seed phrase + Seed Phrase + + + + copied to clipboard + In die Zwischenablage kopiert + + + + Next + Weiter + + + + Let's double check your seed phrase + Lassen Sie uns Ihre Seed-Phrase noch einmal überprüfen + + + + Your seed phrase is important - that's why we like to make sure it's correct. We'll ask you three different questions about your seed phrase to make sure you'll be able to easily restore your wallet whenever you want. + Ihre Seed-Phrase ist wichtig – deshalb stellen wir gerne sicher, dass sie korrekt ist. Wir stellen Ihnen drei verschiedene Fragen zu Ihrer Seed-Phrase, um sicherzustellen, dass Sie Ihre Wallet jederzeit problemlos wiederherstellen können. + + + + Enter the + Geben Sie das + + + + word + Wort ein + + + + Check + Prüfen + + + + Enter the same password to confirm + Geben Sie zur Bestätigung dasselbe Kennwort ein + + + + Continue + Fortsetzen + + + + NoConnection + + + No connection + Keine Verbindung + + + + Please make sure you are connected to the internet + Bitte stellen Sie sicher, dass Sie mit dem Internet verbunden sind + + + + Will automatically retry in %1 seconds + Wird in %1 Sekunde(n) automatisch erneut versucht + + + + Retry + Wiederholen + + + + NotificationsModal + + + Matching + Zusammenführung + + + + Order Matching + Order wird abgeglichen + + + + Matched + Abgestimmt + + + + Order Matched + Order wurde abgestimmt + + + + Ongoing + Läuft + + + + Swap Ongoing + Austausch läuft + + + + Successful + Erfolgreich + + + + Swap Successful + Tausch erfolgreich + + + + Refunding + Rückzahlung + + + + Failed + Fehlgeschlagen + + + + Swap Failed + Tausch fehlgeschlagen + + + + Unknown + Unbekannt + + + + Unknown State + Unbekannter Status + + + + Swap status updated + Austausch-Status aktualisiert + + + + You sent %1 + Sie %1 haben gesendet + + + + You received %1 + Sie %1 haben erhalten + + + + Your wallet balance changed + Ihr Guthaben hat sich geändert + + + + %1 Enable status + TICKER + + + + + Please check your internet connection (e.g. VPN service or firewall might block it). + Bitte überprüfen Sie Ihre Internetverbindung (z. B. könnte VPN-Dienst oder Firewall sie blockieren). + + + + Failed to enable %1 + TICKER + Aktivierung von %1 fehlgeschlagen + + + + + Failed to disable %1 + TICKER + + + + + + Endpoint not reachable + Endpunkt nicht erreichbar + + + + Could not reach to endpoint + Endpunkt konnte nicht erreicht werden + + + + Show + Zeigen + + + + Restart + Neustart + + + + Quit + Beenden + + + + Notifications + Benachrichtigungen + + + + There aren't any notifications + Es gibt keine Benachrichtigungen + + + + Mark all as read + Alle als gelesen makieren + + + + OrderForm + + + Price + Preis + + + + Reduce 1% relative to CEX market price. + + + + + Use CEX market price. + + + + + Increase 1% relative to CEX market price. + + + + + Volume + Volumen + + + + Amount to sell + Zu verkaufender Betrag + + + + Amount to receive + Zu erhaltender Betrag + + + + Max + Max + + + + Swap 25% of your tradable balance. + + + + + Swap 50% of your tradable balance. + + + + + Swap 100% of your tradable balance. + + + + + Min Volume + + + + + Min amount to sell + + + + + Min amount to receive + + + + + Minimum accepted trade equals 10% of order volume. + + + + + Minimum accepted trade equals 25% of order volume. + + + + + Minimum accepted trade equals 50% of order volume. + + + + + Min volume: + Mindestvolumen: + + + + Use custom minimum trade amount + Benutzerdefinierten Mindesthandelsbetrag verwenden + + + + OrderLine + + + Funds are recoverable + Geldmittel sind erstattungsfähig + + + + OrderList + + + No results found + Keine Ergebnisse gefunden + + + + OrderModal + + + Swap Details + Tauschdetails + + + + Order Details + Orderdetails + + + + Order Type + Orderart + + + + Maker Order + Maker-Order + + + + Taker Order + Taker-Order + + + + Refund State + Rückerstattungsstatus + + + + Your swap failed but the auto-refund process for your payment started already. Please wait and keep application opened until you receive your payment back + Ihr Umtausch ist fehlgeschlagen, aber der automatische Rückerstattungsprozess für Ihre Zahlung hat bereits begonnen. Bitte warten Sie und lassen Sie die Anwendung geöffnet, bis Sie Ihre Zahlung zurückerhalten + + + + Date + Datum + + + + Error ID + Fehler-ID + + + + + Error Log + Fehlerprotokoll + + + + Close + Schließen + + + + Cancel Order + Order Abbrechen + + + + + Swap ID + Swap ID + + + + Maker Payment Sent Transaction ID + Maker-Zahlung gesendet: Transaktions-ID + + + + Maker Payment Spent Transaction ID + Maker-Zahlung ausgegeben: Transaktions-ID + + + + Maker Payment TXID + Maker-Zahlung: TXID + + + + Taker Payment Spent Transaction ID + Taker-Zahlung ausgegeben: Transaktions-ID + + + + Taker Payment Sent Transaction ID + Taker-Zahlung gesendet: Transaktions-ID + + + + Taker Payment TXID + Taker-Zahlung: TXID + + + + Recover Funds + Rückerstattung der Geldmittel + + + + Refunding... + Rückzahlung… + + + + View on Explorer + Ansicht im Explorer + + + + OrderRemovedModal + + + Selected Order Removed + Ausgewählte Order entfernt + + + + The selected order does not exist anymore, it might have been matched or canceled, and no order with a better price is available. +Please select a new order. + Die ausgewählte Order existiert nicht mehr! Sie wurde möglicherweise zugeordnet oder storniert und es ist keine Order mit einem besseren Preis verfügbar. +Bitte wählen Sie eine neue Order aus. + + + + OK + OK + + + + OrdersPage + + + + Filter + Filter + + + + Date + Datum + + + + Export CSV + CSV exportieren + + + + Apply Filter + Filter anwenden + + + + Cancel All + Alles stornieren + + + + From + Von + + + + To + Bis + + + + Please choose the CSV export name and location + Bitte wählen Sie den CSV-Exportnamen und den Speicherort aus + + + + Pagination + + + items per page + Elemente pro Seite + + + + PasswordField + + + Password + Kennwort + + + + Enter your wallet password + Geben Sie das Kennwort für ihre Brieftasche ein + + + + At least 1 lowercase alphabetical character + Mindestens 1 Kleinbuchstabe + + + + At least 1 uppercase alphabetical character + Mindestens 1 Großbuchstabe + + + + At least 1 numeric character + Mindestens 1 Ziffer + + + + At least 1 special character (eg. !@#$%) + Mindestens 1 Sonderzeichen (z. B. ! @ # $ %) + + + + Between %1 and %2 character(s) + + + + + PasswordForm + + + Password + Kennwort + + + + Confirm Password + Kennwort bestätigen + + + + Enter the same password to confirm + Geben Sie zur Bestätigung dasselbe Kennwort ein + + + + Portfolio + + + ADD ASSET + ASSET HINZUFÜGEN + + + + Search asset + Asset suchen + + + + Show only coins with balance + Nur Coins mit Guthaben anzeigen + + + + (%1/%2) + (%1/%2) + + + + Portfolio + Portfolio + + + + PriceLine + + + Set swap price for evaluation + Legen Sie den Tausch-Preis für die Bewertung fest + + + + Exchange rate + Wechselkurs + + + + Selected + Ausgewählt + + + + Expensive + Teuer + + + + Expedient + Sinnvoll + + + + %1 compared to CEX + PRICE_DIFF% + %1 im Vergleich zu CEX + + + + CEXchange rate + CEX-Wechselkurs + + + + PriceLineSimplified + + + Exchange rate + Wechselkurs + + + + Selected + Ausgewählt + + + + CEXchange rate + CEX-Wechselkurs + + + + Expensive + Teuer + + + + Expedient + Sinnvoll + + + + %1 compared to CEX + PRICE_DIFF% + %1 im Vergleich zu CEX + + + + ProView + + + Failed to place the order + Die Order konnte nicht platziert werden + + + + Placed the order + Order platziert + + + + QObject + + + Cannot reach the endpoint: + Der Endpunkt kann nicht erreicht werden: + + + + ReceiveModal + + + Receive %1 + TICKER + + + + + Only send %1 to this address + TICKER + + + + + %1 address + TICKER + + + + + copied to clipboard. + In die Zwischenablage kopiert + + + + Close + Schließen + + + + RecoverSeedModal + + + + View seed and private keys + Seed- und privaten Schlüsseln anzeigen + + + + Please enter your password to view the seed. + Bitte geben Sie Ihr Kennwort ein, um den Seed anzuzeigen. + + + + Seed + Seed + + + + Backup Seed + Seed Sicherung + + + + Public Address copied to clipboard + Öffentliche Adresse in die Zwischenablage kopiert + + + + Cancel + Abbrechen + + + + Incorrect Password + Falsches Kennwort + + + + View + Ansehen + + + + + copied to clipboard + In die Zwischenablage kopiert + + + + + RPC Password + RPC Kennwort + + + + Search a coin. + Coin suchen. + + + + Public Address + Öffentliche Adresse + + + + Private Key copied to clipboard + Privater Schlüssel in die Zwischenablage kopiert + + + + Private Key + Privater Schlüssel + + + + RemoveContactPopup + + + Do you want to remove this contact ? + Möchten Sie diesen Kontakt entfernen? + + + + Yes + Ja + + + + No + Nein + + + + RestartModal + + + Applying the changes... + Übernehmen der Änderungen... + + + + Restarting the application. %1 + Neustart der Anwendung. %1 + + + + Restarting the application... + Neustart der Anwendung... + + + + RightClickMenu + + + Cut + Ausschneiden + + + + Copy + Kopieren + + + + Paste + Einfügen + + + + SearchField + + + Search + Suchen + + + + SendModal + + + Failed to send + Fehler beim Senden + + + + Prepare to send + Versandvorbereitung von + + + + Address of the recipient + Adresse des Empfängers + + + + Amount to send + Zu sendender Betrag + + + + Gas price + Gas Preis + + + + Cancel + Abbrechen + + + + Recipient's address + Empfängeradresse + + + + The address has to be mixed case. + Die Adresse muss Groß-/Kleinschreibung sein. + + + + Failed to Broadcast + + + + + Fix + Korrigieren + + + + MAX + MAX + + + + Fiat amount: Unavailable + Fiat-Betrag: Nicht verfügbar + + + + Fiat amount: %1 + Fiat-Betrag: %1 + + + + %1 amount: %2 + %1 Betrag: %2 + + + + Specify in Fiat + In Fiat angeben + + + + Specify in Crypto + In Krypto angeben + + + + Enable Custom Fees + Benutzerdefinierte Gebühren + + + + Enter the custom fee + Geben Sie die benutzerdefinierte Gebühr ein + + + + Gas Limit + Gas Limit + + + + Custom Fee can't be higher than the amount + Die benutzerdefinierten Gebühren dürfen nicht höher sein als der Betrag + + + + Not enough funds. + Nicht genug Geldmittel. + + + + + You have %1 + AMT TICKER + Sie haben %1 + + + + + Only use custom fees if you know what you are doing! + + + + + Prepare + Vorbereiten + + + + + Send + Senden + + + + %1 address + TICKER + + + + + copied to clipboard. + In die Zwischenablage kopiert + + + + Amount + Menge + + + + Fees + Gebühren + + + + Date + Datum + + + + Back + Zurück + + + + SendModalContactList + + + Select a contact with an %1 address + Wählen Sie einen Kontakt mit einer %1-Adresse aus + + + + Search for contacts... + Kontakte suchen... + + + + %1 addresses + %1 Adressen + + + + 1 address + 1 Adresse + + + + + Back + Zurück + + + + Choose an %1 address of %2 + Wählen Sie eine %1-Adresse von %2 + + + + Name + Name + + + + Address + Adresse + + + + SendResult + + + Transaction Complete! + Transaktion abgeschlossen! + + + + %1 txid + TICKER + + + + + + copied to clipboard. + In die Zwischenablage kopiert + + + + Recipient's address + Empfängeradresse + + + + %1 address + TICKER + + + + + Amount + Menge + + + + Fees + Gebühren + + + + Date + Datum + + + + Transaction Hash + Transaktions-Hash + + + + Close + Schließen + + + + View on Explorer + Ansicht im Explorer + + + + SettingModal + + + + Cancel + Abbrechen + + + + Settings + Einstellungen + + + + General + Allgemein + + + + Language + Sprache + + + + User Interface + Benutzeroberfläche + + + + Security + Sicherheit + + + + Enable Desktop Notifications + Desktop-Benachrichtigungen aktivieren + + + + Maximum number of enabled coins + Maximale Anzahl aktivierter Coins + + + + Logs + Protokolle + + + + Open Folder + Ordner öffnen + + + + 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 + + + + 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. + + + + 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 + + + + Sidebar + + + Search + Suchen + + + + Add asset + Asset hinzufügen + + + + SmartChartView + + + Loading market data + Laden von Marktdaten + + + + There is no chart data for this ticker yet + Für diesen Ticker liegen noch keine Chartdaten vor + + + + SubBestOrder + + + Token + Token + + + + Available Quantity + Verfügbare Menge + + + + Available Quantity (in %1) + Verfügbare Menge (in %1) + + + + Fiat Volume + Fiat Volumen + + + + CEX Rate + CEX-Kurs + + + + %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?<br><a href='#'>Yes</a> - <a href='#no'>No</a> + %1 ist nicht aktiviert - Möchten Sie es aktivieren, um die günstigsten Order von %2 auswählen zu können? <br><a href='#'>Ja</a> - <a href='#no'>Nein</a> + + + + SubCoinSelector + + + Token + Token + + + + Balance + Balance + + + + Balance Fiat + Fiat Balance + + + + No Selectable coin. + Kein wählbarer Coin. + + + + SubHistory + + + History + Historie + + + + Filter + Filter + + + + Date + Datum + + + + Close filtering options. + Filteroptionen schließen. + + + + Open filtering options. + Filteroptionen öffnen. + + + + Filter settings + Filtereinstellungen + + + + From + Von + + + + To + Bis + + + + Cancel + Abbrechen + + + + Apply filter + Filter anwenden + + + + Export + Exportieren + + + + Please choose the CSV export name and location + Bitte wählen Sie den CSV-Exportnamen und den Speicherort aus + + + + No results found + Keine Ergebnisse gefunden + + + + SubOrders + + + + Orders + Order + + + + Close filtering options. + Filteroptionen schließen. + + + + Filter + Filter + + + + Date + Datum + + + + Open filtering options. + Filteroptionen öffnen. + + + + Filter settings + Filtereinstellungen + + + + From + Von + + + + To + Bis + + + + Cancel + Abbrechen + + + + Apply filter + Filter anwenden + + + + No results found + Keine Ergebnisse gefunden + + + + SupportModal + + + Frequently Asked Questions + Häufig gestellte Fragen + + + + Do you store my private keys? + Speichern Sie meine privaten Schlüssel? + + + + No! %1 is non-custodial. We never store any sensitive data, including your private keys, seed phrases, or PIN. This data is only stored on the user’s device and never leaves it. You are in full control of your assets. + Nein! %1 hat keine Vormundschaft. Wir speichern niemals sensible Daten, einschließlich Ihrer privaten Schlüssel, Seed-Phrasen oder PINs. Diese Daten werden nur auf dem Gerät des Benutzers gespeichert und verlassen es nie. Sie haben die volle Kontrolle über Ihr Vermögen. + + + + How is trading on %1 different from trading on other DEXs? + Wie unterscheidet sich der Handel auf %1 vom Handel auf anderen DEXs? + + + + Other DEXs generally only allow you to trade assets that are based on a single blockchain network, use proxy tokens, and only allow placing a single order with the same funds. + +%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. + Bei anderen DEXs können Sie im Allgemeinen nur Assets handeln, die auf einem einzigen Blockchain-Netzwerk basieren, Proxy-Token verwenden und nur eine einzige Order mit denselben Geldmitteln aufgeben. + +%1 ermöglicht Ihnen den nativen Handel über zwei verschiedene Blockchain-Netzwerke ohne Proxy-Token. Sie können auch mehrere Order mit demselben Guthaben aufgeben. Sie können beispielsweise 0,1 BTC für KMD, QTUM oder VRSC verkaufen – die erste Order, die automatisch ausgeführt wird, storniert alle anderen Orders. + + + + 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? + + + + 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. + +The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. + +If you go offline, so will your orders, and any that are in progress will fail, leading to potential loss of trade / transaction fees, and a wait for the swap to timeout and issue a refund. It may also negatively affect your wallet's reputation score for future trade matching. + +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. + + + + How are the fees on %1 calculated? + Wie werden die Gebühren für %1 berechnet? + + + + There are two fee categories to consider when trading on %1. + +1. %1 charges approximately 0.13% (1/777 of trading volume but not lower than 0.0001) as the trading fee for taker orders, and maker orders have zero fees. + +2. Both makers and takers will need to pay normal network fees to the involved blockchains when making atomic swap transactions. + +Network fees can vary greatly depending on your selected trading pair. + Beim Handel von %1 sind zwei Gebührenkategorien zu berücksichtigen. + +1. %1 berechnet ungefähr 0,13 % (1/777 des Handelsvolumens, aber nicht weniger als 0,0001) als Handelsgebühr für Taker-Orders, Maker-Orders haben keine Gebühren. + +2. Sowohl Maker als auch Taker müssen normale Netzwerkgebühren an die beteiligten Blockchains zahlen, wenn sie Atomic-Swap-Transaktionen durchführen. + +Die Netzwerkgebühren können je nach ausgewähltem Handelspaar stark variieren. + + + + Do you provide user support? + Bieten Sie Benutzerunterstützung an? + + + + Yes! %1 offers support through the <a href="%2">%1 Discord server</a>. The team and the community are always happy to help! + Ja! %1 bietet Support über den <a href="%2">%1 Discord server</a>. Das Team und die Community helfen Euch gerne weiter! + + + + Who is behind %1? + Wer steckt hinter %1? + + + + %1 is developed by the Komodo team. Komodo is one of the most established blockchain projects working on innovative solutions like atomic swaps, Delayed Proof of Work, and an interoperable multi-chain architecture. + %1 wird vom Komodo-Team entwickelt. Komodo ist eines der etabliertesten Blockchain-Projekte, das an innovativen Lösungen wie Atomic Swaps, Delayed Proof of Work und einer interoperablen Multi-Chain-Architektur arbeitet. + + + + Is it possible to develop my own white-label exchange on %1? + Ist es möglich, meine eigene White-Label-Börse auf %1 zu entwickeln? + + + + Absolutely! You can read our developer documentation for more details or contact us with your partnership inquiries. Have a specific technical question? The %1 developer community is always ready to help! + Auf jeden Fall! Sie können unsere Entwicklerdokumentation für weitere Details lesen oder uns mit Ihren Partnerschaftsanfragen kontaktieren. Haben Sie eine spezielle technische Frage? Die %1-Entwicklercommunity ist immer bereit zu helfen! + + + + Which devices can I use %1 on? + Auf welchen Geräten kann ich %1 verwenden? + + + + %1 is available for mobile on both <a href="%2">Android and iPhone, and for desktop on Windows, Mac, and Linux</a> operating systems. + %1 ist auf Mobilgeräte für <a href="%2">Android und iPhone sowie auf dem Desktop für Windows, Mac und Linux</a> Betriebssystemen erhältlich. + + + + Compliance Info + Compliance-Informationen + + + + Due to regulatory and legal circumstances the citizens of certain jurisdictions including, but not limited to, the United States of America, Canada, Hong Kong, Israel, Singapore, Sudan, Austria, Iran and any other state, country or other jurisdiction that is embargoed by the United States of America or the European Union are not allowed to use this application. + Aufgrund regulatorischer und rechtlicher Umstände sind die Bürger bestimmter Gerichtsbarkeiten, einschließlich, aber nicht beschränkt auf, der Vereinigten Staaten von Amerika, Kanada, Hongkong, Israel, Singapur, Sudan, Österreich, Iran und alle anderen Staaten, Länder oder anderen Gerichtsbarkeiten, die mit einem Embargo von den Vereinigten Staaten von Amerika oder der Europäischen Union belegt sind, dürfen diese Anwendung nicht verwenden. + + + + Changelog + Änderungsprotokoll + + + + Open Logs Folder + Protokollordner öffnen + + + + SwapProgress + + + act + SHORT FOR ACTUAL TIME + tatsächlich + + + + est + SHORT FOR ESTIMATED + geschätzt + + + + Progress details + Fortschrittsdetails + + + + TextAreaWithTitle + + + Save + Speichern + + + + Edit + Bearbeiten + + + + TextEditWithCopy + + + copied to clipboard + In die Zwischenablage kopiert + + + + TextEditWithTitle + + + copied to clipboard + In die Zwischenablage kopiert + + + + TextFieldWithTitle + + + Required + Erforderlich + + + + Toast + + + Click here to see the details + Klicken Sie hier, um die Details anzuzeigen + + + + Trade + + + Swap + Tauschen + + + + Instant trading with best orders + Sofortiger Handel mit den besten Order + + + + Reset form + Formular zurücksetzen + + + + You have no tradable assets + Keine handelbaren Assets vorhanden + + + + From + Von + + + + Enter an amount + Betrag eingeben + + + + MAX + MAX + + + + To + Nach + + + + Pick an order + Order auswählen + + + + Price + Preis + + + + Better price found: %1. Updating forms. + Besseren Preis gefunden: %1. Formulare aktualisieren. + + + + Better price (%1) found but received quantity (%2) is lower than your current one (%3). Click here to update the selected order. + Besseren Preis (%1) gefunden, aber erhaltene Menge (%2) ist niedriger als Ihre aktuelle (%3). Klicken Sie hier, um den ausgewählte Order zu aktualisieren. + + + + %1 + %1 + + + + Tradable: + Handelbar: + + + + Min: %1 + Minimum: %1 + + + + Pick a coin + Wählen Sie einen Coin + + + + SWAP NOW + JETZT TAUSCHEN + + + + Failed to place the order + Die Order konnte nicht platziert werden + + + + Placed the order + Order platziert + + + + Entered amount must be superior than 0. + Der eingegebene Betrag muss größer als 0 sein. + + + + You must select an order. + Sie müssen eine Order auswählen. + + + + Entered amount is below the minimum required by this order: %1 + Der eingegebene Betrag liegt unter dem für diese Order erforderlichen Mindestbetrag: %1 + + + + + %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 + + + + %1 balance does not have enough funds to pay the gas of %2 transactions + Das Guthaben von %1 reicht nicht aus, um das Gas von %2 Transaktionen zu bezahlen + + + + No buy orders found for %1. + Keine Kauforder für %1 gefunden. + + + + You can check later or try to sell a different coin. + Sie können später nachsehen oder versuchen, einen anderen Coin zu verkaufen. + + + + Calculating fee estimate... + Geschätzten Gebühren werden berechnet... + + + + Total %1 fees: + %1 Gesamtgebühren: + + + + %2 (%3) + %2 (%3) + + + + TradeViewHeader + + + Pro View Settings + Pro-Ansicht Einstellungen + + + + Display Settings + Bildschirmeinstellungen + + + + Ticker Selectors + Ticker Selektoren + + + + Trading Information + Handelsinformationen + + + + Order Book + Orderbuch + + + + Best Orders + Beste Order + + + + Place Order + Order platzieren + + + + TransactionDetailsModal + + + Transaction Details + Transaktionsdetails + + + + Amount + Menge + + + + Fees + Gebühren + + + + Date + Datum + + + + Unconfirmed + Unbestätigt + + + + Transaction Hash + Transaktions-Hash + + + + Confirmations + Bestätigungen + + + + Block Height + Blockhöhe + + + + From + Von + + + + %1 txid + TICKER + + + + + copied to clipboard. + In die Zwischenablage kopiert + + + + From address + Von Adresse + + + + To + Nach + + + + To address + Nach Adresse + + + + Notes + Anmerkungen + + + + Close + Schließen + + + + View on Explorer + Ansicht im Explorer + + + + Transactions + + + Sent + Gesendet + + + + Received + Erhalten + + + + fees + Gebühren + + + + Unconfirmed + Unbestätigt + + + + UpdateInvalidChecksum + + + The downloaded update archive is corrupted ! + Das heruntergeladene Update-Archiv ist beschädigt! + + + + Vertical + + + Order Book + Orderbuch + + + + WalletsView + + + Welcome + Herzlich Willkommen + + + + New wallet + Neue Brieftasche + + + + Import wallet + Brieftasche importieren + + + + Search your wallets... + Brieftaschen durchsuchen ... + + + + My Wallets + Meine Brieftaschen + + + + No wallets found! + Keine Brieftaschen gefunden! + + + + + Delete + Löschen + + + + Enter password to confirm deletion of + Geben Sie das Kennwort ein, um das Löschen zu bestätigen + + + + wallet + Brieftasche + + + + Type password + Kennwort eingeben + + + + Cancel + Abbrechen + + + + + Wallet status + Status der Brieftasche + + + + wallet deleted successfully + Brieftasche erfolgreich gelöscht + + + + + Ok + Ok + + + + wallet password is incorrect + Kennwort der Brieftasche ist falsch + + + + ZcashParamsModal + + + %1 Activation Failed! + + + + + To activate ZHTLC coins, you need to download the Zcash Params. +This might take a few minutes... + + + + + Download params & enable coins + + + + + More Info + + + + + Close + Schließen + + + + atomic_dex::settings_page + + + An error has occurred. + + + + + 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 + + + + main + + + Logout + Abmelden + + + + Balance + Balance + + + diff --git a/atomic_defi_design/assets/languages/atomic_defi_en.ts b/atomic_defi_design/assets/languages/atomic_defi_en.ts index 9307dfb436..574da37ff9 100644 --- a/atomic_defi_design/assets/languages/atomic_defi_en.ts +++ b/atomic_defi_design/assets/languages/atomic_defi_en.ts @@ -2,560 +2,382 @@ - QPlatformTheme + AddAddressForm - &Yes - Yes + + Use standard network address + + + + + Label + + + + + This key already exists. + - &No - No + + Address + + + Cancel - Cancel + Cancel - AddCustomCoinModal - - Get the contract address from + + Convert - - Choose the asset type + + Edit + + + + + Add - - Type + + You need to enable %1 before adding this kind of address. - + + Enable + + + + + 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 - - 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 - + Enter the Coingecko ID - + Get the Coingecko ID - + Active - - + + Preview - + WARNING: Application will restart immidiately to apply the changes! - + Asset not found, please go back and make sure Contract Address is correct - + Config Fields - + Fetched Data - + Submit & Restart - AddressBook - - - Address Book - - + AddTagPopup - - Search a contact by name or tags + + Tag name - - New Contact + + Contact already has this tag. - - Name - - - - - Tags (first 6) - - - - - Actions - - - - - Edit - - - - - Remove - - - - - Do you want to remove this contact ? - - - - - Yes - Yes - - - - No + + + ADD - AddressBookAddContactAddressModal - - - Edit address entry - - - - - Create a new address - - - - - Selected wallet: %1 - - - - - NONE - - - - - Enter a name - - - - - This key already exists. - - - - - Enter the address - - - - - Validate - - - - - Cancel - Cancel - + AmountChart - - Convert + + Work in progress - AddressBookEditContactModal - - - Edit contact - - - - - Contact Name - - - - - Enter a contact name - - - - - Address List - - - - - Search for an address entry. - - - - - Type - - - - - Key - - - - - Address - - - - - Actions - - - - - New Address - - - - - Tags - - - - - + - - - - - Confirm - - - - - - Cancel - Cancel - - - - The selected address belongs to a disabled coin, you need to enabled it before sending. - - - - - Enable - - + App - - Cannot send to this address + + Recover Funds Result + + + AssetFromStandardSelector - - Your balance is empty + + Choose a valid - - Ok + + asset - - Remove address ? + + Search an asset - - Yes - Yes - - - - No + + Disabled - AddressBookNewContactCategoryModal - - - Add a new tag - - - - - Enter the tag name - - - - - This contact already has this tag - - + AssetPieChart - - Add + + Assets - - - Cancel - Cancel - - AddressBookNewContactModal + AssetsList - - Create a new contact + + Asset - - Enter the contact name + + Balance - - This contact name already exists. + + Fiat Balance - - Confirm + + Change 24h - - Cancel - Cancel - - - - AddressBookSendWalletSelector - - - Choose a valid + + Price - - coin + + Source - - - AddressBookWalletTypeListModal - - Select wallet type + + Activating: - - Search + + Price provider is: %1 - AmountChart + Bottom - - Work in progress + + Settings - - - App - - Recover Funds Result + + Support - - - AssetPieChart - - Assets + + Privacy - - - AssetsList - - Asset + + Disable Privacy? - - Balance + + Enter wallet password to confirm - - Change 24h + + Type password - - Price + + Confirm - - Source - + + Cancel + Cancel - - Price provider is: %1 + + Privacy status - - - Bottom - - Settings + + Privacy mode disabled successfully - - Support + + + Ok - - Privacy + + Wrong password! - - - BuyBox - - Buy + + wallet password is incorrect @@ -567,64 +389,51 @@ - + Camouflage Password is a secret password for emergency situations. - + Using it to login will display your balance lower than it actually is. - + Here you enter the suffix and at login you need to enter {real_password}{suffix} - + Password suffix - + Confirm pasword suffix - + Enter a password suffix - + Enter the same password suffix to confirm - + Cancel Cancel - + Save - - CandleStickChart - - - Loading market data - - - - - There is no chart data for this pair yet - - - CannotEnableCoinModal @@ -689,122 +498,134 @@ + + Chart + + + Loading market data + + + + + There is no chart data for this pair yet + + + ClaimRewardsModal - + Failed to prepare to claim rewards - + Claim your %1 reward? TICKER - + No UTXOs eligible for claiming - + Transaction fee is higher than the reward! - - You will receive %1 - AMT TICKER + + You will receive - + Refresh - + Read more about KMD active users rewards - + UTXO - + Amount - + Reward - + Accruing Start - + Accruing Stop - + Time Left - + Error - + Locktime is not set - + Locktime is less than the threshold - + UTXO height is greater than end of the era - + UTXO amount is less than 10 - + One hour did not pass yet - + Transaction is in mempool - + Unknown problem - + Cancel Cancel - + Confirm @@ -812,37 +633,55 @@ CoinMenu - + Disable %1 TICKER - + Disable and Delete %1 TICKER - + Disable all %1 assets - + Disable all assets + + + Disable 0 balance assets + + + + + ComboBoxWithSearchBar + + + Search + + Combo_fiat - + + Language + + + + Fiat - + Recommended: @@ -893,74 +732,83 @@ ConfirmTradeModal - + Confirm Exchange Details - + + Trade price is more than 50% different to CEX! Confirm? + + + + This swap request can not be undone and is a final event! - + This transaction can take up to 60 mins - DO NOT close this application! - - Total %1 fees: %2 (%3) + + Loading fees... - - Security configuration + + <b>Total %1 fees:</b> - - dPoW protected + + Security configuration - + %1 confirmations for incoming %2 transactions - - + Read more about dPoW - + Use custom protection settings for incoming %1 transactions TICKER - + Enable Komodo dPoW security - + + dPoW protected + + + + Required Confirmations - + Warning, this atomic swap is not dPoW protected! - + Cancel Cancel - + Confirm @@ -981,181 +829,197 @@ - + Matching - + Order Matching - + Matched - + Order Matched - + Ongoing - + Swap Ongoing - + Successful - + Swap Successful - + Refunding - + Failed - + Swap Failed - + Unknown - + Unknown State - + Started - + Negotiated - + Taker fee sent - + Maker payment received - + Maker payment wait confirm started - + Maker payment validated and confirmed - + Taker payment sent - + Taker payment spent - + Maker payment spent - + Finished - + Start failed - + Negotiate failed - + Taker fee validate failed - + Maker payment transaction failed - + Maker payment Data send failed - + Maker payment wait confirm failed - + Taker payment validate failed - + Taker payment wait confirm failed - + Taker payment spend failed - + Maker payment wait refund started - + Maker payment refunded - + Maker payment refund failed + + DatePicker + + + Date + + + + + DefaultCopyIcon + + + copied to clipboard + + + DefaultRangeSlider @@ -1164,8 +1028,16 @@ - - Max + + Max + + + + + DefaultTextEdit + + + copied to clipboard @@ -1211,7 +1083,7 @@ DexAppPasswordField - + Type password @@ -1219,35 +1091,32 @@ DexKeyChecker - + At least 1 lowercase alphabetical character - + At least 1 uppercase alphabetical character - + At least 1 numeric character - + At least 1 special character (eg. !@#$%) - - - At least %n character(s) - - - - + + + Between %1 and %2 character(s) + - + Password and Confirm Password have to be same @@ -1255,7 +1124,7 @@ DexPaginator - + items per page @@ -1281,55 +1150,136 @@ DexSweetComboBox - + Search - EnableCoinModal + EditContactModal - - Enable assets + + Edit contact + + + + + Contact name + + + + + Enter a contact name + + + + + Address list + + + + + Address Book + + + + + address copied to clipboard + + + + + Edit + + + + + + Add + + + + + Tags + + + + + Add tag + + + + + Cancel + Cancel + + + + Confirm + + + + + EnableAssetModal + + + The selected address belongs to a disabled asset, you need to enabled it before sending. + + + + + Enable - - Add a custom asset to the list + + Cancel + Cancel + + + + EnableCoinModal + + + Enable assets - + Select all assets - + All assets are already enabled! - + You can still enable %1 assets. Selected: %2. - + Search asset - + Change assets limit - - Close + + Add a custom asset - + + Cancel + Cancel + + + Enable @@ -1342,27 +1292,27 @@ - + Accept EULA - + Accept Terms and Conditions - + Close - + Cancel Cancel - + Confirm @@ -1388,20 +1338,53 @@ FeeInfo - + Minimum fee - + Fees will be calculated + + GasInfoModal + + + How do I calculate gas? + + + + + Gas is measured in gwei. Gwei is just a unit of Ether, and is equal to 0.000000001 ETH (or the equivalent platform coin such as AVAX or BNB). The gas price varies over time depending on network congestion. + + + + + The gas limit is how many units of gas (maximum) you allocate to pay for a transaction. The gas required depending on the size of the transaction & data being transmitted. + + + + + A standard transaction not involving contracts uses 21,000 gas units, with any of the limit remaining returned to the source address. + + + + + Transactions involving contracts may result in the whole limit being consumed, so be careful not to set it too high. + + + + + For more information, read the article at <a href="https://support.mycrypto.com/how-to/sending/how-to-know-what-gas-limit-to-use">https://support.mycrypto.com/how-to/sending/how-to-know-what-gas-limit-to-use</a> + + + General - + %n day(s) @@ -1409,7 +1392,7 @@ - + %nd day @@ -1418,7 +1401,7 @@ - + %nh hours @@ -1427,7 +1410,7 @@ - + %nm minutes @@ -1436,7 +1419,7 @@ - + %ns seconds @@ -1445,7 +1428,7 @@ - + %nms milliseconds @@ -1454,66 +1437,92 @@ - + - - + + <b>Taker tx fee:</b> + + + + + <b>Dex tx fee:</b> + + + + + <b>Dex fee:</b> + + + + + <b>Maker tx fee:</b> + + + + 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 @@ -1521,146 +1530,165 @@ Header - + You get - + You send - + Fiat Price - + CEX rate - Price - + Quantity - + Total - - History - - - Recent Swaps - - - ImportWallet - + Failed to Import the wallet - + Import wallet - Setup - + Import wallet - Choose password - + Wallet Name - + Enter seed - - BIP39 seed validation failed, try again or select 'Allow custom seed' + + Your seed is not BIP39 compliant. +Try again or select 'Allow custom seed' to continue. + + + + + + i understand + + + + + + я согласен + + + + + + je comprends + + + + + + entiendo + + + + + + anladım + + + + + + ich verstehe + + + + + Ok - + Allow custom seed - + <strong>Allow custom seed</strong> - + Custom seed phrases might be less secure and easier to crack than a generated BIP39 compliant seed phrase or private key (WIF).<br><br>To confirm you understand the risk and know what you are doing, type <strong>'I understand'</strong> in the box below. - I understand - - Enable - - - - + Next - + Enter the same password to confirm - + Continue - - Languages - - - Language - - - LinksRow - + Join our Discord server - + Follow us on Twitter - + Go to Support Guides @@ -1672,16 +1700,26 @@ Funds are recoverable + + + Best Orders + + + + + Enter volume to see best orders. + + ListDelegate - + %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?<br><a href='#'>Yes</a> - <a href='#no'>No</a> - + This order requires a minimum amount of %1 %2 <br>You don't have enough funds.<br> %3 @@ -1720,17 +1758,52 @@ Login - + Incorrect Password - - Connect + + Log In + + + + + Cancel + Cancel + + + + LogoutModal + + + Exit %1 or go to login menu? + + + + + Warning: You currently have a swap in progress. +Logging out may result in a failed swap. + + + + + Warning: You currently have open maker orders. +They will be removed from the orderbook until you log in again. + + + + + Login menu - + + Exit + + + + Cancel Cancel @@ -1738,128 +1811,140 @@ Main - + Segwit - + Confirmation - + Do you want to send your %1 funds to %2 wallet first? - + Success - + Your transaction is send, may take some time to arrive - - Wallet Balance + + Price - - Price + + Change 24hr - - Change 24h + + Porfolio - - Portfolio % + + Contract Address - + Send - + Enable %1 ? - + Yes Yes - + No - + Receive - + Swap - + + is wallet only + + + + Rewards - + Faucet - - Loading market data + + + + Public Key - - There is no chart data for this ticker yet + + Copied to Clipboard + + + + + Loading market data - - Loading + + There is no chart data for this ticker yet - - Scanning blocks for TX History... + + Fetching transactions... - - Syncing TX History... + + Please wait, %1 is %2 - - Refreshing + + % activated... - - No transactions + + No transactions available - - Fetching transactions + + Click to view your address on %1 (%2) block explorer @@ -1868,26 +1953,101 @@ + + Trading Information + + + + + Chart + + + + Orders + History + + + Place Order + + + + + Order Selected + + + + + START SWAP + + + + + + Address Book + + + + + Search contact + + + + + + NEW CONTACT + + + + + Name + + + + + Tags + + + + + Edit + + + + + Delete + + + + + address copied to clipboard + + + + + This contact does not have any registered address. + + MarketModeSelector - - Sell + + Sell %1 + TICKER - - Buy + + Buy %1 + TICKER @@ -1930,171 +2090,202 @@ - - Price + + Price + + + + + NewContactPopup + + + Contact name + + + + + This contact name already exists. + + + + + + ADD NewUpdateModal - - Searching new updates... + + + + Searching new updates - - Please wait while the application is finding a new update... You can close this modal if you want. + + Fetching... - - Already updated + + + + + Close - - %1 is already up-to-date ! + + Could not check new updates for the following reason: +%1 - - Close + + New version found - - New update detected ! + + Mandatory version found - - Do you want to update %1 from %2 to %3 ? + + %1 %2 is available ! - - Download + + This update is mandatory to continue using the application - - Remind me later + + Close Dex - - Download in progress... + + Your application is updated. - - Update downloaded + + Download + + + NewWallet - - Update has been successfully downloaded. Do you want to restart the application now ? + + Wrong word, please check again - - Restart now + + st - - Restart later + + nd - - - NewWallet - - Wrong word, please check again + + rd + + + + + th - + Failed to create a wallet - + New Wallet - + Confirm Seed - + Choose Password - + Important: Back up your seed phrase before proceeding! - + We recommend storing it offline. - + Generated Seed - + Seed phrase - + copied to clipboard - + Next - + Let's double check your seed phrase - + Your seed phrase is important - that's why we like to make sure it's correct. We'll ask you three different questions about your seed phrase to make sure you'll be able to easily restore your wallet whenever you want. - - - Enter the %n. word - - - - + + + Enter the + + + + + word + - + Check - + Enter the same password to confirm - + Continue @@ -2125,150 +2316,152 @@ NotificationsModal - + Matching - + Order Matching - + Matched - + Order Matched - + Ongoing - + Swap Ongoing - + Successful - + Swap Successful - + Refunding - + Failed - + Swap Failed - + Unknown - + Unknown State - + Swap status updated - + You sent %1 - + You received %1 - + Your wallet balance changed - - Please check your internet connection (e.g. VPN service or firewall might block it). - - - - - Failed to enable %1 + + %1 Enable status TICKER - - Endpoint not reachable + + Please check your internet connection (e.g. VPN service or firewall might block it). - - Could not reach to endpoint + + Failed to enable %1 + TICKER - - Mismatch at %1 custom asset configuration + + + Failed to disable %1 TICKER - - Application needs to be restarted for %1 custom asset. - TICKER + + + Endpoint not reachable - - Batch %1 failed. Reason: %2 + + Could not reach to endpoint - + Show - + Restart - + Quit - - There isn't any notification + + Notifications + + + + + There aren't any notifications - + Mark all as read @@ -2276,44 +2469,97 @@ OrderForm - + Price - + + Reduce 1% relative to CEX market price. + + + + + Use CEX market price. + + + + + Increase 1% relative to CEX market price. + + + + Volume - + Amount to sell - + Amount to receive - - Min volume: + + Max + + + + + Swap 25% of your tradable balance. + + + + + Swap 50% of your tradable balance. + + + + + Swap 100% of your tradable balance. + + + + + Min Volume + + + + + Min amount to sell + + + + + Min amount to receive + + + + + Minimum accepted trade equals 10% of order volume. + + + + + Minimum accepted trade equals 25% of order volume. - - How to use the pro-view slider ? + + Minimum accepted trade equals 50% of order volume. - - This slider is used to setup the order requirements you need. -Left slider: Sets the minimum amount required to process a trade. -Right slider: Sets the volume you want to trade. + + Min volume: - + Use custom minimum trade amount @@ -2321,7 +2567,7 @@ Right slider: Sets the volume you want to trade. OrderLine - + Funds are recoverable @@ -2329,7 +2575,7 @@ Right slider: Sets the volume you want to trade. OrderList - + No results found @@ -2337,97 +2583,114 @@ Right slider: Sets the volume you want to trade. OrderModal - + Swap Details - + Order Details - + + Order Type + + + + Maker Order - + Taker Order - + Refund State - + Your swap failed but the auto-refund process for your payment started already. Please wait and keep application opened until you receive your payment back - + Date - - ID + + Error ID - - Maker Payment Sent ID + + + Error Log - - Maker Payment Spent ID + + Close - - Taker Payment Spent ID + + Cancel Order - - Taker Payment Sent ID + + + Swap ID - - Error ID + + Maker Payment Sent Transaction ID - - Error Log + + Maker Payment Spent Transaction ID - - Close + + Maker Payment TXID - - Cancel Order + + Taker Payment Spent Transaction ID + + + + + Taker Payment Sent Transaction ID + + + + + Taker Payment TXID - + Recover Funds - + Refunding... - + View on Explorer @@ -2435,64 +2698,62 @@ Right slider: Sets the volume you want to trade. OrderRemovedModal - + Selected Order Removed - - The selected order does not exist anymore, it might have been matched or canceled, and no order with a better price is available. Please select a new order. + + The selected order does not exist anymore, it might have been matched or canceled, and no order with a better price is available. +Please select a new order. - + OK - - Orders - - - Orders - - - OrdersPage - - + + Filter - + Date - + Export CSV - + Apply Filter - + + Cancel All + + + + From - + To - + Please choose the CSV export name and location @@ -2500,7 +2761,7 @@ Right slider: Sets the volume you want to trade. Pagination - + items per page @@ -2508,42 +2769,39 @@ Right slider: Sets the volume you want to trade. PasswordField - + Password - + Enter your wallet password - + At least 1 lowercase alphabetical character - + At least 1 uppercase alphabetical character - + At least 1 numeric character - + At least 1 special character (eg. !@#$%) - - - At least %n character(s) - - - - + + + Between %1 and %2 character(s) + @@ -2567,66 +2825,66 @@ Right slider: Sets the volume you want to trade. Portfolio - + + ADD ASSET + + + + Search asset - + Show only coins with balance - + (%1/%2) - + Portfolio - - - Add asset - - PriceLine - + Set swap price for evaluation - + Exchange rate - + Selected - + Expensive - + Expedient - + %1 compared to CEX PRICE_DIFF% - + CEXchange rate @@ -2634,37 +2892,32 @@ Right slider: Sets the volume you want to trade. PriceLineSimplified - - Set swap price for evaluation - - - - + Exchange rate - + Selected - + CEXchange rate - + Expensive - + Expedient - + %1 compared to CEX PRICE_DIFF% @@ -2673,63 +2926,21 @@ Right slider: Sets the volume you want to trade. ProView - + Failed to place the order - + Placed the order + + + QObject - - Chart - - - - - Trading Information - - - - - Exchange Rates - - - - - Orders - - - - - History - - - - - Order Book - - - - - Best Orders - - - - - Place Order - - - - - START SWAP - - - - - Order Selected + + Cannot reach the endpoint: @@ -2737,27 +2948,29 @@ Right slider: Sets the volume you want to trade. ReceiveModal - Receive + Receive %1 + TICKER - + Only send %1 to this address TICKER - + %1 address + TICKER - - copied to clipboard + + copied to clipboard. - + Close @@ -2765,91 +2978,94 @@ Right slider: Sets the volume you want to trade. RecoverSeedModal - - + + View seed and private keys - + Please enter your password to view the seed. - - Wrong Password + + Seed - - Cancel - Cancel - - - - View + + Backup Seed - - Seed phrase + + Public Address copied to clipboard - - - - copied to clipboard - + + Cancel + Cancel - - RPC password + + Incorrect Password - - phrase key copied to clipboard + + View - - Backup seed + + + copied to clipboard - + + RPC Password - + Search a coin. - - %1 address + + Public Address - - %1 private key + + Private Key copied to clipboard - - Public Address + + Private Key + + + RemoveContactPopup - - Private Key + + Do you want to remove this contact ? - - Close + + Yes + Yes + + + + No @@ -2897,140 +3113,165 @@ Right slider: Sets the volume you want to trade. - - SellBox - - - Sell - - - SendModal - + Failed to send - - Failed to Send - - - - + Prepare to send - + Address of the recipient - + Amount to send - - Max amount + + Gas price - - Gas price - + + Cancel + Cancel - + Recipient's address - - Address Book + + The address has to be mixed case. - - The address has to be mixed case. + + Failed to Broadcast - + Fix - - Enable Custom Fees + + MAX + + + + + Fiat amount: Unavailable + + + + + Fiat amount: %1 + + + + + %1 amount: %2 + + + + + Specify in Fiat + + + + + Specify in Crypto - - Only use custom fees if you know what you are doing! + + Enable Custom Fees - + Enter the custom fee - + Gas Limit - + Custom Fee can't be higher than the amount - + Not enough funds. - + + You have %1 AMT TICKER - - Close + + + Only use custom fees if you know what you are doing! - + Prepare - - + + Send - + + %1 address + TICKER + + + + + copied to clipboard. + + + + Amount - + Fees - + Date - + Back @@ -3038,86 +3279,104 @@ Right slider: Sets the volume you want to trade. SendModalContactList - + Select a contact with an %1 address - + Search for contacts... - + %1 addresses - + 1 address - - + + Back - + Choose an %1 address of %2 - + Name - - Address + + Address + + + + + SendResult + + + Transaction Complete! + + + + + %1 txid + TICKER + + + + + + copied to clipboard. - - - SendResult - - Transaction Complete! + + Recipient's address - - Recipient's address + + %1 address + TICKER - + Amount - + Fees - + Date - + Transaction Hash - + Close - + View on Explorer @@ -3125,282 +3384,240 @@ Right slider: Sets the volume you want to trade. SettingModal - - Confirm Logout - - - - - Are you sure you want to log out? - - - - - Yes - Yes - - - - + + 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 - - + + Reset wallet configuration - + This will restart your wallet with default settings - + + Confirm - + Ask system's password before sending coins ? (2FA) - - View seed and private keys - - - - - - Show - - - - - Setup Camouflage Password - - - - - Open - - - - - Disclaimer and ToS - - - - - Application version - - - - - DEX Version + + Disable 2FA? - - DEX Version copied to clipboard. + + Enter your wallet password to confirm - - MM2 version + + Type password - - MM2 Version + + 2FA status - - MM2 Version copied to clipboard. + + 2FA disabled successfully - - Qt version + + + Ok - - Qt Version + + Wrong password! - - Qt Version copied to clipboard. + + Wallet password is incorrect - - Search Update + + View seed and private keys - - Logout + + + Show - - - Settings - - Fiat + + Setup Camouflage Password - - Recommended: + + Open - - Enable Desktop Notifications + + Disclaimer and ToS - - Use QtTextRendering Or NativeTextRendering + + Application version - - Open Logs Folder + + MM2 version - - View seed and private keys + + MM2 Version - - Disclaimer and ToS + + MM2 Version copied to clipboard. - - Setup Camouflage Password + + Qt version - - Reset wallet configuration + + Qt Version - - Delete Wallet + + Qt Version copied to clipboard. - - Log out + + Search Update - - mm2 version + + Logout Sidebar - - Search coin + + Search - + Add asset @@ -3421,32 +3638,32 @@ Right slider: Sets the volume you want to trade. SubBestOrder - + Token - + Available Quantity - + Available Quantity (in %1) - + Fiat Volume - + CEX Rate - + %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?<br><a href='#'>Yes</a> - <a href='#no'>No</a> @@ -3454,22 +3671,22 @@ Right slider: Sets the volume you want to trade. SubCoinSelector - + Token - + Balance - + Balance Fiat - + No Selectable coin. @@ -3512,32 +3729,32 @@ Right slider: Sets the volume you want to trade. - + To - + Cancel Cancel - + Apply filter - + Export - + Please choose the CSV export name and location - + No results found @@ -3546,250 +3763,240 @@ Right slider: Sets the volume you want to trade. SubOrders - + Orders - + Close filtering options. - + Filter - + Date - + Open filtering options. - + Filter settings - + From - + To - + Cancel Cancel - + Apply filter - + No results found - Support - - - Update available - - - - - Up to date - - - - - Changelog - - - - - Open Logs Folder - - + SupportModal - + Frequently Asked Questions - + Do you store my private keys? - + No! %1 is non-custodial. We never store any sensitive data, including your private keys, seed phrases, or PIN. This data is only stored on the user’s device and never leaves it. You are in full control of your assets. - + How is trading on %1 different from trading on other DEXs? - - Other DEXs generally only allow you to trade assets that are based on a single blockchain network, use proxy tokens, and only allow placing a single order with the same funds. + + Other DEXs generally only allow you to trade assets that are based on a single blockchain network, use proxy tokens, and only allow placing a single order with the same funds. %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. - + 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>. - + Do I need to be online for the duration of the swap? - + 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. + The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. + If you go offline, so will your orders, and any that are in progress will fail, leading to potential loss of trade / transaction fees, and a wait for the swap to timeout and issue a refund. It may also negatively affect your wallet's reputation score for future trade matching. + 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. - + How are the fees on %1 calculated? - + There are two fee categories to consider when trading on %1. 1. %1 charges approximately 0.13% (1/777 of trading volume but not lower than 0.0001) as the trading fee for taker orders, and maker orders have zero fees. + 2. Both makers and takers will need to pay normal network fees to the involved blockchains when making atomic swap transactions. Network fees can vary greatly depending on your selected trading pair. - + Do you provide user support? - + Yes! %1 offers support through the <a href="%2">%1 Discord server</a>. The team and the community are always happy to help! - - %1 is available for mobile on both <a href="%2">Android and iPhone, and for desktop on Windows, Mac, and Linux</a> operating systems. - - - - + Who is behind %1? - + %1 is developed by the Komodo team. Komodo is one of the most established blockchain projects working on innovative solutions like atomic swaps, Delayed Proof of Work, and an interoperable multi-chain architecture. - + Is it possible to develop my own white-label exchange on %1? - + Absolutely! You can read our developer documentation for more details or contact us with your partnership inquiries. Have a specific technical question? The %1 developer community is always ready to help! - + Which devices can I use %1 on? - + + %1 is available for mobile on both <a href="%2">Android and iPhone, and for desktop on Windows, Mac, and Linux</a> operating systems. + + + + Compliance Info - + Due to regulatory and legal circumstances the citizens of certain jurisdictions including, but not limited to, the United States of America, Canada, Hong Kong, Israel, Singapore, Sudan, Austria, Iran and any other state, country or other jurisdiction that is embargoed by the United States of America or the European Union are not allowed to use this application. + + + Changelog + + + + + Open Logs Folder + + SwapProgress - + act SHORT FOR ACTUAL TIME - + est SHORT FOR ESTIMATED - + Progress details - - SweetDexComboBox - - - Search - - - TextAreaWithTitle - + Save - + Edit - TextEditWithTitle + TextEditWithCopy - - Swap ID + + copied to clipboard + + + TextEditWithTitle - + copied to clipboard @@ -3797,7 +4004,7 @@ Network fees can vary greatly depending on your selected trading pair. TextFieldWithTitle - + Required @@ -3813,213 +4020,281 @@ Network fees can vary greatly depending on your selected trading pair. Trade - + Swap - + Instant trading with best orders - + + Reset form + + + + + You have no tradable assets + + + + From - + Enter an amount - + MAX - + To - + Pick an order - + Price - + Better price found: %1. Updating forms. - + Better price (%1) found but received quantity (%2) is lower than your current one (%3). Click here to update the selected order. - - Reset form. - - - - + %1 - + Tradable: - + Min: %1 - + Pick a coin - + SWAP NOW - + Failed to place the order - + Placed the order - + Entered amount must be superior than 0. - + You must select an order. - + Entered amount is below the minimum required by this order: %1 - - + + %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 - - - Search + + %1 balance does not have enough funds to pay the gas of %2 transactions - + No buy orders found for %1. - + You can check later or try to sell a different coin. - + + Calculating fee estimate... + + + + Total %1 fees: - + %2 (%3) + + TradeViewHeader + + + Pro View Settings + + + + + Display Settings + + + + + Ticker Selectors + + + + + Trading Information + + + + + Order Book + + + + + Best Orders + + + + + Place Order + + + TransactionDetailsModal - + Transaction Details - + + %1 txid + TICKER + + + + + copied to clipboard. + + + + Amount - + Fees - + + From address + + + + + To address + + + + Date - + Unconfirmed - + Transaction Hash - + Confirmations - + Block Height - + From - + To - + Notes - + Close - + View on Explorer @@ -4027,22 +4302,22 @@ Network fees can vary greatly depending on your selected trading pair. Transactions - + Sent - + Received - + fees - + Unconfirmed @@ -4056,15 +4331,10 @@ Network fees can vary greatly depending on your selected trading pair. - WalletNameField - - - Wallet Name - - + Vertical - - Enter the name of your wallet here + + Order Book @@ -4086,118 +4356,165 @@ Network fees can vary greatly depending on your selected trading pair. - + + Search your wallets... + + + + My Wallets - - + + No wallets found! + + + + + Delete - + Enter password to confirm deletion of - + wallet - + Type password - + Cancel Cancel - - + + Wallet status - + wallet deleted successfully - - + + Ok - + wallet password is incorrect + + ZcashParamsModal + + + %1 Activation Failed! + + + + + To activate ZHTLC coins, you need to download the Zcash Params. +This might take a few minutes... + + + + + Download params & enable coins + + + + + More Info + + + + + Close + + + + + atomic_dex::settings_page + + + An error has occurred. + + + 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 on the convert button to turn it into a mixed case address + + Invalid checksum for %1. Click the button to convert to mixed case address. - - Legacy address used for %1, click on the convert button to convert it to a Cashaddress. + + 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 @@ -4205,32 +4522,12 @@ Network fees can vary greatly depending on your selected trading pair. main - + Logout - - Confirm Logout - - - - - Are you sure you want to log out? - - - - - Yes - Yes - - - - Cancel - Cancel - - - + Balance diff --git a/atomic_defi_design/assets/languages/atomic_defi_es.ts b/atomic_defi_design/assets/languages/atomic_defi_es.ts new file mode 100644 index 0000000000..c2b1055f75 --- /dev/null +++ b/atomic_defi_design/assets/languages/atomic_defi_es.ts @@ -0,0 +1,4556 @@ + + + + + AddAddressForm + + + Use standard network address + Utilice la dirección de red + + + + Label + Etiqueta + + + + This key already exists. + Esta clave ya existe. + + + + Address + Dirección + + + + + Cancel + Cancelar + + + + Convert + Convertir + + + + Edit + Editar + + + + Add + Agregar + + + + You need to enable %1 before adding this kind of address. + Debe habilitar %1 antes de agregar este tipo de dirección. + + + + Enable + Habilitar + + + + 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! + + + + 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 + + + + AddTagPopup + + + Tag name + Nombre de la etiqueta + + + + Contact already has this tag. + El contacto ya tiene esta etiqueta. + + + + + ADD + + Añadir + + + + AmountChart + + + Work in progress + Trabajo en proceso + + + + App + + + Recover Funds Result + Resultados de Recuperar Fondos + + + + AssetFromStandardSelector + + + Choose a valid + Elija un + + + + asset + activo + + + + Search an asset + Buscar un activo + + + + Disabled + deshabilitados + + + + AssetPieChart + + + Assets + Activos + + + + AssetsList + + + Asset + Activo + + + + Balance + Saldo + + + + Fiat Balance + Saldo Fiat + + + + Change 24h + Cambio en 24h + + + + Price + Precio + + + + Source + Fuente + + + + Activating: + Activando: + + + + Price provider is: %1 + El proveedor de precios es: %1 + + + + Bottom + + + Settings + Configuración + + + + Support + Soporte + + + + Privacy + Privacidad + + + + Disable Privacy? + ¿Deshabilitar privacidad? + + + + Enter wallet password to confirm + Ingrese la contraseña de la billetera para confirmar + + + + Type password + Escriba la contraseña + + + + Confirm + Confirmar + + + + Cancel + Cancelar + + + + Privacy status + Estado de privacidad + + + + Privacy mode disabled successfully + Modo de privacidad deshabilitado correctamente + + + + + Ok + Ok + + + + Wrong password! + ¡Contraseña incorrecta! + + + + wallet password is incorrect + la contraseña de la billetera es incorrecta + + + + CamouflagePasswordModal + + + Setup Camouflage Password + Configuración de Contraseña Camuflaje + + + + Camouflage Password is a secret password for emergency situations. + Contraseña Camuflaje es una contraseña secreta para situaciones de emergencia. + + + + Using it to login will display your balance lower than it actually is. + Usarlo para iniciar sesión mostrará su saldo más bajo de lo que realmente es. + + + + Here you enter the suffix and at login you need to enter {real_password}{suffix} + Aquí ingresa el sufijo y al iniciar sesión debe ingresar {real_password}{suffix} + + + + Password suffix + Sufijo de contraseña + + + + Confirm pasword suffix + Confirmar sufijo + + + + Enter a password suffix + Ingrese un sufijo de contraseña + + + + Enter the same password suffix to confirm + Ingrese el mismo sufijo de contraseña para confirmar + + + + Cancel + Cancelar + + + + Save + Guardar + + + + CannotEnableCoinModal + + + Failed to enable %1 + No se pudo habilitar %1 + + + + Enabling %1 did not succeed. Limit of enabled coins might have been reached. + No se pudo habilitar %1. Es posible que se haya alcanzado el límite de monedas habilitadas. + + + + Change limit in settings + Cambiar el límite en la configuración + + + + Cancel + Cancelar + + + + Center + + + Portfolio + Cartera + + + + Wallet + Monedero + + + + DEX + DEX + + + + Address Book + Directorio + + + + Fiat + Fiat + + + + CexInfoModal + + + Market Data + Data de Mercado + + + + Market data (prices, charts, etc.) marked with the ⓘ icon originates from third-party sources.<br><br>Data is sourced via <a href="https://bandprotocol.com/">Band Decentralized Oracle</a> and <a href="https://coingecko.com">CoinGecko</a>.<br><br><b>Oracle Supported Pairs:</b><br>%1<br><br><b>Last reference (Band Oracle):</b><br><a href="%2">%2</a> + Datos de mercado (precios, estadisticas, etc.) marcados con ⓘ se obtienen a través de fuentes terceras.<br><br>Data is sourced via <a href="https://bandprotocol.com/">Band Decentralized Oracle</a> and <a href="https://coingecko.com">CoinGecko</a>.<br><br><b>Oracle Supported Pairs:</b><br>%1<br><br><b>Last reference (Band Oracle):</b><br><a href="%2">%2</a> + + + + Chart + + + Loading market data + Cargando datos de mercado + + + + There is no chart data for this pair yet + Todavía no hay datos de gráficos para este par + + + + ClaimRewardsModal + + + Failed to prepare to claim rewards + No se pudo preparar para reclamar recompensas + + + + Claim your %1 reward? + TICKER + ¿Reclamar su %1 de recompensa? + + + + No UTXOs eligible for claiming + Ningún UTXO elegible para reclamar + + + + Transaction fee is higher than the reward! + ¡La tarifa de transacción es más alta que la recompensa! + + + + You will receive + Recibirá + + + + Refresh + Actualizar + + + + Read more about KMD active users rewards + Lea más sobre las recompensas de los usuarios activos de KMD + + + + UTXO + UTXO + + + + Amount + Cantidad + + + + Reward + Recompensa + + + + Accruing Start + Inicio de Acumulación + + + + Accruing Stop + Detener Acumulación + + + + Time Left + Tiempo Restante + + + + Error + Error + + + + Locktime is not set + Locktime no está configurado + + + + Locktime is less than the threshold + Locktime es inferior al umbral + + + + UTXO height is greater than end of the era + La altura de UTXO es mayor que el final de la era + + + + UTXO amount is less than 10 + La cantidad de UTXO es inferior a 10 + + + + One hour did not pass yet + Una hora no pasa aún + + + + Transaction is in mempool + La transacción está en el mempool + + + + Unknown problem + Problema desconocido + + + + Cancel + Cancelar + + + + Confirm + Confirmar + + + + CoinMenu + + + Disable %1 + TICKER + Deshabilitar %1 + + + + Disable and Delete %1 + TICKER + Deshabilitar y eliminar %1 + + + + Disable all %1 assets + Deshabilitar todos los activos de %1 + + + + Disable all assets + Deshabilitar todos los activos + + + + Disable 0 balance assets + Deshabilitar 0 balancear activos + + + + ComboBoxWithSearchBar + + + Search + Buscar + + + + Combo_fiat + + + Language + Idioma + + + + Fiat + Fiat + + + + Recommended: + Recomendado: + + + + ConfirmMultiOrderTradeModal + + + Confirm Multi Order Details + Confirmar detalles de Multi Order + + + + These swaps requests can not be undone and this is the final event! + Estas solicitudes de intercambio no se pueden deshacer y este es el evento final! + + + + These transactions can take up to 60 mins - DO NOT close this application! + Estas transacciones pueden demorar hasta 60 minutos. ¡NO cierre esta aplicación! + + + + Same funds will be used until an order matches. + Se utilizarán los mismos fondos hasta que coincida un pedido. + + + + Note that if one order is filled other will not be cancelled. + Tenga en cuenta que si se completa un pedido, el otro no se cancelará. + + + + Cancel + Cancelar + + + + Confirm + Confirmar + + + + Placed multiple orders + Pedidos múltiples realizados + + + + ConfirmTradeModal + + + Confirm Exchange Details + Confirmar Detalles de Intercambio + + + + Trade price is more than 50% different to CEX! Confirm? + ¡El precio comercial es más del 50% diferente al de CEX! ¿Confirmar? + + + + This swap request can not be undone and is a final event! + ¡Esta solicitud de intercambio no se puede deshacer y es un evento final! + + + + This transaction can take up to 60 mins - DO NOT close this application! + Esta transacción puede demorar hasta 60 minutos. ¡NO cierre esta aplicación! + + + + Loading fees... + Cargando tarifas... + + + + <b>Total %1 fees:</b> + <b>Cuota total de %1:</b> + + + + Security configuration + Configuración de seguridad + + + + %1 confirmations for incoming %2 transactions + %1 confirmaciones para %2 transacciones entrantes + + + + Read more about dPoW + Obtenga más información sobre dPoW + + + + Use custom protection settings for incoming %1 transactions + TICKER + Utilice configuraciones de protección personalizadas para %1 transacciones entrantes + + + + Enable Komodo dPoW security + Habilite la seguridad dPoW de Komodo + + + + dPoW protected + Protegido por dPoW + + + + Required Confirmations + Confirmaciones Requeridas + + + + Warning, this atomic swap is not dPoW protected! + Advertencia, este intercambio atómico no está protegido por dPoW! + + + + Cancel + Cancelar + + + + Confirm + Confirmar + + + + CopyFieldButton + + + Copied to Clipboard + Copiada en el Portapapeles + + + + Dashboard + + + The current number of enabled coins does not match your configuration specification. Your assets configuration will be reset. + El número actual de monedas habilitadas no coincide con su especificación de configuración. Se restablecerá la configuración de sus activos. + + + + Matching + Emparejando + + + + Order Matching + Emparejando Orden + + + + Matched + Emparejado + + + + Order Matched + Orden Emparejada + + + + Ongoing + En Curso + + + + Swap Ongoing + Intercambio En Curso + + + + Successful + Exitoso + + + + Swap Successful + Intercambio exitoso + + + + Refunding + Reembolso + + + + Failed + Fallo + + + + Swap Failed + Intercambio fallido + + + + Unknown + Desconocido + + + + Unknown State + Estado Desconocido + + + + Started + Iniciado + + + + Negotiated + Negociado + + + + Taker fee sent + Tarifa taker enviada + + + + Maker payment received + Pago de maker recibido + + + + Maker payment wait confirm started + Inicio de espera de confirmacion de pago de maker + + + + Maker payment validated and confirmed + Validacion y confirmacion de pago de maker + + + + Taker payment sent + Pago de taker enviado + + + + Taker payment spent + Pago del taker gastado + + + + Maker payment spent + Pago del maker gastado + + + + Finished + Terminado + + + + Start failed + Inicio fallido + + + + Negotiate failed + Negociacion fallida + + + + Taker fee validate failed + Validación de tarifa del taker fallida + + + + Maker payment transaction failed + Transacción de pago de maker fallo + + + + Maker payment Data send failed + Envio de data de pago de maker fallo + + + + Maker payment wait confirm failed + Espera de confirmacion de pago de maker fallo + + + + Taker payment validate failed + Validacion de pago de taker fallo + + + + Taker payment wait confirm failed + Espera de confirmacion de pago de taker fallo + + + + Taker payment spend failed + Gasto de pago de taker fallo + + + + Maker payment wait refund started + Reembolso de espera de pago de maker iniciado + + + + Maker payment refunded + Pago de maker reembolsado + + + + Maker payment refund failed + Reembolso del pago de maker fallo + + + + DatePicker + + + Date + Fecha + + + + DefaultCopyIcon + + + copied to clipboard + copiado al portapapeles + + + + DefaultRangeSlider + + + Min + Min + + + + Max + Max + + + + DefaultTextEdit + + + copied to clipboard + copiado al portapapeles + + + + DeleteWalletModal + + + Delete Wallet + Eliminar billetera + + + + Are you sure you want to delete %1 wallet? + WALLET_NAME + ¿Está seguro de que desea eliminar %1 billetera? + + + + If so, make sure you record your seed phrase in order to restore your wallet in the future. + Si es así, asegúrese de registrar su frase inicial para restaurar su billetera en el futuro. + + + + Enter your wallet password + Ingrese la contraseña de su billetera + + + + Wrong Password + Contraseña incorrecta + + + + Cancel + Cancelar + + + + Delete + Eliminar + + + + DexAppPasswordField + + + Type password + Escriba la contraseña + + + + DexKeyChecker + + + At least 1 lowercase alphabetical character + Al menos 1 carácter alfabético en minúsculas + + + + At least 1 uppercase alphabetical character + Al menos 1 carácter alfabético en mayúsculas + + + + At least 1 numeric character + Al menos 1 carácter numérico + + + + At least 1 special character (eg. !@#$%) + Al menos 1 carácter especial ( ej., !@#$%) + + + + Between %1 and %2 character(s) + Entre %1 y %2 carácter(es) + + + + Password and Confirm Password have to be same + Contraseña y Confirmar Contraseña tienen que ser los mismos + + + + DexPaginator + + + items per page + elementos por página + + + + DexRangeSlider + + + Min + Min + + + + Half + Mitad + + + + Max + Max + + + + DexSweetComboBox + + + Search + Buscar + + + + EditContactModal + + + Edit contact + Editar contacto + + + + Contact name + Nombre + + + + Enter a contact name + Ingresar un nombre de contacto + + + + Address list + Lista de direcciónes + + + + Address Book + Libreta de direcciones + + + + address copied to clipboard + dirección copiada al portapapeles + + + + Edit + Editar + + + + + Add + + Añadir + + + + Tags + Etiquetas + + + + Add tag + Agregar etiqueta + + + + Cancel + Cancelar + + + + Confirm + Confirmar + + + + EnableAssetModal + + + The selected address belongs to a disabled asset, you need to enabled it before sending. + La dirección seleccionada pertenece a un activo deshabilitado, debe habilitó antes de enviar. + + + + Enable + Habilitar + + + + Cancel + Cancelar + + + + EnableCoinModal + + + Enable assets + Habilitar activos + + + + Select all assets + Seleccionar todos los activos + + + + All assets are already enabled! + ¡Todos los activos ya están habilitados! + + + + You can still enable %1 assets. Selected: %2. + Todavía puede habilitar activos %1. Seleccionado: %2. + + + + Search asset + Buscar activo + + + + Change assets limit + Cambiar el límite de activos + + + + Add a custom asset + Agregar un activo personalizado + + + + Cancel + Cancelar + + + + Enable + Habilitar + + + + EulaModal + + + Disclaimer & Terms of Service + Descargo de Responsabilidad & Términos de servicio + + + + Accept EULA + Aceptar EULA + + + + Accept Terms and Conditions + Aceptar términos y condiciones + + + + Close + Cerrar + + + + Cancel + Cancelar + + + + Confirm + Confirmar + + + + FatalErrorModal + + + Fatal Error + Error Fatal + + + + Connection has been lost. You have been disconnected. + Ha perdido la conexión. Has sido desconectado. + + + + Close + Cerrar + + + + FeeInfo + + + Minimum fee + Tarifa mínima + + + + Fees will be calculated + Las tarifas se calcularán + + + + GasInfoModal + + + How do I calculate gas? + ¿Cómo calculo la gasolina? + + + + Gas is measured in gwei. Gwei is just a unit of Ether, and is equal to 0.000000001 ETH (or the equivalent platform coin such as AVAX or BNB). The gas price varies over time depending on network congestion. + El gas se mide en gwei. Gwei es solo una unidad de Ether y es igual a 0.000000001 ETH (o la moneda de plataforma equivalente como AVAX o BNB). El precio del gas varía con el tiempo dependiendo de la congestión de la red. + + + + The gas limit is how many units of gas (maximum) you allocate to pay for a transaction. The gas required depending on the size of the transaction & data being transmitted. + + + + + A standard transaction not involving contracts uses 21,000 gas units, with any of the limit remaining returned to the source address. + Una transacción estándar que no implica contratos utiliza 21.000 unidades de gas, y el límite restante se devuelve a la dirección de origen. + + + + Transactions involving contracts may result in the whole limit being consumed, so be careful not to set it too high. + Las transacciones que involucran contratos pueden resultar en que se consuma todo el límite, así que tenga cuidado de no establecerlo demasiado alto. + + + + For more information, read the article at <a href="https://support.mycrypto.com/how-to/sending/how-to-know-what-gas-limit-to-use">https://support.mycrypto.com/how-to/sending/how-to-know-what-gas-limit-to-use</a> + Para obtener más información, lea el artículo en <a href="https://support.mycrypto.com/how-to/sending/how-to-know-what-gas-limit-to-use">https://support.mycrypto.com/how-to/sending/how-to-know-what-gas-limit-to-use</a> + + + + General + + + %n day(s) + + %n día + %n días + + + + + %nd + day + + + + + + + + %nh + hours + + + + + + + + %nm + minutes + + + + + + + + %ns + seconds + + + + + + + + %nms + milliseconds + + + + + + + + - + - + + + + <b>Taker tx fee:</b> + <b>Cuota de tx del taker:</b> + + + + <b>Dex tx fee:</b> + <b>Cuota de tx del Dex:</b> + + + + <b>Dex fee:</b> + <b>Cuota Dex:</b> + + + + <b>Maker tx fee:</b> + <b>Cuota tx del maker:</b> + + + + 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 + + + + Header + + + You get + Obtienes + + + + You send + Envía + + + + Fiat Price + Precio Fiat + + + + CEX rate + Tasa CEX + + + + Price + Precio + + + + Quantity + Cantidad + + + + Total + Total + + + + ImportWallet + + + Failed to Import the wallet + No se pudo importar la billetera + + + + Import wallet - Setup + Importar billetera - Configurar + + + + Import wallet - Choose password + Importar billetera - Elegir contraseña + + + + Wallet Name + Nombre de billetera + + + + Enter seed + Ingresar semilla + + + + Your seed is not BIP39 compliant. +Try again or select 'Allow custom seed' to continue. + Su semilla no cumple con BIP39. +Vuelva a intentarlo o seleccione 'Permitir semilla personalizada' personalizada continúe. + + + + + i understand + entiendo + + + + + я согласен + + + + + + je comprends + + + + + + entiendo + + + + + + anladım + + + + + + ich verstehe + + + + + Ok + Ok + + + + Allow custom seed + Permitir semilla personalizada + + + + <strong>Allow custom seed</strong> + <strong>Permitir semilla personalizada</strong> + + + + Custom seed phrases might be less secure and easier to crack than a generated BIP39 compliant seed phrase or private key (WIF).<br><br>To confirm you understand the risk and know what you are doing, type <strong>'I understand'</strong> in the box below. + Las frases semilla personalizadas pueden ser menos seguras y más fáciles de descifrar que una frase semilla o clave privada (WIF) compatible con BIP39.<br><br>Para confirmar que comprende el riesgo y sabe lo que está haciendo, escriba <strong> 'Entiendo'</strong> en el cuadro de abajo. + + + + I understand + Entiendo + + + + Next + Siguiente + + + + Enter the same password to confirm + Ingrese la misma contraseña para confirmar + + + + Continue + Continuar + + + + LinksRow + + + Join our Discord server + Únase a nuestro servidor de Discord + + + + Follow us on Twitter + Síganos en Twitter + + + + Go to Support Guides + Ir a Guías de soporte + + + + List + + + Funds are recoverable + Los fondos son recuperables + + + + Best Orders + Mejores Ordenes + + + + Enter volume to see best orders. + Introduce el volumen para ver los mejores ordenes + + + + ListDelegate + + + %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?<br><a href='#'>Yes</a> - <a href='#no'>No</a> + %1 no está habilitado. ¿Desea habilitarlo para poder seleccionar %2 mejores ordenes?<br><a href='#'>Sí</a> - <a href='#no'>No</a> + + + + This order requires a minimum amount of %1 %2 <br>You don't have enough funds.<br> %3 + Este pedido requiere una cantidad mínima de %1 %2 <br>No tiene fondos suficientes.<br> %3 + + + + LogModal + + + Close + Cerrar + + + + Logging + + + Loading, please wait + Cargando, por favor espere + + + + Initializing MM2 + Inicializando MM2 + + + + Enabling assets + Habilitando activos + + + + Getting ready + Preparándose + + + + Login + + + Incorrect Password + Contraseña incorrecta + + + + Log In + Iniciar sesión + + + + Cancel + Cancelar + + + + LogoutModal + + + Exit %1 or go to login menu? + Salga de %1 o vaya al menú de inicio de sesión + + + + Warning: You currently have a swap in progress. +Logging out may result in a failed swap. + Advertencia: actualmente tiene una operación en curso. +Cerrar sesión puede resultar en una transacción fallida. + + + + Warning: You currently have open maker orders. +They will be removed from the orderbook until you log in again. + Advertencia: actualmente tiene órdenes abiertas. +Se eliminarán del libro de pedidos hasta que vuelva a iniciar sesión. + + + + Login menu + Menú de inicio de sesión + + + + Exit + Dejar + + + + Cancel + Cancelar + + + + Main + + + Segwit + Segwit + + + + Confirmation + Confirmación + + + + Do you want to send your %1 funds to %2 wallet first? + ¿Desea enviar sus fondos de %1 a la billetera %2 primero? + + + + Success + Éxito + + + + Your transaction is send, may take some time to arrive + Su transacción se envió, puede demorar algún tiempo en llegar + + + + Price + Precio + + + + Change 24hr + Cambio + + + + Porfolio + Cartera + + + + Contract Address + Dirección del Contrato + + + + Send + Enviar + + + + Enable %1 ? + ¿Habilitar %1? + + + + Yes + + + + + No + No + + + + Receive + Recibir + + + + Swap + Intercambiar + + + + is wallet only + es solo billetera + + + + Rewards + Recompensas + + + + Faucet + Grifo + + + + + + Public Key + Clave Pública + + + + Copied to Clipboard + Copiada en el Portapapeles + + + + Loading market data + Cargando datos de mercado + + + + There is no chart data for this ticker yet + No hay datos de gráficos para este ticker aún + + + + Fetching transactions... + Obteniendo transacciones... + + + + Please wait, %1 is %2 + Por favor espera %1 es %2 + + + + % activated... + % activado... + + + + No transactions available + No hay transacciones disponibles + + + + Click to view your address on %1 (%2) block explorer + Haga clic para ver su dirección en %1 (%2) explorador de bloques + + + + Trade + Intercambio + + + + Trading Information + Información de Intercambios + + + + Chart + Gráfico + + + + + Orders + Pedidos + + + + + History + Historial + + + + Place Order + Realizar pedido + + + + Order Selected + Pedido seleccionado + + + + START SWAP + INICIO INTERCAMBIAR + + + + + Address Book + Libreta de direcciones + + + + Search contact + Buscar contacto + + + + + NEW CONTACT + + Nuevo contacto + + + + Name + Nombre + + + + Tags + Etiquetas + + + + Edit + Editar + + + + Delete + Eliminar + + + + address copied to clipboard + dirección copiada al portapapeles + + + + This contact does not have any registered address. + Este contacto no tiene ninguna dirección registrada. + + + + MarketModeSelector + + + Sell %1 + TICKER + Vender %1 + + + + Buy %1 + TICKER + Comprar %1 + + + + MinTradeModal + + + Minimum Trading Amount + Cantidad Mínima de Intercambio + + + + the minimum amount of %1 coin available for the order; the min_volume must be greater than or equal to %2; it must be also less or equal than volume param; default is %3 + la cantidad mínima de la moneda %1 disponible para la orden; el min_volume debe ser mayor o igual a %2; debe ser también menor o igual que volumen param; el valor predeterminado es %3 + + + + MultiOrder + + + %1 price is zero! + TICKER + el precio de %1 es cero! + + + + %1 receive volume is lower than minimum trade amount + TICKER + volumen de recepción de %1 es inferior al monto mínimo de transacción + + + + Error: + Error: + + + + You'll receive %1 + AMOUNT TICKER + Tu'll recibes %1 + + + + Price + Precio + + + + NewContactPopup + + + Contact name + Nombre + + + + This contact name already exists. + Este nombre de contacto ya existe. + + + + + ADD + + Añadir + + + + NewUpdateModal + + + + + Searching new updates + Buscando nuevas actualizaciones + + + + Fetching... + Buscando... + + + + + + + Close + Cerrar + + + + Could not check new updates for the following reason: +%1 + No se pudieron comprobar las nuevas actualizaciones por el siguiente motivo: %1 + + + + New version found + Nueva versión encontrada + + + + Mandatory version found + Versión obligatoria encontrada + + + + %1 %2 is available ! + %1 ¡%2 está disponible! + + + + This update is mandatory to continue using the application + Esta actualización es obligatoria para seguir usando la aplicación + + + + Close Dex + Cerrar Dex + + + + Your application is updated. + Tu aplicación está actualizada. + + + + Download + Descargar + + + + NewWallet + + + Wrong word, please check again + Palabra incorrecta, verifique nuevamente + + + + st + st + + + + nd + nd + + + + rd + rd + + + + th + th + + + + Failed to create a wallet + No se pudo crear una billetera + + + + New Wallet + Nueva billetera + + + + Confirm Seed + Confirmar semilla + + + + Choose Password + Elegir contraseña + + + + Important: Back up your seed phrase before proceeding! + Importante: ¡Haga una copia de seguridad de su frase semilla antes de continuar! + + + + We recommend storing it offline. + Recomendamos almacenarlo fuera de línea. + + + + Generated Seed + Semilla Generada + + + + Seed phrase + Frase semilla + + + + copied to clipboard + copiado al portapapeles + + + + Next + Siguiente + + + + Let's double check your seed phrase + Verifiquemos dos veces su frase semilla + + + + Your seed phrase is important - that's why we like to make sure it's correct. We'll ask you three different questions about your seed phrase to make sure you'll be able to easily restore your wallet whenever you want. + Su frase semilla es importante, por eso nos gusta asegurarnos de que sea correcta. Le haremos tres preguntas diferentes sobre su frase semilla para asegurarnos de que podrá restaurar fácilmente su billetera cuando lo desee. + + + + Enter the + Ingresa la + + + + word + palabra + + + + Check + Verificar + + + + Enter the same password to confirm + Ingrese la misma contraseña para confirmar + + + + Continue + Continuar + + + + NoConnection + + + No connection + Sin conexión + + + + Please make sure you are connected to the internet + Asegúrate de que estás conectado a Internet + + + + Will automatically retry in %1 seconds + Intentará de nuevo automáticamente en %1 segundos + + + + Retry + Reintentar + + + + NotificationsModal + + + Matching + Emparejando + + + + Order Matching + Emparejando Orden + + + + Matched + Emparejado + + + + Order Matched + Orden Emparejada + + + + Ongoing + En Curso + + + + Swap Ongoing + Intercambio En Curso + + + + Successful + Exitoso + + + + Swap Successful + Intercambio exitoso + + + + Refunding + Reembolso + + + + Failed + Fallo + + + + Swap Failed + Intercambio fallido + + + + Unknown + Desconocido + + + + Unknown State + Estado Desconocido + + + + Swap status updated + Estado de Intercambio Actualizado + + + + You sent %1 + Enviaste %1 + + + + You received %1 + Recibiste %1 + + + + Your wallet balance changed + El saldo de tu billetera cambió + + + + %1 Enable status + TICKER + %1 habilitar el estado + + + + Please check your internet connection (e.g. VPN service or firewall might block it). + Verifica tu conexión a Internet (por ejemplo, el servicio VPN o el firewall pueden bloquearlo). + + + + Failed to enable %1 + TICKER + No se pudo habilitar %1 + + + + + Failed to disable %1 + TICKER + Error al deshabilitar %1 + + + + + Endpoint not reachable + Punto final no accesible + + + + Could not reach to endpoint + No se pudo llegar al punto final + + + + Show + Mostrar + + + + Restart + Reiniciar + + + + Quit + Salir + + + + Notifications + Notificaciones + + + + There aren't any notifications + No hay ' notificaciones + + + + Mark all as read + Marcar todo como leído + + + + OrderForm + + + Price + Precio + + + + Reduce 1% relative to CEX market price. + Reducción del 1% en relación con el precio de mercado CEX. + + + + Use CEX market price. + Utilice el precio de mercado CEX. + + + + Increase 1% relative to CEX market price. + Aumento del 1% en relación con el precio de mercado de CEX. + + + + Volume + Volumen + + + + Amount to sell + Importe para vender + + + + Amount to receive + Importe para recibir + + + + Max + Max + + + + Swap 25% of your tradable balance. + Usar el 25% de su saldo comercial. + + + + Swap 50% of your tradable balance. + Usar el 50% de su saldo comercial. + + + + Swap 100% of your tradable balance. + Usar el 100% de su saldo comercial. + + + + Min Volume + Volumen Mínimo + + + + Min amount to sell + Cantidad mínima para vender + + + + Min amount to receive + Cantidad mínimo para recibir + + + + Minimum accepted trade equals 10% of order volume. + El comercio mínimo aceptado es igual al 10% del volumen del pedido. + + + + Minimum accepted trade equals 25% of order volume. + El comercio mínimo aceptado es igual al 25% del volumen del pedido. + + + + Minimum accepted trade equals 50% of order volume. + El comercio mínimo aceptado es igual al 50% del volumen del pedido. + + + + Min volume: + Volumen mínimo: + + + + Use custom minimum trade amount + Utilizar una cantidad personalizada de intercambio mínima + + + + OrderLine + + + Funds are recoverable + Los fondos son recuperables + + + + OrderList + + + No results found + No se encontraron resultados + + + + OrderModal + + + Swap Details + Detalles de Intercambio + + + + Order Details + Detalles de Orden + + + + Order Type + Tipo de Orden + + + + Maker Order + Orden de Maker + + + + Taker Order + Orden de Taker + + + + Refund State + Estado del Reembolso + + + + Your swap failed but the auto-refund process for your payment started already. Please wait and keep application opened until you receive your payment back + Su intercambio falló, pero el proceso de reembolso automático para su pago ya comenzó. Espere y mantenga la aplicación abierta hasta que reciba su pago + + + + Date + Fecha + + + + Error ID + ID de Error + + + + + Error Log + Registro de Error + + + + Close + Cerrar + + + + Cancel Order + Cancelar Pedido + + + + + Swap ID + ID de Intercambio + + + + Maker Payment Sent Transaction ID + ID de la transacción pago enviada de Maker + + + + Maker Payment Spent Transaction ID + ID de la transacción pago gastado de Maker + + + + Maker Payment TXID + TXID del pago de Maker + + + + Taker Payment Spent Transaction ID + ID de la transacción pago gastado de Taker + + + + Taker Payment Sent Transaction ID + ID de la transacción pago enviada de Taker + + + + Taker Payment TXID + TXID del pago de Taker + + + + Recover Funds + Recuperar fondos + + + + Refunding... + Reembolso... + + + + View on Explorer + Ver en Explorer + + + + OrderRemovedModal + + + Selected Order Removed + Pedido Seleccionado Eliminado + + + + The selected order does not exist anymore, it might have been matched or canceled, and no order with a better price is available. +Please select a new order. + El pedido seleccionado ya no existe, puede haber sido igualado o cancelado, y no hay un pedido con mejor precio disponible. +Seleccione un nuevo pedido. + + + + OK + Aceptar + + + + OrdersPage + + + + Filter + Filtrar + + + + Date + Fecha + + + + Export CSV + Exportar CSV + + + + Apply Filter + Aplicar Filtro + + + + Cancel All + Cancelar Todo + + + + From + Desde + + + + To + A + + + + Please choose the CSV export name and location + Por favor, elija el nombre y la ubicación de exportación CSV + + + + Pagination + + + items per page + elementos por página + + + + PasswordField + + + Password + Contraseña + + + + Enter your wallet password + Ingrese la contraseña de su billetera + + + + At least 1 lowercase alphabetical character + Al menos 1 carácter alfabético en minúsculas + + + + At least 1 uppercase alphabetical character + Al menos 1 carácter alfabético en mayúsculas + + + + At least 1 numeric character + Al menos 1 carácter numérico + + + + At least 1 special character (eg. !@#$%) + Al menos 1 carácter especial ( ej., !@#$%) + + + + Between %1 and %2 character(s) + Entre %1 y %2 carácter(es) + + + + PasswordForm + + + Password + Contraseña + + + + Confirm Password + Confirmar contraseña + + + + Enter the same password to confirm + Ingrese la misma contraseña para confirmar + + + + Portfolio + + + ADD ASSET + AGREGAR ACTIVO + + + + Search asset + Buscar activo + + + + Show only coins with balance + Mostrar solo monedas con saldo + + + + (%1/%2) + (%1/%2) + + + + Portfolio + Cartera + + + + PriceLine + + + Set swap price for evaluation + Establecer precio de intercambio para evaluación + + + + Exchange rate + Tasa de cambio + + + + Selected + Seleccionada + + + + Expensive + Caro + + + + Expedient + Expediente + + + + %1 compared to CEX + PRICE_DIFF% + %1 en comparación con CEX + + + + CEXchange rate + Tasa de cambio CEX + + + + PriceLineSimplified + + + Exchange rate + Tasa de cambio + + + + Selected + Seleccionada + + + + CEXchange rate + Tasa de cambio CEX + + + + Expensive + Caro + + + + Expedient + Expediente + + + + %1 compared to CEX + PRICE_DIFF% + %1 en comparación con CEX + + + + ProView + + + Failed to place the order + Error al realizar el pedido + + + + Placed the order + Realizó el pedido El + + + + QObject + + + Cannot reach the endpoint: + No se puede llegar al punto final: + + + + ReceiveModal + + + Receive %1 + TICKER + Recibir %1 + + + + Only send %1 to this address + TICKER + Enviar solo %1 a esta dirección + + + + %1 address + TICKER + %1 dirección + + + + copied to clipboard. + copiado al portapapeles. + + + + Close + Cerrar + + + + RecoverSeedModal + + + + View seed and private keys + Ver semilla y claves privadas + + + + Please enter your password to view the seed. + Por favor ingrese su contraseña para ver la semilla. + + + + Seed + Semilla + + + + Backup Seed + Copia de seguridad de semilla + + + + Public Address copied to clipboard + Direccion publica copiada en el portapapeles + + + + Cancel + Cancelar + + + + Incorrect Password + Contraseña incorrecta + + + + View + Ver + + + + + copied to clipboard + copiado al portapapeles + + + + + RPC Password + Contraseña RPC + + + + Search a coin. + Buscar una moneda. + + + + Public Address + Dirección Pública + + + + Private Key copied to clipboard + Clave Privada copiada en el portapapeles + + + + Private Key + Clave Privada + + + + RemoveContactPopup + + + Do you want to remove this contact ? + ¿Desea eliminar este contacto? + + + + Yes + + + + + No + No + + + + RestartModal + + + Applying the changes... + Aplicando los cambios... + + + + Restarting the application. %1 + Reiniciando la aplicación. %1 + + + + Restarting the application... + Reiniciando la aplicación... + + + + RightClickMenu + + + Cut + Cortar + + + + Copy + Copiar + + + + Paste + Pegar + + + + SearchField + + + Search + Buscar + + + + SendModal + + + Failed to send + Error al enviar + + + + Prepare to send + Preparar para enviar + + + + Address of the recipient + Dirección del destinatario + + + + Amount to send + Cantidad a enviar + + + + Gas price + Precio del gas + + + + Cancel + Cancelar + + + + Recipient's address + Dirección del destinatario + + + + The address has to be mixed case. + La dirección debe estar en mayúsculas y minúsculas. + + + + Failed to Broadcast + Error al transmitir + + + + Fix + Arreglar + + + + MAX + MAX + + + + Fiat amount: Unavailable + Cantidad en Fiat: No disponible + + + + Fiat amount: %1 + Cantidad de Fiat: %1 + + + + %1 amount: %2 + Cantidad de %1: %2 + + + + Specify in Fiat + Especificar en Fiat + + + + Specify in Crypto + Especificar en Crypto + + + + Enable Custom Fees + Habilitar Tarifas Personalizadas + + + + Enter the custom fee + Ingrese la tarifa personalizada + + + + Gas Limit + Límite de gas + + + + Custom Fee can't be higher than the amount + Tarifa personalizada no puede ser mayor que la cantidad + + + + Not enough funds. + No hay suficientes fondos. + + + + + You have %1 + AMT TICKER + Tiene %1 + + + + + Only use custom fees if you know what you are doing! + ¡Solo use tarifas personalizadas si sabe lo que está haciendo! + + + + Prepare + Preparar + + + + + Send + Enviar + + + + %1 address + TICKER + %1 dirección + + + + copied to clipboard. + copiado al portapapeles. + + + + Amount + Cantidad + + + + Fees + Tarifas + + + + Date + Fecha + + + + Back + Atrás + + + + SendModalContactList + + + Select a contact with an %1 address + Seleccione un contacto con %1 dirección + + + + Search for contacts... + Buscar contactos... + + + + %1 addresses + direcciones %1 + + + + 1 address + 1 dirección + + + + + Back + Atrás + + + + Choose an %1 address of %2 + Elija una direccion %1 de %2 + + + + Name + Nombre + + + + Address + Dirección + + + + SendResult + + + Transaction Complete! + ¡Transacción completa! + + + + %1 txid + TICKER + %1 txid + + + + + copied to clipboard. + copiado al portapapeles. + + + + Recipient's address + Dirección del destinatario + + + + %1 address + TICKER + %1 dirección + + + + Amount + Cantidad + + + + Fees + Tarifas + + + + Date + Fecha + + + + Transaction Hash + Hash de Transaccion + + + + Close + Cerrar + + + + View on Explorer + Ver en Explorer + + + + 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 + + + + + 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 + + + + 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. + + + + 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 + + + + Sidebar + + + Search + Buscar + + + + Add asset + Agregar activo + + + + SmartChartView + + + Loading market data + Cargando datos de mercado + + + + There is no chart data for this ticker yet + No hay datos de gráficos para este ticker aún + + + + SubBestOrder + + + Token + Token + + + + Available Quantity + Cantidad Disponible + + + + Available Quantity (in %1) + Cantidad Disponible (en %1) + + + + Fiat Volume + Volumen en Fiat + + + + CEX Rate + Tasa CEX + + + + %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?<br><a href='#'>Yes</a> - <a href='#no'>No</a> + %1 no está habilitado. ¿Desea habilitarlo para poder seleccionar %2 mejores ordenes?<br><a href='#'>Sí</a> - <a href='#no'>No</a> + + + + SubCoinSelector + + + Token + Token + + + + Balance + Saldo + + + + Balance Fiat + Saldo Fiat + + + + No Selectable coin. + No Moneda seleccionable. + + + + SubHistory + + + History + Historial + + + + Filter + Filtrar + + + + Date + Fecha + + + + Close filtering options. + Cerrar opciones de filtrado. + + + + Open filtering options. + Abrir opciones de filtrado. + + + + Filter settings + Configuración de filtros + + + + From + Desde + + + + To + A + + + + Cancel + Cancelar + + + + Apply filter + Aplicar filtro + + + + Export + Exportar + + + + Please choose the CSV export name and location + Por favor, elija el nombre y la ubicación de exportación CSV + + + + No results found + No se encontraron resultados + + + + SubOrders + + + + Orders + Pedidos + + + + Close filtering options. + Cerrar opciones de filtrado. + + + + Filter + Filtrar + + + + Date + Fecha + + + + Open filtering options. + Abrir opciones de filtrado. + + + + Filter settings + Configuración de filtros + + + + From + Desde + + + + To + A + + + + Cancel + Cancelar + + + + Apply filter + Aplicar filtro + + + + No results found + No se encontraron resultados + + + + SupportModal + + + Frequently Asked Questions + Preguntas frecuentes + + + + Do you store my private keys? + ¿Almacenan mis claves privadas? + + + + No! %1 is non-custodial. We never store any sensitive data, including your private keys, seed phrases, or PIN. This data is only stored on the user’s device and never leaves it. You are in full control of your assets. + ¡No! %1 no tiene custodia. Nunca almacenamos datos confidenciales, incluidas sus claves privadas, frases iniciales o PIN. Estos datos solo se almacenan en el dispositivo del usuario y nunca lo abandonan. Usted tiene el control total de sus activos. + + + + How is trading on %1 different from trading on other DEXs? + ¿En qué se diferencia el intercambio en %1 del comercio en otros DEX? + + + + Other DEXs generally only allow you to trade assets that are based on a single blockchain network, use proxy tokens, and only allow placing a single order with the same funds. + +%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. + Otros DEX generalmente solo le permiten intercambiar activos que se basan en una sola red de cadena de bloques, usar tokens de proxy y solo permiten realizar un solo pedido con los mismos fondos. + +%1 le permite comerciar de forma nativa en dos redes de cadena de bloques diferentes sin tokens de proxy. También puede realizar varios pedidos con los mismos fondos. Por ejemplo, puede vender 0,1 BTC por KMD, QTUM o VRSC: el primer pedido que se completa automáticamente cancela todos los demás pedidos. + + + + 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? + + + + 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. + +The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. + +If you go offline, so will your orders, and any that are in progress will fail, leading to potential loss of trade / transaction fees, and a wait for the swap to timeout and issue a refund. It may also negatively affect your wallet's reputation score for future trade matching. + +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. + + + + How are the fees on %1 calculated? + ¿Cómo se calculan las tarifas de %1? + + + + There are two fee categories to consider when trading on %1. + +1. %1 charges approximately 0.13% (1/777 of trading volume but not lower than 0.0001) as the trading fee for taker orders, and maker orders have zero fees. + +2. Both makers and takers will need to pay normal network fees to the involved blockchains when making atomic swap transactions. + +Network fees can vary greatly depending on your selected trading pair. + Hay dos categorías de tarifas a tener en cuenta al operar en %1. + +1. %1 cobra aproximadamente el 0,13 % (1/777 del volumen de negociación pero no menos de 0,0001) como tarifa de negociación para las órdenes del tomador, y las órdenes del fabricante no tienen tarifas. + +2. Tanto los creadores como los tomadores deberán pagar tarifas de red normales a las cadenas de bloques involucradas al realizar transacciones de intercambio atómico. + +Las tarifas de la red pueden variar mucho según el par comercial seleccionado. + + + + Do you provide user support? + ¿Ofrecen soporte al usuario? + + + + Yes! %1 offers support through the <a href="%2">%1 Discord server</a>. The team and the community are always happy to help! + ¡Sí! %1 ofrece soporte a través del <a href="%2">%1 servidor Discord</a>. ¡El equipo y la comunidad siempre están dispuestos a ayudar! + + + + Who is behind %1? + ¿Quién está detrás de %1? + + + + %1 is developed by the Komodo team. Komodo is one of the most established blockchain projects working on innovative solutions like atomic swaps, Delayed Proof of Work, and an interoperable multi-chain architecture. + %1 está desarrollado por el equipo de Komodo. Komodo es uno de los proyectos de cadena de bloques más establecidos que trabaja en soluciones innovadoras como intercambios atómicos, prueba de trabajo retrasada y una arquitectura multicadena interoperable. + + + + Is it possible to develop my own white-label exchange on %1? + ¿Es posible desarrollar mi propio intercambio de marca blanca en %1? + + + + Absolutely! You can read our developer documentation for more details or contact us with your partnership inquiries. Have a specific technical question? The %1 developer community is always ready to help! + ¡Absolutamente! Puede leer nuestra documentación para desarrolladores para obtener más detalles o ponerse en contacto con nosotros con sus consultas de asociación. ¿Tiene una pregunta técnica específica? ¡La comunidad de desarrolladores de %1 siempre está lista para ayudar! + + + + Which devices can I use %1 on? + ¿En qué dispositivos puedo usar %1? + + + + %1 is available for mobile on both <a href="%2">Android and iPhone, and for desktop on Windows, Mac, and Linux</a> operating systems. + %1 está disponible para dispositivos móviles en <a href="%2">Android y iPhone, y para escritorio en Windows, Mac y Linux</a> sistemas operativos. + + + + Compliance Info + Información de cumplimiento + + + + Due to regulatory and legal circumstances the citizens of certain jurisdictions including, but not limited to, the United States of America, Canada, Hong Kong, Israel, Singapore, Sudan, Austria, Iran and any other state, country or other jurisdiction that is embargoed by the United States of America or the European Union are not allowed to use this application. + Debido a circunstancias reglamentarias y legales, los ciudadanos de ciertas jurisdicciones, incluidos, entre otros, los Estados Unidos de América, Canadá, Hong Kong, Israel, Singapur, Sudán, Austria, Irán y cualquier otro estado, país u otra jurisdicción que está embargado por los Estados Unidos de América o la Unión Europea no se les permite utilizar esta aplicación. + + + + Changelog + Cambios + + + + Open Logs Folder + Abrir Carpeta de Registros + + + + SwapProgress + + + act + SHORT FOR ACTUAL TIME + act + + + + est + SHORT FOR ESTIMATED + est + + + + Progress details + Detalles del Progreso + + + + TextAreaWithTitle + + + Save + Guardar + + + + Edit + Editar + + + + TextEditWithCopy + + + copied to clipboard + copiado al portapapeles + + + + TextEditWithTitle + + + copied to clipboard + copiado al portapapeles + + + + TextFieldWithTitle + + + Required + Requerido + + + + Toast + + + Click here to see the details + Haga clic aquí para ver los detalles + + + + Trade + + + Swap + Intercambiar + + + + Instant trading with best orders + Comercio instantáneo con las mejores órdenes + + + + Reset form + Restablecer formulario + + + + You have no tradable assets + No tiene activos intercambiables + + + + From + Desde + + + + Enter an amount + Ingrese una cantidad + + + + MAX + MAX + + + + To + A + + + + Pick an order + Elegir una orden + + + + Price + Precio + + + + Better price found: %1. Updating forms. + Mejor precio encontrado: %1. Actualización de formularios. + + + + Better price (%1) found but received quantity (%2) is lower than your current one (%3). Click here to update the selected order. + Mejor precio (%1) encontrado pero la cantidad recibida (%2) es más baja que la actual (%3). Haga clic aquí para actualizar el pedido seleccionado. + + + + %1 + %1 + + + + Tradable: + Negociable: + + + + Min: %1 + Mín.: %1 + + + + Pick a coin + Elija una moneda + + + + SWAP NOW + CAMBIE AHORA + + + + Failed to place the order + Error al realizar el pedido + + + + Placed the order + Realizó el pedido El + + + + Entered amount must be superior than 0. + monto ingresado debe ser superior a 0. + + + + You must select an order. + Debe seleccionar un pedido. + + + + Entered amount is below the minimum required by this order: %1 + El monto ingresado está por debajo del mínimo requerido por esta orden: %1 + + + + + %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 + + + + %1 balance does not have enough funds to pay the gas of %2 transactions + %1 el saldo no tiene fondos suficientes para pagar el gas de %2 transacciones + + + + No buy orders found for %1. + No se encontraron órdenes de compra para %1. + + + + You can check later or try to sell a different coin. + Puede verificar más tarde o intentar vender una moneda diferente. + + + + Calculating fee estimate... + Calculando tarifa estimada... + + + + Total %1 fees: + Total de %1 tarifas: + + + + %2 (%3) + %2 (%3) + + + + TradeViewHeader + + + Pro View Settings + Vista de Configuración Pro + + + + Display Settings + Configuracion de Vista + + + + Ticker Selectors + Selectores + + + + Trading Information + Información de Intercambios + + + + Order Book + Libro de Ordenes + + + + Best Orders + Mejores Ordenes + + + + Place Order + Realizar pedido + + + + TransactionDetailsModal + + + Transaction Details + Detalles de Transacción + + + + %1 txid + TICKER + %1 txid + + + + copied to clipboard. + copiado al portapapeles. + + + + Amount + Cantidad + + + + Fees + Tarifas + + + + From address + Desde dirección + + + + To address + Para dirección + + + + Date + Fecha + + + + Unconfirmed + Sin confirmar + + + + Transaction Hash + Hash de Transaccion + + + + Confirmations + Confirmaciones + + + + Block Height + Altura del Bloque + + + + From + Desde + + + + To + A + + + + Notes + Notas + + + + Close + Cerrar + + + + View on Explorer + Ver en Explorer + + + + Transactions + + + Sent + Enviado + + + + Received + Recibido + + + + fees + tarifas + + + + Unconfirmed + Sin confirmar + + + + UpdateInvalidChecksum + + + The downloaded update archive is corrupted ! + ¡El archivo de actualización descargado está dañado! + + + + Vertical + + + Order Book + Libro de Ordenes + + + + WalletsView + + + Welcome + Bienvenido + + + + New wallet + Nuevo monedero + + + + Import wallet + Importar monedero + + + + Search your wallets... + Buscar en sus monederos... + + + + My Wallets + Mis Monederos + + + + No wallets found! + ¡No se han encontrado monederos! + + + + + Delete + Eliminar + + + + Enter password to confirm deletion of + Ingrese la contraseña para confirmar la eliminación de + + + + wallet + billetera + + + + Type password + Escriba la contraseña + + + + Cancel + Cancelar + + + + + Wallet status + Estado + + + + wallet deleted successfully + billetera eliminada con éxito + + + + + Ok + Ok + + + + wallet password is incorrect + la contraseña de la billetera es incorrecta + + + + ZcashParamsModal + + + %1 Activation Failed! + ¡Error en la activación de %1! + + + + To activate ZHTLC coins, you need to download the Zcash Params. +This might take a few minutes... + Para activar las monedas ZHTLC, debe descargar Zcash Params. +Esto puede tardar unos minutos... + + + + Download params & enable coins + Descargar parámetros & habilitar monedas + + + + More Info + Más información + + + + Close + Cerrar + + + + atomic_dex::settings_page + + + An error has occurred. + Se ha producido un error. + + + + 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 + + + + main + + + Logout + Cerrar sesión + + + + Balance + Saldo + + + diff --git a/atomic_defi_design/assets/languages/atomic_defi_fr.ts b/atomic_defi_design/assets/languages/atomic_defi_fr.ts index 674e6081c5..ca2981786a 100644 --- a/atomic_defi_design/assets/languages/atomic_defi_fr.ts +++ b/atomic_defi_design/assets/languages/atomic_defi_fr.ts @@ -2,502 +2,269 @@ - QPlatformTheme + AddAddressForm - &Yes - Oui + + Use standard network address + - &No - Non + + Label + + + + + This key already exists. + Cette clé existe déjà. + + Address + Adresse + + + + Cancel - Annuler + Annuler + + + + Convert + + + + + Edit + Éditer + + + + Add + Ajouter + + + + You need to enable %1 before adding this kind of address. + + + + + Enable + Activer AddCustomCoinModal - + Choose the asset type Choisir le type d'actif - - Type - Type - - - + 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 - - Contract Address - Adresse du contrat - - - + 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! - + 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 - AddressBook - - - Address Book - Carnet d'adresses - - - - New Contact - Nouveau contact - - - - Search a contact by name or tags - Rechercher un contact par nom ou par tags - - - - Name - Nom - - - - Tags (first 6) - Tags (Les 6 premiers) - - - - Actions - Actions - - - - Edit - Éditer - - - - Remove - Retirer - - - - Do you want to remove this contact ? - Voulez-vous supprimer ce contact ? - - - - Yes - Oui - - - - No - Non - - - - AddressBookAddContactAddressModal - - - Create a new address - Créer une nouvelle adresse - - - - Edit address entry - Edition de l'entrée pour l'addresse - - - - Selected wallet: %1 - Portefeuille sélectionné : %1 - - - - NONE - RIEN - - - - Enter a name - Entrez un nom - - - - This key already exists. - Cette clé existe déjà. - - - - Enter the address - Entrez l'adresse - - - - Validate - Valider - - - - Cancel - Annuler - + AddTagPopup - - Convert + + Tag name - - - AddressBookEditContactModal - - - Edit contact - Modifier le contact - - - - Contact Name - Nom du contact - - - - Enter a contact name - Entrez un nom de contact - - - - Address List - Liste d'addresse - - - - Search for an address entry. - Rechercher une addresse. - - - - Type - Type - - - - Key - Clef - - - - Address - Addresse - - - - Actions - Actions - - - - New Address - Nouvelle addresse - - - - Tags - Tags - - - - + - + - - - - Confirm - Confirmer - - - - - Cancel - Annuler - - - - The selected address belongs to a disabled coin, you need to enabled it before sending. - L'adresse sélectionnée appartient à un actif désactivée, vous devez l'activer avant l'envoi. - - - - Enable - Activer - - - - Cannot send to this address - Impossible d'envoyer à cette adresse - - - - Your balance is empty - Votre solde est vide - - - - Ok - Ok - - - Remove address ? + + Contact already has this tag. - - Yes - Oui - - - - No - Non + + + ADD + - AddressBookNewContactCategoryModal - - - Add a new tag - Ajouter un nouveau tag - - - - Enter the tag name - Entrer le nom du tag - - - - This contact already has this tag - Ce contact possède déjà ce tag - - - - Add - Ajouter - + AmountChart - - Cancel - Annuler + + Work in progress + Travail en cours - AddressBookNewContactModal - - - Create a new contact - Créer un nouveau contact - - - - Enter the contact name - Entrez le nom du contact - - - - This contact name already exists. - Ce nom de contact existe déjà. - - - - Confirm - Confirmer - + App - - Cancel - Annuler + + Recover Funds Result + Le résultat de la récupération des fonds - AddressBookSendWalletSelector + AssetFromStandardSelector - + Choose a valid - Choisissez un actif - - - - coin - valide - - - - AddressBookWalletTypeListModal - - - Select wallet type - Sélectionnez le type de portefeuille + Choisissez un actif - - Search - Rechercher + + asset + - - - AmountChart - - Work in progress - Travail en cours + + Search an asset + - - - App - - Recover Funds Result - Le résultat de la récupération des fonds + + Disabled + AssetPieChart - + Assets Actifs @@ -505,32 +272,42 @@ AssetsList - + Asset Asset - + Balance Balance - + + Fiat Balance + + + + Change 24h Changement 24H - + Price Prix - + Source Source - + + Activating: + + + + Price provider is: %1 Fournisseur de prix : %1 @@ -538,27 +315,70 @@ Bottom - + Settings Réglages - + Support Support - + Privacy Intimité - - - BuyBox - - Buy - Acheter + + Disable Privacy? + + + + + Enter wallet password to confirm + + + + + Type password + Tapez votre mot de passe + + + + Confirm + Confirmer + + + + Cancel + Annuler + + + + Privacy status + + + + + Privacy mode disabled successfully + + + + + + Ok + Ok + + + + Wrong password! + + + + + wallet password is incorrect + le mot de passe du portefeuille est incorrect @@ -569,64 +389,51 @@ Configurer le mot de passe de camouflage - + Camouflage Password is a secret password for emergency situations. Le mot de passe de camouflage est un mot de passe secret pour les situations d'urgence. - + Using it to login will display your balance lower than it actually is. Son utilisation pour vous connecter affichera votre solde inférieur à ce qu'il est réellement. - + Here you enter the suffix and at login you need to enter {real_password}{suffix} Ici, vous entrez le suffixe et lors de la connexion, vous devez entrer {mot de passe réel}{suffixe} - + Password suffix Suffixe du mot de passe - + Confirm pasword suffix Confirmer le suffixe du mot de passe - + Enter a password suffix Entrez un suffixe de mot de passe - + Enter the same password suffix to confirm Entrez le même suffixe de mot de passe pour confirmer - + Cancel Annuler - + Save Sauvegarder - - CandleStickChart - - - Loading market data - Chargement des données de marché - - - - There is no chart data for this pair yet - Il n'y a pas encore de données graphiques pour cette paire - - CannotEnableCoinModal @@ -691,122 +498,134 @@ Les données de marché (prix, graphiques, etc.) marquées de l'icône ⓘ proviennent de sources tierces.<br><br>Les données proviennent de <a href="https://bandprotocol.com/"> Band Decentralized Oracle</a> et <a href="https://www.coingecko.com/fr">Coingecko </a>.<br><br><b>Paires prises en charge par Oracle:</b><br>%1<br><br><b>Dernière référence (Band Oracle) :</b><br><a href="%2">%2</a> + + Chart + + + Loading market data + Chargement des données de marché + + + + There is no chart data for this pair yet + Il n'y a pas encore de données graphiques pour cette paire + + ClaimRewardsModal - + Failed to prepare to claim rewards Échec de la préparation de la réclamation des récompenses - + Claim your %1 reward? TICKER Réclamer votre %1 récompense ? - + No UTXOs eligible for claiming Aucun UTXO éligible pour réclamer - - You will receive %1 - AMT TICKER - Vous allez recevoir %1 - - - + Transaction fee is higher than the reward! Les frais de transaction sont plus élevés que la récompense ! - + + You will receive + + + + Refresh Actualiser - + Read more about KMD active users rewards En savoir plus sur les récompenses des utilisateurs actifs de KMD - + UTXO UTXO - + Amount Montant - + Reward Récompense - + Accruing Start Début accumulation - + Accruing Stop Fin accumulation - + Time Left Temps restant - + Error Erreur - + Locktime is not set L'heure de verrouillage n'est pas définie - + Locktime is less than the threshold Le temps de verrouillage est inférieur au seuil - + UTXO height is greater than end of the era La hauteur UTXO est supérieure à la fin de l'ère - + UTXO amount is less than 10 Le montant UTXO est inférieur à 10 - + One hour did not pass yet Une heure ne s'est pas encore écoulée - + Transaction is in mempool La transaction est en mempool - + Unknown problem Problème inconnu - + Cancel Annuler - + Confirm Confirmer @@ -814,37 +633,55 @@ CoinMenu - + Disable %1 TICKER Désactiver %1 - + Disable and Delete %1 TICKER Désactiver et Supprimer %1 - + Disable all %1 assets Désactiver tous les actifs %1 - + Disable all assets Désactiver tous les actifs + + + Disable 0 balance assets + + + + + ComboBoxWithSearchBar + + + Search + Rechercher + Combo_fiat - + + Language + Langue + + + Fiat Monnaie fiduciaire - + Recommended: Conseillé: @@ -895,74 +732,83 @@ ConfirmTradeModal - + Confirm Exchange Details Détails de la confirmation de l'échange - + This swap request can not be undone and is a final event! La requête de ce swap ne peut pas être annulé, c'est irréversible ! - - Total %1 fees: %2 (%3) - Total %1 frais: %2 (%3) - - - + Security configuration Configuration de la sécurité - - dPoW protected - dPoW protégé - - - - + Read more about dPoW En savoir plus sur dPoW - + Use custom protection settings for incoming %1 transactions TICKER - Utiliser les paramètres de protection personnalisés pour les transactions%1 entrantes + Utiliser les paramètres de protection personnalisés pour les transactions %1 entrantes - + Enable Komodo dPoW security Activer la sécurité de Komodo dPoW - + %1 confirmations for incoming %2 transactions Il y a %1 confirmations pour les transactions entrantes du ticker %2 - + This transaction can take up to 60 mins - DO NOT close this application! Cette transaction peut prendre jusqu'à 60 minutes - NE fermez PAS cette application ! - + + Trade price is more than 50% different to CEX! Confirm? + Le prix est supérieur à 50% du prix sur les CEX ! Êtes-vous sûr ? + + + + Loading fees... + + + + + <b>Total %1 fees:</b> + Frais totaux %1: + + + + dPoW protected + Protégé par dPoW + + + Required Confirmations Confirmations requises - + Warning, this atomic swap is not dPoW protected! Attention, ce swap atomique n'est pas protégé par dPoW ! - + Cancel Annuler - + Confirm Confirmer @@ -983,181 +829,197 @@ Le nombre actuel d'actifs activées ne correspond pas à vos spécifications de configuration. La configuration de vos actifs sera réinitialisée. - + Matching Recherche en cours - + Order Matching Recherche d'un ordre - + Matched Trouvé - + Order Matched Ordre trouvé - + Ongoing En cours - + Swap Ongoing Échange en cours - + Successful Réussi - + Swap Successful Échange terminé - + Refunding En cours de remboursement - + Failed Échoué - + Swap Failed Erreur lors de l'échange - + Unknown Inconnue - + Unknown State État inconnu - + Started Commencé - + Negotiated Négocié - + Taker fee sent Frais de preneur envoyés - + Maker payment received Paiement de l'envoyeur reçu - + Maker payment wait confirm started La confirmation d'attente de paiement de l'envoyeur a commencé - + Maker payment validated and confirmed Paiement de l'envoyeur validé et confirmé - + Taker payment sent Paiement du preneur envoyé - + Taker payment spent Paiement du preneur dépensé - + Maker payment spent Paiement de l'envoyeur dépensé - + Finished Fini - + Start failed Le démarrage a échoué - + Negotiate failed La négociation a échoué - + Taker fee validate failed Échec de la validation des frais du preneur - + Maker payment transaction failed La transaction de paiement du créateur a échoué - + Maker payment Data send failed Échec de l'envoi des données de paiement du créateur - + Maker payment wait confirm failed La confirmation de l'attente de paiement du créateur a échoué - + Taker payment validate failed La validation du paiement du preneur a échoué - + Taker payment wait confirm failed La confirmation de l'attente de paiement du preneur a échoué - + Taker payment spend failed Échec des dépenses de paiement du preneur - + Maker payment wait refund started attente de paiement du créateur, remboursement commencé - + Maker payment refunded Paiement du créateur remboursé - + Maker payment refund failed échec du remboursement du paiement du créateur + + DatePicker + + + Date + Date + + + + DefaultCopyIcon + + + copied to clipboard + copié dans le presse-papier + + DefaultRangeSlider @@ -1171,6 +1033,14 @@ Max + + DefaultTextEdit + + + copied to clipboard + copié dans le presse-papier + + DeleteWalletModal @@ -1213,7 +1083,7 @@ DexAppPasswordField - + Type password Tapez votre mot de passe @@ -1221,35 +1091,32 @@ DexKeyChecker - + At least 1 lowercase alphabetical character Au moins 1 caractère alphabétique en minuscule - + At least 1 uppercase alphabetical character Au moins 1 caractère alphabétique en majuscule - + At least 1 numeric character Au moins 1 caractère numérique - + At least 1 special character (eg. !@#$%) Au moins 1 caractère spécial (ex: ! @ # $%) - - - At least %n character(s) - - Au moins %n caractère - Au moins %n caractères - + + + Between %1 and %2 character(s) + - + Password and Confirm Password have to be same Le mot de passe et la confirmation du mot de passe doivent être identiques @@ -1257,7 +1124,7 @@ DexPaginator - + items per page Nombres d'éléments par page @@ -1283,55 +1150,136 @@ DexSweetComboBox - + Search Rechercher + + EditContactModal + + + Edit contact + Modifier le contact + + + + Contact name + + + + + Enter a contact name + Entrez un nom de contact + + + + Address list + + + + + Address Book + Carnet d'adresses + + + + address copied to clipboard + + + + + Edit + Éditer + + + + + Add + + + + + Tags + Tags + + + + Add tag + + + + + Cancel + Annuler + + + + Confirm + Confirmer + + + + EnableAssetModal + + + The selected address belongs to a disabled asset, you need to enabled it before sending. + + + + + Enable + Activer + + + + Cancel + Annuler + + EnableCoinModal - + Enable assets Activer les actifs - + Search asset Rechercher un actif - - Add a custom asset to the list - Ajouter un token personnalisé à la liste - - - + All assets are already enabled! Tous les actifs sont déjà activés ! - + Change assets limit Limiter le nombre d'actifs - + + Cancel + Annuler + + + Select all assets Sélectionnez tous les actifs - + You can still enable %1 assets. Selected: %2. Vous pouvez toujours activer %1 actifs. Sélectionnés: %2. - - Close - Fermer + + Add a custom asset + - + Enable Activer @@ -1344,27 +1292,27 @@ Clause de non-responsabilité et conditions d'utilisation - + Accept EULA Acceptez l'EULA - + Accept Terms and Conditions Accepter les termes et conditions - + Close Fermer - + Cancel Annuler - + Confirm Confirmer @@ -1382,28 +1330,61 @@ La connexion a été perdue. Vous avez été déconnecté. - - Close - Fermer + + Close + Fermer + + + + FeeInfo + + + Minimum fee + Frais minimum + + + + Fees will be calculated + Les frais seront calculés + + + + GasInfoModal + + + How do I calculate gas? + + + + + Gas is measured in gwei. Gwei is just a unit of Ether, and is equal to 0.000000001 ETH (or the equivalent platform coin such as AVAX or BNB). The gas price varies over time depending on network congestion. + + + + + The gas limit is how many units of gas (maximum) you allocate to pay for a transaction. The gas required depending on the size of the transaction & data being transmitted. + + + + + A standard transaction not involving contracts uses 21,000 gas units, with any of the limit remaining returned to the source address. + - - - FeeInfo - - Minimum fee - Frais minimum + + Transactions involving contracts may result in the whole limit being consumed, so be careful not to set it too high. + - - Fees will be calculated - Les frais seront calculés + + For more information, read the article at <a href="https://support.mycrypto.com/how-to/sending/how-to-know-what-gas-limit-to-use">https://support.mycrypto.com/how-to/sending/how-to-know-what-gas-limit-to-use</a> + General - + %n day(s) %n jour(s) @@ -1411,7 +1392,7 @@ - + %nd day @@ -1420,7 +1401,7 @@ - + %nh hours @@ -1429,7 +1410,7 @@ - + %nm minutes @@ -1438,7 +1419,7 @@ - + %ns seconds @@ -1447,7 +1428,7 @@ - + %nms milliseconds @@ -1456,66 +1437,92 @@ - + - - - + + <b>Taker tx fee:</b> + Taxes de transaction du preneur: + + + + <b>Dex tx fee:</b> + Taxes de transaction de DEX: + + + + <b>Dex fee:</b> + Taxes de DEX: + + + + <b>Maker tx fee:</b> + Taxes de transaction du créateur + + + 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 - Veuillez remplir le champ de volume + - - + + + 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 @@ -1523,146 +1530,165 @@ Header - + You get Vous recevez - + You send Vous envoyez - + Fiat Price Prix fiduciaire - + CEX rate Taux CEX - Price Prix - + Quantity Quantité - + Total Total - - History - - - Recent Swaps - Swaps récents - - ImportWallet - + Failed to Import the wallet Échec de l'importation du portefeuille - + Import wallet - Setup Importer le portefeuille - Configuration - + Import wallet - Choose password Importer le portefeuille - Choisir le mot de passe - + Wallet Name Nom du portefeuille - + Enter seed Entrez la phrase de récupération - - BIP39 seed validation failed, try again or select 'Allow custom seed' - Échec de la validation de la phrase de récupération BIP39, réessayez ou sélectionnez ' Autoriser les phrases de récupérations personnalisées' + + Your seed is not BIP39 compliant. +Try again or select 'Allow custom seed' to continue. + + + + + + i understand + je comprends + + + + + я согласен + + + + + + je comprends + + + + + + entiendo + + + + + + anladım + + + + + + ich verstehe + + + + + Ok + Ok - + Allow custom seed Autoriser les phrases de récupération personnalisées - + <strong>Allow custom seed</strong> <strong>Autoriser les phrases personnalisées</strong> - + Custom seed phrases might be less secure and easier to crack than a generated BIP39 compliant seed phrase or private key (WIF).<br><br>To confirm you understand the risk and know what you are doing, type <strong>'I understand'</strong> in the box below. Les phrases de départ personnalisées peuvent être moins sécurisées et plus faciles à déchiffrer qu'une phrase de départ ou une clé privée (WIF) conforme à BIP39 générée.<br><br>Pour confirmer que vous comprenez le risque et savez ce que vous faites, tapez <strong>'Je comprends'</strong> dans la case ci-dessous. - I understand Je comprends - - Enable - Activer - - - + Next Suivant - + Enter the same password to confirm Entrez le même mot de passe pour confirmer - + Continue Continuer - - Languages - - - Language - Langue - - LinksRow - + Join our Discord server Rejoignez notre serveur Discord - + Follow us on Twitter Suivez-nous sur Twitter - + Go to Support Guides M'envoyer sur les guides du support @@ -1674,16 +1700,26 @@ Funds are recoverable Les fonds sont récupérables + + + Best Orders + Meilleurs offres + + + + Enter volume to see best orders. + + ListDelegate - + %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?<br><a href='#'>Yes</a> - <a href='#no'>No</a> %1 n'est pas activé - Souhaitez vous l'activer pour pouvoir selectionnez les meilleurs offres %2 ?<br><a href='#'>Oui</a> - <a href='#no'>Non</a> - + This order requires a minimum amount of %1 %2 <br>You don't have enough funds.<br> %3 Cette commande nécessite un montant minimum de %1 %2 <br>Vous n'avez pas assez de fonds.<br> %3 @@ -1722,147 +1758,194 @@ Login - + Incorrect Password Mot de passe incorrect - - Connect - Connection + + Log In + - + Cancel Annuler + + LogoutModal + + + Exit %1 or go to login menu? + + + + + Warning: You currently have a swap in progress. +Logging out may result in a failed swap. + + + + + Warning: You currently have open maker orders. +They will be removed from the orderbook until you log in again. + + + + + Login menu + + + + + Exit + + + + + Cancel + Annuler + + Main - + Segwit Segwit - + Confirmation Confirmation - + Do you want to send your %1 funds to %2 wallet first? Voulez-vous d'abord envoyer vos fonds %1 vers le portefeuille %2 ? - + Success Succès - + Your transaction is send, may take some time to arrive Votre transaction est envoyée, peut prendre un certain temps pour arriver - - Wallet Balance - Solde portefeuille - - - + Price Prix - - Change 24h - Changement 24H + + Change 24hr + + + + + Porfolio + - - Portfolio % - Portefeuille % + + Contract Address + - + Send Envoyez - + Enable %1 ? Activer %1 ? - + Yes Oui - + No Non - + Receive Recevoir - + Swap Échange - + + is wallet only + + + + Rewards Récompenses - + Faucet Robinet - + + + + Public Key + + + + + Copied to Clipboard + Copier dans le presse-papier + + + Loading market data Chargement des données de marché - + There is no chart data for this ticker yet Il n'y a pas encore de données graphiques pour ce ticker - - Loading - Chargement - - - - Scanning blocks for TX History... - Analyses des blocs pour l'historique TX... + + Fetching transactions... + - - Syncing TX History... - Synchronisation de l'historique de transactions... + + Please wait, %1 is %2 + - - No transactions - Pas de transactions + + % activated... + - - Refreshing - Actualiser + + No transactions available + - - Fetching transactions - Récupération des transactions + + Click to view your address on %1 (%2) block explorer + @@ -1870,27 +1953,102 @@ Échanger + + Trading Information + Informations de Trading + + + + Chart + Chart + + + Orders Ordres + History Historique + + + Place Order + Placer l'ordre + + + + Order Selected + Ordre séléctionné + + + + START SWAP + COMMENCER L'ÉCHANGE + + + + + Address Book + Carnet d'adresses + + + + Search contact + + + + + + NEW CONTACT + + + + + Name + Nom + + + + Tags + Tags + + + + Edit + Éditer + + + + Delete + Supprimez + + + + address copied to clipboard + + + + + This contact does not have any registered address. + + MarketModeSelector - - Sell - Vendre + + Sell %1 + TICKER + - - Buy - Acheter + + Buy %1 + TICKER + @@ -1938,165 +2096,196 @@ - NewUpdateModal + NewContactPopup - - Searching new updates... - Recherche de nouvelles mises à jour ... + + Contact name + - - Please wait while the application is finding a new update... You can close this modal if you want. - Veuillez patienter pendant que l'application recherche une nouvelle mise à jour ... Vous pouvez fermer ce modal si vous le souhaitez. + + This contact name already exists. + Ce nom de contact existe déjà. - - Already updated - Déjà mis à jour + + + ADD + + + + NewUpdateModal - - %1 is already up-to-date ! - %1 est déjà à jour ! + + + + Searching new updates + - - Close - Fermer + + Fetching... + - - New update detected ! - Nouvelle mise à jour détectée ! + + + + + Close + Fermer - - Do you want to update %1 from %2 to %3 ? - Voulez-vous mettre à jour %1 de %2 vers %3 ? + + Could not check new updates for the following reason: +%1 + - - Download - Téléchargement + + New version found + - - Remind me later - Rappelle-moi plus tard + + Mandatory version found + - - Download in progress... - Téléchargement en cours... + + %1 %2 is available ! + - - Update downloaded - Mise à jour téléchargée + + This update is mandatory to continue using the application + - - Update has been successfully downloaded. Do you want to restart the application now ? - La mise à jour a été téléchargée avec succès. Voulez-vous redémarrer l'application maintenant ? + + Close Dex + - - Restart now - Redémarrer maintenant + + Your application is updated. + - - Restart later - Redémarrer plus tard + + Download + Téléchargement NewWallet - + Wrong word, please check again Mauvais mot, veuillez vérifier à nouveau - + + st + + + + + nd + + + + + rd + + + + + th + + + + Failed to create a wallet Impossible de créer un portefeuille - + New Wallet Nouveau portefeuille - + Confirm Seed Confirmer la phrase de récupération - + Choose Password Choisissez un mot de passe - + Important: Back up your seed phrase before proceeding! Important: sauvegardez votre phrase de recupération avant de continuer ! - + We recommend storing it offline. Nous vous recommandons de le stocker hors ligne. - + Generated Seed Générer un Seed - + Seed phrase Phrase de récupération - + copied to clipboard copié dans le presse-papier - + Next Suivant - + Let's double check your seed phrase Vérifions à nouveau votre phrase de récupération - + Your seed phrase is important - that's why we like to make sure it's correct. We'll ask you three different questions about your seed phrase to make sure you'll be able to easily restore your wallet whenever you want. Votre phrase de récupération est importante - c'est pourquoi nous aimons nous assurer qu'elle est correcte. Nous vous poserons trois questions différentes au sujet de votre phrase source pour vous assurer que vous pourrez facilement restaurer votre portefeuille à tout moment. - - - Enter the %n. word - - Entrez le mot numéro %n - Entrez le mot numéro %n - + + + Enter the + + + + + word + - + Check Vérifier - + Enter the same password to confirm Entrez le même mot de passe pour confirmer - + Continue Continuer @@ -2127,150 +2316,152 @@ NotificationsModal - + Matching Recherche en cours - + Order Matching Recherche d'un ordre - + Matched Trouvé - + Order Matched Ordre trouvé - + Ongoing En cours - + Swap Ongoing Échange en cours - + Successful Réussi - + Swap Successful Échange terminé - + Refunding En cours de remboursement - + Failed Échoué - + Swap Failed Erreur lors de l'échange - + Unknown Inconnue - + Unknown State État inconnu - + Swap status updated État du swap mis à jour - + You sent %1 Vous avez envoyé %1 - + You received %1 Vous avez reçu %1 - + Your wallet balance changed Le solde de votre portefeuille a changé - + + %1 Enable status + TICKER + + + + Please check your internet connection (e.g. VPN service or firewall might block it). Veuillez vérifier votre connexion Internet (par exemple, le service VPN ou le pare-feu peut la bloquer). - + Failed to enable %1 TICKER Échec de l'activation de %1 - + + + Failed to disable %1 + TICKER + + + + + Endpoint not reachable Point final non accessible - + Could not reach to endpoint Impossible d'atteindre le point de terminaison - - Mismatch at %1 custom asset configuration - TICKER - Non-correspondance à la configuration de l'asset personnalisé %1 - - - - Application needs to be restarted for %1 custom asset. - TICKER - L'application doit être redémarrée pour l'asset personnalisé %1. - - - - Batch %1 failed. Reason: %2 - Le lot %1 a échoué. Raison :%2 - - - + Show Montrer - + Restart Redémarrer - + Quit Quitter - - There isn't any notification - Il n'y a aucune notification + + Notifications + + + + + There aren't any notifications + - + Mark all as read Tout marquer comme lu @@ -2278,46 +2469,97 @@ OrderForm - + Amount to sell Montant à vendre - + Amount to receive Montant à recevoir - - Min volume: - Min volume : + + Max + Max + + + + Swap 25% of your tradable balance. + + + + + Swap 50% of your tradable balance. + + + + + Swap 100% of your tradable balance. + - - How to use the pro-view slider ? - Comment utiliser le slider pro-view ? + + Min Volume + + + + + Min amount to sell + + + + + Min amount to receive + + + + + Minimum accepted trade equals 10% of order volume. + + + + + Minimum accepted trade equals 25% of order volume. + + + + + Minimum accepted trade equals 50% of order volume. + - - This slider is used to setup the order requirements you need. -Left slider: Sets the minimum amount required to process a trade. -Right slider: Sets the volume you want to trade. - Ce curseur est utilisé pour configurer les exigences de commande dont vous avez besoin. -Curseur de gauche : définit le montant minimum requis pour traiter une transaction. -Curseur droit : définit le volume que vous souhaitez trader. + + Min volume: + Min volume : - + Use custom minimum trade amount Utiliser le montant d'échange minimum personnalisé - + Price Prix - + + Reduce 1% relative to CEX market price. + + + + + Use CEX market price. + + + + + Increase 1% relative to CEX market price. + + + + Volume Volume @@ -2325,7 +2567,7 @@ Curseur droit : définit le volume que vous souhaitez trader. OrderLine - + Funds are recoverable Les fonds sont récupérables @@ -2333,7 +2575,7 @@ Curseur droit : définit le volume que vous souhaitez trader. OrderList - + No results found Aucun résultat trouvé @@ -2341,97 +2583,114 @@ Curseur droit : définit le volume que vous souhaitez trader. OrderModal - + Swap Details Détails de l'échange - + Order Details Détails de l'ordre - + + Order Type + + + + Maker Order Ordre de vente - + Taker Order Ordre d'achat - + Refund State État de remboursement - + Your swap failed but the auto-refund process for your payment started already. Please wait and keep application opened until you receive your payment back Votre échange a échoué, mais le processus de remboursement automatique de votre paiement a déjà commencé. Veuillez patienter et garder l'application ouverte jusqu'à ce que vous receviez votre remboursement - + Date Date - - ID - ID - - - + Recover Funds Récupérer des fonds - + Refunding... Remboursement... - + View on Explorer Voir dans l'explorateur - - Maker Payment Sent ID - Identifiant d'envoi du paiement du créateur + + Cancel Order + Annuler l'ordre - - Maker Payment Spent ID - Identifiant de paiement du créateur + + Error ID + ID de l'erreur - - Taker Payment Spent ID - Identifiant de paiement du preneur d'achat + + + Swap ID + ID du Swap - - Taker Payment Sent ID - Identifiant d'envoi du paiement du preneur + + Maker Payment Sent Transaction ID + - - Cancel Order - Annuler l'ordre + + Maker Payment Spent Transaction ID + - - Error ID - ID de l'erreur + + Maker Payment TXID + + + + + Taker Payment Spent Transaction ID + + + + + Taker Payment Sent Transaction ID + + + + + Taker Payment TXID + - + + Error Log Journal des erreurs - + Close Fermer @@ -2439,64 +2698,62 @@ Curseur droit : définit le volume que vous souhaitez trader. OrderRemovedModal - + Selected Order Removed Ordre sélectionné supprimé - - The selected order does not exist anymore, it might have been matched or canceled, and no order with a better price is available. Please select a new order. - La commande sélectionnée n'existe plus, elle a peut-être été matché ou annulée, et aucune commande avec un meilleur prix n'est disponible. Veuillez sélectionner un nouvelle ordre. + + The selected order does not exist anymore, it might have been matched or canceled, and no order with a better price is available. +Please select a new order. + - + OK OK - - Orders - - - Orders - Ordres - - OrdersPage - + From De - + To Vers - + Apply Filter Appliquer les changements - - + + Filter Filtrer - + Date Date - + Export CSV Exporter CSV - + + Cancel All + + + + Please choose the CSV export name and location Veuillez choisir le nom et l'emplacement de l'exportation CSV @@ -2504,7 +2761,7 @@ Curseur droit : définit le volume que vous souhaitez trader. Pagination - + items per page Nombres d'éléments par page @@ -2512,42 +2769,39 @@ Curseur droit : définit le volume que vous souhaitez trader. PasswordField - + Password Mot de passe - + Enter your wallet password Entrez le mot de passe de votre portefeuille - + At least 1 lowercase alphabetical character Au moins 1 caractère alphabétique en minuscule - + At least 1 uppercase alphabetical character Au moins 1 caractère alphabétique en majuscule - + At least 1 numeric character Au moins 1 caractère numérique - + At least 1 special character (eg. !@#$%) Au moins 1 caractère spécial (ex: ! @ # $%) - - - At least %n character(s) - - Au moins %n caractère - Au moins %n caractères - + + + Between %1 and %2 character(s) + @@ -2571,66 +2825,66 @@ Curseur droit : définit le volume que vous souhaitez trader. Portfolio - + + ADD ASSET + + + + Search asset Rechercher un actif - + Show only coins with balance Afficher uniquement les assets avec solde - + (%1/%2) (%1/%2) - + Portfolio Portfolio - - - Add asset - Ajouter un actif - PriceLine - + Set swap price for evaluation Définir le prix d'échange pour l'évaluation - + Exchange rate Taux de l'échange - + Selected Choisi - + Expensive Coûteuse - + Expedient Abordable - + %1 compared to CEX PRICE_DIFF% %1 par rapport aux CEX - + CEXchange rate Taux du CEX @@ -2638,37 +2892,32 @@ Curseur droit : définit le volume que vous souhaitez trader. PriceLineSimplified - - Set swap price for evaluation - Définir le prix d'échange pour l'évaluation - - - + Exchange rate Taux de l'échange - + Selected Choisi - + CEXchange rate Taux du CEX - + Expensive Coûteuse - + Expedient Abordable - + %1 compared to CEX PRICE_DIFF% %1 par rapport aux CEX @@ -2677,91 +2926,51 @@ Curseur droit : définit le volume que vous souhaitez trader. ProView - + Failed to place the order Échec lors du placement de l'ordre - + Placed the order L'ordre a été placé avec succès + + + QObject - - Chart - Chart - - - - Trading Information - Informations de Trading - - - - Exchange Rates - Taux d'échanges - - - - Orders - Ordres - - - - History - Historique - - - - Order Book - Carnet d'ordres - - - - Best Orders - Meilleurs offres - - - - Place Order - Placer l'ordre - - - - START SWAP - COMMENCER L'ÉCHANGE - - - - Order Selected - Ordre séléctionné + + Cannot reach the endpoint: + ReceiveModal - Receive - Recevoir + Receive %1 + TICKER + - + Only send %1 to this address TICKER - Envoyez uniquement %1 à cette adresse + - + %1 address - adresse %1 + TICKER + - - copied to clipboard - copié dans le presse-papier + + copied to clipboard. + - + Close Fermer @@ -2769,94 +2978,97 @@ Curseur droit : définit le volume que vous souhaitez trader. RecoverSeedModal - - + + View seed and private keys Afficher le seed et les clefs privées - + Please enter your password to view the seed. Veuillez entrer votre mot de passe pour voir la phrase de récupération. - - Wrong Password - Mauvais mot de passe - - - - Cancel - Annuler + + Seed + - - Seed phrase - Phrase de récupération + + Backup Seed + - - - - copied to clipboard - copié dans le presse-papier + + Public Address copied to clipboard + - - RPC password - Mot de passe RPC + + Cancel + Annuler - - phrase key copied to clipboard - clé de phrase copiée dans le presse-papiers + + Incorrect Password + Mot de passe incorrect - - Backup seed - Seed de récuperation + + + copied to clipboard + copié dans le presse-papier - + + RPC Password Mot de passe RPC - + Search a coin. Rechercher une asset. - - %1 address - adresse %1 - - - - %1 private key - clef privée %1 - - - + Public Address Adresse publique - - Private Key - Clé privée + + Private Key copied to clipboard + - - Close - Fermer + + Private Key + Clé privée - + View Voir + + RemoveContactPopup + + + Do you want to remove this contact ? + Voulez-vous supprimer ce contact ? + + + + Yes + Oui + + + + No + Non + + RestartModal @@ -2901,140 +3113,165 @@ Curseur droit : définit le volume que vous souhaitez trader. Rechercher - - SellBox - - - Sell - Vendre - - SendModal - + Failed to send Échec de l'envoi - - Failed to Send - Échec de l'envoi - - - + Prepare to send Préparez à envoyer du - + Address of the recipient Adresse du destinataire - + Amount to send Montant à envoyer - - Max amount - Montant maximum - - - + Gas price Prix ​​du gaz - - Recipient's address - Adresse du destinataire + + Cancel + Annuler - - Address Book - Carnet d'adresses + + Recipient's address + Adresse du destinataire - + The address has to be mixed case. L'adresse doit être mixte (case). - + + Failed to Broadcast + + + + Fix Réparer - - Enable Custom Fees - Activer les frais personnalisés + + MAX + MAX + + + + Fiat amount: Unavailable + - - Only use custom fees if you know what you are doing! - N'utilisez des frais personnalisés que si vous savez ce que vous faites ! + + Fiat amount: %1 + + + + + %1 amount: %2 + + + + + Specify in Fiat + + + + + Specify in Crypto + + + + + Enable Custom Fees + Activer les frais personnalisés - + Enter the custom fee Entrez les frais personnalisées - + Gas Limit Limite de gaz - + Custom Fee can't be higher than the amount Les frais personnalisées ne peuvent pas être supérieurs au montant - + Not enough funds. Pas assez de fonds. - + + You have %1 AMT TICKER Vous avez %1 - - Close - Fermer + + + Only use custom fees if you know what you are doing! + - + Prepare Préparer - - + + Send Envoyez - + + %1 address + TICKER + + + + + copied to clipboard. + + + + Amount Montant - + Fees Frais - + Date Date - + Back Retour @@ -3042,43 +3279,43 @@ Curseur droit : définit le volume que vous souhaitez trader. SendModalContactList - + Select a contact with an %1 address Sélectionnez un contact avec une adresse %1 - + Search for contacts... Rechercher des contacts... - + %1 addresses %1 adresses - + 1 address 1 adresse - - + + Back Retour - + Choose an %1 address of %2 Choisissez une adresse %1 de %2 - + Name Nom - + Address Adresse @@ -3086,42 +3323,60 @@ Curseur droit : définit le volume que vous souhaitez trader. SendResult - + Transaction Complete! Transaction terminée ! - + + %1 txid + TICKER + + + + + + copied to clipboard. + + + + Recipient's address Adresse du destinataire - + + %1 address + TICKER + + + + Amount Montant - + Fees Frais - + Date Date - + Transaction Hash Hachage de la transaction - + Close Fermer - + View on Explorer Voir dans l'explorateur @@ -3129,282 +3384,240 @@ Curseur droit : définit le volume que vous souhaitez trader. SettingModal - - Confirm Logout - Confirmer la déconnexion - - - - Are you sure you want to log out? - Êtes-vous sûr de vouloir vous déconnecter ? - - - - Yes - Oui - - - - + + 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 - + Maximum number of enabled coins Nombre maximum d'actifs activés - + Logs Journaux - - Open Folder - Ouvrir le dossier + + Open Folder + Ouvrir le dossier + + + + + 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 - - - Reset wallet configuration - Réinitialiser la configuration du portefeuille + + Wrong password! + - - This will restart your wallet with default settings - Cela redémarrera votre portefeuille avec les paramètres par défaut + + Wallet password is incorrect + - - Confirm - Confirmer + + Application Version + - - Changing theme to %1 - Changer le thème en %1 + + 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 - - DEX Version - DEX Version - - - - DEX Version copied to clipboard. - Version DEX copiée dans le presse-papiers. - - - + MM2 version Version de MM2 - + MM2 Version MM2 Version - + MM2 Version copied to clipboard. MM2 Version copiée dans le presse-papiers. - + 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 - - - - Settings - - - Fiat - Monnaie fiduciaire - - - - Recommended: - Conseillé : - - - - Enable Desktop Notifications - Activer les notifications - - - - Use QtTextRendering Or NativeTextRendering - Utilisez QtTextRendering ou NativeTextRendering - - - - Open Logs Folder - Ouvrir le répertoire de logs - - - - View seed and private keys - Voir le seed et les clefs privées - - - + Disclaimer and ToS Clause de non-responsabilité et conditions d'utilisation - - - Setup Camouflage Password - Configurez un mot de passe de camouflage - - - - Reset wallet configuration - Réinitialiser la configuration du portefeuille - - - - Delete Wallet - Supprimez le portefeuille - - - - Log out - Déconnexion - - - - mm2 version - Version de mm2 - Sidebar - - Search coin - Rechercher un actif + + Search + Rechercher - + Add asset Ajouter un actif @@ -3425,32 +3638,32 @@ Curseur droit : définit le volume que vous souhaitez trader. SubBestOrder - + Token Asset - + Available Quantity Quantité disponible - + Available Quantity (in %1) Quantité disponible (en %1) - + Fiat Volume Montant Fiduciaire - + CEX Rate Taux CEX - + %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?<br><a href='#'>Yes</a> - <a href='#no'>No</a> %1 n'est pas activé - Souhaitez vous l'activer pour pouvoir selectionnez les meilleurs offres %2 ?<br><a href='#'>Oui</a> - <a href='#no'>Non</a> @@ -3458,22 +3671,22 @@ Curseur droit : définit le volume que vous souhaitez trader. SubCoinSelector - + Token Asset - + Balance Balance - + Balance Fiat Balance Fiduciaire - + No Selectable coin. Aucune asset sélectionnable. @@ -3516,32 +3729,32 @@ Curseur droit : définit le volume que vous souhaitez trader. De - + To Vers - + Cancel Annuler - + Apply filter Appliquer changement - + Export Exportation - + Please choose the CSV export name and location Veuillez choisir le nom et l'emplacement de l'exportation CSV - + No results found Aucun résultat trouvé @@ -3550,266 +3763,242 @@ Curseur droit : définit le volume que vous souhaitez trader. SubOrders - + Orders Ordres - + Close filtering options. Fermez les options de filtrage. - + Filter Filtrer - + Date Date - + Open filtering options. Ouvrir les options de filtrage. - + Filter settings Paramètres de filtre - + From De - + To Vers - + Cancel Annuler - + Apply filter Appliquer changement - + No results found Aucun résultat trouvé - Support - - - Update available - Mise à jour disponible - - - - Up to date - À jour - + SupportModal - - Changelog - Anglicisme - Changelog - - - - Open Logs Folder - Ouvrir le répertoire de logs - - - + Frequently Asked Questions - Foire aux questions + Foire aux questions - + Do you store my private keys? - Stockez-vous mes clés privées ? + Stockez-vous mes clés privées ? - + No! %1 is non-custodial. We never store any sensitive data, including your private keys, seed phrases, or PIN. This data is only stored on the user’s device and never leaves it. You are in full control of your assets. - Non! %1 n'est pas dépositaire. Nous ne stockons jamais de données sensibles, y compris vos clés privées, vos phrases de départ ou votre code PIN. Ces données ne sont stockées que sur l'appareil de l'utilisateur et ne le quittent jamais. Vous avez le plein contrôle de vos actifs. + Non! %1 n'est pas dépositaire. Nous ne stockons jamais de données sensibles, y compris vos clés privées, vos phrases de départ ou votre code PIN. Ces données ne sont stockées que sur l'appareil de l'utilisateur et ne le quittent jamais. Vous avez le plein contrôle de vos actifs. - + How is trading on %1 different from trading on other DEXs? - En quoi le trading sur %1 est-il différent du trading sur d'autres DEX ? + En quoi le trading sur %1 est-il différent du trading sur d'autres DEX ? - - Other DEXs generally only allow you to trade assets that are based on a single blockchain network, use proxy tokens, and only allow placing a single order with the same funds. + + Other DEXs generally only allow you to trade assets that are based on a single blockchain network, use proxy tokens, and only allow placing a single order with the same funds. %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. - 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. - -%1 vous permet de trader de manière native sur deux réseaux blockchain différents sans jetons proxy. Vous pouvez également passer plusieurs commandes avec les mêmes fonds. Par exemple, vous pouvez vendre 0,1 BTC pour KMD, QTUM ou VRSC - la première commande exécutée annule automatiquement toutes les autres commandes. + - + + 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. + 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 ? + + + 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. + The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. + If you go offline, so will your orders, and any that are in progress will fail, leading to potential loss of trade / transaction fees, and a wait for the swap to timeout and issue a refund. It may also negatively affect your wallet's reputation score for future trade matching. + 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. - Les autres DEX ne vous permettent généralement de négocier 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. -Oui. Vous devez rester connecté à Internet et exécuter votre application pour terminer avec succès chaque échange atomique (de très courtes interruptions de connectivité conviennent généralement). Sinon, il existe un risque d'annulation de la transaction si vous êtes un fabricant et un risque de perte de fonds si vous êtes un preneur. -Le protocole d'échange atomique exige que les deux participants restent en ligne et surveillent les chaînes de blocs impliquées pour que le processus reste atomique. -Si vous vous déconnectez, vos commandes échoueront également, et toutes celles qui sont en cours échoueront, ce qui entraînera une perte potentielle de frais de transaction / transaction et une attente pour que l'échange expire et émette un remboursement. Cela peut également affecter négativement le score de réputation de votre portefeuille pour les futures correspondances commerciales. -Lorsque vous reviendrez en ligne, vos commandes recommenceront à être diffusées au prix que vous avez défini avant de vous déconnecter. S'il y a eu un mouvement de prix important entre-temps, vous pourriez involontairement proposer une bonne affaire à quelqu'un ! -Pour cette raison, nous vous recommandons d'annuler les commandes avant de fermer %1, ou de revoir et de réviser vos prix lors du redémarrage de %1. +For this reason, we recommend cancelling orders before closing %1, or reviewing and revising your prices when restarting %1. + - + How are the fees on %1 calculated? - Comment les frais sur %1 sont-ils calculés ? + Comment les frais sur %1 sont-ils calculés ? + + + + There are two fee categories to consider when trading on %1. + +1. %1 charges approximately 0.13% (1/777 of trading volume but not lower than 0.0001) as the trading fee for taker orders, and maker orders have zero fees. + +2. Both makers and takers will need to pay normal network fees to the involved blockchains when making atomic swap transactions. + +Network fees can vary greatly depending on your selected trading pair. + + + + + Do you provide user support? + Fournissez-vous un support utilisateur ? + + + + Yes! %1 offers support through the <a href="%2">%1 Discord server</a>. The team and the community are always happy to help! + Oui! %1 offre une assistance via le <a href="%2">%1 serveur Discord</a>. L'équipe et la communauté sont toujours ravies de vous aider ! - + Who is behind %1? - Qui est derrière %1 ? + Qui est derrière %1 ? - + %1 is developed by the Komodo team. Komodo is one of the most established blockchain projects working on innovative solutions like atomic swaps, Delayed Proof of Work, and an interoperable multi-chain architecture. - %1 est développé par l'équipe de Komodo. Komodo est l'un des projets de blockchain les plus établis travaillant sur des solutions innovantes telles que les échanges atomiques, la preuve de travail différée et une architecture multichaîne interopérable. + %1 est développé par l'équipe de Komodo. Komodo est l'un des projets de blockchain les plus établis travaillant sur des solutions innovantes telles que les échanges atomiques, la preuve de travail différée et une architecture multichaîne interopérable. - + Is it possible to develop my own white-label exchange on %1? - Est-il possible de développer mon propre échange en white label sur %1 ? + Est-il possible de développer mon propre échange en white label sur %1 ? - + Absolutely! You can read our developer documentation for more details or contact us with your partnership inquiries. Have a specific technical question? The %1 developer community is always ready to help! - Absolument! Vous pouvez lire notre documentation développeur pour plus de détails ou nous contacter avec vos demandes de partenariat. Vous avez une question technique spécifique? La communauté de développeurs %1 est toujours prête à vous aider ! + Absolument! Vous pouvez lire notre documentation développeur pour plus de détails ou nous contacter avec vos demandes de partenariat. Vous avez une question technique spécifique? La communauté de développeurs %1 est toujours prête à vous aider ! - + Which devices can I use %1 on? - Sur quels appareils puis-je utiliser %1 ? - - - - There are two fee categories to consider when trading on %1. - -1. %1 charges approximately 0.13% (1/777 of trading volume but not lower than 0.0001) as the trading fee for taker orders, and maker orders have zero fees. -2. Both makers and takers will need to pay normal network fees to the involved blockchains when making atomic swap transactions. - -Network fees can vary greatly depending on your selected trading pair. - Il existe deux catégories de frais à prendre en compte lors de la négociation sur %1. - -1. %1 facture environ 0,13% (1/777 du volume de négociation mais pas moins de 0,0001) comme frais de négociation pour les ordres preneurs, et les ordres maker n'ont aucun frais. -2. Les fabricants et les preneurs devront payer des frais de réseau normaux aux chaînes de blocs impliquées lors de transactions d'échange atomique. - -Les frais de réseau peuvent varier considérablement en fonction de votre paire de trading sélectionnée. - - - - Yes! %1 offers support through the <a href="%2">%1 Discord server</a>. The team and the community are always happy to help! - Oui! %1 offre une assistance via le <a href="%2">%1 serveur Discord</a>. L'équipe et la communauté sont toujours ravies de vous aider ! + Sur quels appareils puis-je utiliser %1 ? - + %1 is available for mobile on both <a href="%2">Android and iPhone, and for desktop on Windows, Mac, and Linux</a> operating systems. - %1 est disponible pour mobile sur <a href="%2">Android et iPhone, et pour ordinateur de bureau sur les systèmes d'exploitation Windows, Mac et Linux</a>. + %1 est disponible pour mobile sur <a href="%2">Android et iPhone, et pour ordinateur de bureau sur les systèmes d'exploitation Windows, Mac et Linux</a>. - + Compliance Info - Informations de conformité + Informations de conformité - + Due to regulatory and legal circumstances the citizens of certain jurisdictions including, but not limited to, the United States of America, Canada, Hong Kong, Israel, Singapore, Sudan, Austria, Iran and any other state, country or other jurisdiction that is embargoed by the United States of America or the European Union are not allowed to use this application. - En raison de circonstances réglementaires et juridiques, les citoyens de certaines juridictions, y compris, mais sans s'y limiter, les États-Unis d'Amérique, le Canada, Hong Kong, Israël, Singapour, le Soudan, l'Autriche, l'Iran et tout autre État, pays ou autre juridiction sous embargo par les États-Unis d'Amérique ou l'Union européenne ne sont pas autorisés à utiliser cette application. - - - - How long does each atomic swap take? - Combien de temps dure chaque échange atomique ? + En raison de circonstances réglementaires et juridiques, les citoyens de certaines juridictions, y compris, mais sans s'y limiter, les États-Unis d'Amérique, le Canada, Hong Kong, Israël, Singapour, le Soudan, l'Autriche, l'Iran et tout autre État, pays ou autre juridiction sous embargo par les États-Unis d'Amérique ou l'Union européenne ne sont pas autorisés à utiliser cette application. - - Do I need to be online for the duration of the swap? - Dois-je être en ligne pendant toute la durée du swap ? + + Changelog + Changelog - - Do you provide user support? - Fournissez-vous un support utilisateur ? + + Open Logs Folder + Ouvrir le répertoire de logs SwapProgress - + act SHORT FOR ACTUAL TIME act - + est SHORT FOR ESTIMATED est - + Progress details Détails de la progression - - SweetDexComboBox - - - Search - Rechercher - - TextAreaWithTitle - + Save Sauvegarder - + Edit Éditer - TextEditWithTitle + TextEditWithCopy - - Swap ID - ID du Swap + + copied to clipboard + copié dans le presse-papier + + + TextEditWithTitle - + copied to clipboard copié dans le presse-papier @@ -3817,7 +4006,7 @@ Les frais de réseau peuvent varier considérablement en fonction de votre paire TextFieldWithTitle - + Required Requis @@ -3833,213 +4022,281 @@ Les frais de réseau peuvent varier considérablement en fonction de votre paire Trade - + Swap Échange - + Instant trading with best orders Trading instantané avec les meilleurs ordres - + + Reset form + + + + + You have no tradable assets + + + + From De - + Enter an amount Entrez un montant - + MAX MAX - + To Vers - + Pick an order Choisir une commande - + Price Prix - + Better price found: %1. Updating forms. Meilleur prix trouvé : %1. Mise à jour du formulaire. - + Better price (%1) found but received quantity (%2) is lower than your current one (%3). Click here to update the selected order. Meilleur prix (%1) trouvé mais la quantité reçue (%2) est inférieure à votre montant de réception (%3). Cliquez ici pour mettre à jour la commande sélectionnée. - - Reset form. - Réinitialiser le formulaire. - - - + %1 - + Tradable: Disponible: - + Min: %1 - + Pick a coin Choisissez un actif - + SWAP NOW ÉCHANGER MAINTENANT - + Failed to place the order Échec lors du placement de l'ordre - + Placed the order L'ordre a été placé - + Entered amount must be superior than 0. Le montant saisi doit être supérieur à 0. - + You must select an order. Vous devez sélectionner une commande. - + Entered amount is below the minimum required by this order: %1 Le montant saisi est inférieur au minimum requis par cette commande : %1 - - + + %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 - - - Search - Rechercher + + %1 balance does not have enough funds to pay the gas of %2 transactions + - + No buy orders found for %1. Aucun ordre d'achat trouvé pour %1. - + You can check later or try to sell a different coin. Vous pouvez vérifier plus tard ou essayer de vendre un actif différent. - + + Calculating fee estimate... + + + + Total %1 fees: Frais totaux %1 : - + %2 (%3) + + TradeViewHeader + + + Pro View Settings + + + + + Display Settings + + + + + Ticker Selectors + + + + + Trading Information + Informations de Trading + + + + Order Book + Carnet d'ordres + + + + Best Orders + Meilleurs offres + + + + Place Order + Placer l'ordre + + TransactionDetailsModal - + Transaction Details Détails de la transaction - + + %1 txid + TICKER + + + + + copied to clipboard. + + + + Amount Montant - + Fees Frais - + + From address + + + + + To address + + + + Date Date - + Unconfirmed Non confirmé - + Transaction Hash Hachage de la transaction - + Confirmations Confirmations - + Block Height Hauteur de bloc - + From De - + To Vers - + Notes Remarques - + Close Fermer - + View on Explorer Voir dans l'explorateur @@ -4047,22 +4304,22 @@ Les frais de réseau peuvent varier considérablement en fonction de votre paire Transactions - + Received Reçue - + Sent Envoyé - + fees frais - + Unconfirmed Non confirmé @@ -4076,16 +4333,11 @@ Les frais de réseau peuvent varier considérablement en fonction de votre paire - WalletNameField + Vertical - - Wallet Name - Nom du portefeuille - - - - Enter the name of your wallet here - Entrez le nom du portefeuille ici + + Order Book + Carnet d'ordres @@ -4106,118 +4358,165 @@ Les frais de réseau peuvent varier considérablement en fonction de votre paire Importer un portefeuille - + + Search your wallets... + + + + My Wallets Mes portefeuilles - - + + No wallets found! + + + + + Delete Supprimez - + Enter password to confirm deletion of Entrez le mot de passe pour confirmer la suppression de - + wallet portefeuille - + Type password Tapez votre mot de passe - + Cancel Annuler - - + + Wallet status État du portefeuille - + wallet deleted successfully portefeuille supprimé avec succès - - + + Ok Ok - + wallet password is incorrect le mot de passe du portefeuille est incorrect + + ZcashParamsModal + + + %1 Activation Failed! + + + + + To activate ZHTLC coins, you need to download the Zcash Params. +This might take a few minutes... + + + + + Download params & enable coins + + + + + More Info + + + + + Close + Fermer + + + + atomic_dex::settings_page + + + An error has occurred. + + + 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 on the convert button to turn it into a mixed case address - Checksum-non valide pour %1. Cliquez sur le bouton pour avoir une adresse de cas mixte + + Invalid checksum for %1. Click the button to convert to mixed case address. + - - Legacy address used for %1, click on the convert button to convert it to a Cashaddress. - Ancien format d'adresse utilisée pour %1, cliquez sur le bouton pour la convertir en Cashaddress. + + 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 @@ -4225,32 +4524,12 @@ Les frais de réseau peuvent varier considérablement en fonction de votre paire main - + Logout Se déconnecter - - Confirm Logout - Confirmer la déconnexion - - - - Are you sure you want to log out? - Êtes-vous sûr de vouloir vous déconnecter ? - - - - Yes - Oui - - - - Cancel - Annuler - - - + Balance Balance diff --git a/atomic_defi_design/assets/languages/atomic_defi_lang_template.ts b/atomic_defi_design/assets/languages/atomic_defi_lang_template.ts new file mode 100644 index 0000000000..5836a5dfc1 --- /dev/null +++ b/atomic_defi_design/assets/languages/atomic_defi_lang_template.ts @@ -0,0 +1,3713 @@ + + + + + AddAddressForm + + + Use standard network address + + + + Label + + + + This key already exists. + + + + Address + + + + + Cancel + + + + Convert + + + + Edit + + + + Add + + + + You need to enable %1 before adding this kind of address. + + + + Enable + + + + AddCustomCoinModal + + + Get the contract address from + + + + Choose the asset type + + + + 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! + + + + Asset not found, please go back and make sure Contract Address is correct + + + + Config Fields + + + + Fetched Data + + + + Submit & Restart + + + + AddTagPopup + + + Tag name + + + + Contact already has this tag. + + + + + ADD + + + + AmountChart + + + Work in progress + + + + App + + + Recover Funds Result + + + + AssetFromStandardSelector + + + Choose a valid + + + + asset + + + + Search an asset + + + + Disabled + + + + AssetPieChart + + + Assets + + + + AssetsList + + + Asset + + + + Balance + + + + Fiat Balance + + + + Change 24h + + + + Price + + + + Source + + + + Activating: + + + + Price provider is: %1 + + + + Bottom + + + Settings + + + + Support + + + + Privacy + + + + Disable Privacy? + + + + Enter wallet password to confirm + + + + Type password + + + + Confirm + + + + Cancel + + + + Privacy status + + + + Privacy mode disabled successfully + + + + + Ok + + + + Wrong password! + + + + wallet password is incorrect + + + + CamouflagePasswordModal + + + Setup Camouflage Password + + + + Camouflage Password is a secret password for emergency situations. + + + + Using it to login will display your balance lower than it actually is. + + + + Here you enter the suffix and at login you need to enter {real_password}{suffix} + + + + Password suffix + + + + Confirm pasword suffix + + + + Enter a password suffix + + + + Enter the same password suffix to confirm + + + + Cancel + + + + Save + + + + CannotEnableCoinModal + + + Failed to enable %1 + + + + Enabling %1 did not succeed. Limit of enabled coins might have been reached. + + + + Change limit in settings + + + + Cancel + + + + Center + + + Portfolio + + + + Wallet + + + + DEX + + + + Address Book + + + + Fiat + + + + CexInfoModal + + + Market Data + + + + Market data (prices, charts, etc.) marked with the ⓘ icon originates from third-party sources.<br><br>Data is sourced via <a href="https://bandprotocol.com/">Band Decentralized Oracle</a> and <a href="https://coingecko.com">CoinGecko</a>.<br><br><b>Oracle Supported Pairs:</b><br>%1<br><br><b>Last reference (Band Oracle):</b><br><a href="%2">%2</a> + + + + Chart + + + Loading market data + + + + There is no chart data for this pair yet + + + + ClaimRewardsModal + + + Failed to prepare to claim rewards + + + + Claim your %1 reward? + TICKER + + + + No UTXOs eligible for claiming + + + + Transaction fee is higher than the reward! + + + + You will receive + + + + Refresh + + + + Read more about KMD active users rewards + + + + UTXO + + + + Amount + + + + Reward + + + + Accruing Start + + + + Accruing Stop + + + + Time Left + + + + Error + + + + Locktime is not set + + + + Locktime is less than the threshold + + + + UTXO height is greater than end of the era + + + + UTXO amount is less than 10 + + + + One hour did not pass yet + + + + Transaction is in mempool + + + + Unknown problem + + + + Cancel + + + + Confirm + + + + CoinMenu + + + Disable %1 + TICKER + + + + Disable and Delete %1 + TICKER + + + + Disable all %1 assets + + + + Disable all assets + + + + Disable 0 balance assets + + + + ComboBoxWithSearchBar + + + Search + + + + Combo_fiat + + + Language + + + + Fiat + + + + Recommended: + + + + ConfirmMultiOrderTradeModal + + + Confirm Multi Order Details + + + + These swaps requests can not be undone and this is the final event! + + + + These transactions can take up to 60 mins - DO NOT close this application! + + + + Same funds will be used until an order matches. + + + + Note that if one order is filled other will not be cancelled. + + + + Cancel + + + + Confirm + + + + Placed multiple orders + + + + ConfirmTradeModal + + + Confirm Exchange Details + + + + Trade price is more than 50% different to CEX! Confirm? + + + + This swap request can not be undone and is a final event! + + + + This transaction can take up to 60 mins - DO NOT close this application! + + + + Loading fees... + + + + <b>Total %1 fees:</b> + + + + Security configuration + + + + dPoW protected + + + + %1 confirmations for incoming %2 transactions + + + + Read more about dPoW + + + + Use custom protection settings for incoming %1 transactions + TICKER + + + + Enable Komodo dPoW security + + + + Required Confirmations + + + + Warning, this atomic swap is not dPoW protected! + + + + Cancel + + + + Confirm + + + + CopyFieldButton + + + Copied to Clipboard + + + + Dashboard + + + The current number of enabled coins does not match your configuration specification. Your assets configuration will be reset. + + + + Matching + + + + Order Matching + + + + Matched + + + + Order Matched + + + + Ongoing + + + + Swap Ongoing + + + + Successful + + + + Swap Successful + + + + Refunding + + + + Failed + + + + Swap Failed + + + + Unknown + + + + Unknown State + + + + Started + + + + Negotiated + + + + Taker fee sent + + + + Maker payment received + + + + Maker payment wait confirm started + + + + Maker payment validated and confirmed + + + + Taker payment sent + + + + Taker payment spent + + + + Maker payment spent + + + + Finished + + + + Start failed + + + + Negotiate failed + + + + Taker fee validate failed + + + + Maker payment transaction failed + + + + Maker payment Data send failed + + + + Maker payment wait confirm failed + + + + Taker payment validate failed + + + + Taker payment wait confirm failed + + + + Taker payment spend failed + + + + Maker payment wait refund started + + + + Maker payment refunded + + + + Maker payment refund failed + + + + DatePicker + + + Date + + + + DefaultCopyIcon + + + copied to clipboard + + + + DefaultRangeSlider + + + Min + + + + Max + + + + DefaultTextEdit + + + copied to clipboard + + + + DeleteWalletModal + + + Delete Wallet + + + + Are you sure you want to delete %1 wallet? + WALLET_NAME + + + + If so, make sure you record your seed phrase in order to restore your wallet in the future. + + + + Enter your wallet password + + + + Wrong Password + + + + Cancel + + + + Delete + + + + DexAppPasswordField + + + Type password + + + + DexKeyChecker + + + At least 1 lowercase alphabetical character + + + + At least 1 uppercase alphabetical character + + + + At least 1 numeric character + + + + At least 1 special character (eg. !@#$%) + + + + At least %n character(s) + + + + Password and Confirm Password have to be same + + + + DexPaginator + + + items per page + + + + DexRangeSlider + + + Min + + + + Half + + + + Max + + + + DexSweetComboBox + + + Search + + + + EditContactModal + + + Edit contact + + + + Contact name + + + + Enter a contact name + + + + Address list + + + + Address Book + + + + address copied to clipboard + + + + Edit + + + + + Add + + + + Tags + + + + Add tag + + + + Close + + + + Confirm + + + + EnableAssetModal + + + The selected address belongs to a disabled asset, you need to enabled it before sending. + + + + Enable + + + + Cancel + + + + EnableCoinModal + + + Enable assets + + + + Select all assets + + + + All assets are already enabled! + + + + You can still enable %1 assets. Selected: %2. + + + + Search asset + + + + Change assets limit + + + + Add a custom asset + + + + Close + + + + Enable + + + + EulaModal + + + Disclaimer & Terms of Service + + + + Accept EULA + + + + Accept Terms and Conditions + + + + Close + + + + Cancel + + + + Confirm + + + + FatalErrorModal + + + Fatal Error + + + + Connection has been lost. You have been disconnected. + + + + Close + + + + FeeInfo + + + Minimum fee + + + + Fees will be calculated + + + + General + + + %n day(s) + + + + %nd + day + + + + %nh + hours + + + + %nm + minutes + + + + %ns + seconds + + + + %nms + milliseconds + + + + - + + + + <b>Taker tx fee:</b> + + + + <b>Dex tx fee:</b> + + + + <b>Dex fee:</b> + + + + <b>Maker tx fee:</b> + + + + %1 %2 %3 (%4) + + + + 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 + + + + Header + + + You get + + + + You send + + + + Fiat Price + + + + CEX rate + + + + Price + + + + Quantity + + + + Total + + + + ImportWallet + + + Failed to Import the wallet + + + + Import wallet - Setup + + + + Import wallet - Choose password + + + + Wallet Name + + + + Enter seed + + + + Your seed is not BIP39 compliant. +Try again or select 'Allow custom seed' to continue. + + + + + i understand + + + + Ok + + + + Allow custom seed + + + + <strong>Allow custom seed</strong> + + + + Custom seed phrases might be less secure and easier to crack than a generated BIP39 compliant seed phrase or private key (WIF).<br><br>To confirm you understand the risk and know what you are doing, type <strong>'I understand'</strong> in the box below. + + + + I understand + + + + Next + + + + Enter the same password to confirm + + + + Continue + + + + LinksRow + + + Join our Discord server + + + + Follow us on Twitter + + + + Go to Support Guides + + + + List + + + Funds are recoverable + + + + Best Orders + + + + Enter volume to see best orders. + + + + ListDelegate + + + %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?<br><a href='#'>Yes</a> - <a href='#no'>No</a> + + + + This order requires a minimum amount of %1 %2 <br>You don't have enough funds.<br> %3 + + + + LogModal + + + Close + + + + Logging + + + Loading, please wait + + + + Initializing MM2 + + + + Enabling assets + + + + Getting ready + + + + Login + + + Incorrect Password + + + + Log In + + + + Cancel + + + + LogoutModal + + + Exit %1 or go to login menu? + + + + Warning: You currently have a swap in progress. +Logging out may result in a failed swap. + + + + Warning: You currently have open maker orders. +They will be removed from the orderbook until you log in again. + + + + Login menu + + + + Exit + + + + Cancel + + + + Main + + + Segwit + + + + Confirmation + + + + Do you want to send your %1 funds to %2 wallet first? + + + + Success + + + + Your transaction is send, may take some time to arrive + + + + Price + + + + Change 24hr + + + + Porfolio + + + + Contract Address + + + + Send + + + + Enable %1 ? + + + + Yes + + + + No + + + + Receive + + + + Swap + + + + is wallet only + + + + Rewards + + + + Faucet + + + + + + Public Key + + + + Copied to Clipboard + + + + Loading market data + + + + There is no chart data for this ticker yet + + + + Fetching transactions... + + + + Please wait, %1 is %2 + + + + % activated... + + + + No transactions available + + + + Click to view your address on %1 (%2) block explorer + + + + Trade + + + + Trading Information + + + + Chart + + + + + Orders + + + + + History + + + + Place Order + + + + Order Selected + + + + START SWAP + + + + + Address Book + + + + Search contact + + + + + NEW CONTACT + + + + Name + + + + Tags + + + + Edit + + + + Delete + + + + address copied to clipboard + + + + This contact does not have any registered address. + + + + MarketModeSelector + + + Sell %1 + TICKER + + + + Buy %1 + TICKER + + + + MinTradeModal + + + Minimum Trading Amount + + + + the minimum amount of %1 coin available for the order; the min_volume must be greater than or equal to %2; it must be also less or equal than volume param; default is %3 + + + + MultiOrder + + + %1 price is zero! + TICKER + + + + %1 receive volume is lower than minimum trade amount + TICKER + + + + Error: + + + + You'll receive %1 + AMOUNT TICKER + + + + Price + + + + NewContactPopup + + + Contact name + + + + This contact name already exists. + + + + + ADD + + + + NewUpdateModal + + + + + Searching new updates + + + + Fetching... + + + + + + + Close + + + + Could not check new updates for the following reason: +%1 + + + + New version found + + + + Mandatory version found + + + + %1 %2 is available ! + + + + This update is mandatory to continue using the application + + + + Close Dex + + + + Your application is updated. + + + + Download + + + + NewWallet + + + Wrong word, please check again + + + + st + + + + nd + + + + rd + + + + th + + + + Failed to create a wallet + + + + New Wallet + + + + Confirm Seed + + + + Choose Password + + + + Important: Back up your seed phrase before proceeding! + + + + We recommend storing it offline. + + + + Generated Seed + + + + Seed phrase + + + + copied to clipboard + + + + Next + + + + Let's double check your seed phrase + + + + Your seed phrase is important - that's why we like to make sure it's correct. We'll ask you three different questions about your seed phrase to make sure you'll be able to easily restore your wallet whenever you want. + + + + Enter the + + + + word + + + + Check + + + + Enter the same password to confirm + + + + Continue + + + + NoConnection + + + No connection + + + + Please make sure you are connected to the internet + + + + Will automatically retry in %1 seconds + + + + Retry + + + + NotificationsModal + + + Matching + + + + Order Matching + + + + Matched + + + + Order Matched + + + + Ongoing + + + + Swap Ongoing + + + + Successful + + + + Swap Successful + + + + Refunding + + + + Failed + + + + Swap Failed + + + + Unknown + + + + Unknown State + + + + Swap status updated + + + + You sent %1 + + + + You received %1 + + + + Your wallet balance changed + + + + %1 Enable status + TICKER + + + + Please check your internet connection (e.g. VPN service or firewall might block it). + + + + Failed to enable %1 + TICKER + + + + Failed to disable %1 + TICKER + + + + Endpoint not reachable + + + + Could not reach to endpoint + + + + Mismatch at %1 custom asset configuration + TICKER + + + + Application needs to be restarted for %1 custom asset. + TICKER + + + + Batch %1 failed. Reason: %2 + + + + Show + + + + Restart + + + + Quit + + + + Notifications + + + + There aren't any notifications + + + + Mark all as read + + + + OrderForm + + + Price + + + + Reduce 1% relative to CEX market price. + + + + Use CEX market price. + + + + Increase 1% relative to CEX market price. + + + + Volume + + + + Amount to sell + + + + Amount to receive + + + + Max + + + + Swap 25% of your tradable balance. + + + + Swap 50% of your tradable balance. + + + + Swap 100% of your tradable balance. + + + + Min Volume + + + + Min amount to sell + + + + Min amount to receive + + + + Minimum accepted trade equals 10% of order volume. + + + + Minimum accepted trade equals 25% of order volume. + + + + Minimum accepted trade equals 50% of order volume. + + + + Min volume: + + + + Use custom minimum trade amount + + + + OrderLine + + + Funds are recoverable + + + + OrderList + + + No results found + + + + OrderModal + + + Swap Details + + + + Order Details + + + + Order Type + + + + Maker Order + + + + Taker Order + + + + Refund State + + + + Your swap failed but the auto-refund process for your payment started already. Please wait and keep application opened until you receive your payment back + + + + Date + + + + Error ID + + + + + Error Log + + + + Close + + + + Cancel Order + + + + + Swap ID + + + + Maker Payment Sent Transaction ID + + + + Maker Payment Spent Transaction ID + + + + Maker Payment TXID + + + + Taker Payment Spent Transaction ID + + + + Taker Payment Sent Transaction ID + + + + Taker Payment TXID + + + + Recover Funds + + + + Refunding... + + + + View on Explorer + + + + OrderRemovedModal + + + Selected Order Removed + + + + The selected order does not exist anymore, it might have been matched or canceled, and no order with a better price is available. +Please select a new order. + + + + OK + + + + OrdersPage + + + + Filter + + + + Date + + + + Export CSV + + + + Apply Filter + + + + Cancel All + + + + From + + + + To + + + + Please choose the CSV export name and location + + + + Pagination + + + items per page + + + + PasswordField + + + Password + + + + Enter your wallet password + + + + At least 1 lowercase alphabetical character + + + + At least 1 uppercase alphabetical character + + + + At least 1 numeric character + + + + At least 1 special character (eg. !@#$%) + + + + At least %n character(s) + + + + PasswordForm + + + Password + + + + Confirm Password + + + + Enter the same password to confirm + + + + Portfolio + + + ADD ASSET + + + + Search asset + + + + Show only coins with balance + + + + (%1/%2) + + + + Portfolio + + + + PriceLine + + + Set swap price for evaluation + + + + Exchange rate + + + + Selected + + + + Expensive + + + + Expedient + + + + %1 compared to CEX + PRICE_DIFF% + + + + CEXchange rate + + + + PriceLineSimplified + + + Exchange rate + + + + Selected + + + + CEXchange rate + + + + Expensive + + + + Expedient + + + + %1 compared to CEX + PRICE_DIFF% + + + + ProView + + + Failed to place the order + + + + Placed the order + + + + QObject + + + Cannot reach the endpoint: + + + + ReceiveModal + + + Receive %1 + TICKER + + + + Only send %1 to this address + TICKER + + + + %1 address + TICKER + + + + copied to clipboard. + + + + Close + + + + RecoverSeedModal + + + + View seed and private keys + + + + Please enter your password to view the seed. + + + + Seed + + + + Backup Seed + + + + Public Address copied to clipboard + + + + Cancel + + + + View + + + + + copied to clipboard + + + + + RPC Password + + + + Search a coin. + + + + Public Address + + + + Private Key copied to clipboard + + + + Private Key + + + + RemoveContactPopup + + + Do you want to remove this contact ? + + + + Yes + + + + No + + + + RestartModal + + + Applying the changes... + + + + Restarting the application. %1 + + + + Restarting the application... + + + + RightClickMenu + + + Cut + + + + Copy + + + + Paste + + + + SearchField + + + Search + + + + SendModal + + + Failed to send + + + + Prepare to send + + + + Address of the recipient + + + + Amount to send + + + + Gas price + + + + Recipient's address + + + + The address has to be mixed case. + + + + Taproot not supported + + + + Failed to Broadcast + + + + Fix + + + + MAX + + + + Fiat amount: Unavailable + + + + Fiat amount: %1 + + + + %1 amount: %2 + + + + Specify in Fiat + + + + Specify in Crypto + + + + Enable Custom Fees + + + + Only use custom fees if you know what you are doing! + + + + Enter the custom fee + + + + Gas Limit + + + + Custom Fee can't be higher than the amount + + + + Not enough funds. + + + + + You have %1 + AMT TICKER + + + + Close + + + + Prepare + + + + + Send + + + + %1 address + TICKER + + + + copied to clipboard. + + + + Amount + + + + Fees + + + + Date + + + + Back + + + + SendModalContactList + + + Select a contact with an %1 address + + + + Search for contacts... + + + + %1 addresses + + + + 1 address + + + + + Back + + + + Choose an %1 address of %2 + + + + Name + + + + Address + + + + SendResult + + + Transaction Complete! + + + + %1 txid + TICKER + + + + + copied to clipboard. + + + + Recipient's address + + + + %1 address + TICKER + + + + Amount + + + + Fees + + + + Date + + + + Transaction Hash + + + + Close + + + + View on Explorer + + + + SettingModal + + + + 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 + + + + + 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 + + + + Disclaimer and ToS + + + + Application version + + + + MM2 version + + + + MM2 Version + + + + MM2 Version copied to clipboard. + + + + Qt version + + + + Qt Version + + + + Qt Version copied to clipboard. + + + + Search Update + + + + Logout + + + + Settings + + + Fiat + + + + Recommended: + + + + Enable Desktop Notifications + + + + Use QtTextRendering Or NativeTextRendering + + + + Open Logs Folder + + + + View seed and private keys + + + + Disclaimer and ToS + + + + Setup Camouflage Password + + + + Reset wallet configuration + + + + Delete Wallet + + + + Log out + + + + mm2 version + + + + Sidebar + + + Search + + + + Add asset + + + + SmartChartView + + + Loading market data + + + + There is no chart data for this ticker yet + + + + SubBestOrder + + + Token + + + + Available Quantity + + + + Available Quantity (in %1) + + + + Fiat Volume + + + + CEX Rate + + + + %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?<br><a href='#'>Yes</a> - <a href='#no'>No</a> + + + + SubCoinSelector + + + Token + + + + Balance + + + + Balance Fiat + + + + No Selectable coin. + + + + SubHistory + + + History + + + + Filter + + + + Date + + + + Close filtering options. + + + + Open filtering options. + + + + Filter settings + + + + From + + + + To + + + + Cancel + + + + Apply filter + + + + Export + + + + Please choose the CSV export name and location + + + + No results found + + + + SubOrders + + + + Orders + + + + Close filtering options. + + + + Filter + + + + Date + + + + Open filtering options. + + + + Filter settings + + + + From + + + + To + + + + Cancel + + + + Apply filter + + + + No results found + + + + SupportModal + + + Frequently Asked Questions + + + + Do you store my private keys? + + + + No! %1 is non-custodial. We never store any sensitive data, including your private keys, seed phrases, or PIN. This data is only stored on the user’s device and never leaves it. You are in full control of your assets. + + + + How is trading on %1 different from trading on other DEXs? + + + + Other DEXs generally only allow you to trade assets that are based on a single blockchain network, use proxy tokens, and only allow placing a single order with the same funds. + +%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. + + + + 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>. + + + + Do I need to be online for the duration of the swap? + + + + 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. + +The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. + +If you go offline, so will your orders, and any that are in progress will fail, leading to potential loss of trade / transaction fees, and a wait for the swap to timeout and issue a refund. It may also negatively affect your wallet's reputation score for future trade matching. + +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. + + + + How are the fees on %1 calculated? + + + + There are two fee categories to consider when trading on %1. + +1. %1 charges approximately 0.13% (1/777 of trading volume but not lower than 0.0001) as the trading fee for taker orders, and maker orders have zero fees. + +2. Both makers and takers will need to pay normal network fees to the involved blockchains when making atomic swap transactions. + +Network fees can vary greatly depending on your selected trading pair. + + + + Do you provide user support? + + + + Yes! %1 offers support through the <a href="%2">%1 Discord server</a>. The team and the community are always happy to help! + + + + Who is behind %1? + + + + %1 is developed by the Komodo team. Komodo is one of the most established blockchain projects working on innovative solutions like atomic swaps, Delayed Proof of Work, and an interoperable multi-chain architecture. + + + + Is it possible to develop my own white-label exchange on %1? + + + + Absolutely! You can read our developer documentation for more details or contact us with your partnership inquiries. Have a specific technical question? The %1 developer community is always ready to help! + + + + Which devices can I use %1 on? + + + + %1 is available for mobile on both <a href="%2">Android and iPhone, and for desktop on Windows, Mac, and Linux</a> operating systems. + + + + Compliance Info + + + + Due to regulatory and legal circumstances the citizens of certain jurisdictions including, but not limited to, the United States of America, Canada, Hong Kong, Israel, Singapore, Sudan, Austria, Iran and any other state, country or other jurisdiction that is embargoed by the United States of America or the European Union are not allowed to use this application. + + + + Changelog + + + + Open Logs Folder + + + + SwapProgress + + + act + SHORT FOR ACTUAL TIME + + + + est + SHORT FOR ESTIMATED + + + + Progress details + + + + TextAreaWithTitle + + + Save + + + + Edit + + + + TextEditWithCopy + + + copied to clipboard + + + + TextEditWithTitle + + + copied to clipboard + + + + TextFieldWithTitle + + + Required + + + + Toast + + + Click here to see the details + + + + Trade + + + Swap + + + + Instant trading with best orders + + + + Reset form + + + + You have no tradable assets + + + + From + + + + Enter an amount + + + + MAX + + + + To + + + + Pick an order + + + + Price + + + + Better price found: %1. Updating forms. + + + + Better price (%1) found but received quantity (%2) is lower than your current one (%3). Click here to update the selected order. + + + + %1 + + + + Tradable: + + + + Min: %1 + + + + Pick a coin + + + + SWAP NOW + + + + Failed to place the order + + + + Placed the order + + + + Entered amount must be superior than 0. + + + + You must select an order. + + + + Entered amount is below the minimum required by this order: %1 + + + + + %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 + + + + %1 balance does not have enough funds to pay the gas of %2 transactions + + + + No buy orders found for %1. + + + + You can check later or try to sell a different coin. + + + + Calculating fee estimate... + + + + Total %1 fees: + + + + %2 (%3) + + + + TradeViewHeader + + + Pro View Settings + + + + Display Settings + + + + Ticker Selectors + + + + Trading Information + + + + Order Book + + + + Best Orders + + + + Place Order + + + + TransactionDetailsModal + + + Transaction Details + + + + %1 txid + TICKER + + + + copied to clipboard. + + + + Amount + + + + Fees + + + + From address + + + + To address + + + + Date + + + + Unconfirmed + + + + Transaction Hash + + + + Confirmations + + + + Block Height + + + + From + + + + To + + + + Notes + + + + Close + + + + View on Explorer + + + + Transactions + + + Sent + + + + Received + + + + fees + + + + Unconfirmed + + + + UpdateInvalidChecksum + + + The downloaded update archive is corrupted ! + + + + Vertical + + + Order Book + + + + WalletsView + + + Welcome + + + + New wallet + + + + Import wallet + + + + Search your wallets... + + + + My Wallets + + + + No wallets found! + + + + + Delete + + + + Enter password to confirm deletion of + + + + wallet + + + + Type password + + + + Cancel + + + + + Wallet status + + + + wallet deleted successfully + + + + + Ok + + + + wallet password is incorrect + + + + ZcashParamsModal + + + %1 Activation Failed! + + + + To activate ZHTLC coins, you need to download the Zcash Params. +This might take a few minutes... + + + + Download params & enable coins + + + + More Info + + + + Close + + + + atomic_dex::settings_page + + + An error has occurred. + + + + 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 + + + + main + + + Logout + + + + Balance + + + diff --git a/atomic_defi_design/assets/languages/atomic_defi_ru.ts b/atomic_defi_design/assets/languages/atomic_defi_ru.ts index fb38f9ed71..31ae9a0ed6 100644 --- a/atomic_defi_design/assets/languages/atomic_defi_ru.ts +++ b/atomic_defi_design/assets/languages/atomic_defi_ru.ts @@ -2,502 +2,269 @@ - QPlatformTheme + AddAddressForm - &Yes - &Да + + Use standard network address + - &No - &Нет + + Label + + + This key already exists. + Этот ключ уже существует. + + + + Address + Адрес + + + + Cancel - Отменить + + + + + Convert + Преобразовать + + + + Edit + Редактировать + + + + Add + Добавить + + + + You need to enable %1 before adding this kind of address. + + + + + Enable + Добавить AddCustomCoinModal - + Choose the asset type Выберите тип монеты - - Type - Тип - - - + Cancel Отменить - - - + + + Next Далее - - + Enter the contract address Введите адрес контракта - + Choose the asset ticker Введите тикер монеты - + Ticker Тикер - + Enter the ticker Введите тикер - - Contract Address - Адрес контракта - - - + 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! ПРЕДУПРЕЖДЕНИЕ: Приложение будет немедленно перезапущено для применения изменений! - + Asset not found, please go back and make sure Contract Address is correct Токен не найден, убедитесь, что адрес контракта указан верно - + Config Fields Параметры конфигурации - + Fetched Data Полученные данные - + Submit & Restart Отправить и перезапустить - AddressBook - - - Address Book - Адресная книга - - - - New Contact - Новый контакт - - - - Search a contact by name or tags - Поиск контакта по имени или тегам - + AddTagPopup - - Name - Имя - - - - Tags (first 6) - Теги (первые 6) - - - - Actions - Действия - - - - Edit - Редактировать - - - - Remove - Удалить - - - - Do you want to remove this contact ? - Вы действительно хотите удалить этот контакт? - - - - Yes - Да - - - - No - Нет - - - - AddressBookAddContactAddressModal - - - Create a new address - Добавить новый адрес - - - - Edit address entry - Внести изменения в адрес - - - - Selected wallet: %1 - Выбранный кошелек: %1 - - - - NONE - НИ ОДИН - - - - Enter a name - Введите имя - - - - This key already exists. - Этот ключ уже существует. - - - - Enter the address - Введите адрес - - - - Validate - Валидировать - - - - Cancel - Отменить - - - - Convert - Преобразовать - - - - AddressBookEditContactModal - - - Edit contact - Редактировать контакт - - - - Contact Name - Имя контакта - - - - Enter a contact name - Введите имя - - - - Address List - Список адресов - - - - Search for an address entry. - Поиск адреса. - - - - Type - Тип - - - - Key - Ключ - - - - Address - Адрес - - - - Actions - Действия - - - - New Address - Новый Адрес - - - - Tags - Теги - - - - + - + - - - - Confirm - Подтвердить - - - - - Cancel - Отменить - - - - The selected address belongs to a disabled coin, you need to enabled it before sending. - Вы выбрали адрес отключенной монеты, ее необходимо включить перед отправкой. - - - - Enable - Добавить - - - - Cannot send to this address - Отправка на этот адрес невозможна - - - - Your balance is empty - Баланс отсутствует - - - - Ok - ОК - - - - Remove address ? - Удалить адрес ? + + Tag name + - - Yes - Да + + Contact already has this tag. + - - No - Нет + + + ADD + - AddressBookNewContactCategoryModal - - - Add a new tag - Добавить новый тег - - - - Enter the tag name - Добавить имя тега - - - - This contact already has this tag - У этого контакта уже есть этот тег - - - - Add - Добавить - + AmountChart - - Cancel - Отменить + + Work in progress + Разработка в процессе - AddressBookNewContactModal - - - Create a new contact - Добавить новый контакт - - - - Enter the contact name - Введите имя контакта - - - - This contact name already exists. - Контакт с таким именем уже существует. - - - - Confirm - Подтвердить - + App - - Cancel - Отменить + + Recover Funds Result + Результат восстановления средств - AddressBookSendWalletSelector + AssetFromStandardSelector - + Choose a valid - Выберите валидную - - - - coin - монету + Выберите валидную - - - AddressBookWalletTypeListModal - - Select wallet type - Выберите тип кошелька - - - - Search - Поиск + + asset + - - - AmountChart - - Work in progress - Разработка в процессе + + Search an asset + - - - App - - Recover Funds Result - Результат восстановления средств + + Disabled + AssetPieChart - + Assets Активы @@ -505,32 +272,42 @@ AssetsList - + Asset Актив - + Balance Баланс - + + Fiat Balance + + + + Change 24h Изменение за 24ч - + Price Цена - + Source Источник - + + Activating: + + + + Price provider is: %1 Провайдер цены: %1 @@ -538,27 +315,70 @@ Bottom - + Settings Настройки - + Support Поддержка - + Privacy Скрыть баланс - - - BuyBox - - Buy - Купить + + Disable Privacy? + + + + + Enter wallet password to confirm + + + + + Type password + Введите пароль + + + + Confirm + + + + + Cancel + + + + + Privacy status + + + + + Privacy mode disabled successfully + + + + + + Ok + Ок + + + + Wrong password! + + + + + wallet password is incorrect + введен неправильный пароль @@ -569,64 +389,51 @@ Установить камуфляжный пароль - + Camouflage Password is a secret password for emergency situations. Камуфляжный пароль - секретный пароль для чрезвычайных ситуаций. - + Using it to login will display your balance lower than it actually is. Используйте его во время входа, чтобы ваш баланс не отображался полностью. - + Here you enter the suffix and at login you need to enter {real_password}{suffix} Здесь вы можете ввести окончание пароля. Во время входа в приложения необходимо будет ввести {ваш пароль}{окончание} - + Password suffix Суффикс пароля - + Confirm pasword suffix Подтвердите суффикс пароля - + Enter a password suffix Задайте суффикс пароля - + Enter the same password suffix to confirm Подтвердите суффикс пароля - + Cancel Отменить - + Save Сохранить - - CandleStickChart - - - Loading market data - Загрузка данных - - - - There is no chart data for this pair yet - Нет данных для построения графика для этой торговой пары - - CannotEnableCoinModal @@ -691,122 +498,134 @@ Рыночные данные (цены, графики, и тд.) отмеченные ⓘ иконкой получены от <a href="https://bandprotocol.com/">Band Decentralized Oracle</a> и <a href="https://coingecko.com">CoinGecko</a>.<br><br><b>Oracle Supported Pairs:</b><br>%1<br><br><b>Last reference (Band Oracle):</b><br><a href="%2">%2</a> + + Chart + + + Loading market data + Загрузка рыночных данных + + + + There is no chart data for this pair yet + Нет данных для построения графика для этой торговой пары + + ClaimRewardsModal - + Failed to prepare to claim rewards Ошибка при создании транзакции для получения вознаграждения - + Claim your %1 reward? TICKER Получить %1 вознаграждение? - + No UTXOs eligible for claiming Нет UTXO, для которых доступны вознаграждения - + Transaction fee is higher than the reward! Комиссия за транзакцию превышает сумму вознаграждений! - - You will receive %1 - AMT TICKER - Вы получите %1 + + You will receive + - + Refresh Обновить - + Read more about KMD active users rewards Подробнее о вознаграждениях для активных пользователей KMD - + UTXO UTXO - + Amount Сумма - + Reward Вознаграждения - + Accruing Start Начало начисления - + Accruing Stop Прекращение начисления - + Time Left Осталось - + Error Ошибка - + Locktime is not set Время блокировки не установлено - + Locktime is less than the threshold Время блокировки меньше минимального - + UTXO height is greater than end of the era Высота UTXO больше, чем конец эпохи - + UTXO amount is less than 10 UTXO меньше 10 - + One hour did not pass yet 1 час еще не прошел - + Transaction is in mempool Транзакция находится в мемпуле - + Unknown problem Неизвестная проблема - + Cancel Отменить - + Confirm Подтвердить @@ -814,37 +633,55 @@ CoinMenu - + Disable %1 TICKER Удалить %1 - + Disable and Delete %1 TICKER Удалить токен %1 из AtomicDex - + Disable all %1 assets Отключить все %1 ассеты - + Disable all assets Отключить все ассеты + + + Disable 0 balance assets + + + + + ComboBoxWithSearchBar + + + Search + Поиск + Combo_fiat - + + Language + Язык + + + Fiat Фиат - + Recommended: Рекомендации: @@ -895,74 +732,83 @@ ConfirmTradeModal - + Confirm Exchange Details Подтвердить данные обмена - + + Trade price is more than 50% different to CEX! Confirm? + Стоимость обмена в сравнении с CEX дороже более чем на 50%, вы подтверждаете сделку? + + + This swap request can not be undone and is a final event! Этот запрос на своп не может быть отменен и является окончательным! - + This transaction can take up to 60 mins - DO NOT close this application! Эта транзакция может занять до 60 минут - НЕ закрывайте приложение! - - Total %1 fees: %2 (%3) - Всего %1 комиссии: %2 (%3) + + Loading fees... + - - Security configuration - Настройки безопасности + + <b>Total %1 fees:</b> + - - dPoW protected - защищено dPoW + + Security configuration + Настройки безопасности - + %1 confirmations for incoming %2 transactions %1 подтверждений для входящих %2 транзакций - - + Read more about dPoW Узнать больше о dPoW - + Use custom protection settings for incoming %1 transactions TICKER Использовать пользовательские настройки защиты для входящих транзакций %1 - + Enable Komodo dPoW security Включить Komodo dPoW - + + dPoW protected + dPoW защита + + + Required Confirmations Необходимое количество подтверждений - + Warning, this atomic swap is not dPoW protected! Предупреждение, этот атомарный своп не защищен dPoW! - + Cancel Отменить - + Confirm Подтверждение @@ -983,181 +829,197 @@ Текущее количество включенных монет не совпадает с конфигурацией. Ваша конфигурация активов будет сброшена. - + Matching Матчинг - + Order Matching Матчинг ордеров - + Matched Сматчен - + Order Matched Ордер сматчен - + Ongoing В процессе - + Swap Ongoing Своп продолжается - + Successful Успешно - + Swap Successful Своп успешно завершен - + Refunding Проводится возврат - + Failed Не завершено - + Swap Failed Своп не был завершен - + Unknown Неизвестно - + Unknown State Статус неизвестен - + Started Начат - + Negotiated Согласован - + Taker fee sent Комиссия тейкера отправлена - + Maker payment received Платеж мейкера получен - + Maker payment wait confirm started Ожидание платежа мейкера - + Maker payment validated and confirmed Платеж мейкера валидирован и подтвержден - + Taker payment sent Платеж тейкера отправлен - + Taker payment spent Платеж тейкера потрачен - + Maker payment spent Платеж мейкера потрачен - + Finished Завершено - + Start failed Не удалось начать - + Negotiate failed Согласование не прошло - + Taker fee validate failed Валидация комиссии тейкера не прошла - + Maker payment transaction failed Платежная транзакция мейкера не прошла - + Maker payment Data send failed Отправка платежных данных мейкера не прошла - + Maker payment wait confirm failed Платежная транзакция мейкера не была подтверждена - + Taker payment validate failed Не прошла валидация платежа тейкера - + Taker payment wait confirm failed Платежная транзакция тейкера не была подтверждена - + Taker payment spend failed Spend платежа тейкера не прошел - + Maker payment wait refund started Ожидание возврата платежа мейкера - + Maker payment refunded Платеж мейкера возвращен - + Maker payment refund failed Возврат платежа мейкера не выполнен + + DatePicker + + + Date + Дата + + + + DefaultCopyIcon + + + copied to clipboard + скопировано в буфер + + DefaultRangeSlider @@ -1171,6 +1033,14 @@ Макс + + DefaultTextEdit + + + copied to clipboard + скопировано в буфер + + DeleteWalletModal @@ -1213,7 +1083,7 @@ DexAppPasswordField - + Type password Введите пароль @@ -1221,36 +1091,32 @@ DexKeyChecker - + At least 1 lowercase alphabetical character Как минимум 1 строчная буква - + At least 1 uppercase alphabetical character Как минимум 1 заглавная буква - + At least 1 numeric character Как минимум 1 цифра - + At least 1 special character (eg. !@#$%) Как минимум 1 специальный символ (!@#$%) - - - At least %n character(s) - - Не менее %n символов - Не менее %n символов - Не менее %n символов - + + + Between %1 and %2 character(s) + - + Password and Confirm Password have to be same Пароль и подтверждение пароля должны совпадать @@ -1258,7 +1124,7 @@ DexPaginator - + items per page элементов на странице @@ -1284,55 +1150,136 @@ DexSweetComboBox - + Search Поиск + + EditContactModal + + + Edit contact + Редактировать контакт + + + + Contact name + + + + + Enter a contact name + Введите имя + + + + Address list + + + + + Address Book + Адресная книга + + + + address copied to clipboard + + + + + Edit + Редактировать + + + + + Add + + + + + Tags + Теги + + + + Add tag + + + + + Cancel + Отменить + + + + Confirm + + + + + EnableAssetModal + + + The selected address belongs to a disabled asset, you need to enabled it before sending. + + + + + Enable + Добавить + + + + Cancel + Отменить + + EnableCoinModal - + Enable assets Подключить активы - + Search asset Поиск актива - - Add a custom asset to the list - Добавить пользовательский ассет в список - - - + All assets are already enabled! Все ассеты уже добавлены! - + Change assets limit Изменить лимит - + + Cancel + + + + Select all assets Выбрать все ассеты - + You can still enable %1 assets. Selected: %2. Вы можете активировать еще %1 активов. Активно: %2. - - Close - Закрыть + + Add a custom asset + - + Enable Добавить @@ -1345,27 +1292,27 @@ Дисклеймер и условия использования - + Accept EULA Принять EULA - + Accept Terms and Conditions Принять Terms of Service - + Close Закрыть - + Cancel Отменить - + Confirm Подтвердить @@ -1391,20 +1338,53 @@ FeeInfo - - Minimum fee - Минимальная комиссия + + Minimum fee + Минимальная комиссия + + + + Fees will be calculated + Комиссия будет рассчитана + + + + GasInfoModal + + + How do I calculate gas? + + + + + Gas is measured in gwei. Gwei is just a unit of Ether, and is equal to 0.000000001 ETH (or the equivalent platform coin such as AVAX or BNB). The gas price varies over time depending on network congestion. + + + + + The gas limit is how many units of gas (maximum) you allocate to pay for a transaction. The gas required depending on the size of the transaction & data being transmitted. + + + + + A standard transaction not involving contracts uses 21,000 gas units, with any of the limit remaining returned to the source address. + + + + + Transactions involving contracts may result in the whole limit being consumed, so be careful not to set it too high. + - - Fees will be calculated - Комиссия будет рассчитана + + For more information, read the article at <a href="https://support.mycrypto.com/how-to/sending/how-to-know-what-gas-limit-to-use">https://support.mycrypto.com/how-to/sending/how-to-know-what-gas-limit-to-use</a> + General - + %n day(s) %n день @@ -1413,7 +1393,7 @@ - + %nd day @@ -1423,7 +1403,7 @@ - + %nh hours @@ -1433,7 +1413,7 @@ - + %nm minutes @@ -1443,7 +1423,7 @@ - + %ns seconds @@ -1453,7 +1433,7 @@ - + %nms milliseconds @@ -1463,66 +1443,92 @@ - + - - - + + <b>Taker tx fee:</b> + + + + + <b>Dex tx fee:</b> + + + + + <b>Dex fee:</b> + + + + + <b>Maker tx fee:</b> + + + + 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 Неизвестная ошибка @@ -1530,146 +1536,165 @@ Header - + You get Вы получите - + You send Вы отправите - + Fiat Price фиатная цена - + CEX rate Цена на CEX - Price Цена - + Quantity Количество - + Total Всего - - History - - - Recent Swaps - Последние свопы - - ImportWallet - + Failed to Import the wallet Не удалось импортировать кошелек - + Import wallet - Setup Импорт кошелька - Введите данные - + Import wallet - Choose password Импорт кошелька - Задайте пароль - + Wallet Name Название кошелька - + Enter seed Введите сид-фразу - - BIP39 seed validation failed, try again or select 'Allow custom seed' - BIP39 валидация сид-фразы неуспешна, пожалуйста попробуйте снова или выберите 'Разрешить пользовательский формат сид-фразы' + + Your seed is not BIP39 compliant. +Try again or select 'Allow custom seed' to continue. + + + + + + i understand + Я согласен + + + + + я согласен + + + + + + je comprends + + + + + + entiendo + + + + + + anladım + + + + + + ich verstehe + + + + + Ok + Ок - + Allow custom seed Разрешить пользовательский формат сид-фразы - + <strong>Allow custom seed</strong> <strong>Разрешить произвольный seed</strong> - + Custom seed phrases might be less secure and easier to crack than a generated BIP39 compliant seed phrase or private key (WIF).<br><br>To confirm you understand the risk and know what you are doing, type <strong>'I understand'</strong> in the box below. - Пользовательские seed фразы могут быть менее безопасными и подверженными взлому, в сравнении с фразой сгенерированной в соответствии со стандартом BIP39 или приватным ключом (WIF).<br><br>Для подтверждения того, что вы понимаете что делаете введите <strong>'I understand'</strong> в поле ниже. + Пользовательские исходные фразы могут быть менее безопасными и их легче взломать, чем сгенерированные исходные фразы или закрытый ключ (WIF), совместимые с BIP39.<br><br>Чтобы подтвердить, что вы понимаете риск и знаете, что делаете, введите <strong>'Я согласен'</strong> в поле ниже. - I understand - - - - - Enable - Добавить + Я согласен - + Next Далее - + Enter the same password to confirm Введите тот же пароль для подтверждения - + Continue Продолжить - - Languages - - - Language - Язык - - LinksRow - + Join our Discord server Присоединяйтесь к нашему Discord серверу - + Follow us on Twitter Подписывайтесь на наш Twitter - + Go to Support Guides Форум и база знаний @@ -1681,16 +1706,26 @@ Funds are recoverable Средства могут быть восстановлены + + + Best Orders + Лучшие ордеры + + + + Enter volume to see best orders. + + ListDelegate - + %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?<br><a href='#'>Yes</a> - <a href='#no'>No</a> %1 не активирован -Вы хотите активировать этот %2 актив чтобы видеть лучшие ордеры для него ?<br><a href='#'>Да</a> - <a href='#no'>Нет</a> - + This order requires a minimum amount of %1 %2 <br>You don't have enough funds.<br> %3 @@ -1729,175 +1764,297 @@ Login - + Incorrect Password Неправильный пароль - - Connect + + Log In - + Cancel Отменить + + LogoutModal + + + Exit %1 or go to login menu? + + + + + Warning: You currently have a swap in progress. +Logging out may result in a failed swap. + + + + + Warning: You currently have open maker orders. +They will be removed from the orderbook until you log in again. + + + + + Login menu + + + + + Exit + + + + + Cancel + + + Main - + Segwit Segwit - + Confirmation Подтверждение - + Do you want to send your %1 funds to %2 wallet first? Хотели бы вы сначала отправить ваши %1 средства на кошелек %2? - + Success Успех - + Your transaction is send, may take some time to arrive Ваша транзакция была отправлена, получение может занять какое-то время - - Wallet Balance - Баланс кошелька - - - + Price Цена - - Change 24h - Изменение за 24ч + + Change 24hr + + + + + Porfolio + - - Portfolio % - % портфолио + + Contract Address + - + Send Отправить - + Enable %1 ? Активировать %1 ? - + Yes Да - + No Нет - + Receive Получить - + Swap Обменять - + + is wallet only + + + + Rewards Награды - + Faucet Фаусет - + + + + Public Key + + + + + Copied to Clipboard + Скопировано в буфер обмена + + + Loading market data Загрузка рыночных данных - + There is no chart data for this ticker yet Для данного актива пока еще нет графиков данных - - Loading - Загрузка - - - - Scanning blocks for TX History... - Сканирование блокчейна для получения данных о транзакциях... + + Fetching transactions... + - - Syncing TX History... - Синхронизация истории транзакций... + + Please wait, %1 is %2 + - - No transactions - Нет транзакций + + % activated... + - - Refreshing - Обновление данных + + No transactions available + - - Fetching transactions - Получение данных о транзакциях + + Click to view your address on %1 (%2) block explorer + Trade - + торговля + + + + Trading Information + Торговая информация + + Chart + График + + + Orders Ордеры + History История + + + Place Order + Разместить ордер + + + + Order Selected + Ордер выбран + + + + START SWAP + НАЧАТЬ ОБМЕН + + + + + Address Book + Адресная книга + + + + Search contact + поиск контактов + + + + + NEW CONTACT + новый контакт + + + + Name + Название + + + + Tags + Теги + + + + Edit + Редактировать + + + + Delete + Удалить + + + + address copied to clipboard + + + + + This contact does not have any registered address. + + MarketModeSelector - - Sell - Продать + + Sell %1 + TICKER + - - Buy - Купить + + Buy %1 + TICKER + @@ -1945,166 +2102,196 @@ - NewUpdateModal + NewContactPopup + + + Contact name + + - - Searching new updates... - Ищем обновление... + + This contact name already exists. + Контакт с таким именем уже существует. - - Please wait while the application is finding a new update... You can close this modal if you want. - Пожалуйста подождите пока приложение ищет обновление... Вы можете закрыть это окно если желаете. + + + ADD + + + + NewUpdateModal - - Already updated - Обновлено + + + + Searching new updates + - - %1 is already up-to-date ! - %1 уже последней версии! + + Fetching... + - + + + + Close Закрыть - - New update detected ! - Обнаружено обновление ! - - - - Do you want to update %1 from %2 to %3 ? - Хотели бы вы обновить %1 с %2 на %3 ? + + Could not check new updates for the following reason: +%1 + - - Download - Скачать + + New version found + - - Remind me later - Напомнить мне позже + + Mandatory version found + - - Download in progress... - В процессе скачивания... + + %1 %2 is available ! + - - Update downloaded - Новая версия скачана + + This update is mandatory to continue using the application + - - Update has been successfully downloaded. Do you want to restart the application now ? - Новая версия была успешно скачана. Хотели бы вы перезагрузить приложение сейчас? + + Close Dex + - - Restart now - Перезагрузить сейчас + + Your application is updated. + - - Restart later - Перезагрузить потом + + Download + Скачать NewWallet - + Wrong word, please check again Неверное слово. Пожалуйста, попробуйте еще раз - + + st + + + + + nd + + + + + rd + + + + + th + + + + Failed to create a wallet Ошибка при создании кошелька - + New Wallet Новый кошелек - + Confirm Seed Подтвердить seed ключ - + Choose Password Задайте пароль - + Important: Back up your seed phrase before proceeding! Важно: убедитесь, что вы сохранили ваш seed ключ, прежде чем продолжить! - + We recommend storing it offline. Мы рекумендуем хранить его офлайн. - + Generated Seed Сгенерированный seed ключ - + Seed phrase Seed фраза - + copied to clipboard скопировано в буфер - + Next Далее - + Let's double check your seed phrase Давайте перепроверим ваш seed ключ - + Your seed phrase is important - that's why we like to make sure it's correct. We'll ask you three different questions about your seed phrase to make sure you'll be able to easily restore your wallet whenever you want. Ваш seed ключ важен, и поэтому мы хотим убедиться, что вы его сохранили. Мы зададим вам три разных вопроса о вашем seed ключе, чтобы убедиться, что вы сможете легко восстановить свой кошелек, когда захотите. - - - Enter the %n. word - - Введите %nе слово - Введите %nе слово - Введите %nе слово - + + + Enter the + + + + + word + - + Check Проверить - + Enter the same password to confirm Введите тот же пароль для подтверждения - + Continue Продолжить @@ -2135,150 +2322,152 @@ NotificationsModal - + Matching Матчинг - + Order Matching Матчинг ордеров - + Matched Сматчен - + Order Matched Ордер сматчен - + Ongoing В процессе - + Swap Ongoing Обмен продолжается - + Successful Успешно - + Swap Successful Обмен успешно завершен - + Refunding Проводится возврат - + Failed Не завершено - + Swap Failed Обмен не был завершен - + Unknown Неизвестно - + Unknown State Статус неизвестен - + Swap status updated Обновление статуса Свопа - + You sent %1 Вы отправили %1 - + You received %1 Вы получили %1 - + Your wallet balance changed Баланс вашего кошелька изменился - + + %1 Enable status + TICKER + + + + Please check your internet connection (e.g. VPN service or firewall might block it). Пожалуйста, проверьте ваше интернет-соединение (например, служба VPN или брандмауэр могут блокировать подключение). - + Failed to enable %1 TICKER Не получается включить %1 - + + + Failed to disable %1 + TICKER + + + + + Endpoint not reachable Эндпоинт не доступен - + Could not reach to endpoint Не удалось подключиться - - Mismatch at %1 custom asset configuration - TICKER - Несоответствие в конфигурации актива %1 - - - - Application needs to be restarted for %1 custom asset. - TICKER - Необходимо перезапустить приложение для %1. - - - - Batch %1 failed. Reason: %2 - Группа %1 .не удалась. Причина: %2 - - - + Show Показать - + Restart Перезапустить - + Quit Выйти - - There isn't any notification - Нет новых уведомлений + + Notifications + + + + + There aren't any notifications + - + Mark all as read Отметить все как прочитанные @@ -2286,46 +2475,97 @@ OrderForm - + Price Цена - + + Reduce 1% relative to CEX market price. + + + + + Use CEX market price. + + + + + Increase 1% relative to CEX market price. + + + + Volume Объем - - Amount to sell - Сумма для продажи + + Amount to sell + Сумма для продажи + + + + Amount to receive + Получаемая сумма + + + + Max + Макс + + + + Swap 25% of your tradable balance. + + + + + Swap 50% of your tradable balance. + + + + + Swap 100% of your tradable balance. + + + + + Min Volume + + + + + Min amount to sell + + + + + Min amount to receive + - - Amount to receive - Получаемая сумма + + Minimum accepted trade equals 10% of order volume. + - - Min volume: - Мин. объем: + + Minimum accepted trade equals 25% of order volume. + - - How to use the pro-view slider ? - Как использовать pro-view слайдер? + + Minimum accepted trade equals 50% of order volume. + - - This slider is used to setup the order requirements you need. -Left slider: Sets the minimum amount required to process a trade. -Right slider: Sets the volume you want to trade. - Этот слайдер используется для настройки желаемых параметров сделки. -Левый слайдер: Задает минимальный объем для начала обмена. -Правый слайдер: Задает объем который вы хотите обменять. + + Min volume: + Мин. объем: - + Use custom minimum trade amount Задать минимальный объем сделки @@ -2333,7 +2573,7 @@ Right slider: Sets the volume you want to trade. OrderLine - + Funds are recoverable Средства могут быть восстановлены @@ -2341,7 +2581,7 @@ Right slider: Sets the volume you want to trade. OrderList - + No results found Не найдено результатов @@ -2349,97 +2589,114 @@ Right slider: Sets the volume you want to trade. OrderModal - + Swap Details Детали свопа - + Order Details Детали ордера - + + Order Type + + + + Maker Order Мейкер ордер - + Taker Order Тейкер ордер - + Refund State Статус рефанда - + Your swap failed but the auto-refund process for your payment started already. Please wait and keep application opened until you receive your payment back Обмен не был завершен, но процесс автоматического рефанда уже начался. Пожалуйста, подождите, оставляя приложение открытым, пока вы не получите свои средства - + Date Дата - - ID - ID + + Error ID + ID ошибки - - Maker Payment Sent ID - ID отправки платежа мейкера + + + Error Log + Лог ошибки - - Maker Payment Spent ID - ID spend платежа мейкера + + Close + Закрыть - - Taker Payment Spent ID - ID spend платежа тейкера + + Cancel Order + Отменить ордер - - Taker Payment Sent ID - ID отправки платежа тейкера + + + Swap ID + ID обмена - - Error ID - ID ошибки + + Maker Payment Sent Transaction ID + - - Error Log - Лог ошибки + + Maker Payment Spent Transaction ID + - - Close - Закрыть + + Maker Payment TXID + - - Cancel Order - Отменить ордер + + Taker Payment Spent Transaction ID + + + + + Taker Payment Sent Transaction ID + + + + + Taker Payment TXID + - + Recover Funds Восстановить средства - + Refunding... Возмещается... - + View on Explorer Показать в эксплорере @@ -2447,64 +2704,62 @@ Right slider: Sets the volume you want to trade. OrderRemovedModal - + Selected Order Removed Выбранный ордер удален - - The selected order does not exist anymore, it might have been matched or canceled, and no order with a better price is available. Please select a new order. - Выбранный ордер больше не существует. Возможно его отменили или заполнили. Пожалуйста выберите другой ордер. + + The selected order does not exist anymore, it might have been matched or canceled, and no order with a better price is available. +Please select a new order. + - + OK - - - - - Orders - - - Orders - Ордеры + OK OrdersPage - + From От - + To Кому - + Export CSV Скачать CSV - - + + Filter Фильтр - + Date Дата - + Apply Filter Применить фильтр - + + Cancel All + + + + Please choose the CSV export name and location Выберите название и расположение загружаемого файла @@ -2512,7 +2767,7 @@ Right slider: Sets the volume you want to trade. Pagination - + items per page элементов на странице @@ -2520,43 +2775,39 @@ Right slider: Sets the volume you want to trade. PasswordField - + Password Пароль - + Enter your wallet password Введите пароль вашего кошелька - + At least 1 lowercase alphabetical character Как минимум 1 строчная буква - + At least 1 uppercase alphabetical character Как минимум 1 заглавная буква - + At least 1 numeric character Как минимум 1 цифра - + At least 1 special character (eg. !@#$%) Как минимум 1 специальный символ (!@#$%) - - - At least %n character(s) - - Не менее %n символов - Не менее %n символов - Не менее %n символов - + + + Between %1 and %2 character(s) + @@ -2580,66 +2831,66 @@ Right slider: Sets the volume you want to trade. Portfolio - + + ADD ASSET + + + + Search asset Поиск актива - + Show only coins with balance Показывать только монеты с балансом - + (%1/%2) - + (%1/%2) - + Portfolio Портфолио - - - Add asset - Добавить крипто актив - PriceLine - + Set swap price for evaluation Установите цену для оценки - + Exchange rate Обменный курс - + Selected Выбрано - + Expensive Невыгодный курс - + Expedient Выгодный курс - + %1 compared to CEX PRICE_DIFF% %1 по сравнению с CEX - + CEXchange rate CEXchange Цена @@ -2647,37 +2898,32 @@ Right slider: Sets the volume you want to trade. PriceLineSimplified - - Set swap price for evaluation - Установите цену для оценки - - - + Exchange rate Обменный курс - + Selected Выбрано - + CEXchange rate CEXchange Цена - + Expensive Невыгодный курс - + Expedient Выгодный курс - + %1 compared to CEX PRICE_DIFF% %1 по сравнению с CEX @@ -2686,91 +2932,51 @@ Right slider: Sets the volume you want to trade. ProView - + Failed to place the order Не удалось разместить ордер - + Placed the order Ордер размещен + + + QObject - - Chart - График - - - - Trading Information - Торговая информация - - - - Exchange Rates - Курс обмена - - - - Orders - Ордеры - - - - History - История - - - - Order Book - Ордербук - - - - Best Orders - Лучшие ордеры - - - - Place Order - Разместить ордер - - - - START SWAP - НАЧАТЬ ОБМЕН - - - - Order Selected - Ордер выбран + + Cannot reach the endpoint: + ReceiveModal - Receive - Получить + Receive %1 + TICKER + - + Only send %1 to this address TICKER - Отправить %1 на данный адресс + - + %1 address - %1 адрес + TICKER + - - copied to clipboard - скопировано в буфер + + copied to clipboard. + - + Close Закрыть @@ -2778,94 +2984,97 @@ Right slider: Sets the volume you want to trade. RecoverSeedModal - - + + View seed and private keys Показать seed-фразу и приватные ключи - + Please enter your password to view the seed. Введите пароль для отображения seed ключа. - - Wrong Password - Неправильный пароль - - - - Cancel - Отменить + + Seed + - - Seed phrase - Seed фраза + + Backup Seed + - - - - copied to clipboard - скопировано в буфер + + Public Address copied to clipboard + - - RPC password - RPC пароль + + Cancel + Отменить - - phrase key copied to clipboard - ключевая фраза скопирована в буфер + + Incorrect Password + Неправильный пароль - - Backup seed - Сделать бекап seed-фразы + + + copied to clipboard + скопировано в буфер - + + RPC Password RPC Пароль - + Search a coin. Поиск актива. - - %1 address - %1 адрес - - - - %1 private key - %1 приватный ключ - - - + Public Address Публичный адрес - - Private Key - Приватный ключ + + Private Key copied to clipboard + - - Close - Закрыть + + Private Key + Приватный ключ - + View Показать + + RemoveContactPopup + + + Do you want to remove this contact ? + Вы действительно хотите удалить этот контакт? + + + + Yes + Да + + + + No + Нет + + RestartModal @@ -2910,140 +3119,165 @@ Right slider: Sets the volume you want to trade. Поиск - - SellBox - - - Sell - Продать - - SendModal - + Failed to send Ошибка отправки - - Failed to Send - Отправка не прошла - - - + Prepare to send Подготовить к отправке - + Address of the recipient Адрес получателя - + Amount to send Сумма для отправки - - Max amount - Максимальное количество - - - + Gas price Цена газа - - Recipient's address - Адрес получателя + + Cancel + - - Address Book - Адресная книга + + Recipient's address + Адрес получателя - + The address has to be mixed case. Адрес должен быть написан в смешанном регистре. - + + Failed to Broadcast + + + + Fix Фикс - - Enable Custom Fees - Включить настройку комиссий + + MAX + МАКС + + + + Fiat amount: Unavailable + + + + + Fiat amount: %1 + + + + + %1 amount: %2 + - - Only use custom fees if you know what you are doing! - Используйте настраиваемые комиссии только если знаете, что делаете! + + Specify in Fiat + + + + + Specify in Crypto + + + + + Enable Custom Fees + Включить настройку комиссий - + Enter the custom fee Введите комиссию сети - + Gas Limit Gas лимит - + Custom Fee can't be higher than the amount Комиссия не может больше общей суммы транзакции - + Not enough funds. Недостаточно средств. - + + You have %1 AMT TICKER У вас %1 - - Close - Закрыть + + + Only use custom fees if you know what you are doing! + - + Prepare Подготовка - - + + Send Отправить - + + %1 address + TICKER + + + + + copied to clipboard. + + + + Amount Сумма - + Fees Комиссия - + Date Дата - + Back Назад @@ -3051,43 +3285,43 @@ Right slider: Sets the volume you want to trade. SendModalContactList - + Select a contact with an %1 address Выберите контакт с %1 адресом - + Search for contacts... Поиск по контактам... - + %1 addresses %1 адреса - + 1 address 1 адрес - - + + Back Назад - + Choose an %1 address of %2 Выбрать %1 адрес из %2 - + Name Название - + Address Адрес @@ -3095,42 +3329,60 @@ Right slider: Sets the volume you want to trade. SendResult - + Transaction Complete! Транзакция завершена! - + + %1 txid + TICKER + + + + + + copied to clipboard. + + + + Recipient's address Адрес получателя - + + %1 address + TICKER + + + + Amount Общая сумма транзакции - + Fees Комиссия сети - + Date Дата - + Transaction Hash Хэш транзакции - + Close Закрыть - + View on Explorer Смотреть в эксплорере @@ -3138,282 +3390,240 @@ Right slider: Sets the volume you want to trade. SettingModal - - Confirm Logout - Подтвердите выход - - - - Are you sure you want to log out? - Вы действительно хотите выйти? - - - - Yes - Да - - - - + + Cancel Отмена - + Settings Настройки - - + Language Язык - + User Interface Интерфейс - + Security Приватность - + General Общие - + About & Version О программе - + Enable Desktop Notifications Включить уведомления для рабочего стола - + Maximum number of enabled coins Макс. количество активированных монет - + Logs Логи - + Open Folder Открыть папку с логами - - + + Reset wallet configuration Сбросить конфигурацию кошелька - + This will restart your wallet with default settings Эта опция перезапустит ваш кошелек с настройками по умолчанию - - Confirm - Подтвердить + + + 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 + + + + + Application Version + - - Changing theme to %1 - Изменить тему на %1 + + copied to clipboard + скопировано в буфер - + Reset Сбросить - + Current Font Текущий шрифт - + Current font changed to %1. Текущий шрифт изменен на %1. - + Theme Тема - + Ask system's password before sending coins ? (2FA) Спрашивать системный пароль перед отправкой монет? (2FA) - + Application version Версия приложения - - DEX Version - Версия DEX - - - - DEX Version copied to clipboard. - Версия DEX скопирована в буфер обмена. - - - + MM2 version Версия MM2 - + MM2 Version Версия MM2 - + MM2 Version copied to clipboard. Версия MM2 скопирована в буфер обмена. - + 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 Дисклеймер и Условия Использования - - Settings - - - Fiat - Фиат - - - - Recommended: - Рекомендации: - - - - Enable Desktop Notifications - Включить уведомления для рабочего стола - - - - Use QtTextRendering Or NativeTextRendering - Использовать QtTextRendering или NativeTextRendering - - - - Open Logs Folder - Открыть папку с логами - - - - View seed and private keys - Показать seed-фразу и приватные ключи - - - - Disclaimer and ToS - Дисклеймер и TOS - - - - Setup Camouflage Password - Установить камуфляжный пароль - - - - Reset wallet configuration - Сбросить конфигурацию кошелька - - - - Delete Wallet - Удалить кошелек - - - - Log out - Выйти - - - - mm2 version - версия MM2 - - Sidebar - - Search coin - Поиск монеты + + Search + Поиск - + Add asset Добавить крипто актив @@ -3434,32 +3644,32 @@ Right slider: Sets the volume you want to trade. SubBestOrder - + Token Токен - + Available Quantity Доступное количество - + Available Quantity (in %1) Доступное количество (в %1) - + Fiat Volume Фиатный объем - + CEX Rate CEX цена - + %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?<br><a href='#'>Yes</a> - <a href='#no'>No</a> %1 не активирован -Вы хотите активировать этот %2 актив чтобы видеть лучшие ордеры для него ?<br><a href='#'>Да</a> - <a href='#no'>Нет</a> @@ -3467,22 +3677,22 @@ Right slider: Sets the volume you want to trade. SubCoinSelector - + Token - + Токен - + Balance Баланс - + Balance Fiat Баланс в фиате - + No Selectable coin. Нет монет для выбора. @@ -3525,32 +3735,32 @@ Right slider: Sets the volume you want to trade. От - + To Кому - + Cancel Отменить - + Apply filter Применить фильтр - + Export Экспорт - + Please choose the CSV export name and location Выберите название и расположение экспортируемого CSV файла - + No results found Ничего не найдено @@ -3559,261 +3769,240 @@ Right slider: Sets the volume you want to trade. SubOrders - + Orders Ордеры - + Close filtering options. Закрыть настройки фильтра. - + Filter Фильтр - + Date Дата - + Open filtering options. Открыть настройки фильтра. - + Filter settings - + Настройки фильтра - + From От - + To Кому - + Cancel Отменить - + Apply filter Применить фильтр - + No results found Не найдено результатов - Support - - - Update available - Доступно обновление - - - - Up to date - Последняя версия - - - - Changelog - Журнал изменений - - - - Open Logs Folder - Открыть папку с логами - + SupportModal - + Frequently Asked Questions - Часто задаваемые вопросы + Часто задаваемые вопросы - + Do you store my private keys? - Вы храните мои личные ключи? + Вы храните мои личные ключи? - + No! %1 is non-custodial. We never store any sensitive data, including your private keys, seed phrases, or PIN. This data is only stored on the user’s device and never leaves it. You are in full control of your assets. - Нет! %1 не хранит персональную информацию, включая приватные ключи, seed фразы, или PIN. Эти данные хранятся только у вас и никогда не покидают ваше устройство. Ваши активы всегда в вашем и только вашем распоряжении. + Нет! %1 не хранит персональную информацию, включая приватные ключи, seed фразы, или PIN. Эти данные хранятся только у вас и никогда не покидают ваше устройство. Ваши активы всегда в вашем и только вашем распоряжении. - + How is trading on %1 different from trading on other DEXs? - Как торговля на %1 отличается от других торговли на других децентрализованных биржах? + Как торговля на %1 отличается от других торговли на других децентрализованных биржах? - - Other DEXs generally only allow you to trade assets that are based on a single blockchain network, use proxy tokens, and only allow placing a single order with the same funds. + + Other DEXs generally only allow you to trade assets that are based on a single blockchain network, use proxy tokens, and only allow placing a single order with the same funds. %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. - Другие Децентрализованные биржи обычно позволяют торговать активами которые базируются лишь на единственном блокчейне, используют прокси - токены и разрешают размещать только один ордер одними и теми же средств. - -%1 же позволяет вам торговать нативно через две разные блокчейн сети без прокси токенов. Также вы можете размещать несколько ордеов одним и тем же балансом. Например вы можете продать 0.1 BTC за KMD, QTUM или VRSC – первый сматченный ордер автоматически отменит остальные. + - + + 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>. + Несколько факторов определяют время завершения каждого Атомарного Свопа. Время блока на каждой из торгуемых сетей (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? + Необходимо ли мне быть в сети во время свопа? - + 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. + The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. + If you go offline, so will your orders, and any that are in progress will fail, leading to potential loss of trade / transaction fees, and a wait for the swap to timeout and issue a refund. It may also negatively affect your wallet's reputation score for future trade matching. + 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. - Да. Вы должны оставаться подключенным к Интернету и иметь работающее приложение для успешного завершения каждого атомарного свопа (очень короткие перерывы в подключении обычно допустимы). В противном случае существует риск отмены сделки, если вы - мейкер, и риск потери средств, если вы - тейкер. -Протокол атомарных свопов требует, чтобы оба участника обмена оставались в сети для наблюдения за блокчейнами, чтобы процесс оставался атомарным. -Если вы перейдете в оффлайн режим, ваши ордеры не будут доступны, и все обмены в процессе закончатся неуспешно, что приведет к потенциальной потере комиссий за торговлю / транзакции, а также к ожиданию отмены свопа и возврата средств. Это также может негативно повлиять на рейтинг репутации вашего кошелька для будущих сделок. -Когда вы вернетесь в онлайн, ваши ордеры снова начнут транслироваться по цене, которую вы установили до выхода в офлайн. Если тем временем произошло значительное движение цены, вы можете непреднамеренно предложить кому-то сделку! -По этой причине мы рекомендуем отменять заказы перед закрытием%1 или проверять и корректировать свои цены при перезапуске%1. + - - Yes! %1 offers support through the <a href="%2">%1 Discord server</a>. The team and the community are always happy to help! - Да! %1 предоставляет саппорт через <a href="%2">%1 Discord сервер</a>. Команда и сообщество проекта всегда рады помочь! + + How are the fees on %1 calculated? + Как подсчитывается %1 комиссия? - - %1 is available for mobile on both <a href="%2">Android and iPhone, and for desktop on Windows, Mac, and Linux</a> operating systems. - %1 доступен для Android и iOS мобильных устройв <a href="%2">, и для операционных систем Windows, Mac и Linux</a> на PC. + + There are two fee categories to consider when trading on %1. + +1. %1 charges approximately 0.13% (1/777 of trading volume but not lower than 0.0001) as the trading fee for taker orders, and maker orders have zero fees. + +2. Both makers and takers will need to pay normal network fees to the involved blockchains when making atomic swap transactions. + +Network fees can vary greatly depending on your selected trading pair. + + + + + Do you provide user support? + Предоставляете ли вы поддержку пользователей? + + + + Yes! %1 offers support through the <a href="%2">%1 Discord server</a>. The team and the community are always happy to help! + Да! %1 предоставляет саппорт через <a href="%2">%1 Discord сервер</a>. Команда и сообщество проекта всегда рады помочь! - + Who is behind %1? - Кто создал %1? + Кто создал %1? - + %1 is developed by the Komodo team. Komodo is one of the most established blockchain projects working on innovative solutions like atomic swaps, Delayed Proof of Work, and an interoperable multi-chain architecture. - %1 разрабатывается командой Komodo. Komodo один из наиболее известных блокчейн проектов который работает над такими инновационными решениями как Атомарные Свопы, "Отложенный" PoW, а также над совместимой мульти-чейн архитектурой. + %1 разрабатывается командой Komodo. Komodo один из наиболее известных блокчейн проектов который работает над такими инновационными решениями как Атомарные Свопы, "Отложенный" PoW, а также над совместимой мульти-чейн архитектурой. - + Is it possible to develop my own white-label exchange on %1? - Возможно ли разработать децентрализованную биржу с моим брендом на %1? + Возможно ли разработать децентрализованную биржу с моим брендом на %1? - + Absolutely! You can read our developer documentation for more details or contact us with your partnership inquiries. Have a specific technical question? The %1 developer community is always ready to help! - Обязательно! Вы можете прочитать нашу документацию для разработчиков для более детального ревью или же связаться с нашей командой по поводу партнерства. Есть очень специфичный технический вопрос? %1 наше комьюнити разработчиков всегда готово помочь! + Обязательно! Вы можете прочитать нашу документацию для разработчиков для более детального ревью или же связаться с нашей командой по поводу партнерства. Есть очень специфичный технический вопрос? %1 наше комьюнити разработчиков всегда готово помочь! - + Which devices can I use %1 on? - На каких устройствах я могу использовать %1 ? + На каких устройствах я могу использовать %1 ? - - Compliance Info - Комплаенс информация - - - - Due to regulatory and legal circumstances the citizens of certain jurisdictions including, but not limited to, the United States of America, Canada, Hong Kong, Israel, Singapore, Sudan, Austria, Iran and any other state, country or other jurisdiction that is embargoed by the United States of America or the European Union are not allowed to use this application. - В связи с нормативными и правовыми обстоятельствами граждане определенных юрисдикций, включая, помимо прочего, Соединенные Штаты Америки, Канаду, Гонконг, Израиль, Сингапур, Судан, Австрию, Иран и любые другие государства, страны или другие юрисдикции, на которые введено эмбарго. Соединенных Штатов Америки или Европейского Союза не могут использовать это приложение. - - - - How long does each atomic swap take? - Сколько времени занимает каждый атомарный своп? + + %1 is available for mobile on both <a href="%2">Android and iPhone, and for desktop on Windows, Mac, and Linux</a> operating systems. + %1 доступен для Android и iOS мобильных устройв <a href="%2">, и для операционных систем Windows, Mac и Linux</a> на PC. - - Do I need to be online for the duration of the swap? - Необходимо ли мне быть в сети во время свопа? + + Compliance Info + Комплаенс информация - - How are the fees on %1 calculated? - Как подсчитывается %1 комиссия? + + Due to regulatory and legal circumstances the citizens of certain jurisdictions including, but not limited to, the United States of America, Canada, Hong Kong, Israel, Singapore, Sudan, Austria, Iran and any other state, country or other jurisdiction that is embargoed by the United States of America or the European Union are not allowed to use this application. + В связи с нормативными и правовыми обстоятельствами граждане определенных юрисдикций, включая, помимо прочего, Соединенные Штаты Америки, Канаду, Гонконг, Израиль, Сингапур, Судан, Австрию, Иран и любые другие государства, страны или другие юрисдикции, на которые введено эмбарго. Соединенных Штатов Америки или Европейского Союза не могут использовать это приложение. - - There are two fee categories to consider when trading on %1. - -1. %1 charges approximately 0.13% (1/777 of trading volume but not lower than 0.0001) as the trading fee for taker orders, and maker orders have zero fees. -2. Both makers and takers will need to pay normal network fees to the involved blockchains when making atomic swap transactions. - -Network fees can vary greatly depending on your selected trading pair. - Две категории комиссий каждый трейдер должен иметь ввиду когда использует %1. - -1. %1 комиссия это примерно 0.13% (1/777 от объема торга но не менее чем 0.0001) в качестве торговой комиссия за тейкер ордеры, а мейкер ордеры в данном случае комиссию не платят. -2. Но и мейкер и тейкер в любом случае должны иметь возможность оплатить комиссиии сети за обычные транзакции во время проведения Атомарного Свопа. - -Комиссии сети могут очень сильно варьироваться в зависимости от выбранной торговой пары. + + Changelog + Журнал изменений - - Do you provide user support? - Предоставляете ли вы поддержку пользователей? + + Open Logs Folder + Открыть папку с логами SwapProgress - + act SHORT FOR ACTUAL TIME фактич - + est SHORT FOR ESTIMATED прибл - + Progress details Прогресс - - SweetDexComboBox - - - Search - Поиск - - TextAreaWithTitle - + Save Сохранить - + Edit Редактировать - TextEditWithTitle + TextEditWithCopy - - Swap ID - ID обмена + + copied to clipboard + скопировано в буфер + + + TextEditWithTitle - + copied to clipboard скопировано в буфер @@ -3821,7 +4010,7 @@ Network fees can vary greatly depending on your selected trading pair. TextFieldWithTitle - + Required Обязательное поле @@ -3837,213 +4026,281 @@ Network fees can vary greatly depending on your selected trading pair. Trade - + Swap Обменять - + Instant trading with best orders Быстрая торговля с лучшими ордерами - + + Reset form + + + + + You have no tradable assets + + + + From От - + Enter an amount Введите количество - + MAX МАКС - + To Получатель - + Pick an order Выберите ордер - + Price Цена - + Better price found: %1. Updating forms. Найдена цена лучше: %1.Обновляю форму. - + Better price (%1) found but received quantity (%2) is lower than your current one (%3). Click here to update the selected order. Лучшая цена (%1) была обнаружена но количество (%2) меньше чем в вашем текущем ордере (%3).Нажмите чтобы обновить выбранный ордер. - - Reset form. - Сбросить форму. - - - + %1 - + %1 - + Tradable: Доступно: - + Min: %1 Мин: %1 - + Pick a coin Выберите монету - + SWAP NOW - + Failed to place the order Не удалось разместить ордер - + Placed the order Ордер размещен - + Entered amount must be superior than 0. Введенная сумма должна быть больше 0. - + You must select an order. Вы должны выбрать ордер. - + Entered amount is below the minimum required by this order: %1 Введнная сумма меньше минимальной для этого ордера: %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 транзакций - - - Search - Поиск + + %1 balance does not have enough funds to pay the gas of %2 transactions + - + No buy orders found for %1. Не найдено ордеров на покупку дл] %1. - + You can check later or try to sell a different coin. Вы можете попробовать позже или попробовать продать другой актив. - + + Calculating fee estimate... + + + + Total %1 fees: Всего %1 комиссий: - + %2 (%3) - + %2 (%3) + + + + TradeViewHeader + + + Pro View Settings + + + + + Display Settings + + + + + Ticker Selectors + + + + + Trading Information + Торговая информация + + + + Order Book + Ордербук + + + + Best Orders + Лучшие ордеры + + + + Place Order + Разместить ордер TransactionDetailsModal - + Transaction Details Детали транзакции - + + %1 txid + TICKER + + + + + copied to clipboard. + + + + Amount Сумма - + Fees Комиссия сети - + + From address + + + + + To address + + + + Date Дата - + Unconfirmed Не подтверждена - + Transaction Hash Хэш транзакции - + Confirmations Подтверждения - + Block Height Блок - + From От - + To Получатель - + Notes Заметки - + Close Закрыть - + View on Explorer Смотреть в эксплорере @@ -4051,22 +4308,22 @@ Network fees can vary greatly depending on your selected trading pair. Transactions - + Received Получено - + Sent Отправлено - + fees комиссии - + Unconfirmed Не подтверждена @@ -4080,17 +4337,11 @@ Network fees can vary greatly depending on your selected trading pair. - WalletNameField - - - Wallet Name - Название кошелька - + Vertical - - Enter the name of your wallet here - Введите название для вашего кошелька - Название кошелька + + Order Book + Ордербук @@ -4111,118 +4362,165 @@ Network fees can vary greatly depending on your selected trading pair. Импортировать кошелек - + + Search your wallets... + + + + My Wallets Мои кошельки - - + + No wallets found! + + + + + Delete Удалить - + Enter password to confirm deletion of Введите пароль чтобы подтвердить удаление - + wallet кошелек - + Type password Введите пароль - + Cancel Отменить - - + + Wallet status Статус кошелька - + wallet deleted successfully кошелек успешно удален - - + + Ok Ок - + wallet password is incorrect введен неправильный пароль + + ZcashParamsModal + + + %1 Activation Failed! + + + + + To activate ZHTLC coins, you need to download the Zcash Params. +This might take a few minutes... + + + + + Download params & enable coins + + + + + More Info + + + + + Close + Закрыть + + + + atomic_dex::settings_page + + + An error has occurred. + + + 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 on the convert button to turn it into a mixed case address - Невалидная хэш-сумма для %1. Нажмите на кнопку конвертации в mixed case адрес + + Invalid checksum for %1. Click the button to convert to mixed case address. + - - Legacy address used for %1, click on the convert button to convert it to a Cashaddress. - Введен legacy адрес для %1, нажмите на кнопку для конвертации в Cashaddress формат. + + 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 @@ -4230,32 +4528,12 @@ Network fees can vary greatly depending on your selected trading pair. main - + Logout Выход - - Confirm Logout - Подтверждение выхода - - - - Are you sure you want to log out? - Вы действительно хотите выйти? - - - - Yes - Да - - - - Cancel - Отменить - - - + Balance Баланс diff --git a/atomic_defi_design/assets/languages/atomic_defi_tr.ts b/atomic_defi_design/assets/languages/atomic_defi_tr.ts index 6b69125052..d4fe94d9c5 100644 --- a/atomic_defi_design/assets/languages/atomic_defi_tr.ts +++ b/atomic_defi_design/assets/languages/atomic_defi_tr.ts @@ -2,500 +2,269 @@ - QPlatformTheme + AddAddressForm - &Yes - Yes + + Use standard network address + + + + + Label + + + + + This key already exists. + Bu anahtar zaten mevcut. - &No - No + + Address + Adres + + Cancel - Cancel + İptal + + + Convert + + + + + Edit + Düzenle + + + + Add + Ekle + + + + You need to enable %1 before adding this kind of address. + + + + + Enable + Etkinleştir + + + AddCustomCoinModal - + Choose the asset type Varlık türünü seçin - - Type - Tip - - - + 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 - - Contract Address - Kontrat Adresi - - - + 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! - + 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 - AddressBook + AddTagPopup - - Address Book - Adres Defteri - - - - New Contact - Yeni Kişi - - - - Search a contact by name or tags - İsim ya da etiket ile kişi ara - - - - Name - İsim - - - - Tags (first 6) - Etiket - - - - Actions - Eylemler - - - - Edit - Düzenle - - - - Remove - Kaldır - - - - Do you want to remove this contact ? - Bu kişiyi kaldırmak istiyor musunuz ? - - - - Yes - Evet - - - - No - Hayır - - - - AddressBookAddContactAddressModal - - - Create a new address - Yeni bir adres oluştur - - - - Edit address entry - Adres girdisini düzenleyin - - - - Selected wallet: %1 + + Tag name - - NONE + + Contact already has this tag. - - Enter a name - Bir ad girin - - - - This key already exists. - Bu anahtar zaten mevcut. - - - - Enter the address - Adresi girin - - - - Validate - Geçerle - - - - Cancel - İptal - - - - Convert + + + ADD - AddressBookEditContactModal - - - Edit contact - Kişiyi düzenle - - - - Contact Name - Kişi Adı - - - - Enter a contact name - Bir kişi adı girin - - - - Address List - Adres Listesi - - - - Search for an address entry. - Bir adres girdisi arayın. - - - - Type - Tür - - - - Key - Anahtar - - - - Address - Adres - - - - Actions - Eylemler - - - - New Address - Yeni Adres - - - - Tags - Etiketler - - - - + - + - - - - Confirm - Onayla - - - - - Cancel - İptal - - - - The selected address belongs to a disabled coin, you need to enabled it before sending. - Seçilen adres devre dışı bırakılmış bir koine aittir, göndermeden önce etkinleştirmeniz gerekir. - - - - Enable - Etkinleştir - - - - Cannot send to this address - Bu adrese gönderilemiyor - - - - Your balance is empty - Bakiyeniz boş - - - - Ok - Tamam - - - - Remove address ? - - - - - Yes - Evet - - - - No - Hayır - - - - AddressBookNewContactCategoryModal - - - Add a new tag - Yeni etiket ekle - - - - Enter the tag name - Etiket adı girin - - - - This contact already has this tag - Bu kişi zaten bu etikete sahip - - - - Add - Ekle - + AmountChart - - Cancel - İptal + + Work in progress + İş devam ediyor - AddressBookNewContactModal - - - Create a new contact - Yeni bir kişi ekle - - - - Enter the contact name - Kişi adını girin - - - - This contact name already exists. - Bu kişi adı zaten mevcut. - - - - Confirm - Onayla - + App - - Cancel - İptal + + Recover Funds Result + Fon Kurtarma Sonucu - AddressBookSendWalletSelector + AssetFromStandardSelector - + Choose a valid - Geçerli bir - - - - coin - koin seçin - - - - AddressBookWalletTypeListModal - - - Select wallet type - Cüzdan türünü seçin + Geçerli bir - - Search - Ara + + asset + - - - AmountChart - - Work in progress - İş devam ediyor + + Search an asset + - - - App - - Recover Funds Result - Fon Kurtarma Sonucu + + Disabled + AssetPieChart - + Assets Varlıklar @@ -503,32 +272,42 @@ AssetsList - + Asset Varlık - + Balance Bakiye - + + Fiat Balance + + + + Change 24h Değişim 24sa - + Price Fiyat - + Source - + + Activating: + + + + Price provider is: %1 @@ -536,27 +315,70 @@ Bottom - + Settings Ayarlar - + Support Destek - + Privacy Gizlilik - - - BuyBox - - Buy - Satın Al + + Disable Privacy? + + + + + Enter wallet password to confirm + + + + + Type password + + + + + Confirm + Onayla + + + + Cancel + İptal + + + + Privacy status + + + + + Privacy mode disabled successfully + + + + + + Ok + Tamam + + + + Wrong password! + + + + + wallet password is incorrect + @@ -567,64 +389,51 @@ Kamuflaj Parolasını Ayarla - + Camouflage Password is a secret password for emergency situations. Kamuflaj Parolası acil durumlar için olan gizli bir paroladır. - + Using it to login will display your balance lower than it actually is. Bu parolayla giriş yapınca bakiyeniz normalinden daha az görünecektir. - + Here you enter the suffix and at login you need to enter {real_password}{suffix} Buraya son eki gireceksiniz, giriş yaparken ise {gerçek_şifre}{son ek} şeklinde giriş yapacaksınız - + Password suffix - + Confirm pasword suffix - + Enter a password suffix - + Enter the same password suffix to confirm - + Cancel İptal - + Save Kaydet - - CandleStickChart - - - Loading market data - Borsa bilgisi yükleniyor - - - - There is no chart data for this pair yet - Bu parite için henüz grafik verisi yok - - CannotEnableCoinModal @@ -689,122 +498,134 @@ ⓘ simgesiyle işaretlenen piyasa verileri (fiyatlar, grafikler vb.) üçüncü taraf kaynaklardan alınmıştır. .<br><br>Veriler kaynakları: <a href="https://bandprotocol.com/">Band Decentralized Oracle</a> ve <a href="https://coingecko.com">CoinGecko</a>.<br><br><b>Oracle Supported Pairs:</b><br>%1<br><br><b>Son referans (Band Oracle):</b><br><a href="%2">%2</a> + + Chart + + + Loading market data + Piyasa bilgisi yükleniyor + + + + There is no chart data for this pair yet + Bu parite için henüz grafik verisi yok + + ClaimRewardsModal - + Failed to prepare to claim rewards Ödül alımı hazırlığı başarısız sonuçlandı - + Claim your %1 reward? TICKER %1 ödülünüzü alacak mısınız? - + No UTXOs eligible for claiming Ödül alımı için uygun UTXO yok - - You will receive %1 - AMT TICKER - %1 alacaksınız - - - + Transaction fee is higher than the reward! İşlem ücreti ödülden daha yüksek! - + + You will receive + + + + Refresh Yenile - + Read more about KMD active users rewards KMD aktif kullanıcı ödülleri hakkında daha fazla bilgi - + UTXO UTXO - + Amount Miktar - + Reward Ödül - + Accruing Start Tahakkuk Başlangıcı - + Accruing Stop Tahakkuk Bitişi - + Time Left Kalan Zaman - + Error Hata - + Locktime is not set Kilit süresi ayarlanmamış - + Locktime is less than the threshold Kilit süresi limitin altında - + UTXO height is greater than end of the era UTXO uzunluğu dönem sonundan daha büyük - + UTXO amount is less than 10 UTXO miktarı 10'dan az - + One hour did not pass yet Henüz bir saat geçmedi - + Transaction is in mempool İşlem mempool'da - + Unknown problem Bilinmeyen hata - + Cancel İptal - + Confirm Onayla @@ -812,37 +633,55 @@ CoinMenu - + Disable %1 TICKER %1'i Etkisizleştir - + Disable and Delete %1 TICKER %1'i Etkisizleştir ve Sil - + Disable all %1 assets Tüm %1 türü varlıkları etkisizleştir - + Disable all assets Tüm varlıkları etkisizleştir + + + Disable 0 balance assets + + + + + ComboBoxWithSearchBar + + + Search + Ara + Combo_fiat - + + Language + Dil + + + Fiat Döviz - + Recommended: Önerilen: @@ -893,74 +732,83 @@ ConfirmTradeModal - + Confirm Exchange Details Al-Sat Detaylarını Onayla - + This swap request can not be undone and is a final event! Bu takas isteği geri döndürülemez! - - Total %1 fees: %2 (%3) - Toplam %1 ücreti: %2 (%3) - - - + Security configuration Güvenlik yapılandırması - - dPoW protected - dPoW korumalı - - - - + Read more about dPoW dPoW hakkında daha fazla bilgi - + Use custom protection settings for incoming %1 transactions TICKER %1 işlemleri için özel güvenlik ayarları kullan - + Enable Komodo dPoW security Komodo dPoW güvenliğini etkinleştir - + %1 confirmations for incoming %2 transactions Gelen %2 işlemleri için %1 onay - + This transaction can take up to 60 mins - DO NOT close this application! Bu işlem 60 dakikayı bulabilir - Programı KAPATMAYINIZ! - + + Trade price is more than 50% different to CEX! Confirm? + Takas ücreti CEX ile karşılaştırıldığında %50'den daha fazla farka sahip. Onaylıyor musunuz? + + + + Loading fees... + + + + + <b>Total %1 fees:</b> + <b>Toplam %1 işlem giderleri: </b> + + + + dPoW protected + dPoW korumalı + + + Required Confirmations Gereken Onaylar - + Warning, this atomic swap is not dPoW protected! Uyarı, bu atomik takas dPoW korumalı değil! - + Cancel İptal - + Confirm Onayla @@ -981,181 +829,197 @@ Etkinleştirilmiş koinlerin mevcut sayısı yapılandırma ayarlarınızla eşleşmiyor. Varlık yapılandırmanız sıfırlanacak. - + Matching Eşleşiyor - + Order Matching Emir Eşleşiyor - + Matched Eşleşti - + Order Matched Emir Eşleşti - + Ongoing Devam ediyor - + Swap Ongoing Takas Devam Ediyor - + Successful Başarılı - + Swap Successful Takas Başarılı - + Refunding Geri ödeniyor - + Failed Başarısız - + Swap Failed Takas Başarısız - + Unknown Bilinmiyor - + Unknown State Bilinmeyen durum - + Started Başlatıldı - + Negotiated Pazarlık yapıldı - + Taker fee sent Alıcı ücreti gönderildi - + Maker payment received Yapıcı ödemesi alındı - + Maker payment wait confirm started Yapıcı ödemesi bekleme onayı başladı - + Maker payment validated and confirmed Yapıcı ödemesi doğrulandı ve onaylandı - + Taker payment sent Alıcı ödemesi gönderildi - + Taker payment spent Alıcı ödemesi harcandı - + Maker payment spent Yapıcı ödemesi harcandı - + Finished Tamamlandı - + Start failed Başlatılamadı - + Negotiate failed Pazarlık başarısız - + Taker fee validate failed Alıcı ücreti doğrulanamadı - + Maker payment transaction failed Yapıcı ödeme işlemi başarısız - + Maker payment Data send failed Yapıcı ödeme verileri gönderilemedi - + Maker payment wait confirm failed Yapıcı ödemesi bekleme onayı başarısız - + Taker payment validate failed Alıcı ödemesi doğrulanamadı - + Taker payment wait confirm failed Alıcı ödemesi bekleme onayı başarısız oldu - + Taker payment spend failed Alıcı ödeme harcaması başarısız oldu - + Maker payment wait refund started Yapıcı ödemesi bekleme iadesi başladı - + Maker payment refunded Yapıcı ödemesi iade edildi - + Maker payment refund failed Yapıcı ödeme iadesi başarısız + + DatePicker + + + Date + Tarih + + + + DefaultCopyIcon + + + copied to clipboard + + + DefaultRangeSlider @@ -1169,6 +1033,14 @@ Maks + + DefaultTextEdit + + + copied to clipboard + + + DeleteWalletModal @@ -1211,7 +1083,7 @@ DexAppPasswordField - + Type password @@ -1219,34 +1091,32 @@ DexKeyChecker - + At least 1 lowercase alphabetical character En az 1 küçük harf - + At least 1 uppercase alphabetical character En az 1 büyük harf - + At least 1 numeric character En az 1 sayı - + At least 1 special character (eg. !@#$%) En az 1 özel karakter (ör. !@#$%) - - - At least %n character(s) - - En az %n karakter - + + + Between %1 and %2 character(s) + - + Password and Confirm Password have to be same Parola ve Parola Doğrulaması aynı olmalıdır @@ -1254,7 +1124,7 @@ DexPaginator - + items per page sayfa başına öğe @@ -1280,55 +1150,136 @@ DexSweetComboBox - + Search Ara + + EditContactModal + + + Edit contact + Kişiyi düzenle + + + + Contact name + + + + + Enter a contact name + Bir kişi adı girin + + + + Address list + + + + + Address Book + Adres Defteri + + + + address copied to clipboard + + + + + Edit + Düzenle + + + + + Add + + + + + Tags + Etiketler + + + + Add tag + + + + + Cancel + İptal + + + + Confirm + Onayla + + + + EnableAssetModal + + + The selected address belongs to a disabled asset, you need to enabled it before sending. + + + + + Enable + Etkinleştir + + + + Cancel + İptal + + EnableCoinModal - + Enable assets Varlıkları etkineştir - + Search asset - - Add a custom asset to the list - Listeye özel varlık ekleyin - - - + All assets are already enabled! Bütün varlıklar zaten etkinleştirildi! - + Change assets limit Varlıkların limitini değiştirin - + + Cancel + İptal + + + Select all assets Tüm varlıkları seç - + You can still enable %1 assets. Selected: %2. Hala %1 varlık etkinleştirebilirsiniz. Seçilen: %2. - - Close - Kapat + + Add a custom asset + - + Enable Etkinleştir @@ -1341,27 +1292,27 @@ Sorumluluk Reddi & Kullanım Şartları - + Accept EULA Son Kullanıcı Lisans Sözleşmesi (EULA) 'ni kabul ediyorum - + Accept Terms and Conditions Şartları ve koşulları kabul ediyorum - + Close Kapat - + Cancel İptal - + Confirm Onayla @@ -1374,40 +1325,73 @@ Kritik Hata - - Connection has been lost. You have been disconnected. - Bağlantı kaybedildi. + + Connection has been lost. You have been disconnected. + Bağlantı kaybedildi. + + + + Close + Kapat + + + + FeeInfo + + + Minimum fee + En düşük ücret + + + + Fees will be calculated + Ücretler hesaplanacak + + + + GasInfoModal + + + How do I calculate gas? + + + + + Gas is measured in gwei. Gwei is just a unit of Ether, and is equal to 0.000000001 ETH (or the equivalent platform coin such as AVAX or BNB). The gas price varies over time depending on network congestion. + + + + + The gas limit is how many units of gas (maximum) you allocate to pay for a transaction. The gas required depending on the size of the transaction & data being transmitted. + - - Close - Kapat + + A standard transaction not involving contracts uses 21,000 gas units, with any of the limit remaining returned to the source address. + - - - FeeInfo - - Minimum fee - En düşük ücret + + Transactions involving contracts may result in the whole limit being consumed, so be careful not to set it too high. + - - Fees will be calculated - Ücretler hesaplanacak + + For more information, read the article at <a href="https://support.mycrypto.com/how-to/sending/how-to-know-what-gas-limit-to-use">https://support.mycrypto.com/how-to/sending/how-to-know-what-gas-limit-to-use</a> + General - + %n day(s) %n gün - + %nd day @@ -1415,7 +1399,7 @@ - + %nh hours @@ -1423,7 +1407,7 @@ - + %nm minutes @@ -1431,7 +1415,7 @@ - + %ns seconds @@ -1439,7 +1423,7 @@ - + %nms milliseconds @@ -1447,66 +1431,92 @@ - + - - - + + <b>Taker tx fee:</b> + + + + + <b>Dex tx fee:</b> + + + + + <b>Dex fee:</b> + + + + + <b>Maker tx fee:</b> + + + + 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 - Lütfen hacim alanını doldurunuz + + + + + + 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 @@ -1514,146 +1524,165 @@ Header - + You get Alacağınız - + You send Göndereceğiniz - + Fiat Price Döviz Fiyatı - + CEX rate CEX oranı - Price Fiyat - + Quantity Miktar - + Total Toplam - - History - - - Recent Swaps - Son Takaslar - - ImportWallet - + Failed to Import the wallet - + Import wallet - Setup - + Import wallet - Choose password - + Wallet Name Cüzdan Adı - + Enter seed - - BIP39 seed validation failed, try again or select 'Allow custom seed' + + Your seed is not BIP39 compliant. +Try again or select 'Allow custom seed' to continue. + + + + + + i understand + Anladım + + + + + я согласен + + + + + + je comprends + + + + + + entiendo - + + + anladım + + + + + + ich verstehe + + + + + Ok + Tamam + + + Allow custom seed Özel Seed'e izin ver - + <strong>Allow custom seed</strong> - + Custom seed phrases might be less secure and easier to crack than a generated BIP39 compliant seed phrase or private key (WIF).<br><br>To confirm you understand the risk and know what you are doing, type <strong>'I understand'</strong> in the box below. - + Özel çekirdek tümceler, oluşturulmuş bir BIP39 uyumlu çekirdek sözcük grubu veya özel anahtara (WIF).<br><br> Riski anladığınızı ve ne yaptığınızı bildiğinizi doğrulamak için lütfen aşağıdaki kutuya <strong>'Anladım'</strong> yazın. - I understand - - - - - Enable - Etkinleştir + Anladım - + Next İleri - + Enter the same password to confirm Doğrulamak için aynı parolayı giriniz - + Continue Devam - - Languages - - - Language - Dil - - LinksRow - + Join our Discord server Discord kanalımıza katılın - + Follow us on Twitter Bizi Twitter'dan takip edin - + Go to Support Guides Destek Kılavuzlarına Git @@ -1665,16 +1694,26 @@ Funds are recoverable Fonlar kurtarılabilir + + + Best Orders + En İyi Emirler + + + + Enter volume to see best orders. + + ListDelegate - + %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?<br><a href='#'>Yes</a> - <a href='#no'>No</a> %1 etkin değil - En iyi %2 siparişini seçebilmesi için etkinleştirmek istiyor musunuz ? <br><a href='#'>Evet</a> - <a href='#no'>Hayır</a> - + This order requires a minimum amount of %1 %2 <br>You don't have enough funds.<br> %3 @@ -1713,17 +1752,52 @@ Login - + Incorrect Password Yanlış Parola - - Connect + + Log In + + + + + Cancel + İptal + + + + LogoutModal + + + Exit %1 or go to login menu? + + + + + Warning: You currently have a swap in progress. +Logging out may result in a failed swap. + + + + + Warning: You currently have open maker orders. +They will be removed from the orderbook until you log in again. + + + + + Login menu + + + + + Exit - + Cancel İptal @@ -1731,129 +1805,141 @@ Main - + Segwit - + Confirmation - + Do you want to send your %1 funds to %2 wallet first? - + Success - + Your transaction is send, may take some time to arrive - - Wallet Balance - Cüzdan Bakiyesi - - - + Price Fiyat - - Change 24h - Değişim 24sa + + Change 24hr + + + + + Porfolio + - - Portfolio % - Portföy % + + Contract Address + - + Send Gönder - + Enable %1 ? %1 Etkinleştirilsin mi ? - + Yes Evet - + No Hayır - + Receive Al - + Swap Takasla - + + is wallet only + + + + Rewards - + Faucet Musluk - + + + + Public Key + + + + + Copied to Clipboard + Panoya Kopyalandı + + + Loading market data Piyasa bilgisi yükleniyor - + There is no chart data for this ticker yet Henüz bu hisse senedi için grafik verisi yok - - Loading - Yükleniyor - - - - Scanning blocks for TX History... - TX Geçmişi için bloklar taranıyor ... + + Fetching transactions... + - - Syncing TX History... - TX Geçmişi senkronize ediliyor ... + + Please wait, %1 is %2 + - - No transactions - İşlem yok + + % activated... + - - Refreshing - Yenileniyor + + No transactions available + - - Fetching transactions - İşlemler alınıyor + + Click to view your address on %1 (%2) block explorer + @@ -1861,27 +1947,102 @@ Al Sat + + Trading Information + Al Sat Bilgisi + + + + Chart + Grafik + + + Orders Emirler + History Tarihçe + + + Place Order + Emir Ver + + + + Order Selected + Emir Seçildi + + + + START SWAP + Takası başlat + + + + + Address Book + Adres Defteri + + + + Search contact + Kişileri ara + + + + + NEW CONTACT + Yeni bağlantı + + + + Name + İsim + + + + Tags + Etiketler + + + + Edit + Düzenle + + + + Delete + Sil + + + + address copied to clipboard + + + + + This contact does not have any registered address. + + MarketModeSelector - - Sell - Sat + + Sell %1 + TICKER + - - Buy - Satın Al + + Buy %1 + TICKER + @@ -1929,164 +2090,196 @@ - NewUpdateModal + NewContactPopup + + + Contact name + + - - Searching new updates... - Yeni güncellemeler aranıyor... + + This contact name already exists. + Bu kişi adı zaten mevcut. - - Please wait while the application is finding a new update... You can close this modal if you want. - Uygulama yeni bir güncelleme ararken lütfen bekleyin... İsterseniz bu sekmeyi kapatabilirsiniz. + + + ADD + + + + NewUpdateModal - - Already updated - Zaten güncellendi + + + + Searching new updates + - - %1 is already up-to-date ! - %1 zaten güncel ! + + Fetching... + - + + + + Close Kapat - - New update detected ! - Yeni güncelleme tespit edildi ! - - - - Do you want to update %1 from %2 to %3 ? - %1'i %2'den %3'e güncellemek istiyor musunuz ? + + Could not check new updates for the following reason: +%1 + - - Download - İndir + + New version found + - - Remind me later - Daha sonra hatırlat + + Mandatory version found + - - Download in progress... - İndirme işlemi devam ediyor... + + %1 %2 is available ! + - - Update downloaded - Güncelleme indirildi + + This update is mandatory to continue using the application + - - Update has been successfully downloaded. Do you want to restart the application now ? - Güncelleme başarıyla indirildi. Uygulamayı şimdi yeniden başlatmak istiyor musunuz ? + + Close Dex + - - Restart now - Şimdi yeniden başlat + + Your application is updated. + - - Restart later - Daha sonra yeniden başlat + + Download + İndir NewWallet - + Wrong word, please check again Hatalı kelime, lütfen kontrol ediniz - + + st + + + + + nd + + + + + rd + + + + + th + + + + Failed to create a wallet Cüzdan oluşturulamadı - + New Wallet Yeni Cüzdan - + Confirm Seed Seed'i Onayla - + Choose Password - + Important: Back up your seed phrase before proceeding! Önemli: Devam etmeden önce seed kelimelerinizi yedekleyin! - + We recommend storing it offline. Çevrimdışı saklamanızı öneririz. - + Generated Seed Seed Oluştur - + Seed phrase - + copied to clipboard - + Next İleri - + Let's double check your seed phrase Seed kelimelerinizi tekrar kontrol edelim - + Your seed phrase is important - that's why we like to make sure it's correct. We'll ask you three different questions about your seed phrase to make sure you'll be able to easily restore your wallet whenever you want. Seed kelimeleriniz önemlidir - bu yüzden doğru olduğundan emin olmak istiyoruz. Cüzdanınızı istediğiniz zaman kolayca kurtarabileceğinizden emin olmak için seed kelimeleriniz hakkında üç farklı soru soracağız. - - - Enter the %n. word - - %n. kelimeyi giriniz - + + + Enter the + + + + + word + - + Check - + Enter the same password to confirm Doğrulamak için aynı parolayı giriniz - + Continue Devam @@ -2117,150 +2310,152 @@ NotificationsModal - + Matching Eşleşiyor - + Order Matching Emir Eşleşiyor - + Matched Eşleşti - + Order Matched Emir Eşleşti - + Ongoing Devam ediyor - + Swap Ongoing Takas Devam Ediyor - + Successful Başarılı - + Swap Successful Takas Başarılı - + Refunding Geri ödeniyor - + Failed Başarısız - + Swap Failed Takas Başarısız - + Unknown Bilinmiyor - + Unknown State Bilinmeyen durum - + Swap status updated Takas durumu güncellendi - + You sent %1 %1 gönderdiniz - + You received %1 %1 aldınız - + Your wallet balance changed Cüzdan bakiyeniz değişti - + + %1 Enable status + TICKER + + + + Please check your internet connection (e.g. VPN service or firewall might block it). Lütfen internet bağlantınızı kontrol edin (ör. VPN hizmeti veya güvenlik duvarı bağlantıyı engelliyor olabilir). - + Failed to enable %1 TICKER %1 etkinleştirilemedi - + + + Failed to disable %1 + TICKER + + + + + Endpoint not reachable Uç nokta ulaşılabilir değil - + Could not reach to endpoint Uç noktaya ulaşılamadı - - Mismatch at %1 custom asset configuration - TICKER - %1 özel varlık yapılandırmasında uyuşmazlık - - - - Application needs to be restarted for %1 custom asset. - TICKER - %1 özel varlığı için uygulamanın yeniden başlatılması gerekiyor. - - - - Batch %1 failed. Reason: %2 - %1 toplu işlemi başarısız oldu. Sebep: %2 - - - + Show Göster - + Restart Yeniden Başlat - + Quit Çık - - There isn't any notification - Bildirim yok + + Notifications + + + + + There aren't any notifications + - + Mark all as read @@ -2268,44 +2463,97 @@ OrderForm - + Amount to sell Satılacak miktar - + Amount to receive Alınacak miktar - - Min volume: + + Max + Maks + + + + Swap 25% of your tradable balance. + + + + + Swap 50% of your tradable balance. + + + + + Swap 100% of your tradable balance. + + + + + Min Volume + + + + + Min amount to sell + + + + + Min amount to receive + + + + + Minimum accepted trade equals 10% of order volume. + + + + + Minimum accepted trade equals 25% of order volume. - - How to use the pro-view slider ? + + Minimum accepted trade equals 50% of order volume. - - This slider is used to setup the order requirements you need. -Left slider: Sets the minimum amount required to process a trade. -Right slider: Sets the volume you want to trade. + + Min volume: - + Use custom minimum trade amount - + Price Fiyat - + + Reduce 1% relative to CEX market price. + + + + + Use CEX market price. + + + + + Increase 1% relative to CEX market price. + + + + Volume Hacim @@ -2313,7 +2561,7 @@ Right slider: Sets the volume you want to trade. OrderLine - + Funds are recoverable Fonlar kurtarılabilir @@ -2321,7 +2569,7 @@ Right slider: Sets the volume you want to trade. OrderList - + No results found @@ -2329,97 +2577,114 @@ Right slider: Sets the volume you want to trade. OrderModal - + Swap Details Takas Detayları - + Order Details Emir Detayları - + + Order Type + + + + Maker Order Yapıcı Emri - + Taker Order Alıcı Emri - + Refund State Geri Ödeme Durumu - + Your swap failed but the auto-refund process for your payment started already. Please wait and keep application opened until you receive your payment back Takas işlemi başarısız oldu, ancak otomatik geri ödeme süreci başladı. Lütfen bekleyin ve ödemenizi geri alana kadar uygulamayı açık tutun - + Date Tarih - - ID - ID - - - + Recover Funds Fon Kurtar - + Refunding... - + View on Explorer Explorer'da Göster - - Maker Payment Sent ID - Yapıcı Ödemesi Gönderilen Kimliği + + Cancel Order + Emri İptal Et - - Maker Payment Spent ID - Yapıcı Ödemesi Harcanan Kimliği + + Error ID + Hata ID - - Taker Payment Spent ID - Alıcı Ödemesi Harcanan Kimliği + + + Swap ID + - - Taker Payment Sent ID - Alıcı Ödemesi Gönderilen Kimliği + + Maker Payment Sent Transaction ID + - - Cancel Order - Emri İptal Et + + Maker Payment Spent Transaction ID + - - Error ID - Hata ID + + Maker Payment TXID + + + + + Taker Payment Spent Transaction ID + - + + Taker Payment Sent Transaction ID + + + + + Taker Payment TXID + + + + + Error Log Hata Kaydı - + Close Kapat @@ -2427,64 +2692,62 @@ Right slider: Sets the volume you want to trade. OrderRemovedModal - + Selected Order Removed Seçilen Emir Kaldırıldı - - The selected order does not exist anymore, it might have been matched or canceled, and no order with a better price is available. Please select a new order. - Seçilen emir artık mevcut değil, eşleşmiş veya iptal edilmiş olabilir, ve daha iyi fiyatlı bir emir bulunmamakta. Lütfen yeni bir emir seçin. + + The selected order does not exist anymore, it might have been matched or canceled, and no order with a better price is available. +Please select a new order. + - + OK TAMAM - - Orders - - - Orders - Emirler - - OrdersPage - + From Gönderen - + To Alan - + Apply Filter Filtreyi Uygula - - + + Filter - + Date Tarih - + Export CSV CSV'yi dışa aktar - + + Cancel All + + + + Please choose the CSV export name and location Lütfen CSV dışa aktarma adını ve konumunu seçin @@ -2492,7 +2755,7 @@ Right slider: Sets the volume you want to trade. Pagination - + items per page sayfa başına öğe @@ -2500,41 +2763,39 @@ Right slider: Sets the volume you want to trade. PasswordField - + Password Parola - + Enter your wallet password Cüzdan parolanızı girin - + At least 1 lowercase alphabetical character En az 1 küçük harf - + At least 1 uppercase alphabetical character En az 1 büyük harf - + At least 1 numeric character En az 1 sayı - + At least 1 special character (eg. !@#$%) En az 1 özel karakter (ör. !@#$%) - - - At least %n character(s) - - En az %n karakter - + + + Between %1 and %2 character(s) + @@ -2558,66 +2819,66 @@ Right slider: Sets the volume you want to trade. Portfolio - + + ADD ASSET + + + + Search asset - + Show only coins with balance Sadece bakiyesi olan koinleri göster - + (%1/%2) - + Portfolio - - - Add asset - Varlık ekle - PriceLine - + Set swap price for evaluation Değerlendirme için takas fiyatı belirleyin - + Exchange rate Döviz kuru - + Selected Seçili - + Expensive Pahalı - + Expedient Uygun - + %1 compared to CEX PRICE_DIFF% CEX ile karşılaştırıldığında %1 - + CEXchange rate CEXchange kuru @@ -2625,37 +2886,32 @@ Right slider: Sets the volume you want to trade. PriceLineSimplified - - Set swap price for evaluation - Değerlendirme için takas fiyatı belirleyin - - - + Exchange rate Döviz kuru - + Selected Seçili - + CEXchange rate CEXchange kuru - + Expensive Pahalı - + Expedient Uygun - + %1 compared to CEX PRICE_DIFF% CEX ile karşılaştırıldığında %1 @@ -2664,91 +2920,51 @@ Right slider: Sets the volume you want to trade. ProView - + Failed to place the order Emir başarısız oldu - + Placed the order Emir başarılı + + + QObject - - Chart - Grafik - - - - Trading Information - Al Sat Bilgisi - - - - Exchange Rates - Döviz kurları - - - - Orders - Emirler - - - - History - Tarihçe - - - - Order Book - Emir Defteri - - - - Best Orders - En İyi Emirler - - - - Place Order - Emir Ver - - - - START SWAP + + Cannot reach the endpoint: - - - Order Selected - Emir Seçildi - ReceiveModal - Receive - Al + Receive %1 + TICKER + - + Only send %1 to this address TICKER - Bu adrese yalnızca %1 gönder + - + %1 address + TICKER - - copied to clipboard + + copied to clipboard. - + Close Kapat @@ -2756,94 +2972,97 @@ Right slider: Sets the volume you want to trade. RecoverSeedModal - - + + View seed and private keys Seed ve özel anahtarları görüntüle - + Please enter your password to view the seed. Seed'i görmek için lütfen parolanızı giriniz. - - Wrong Password - Yanlış Parola - - - - Cancel - İptal + + Seed + - - Seed phrase + + Backup Seed - - - - copied to clipboard + + Public Address copied to clipboard - - RPC password - + + Cancel + İptal - - phrase key copied to clipboard - + + Incorrect Password + Yanlış Parola - - Backup seed - Seed'i yedekle + + + copied to clipboard + - + + RPC Password RPC Parolası - + Search a coin. Koin ara. - - %1 address - + + Public Address + Public Adres - - %1 private key + + Private Key copied to clipboard - - Public Address - Public Adres - - - + Private Key Private Key - - Close - Kapat - - - + View Görüntüle + + RemoveContactPopup + + + Do you want to remove this contact ? + Bu kişiyi kaldırmak istiyor musunuz ? + + + + Yes + Evet + + + + No + Hayır + + RestartModal @@ -2888,140 +3107,165 @@ Right slider: Sets the volume you want to trade. Ara - - SellBox - - - Sell - Sat - - SendModal - + Failed to send Gönderilemedi - - Failed to Send - Gönderilemedi - - - + Prepare to send Göndermeye hazırlanıyor - + Address of the recipient - + Amount to send - - Max amount + + Gas price - - Gas price - + + Cancel + İptal - + Recipient's address Alıcı adresi - - Address Book - Adres Defteri - - - + The address has to be mixed case. Adres, büyük-küçük harf karışık olmalıdır. - + + Failed to Broadcast + + + + Fix Düzelt - - Enable Custom Fees - Özel İşlem Ücretlerini Etkinleştir + + MAX + MAKS + + + + Fiat amount: Unavailable + + + + + Fiat amount: %1 + + + + + %1 amount: %2 + + + + + Specify in Fiat + - - Only use custom fees if you know what you are doing! - Özel işlem ücretleri hakkında bilginiz yoksa kullanmayınız! + + Specify in Crypto + + + + + Enable Custom Fees + Özel İşlem Ücretlerini Etkinleştir - + Enter the custom fee Özel ücreti giriniz - + Gas Limit Gas Limiti - + Custom Fee can't be higher than the amount Özel İşlem Ücreti takas miktarından daha yüksek olamaz - + Not enough funds. Yetersiz bakiye. - + + You have %1 AMT TICKER %1'niz var - - Close - Kapat + + + Only use custom fees if you know what you are doing! + - + Prepare Hazırla - - + + Send Gönder - + + %1 address + TICKER + + + + + copied to clipboard. + + + + Amount Miktar - + Fees İşlem Ücreti - + Date Tarih - + Back Geri @@ -3029,43 +3273,43 @@ Right slider: Sets the volume you want to trade. SendModalContactList - + Select a contact with an %1 address %1 adresi olan bir kişi seçin - + Search for contacts... Kişi ara... - + %1 addresses %1 adresleri - + 1 address 1 adres - - + + Back Geri - + Choose an %1 address of %2 %2'nin bir %1 adresini seçin - + Name İsim - + Address Adres @@ -3073,42 +3317,60 @@ Right slider: Sets the volume you want to trade. SendResult - + Transaction Complete! İşlem Tamamlandı! - + + %1 txid + TICKER + + + + + + copied to clipboard. + + + + Recipient's address Alıcının adresi - + + %1 address + TICKER + + + + Amount Miktar - + Fees İşlem Ücreti - + Date Tarih - + Transaction Hash İşlem Hash'i - + Close Kapat - + View on Explorer Explorer'da göster @@ -3116,282 +3378,240 @@ Right slider: Sets the volume you want to trade. SettingModal - - Confirm Logout - - - - - Are you sure you want to log out? - - - - - Yes - Evet - - - - + + Cancel İptal - + Settings Ayarlar - - + Language Dil - + User Interface Kullanıcı Arayüzü - + Security Güvenlik - - General - Genel + + General + Genel + + + + About & Version + + + + + Enable Desktop Notifications + Masaüstü Bildirimlerini Aktif Et + + + + Maximum number of enabled coins + Maksimum etkin koin sayısı + + + + Logs + Günlük Kaydı + + + + Open Folder + Klasörü Aç + + + + + Reset wallet configuration + + + + + This will restart your wallet with default settings + + + + + + Confirm + Onayla + + + + Changing theme to %1 + + + + + Disable 2FA? + - - About & Version + + Enter your wallet password to confirm - - Enable Desktop Notifications - Masaüstü Bildirimlerini Aktif Et + + Type password + - - Maximum number of enabled coins - Maksimum etkin koin sayısı + + 2FA status + - - Logs - Günlük Kaydı + + 2FA disabled successfully + - - Open Folder - Klasörü Aç + + + Ok + Tamam - - - Reset wallet configuration + + Wrong password! - - This will restart your wallet with default settings + + Wallet password is incorrect - - Confirm - Onayla + + Application Version + - - Changing theme to %1 + + 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ü - - DEX Version - - - - - DEX Version copied to clipboard. - - - - + MM2 version MM2 sürümü - + MM2 Version - + MM2 Version 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.Ş. - - - - Settings - - - Fiat - Döviz - - - - Recommended: - Önerilen: - - - - Enable Desktop Notifications - Masaüstü Bildirimlerini Aktif Et - - - - Use QtTextRendering Or NativeTextRendering - QtTextRendering veya NativeTextRendering Kullan - - - - Open Logs Folder - Günlük Kaydı Klasörünü Aç - - - + Disclaimer and ToS Sorumluluk Reddi ve K.Ş. - - - Setup Camouflage Password - Kamuflaj Parolasını Ayarla - - - - mm2 version - mm2 versiyonu - - - - Delete Wallet - Cüzdanı Sil - - - - View seed and private keys - Seed ve özel anahtarları görüntüle - - - - Reset wallet configuration - - - - - Log out - Çıkış yap - Sidebar - - Search coin - + + Search + Ara - + Add asset Varlık ekle @@ -3412,32 +3632,32 @@ Right slider: Sets the volume you want to trade. SubBestOrder - + Token Token - + Available Quantity Mevcut Miktar - + Available Quantity (in %1) Mevcut Miktar (%1 olarak) - + Fiat Volume Fiat Hacmi - + CEX Rate CEX Oranı - + %1 is not enabled - Do you want to enable it to be able to select %2 best orders ?<br><a href='#'>Yes</a> - <a href='#no'>No</a> %1 etkin değil - En iyi %2 siparişini seçebilmesi için etkinleştirmek istiyor musunuz ? <br><a href='#'>Evet</a> - <a href='#no'>Hayır</a> @@ -3445,22 +3665,22 @@ Right slider: Sets the volume you want to trade. SubCoinSelector - + Token Token - + Balance Bakiye - + Balance Fiat Fiat Bakiye - + No Selectable coin. Seçilebilir Koin Yok @@ -3503,32 +3723,32 @@ Right slider: Sets the volume you want to trade. Gönderen - + To Alan - + Cancel İptal - + Apply filter Filtreyi uygula - + Export Dışarı al - + Please choose the CSV export name and location Lütfen CSV dışa aktarma adını ve konumunu seçin - + No results found @@ -3537,261 +3757,240 @@ Right slider: Sets the volume you want to trade. SubOrders - + Orders Emirler - + Filter - + Date Tarih - + Close filtering options. - + Open filtering options. - + Filter settings Ayarları filtrele - + From Gönderen - + To Alan - + Cancel İptal - + Apply filter Filtreyi uygula - + No results found - Support - - - Update available - Güncelleme mevcut - - - - Up to date - Güncel - - - - Changelog - Değişim günlüğü - - - - Open Logs Folder - Günlük Kaydı Klasörünü Aç - + SupportModal - + Frequently Asked Questions - Sıkça Sorulan Sorular + Sıkça Sorulan Sorular - + Do you store my private keys? - Özel anahtarlarımızı depoluyor musunuz? + Özel anahtarlarımızı depoluyor musunuz? - + No! %1 is non-custodial. We never store any sensitive data, including your private keys, seed phrases, or PIN. This data is only stored on the user’s device and never leaves it. You are in full control of your assets. - Hayır! %1 gözetlenmiyor. Özel anahtarlarınız, seed veya PIN'iniz dahil olmak üzere hiçbir hassas veriyi asla depolamayız. Bu veriler yalnızca kullanıcının cihazında depolanır ve asla oradan çıkmaz. Varlıklarınızın tam kontrolü sizdedir. + Hayır! %1 gözetlenmiyor. Özel anahtarlarınız, seed veya PIN'iniz dahil olmak üzere hiçbir hassas veriyi asla depolamayız. Bu veriler yalnızca kullanıcının cihazında depolanır ve asla oradan çıkmaz. Varlıklarınızın tam kontrolü sizdedir. - + How is trading on %1 different from trading on other DEXs? - %1'de işlem yapmanın diğer DEX'lerde işlem yapmaktan farkı nedir? + %1'de işlem yapmanın diğer DEX'lerde işlem yapmaktan farkı nedir? - - Other DEXs generally only allow you to trade assets that are based on a single blockchain network, use proxy tokens, and only allow placing a single order with the same funds. + + Other DEXs generally only allow you to trade assets that are based on a single blockchain network, use proxy tokens, and only allow placing a single order with the same funds. %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. - Diğer DEX'ler genellikle yalnızca tek bir blok zinciri ağına dayalı varlıklarla ticaret yapmanıza izin verir, ve aracı token kullanmanızı ister ve yalnızca aynı fonlarla tek bir sipariş vermenize izin verir. - -%1, aracı token olmadan iki farklı blok zinciri ağında yerel olarak ticaret yapmanızı sağlar. Aynı parayla birden fazla sipariş verebilirsiniz. Örneğin, KMD, QTUM veya VRSC için 0,1 BTC satabilirsiniz - otomatik olarak doldurulan ilk sipariş diğer tüm siparişleri iptal eder. + + + + + 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. + 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? - + 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. + The atomic swap protocol requires both participants to stay online and monitor the involved blockchains for the process to stay atomic. + If you go offline, so will your orders, and any that are in progress will fail, leading to potential loss of trade / transaction fees, and a wait for the swap to timeout and issue a refund. It may also negatively affect your wallet's reputation score for future trade matching. + 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. - Evet. Her atomik takası başarıyla tamamlamak için internete bağlı kalmalı ve uygulamanızın çalışır durumda olmasını sağlamalısınız (bağlantıda çok kısa kesintilerde sorun yoktur). Aksi takdirde, eğer satıcıysanız işlemin iptali ve alıcı iseniz fon kaybı riski vardır. -Atomik takas protokolü, her iki katılımcının da çevrimiçi kalmasını ve sürecin atomik kalması için ilgili blok zincirlerini izlemesini gerektirir. -Çevrimdışı olursanız, siparişleriniz ve devam eden siparişleriniz de başarısız olur, bu da potansiyel ticaret / işlem ücretleri kaybına ve takasın zaman aşımına uğraması ve geri ödeme yapılması için beklemeye neden olur. Ayrıca gelecekteki ticaret eşleşmeleri için cüzdanınızın itibar puanını da olumsuz etkileyebilir. -Tekrar çevrimiçi olduğunuzda, siparişleriniz çevrimdışı olmadan önce belirlediğiniz fiyat üzerinden tekrar yayınlanmaya başlayacaktır. Bu arada önemli bir fiyat hareketi olduysa, istemeden birine pazarlık teklif edebilirsiniz! -Bu nedenle, %1 'i kapatmadan önce siparişleri iptal etmenizi veya %1 'i yeniden başlatırken fiyatlarınızı gözden geçirmenizi ve revize etmenizi öneririz. + - + How are the fees on %1 calculated? - %1 üzerinde işlem ücretleri nasıl hesaplanır? + %1 üzerinde işlem ücretleri nasıl hesaplanır? - + There are two fee categories to consider when trading on %1. 1. %1 charges approximately 0.13% (1/777 of trading volume but not lower than 0.0001) as the trading fee for taker orders, and maker orders have zero fees. + 2. Both makers and takers will need to pay normal network fees to the involved blockchains when making atomic swap transactions. Network fees can vary greatly depending on your selected trading pair. - %1 üzerinde alım satım yaparken iki işlem ücreti kategorisi vardır. - -1. %1, alıcı emirler için işlem ücreti olarak yaklaşık %0.13'ünü (0,0001'den düşük olmayacak şekilde alım satım hacminin 1/777'si) alır ve satıcı emirleri sıfır ücrete sahiptir. -2. Hem satıcılar hem de alıcılar, atomik takas işlemleri yaparken ilgili blok zincirlerine normal ağ ücretleri ödemek zorundadırlar. - -Ağ ücretleri, seçtiğiniz işlem çiftine bağlı olarak büyük ölçüde değişebilir. + - - Yes! %1 offers support through the <a href="%2">%1 Discord server</a>. The team and the community are always happy to help! - + + Do you provide user support? + Kullanıcı desteği sağlıyor musunuz? - - %1 is available for mobile on both <a href="%2">Android and iPhone, and for desktop on Windows, Mac, and Linux</a> operating systems. + + Yes! %1 offers support through the <a href="%2">%1 Discord server</a>. The team and the community are always happy to help! - + Who is behind %1? - %1 arkasında kim var? + %1 arkasında kim var? - + %1 is developed by the Komodo team. Komodo is one of the most established blockchain projects working on innovative solutions like atomic swaps, Delayed Proof of Work, and an interoperable multi-chain architecture. - %1, Komodo ekibi tarafından geliştirilmiştir. Komodo, atomik takaslar, Gecikmeli Çalışma Kanıtı ve birlikte çalışabilir bir çok zincirli mimari gibi yenilikçi çözümler üzerinde çalışan en köklü blok zinciri projelerinden biridir. + %1, Komodo ekibi tarafından geliştirilmiştir. Komodo, atomik takaslar, Gecikmeli Çalışma Kanıtı ve birlikte çalışabilir bir çok zincirli mimari gibi yenilikçi çözümler üzerinde çalışan en köklü blok zinciri projelerinden biridir. - + Is it possible to develop my own white-label exchange on %1? - %1 üzerinde kendi markamla borsamı geliştirmem mümkün mü? + %1 üzerinde kendi markamla borsamı geliştirmem mümkün mü? - + Absolutely! You can read our developer documentation for more details or contact us with your partnership inquiries. Have a specific technical question? The %1 developer community is always ready to help! - Kesinlikle! Daha fazla ayrıntı için geliştirici belgelerimizi okuyabilir veya ortaklık sorularınız için bizimle iletişime geçebilirsiniz. Belirli bir teknik sorunuz mu var? %1 geliştirici topluluğu her zaman yardıma hazır! + Kesinlikle! Daha fazla ayrıntı için geliştirici belgelerimizi okuyabilir veya ortaklık sorularınız için bizimle iletişime geçebilirsiniz. Belirli bir teknik sorunuz mu var? %1 geliştirici topluluğu her zaman yardıma hazır! - + Which devices can I use %1 on? - %1 'i hangi cihazlarda kullanabilirim? + %1 'i hangi cihazlarda kullanabilirim? - - Compliance Info - Uyumluluk Bilgisi + + %1 is available for mobile on both <a href="%2">Android and iPhone, and for desktop on Windows, Mac, and Linux</a> operating systems. + - - Due to regulatory and legal circumstances the citizens of certain jurisdictions including, but not limited to, the United States of America, Canada, Hong Kong, Israel, Singapore, Sudan, Austria, Iran and any other state, country or other jurisdiction that is embargoed by the United States of America or the European Union are not allowed to use this application. - Düzenleyici ve yasal koşullar nedeniyle, Amerika Birleşik Devletleri, Kanada, Hong Kong, İsrail, Singapur, Sudan, Avusturya, İran ve Amerika Birleşik Devletleri veya Avrupa Birliği tarafından ambargo uygulanan diğer herhangi bir eyalet, ülke veya diğer bölge vatandaşlarının bu uygulamayı kullanmasına izin verilmez. + + Compliance Info + Uyumluluk Bilgisi - - How long does each atomic swap take? - Her bir atomik takas ne kadar sürer? + + Due to regulatory and legal circumstances the citizens of certain jurisdictions including, but not limited to, the United States of America, Canada, Hong Kong, Israel, Singapore, Sudan, Austria, Iran and any other state, country or other jurisdiction that is embargoed by the United States of America or the European Union are not allowed to use this application. + Düzenleyici ve yasal koşullar nedeniyle, Amerika Birleşik Devletleri, Kanada, Hong Kong, İsrail, Singapur, Sudan, Avusturya, İran ve Amerika Birleşik Devletleri veya Avrupa Birliği tarafından ambargo uygulanan diğer herhangi bir eyalet, ülke veya diğer bölge vatandaşlarının bu uygulamayı kullanmasına izin verilmez. - - Do I need to be online for the duration of the swap? - Takas süresi boyunca çevrimiçi olmam gerekir mi? + + Changelog + Değişim günlüğü - - Do you provide user support? - Kullanıcı desteği sağlıyor musunuz? + + Open Logs Folder + Günlük Kaydı Klasörünü Aç SwapProgress - + act SHORT FOR ACTUAL TIME gerçek - + est SHORT FOR ESTIMATED tahmini - + Progress details İlerleme ayrıntıları - - SweetDexComboBox - - - Search - Ara - - TextAreaWithTitle - + Save Kaydet - + Edit Düzenle - TextEditWithTitle + TextEditWithCopy - - Swap ID + + copied to clipboard + + + TextEditWithTitle - + copied to clipboard @@ -3799,7 +3998,7 @@ Ağ ücretleri, seçtiğiniz işlem çiftine bağlı olarak büyük ölçüde de TextFieldWithTitle - + Required Gerekli @@ -3815,213 +4014,281 @@ Ağ ücretleri, seçtiğiniz işlem çiftine bağlı olarak büyük ölçüde de Trade - + Swap Takasla - + Instant trading with best orders En iyi emirlerle anında alım satım - + + Reset form + + + + + You have no tradable assets + + + + From Gönderen - + Enter an amount Bir miktar gir - + MAX MAKS - + To Alan - + Pick an order Emri seç - + Price Fiyat - + Better price found: %1. Updating forms. Daha iyi fiyat bulundu: %1. Formları güncelliyor. - + Better price (%1) found but received quantity (%2) is lower than your current one (%3). Click here to update the selected order. Daha iyi fiyat (%1) bulundu, ancak alınan miktar (%2) mevcut fiyattan (%3) daha düşük. Seçilen emri güncellemek için buraya tıklayın. - - Reset form. - Formu sıfırla - - - + %1 %1 - + Tradable: Al sat yapılabilir: - + Min: %1 - + Pick a coin - + SWAP NOW - + Failed to place the order Emir başarısız oldu - + Placed the order Emir başarılı - + Entered amount must be superior than 0. Girilen tutar 0'dan büyük olmalıdır. - + You must select an order. Bir emir seçmelisiniz. - + Entered amount is below the minimum required by this order: %1 Girilen miktar, bu emrin gerektirdiği minimum %1 tutarının altında - - + + %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 - - - Search - Ara + + %1 balance does not have enough funds to pay the gas of %2 transactions + - + No buy orders found for %1. - + You can check later or try to sell a different coin. - + + Calculating fee estimate... + + + + Total %1 fees: Toplam %1 işlem giderleri: - + %2 (%3) %2 (%3) + + TradeViewHeader + + + Pro View Settings + + + + + Display Settings + + + + + Ticker Selectors + + + + + Trading Information + Al Sat Bilgisi + + + + Order Book + Emir Defteri + + + + Best Orders + En İyi Emirler + + + + Place Order + Emir Ver + + TransactionDetailsModal - + Transaction Details İşlem Detayları - + + %1 txid + TICKER + + + + + copied to clipboard. + + + + Amount Miktar - + Fees İşlem Ücreti - + + From address + + + + + To address + + + + Date Tarih - + Unconfirmed Onaylanmamış - + Transaction Hash İşlem Hash'i - + Confirmations Onay Sayısı - + Block Height Blok Uzunluğu - + From Gönderen - + To Alan - + Notes Notlar - + Close Kapat - + View on Explorer Explorer'da göster @@ -4029,22 +4296,22 @@ Ağ ücretleri, seçtiğiniz işlem çiftine bağlı olarak büyük ölçüde de Transactions - + Received Alınan - + Sent Gönderilen - + fees işlem ücretleri - + Unconfirmed Onaylanmamış @@ -4058,16 +4325,11 @@ Ağ ücretleri, seçtiğiniz işlem çiftine bağlı olarak büyük ölçüde de - WalletNameField - - - Wallet Name - Cüzdan Adı - + Vertical - - Enter the name of your wallet here - Cüzdanınızın adını giriniz + + Order Book + Emir Defteri @@ -4088,118 +4350,165 @@ Ağ ücretleri, seçtiğiniz işlem çiftine bağlı olarak büyük ölçüde de - + + Search your wallets... + + + + My Wallets Cüzdanlarım - - + + No wallets found! + + + + + Delete Sil - + Enter password to confirm deletion of - + wallet - + Type password - + Cancel İptal - - + + Wallet status - + wallet deleted successfully - - + + Ok Tamam - + wallet password is incorrect + + ZcashParamsModal + + + %1 Activation Failed! + + + + + To activate ZHTLC coins, you need to download the Zcash Params. +This might take a few minutes... + + + + + Download params & enable coins + + + + + More Info + + + + + Close + Kapat + + + + atomic_dex::settings_page + + + An error has occurred. + + + 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 on the convert button to turn it into a mixed case address - %1 için geçersiz sağlama toplamı. Karışık bir durum adresine dönüştürmek için dönüştür düğmesine tıklayın + + Invalid checksum for %1. Click the button to convert to mixed case address. + - - Legacy address used for %1, click on the convert button to convert it to a Cashaddress. - %1 için kullanılan eski adres, onu bir Cashaddress'e dönüştürmek için dönüştür düğmesine tıklayın. + + 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 @@ -4207,32 +4516,12 @@ Ağ ücretleri, seçtiğiniz işlem çiftine bağlı olarak büyük ölçüde de main - + Logout Çıkış - - Confirm Logout - - - - - Are you sure you want to log out? - - - - - Yes - Evet - - - - Cancel - İptal - - - + Balance Bakiye diff --git a/atomic_defi_design/assets/languages/gen_translation.py b/atomic_defi_design/assets/languages/gen_translation.py new file mode 100755 index 0000000000..a401e547fd --- /dev/null +++ b/atomic_defi_design/assets/languages/gen_translation.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +import os +import csv + +''' +NOTE: This script takes a CSV file as input, then generates a .ts file using the english file as a template. +There may be some postprocessing required to manually fix bad csv input and numerusform values. +''' + + +def get_lang_dict(): + with open('translations_matrix.csv') as f: + csv_reader = csv.reader(f, delimiter=',') + lang_dict = {} + line_count = 0 + for row in csv_reader: + if line_count == 0: + en = row.index("English") + es = row.index("Spanish") + de = row.index("German") + line_count += 1 + else: + lang_dict.update({ + row[en]: { + "es": row[es], + "de": row[de] + } + }) + line_count += 1 + return lang_dict + +def remove_existing_translations(): + with open(f"atomic_defi_en.ts", "r") as f: + ts_file = f.readlines() + + with open(f"atomic_defi_lang_template.ts", "w") as f: + lines = [] + ignoring = False + for l in ts_file: + if l.find(" -1 or ignoring: + ignoring = True + if l.find("translation>") > -1: + ignoring = False + else: + lines.append(l) + f.writelines(lines) + + +def generate_translation(lang='en'): + lang_dict = get_lang_dict() + remove_existing_translations() + + with open(f"atomic_defi_lang_template.ts", "r") as f: + lang_file = f.read() + + multiline = False + multiline_data = [] + untranslated_count = 0 + for i in lang_dict: + try: + # TODO: handle numerusform translations + if f"{i}" in lang_file: + lang_file = lang_file.replace(f"{i}", f"{i}\n {lang_dict[i][lang]}") + if f" {i}" in lang_file: + lang_file = lang_file.replace(f"{i}", f"{i}\n {lang_dict[i][lang]}") + elif f"{i}" in lang_file: + multiline = True + multiline_data.append(f"{lang_dict[i][lang]}") + elif multiline: + multiline_data.append(f"{lang_dict[i][lang]}") + elif f"{i}" in lang_file: + multiline_data.append(f"{lang_dict[i][lang]}") + translation = '\n'.join(multiline_data) + lang_file = lang_file.replace(f"{i}", f"{i}\n {translation}") + multiline = False + elif f"{i}" not in lang_file: + print(f"{i} ---> {lang_dict[i][lang]}") + print(f">>>>>>>>>>>>>>>>>>>>>>>>>> '{i}' not found!") + untranslated_count += 1 + else: + #print(lang_dict[i][lang]) + untranslated_count += 1 + pass + except Exception as e: + untranslated_count += 1 + print(f">>>>>>>>>>>>>>>>>>>>>>>>>> 'Error: {e} | source: {i}") + print(f"{untranslated_count} lines untranslated") + + with open(f"atomic_defi_{lang}.ts", 'w') as f: + f.write(lang_file) + + +if __name__ == '__main__': + generate_translation('es') + + \ No newline at end of file diff --git a/atomic_defi_design/assets/languages/translations_matrix.csv b/atomic_defi_design/assets/languages/translations_matrix.csv new file mode 100644 index 0000000000..37a934e80a --- /dev/null +++ b/atomic_defi_design/assets/languages/translations_matrix.csv @@ -0,0 +1,807 @@ +"Location/Area line +(German lang. file)",Location/Area,comment,"Source Line +(German lang. file)",English,"Translation Line +(German lang. file)",German,Spanish,Mandarin,… +7,Dex/Addressbook/AddAddressForm.qml,,8,Use standard network address,9,Standard-Netzwerkadresse verwenden,Utilice la dirección de red,, +12,Dex/Addressbook/AddAddressForm.qml,,13,Label,14,Bezeichnung,Etiqueta,, +17,Dex/Addressbook/AddAddressForm.qml,,18,This key already exists.,19,Dieser Schlüssel existiert bereits.,Esta clave ya existe.,, +22,Dex/Addressbook/AddAddressForm.qml,,23,Address,24,Adresse,Dirección,, +27,Dex/Addressbook/AddAddressForm.qml,,29,Cancel,30,Abbrechen,Cancelar,, +33,Dex/Addressbook/AddAddressForm.qml,,34,Convert,35,Umwandeln,Convertir,, +38,Dex/Addressbook/AddAddressForm.qml,,39,Edit,40,Bearbeiten,Editar,, +43,Dex/Addressbook/AddAddressForm.qml,,44,Add,45,Hinzufügen,Agregar,, +48,Dex/Addressbook/AddAddressForm.qml,,49,You need to enable %1 before adding this kind of address.,50,"Sie müssen %1 aktivieren, bevor Sie diese Art von Adresse hinzufügen.",Debe habilitar %1 antes de agregar este tipo de dirección.,, +53,Dex/Addressbook/AddAddressForm.qml,,54,Enable,55,Aktivieren,Habilitar,, +61,Dex/Settings/AddCustomCoinModal.qml,,62,Get the contract address from,63,Erhalten Sie die Vertragsadresse von,Obtener la dirección del contrato de,, +66,Dex/Settings/AddCustomCoinModal.qml,,67,Choose the asset type,68,Wählen Sie den Asset-Typ aus,Elija el tipo de activo,, +71,Dex/Settings/AddCustomCoinModal.qml,,72,Cancel,73,Abbrechen,Cancelar,, +78,Dex/Settings/AddCustomCoinModal.qml,,79,Next,80,Weiter,Siguiente,, +83,Dex/Settings/AddCustomCoinModal.qml,,84,Contract address,85,Vertragsadresse,Dirección del contrato,, +88,Dex/Settings/AddCustomCoinModal.qml,,89,Enter the contract address,90,Geben Sie die Vertragsadresse ein,Ingrese la dirección del contrato,, +93,Dex/Settings/AddCustomCoinModal.qml,,94,Choose the asset ticker,95,Wählen Sie den Asset-Ticker,Elija el ticker del activo,, +98,Dex/Settings/AddCustomCoinModal.qml,,99,Ticker,100,Ticker,Ticker,, +103,Dex/Settings/AddCustomCoinModal.qml,,104,Enter the ticker,105,Geben Sie den Ticker ein,Ingrese el ticker,, +108,Dex/Settings/AddCustomCoinModal.qml,,109,Get the contract address from ,110,Erhalten Sie die Vertragsadresse von,Obtener la dirección del contrato de,, +116,Dex/Settings/AddCustomCoinModal.qml,,117,Previous,118,Vorherige,Anterior,, +121,Dex/Settings/AddCustomCoinModal.qml,,122,Choose the asset logo,123,Wählen Sie ein Logo für das Asset aus,Elija el logotipo del activo,, +126,Dex/Settings/AddCustomCoinModal.qml,,127,Browse,128,Durchsuchen,Navegar,, +131,Dex/Settings/AddCustomCoinModal.qml,,132,Please choose the asset logo,133,Bitte wählen Sie für das Asset ein Logo aus,Elija el logotipo del activo,, +136,Dex/Settings/AddCustomCoinModal.qml,,137,Configuration,138,Konfiguration,Configuración,, +141,Dex/Settings/AddCustomCoinModal.qml,,142,All configuration fields will be fetched using the contract address you provided.,143,Alle Konfigurationsfelder werden mit der von Ihnen angegebenen Vertragsadresse abgerufen.,Todos los campos de configuración se obtendrán usando la dirección del contrato que proporcionó.,, +146,Dex/Settings/AddCustomCoinModal.qml,,147,Name,148,Name,Nombre,, +151,Dex/Settings/AddCustomCoinModal.qml,,152,Enter the name,153,Geben Sie den Namen ein,Ingrese el nombre,, +156,Dex/Settings/AddCustomCoinModal.qml,,157,Coingecko ID,158,Coingecko ID,Coingecko ID,, +161,Dex/Settings/AddCustomCoinModal.qml,,162,Enter the Coingecko ID,163,Geben Sie die Coingecko-ID ein,Ingrese el Coingecko ID,, +166,Dex/Settings/AddCustomCoinModal.qml,,167,Get the Coingecko ID,168,Coingecko-ID erhalten,Obtener el Coingecko ID,, +171,Dex/Settings/AddCustomCoinModal.qml,,172,Active,173,Aktiv,Activo,, +177,Dex/Settings/AddCustomCoinModal.qml,,178,Preview,179,Vorschau,Vista previa,, +182,Dex/Settings/AddCustomCoinModal.qml,,183,WARNING: Application will restart immidiately to apply the changes!,184,"WARNUNG: Die Anwendung wird sofort neu gestartet, um die Änderungen zu übernehmen!",ADVERTENCIA: ¡La aplicación se reiniciará inmediatamente para aplicar los cambios!,, +187,Dex/Settings/AddCustomCoinModal.qml,,188,"Asset not found, please go back and make sure Contract Address is correct",189,"Asset nicht gefunden, bitte gehen Sie zurück und stellen Sie sicher, dass die Vertragsadresse korrekt ist","Activo no encontrado, regrese y asegúrese de que la dirección del contrato sea correcta",, +192,Dex/Settings/AddCustomCoinModal.qml,,193,Config Fields,194,Konfigurationsfelder,Campos de configuracion,, +197,Dex/Settings/AddCustomCoinModal.qml,,198,Fetched Data,199,Abgerufene Daten,Datos obtenidos,, +202,Dex/Settings/AddCustomCoinModal.qml,,203,Submit & Restart,204,Bestätigen und Neu starten,Enviar & Reiniciar,, +210,Dex/Addressbook/AddTagPopup.qml,,211,Tag name,212,Schlagwort,Nombre de la etiqueta,, +215,Dex/Addressbook/AddTagPopup.qml,,216,Contact already has this tag.,217,Der Kontakt hat bereits dieses Schlagwort.,El contacto ya tiene esta etiqueta.,, +220,Dex/Addressbook/AddTagPopup.qml,,221,+ ADD,222,+ HINZUFÜGEN,#NAME?,, +228,Dex/Portfolio/AmountChart.qml,,229,Work in progress,230,In Arbeit,Trabajo en proceso,, +236,Dex/App.qml,,237,Recover Funds Result,238,Ergebnis der Rückerstattung der Geldmittel,Resultados de Recuperar Fondos,, +244,Dex/Addressbook/AssetFromStandardSelector.qml,,245,Choose a valid ,246,Wählen Sie eine gültige,Elija un,, +249,Dex/Addressbook/AssetFromStandardSelector.qml,,250,asset,251,Asset,activo,, +254,Dex/Addressbook/AssetFromStandardSelector.qml,,255,Search an asset,256,Asset suchen,Buscar un activo,, +259,Dex/Addressbook/AssetFromStandardSelector.qml,,260,Disabled,261,Deaktiviert,deshabilitados,, +267,Dex/Portfolio/AssetPieChart.qml,,268,Assets,269,Assets,Activos,, +275,Dex/Portfolio/AssetsList.qml,,276,Asset,277,Asset,Activo,, +280,Dex/Portfolio/AssetsList.qml,,281,Balance,282,Balance,Saldo,, +285,Dex/Portfolio/AssetsList.qml,,286,Fiat Balance,287,Fiat Balance,Saldo Fiat,, +290,Dex/Portfolio/AssetsList.qml,,291,Change 24h,292,24h Veränderung,Cambio en 24h,, +295,Dex/Portfolio/AssetsList.qml,,296,Price,297,Preis,Precio,, +300,Dex/Portfolio/AssetsList.qml,,301,Source,302,Quelle,Fuente,, +305,Dex/Portfolio/AssetsList.qml,,306,Price provider is: %1,307,Preisanbieter ist: %1,El proveedor de precios es: %1,, +313,Dex/Sidebar/Bottom.qml,,314,Settings,315,Einstellungen,Configuración,, +318,Dex/Sidebar/Bottom.qml,,319,Support,320,Support,Soporte,, +323,Dex/Sidebar/Bottom.qml,,324,Privacy,325,Datenschutz,Privacidad,, +328,Dex/Sidebar/Bottom.qml,,329,Disable Privacy?,330,Datenschutz deaktivieren?,¿Deshabilitar privacidad?,, +333,Dex/Sidebar/Bottom.qml,,334,Enter wallet password to confirm,335,Geben Sie zur Bestätigung das Kennwort der Brieftasche ein,Ingrese la contraseña de la billetera para confirmar,, +338,Dex/Sidebar/Bottom.qml,,339,Type password,340,Kennwort eingeben,Escriba la contraseña,, +343,Dex/Sidebar/Bottom.qml,,344,Confirm,345,Bestätigen,Confirmar,, +348,Dex/Sidebar/Bottom.qml,,349,Cancel,350,Abbrechen,Cancelar,, +353,Dex/Sidebar/Bottom.qml,,354,Privacy status,355,Status Datenschutz,Estado de privacidad,, +358,Dex/Sidebar/Bottom.qml,,359,Privacy mode disabled successfully,360,Der Datenschutzmodus wurde erfolgreich deaktiviert,Modo de privacidad deshabilitado correctamente,, +364,Dex/Sidebar/Bottom.qml,,365,Ok,366,Ok,Ok,, +369,Dex/Sidebar/Bottom.qml,,370,Wrong password!,371,Falsches Kennwort!,¡Contraseña incorrecta!,, +374,Dex/Sidebar/Bottom.qml,,375,wallet password is incorrect,376,Kennwort der Brieftasche ist falsch,la contraseña de la billetera es incorrecta,, +382,Dex/Settings/CamouflagePasswordModal.qml,,383,Setup Camouflage Password,384,Tarnkennwort einrichten,Configurar Contraseña Camuflaje,, +387,Dex/Settings/CamouflagePasswordModal.qml,,388,Camouflage Password is a secret password for emergency situations.,389,Das Tarnkennwort (Camouflage Password) ist ein geheimes Passwort für Notsituationen.,Contraseña Camuflaje es una contraseña secreta para situaciones de emergencia.,, +392,Dex/Settings/CamouflagePasswordModal.qml,,393,Using it to login will display your balance lower than it actually is.,394,"Wenn Sie sich damit anmelden, wird Ihr Guthaben niedriger angezeigt, als es tatsächlich ist.",Usarlo para iniciar sesión mostrará su saldo más bajo de lo que realmente es.,, +397,Dex/Settings/CamouflagePasswordModal.qml,,398,Here you enter the suffix and at login you need to enter {real_password}{suffix},399,Hier geben Sie den Zusatz ein und beim Einloggen benötigen Sie {echtes Kennwort}{suffix},Aquí ingresa el sufijo y al iniciar sesión debe ingresar {real_password}{suffix},, +403,Dex/Settings/CamouflagePasswordModal.qml,,404,Password suffix,405,Kennwort-Zusatz,Sufijo de contraseña,, +408,Dex/Settings/CamouflagePasswordModal.qml,,409,Confirm pasword suffix,410,Kennwort-Zusatz bestätigen,Confirmar sufijo,, +413,Dex/Settings/CamouflagePasswordModal.qml,,414,Enter a password suffix,415,Geben Sie einen Kennwort-Zusatz ein,Ingrese un sufijo de contraseña,, +418,Dex/Settings/CamouflagePasswordModal.qml,,419,Enter the same password suffix to confirm,420,Geben Sie zur Bestätigung denselben Kennwort-Zusatz ein,Ingrese el mismo sufijo de contraseña para confirmar,, +423,Dex/Settings/CamouflagePasswordModal.qml,,424,Cancel,425,Abbrechen,Cancelar,, +428,Dex/Settings/CamouflagePasswordModal.qml,,429,Save,430,Speichern,Guardar,, +436,Dex/Components/CannotEnableCoinModal.qml,,437,Failed to enable %1,438,Aktivierung von %1 fehlgeschlagen,No se pudo habilitar %1,, +441,Dex/Components/CannotEnableCoinModal.qml,,442,Enabling %1 did not succeed. Limit of enabled coins might have been reached.,443,Das Aktivieren von %1 war nicht erfolgreich. Das Limit der aktivierten Coins wurde möglicherweise erreicht.,No se pudo habilitar %1. Es posible que se haya alcanzado el límite de monedas habilitadas.,, +446,Dex/Components/CannotEnableCoinModal.qml,,447,Change limit in settings,448,Limit in den Einstellungen ändern,Cambiar el límite en la configuración,, +451,Dex/Components/CannotEnableCoinModal.qml,,452,Cancel,453,Abbrechen,Cancelar,, +459,Dex/Sidebar/Center.qml,,460,Portfolio,461,Portfolio,Portafolio,, +464,Dex/Sidebar/Center.qml,,465,Wallet,466,Brieftasche,Monedero,, +469,Dex/Sidebar/Center.qml,,470,DEX,471,DEX,DEX,, +474,Dex/Sidebar/Center.qml,,475,Address Book,476,Adressbuch,Libreta de direcciones,, +479,Dex/Sidebar/Center.qml,,480,Fiat,481,Fiat,Fiat,, +487,Dex/Components/CexInfoModal.qml,,488,Market Data,489,Marktdaten,Data de Mercado,, +492,Dex/Components/CexInfoModal.qml,,493,"Market data (prices, charts, etc.) marked with the ⓘ icon originates from third-party sources.<br><br>Data is sourced via <a href="https://bandprotocol.com/">Band Decentralized Oracle</a> and <a href="https://coingecko.com">CoinGecko</a>.<br><br><b>Oracle Supported Pairs:</b><br>%1<br><br><b>Last reference (Band Oracle):</b><br><a href="%2">%2</a>",494,"Mit dem Symbol ⓘ gekennzeichnete Marktdaten (Kurse, Charts etc.) stammen aus Drittquellen.<br><br>Die Daten stammen von <a href="https://bandprotocol.com/">Band Decentralized Oracle</a> und <a href="https://coingecko.com">CoinGecko</a>.<br><br><b>Oracle unterstützte Paare:</b><br>%1<br><br><b>Letzte Referenz (Band Oracle):</b><br><a href="%2">%2</a>","Datos de mercado (precios, estadisticas, etc.) marcados con ⓘ se obtienen a través de fuentes terceras.<br><br>Data is sourced via <a href="https://bandprotocol.com/">Band Decentralized Oracle</a> and <a href="https://coingecko.com">CoinGecko</a>.<br><br><b>Oracle Supported Pairs:</b><br>%1<br><br><b>Last reference (Band Oracle):</b><br><a href="%2">%2</a>",, +500,Dex/Exchange/ProView/Chart.qml,,501,Loading market data,502,Laden von Marktdaten,Cargando datos de mercado,, +505,Dex/Exchange/ProView/Chart.qml,,506,There is no chart data for this pair yet,507,Für dieses Paar liegen noch keine Chartdaten vor,Todavía no hay datos de gráficos para este par,, +513,Dex/Wallet/ClaimRewardsModal.qml,,514,Failed to prepare to claim rewards,515,Vorbereitung zum Einfordern von Belohnungen fehlgeschlagen,No se pudo preparar para reclamar recompensas,, +518,Dex/Wallet/ClaimRewardsModal.qml,TICKER,519,Claim your %1 reward?,521,%1 Belohnung beantragen?,¿Reclamar su %1 de recompensa?,, +524,Dex/Wallet/ClaimRewardsModal.qml,,525,No UTXOs eligible for claiming,526,Keine beanspruchungsberechtigten UTXOs vorhanden,Ningún UTXO elegible para reclamar,, +529,Dex/Wallet/ClaimRewardsModal.qml,,530,Transaction fee is higher than the reward!,531,Die Transaktionsgebühr ist höher als die Belohnung!,¡La tarifa de transacción es más alta que la recompensa!,, +534,Dex/Wallet/ClaimRewardsModal.qml,,535,You will receive ,536,Sie erhalten,Recibirá,, +539,Dex/Wallet/ClaimRewardsModal.qml,,540,Refresh,541,Aktualisieren,Actualizar,, +544,Dex/Wallet/ClaimRewardsModal.qml,,545,Read more about KMD active users rewards,546,Lesen Sie mehr über die Belohnungen für aktive KMD-Benutzer,Lea más sobre las recompensas de los usuarios activos de KMD,, +549,Dex/Wallet/ClaimRewardsModal.qml,,550,UTXO,551,UTXO,UTXO,, +554,Dex/Wallet/ClaimRewardsModal.qml,,555,Amount,556,Menge,Monto,, +559,Dex/Wallet/ClaimRewardsModal.qml,,560,Reward,561,Belohnung,Recompensa,, +564,Dex/Wallet/ClaimRewardsModal.qml,,565,Accruing Start,566,Anfallender Start,Inicio de Acumulación,, +569,Dex/Wallet/ClaimRewardsModal.qml,,570,Accruing Stop,571,Anfallender Stopp,Detener Acumulación,, +574,Dex/Wallet/ClaimRewardsModal.qml,,575,Time Left,576,Verbleibende Zeit,Tiempo Restante,, +579,Dex/Wallet/ClaimRewardsModal.qml,,580,Error,581,Fehler,Error,, +584,Dex/Wallet/ClaimRewardsModal.qml,,585,Locktime is not set,586,Die Sperrzeit ist nicht eingestellt,Locktime no está configurado,, +589,Dex/Wallet/ClaimRewardsModal.qml,,590,Locktime is less than the threshold,591,Die Sperrzeit liegt unter dem Schwellenwert,Locktime es inferior al umbral,, +594,Dex/Wallet/ClaimRewardsModal.qml,,595,UTXO height is greater than end of the era,596,UTXO-Höhe ist größer als Ende der Ära,La altura de UTXO es mayor que el final de la era,, +599,Dex/Wallet/ClaimRewardsModal.qml,,600,UTXO amount is less than 10,601,UTXO-Menge ist kleiner als 10,La cantidad de UTXO es inferior a 10,, +604,Dex/Wallet/ClaimRewardsModal.qml,,605,One hour did not pass yet,606,Eine Stunde ist noch nicht vergangen,Una hora no pasa aún,, +609,Dex/Wallet/ClaimRewardsModal.qml,,610,Transaction is in mempool,611,Die Transaktion befindet sich in Mempool,La transacción está en el mempool,, +614,Dex/Wallet/ClaimRewardsModal.qml,,615,Unknown problem,616,Unbekanntes Problem,Problema desconocido,, +619,Dex/Wallet/ClaimRewardsModal.qml,,620,Cancel,621,Abbrechen,Cancelar,, +624,Dex/Wallet/ClaimRewardsModal.qml,,625,Confirm,626,Bestätigen,Confirmar,, +632,Dex/Components/CoinMenu.qml,TICKER,633,Disable %1,635,%1 deaktivieren,Deshabilitar %1,, +638,Dex/Components/CoinMenu.qml,TICKER,639,Disable and Delete %1,641,%1 deaktivieren und löschen,Deshabilitar y eliminar %1,, +644,Dex/Components/CoinMenu.qml,,645,Disable all %1 assets,646,Alle %1 Assets deaktivieren,Deshabilitar todos los activos de %1,, +649,Dex/Components/CoinMenu.qml,,650,Disable all assets,651,Alle Assets deaktivieren,Deshabilitar todos los activos,, +654,Dex/Components/CoinMenu.qml,,655,Disable 0 balance assets,656,Alle Assets mit der Balance 0 deaktivieren,Deshabilitar 0 balancear activos,, +662,Dex/Components/ComboBoxWithSearchBar.qml,,663,Search,664,Suchen,Búsqueda,, +670,Dex/Settings/Combo_fiat.qml,,671,Language,672,Sprache,Idioma,, +675,Dex/Settings/Combo_fiat.qml,,676,Fiat,677,Fiat,Fiat,, +680,Dex/Settings/Combo_fiat.qml,,681,Recommended: ,682,Empfohlen:,Recomendado:,, +688,Dex/Exchange/Trade/ConfirmMultiOrderTradeModal.qml,,689,Confirm Multi Order Details,690,Bestätigen Sie die Details des Mehrfachauftrags,Confirmar detalles de Multi Order,, +693,Dex/Exchange/Trade/ConfirmMultiOrderTradeModal.qml,,694,These swaps requests can not be undone and this is the final event!,695,Diese Tauschanfragen können nicht rückgängig gemacht werden und dies ist das endgültige Ereignis!,Estas solicitudes de intercambio no se pueden deshacer y este es el evento final!,, +698,Dex/Exchange/Trade/ConfirmMultiOrderTradeModal.qml,,699,These transactions can take up to 60 mins - DO NOT close this application!,700,Diese Transaktionen können bis zu 60 Minuten dauern - schließen Sie diese Anwendung NICHT!,Estas transacciones pueden demorar hasta 60 minutos. ¡NO cierre esta aplicación!,, +703,Dex/Exchange/Trade/ConfirmMultiOrderTradeModal.qml,,704,Same funds will be used until an order matches.,705,"Die gleichen Geldmittel werden verwendet, bis eine Bestellung übereinstimmt.",Se utilizarán los mismos fondos hasta que coincida un pedido.,, +708,Dex/Exchange/Trade/ConfirmMultiOrderTradeModal.qml,,709,Note that if one order is filled other will not be cancelled.,710,"Beachten Sie, dass, wenn eine Bestellung ausgeführt wird, andere nicht storniert werden.","Tenga en cuenta que si se completa un pedido, el otro no se cancelará.",, +713,Dex/Exchange/Trade/ConfirmMultiOrderTradeModal.qml,,714,Cancel,715,Abbrechen,Cancelar,, +718,Dex/Exchange/Trade/ConfirmMultiOrderTradeModal.qml,,719,Confirm,720,Bestätigen,Confirmar,, +723,Dex/Exchange/Trade/ConfirmMultiOrderTradeModal.qml,,724,Placed multiple orders,725,Mehrere Aufrtäge aufgegeben,Pedidos múltiples realizados,, +731,Dex/Exchange/Trade/ConfirmTradeModal.qml,,732,Confirm Exchange Details,733,Bestätigen Sie die Austausch-Details,Confirmar Detalles de Intercambio,, +736,Dex/Exchange/Trade/ConfirmTradeModal.qml,,737,Trade price is more than 50% different to CEX! Confirm?,738,Der Handelspreis unterscheidet sich um mehr als 50 % vom CEX-Preis! Bestätigen?,¡El precio comercial es más del 50% diferente al de CEX! ¿Confirmar?,, +741,Dex/Exchange/Trade/ConfirmTradeModal.qml,,742,This swap request can not be undone and is a final event!,743,Diese Tauschanfrage kann nicht rückgängig gemacht werden und ist ein endgültiges Ereignis!,¡Esta solicitud de intercambio no se puede deshacer y es un evento final!,, +746,Dex/Exchange/Trade/ConfirmTradeModal.qml,,747,This transaction can take up to 60 mins - DO NOT close this application!,748,Diese Transaktion kann bis zu 60 Minuten dauern - schließen Sie diese Anwendung NICHT!,Esta transacción puede demorar hasta 60 minutos. ¡NO cierre esta aplicación!,, +751,Dex/Exchange/Trade/ConfirmTradeModal.qml,,752,Loading fees...,753,Lade Gebühren...,Cargando tarifas...,, +756,Dex/Exchange/Trade/ConfirmTradeModal.qml,,757,<b>Total %1 fees:</b>,758,<b>Gesamt %1 Gebühren:</b>,<b>Total de %1 fees:</b>,, +761,Dex/Exchange/Trade/ConfirmTradeModal.qml,,762,Security configuration,763,Sicherheitskonfiguration,Configuración de seguridad,, +766,Dex/Exchange/Trade/ConfirmTradeModal.qml,,767,dPoW protected,768,dPoW-geschützt,Protegido por dPoW,, +771,Dex/Exchange/Trade/ConfirmTradeModal.qml,,772,%1 confirmations for incoming %2 transactions,773,%1 Bestätigungen für eingehende %2 Transaktionen,%1 confirmaciones para %2 transacciones entrantes,, +776,Dex/Exchange/Trade/ConfirmTradeModal.qml,,777,Read more about dPoW,778,Lesen Sie mehr über dPoW,Obtenga más información sobre dPoW,, +781,Dex/Exchange/Trade/ConfirmTradeModal.qml,TICKER,782,Use custom protection settings for incoming %1 transactions,784,Benutzerdefinierte Schutzeinstellungen für eingehende %1 Transaktionen verwenden,Utilice configuraciones de protección personalizadas para %1 transacciones entrantes,, +787,Dex/Exchange/Trade/ConfirmTradeModal.qml,,788,Enable Komodo dPoW security,789,Komodo dPoW-Sicherheit aktivieren,Habilite la seguridad dPoW de Komodo,, +792,Dex/Exchange/Trade/ConfirmTradeModal.qml,,793,Required Confirmations,794,Erforderliche Bestätigungen,Confirmaciones Requeridas,, +797,Dex/Exchange/Trade/ConfirmTradeModal.qml,,798,"Warning, this atomic swap is not dPoW protected!",799,"Achtung, dieser Atomic Swap ist nicht dPoW-geschützt!","Advertencia, este intercambio atómico no está protegido por dPoW!",, +802,Dex/Exchange/Trade/ConfirmTradeModal.qml,,803,Cancel,804,Abbrechen,Cancelar,, +807,Dex/Exchange/Trade/ConfirmTradeModal.qml,,808,Confirm,809,Bestätigen,Confirmar,, +815,Dex/Components/CopyFieldButton.qml,,816,Copied to Clipboard,817,In die Zwischenablage kopiert,Copiado al Portapapeles,, +823,Dex/Screens/Dashboard.qml,,824,The current number of enabled coins does not match your configuration specification. Your assets configuration will be reset.,825,Die aktuelle Anzahl aktivierter Coins stimmt nicht mit Ihrer Konfigurationsvorgabe überein. Die Konfiguration der Assets wird zurückgesetzt.,El número actual de monedas habilitadas no coincide con su especificación de configuración. Se restablecerá la configuración de sus activos.,, +828,Dex/Screens/Dashboard.qml,,829,Matching,830,"Zusammenführung",Emparejamiento,, +833,Dex/Screens/Dashboard.qml,,834,Order Matching,835,"Auftrag wird zusammengeführt",Emparejamiento de Ordenes,, +838,Dex/Screens/Dashboard.qml,,839,Matched,840,"Zusammengeführt",Emparejamiento Completo,, +843,Dex/Screens/Dashboard.qml,,844,Order Matched,845,"Auftrag wurde zusammengeführt",Orden Emparejada,, +848,Dex/Screens/Dashboard.qml,,849,Ongoing,850,"Laufend",En curso,, +853,Dex/Screens/Dashboard.qml,,854,Swap Ongoing,855,Austausch läuft,Intercambio en Curso,, +858,Dex/Screens/Dashboard.qml,,859,Successful,860,Erfolgreich,Exitoso,, +863,Dex/Screens/Dashboard.qml,,864,Swap Successful,865,Tausch erfolgreich,Intercambio Exitoso,, +868,Dex/Screens/Dashboard.qml,,869,Refunding,870,Rückzahlung,Reembolso,, +873,Dex/Screens/Dashboard.qml,,874,Failed,875,Fehlgeschlagen,Fallido,, +878,Dex/Screens/Dashboard.qml,,879,Swap Failed,880,Tausch fehlgeschlagen,Intercambio Fallido,, +883,Dex/Screens/Dashboard.qml,,884,Unknown,885,Unbekannt,Desconocido,, +888,Dex/Screens/Dashboard.qml,,889,Unknown State,890,Unbekannter Status,Estado Desconocido,, +893,Dex/Screens/Dashboard.qml,,894,Started,895,Gestartet,Iniciado,, +898,Dex/Screens/Dashboard.qml,,899,Negotiated,900,"Ausgehandelt",Negociado,, +903,Dex/Screens/Dashboard.qml,,904,Taker fee sent,905,Taker-Gebühr gesendet,Tarifa taker enviada,, +908,Dex/Screens/Dashboard.qml,,909,Maker payment received,910,Maker-Zahlung erhalten,Pago de maker recibido,, +913,Dex/Screens/Dashboard.qml,,914,Maker payment wait confirm started,915,Warten auf die Zahlungsbestätigung des Makers gestartet,Inicio de espera de confirmacion de pago de maker,, +918,Dex/Screens/Dashboard.qml,,919,Maker payment validated and confirmed,920,Maker-Zahlung validiert und bestätigt,Validacion y confirmacion de pago de maker,, +923,Dex/Screens/Dashboard.qml,,924,Taker payment sent,925,Taker-Zahlung gesendet,Pago de taker enviado,, +928,Dex/Screens/Dashboard.qml,,929,Taker payment spent,930,Taker-Zahlung ausgegeben,Pago del taker gastado,, +933,Dex/Screens/Dashboard.qml,,934,Maker payment spent,935,Maker-Zahlung ausgegeben,Pago del maker gastado,, +938,Dex/Screens/Dashboard.qml,,939,Finished,940,Fertig,Terminado,, +943,Dex/Screens/Dashboard.qml,,944,Start failed,945,Start fehlgeschlagen,Inicio fallido,, +948,Dex/Screens/Dashboard.qml,,949,Negotiate failed,950,Verhandeln fehlgeschlagen,Negociacion fallida,, +953,Dex/Screens/Dashboard.qml,,954,Taker fee validate failed,955,Validierung der Abnehmergebühr fehlgeschlagen,Validación de tarifa del taker fallida,, +958,Dex/Screens/Dashboard.qml,,959,Maker payment transaction failed,960,Maker-Zahlungstransaktion fehlgeschlagen,Transacción de pago de maker fallo,, +963,Dex/Screens/Dashboard.qml,,964,Maker payment Data send failed,965,Fehler beim Senden der Maker-Zahlungsdaten,Envio de data de pago de maker fallo,, +968,Dex/Screens/Dashboard.qml,,969,Maker payment wait confirm failed,970,Warten auf die Zahlungsbestätigung des Makers fehlgeschlagen,Espera de confirmacion de pago de maker fallo,, +973,Dex/Screens/Dashboard.qml,,974,Taker payment validate failed,975,Validierung der Taker-Zahlung fehlgeschlagen,Validacion de pago de taker fallo,, +978,Dex/Screens/Dashboard.qml,,979,Taker payment wait confirm failed,980,Warten auf die Zahlungsbestätigung des Takers fehlgeschlagen,Espera de confirmacion de pago de taker fallo,, +983,Dex/Screens/Dashboard.qml,,984,Taker payment spend failed,985,Zahlungsausgabe des Takers fehlgeschlagen,Gasto de pago de taker fallo,, +988,Dex/Screens/Dashboard.qml,,989,Maker payment wait refund started,990,Countdown für die Rückerstattung der Maker-Zahlung hat begonnen,Reembolso de espera de pago de maker iniciado,, +993,Dex/Screens/Dashboard.qml,,994,Maker payment refunded,995,Maker-Zahlung zurückerstattet,Pago de maker reembolsado,, +998,Dex/Screens/Dashboard.qml,,999,Maker payment refund failed,1000,Rückerstattung der Maker-Zahlung fehlgeschlagen,Reembolso del pago de maker fallo,, +1006,Dex/Components/DatePicker.qml,,1007,Date,1008,Datum,Fecha,, +1014,Dex/Components/DefaultCopyIcon.qml,,1015,copied to clipboard,1016,In die Zwischenablage kopiert,copiada al portapapeles,, +1022,Dex/Components/DefaultRangeSlider.qml,,1023,Min,1024,Min,Min,, +1027,Dex/Components/DefaultRangeSlider.qml,,1028,Max,1029,Max,Max,, +1035,Dex/Components/DefaultTextEdit.qml,,1036,copied to clipboard,1037,In die Zwischenablage kopiert,copiado al portapapeles,, +1043,Dex/Settings/DeleteWalletModal.qml,,1044,Delete Wallet,1045,Brieftasche löschen,Eliminar billetera,, +1048,Dex/Settings/DeleteWalletModal.qml,WALLET_NAME,1049,Are you sure you want to delete %1 wallet?,1051,"Sind Sie sicher, dass Sie die %1 Brieftasche löschen möchten?",¿Está seguro de que desea eliminar %1 billetera?,, +1054,Dex/Settings/DeleteWalletModal.qml,,1055,"If so, make sure you record your seed phrase in order to restore your wallet in the future.",1056,"Wenn ja, stellen Sie sicher, dass Sie Ihre Seed-Phrase notieren, um Ihre Brieftasche in Zukunft wiederherzustellen.","Si es así, asegúrese de registrar su frase inicial para restaurar su billetera en el futuro.",, +1059,Dex/Settings/DeleteWalletModal.qml,,1060,Enter your wallet password,1061,Geben Sie das Kennwort für ihre Brieftasche ein,Ingrese la contraseña de su billetera,, +1064,Dex/Settings/DeleteWalletModal.qml,,1065,Wrong Password,1066,Falsches Kennwort,Contraseña incorrecta,, +1069,Dex/Settings/DeleteWalletModal.qml,,1070,Cancel,1071,Abbrechen,Cancelar,, +1074,Dex/Settings/DeleteWalletModal.qml,,1075,Delete,1076,Löschen,Eliminar,, +1082,Dex/Components/DexAppPasswordField.qml,,1083,Type password,1084,Kennwort eingeben,Escriba la contraseña,, +1090,Dex/Components/DexKeyChecker.qml,,1091,At least 1 lowercase alphabetical character,1092,Mindestens 1 Kleinbuchstabe,Al menos 1 carácter alfabético en minúscula,, +1095,Dex/Components/DexKeyChecker.qml,,1096,At least 1 uppercase alphabetical character,1097,Mindestens 1 Großbuchstabe,Al menos 1 carácter alfabético en mayúscula,, +1100,Dex/Components/DexKeyChecker.qml,,1101,At least 1 numeric character,1102,Mindestens 1 Ziffer,Al menos 1 carácter numérico,, +1105,Dex/Components/DexKeyChecker.qml,,1106,At least 1 special character (eg. !@#$%),1107,Mindestens 1 Sonderzeichen (z. B. ! @ # $ %),"Al menos 1 carácter especial (p. ej., !@#$%)",, +1110,Dex/Components/DexKeyChecker.qml,,1111,At least %n character(s),1112,,Al menos %n carácter(es),, +1118,Dex/Components/DexKeyChecker.qml,,1119,Password and Confirm Password have to be same,1120,Kennwort und Kennwortbestätigung müssen identisch sein,Contraseña y Confirmar Contraseña tienen que ser los mismos,, +1126,Dex/Components/DexPaginator.qml,,1127,items per page,1128,Elemente pro Seite,elementos por página,, +1134,Dex/Components/DexRangeSlider.qml,,1135,Min,1136,Min,Min,, +1139,Dex/Components/DexRangeSlider.qml,,1140,Half,1141,Halb,Mitad,, +1144,Dex/Components/DexRangeSlider.qml,,1145,Max,1146,Max,Max,, +1152,Dex/Components/DexSweetComboBox.qml,,1153,Search,1154,Suchen,Buscar,, +1160,Dex/Addressbook/EditContactModal.qml,,1161,Edit contact,1162,Kontakt bearbeiten,Editar contacto,, +1165,Dex/Addressbook/EditContactModal.qml,,1166,Contact name,1167,Kontaktname,Nombre,, +1170,Dex/Addressbook/EditContactModal.qml,,1171,Enter a contact name,1172,Geben Sie einen Kontaktnamen ein,Ingresar un nombre de contacto,, +1175,Dex/Addressbook/EditContactModal.qml,,1176,Address list,1177,Adressliste,Lista de direcciónes,, +1180,Dex/Addressbook/EditContactModal.qml,,1181,Address Book,1182,Adressbuch,Libreta de direcciónes,, +1185,Dex/Addressbook/EditContactModal.qml,,1186,address copied to clipboard,1187,Adresse in die Zwischenablage kopiert,direccion copiada al portapapeles,, +1190,Dex/Addressbook/EditContactModal.qml,,1191,Edit,1192,Bearbeiten,Editar,, +1195,Dex/Addressbook/EditContactModal.qml,,1196,+ Add,1197,+ Hinzufügen,#NAME?,, +1200,Dex/Addressbook/EditContactModal.qml,,1201,Tags,1202,Schlagworte,Etiquetas,, +1205,Dex/Addressbook/EditContactModal.qml,,1206,Add tag,1207,Schlagwort hinzufügen,Agregar etiqueta,, +1210,Dex/Addressbook/EditContactModal.qml,,1211,Close,1212,Schließen,Cerrar,, +1215,Dex/Addressbook/EditContactModal.qml,,1216,Confirm,1217,Bestätigen,Confirmar,, +1223,Dex/Addressbook/EnableAssetModal.qml,,1224,"The selected address belongs to a disabled asset, you need to enabled it before sending.",1225,"Die ausgewählte Adresse gehört zu einem deaktivierten Asset, Sie müssen es vor dem Senden aktivieren.","La dirección seleccionada pertenece a un activo deshabilitado, debe habilitó antes de enviar.",, +1228,Dex/Addressbook/EnableAssetModal.qml,,1229,Enable,1230,Aktivieren,Habilitar,, +1233,Dex/Addressbook/EnableAssetModal.qml,,1234,Cancel,1235,Abbrechen,Cancelar,, +1241,Dex/Wallet/EnableCoinModal.qml,,1242,Enable assets,1243,Assets aktivieren,Habilitar activos,, +1246,Dex/Wallet/EnableCoinModal.qml,,1247,Select all assets,1248,Alle Assets auswählen,Seleccionar todos los activos,, +1251,Dex/Wallet/EnableCoinModal.qml,,1252,All assets are already enabled!,1253,Alle Assets sind bereits aktiviert!,¡Todos los activos ya están habilitados!,, +1256,Dex/Wallet/EnableCoinModal.qml,,1257,You can still enable %1 assets. Selected: %2.,1258,Sie können weiterhin %1 Assets aktivieren. Ausgewählt: %2.,Todavía puede habilitar activos %1. Seleccionado: %2.,, +1261,Dex/Wallet/EnableCoinModal.qml,,1262,Search asset,1263,Asset suchen,Buscar activo,, +1266,Dex/Wallet/EnableCoinModal.qml,,1267,Change assets limit,1268,Asset-Limit ändern,Cambiar el límite de activos,, +1271,Dex/Wallet/EnableCoinModal.qml,,1272,Add a custom asset,1273,Benutzerdefiniertes Asset hinzufügen,Agregar un activo personalizado,, +1276,Dex/Wallet/EnableCoinModal.qml,,1277,Close,1278,Schließen,Cerrar,, +1281,Dex/Wallet/EnableCoinModal.qml,,1282,Enable,1283,Aktivieren,Habilitar,, +1289,Dex/Components/EulaModal.qml,,1290,Disclaimer & Terms of Service,1291,Haftungsausschluss & Nutzungsbedingungen,Descargo de Responsabilidad & Términos de servicio,, +1294,Dex/Components/EulaModal.qml,,1295,Accept EULA,1296,EULA akzeptieren,Aceptar EULA,, +1299,Dex/Components/EulaModal.qml,,1300,Accept Terms and Conditions,1301,Allgemeine Geschäftsbedingungen akzeptieren,Aceptar términos y condiciones,, +1304,Dex/Components/EulaModal.qml,,1305,Close,1306,Schließen,Cerrar,, +1309,Dex/Components/EulaModal.qml,,1310,Cancel,1311,Abbrechen,Cancelar,, +1314,Dex/Components/EulaModal.qml,,1315,Confirm,1316,Bestätigen,Confirmar,, +1322,Dex/Dashboard/FatalErrorModal.qml,,1323,Fatal Error,1324,Schwerwiegender Fehler,Error Fatal,, +1327,Dex/Dashboard/FatalErrorModal.qml,,1328,Connection has been lost. You have been disconnected.,1329,Die Verbindung wurde unterbrochen. Ihre Verbindung wurde getrennt.,Ha perdido la conexión. Has sido desconectado.,, +1332,Dex/Dashboard/FatalErrorModal.qml,,1333,Close,1334,Schließen,Cerrar,, +1340,Dex/Exchange/Trade/Trading/Items/FeeInfo.qml,,1341,Minimum fee,1342,Mindestgebühr,Tarifa mínima,, +1345,Dex/Exchange/Trade/Trading/Items/FeeInfo.qml,,1346,Fees will be calculated,1347,Gebühren werden berechnet,Las tarifas se calcularán,, +1353,Dex/Constants/General.qml,,1354,%n day(s),1355,,%n día(s),, +1361,Dex/Constants/General.qml,day,1362,%nd,1364,,%nd,, +1370,Dex/Constants/General.qml,hours,1371,%nh,1373,,%nh,, +1379,Dex/Constants/General.qml,minutes,1380,%nm,1382,,%nm,, +1388,Dex/Constants/General.qml,seconds,1389,%ns,1391,,%ns,, +1397,Dex/Constants/General.qml,milliseconds,1398,%nms,1400,,%nms,, +1406,Dex/Constants/General.qml,,1407,-,1408,-,-,, +1411,Dex/Constants/General.qml,,1412,<b>Taker tx fee:</b> ,1413,<b>Taker tx Gebühren:</b> ,<b>Taker tx fee:</b>,, +1416,Dex/Constants/General.qml,,1417,<b>Dex tx fee:</b> ,1418,<b>Dex tx Gebühren:</b> ,<b>Dex tx fee:</b>,, +1421,Dex/Constants/General.qml,,1422,<b>Dex fee:</b> ,1423,<b>Dex Gebühren:</b> ,<b>Dex fee:</b>,, +1426,Dex/Constants/General.qml,,1427,<b>Maker tx fee:</b> ,1428,<b>Maker tx Gebühren:</b> ,<b>Maker tx fee:</b>,, +1431,Dex/Constants/General.qml,,1432,%1 %2 %3 (%4),1433,%1 %2 %3 (%4),%1 %2 %3 (%4),, +1436,Dex/Constants/General.qml,,1437,Trading Fee,1438,Handelsgebühr,Tarifa de Intercambio,, +1441,Dex/Constants/General.qml,,1442,Minimum Trading Amount,1443,Mindesthandelsbetrag,Minimo Monto de Intercambio,, +1446,Dex/Constants/General.qml,WALLETNAME,1447,Wallet %1 already exists,1449,Brieftasche %1 existiert bereits,Monedero %1 ya existe,, +1452,Dex/Constants/General.qml,,1453,%1 balance is lower than the fees amount: %2 %3,1454,Das %1 Guthaben ist niedriger als der Gebührenbetrag: %2 %3,El saldo de %1 es inferior al monto de las tarifas: %2 %3,, +1457,Dex/Constants/General.qml,,1458,Tradable (after fees) %1 balance is lower than minimum trade amount,1459,Handelbares %1 Guthaben (nach Gebühren) ist niedriger als der Mindesthandelsbetrag,El saldo de %1 (después de las tarifas) es inferior al monto mínimo de intercambio,, +1462,Dex/Constants/General.qml,,1463,Please fill the price field,1464,Bitte füllen Sie das Preisfeld aus,Por favor complete el campo de precio,, +1467,Dex/Constants/General.qml,,1468,Please fill the volume field,1469,Bitte füllen Sie das Volumenfeld aus,Complete el campo de volumen,, +1473,Dex/Constants/General.qml,,1474,%1 volume is lower than minimum trade amount,1475,%1 Volumen ist niedriger als der minimale Handelsbetrag,El volumen de %1 es inferior al monto mínimo de intercambio,, +1479,Dex/Constants/General.qml,,1480,%1 needs to be enabled in order to use %2,1481,"%1 muss aktiviert werden, um %2 verwenden zu können",%1 debe habilitarse para usar %2,, +1485,Dex/Constants/General.qml,,1486,"%1 balance needs to be funded, a non-zero balance is required to pay the gas of %2 transactions",1487,"Das %1 Guthaben muss finanziert werden, ein Guthaben größer Null ist erforderlich, um das Benzin von %2 Transaktionen zu bezahlen","el saldo de %1 esta en cero, se requiere un saldo minimo para pagar el gas de transacciones de % 2",, +1490,Dex/Constants/General.qml,,1491,Unknown Error,1492,Unbekannter Fehler,Error Desconocido,, +1498,Dex/Exchange/Trade/BestOrder/Header.qml,,1499,You get,1500,Du erhältst,Obtienes,, +1503,Dex/Exchange/Trade/BestOrder/Header.qml,,1504,You send,1505,Sie senden,Envía,, +1508,Dex/Exchange/Trade/BestOrder/Header.qml,,1509,Fiat Price,1510,Fiat Preis,Precio Fiat,, +1513,Dex/Exchange/Trade/BestOrder/Header.qml,,1514,CEX rate,1515,CEX-Kurs,Tasa CEX,, +1518,Dex/Exchange/Trade/OrderBook/Header.qml,,1519,Price,1520,Preis,Precio,, +1523,Dex/Exchange/Trade/OrderBook/Header.qml,,1524,Quantity,1525,Menge,Cantidad,, +1528,Dex/Exchange/Trade/OrderBook/Header.qml,,1529,Total,1530,Gesamt,Total,, +1536,Dex/Screens/Startup/ImportWallet.qml,,1537,Failed to Import the wallet,1538,Fehler beim Importieren der Brieftasche,No se pudo importar la billetera,, +1541,Dex/Screens/Startup/ImportWallet.qml,,1542,Import wallet - Setup,1543,Brieftasche importieren - Einrichtung,Importar billetera - Configurar,, +1546,Dex/Screens/Startup/ImportWallet.qml,,1547,Import wallet - Choose password,1548,Brieftasche importieren - Kennwort wählen,Importar billetera - Elegir contraseña,, +1551,Dex/Screens/Startup/ImportWallet.qml,,1552,Wallet Name,1553,Name der Brieftasche,Nombre de billetera,, +1556,Dex/Screens/Startup/ImportWallet.qml,,1557,Enter seed,1558,Geben Sie den Seed ein,Ingresar semilla,, +1561,Dex/Screens/Startup/ImportWallet.qml,,1562,Your seed is not BIP39 compliant. Try again or select 'Allow custom seed' to continue.,1564,Ihr Seed ist nicht BIP39-konform. Versuchen Sie es erneut oder wählen Sie "benutzerdefinierten Seed erlauben" um fortzufahren,Su semilla no es compatible con BIP39. Vuelva a intentarlo o seleccione 'Permitir semilla personalizada' continuar.,, +1568,Dex/Screens/Startup/ImportWallet.qml,,1569,i understand,1570,Ich verstehe,entiendo,, +1573,Dex/Screens/Startup/ImportWallet.qml,,1574,Ok,1575,Ok,Ok,, +1578,Dex/Screens/Startup/ImportWallet.qml,,1579,Allow custom seed,1580,Benutzerdefinierten Seed zulassen,Permitir semilla personalizada,, +1583,Dex/Screens/Startup/ImportWallet.qml,,1584,<strong>Allow custom seed</strong>,1585,<strong>Benutzerdefinierten Seed zulassen</strong>,<strong>Permitir semilla personalizada</strong>,, +1588,Dex/Screens/Startup/ImportWallet.qml,,1589,"Custom seed phrases might be less secure and easier to crack than a generated BIP39 compliant seed phrase or private key (WIF).<br><br>To confirm you understand the risk and know what you are doing, type <strong>'I understand'</strong> in the box below.",1590,"Benutzerdefinierte Seed-Phrasen sind möglicherweise weniger sicher und leichter zu knacken als eine generierte BIP39-konforme Seed-Phrase oder ein privater Schlüssel (WIF).<br><br>Um zu bestätigen, dass Sie das Risiko verstehen und wissen, was Sie tun, geben Sie <strong>'Ich verstehe'</strong> im Kasten unten.","Las frases semilla personalizadas pueden ser menos seguras y más fáciles de descifrar que una frase semilla o clave privada (WIF) compatible con BIP39.<br><br>Para confirmar que comprende el riesgo y sabe lo que está haciendo, escriba <strong> 'Entiendo'</strong> en el cuadro de abajo.",, +1593,Dex/Screens/Startup/ImportWallet.qml,,1594,I understand,1595,Ich verstehe,Entiendo,, +1598,Dex/Screens/Startup/ImportWallet.qml,,1599,Next,1600,Weiter,Siguiente,, +1603,Dex/Screens/Startup/ImportWallet.qml,,1604,Enter the same password to confirm,1605,Geben Sie zur Bestätigung dasselbe Kennwort ein,Ingrese la misma contraseña para confirmar,, +1608,Dex/Screens/Startup/ImportWallet.qml,,1609,Continue,1610,Fortsetzen,Continuar,, +1616,Dex/Components/LinksRow.qml,,1617,Join our Discord server,1618,Tritt unserem Discord-Server bei,Únase a nuestro servidor de Discord,, +1621,Dex/Components/LinksRow.qml,,1622,Follow us on Twitter,1623,Folge uns auf Twitter,Síganos en Twitter,, +1626,Dex/Components/LinksRow.qml,,1627,Go to Support Guides,1628,Zu den Support-Leitfäden,Ir a Guías de soporte,, +1634,Dex/Exchange/Trade/SimpleView/List.qml,,1635,Funds are recoverable,1636,Geldmittel sind erstattungsfähig,Los fondos son recuperables,, +1639,Dex/Exchange/Trade/BestOrder/List.qml,,1640,Best Orders,1641,Die günstigsten Aufträge,Mejores Ordenes,, +1647,Dex/Exchange/Trade/BestOrder/ListDelegate.qml,,1648,%1 is not enabled - Do you want to enable it to be able to select %2 best orders ?<br><a href='#'>Yes</a> - <a href='#no'>No</a>,1649,"%1 ist nicht aktiviert - Möchten Sie es aktivieren, um die günstigsten Aufträge von %2 auswählen zu können? <br><a href='#'>Ja</a> - <a href='#no'>Nein</a>",%1 no está habilitado. ¿Desea habilitarlo para poder seleccionar las mejores ordenes de %2 ?< br><a href='#'>Sí</a> - <a href='#no'>No</a>,, +1652,Dex/Exchange/Trade/OrderBook/ListDelegate.qml,,1653,This order requires a minimum amount of %1 %2 <br>You don't have enough funds.<br> %3,1654,Für diesen Auftrag ist ein Mindestbetrag von %1 %2 erforderlich. <br>Ihr Guthaben reicht nicht aus.<br> %3,Este pedido requiere una cantidad mínima de %1 %2 <br>No tiene fondos suficientes.<br> %3,, +1660,Dex/Components/LogModal.qml,,1661,Close,1662,Schließen,Cerrar,, +1668,Dex/Screens/Startup/Logging.qml,,1669,"Loading, please wait",1670,"Lädt, bitte warten","Cargando, por favor espere",, +1673,Dex/Screens/Startup/Logging.qml,,1674,Initializing MM2,1675,MM2 initialisieren,Inicializando MM2,, +1678,Dex/Screens/Startup/Logging.qml,,1679,Enabling assets,1680,Assets ermöglichen,Habilitando activos,, +1683,Dex/Screens/Startup/Logging.qml,,1684,Getting ready,1685,Fertig werden,Preparándose,, +1691,Dex/Screens/Startup/Login.qml,,1692,Incorrect Password,1693,Falsches Kennwort,Contraseña incorrecta,, +1696,Dex/Screens/Startup/Login.qml,,1697,Log In,1698,Anmelden,Iniciar sesión,, +1701,Dex/Screens/Startup/Login.qml,,1702,Cancel,1703,Abbrechen,Cancelar,, +1709,Dex/Wallet/Main.qml,,1710,Segwit,1711,Segwit,Segwit,, +1714,Dex/Wallet/Main.qml,,1715,Confirmation,1716,Bestätigung,Confirmación,, +1719,Dex/Wallet/Main.qml,,1720,Do you want to send your %1 funds to %2 wallet first?,1721,Möchten Sie Ihr %1-Guthaben zuerst an die %2-Brieftasche senden?,¿Desea enviar sus fondos de %1 a la billetera %2 primero?,, +1724,Dex/Wallet/Main.qml,,1725,Success,1726,Erfolg,Éxito,, +1729,Dex/Wallet/Main.qml,,1730,"Your transaction is send, may take some time to arrive",1731,"Ihre Transaktion wird gesendet, es kann einige Zeit dauern, bis sie ankommt","Su transacción se envió, puede demorar algún tiempo en llegar",, +1734,Dex/Wallet/Main.qml,,1735,Price,1736,Preis,Precio,, +1739,Dex/Wallet/Main.qml,,1740,Change 24hr,1741,24h Veränderung,Cambio,, +1744,Dex/Wallet/Main.qml,,1745,Porfolio,1746,Portfolio,Cartera,, +1749,Dex/Wallet/Main.qml,,1750,Contract Address,1751,Vertragsadresse,Dirección del Contrato,, +1754,Dex/Wallet/Main.qml,,1755,Send,1756,Senden,Enviar,, +1759,Dex/Wallet/Main.qml,,1760,Enable %1 ?,1761,%1 aktivieren?,¿Habilitar %1?,, +1764,Dex/Wallet/Main.qml,,1765,Yes,1766,Ja,Sí,, +1769,Dex/Wallet/Main.qml,,1770,No,1771,Nein,No,, +1774,Dex/Wallet/Main.qml,,1775,Receive,1776,Empfangen,Recibir,, +1779,Dex/Wallet/Main.qml,,1780,Swap,1781,Tausch,Swap,, +1784,Dex/Wallet/Main.qml,,1785,is wallet only,1786,nur Brieftasche (kein DEX möglich),es solo monedero,, +1789,Dex/Wallet/Main.qml,,1790,Rewards,1791,Belohnungen,Recompensas,, +1794,Dex/Wallet/Main.qml,,1795,Faucet,1796,Faucet,Grifo,, +1801,Dex/Wallet/Main.qml,,1802,Public Key,1803,Öffentlicher Schlüssel,Clave Pública,, +1806,Dex/Wallet/Main.qml,,1807,Copied to Clipboard,1808,In die Zwischenablage kopiert,Copiada en el Portapapeles,, +1811,Dex/Wallet/Main.qml,,1812,Loading market data,1813,Laden von Marktdaten,Cargando datos de mercado,, +1816,Dex/Wallet/Main.qml,,1817,There is no chart data for this ticker yet,1818,Für diesen Ticker liegen noch keine Chartdaten vor,Todavía no hay datos de gráfico para este ticker,, +1821,Dex/Wallet/Main.qml,,1822,Fetching transactions...,1823,Transaktionen werden abgerufen...,Obteniendo transacciones...,, +1826,Dex/Wallet/Main.qml,,1827,No transactions available,1828,Keine Transaktionen verfügbar,No hay transacciones disponibles,, +1831,Dex/Wallet/Main.qml,,1832,Click to view your address on %1 (%2) block explorer,1833,"Klicken Sie hier, um Ihre Adresse im %1 (%2) Block-Explorer anzuzeigen",Haga clic para ver su dirección en %1 (%2) explorador de bloques,, +1836,Dex/Exchange/Trade/SimpleView/Main.qml,,1837,Trade,1838,Handeln,Intercambio,, +1841,Dex/Exchange/ProView/TradingInfo/Main.qml,,1842,Trading Information,1843,Handelsinformationen,Informacion de Intercambio,, +1846,Dex/Exchange/ProView/TradingInfo/Main.qml,,1847,Chart,1848,Chart,Gráfico,, +1852,Dex/Exchange/Trade/SimpleView/Main.qml,,1853,Orders,1854,Aufträge,Ordenes,, +1858,Dex/Exchange/Trade/SimpleView/Main.qml,,1859,History,1860,Historie,Historial,, +1863,Dex/Exchange/ProView/PlaceOrderForm/Main.qml,,1864,Place Order,1865,Auftrag platzieren,Realizar pedido,, +1868,Dex/Exchange/ProView/PlaceOrderForm/Main.qml,,1869,Order Selected,1870,Auftrag ausgewählt,Pedido seleccionado,, +1873,Dex/Exchange/ProView/PlaceOrderForm/Main.qml,,1874,START SWAP,1875,TAUSCH STARTEN,INICIO INTERCAMBIAR,, +1879,Dex/Addressbook/Main.qml,,1880,Address Book,1881,Adressbuch,Libreta de direcciones,, +1884,Dex/Addressbook/Main.qml,,1885,Search contact,1886,Kontakt suchen,Buscar contacto,, +1889,Dex/Addressbook/Main.qml,,1890,+ NEW CONTACT,1891,+ Neuer Kontakt,Nuevo contacto,, +1894,Dex/Addressbook/Main.qml,,1895,Name,1896,Name,Nombre,, +1899,Dex/Addressbook/Main.qml,,1900,Tags,1901,Schlagwörter,Etiquetas,, +1904,Dex/Addressbook/Main.qml,,1905,Edit,1906,Bearbeiten,Editar,, +1909,Dex/Addressbook/Main.qml,,1910,Delete,1911,Löschen,Eliminar,, +1914,Dex/Addressbook/Main.qml,,1915,address copied to clipboard,1916,Adresse in die Zwischenablage kopiert,dirección copiada al portapapeles,, +1919,Dex/Addressbook/Main.qml,,1920,This contact does not have any registered address.,1921,Dieser Kontakt hat keine registrierte Adresse.,Este contacto no tiene ninguna dirección registrada.,, +1927,Dex/Exchange/ProView/PlaceOrderForm/MarketModeSelector.qml,TICKER,1928,Sell %1,1930,%1 Verkaufen,Vender %1,, +1933,Dex/Exchange/ProView/PlaceOrderForm/MarketModeSelector.qml,TICKER,1934,Buy %1,1936,%1 Kaufen,Comprar %1,, +1942,Dex/Components/MinTradeModal.qml,,1943,Minimum Trading Amount,1944,Mindesthandelsbetrag,Cantidad Mínima de Intercambio,, +1947,Dex/Components/MinTradeModal.qml,,1948,the minimum amount of %1 coin available for the order; the min_volume must be greater than or equal to %2; it must be also less or equal than volume param; default is %3,1949,"die Mindestmenge von %1 Coin, die für die Bestellung verfügbar ist; das min_volume muss größer oder gleich %2 sein; es muss auch kleiner oder gleich als volume param sein; Standard ist %3",la cantidad mínima de la moneda %1 disponible para la orden; el min_volume debe ser mayor o igual a %2; debe ser también menor o igual que volumen param; el valor predeterminado es %3,, +1955,Dex/Exchange/Trade/MultiOrder.qml,TICKER,1956,%1 price is zero!,1958,%1 Preis ist null!,el precio de %1 es cero!,, +1961,Dex/Exchange/Trade/MultiOrder.qml,TICKER,1962,%1 receive volume is lower than minimum trade amount,1964,%1 Empfangsvolumen ist niedriger als der Mindesthandelsbetrag,volumen de recepción de %1 es inferior al monto mínimo de transacción,, +1967,Dex/Exchange/Trade/MultiOrder.qml,,1968,Error:,1969,Fehler:,Error:,, +1972,Dex/Exchange/Trade/MultiOrder.qml,AMOUNT TICKER,1973,You'll receive %1,1975,Sie erhalten %1,Tu'll recibes %1,, +1978,Dex/Exchange/Trade/MultiOrder.qml,,1979,Price,1980,Preis,Precio,, +1986,Dex/Addressbook/NewContactPopup.qml,,1987,Contact name,1988,Kontaktname,Nombre,, +1991,Dex/Addressbook/NewContactPopup.qml,,1992,This contact name already exists.,1993,Dieser Kontaktname existiert bereits.,Este nombre de contacto ya existe.,, +1996,Dex/Addressbook/NewContactPopup.qml,,1997,+ ADD,1998,+ HINZUFÜGEN,#NAME?,, +2006,Dex/NewUpdateModal.qml,,2007,Searching new updates,2008,Suche nach neuen Updates,Buscando nuevas actualizaciones,, +2011,Dex/NewUpdateModal.qml,,2012,Fetching...,2013,Abrufen…,Buscando...,, +2019,Dex/NewUpdateModal.qml,,2020,Close,2021,Schließen,Cerrar,, +2024,Dex/NewUpdateModal.qml,,2025,Could not check new updates for the following reason: %1,2027,Neue Updates konnten aus folgendem Grund nicht überprüft werden: %1,No se pudieron comprobar nuevas actualizaciones por el siguiente motivo: %1,, +2030,Dex/NewUpdateModal.qml,,2031,New version found,2032,Neue Version gefunden,Nueva versión encontrada,, +2035,Dex/NewUpdateModal.qml,,2036,Mandatory version found,2037,Zwingend notwendige Version gefunden,Versión obligatoria encontrada,, +2040,Dex/NewUpdateModal.qml,,2041,%1 %2 is available !,2042,%1 %2 ist verfügbar !,%1 ¡%2 está disponible!,, +2045,Dex/NewUpdateModal.qml,,2046,This update is mandatory to continue using the application,2047,"Dieses Update ist zwingend erforderlich, um die Anwendung weiterhin verwenden zu können",Esta actualización es obligatoria para seguir usando la aplicación,, +2050,Dex/NewUpdateModal.qml,,2051,Close Dex,2052,Dex schließen,Cerrar Dex,, +2055,Dex/NewUpdateModal.qml,,2056,Your application is updated.,2057,Ihre Anwendung ist auf dem neuesten Stand.,Tu aplicación está actualizada.,, +2060,Dex/NewUpdateModal.qml,,2061,Download,2062,Herunterladen,Descargar,, +2068,Dex/Screens/Startup/NewWallet.qml,,2069,"Wrong word, please check again",2070,"Falsches Wort, bitte überprüfen Sie es erneut","Palabra incorrecta, verifique nuevamente",, +2073,Dex/Screens/Startup/NewWallet.qml,,2074,st,2075,.,st,, +2078,Dex/Screens/Startup/NewWallet.qml,,2079,nd,2080,.,nd,, +2083,Dex/Screens/Startup/NewWallet.qml,,2084,rd,2085,.,rd,, +2088,Dex/Screens/Startup/NewWallet.qml,,2089,th,2090,.,th,, +2093,Dex/Screens/Startup/NewWallet.qml,,2094,Failed to create a wallet,2095,Anlegen einer Brieftasche ist fehlgeschlagen,No se pudo crear una billetera,, +2098,Dex/Screens/Startup/NewWallet.qml,,2099,New Wallet,2100,Neue Brieftasche,Nueva billetera,, +2103,Dex/Screens/Startup/NewWallet.qml,,2104,Confirm Seed,2105,Seed bestätigen,Confirmar semilla,, +2108,Dex/Screens/Startup/NewWallet.qml,,2109,Choose Password,2110,Wählen sie ein Kennwort,Elegir contraseña,, +2113,Dex/Screens/Startup/NewWallet.qml,,2114,Important: Back up your seed phrase before proceeding!,2115,"Wichtig: Sichern Sie Ihre Seed-Phrase, bevor Sie fortfahren!",Importante: ¡Haga una copia de seguridad de su frase semilla antes de continuar!,, +2118,Dex/Screens/Startup/NewWallet.qml,,2119,We recommend storing it offline.,2120,"Wir empfehlen, sie offline zu speichern.",Recomendamos almacenarlo fuera de línea.,, +2123,Dex/Screens/Startup/NewWallet.qml,,2124,Generated Seed,2125,Generierter Seed,Semilla Generada,, +2128,Dex/Screens/Startup/NewWallet.qml,,2129,Seed phrase,2130,Seed Phrase,Frase semilla,, +2133,Dex/Screens/Startup/NewWallet.qml,,2134,copied to clipboard,2135,In die Zwischenablage kopiert,copiada al portapapeles,, +2138,Dex/Screens/Startup/NewWallet.qml,,2139,Next,2140,Weiter,Siguiente,, +2143,Dex/Screens/Startup/NewWallet.qml,,2144,Let's double check your seed phrase,2145,Lassen Sie uns Ihre Seed-Phrase noch einmal überprüfen,Verifiquemos dos veces su frase semilla,, +2148,Dex/Screens/Startup/NewWallet.qml,,2149,Your seed phrase is important - that's why we like to make sure it's correct. We'll ask you three different questions about your seed phrase to make sure you'll be able to easily restore your wallet whenever you want.,2150,"Ihre Seed-Phrase ist wichtig – deshalb stellen wir gerne sicher, dass sie korrekt ist. Wir stellen Ihnen drei verschiedene Fragen zu Ihrer Seed-Phrase, um sicherzustellen, dass Sie Ihre Wallet jederzeit problemlos wiederherstellen können.","Su frase semilla es importante, por eso nos gusta asegurarnos de que sea correcta. Le haremos tres preguntas diferentes sobre su frase semilla para asegurarnos de que podrá restaurar fácilmente su billetera cuando lo desee.",, +2153,Dex/Screens/Startup/NewWallet.qml,,2154,Enter the ,2155,Geben Sie das,Ingresa la,, +2158,Dex/Screens/Startup/NewWallet.qml,,2159,word,2160,Wort ein,palabra,, +2163,Dex/Screens/Startup/NewWallet.qml,,2164,Check,2165,Prüfen,Verificar,, +2168,Dex/Screens/Startup/NewWallet.qml,,2169,Enter the same password to confirm,2170,Geben Sie zur Bestätigung dasselbe Kennwort ein,Ingresa la misma contraseña para confirmar,, +2173,Dex/Screens/Startup/NewWallet.qml,,2174,Continue,2175,Fortsetzen,Continuar,, +2181,Dex/NoConnection.qml,,2182,No connection,2183,Keine Verbindung,Sin conexión,, +2186,Dex/NoConnection.qml,,2187,Please make sure you are connected to the internet,2188,"Bitte stellen Sie sicher, dass Sie mit dem Internet verbunden sind",Asegúrate de que estás conectado a Internet,, +2191,Dex/NoConnection.qml,,2192,Will automatically retry in %1 seconds,2193,Wird in %1 Sekunde(n) automatisch erneut versucht,Intentará de nuevo automáticamente en %1 segundos,, +2196,Dex/NoConnection.qml,,2197,Retry,2198,Wiederholen,Reintentar,, +2204,Dex/Dashboard/NotificationsModal.qml,,2205,Matching,2206,"Zusammenführung",Emparejando,, +2209,Dex/Dashboard/NotificationsModal.qml,,2210,Order Matching,2211,Auftrag wird abgeglichen,Emparejando Orden,, +2214,Dex/Dashboard/NotificationsModal.qml,,2215,Matched,2216,Abgestimmt,Emparejado,, +2219,Dex/Dashboard/NotificationsModal.qml,,2220,Order Matched,2221,Auftrag wurde abgestimmt,Orden Emparejada,, +2224,Dex/Dashboard/NotificationsModal.qml,,2225,Ongoing,2226,"Läuft",En Curso,, +2229,Dex/Dashboard/NotificationsModal.qml,,2230,Swap Ongoing,2231,Austausch läuft,Intercambio En Curso,, +2234,Dex/Dashboard/NotificationsModal.qml,,2235,Successful,2236,Erfolgreich,Exitoso,, +2239,Dex/Dashboard/NotificationsModal.qml,,2240,Swap Successful,2241,Tausch erfolgreich,Intercambio exitoso,, +2244,Dex/Dashboard/NotificationsModal.qml,,2245,Refunding,2246,Rückzahlung,Reembolso,, +2249,Dex/Dashboard/NotificationsModal.qml,,2250,Failed,2251,Fehlgeschlagen,Fallo,, +2254,Dex/Dashboard/NotificationsModal.qml,,2255,Swap Failed,2256,Tausch fehlgeschlagen,Intercambio fallido,, +2259,Dex/Dashboard/NotificationsModal.qml,,2260,Unknown,2261,Unbekannt,Desconocido,, +2264,Dex/Dashboard/NotificationsModal.qml,,2265,Unknown State,2266,Unbekannter Status,Estado Desconocido,, +2269,Dex/Dashboard/NotificationsModal.qml,,2270,Swap status updated,2271,Austausch-Status aktualisiert,Estado de Intercambio Actualizado,, +2274,Dex/Dashboard/NotificationsModal.qml,,2275,You sent %1,2276,Sie %1 haben gesendet,Enviaste %1,, +2279,Dex/Dashboard/NotificationsModal.qml,,2280,You received %1,2281,Sie %1 haben erhalten,Recibiste %1,, +2284,Dex/Dashboard/NotificationsModal.qml,,2285,Your wallet balance changed,2286,Ihr Guthaben hat sich geändert,El saldo de tu billetera cambió,, +2289,Dex/Dashboard/NotificationsModal.qml,,2290,Please check your internet connection (e.g. VPN service or firewall might block it).,2291,Bitte überprüfen Sie Ihre Internetverbindung (z. B. könnte VPN-Dienst oder Firewall sie blockieren).,"Verifica tu conexión a Internet (por ejemplo, el servicio VPN o el firewall pueden bloquearlo).",, +2294,Dex/Dashboard/NotificationsModal.qml,TICKER,2295,Failed to enable %1,2297,Aktivierung von %1 fehlgeschlagen,No se pudo habilitar %1,, +2300,Dex/Dashboard/NotificationsModal.qml,,2301,Endpoint not reachable,2302,Endpunkt nicht erreichbar,Punto final no accesible,, +2305,Dex/Dashboard/NotificationsModal.qml,,2306,Could not reach to endpoint,2307,Endpunkt konnte nicht erreicht werden,No se pudo llegar al punto final,, +2310,Dex/Dashboard/NotificationsModal.qml,TICKER,2311,Mismatch at %1 custom asset configuration,2313,Nichtübereinstimmung bei benutzerdefinierter Konfiguration des %1 Asset,Falta de emparejamiento en %1 configuración de recurso personalizado,, +2316,Dex/Dashboard/NotificationsModal.qml,TICKER,2317,Application needs to be restarted for %1 custom asset.,2319,Die Anwendung muss für benutzerdefiniertes Asset %1 neu gestartet werden.,Es necesario reiniciar la aplicación para %1 recurso personalizado.,, +2322,Dex/Dashboard/NotificationsModal.qml,,2323,Batch %1 failed. Reason: %2,2324,Batch %1 fehlgeschlagen. Grund: %2,El lote %1 falló. Razón: %2,, +2327,Dex/Dashboard/NotificationsModal.qml,,2328,Show,2329,Zeigen,Mostrar,, +2332,Dex/Dashboard/NotificationsModal.qml,,2333,Restart,2334,Neustart,Reiniciar,, +2337,Dex/Dashboard/NotificationsModal.qml,,2338,Quit,2339,Beenden,Salir,, +2342,Dex/Dashboard/NotificationsModal.qml,,2343,Notifications,2344,Benachrichtigungen,Notificaciones,, +2347,Dex/Dashboard/NotificationsModal.qml,,2348,There aren't any notifications,2349,Es gibt keine Benachrichtigungen,No hay ' notificaciones,, +2352,Dex/Dashboard/NotificationsModal.qml,,2353,Mark all as read,2354,Alle als gelesen makieren,Marcar todo como leído,, +2360,Dex/Exchange/ProView/PlaceOrderForm/OrderForm.qml,,2361,Price,2362,Preis,Precio,, +2365,Dex/Exchange/ProView/PlaceOrderForm/OrderForm.qml,,2366,Volume,2367,Volumen,Volumen,, +2370,Dex/Exchange/ProView/PlaceOrderForm/OrderForm.qml,,2371,Amount to sell,2372,Zu verkaufender Betrag,Importe para vender,, +2375,Dex/Exchange/ProView/PlaceOrderForm/OrderForm.qml,,2376,Amount to receive,2377,Zu erhaltender Betrag,Importe para recibir,, +2380,Dex/Exchange/ProView/PlaceOrderForm/OrderForm.qml,,2381,Min Volume,2382,Min Volumen,Volumen Mínimo,, +2385,Dex/Exchange/ProView/PlaceOrderForm/OrderForm.qml,,2386,Min amount to sell,2387,Min Verkaufsmenge,Cantidad mínima para vender,, +2390,Dex/Exchange/ProView/PlaceOrderForm/OrderForm.qml,,2391,Min amount to receive,2392,Min zu erhaltende Menge,Cantidad mínimo para recibir,, +2395,Dex/Exchange/ProView/PlaceOrderForm/OrderForm.qml,,2396,Min volume: ,2397,Mindestvolumen:,Volumen mínimo:,, +2400,Dex/Exchange/ProView/PlaceOrderForm/OrderForm.qml,,2401,Use custom minimum trade amount,2402,Benutzerdefinierten Mindesthandelsbetrag verwenden,Utilizar una cantidad personalizada de intercambio mínima,, +2408,Dex/Exchange/ProView/TradingInfo/OrderLine.qml,,2409,Funds are recoverable,2410,Geldmittel sind erstattungsfähig,Los fondos son recuperables,, +2416,Dex/Exchange/ProView/TradingInfo/OrderList.qml,,2417,No results found,2418,Keine Ergebnisse gefunden,No se han encontrado resultados,, +2424,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2425,Swap Details,2426,Tauschdetails,Detalles de Intercambio,, +2429,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2430,Order Details,2431,Auftragsdetails,Detalles de Orden,, +2434,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2435,Order Type,2436,Auftragsart,Tipo de Orden,, +2439,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2440,Maker Order,2441,Maker-Auftrag,Orden de Maker,, +2444,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2445,Taker Order,2446,Taker-Auftrag,Orden de Taker,, +2449,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2450,Refund State,2451,Rückerstattungsstatus,Estado del Reembolso,, +2454,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2455,Your swap failed but the auto-refund process for your payment started already. Please wait and keep application opened until you receive your payment back,2456,"Ihr Umtausch ist fehlgeschlagen, aber der automatische Rückerstattungsprozess für Ihre Zahlung hat bereits begonnen. Bitte warten Sie und lassen Sie die Anwendung geöffnet, bis Sie Ihre Zahlung zurückerhalten","Su intercambio falló, pero el proceso de reembolso automático para su pago ya comenzó. Espere y mantenga la aplicación abierta hasta que reciba su pago",, +2459,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2460,Date,2461,Datum,Fecha,, +2464,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2465,Error ID,2466,Fehler-ID,ID de Error,, +2470,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2471,Error Log,2472,Fehlerprotokoll,Registro de Error,, +2475,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2476,Close,2477,Schließen,Cerrar,, +2480,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2481,Cancel Order,2482,Auftrag Abbrechen,Cancelar Pedido,, +2486,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2487,Swap ID,2488,Swap ID,ID de Intercambio,, +2491,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2492,Maker Payment Sent Transaction ID,2493,Maker-Zahlung gesendet: Transaktions-ID,ID de la transacción pago enviada de Maker,, +2496,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2497,Maker Payment Spent Transaction ID,2498,Maker-Zahlung ausgegeben: Transaktions-ID,ID de la transacción pago gastado de Maker,, +2501,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2502,Maker Payment TXID,2503,Maker-Zahlung: TXID,TXID del pago de Maker,, +2506,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2507,Taker Payment Spent Transaction ID,2508,Taker-Zahlung ausgegeben: Transaktions-ID,ID de la transacción pago gastado de Taker,, +2511,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2512,Taker Payment Sent Transaction ID,2513,Taker-Zahlung gesendet: Transaktions-ID,ID de la transacción pago enviada de Taker,, +2516,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2517,Taker Payment TXID,2518,Taker-Zahlung: TXID,TXID del pago de Taker,, +2521,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2522,Recover Funds,2523,Rückerstattung der Geldmittel,Recuperar fondos,, +2526,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2527,Refunding...,2528,Rückzahlung…,Reembolso...,, +2531,Dex/Exchange/ProView/TradingInfo/OrderModal.qml,,2532,View on Explorer,2533,Ansicht im Explorer,Ver en Explorer,, +2539,Dex/Exchange/Trade/SimpleView/OrderRemovedModal.qml,,2540,Selected Order Removed,2541,Ausgewählten Auftrag entfernt,Pedido Seleccionado Eliminado,, +2544,Dex/Exchange/Trade/SimpleView/OrderRemovedModal.qml,,2545,"The selected order does not exist anymore, it might have been matched or canceled, and no order with a better price is available.",2547,Der ausgewählte Auftrag existiert nicht mehr! Er wurde möglicherweise zugeordnet oder storniert und es ist kein Auftrag mit einem besseren Preis verfügbar.,"El pedido seleccionado ya no existe, es posible que haya sido igualado o cancelado, y no hay ningún pedido disponible con un mejor precio.",, +2544,Dex/Exchange/Trade/SimpleView/OrderRemovedModal.qml,,2545,Please select a new order.,2548,Bitte wählen Sie einen neuen Auftrag aus.,Seleccione un nuevo pedido.,, +2551,Dex/Exchange/Trade/SimpleView/OrderRemovedModal.qml,,2552,OK,2553,OK,Aceptar,, +2560,Dex/Exchange/ProView/TradingInfo/OrdersPage.qml,,2561,Filter,2562,Filter,Filtrar,, +2565,Dex/Exchange/ProView/TradingInfo/OrdersPage.qml,,2566,Date,2567,Datum,Fecha,, +2570,Dex/Exchange/ProView/TradingInfo/OrdersPage.qml,,2571,Export CSV,2572,CSV exportieren,Exportar CSV,, +2575,Dex/Exchange/ProView/TradingInfo/OrdersPage.qml,,2576,Apply Filter,2577,Filter anwenden,Aplicar Filtro,, +2580,Dex/Exchange/ProView/TradingInfo/OrdersPage.qml,,2581,Cancel All,2582,Alles stornieren,Cancelar Todo,, +2585,Dex/Exchange/ProView/TradingInfo/OrdersPage.qml,,2586,From,2587,Von,De,, +2590,Dex/Exchange/ProView/TradingInfo/OrdersPage.qml,,2591,To,2592,Bis,A,, +2595,Dex/Exchange/ProView/TradingInfo/OrdersPage.qml,,2596,Please choose the CSV export name and location,2597,Bitte wählen Sie den CSV-Exportnamen und den Speicherort aus,Elija el nombre y la ubicación de exportación CSV,, +2603,Dex/Components/Pagination.qml,,2604,items per page,2605,Elemente pro Seite,elementos por página,, +2611,Dex/Components/PasswordField.qml,,2612,Password,2613,Kennwort,Contraseña,, +2616,Dex/Components/PasswordField.qml,,2617,Enter your wallet password,2618,Geben Sie das Kennwort für ihre Brieftasche ein,Ingrese la contraseña de su billetera,, +2621,Dex/Components/PasswordField.qml,,2622,At least 1 lowercase alphabetical character,2623,Mindestens 1 Kleinbuchstabe,Al menos 1 carácter alfabético en minúsculas,, +2626,Dex/Components/PasswordField.qml,,2627,At least 1 uppercase alphabetical character,2628,Mindestens 1 Großbuchstabe,Al menos 1 carácter alfabético en mayúsculas,, +2631,Dex/Components/PasswordField.qml,,2632,At least 1 numeric character,2633,Mindestens 1 Ziffer,Al menos 1 carácter numérico,, +2636,Dex/Components/PasswordField.qml,,2637,At least 1 special character (eg. !@#$%),2638,Mindestens 1 Sonderzeichen (z. B. ! @ # $ %),"Al menos 1 carácter especial ( ej., !@#$%)",, +2641,Dex/Components/PasswordField.qml,,2642,At least %n character(s),2643,,Al menos %n carácter(es),, +2652,Dex/Components/PasswordForm.qml,,2653,Password,2654,Kennwort,Contraseña,, +2657,Dex/Components/PasswordForm.qml,,2658,Confirm Password,2659,Kennwort bestätigen,Confirmar contraseña,, +2662,Dex/Components/PasswordForm.qml,,2663,Enter the same password to confirm,2664,Geben Sie zur Bestätigung dasselbe Kennwort ein,Ingrese la misma contraseña para confirmar,, +2670,Dex/Portfolio/Portfolio.qml,,2671,ADD ASSET,2672,ASSET HINZUFÜGEN,AGREGAR ACTIVO,, +2675,Dex/Portfolio/Portfolio.qml,,2676,Search asset,2677,Asset suchen,Buscar activo,, +2680,Dex/Portfolio/Portfolio.qml,,2681,Show only coins with balance,2682,Nur Coins mit Guthaben anzeigen,Mostrar solo monedas con saldo,, +2685,Dex/Portfolio/Portfolio.qml,,2686,(%1/%2),2687,(%1/%2),(%1/%2),, +2690,Dex/Portfolio/Portfolio.qml,,2691,Portfolio,2692,Portfolio,Cartera,, +2698,Dex/Exchange/ProView/TradingInfo/PriceLine.qml,,2699,Set swap price for evaluation,2700,Legen Sie den Tausch-Preis für die Bewertung fest,Establecer precio de intercambio para evaluación,, +2703,Dex/Exchange/ProView/TradingInfo/PriceLine.qml,,2704,Exchange rate,2705,Wechselkurs,Tipo de cambio,, +2708,Dex/Exchange/ProView/TradingInfo/PriceLine.qml,,2709,Selected,2710,Ausgewählt,seleccionado,, +2713,Dex/Exchange/ProView/TradingInfo/PriceLine.qml,,2714,Expensive,2715,Teuer,Expensive,, +2718,Dex/Exchange/ProView/TradingInfo/PriceLine.qml,,2719,Expedient,2720,Sinnvoll,Expedient,, +2723,Dex/Exchange/ProView/TradingInfo/PriceLine.qml,PRICE_DIFF%,2724,%1 compared to CEX,2726,%1 im Vergleich zu CEX,%1 en comparación con CEX,, +2729,Dex/Exchange/ProView/TradingInfo/PriceLine.qml,,2730,CEXchange rate,2731,CEX-Wechselkurs,Tasa de cambio CEX,, +2737,Dex/Exchange/Trade/PriceLineSimplified.qml,,2738,Exchange rate,2739,Wechselkurs,Tasa de cambio,, +2742,Dex/Exchange/Trade/PriceLineSimplified.qml,,2743,Selected,2744,Ausgewählt,Seleccionada,, +2747,Dex/Exchange/Trade/PriceLineSimplified.qml,,2748,CEXchange rate,2749,CEX-Wechselkurs,Tasa de cambio CEX,, +2752,Dex/Exchange/Trade/PriceLineSimplified.qml,,2753,Expensive,2754,Teuer,Caro,, +2757,Dex/Exchange/Trade/PriceLineSimplified.qml,,2758,Expedient,2759,Sinnvoll,Expediente,, +2762,Dex/Exchange/Trade/PriceLineSimplified.qml,PRICE_DIFF%,2763,%1 compared to CEX,2765,%1 im Vergleich zu CEX,%1 en comparación con CEX,, +2771,Dex/Exchange/Trade/ProView.qml,,2772,Failed to place the order,2773,Der Auftrag konnte nicht platziert werden,No se pudo realizar la orden,, +2776,Dex/Exchange/Trade/ProView.qml,,2777,Placed the order,2778,Auftrag platziert,Orden emitida,, +2784,../src/core/atomicdex/services/update/update.checker.service.cpp,,2785,Cannot reach the endpoint: ,2786,Der Endpunkt kann nicht erreicht werden:,No se puede llegar al punto final:,, +2792,Dex/Wallet/ReceiveModal.qml,,2793,Receive,2794,Empfangen,Recibir,, +2797,Dex/Wallet/ReceiveModal.qml,TICKER,2798,Only send %1 to this address:,2800,Sende nur %1 an diese Adresse:,Enviar solo %1 a esta dirección:,, +2803,Dex/Wallet/ReceiveModal.qml,,2804,copied to clipboard.,2805,In die Zwischenablage kopiert,copiado al portapapeles.,, +2808,Dex/Wallet/ReceiveModal.qml,,2809,Close,2810,Schließen,Cerrar,, +2817,Dex/Settings/RecoverSeedModal.qml,,2818,View seed and private keys,2819,Seed- und privaten Schlüsseln anzeigen,Ver semilla y claves privadas,, +2822,Dex/Settings/RecoverSeedModal.qml,,2823,Please enter your password to view the seed.,2824,"Bitte geben Sie Ihr Kennwort ein, um den Seed anzuzeigen.",Por favor ingrese su contraseña para ver la semilla.,, +2827,Dex/Settings/RecoverSeedModal.qml,,2828,Seed,2829,Seed,Semilla,, +2832,Dex/Settings/RecoverSeedModal.qml,,2833,Backup Seed,2834,Seed Sicherung,Copia de seguridad de semilla,, +2837,Dex/Settings/RecoverSeedModal.qml,,2838,Public Address copied to clipboard,2839,Öffentliche Adresse in die Zwischenablage kopiert,Direccion publica copiada en el portapapeles,, +2842,Dex/Settings/RecoverSeedModal.qml,,2843,Cancel,2844,Abbrechen,Cancelar,, +2847,Dex/Settings/RecoverSeedModal.qml,,2848,View,2849,Ansehen,Ver,, +2853,Dex/Settings/RecoverSeedModal.qml,,2854,copied to clipboard,2855,In die Zwischenablage kopiert,copiada en el portapapeles,, +2859,Dex/Settings/RecoverSeedModal.qml,,2860,RPC Password,2861,RPC Kennwort,Contraseña RPC,, +2864,Dex/Settings/RecoverSeedModal.qml,,2865,Search a coin.,2866,Coin suchen.,Buscar una moneda.,, +2869,Dex/Settings/RecoverSeedModal.qml,,2870,Public Address,2871,Öffentliche Adresse,Dirección Pública,, +2874,Dex/Settings/RecoverSeedModal.qml,,2875,Private Key copied to clipboard,2876,Privater Schlüssel in die Zwischenablage kopiert,Clave Privada copiada en el portapapeles,, +2879,Dex/Settings/RecoverSeedModal.qml,,2880,Private Key,2881,Privater Schlüssel,Clave Privada,, +2887,Dex/Addressbook/RemoveContactPopup.qml,,2888,Do you want to remove this contact ?,2889,Möchten Sie diesen Kontakt entfernen?,¿Desea eliminar este contacto?,, +2892,Dex/Addressbook/RemoveContactPopup.qml,,2893,Yes,2894,Ja,Sí,, +2897,Dex/Addressbook/RemoveContactPopup.qml,,2898,No,2899,Nein,No,, +2905,Dex/Components/RestartModal.qml,,2906,Applying the changes...,2907,Übernehmen der Änderungen...,Aplicando los cambios...,, +2910,Dex/Components/RestartModal.qml,,2911,Restarting the application. %1,2912,Neustart der Anwendung. %1,Reiniciando la aplicación. %1,, +2915,Dex/Components/RestartModal.qml,,2916,Restarting the application...,2917,Neustart der Anwendung...,Reiniciando la aplicación...,, +2923,Dex/Components/RightClickMenu.qml,,2924,Cut,2925,Ausschneiden,Cortar,, +2928,Dex/Components/RightClickMenu.qml,,2929,Copy,2930,Kopieren,Copiar,, +2933,Dex/Components/RightClickMenu.qml,,2934,Paste,2935,Einfügen,Pegar,, +2941,Dex/Components/SearchField.qml,,2942,Search,2943,Suchen,Buscar,, +2949,Dex/Wallet/SendModal.qml,,2950,Failed to send,2951,Fehler beim Senden,Error al enviar,, +2954,Dex/Wallet/SendModal.qml,,2955,Failed to Send,2956,Fehler beim Senden,Error al enviar,, +2959,Dex/Wallet/SendModal.qml,,2960,Prepare to send ,2961,Versandvorbereitung von ,Preparar para enviar,, +2964,Dex/Wallet/SendModal.qml,,2965,Address of the recipient,2966,Adresse des Empfängers,Dirección del destinatario,, +2969,Dex/Wallet/SendModal.qml,,2970,Amount to send,2971,Zu sendender Betrag,Cantidad a enviar,, +2974,Dex/Wallet/SendModal.qml,,2975,Gas price,2976,Gas Preis,Precio del gas,, +2979,Dex/Wallet/SendModal.qml,,2980,Recipient's address,2981,Empfängeradresse,Direccion's recipiente,, +2984,Dex/Wallet/SendModal.qml,,2985,The address has to be mixed case.,2986,Die Adresse muss Groß-/Kleinschreibung sein.,La dirección debe estar en mayúsculas y minúsculas.,, +2989,Dex/Wallet/SendModal.qml,,2990,Fix,2991,Korrigieren,Arreglar,, +2994,Dex/Wallet/SendModal.qml,,2995,MAX,2996,MAX,MAX,, +2999,Dex/Wallet/SendModal.qml,,3000,Fiat amount: Unavailable,3001,Fiat-Betrag: Nicht verfügbar,Cantidad en Fiat: No disponible,, +3004,Dex/Wallet/SendModal.qml,,3005,Fiat amount: %1,3006,Fiat-Betrag: %1,Cantidad de Fiat: %1,, +3009,Dex/Wallet/SendModal.qml,,3010,%1 amount: %2,3011,%1 Betrag: %2,Cantidad de %1: %2,, +3014,Dex/Wallet/SendModal.qml,,3015,Specify in Fiat,3016,In Fiat angeben,Especificar en Fiat,, +3019,Dex/Wallet/SendModal.qml,,3020,Specify in Crypto,3021,In Krypto angeben,Especificar en Crypto,, +3024,Dex/Wallet/SendModal.qml,,3025,Enable Custom Fees,3026,Benutzerdefinierte Gebühren,Habilitar Tarifas Personalizadas,, +3029,Dex/Wallet/SendModal.qml,,3030,Only use custom fees if you know what you are doing!,3031,"Benutzerdefinierte Gebühren nur verwenden, wenn Sie wissen, was Sie tun!",¡Solo use tarifas personalizadas si sabe lo que está haciendo!,, +3034,Dex/Wallet/SendModal.qml,,3035,Enter the custom fee,3036,Geben Sie die benutzerdefinierte Gebühr ein,Ingrese la tarifa personalizada,, +3039,Dex/Wallet/SendModal.qml,,3040,Gas Limit,3041,Gas Limit,Límite de gas,, +3044,Dex/Wallet/SendModal.qml,,3045,Custom Fee can't be higher than the amount,3046,Die benutzerdefinierten Gebühren dürfen nicht höher sein als der Betrag,Tarifa personalizada no puede ser mayor que la cantidad,, +3049,Dex/Wallet/SendModal.qml,,3050,Not enough funds.,3051,Nicht genug Geldmittel.,No hay suficientes fondos.,, +3055,Dex/Wallet/SendModal.qml,AMT TICKER,3056,You have %1,3058,Sie haben %1,Tiene %1,, +3061,Dex/Wallet/SendModal.qml,,3062,Close,3063,Schließen,Cerrar,, +3066,Dex/Wallet/SendModal.qml,,3067,Prepare,3068,Vorbereiten,Preparar,, +3072,Dex/Wallet/SendModal.qml,,3073,Send,3074,Senden,Enviar,, +3077,Dex/Wallet/SendModal.qml,,3078,Amount,3079,Menge,Cantidad,, +3082,Dex/Wallet/SendModal.qml,,3083,Fees,3084,Gebühren,Tarifas,, +3087,Dex/Wallet/SendModal.qml,,3088,Date,3089,Datum,Fecha,, +3092,Dex/Wallet/SendModal.qml,,3093,Back,3094,Zurück,Atrás,, +3100,Dex/Wallet/SendModalContactList.qml,,3101,Select a contact with an %1 address,3102,Wählen Sie einen Kontakt mit einer %1-Adresse aus,Seleccione un contacto con %1 dirección,, +3105,Dex/Wallet/SendModalContactList.qml,,3106,Search for contacts...,3107,Kontakte suchen...,Buscar contactos...,, +3110,Dex/Wallet/SendModalContactList.qml,,3111,%1 addresses,3112,%1 Adressen,direcciones %1,, +3115,Dex/Wallet/SendModalContactList.qml,,3116,1 address,3117,1 Adresse,1 dirección,, +3121,Dex/Wallet/SendModalContactList.qml,,3122,Back,3123,Zurück,Atrás,, +3126,Dex/Wallet/SendModalContactList.qml,,3127,Choose an %1 address of %2,3128,Wählen Sie eine %1-Adresse von %2,Elija una direccion %1 de %2,, +3131,Dex/Wallet/SendModalContactList.qml,,3132,Name,3133,Name,Nombre,, +3136,Dex/Wallet/SendModalContactList.qml,,3137,Address,3138,Adresse,Dirección,, +3144,Dex/Wallet/SendResult.qml,,3145,Transaction Complete!,3146,Transaktion abgeschlossen!,¡Transacción completa!,, +3149,Dex/Wallet/SendResult.qml,,3150,Recipient's address,3151,Empfängeradresse,Dirección del destinatario,, +3154,Dex/Wallet/SendResult.qml,,3155,Amount,3156,Menge,Importe,, +3159,Dex/Wallet/SendResult.qml,,3160,Fees,3161,Gebühren,Tarifas,, +3164,Dex/Wallet/SendResult.qml,,3165,Date,3166,Datum,Fecha,, +3169,Dex/Wallet/SendResult.qml,,3170,Transaction Hash,3171,Transaktions-Hash,Hash de Transacción,, +3174,Dex/Wallet/SendResult.qml,,3175,Close,3176,Schließen,Cerrar,, +3179,Dex/Wallet/SendResult.qml,,3180,View on Explorer,3181,Ansicht im Explorer,Ver en Explorer,, +3187,Dex/Settings/SettingModal.qml,,3188,Confirm Logout,3189,Abmelden bestätigen,Confirmar Cerrar Sesión,, +3192,Dex/Settings/SettingModal.qml,,3193,Are you sure you want to log out?,3194,Wollen Sie sich wirklich abmelden?,¿Está seguro de que desea cerrar sesión?,, +3197,Dex/Settings/SettingModal.qml,,3198,Yes,3199,Ja,Sí,, +3204,Dex/Settings/SettingModal.qml,,3205,Cancel,3206,Abbrechen,Cancelar,, +3209,Dex/Settings/SettingModal.qml,,3210,Settings,3211,Einstellungen,Configuración,, +3214,Dex/Settings/SettingModal.qml,,3215,General,3216,Allgemein,General,, +3219,Dex/Settings/SettingModal.qml,,3220,Language,3221,Sprache,Idioma,, +3224,Dex/Settings/SettingModal.qml,,3225,User Interface,3226,Benutzeroberfläche,Interfaz,, +3229,Dex/Settings/SettingModal.qml,,3230,Security,3231,Sicherheit,Seguridad,, +3234,Dex/Settings/SettingModal.qml,,3235,Enable Desktop Notifications,3236,Desktop-Benachrichtigungen aktivieren,Habilitar Notificaciones de Escritorio,, +3239,Dex/Settings/SettingModal.qml,,3240,Maximum number of enabled coins,3241,Maximale Anzahl aktivierter Coins,Número máximo de monedas habilitadas,, +3244,Dex/Settings/SettingModal.qml,,3245,Logs,3246,Protokolle,Registros,, +3249,Dex/Settings/SettingModal.qml,,3250,Open Folder,3251,Ordner öffnen,Carpeta Abierta,, +3254,Dex/Settings/SettingModal.qml,,3255,Reset,3256,Zurücksetzen,Restablecer,, +3259,Dex/Settings/SettingModal.qml,,3260,Current Font,3261,Aktuelle Schriftart,Fuente Actual,, +3264,Dex/Settings/SettingModal.qml,,3265,Current font changed to %1.,3266,Aktuelle Schriftart in %1 geändert.,La fuente actual cambió a %1.,, +3269,Dex/Settings/SettingModal.qml,,3270,Theme,3271,Thema,Tema,, +3274,Dex/Settings/SettingModal.qml,,3275,Changing theme to %1,3276,Design zu %1 geändert,Cambiando el tema a %1,, +3279,Dex/Settings/SettingModal.qml,,3280,Disable 2FA?,3281,2FA deaktivieren?,¿Deshabilitar 2FA?,, +3284,Dex/Settings/SettingModal.qml,,3285,Enter your wallet password to confirm,3286,Geben Sie zur Bestätigung das Kennwort ihrer Brieftasche ein,Ingrese la contraseña de su billetera para confirmar,, +3289,Dex/Settings/SettingModal.qml,,3290,Type password,3291,Kennwort eingeben,Escriba la contraseña,, +3294,Dex/Settings/SettingModal.qml,,3295,2FA status,3296,2FA Status,Estado 2FA,, +3299,Dex/Settings/SettingModal.qml,,3300,2FA disabled successfully,3301,2FA erfolgreich deaktiviert,2FA deshabilitado correctamente,, +3305,Dex/Settings/SettingModal.qml,,3306,Ok,3307,Ok,Ok,, +3310,Dex/Settings/SettingModal.qml,,3311,Wrong password!,3312,Falsches Kennwort!,¡Contraseña incorrecta!,, +3315,Dex/Settings/SettingModal.qml,,3316,Wallet password is incorrect,3317,Kennwort der Brieftasche ist falsch,Contraseña de la billetera es incorrecta,, +3320,Dex/Settings/SettingModal.qml,,3321,Application Version,3322,Anwendungsversion,La versión de la aplicación,, +3325,Dex/Settings/SettingModal.qml,,3326,copied to clipboard,3327,In die Zwischenablage kopiert,copió en el portapapeles,, +3330, - - assets/fonts/Ubuntu-B.ttf - assets/fonts/Ubuntu-BI.ttf - assets/fonts/Ubuntu-L.ttf - assets/fonts/Ubuntu-LI.ttf - assets/fonts/Ubuntu-M.ttf - assets/fonts/Ubuntu-MI.ttf - assets/fonts/Ubuntu-R.ttf - assets/fonts/Ubuntu-RI.ttf - assets/fonts/Ubuntu-Th.ttf - assets/images/addressbook.png - assets/images/arrow-down.svg - assets/images/arrow-up.svg - assets/images/arrow_down.svg - assets/images/arrow_up.svg - assets/images/bill.svg - assets/images/circle-failed.png - assets/images/circle-success.png - assets/images/coins/1inch.png - assets/images/coins/aave.png - assets/images/coins/aby.png - assets/images/coins/ada.png - assets/images/coins/adx.png - assets/images/coins/agix.png - assets/images/coins/ankr.png - assets/images/coins/ant.png - assets/images/coins/arpa.png - assets/images/coins/arrr.png - assets/images/coins/atom.png - assets/images/coins/aur.png - assets/images/coins/ava.png - assets/images/coins/avax.png - assets/images/coins/avaxt.png - assets/images/coins/awc.png - assets/images/coins/axe.png - assets/images/coins/axs.png - assets/images/coins/babydoge.png - assets/images/coins/bal.png - assets/images/coins/band.png - assets/images/coins/banano.png - assets/images/coins/bat.png - assets/images/coins/bch.png - assets/images/coins/best.png - assets/images/coins/bet.png - assets/images/coins/bidr.png - assets/images/coins/blk.png - assets/images/coins/bnb.png - assets/images/coins/bnbt.png - assets/images/coins/bnt.png - assets/images/coins/bone.png - assets/images/coins/bots.png - assets/images/coins/brz.png - assets/images/coins/bsty.png - assets/images/coins/btc.png - assets/images/coins/btcz.png - assets/images/coins/btt.png - assets/images/coins/bttc.png - assets/images/coins/btu.png - assets/images/coins/btx.png - assets/images/coins/busd.png - assets/images/coins/bte.png - assets/images/coins/cadc.png - assets/images/coins/cake.png - assets/images/coins/case.png - assets/images/coins/cdn.png - assets/images/coins/ccl.png - assets/images/coins/cel.png - assets/images/coins/celr.png - assets/images/coins/cennz.png - assets/images/coins/chips.png - assets/images/coins/ciphs.png - assets/images/coins/chsb.png - assets/images/coins/chz.png - assets/images/coins/clc.png - assets/images/coins/comp.png - assets/images/coins/cro.png - assets/images/coins/crv.png - assets/images/coins/crypto.png - assets/images/coins/cummies.png - assets/images/coins/cvc.png - assets/images/coins/cvt.png - assets/images/coins/dai.png - assets/images/coins/dash.png - assets/images/coins/dex.png - assets/images/coins/dgb.png - assets/images/coins/dgc.png - assets/images/coins/dia.png - assets/images/coins/dimi.png - assets/images/coins/dodo.png - assets/images/coins/doge.png - assets/images/coins/dogedash.png - assets/images/coins/doggy.png - assets/images/coins/doi.png - assets/images/coins/dot.png - assets/images/coins/dp.png - assets/images/coins/dust.png - assets/images/coins/dx.png - assets/images/coins/eca.png - assets/images/coins/efl.png - assets/images/coins/egld.png - assets/images/coins/elf.png - assets/images/coins/emc2.png - assets/images/coins/enj.png - assets/images/coins/eos.png - assets/images/coins/erc-20.png - assets/images/coins/etc.png - assets/images/coins/eth.png - assets/images/coins/ethk.png - assets/images/coins/ethr.png - assets/images/coins/eurs.png - assets/images/coins/fet.png - assets/images/coins/floki.png - assets/images/coins/flux.png - assets/images/coins/fil.png - assets/images/coins/firo.png - assets/images/coins/fjc.png - assets/images/coins/fjcb.png - assets/images/coins/flow.png - assets/images/coins/ftc.png - assets/images/coins/ftm.png - assets/images/coins/ftmt.png - assets/images/coins/gala.png - assets/images/coins/gleec.png - assets/images/coins/glmr.png - assets/images/coins/gno.png - assets/images/coins/grms.png - assets/images/coins/gm.png - assets/images/coins/gms.png - assets/images/coins/grs.png - assets/images/coins/grt.png - assets/images/coins/hex.png - assets/images/coins/hlc.png - assets/images/coins/hodl.png - assets/images/coins/hot.png - assets/images/coins/hpy.png - assets/images/coins/ht.png - assets/images/coins/husd.png - assets/images/coins/ic.png - assets/images/coins/il8p.png - assets/images/coins/iln.png - assets/images/coins/inj.png - assets/images/coins/ink.png - assets/images/coins/iota.png - assets/images/coins/iotx.png - assets/images/coins/jchf.png - assets/images/coins/jeur.png - assets/images/coins/jgbp.png - assets/images/coins/jpyc.png - assets/images/coins/jrt.png - assets/images/coins/jstr.png - assets/images/coins/jumblr.png - assets/images/coins/kcs.png - assets/images/coins/kmd.png - assets/images/coins/knc.png - assets/images/coins/koin.png - assets/images/coins/ksm.png - assets/images/coins/labs.png - assets/images/coins/lbc.png - assets/images/coins/lcc.png - assets/images/coins/leash.png - assets/images/coins/leo.png - assets/images/coins/link.png - assets/images/coins/lrc.png - assets/images/coins/lstr.png - assets/images/coins/ltc.png - assets/images/coins/ltfn.png - assets/images/coins/luna.png - assets/images/coins/lynx.png - assets/images/coins/mana.png - assets/images/coins/matic.png - assets/images/coins/matictest.png - assets/images/coins/mcl.png - assets/images/coins/mesh.png - assets/images/coins/mgw.png - assets/images/coins/mir.png - assets/images/coins/minds.png - assets/images/coins/mkr.png - assets/images/coins/mln.png - assets/images/coins/mm.png - assets/images/coins/mona.png - assets/images/coins/morty.png - assets/images/coins/movr.png - assets/images/coins/mshark.png - assets/images/coins/nav.png - assets/images/coins/near.png - assets/images/coins/nexo.png - assets/images/coins/nmc.png - assets/images/coins/nvc.png - assets/images/coins/nyan.png - assets/images/coins/nzds.png - assets/images/coins/oc.png - assets/images/coins/ocean.png - assets/images/coins/okb.png - assets/images/coins/omg.png - assets/images/coins/one.png - assets/images/coins/ont.png - assets/images/coins/pangea.png - assets/images/coins/pax.png - assets/images/coins/paxg.png - assets/images/coins/pic.png - assets/images/coins/pnk.png - assets/images/coins/powr.png - assets/images/coins/ppc.png - assets/images/coins/prcy.png - assets/images/coins/pgx.png - assets/images/coins/prux.png - assets/images/coins/put.png - assets/images/coins/qbt.png - assets/images/coins/qc.png - assets/images/coins/qi.png - assets/images/coins/qiair.png - assets/images/coins/qkc.png - assets/images/coins/qnt.png - assets/images/coins/qrc-20.png - assets/images/coins/qrc20.png - assets/images/coins/qtum.png - assets/images/coins/rbtc.png - assets/images/coins/ren.png - assets/images/coins/rep.png - assets/images/coins/rev.png - assets/images/coins/revs.png - assets/images/coins/rick.png - assets/images/coins/rlc.png - assets/images/coins/rsr.png - assets/images/coins/rtm.png - assets/images/coins/rvn.png - assets/images/coins/s4f.png - assets/images/coins/sand.png - assets/images/coins/sbch.png - assets/images/coins/sfusd.png - assets/images/coins/shr.png - assets/images/coins/shib.png - assets/images/coins/sibm.png - assets/images/coins/skl.png - assets/images/coins/smart-chain.png - assets/images/coins/smtf.png - assets/images/coins/snt.png - assets/images/coins/snx.png - assets/images/coins/sol.png - assets/images/coins/soulja.png - assets/images/coins/sca.png - assets/images/coins/space.png - assets/images/coins/spc.png - assets/images/coins/srm.png - assets/images/coins/stfiro.png - assets/images/coins/storj.png - assets/images/coins/supernet.png - assets/images/coins/sushi.png - assets/images/coins/sxp.png - assets/images/coins/sys.png - assets/images/coins/tblk.png - assets/images/coins/tbtc.png - assets/images/coins/tel.png - assets/images/coins/tft.png - assets/images/coins/thc.png - assets/images/coins/thc_bep20.png - assets/images/coins/thx.png - assets/images/coins/tkl.png - assets/images/coins/tmtg.png - assets/images/coins/tqtum.png - assets/images/coins/trac.png - assets/images/coins/trc.png - assets/images/coins/trx.png - assets/images/coins/tryb.png - assets/images/coins/tsl.png - assets/images/coins/ttt.png - assets/images/coins/tusd.png - assets/images/coins/ubq.png - assets/images/coins/ubt.png - assets/images/coins/uis.png - assets/images/coins/uma.png - assets/images/coins/uni.png - assets/images/coins/uno.png - assets/images/coins/uos.png - assets/images/coins/uqc.png - assets/images/coins/usbl.png - assets/images/coins/usdc.png - assets/images/coins/usdi.png - assets/images/coins/usdt.png - assets/images/coins/ust.png - assets/images/coins/utk.png - assets/images/coins/val.png - assets/images/coins/vgx.png - assets/images/coins/vite.png - assets/images/coins/vra.png - assets/images/coins/vrm.png - assets/images/coins/vrsc.png - assets/images/coins/wbtc.png - assets/images/coins/wcn.png - assets/images/coins/whive.png - assets/images/coins/wsb.png - assets/images/coins/wwcn.png - assets/images/coins/xec.png - assets/images/coins/xep.png - assets/images/coins/xlm.png - assets/images/coins/xmy.png - assets/images/coins/xor.png - assets/images/coins/xpm.png - assets/images/coins/xrp.png - assets/images/coins/xrg.png - assets/images/coins/xsgd.png - assets/images/coins/xtz.png - assets/images/coins/xvc.png - assets/images/coins/xvs.png - assets/images/coins/yfi.png - assets/images/coins/yfii.png - assets/images/coins/zec.png - assets/images/coins/zer.png - assets/images/coins/zet.png - assets/images/coins/zinu.png - assets/images/coins/zil.png - assets/images/coins/zilla.png - assets/images/coins/zrx.png - assets/images/providers/binance.png - assets/images/providers/coingecko.png - assets/images/providers/coinpaprika.png - assets/images/providers/forex.png - assets/images/providers/nomics.png - assets/images/dashboard-copy.svg - assets/images/dashboard-eye-hide.svg - assets/images/dashboard-eye.svg - assets/images/dashboard-info.svg - assets/images/dex-logo-big.png - assets/images/dex-tray-icon.png - assets/images/exchange-exchange.svg - assets/images/exchange-search.svg - assets/images/exchange-trade-complete.png - assets/images/guide_coingecko_id.gif - assets/images/guide_contract_address_erc.gif - assets/images/guide_contract_address_qrc.gif - assets/images/guide_contract_address_bep.gif - assets/images/icon-discord.png - assets/images/icon-email.png - assets/images/icon-support.png - assets/images/icon-twitter.png - assets/images/komodo-icon.png - assets/images/lang/en.png - assets/images/lang/fr.png - assets/images/lang/ru.png - assets/images/lang/tr.png - assets/images/logo/dex-logo.png - assets/images/menu-assets-portfolio.svg - assets/images/menu-assets-white.svg - assets/images/menu-dapp-white.svg - assets/images/menu-exchange-white.svg - assets/images/menu-news-white.svg - assets/images/menu-settings-white.svg - assets/images/menu-support-white.png - assets/images/settings-seed.svg - assets/images/setup-logs.svg - assets/images/setup-wallet-restore-2.svg - assets/images/setup-welcome-wallet.svg - assets/images/shadowed_circle_blue.svg - assets/images/shadowed_circle_green.svg - assets/images/trade_icon.svg - assets/languages/atomic_defi_en.qm - assets/languages/atomic_defi_fr.qm - assets/languages/atomic_defi_ru.qm - assets/languages/atomic_defi_tr.qm - Dex/App.qml - Dex/String.js - Dex/Components/AddressField.qml - Dex/Components/AddressFieldWithTitle.qml - Dex/Components/AmountField.qml - Dex/Components/AmountFieldWithInfo.qml - Dex/Components/AmountIntField.qml - Dex/Components/AnimatedRectangle.qml - Dex/Components/Arrow.qml - Dex/Components/Blank.qml - Dex/Components/CannotEnableCoinModal.qml - Dex/Components/CexInfoModal.qml - Dex/Components/CexInfoTrigger.qml - Dex/Components/Circle.qml - Dex/Components/ClickableText.qml - Dex/Components/ClipRRect.qml - Dex/Components/CoinMenu.qml - Dex/Components/CoinTypeTag.qml - Dex/Components/ColumnHeader.qml - Dex/Components/ComboBoxWithTitle.qml - Dex/Components/ComponentWithTitle.qml - Dex/Components/CopyFieldButton.qml - Dex/Components/DangerButton.qml - Dex/Components/DefaultAlertIcon.qml - Dex/Components/DefaultAnimatedImage.qml - Dex/Components/DefaultBusyIndicator.qml - Dex/Components/DefaultButton.qml - Dex/Components/DefaultCheckBox.qml - Dex/Components/DefaultColorOverlay.qml - Dex/Components/DefaultComboBox.qml - Dex/Components/DefaultFlickable.qml - Dex/Components/DefaultImage.qml - Dex/Components/DefaultInnerShadow.qml - Dex/Components/DefaultListView.qml - Dex/Components/DefaultLoader.qml - Dex/Components/DefaultModal.qml - Dex/Components/DefaultMouseArea.qml - Dex/Components/DefaultRangeSlider.qml - Dex/Components/DefaultRectangle.qml - Dex/Components/DefaultScrollBar.qml - Dex/Components/DefaultScrollView.qml - Dex/Components/DefaultSlider.qml - Dex/Components/DefaultSplitView.qml - Dex/Components/DefaultSubstractRectangle.qml - Dex/Components/DefaultSweetComboBox.qml - Dex/Components/DefaultSwitch.qml - Dex/Components/DefaultText.qml - Dex/Components/DefaultTextArea.qml - Dex/Components/DefaultTextEdit.qml - Dex/Components/DefaultTextField.qml - Dex/Components/DefaultTooltip.qml - Dex/Components/DexAnimatedImage.qml - Dex/Components/DexAmountField.qml - Dex/Components/DexAppButton.qml - Dex/Components/DexTransparentButton.qml - Dex/Components/DexAppOutlineButton.qml - Dex/Components/DexAppTextField.qml - Dex/Components/DexAppPasswordField.qml - Dex/Components/DexBox.qml - Dex/Components/DexBoxManager.qml - Dex/Components/DexButton.qml - Dex/Components/DexCheckBox.qml - Dex/Components/DexCheckEye.qml - Dex/Components/DexColorOverlay.qml - Dex/Components/DexCopyableLabel.qml - Dex/Components/DexComboBox.qml - Dex/Components/DexDialogManager.qml - Dex/Components/DexDialogTextField.qml - Dex/Components/DexFadebehavior.qml - Dex/Components/DexVisibleBehavior.qml - Dex/Components/DexFlickable.qml - Dex/Components/DexGradientAppButton.qml - Dex/Components/DexIconButton.qml - Dex/Components/DexImage.qml - Dex/Components/DexInnerShadow.qml - Dex/Components/DexItemBox.qml - Dex/Components/DexLabel.qml - Dex/Components/DexLabelUnlinked.qml - Dex/Components/DexLanguage.qml - Dex/Components/DexListView.qml - Dex/Components/DexLoader.qml - Dex/Components/DexKeyChecker.qml - Dex/Components/DexMacControl.qml - Dex/Components/DexModal.qml - Dex/Components/DexModalHeader.qml - Dex/Components/DexMouseArea.qml - Dex/Components/DexPaginator.qml - Dex/Components/DexPopup.qml - Dex/Components/DexRangeSlider.qml - Dex/Components/DexRectangle.qml - Dex/Components/DexScrollBar.qml - Dex/Components/DexSelectableButton.qml - Dex/Components/DexSlider.qml - Dex/Components/DexSplitView.qml - Dex/Components/DexSubstractRectangle.qml - Dex/Components/DexSweetComboBox.qml - Dex/Components/DexSwitch.qml - Dex/Components/DexText.qml - Dex/Components/DexAppTextArea.qml - Dex/Components/DexTextArea.qml - Dex/Components/DexTextEdit.qml - Dex/Components/DexTextField.qml - Dex/Components/DexTooltip.qml - Dex/Components/DexTradeBox.qml - Dex/Components/DexWindow.qml - Dex/Components/DexWindowControl.qml - Dex/Components/DexWindowHeaderControl.qml - Dex/Components/DexMacosHeaderControl.qml - Dex/Components/EulaModal.qml - Dex/Components/FloatingBackground.qml - Dex/Components/ForceRestartModal.qml - Dex/Components/GradientButton.qml - Dex/Components/GradientRectangle.qml - Dex/Components/HelpModal.qml - Dex/Components/HideFieldButton.qml - Dex/Components/HorizontalLine.qml - Dex/Components/InnerBackground.qml - Dex/Components/ItemBox.qml - Dex/Components/LinkIcon.qml - Dex/Components/LinksRow.qml - Dex/Components/LoaderBusyIndicator.qml - Dex/Components/LogModal.qml - Dex/Components/MinTradeModal.qml - Dex/Components/ModalHeader.qml - Dex/Components/ModalLoader.qml - Dex/Components/MultipageModal.qml - Dex/Components/MultipageModalContent.qml - Dex/Components/OutlineButton.qml - Dex/Components/Pagination.qml - Dex/Components/PaginationButton.qml - Dex/Components/PasswordField.qml - Dex/Components/PasswordForm.qml - Dex/Components/PlusButton.qml - Dex/Components/PrimaryButton.qml - Dex/Components/RestartModal.qml - Dex/Components/RightClickMenu.qml - Dex/Components/RoundComboBox.qml - Dex/Components/SearchField.qml - Dex/Components/Separator.qml - Dex/Components/SetupPage.qml - Dex/Components/SidebarPanel.qml - Dex/Components/SquareButton.qml - Dex/Components/SwapIcon.qml - Dex/Components/TextAreaWithTitle.qml - Dex/Components/TextEditWithTitle.qml - Dex/Components/TextFieldWithTitle.qml - Dex/Components/TextWithTitle.qml - Dex/Components/TitleText.qml - Dex/Components/Toast.qml - Dex/Components/ToastManager.qml - Dex/Components/VerticalLine.qml - Dex/Components/VerticalLineBasic.qml - Dex/Components/WalletNameField.qml - Dex/Constants - Dex/Constants/API.qml - Dex/Constants/DexTheme.qml - Dex/Constants/DexTypo.qml - Dex/Constants/General.qml - Dex/Constants/Style.qml - Dex/Dashboard/FatalErrorModal.qml - Dex/Dashboard/NewUpdateModal.qml - Dex/Dashboard/UpdateInvalidChecksum.qml - Dex/Dashboard/NotificationsModal.qml - Dex/Exchange/Exchange.qml - Dex/Exchange/History/History.qml - Dex/Exchange/Orders/Orders.qml - Dex/Exchange/ProView/MarketModeSelector.qml - Dex/Exchange/Trade/BestOrder/Header.qml - Dex/Exchange/Trade/BestOrder/List.qml - Dex/Exchange/Trade/BestOrder/ListDelegate.qml - Dex/Exchange/Trade/CandleStickChart.qml - Dex/Exchange/Trade/ConfirmMultiOrderTradeModal.qml - Dex/Exchange/Trade/ConfirmTradeModal.qml - Dex/Exchange/Trade/DefaultSweetModal.qml - Dex/Exchange/Trade/DexComboBoxLine.qml - Dex/Exchange/Trade/FeeIcon.qml - Dex/Exchange/Trade/MultiOrder.qml - Dex/Exchange/Trade/OrderBook/Header.qml - Dex/Exchange/Trade/OrderBook/Horizontal.qml - Dex/Exchange/Trade/OrderBook/List.qml - Dex/Exchange/Trade/OrderBook/ListDelegate.qml - Dex/Exchange/Trade/OrderBook/Vertical.qml - Dex/Exchange/Trade/Orders/OrderContent.qml - Dex/Exchange/Trade/Orders/OrderLine.qml - Dex/Exchange/Trade/Orders/OrderList.qml - Dex/Exchange/Trade/Orders/OrderModal.qml - Dex/Exchange/Trade/Orders/OrdersPage.qml - Dex/Exchange/Trade/Orders/SwapProgress.qml - Dex/Exchange/Trade/PriceLine.qml - Dex/Exchange/Trade/PriceLineSimplified.qml - Dex/Exchange/Trade/ProView.qml - Dex/Exchange/Trade/SimpleView/List.qml - Dex/Exchange/Trade/SimpleView/Main.qml - Dex/Exchange/Trade/SimpleView/Main.js - Dex/Exchange/Trade/SimpleView/Trade.qml - Dex/Exchange/Trade/SimpleView/OrderRemovedModal.qml - Dex/Exchange/Trade/SimpleView/SubBestOrder.qml - Dex/Exchange/Trade/SimpleView/SubCoinSelector.qml - Dex/Exchange/Trade/SimpleView/SubOrders.qml - Dex/Exchange/Trade/SimpleView/SubHistory.qml - Dex/Exchange/Trade/SweetDexComboBox.qml - Dex/Exchange/Trade/TickerSelector.qml - Dex/Exchange/Trade/Trade.qml - Dex/Exchange/Trade/TradeBox/BuyBox.qml - Dex/Exchange/Trade/TradeBox/OrderForm.qml - Dex/Exchange/Trade/TradeBox/SellBox.qml - Dex/Exchange/Trade/Trading/Items/FeeInfo.qml - Dex/Exchange/Trade/Trading/Items/TotalView.qml - Dex/Exchange/Trade/Trading/TradeViewHeader.qml - Dex/Fiat/FiatRamp.qml - Dex/Graphics/Color.js - Dex/Graphics/qmldir - Dex/NoConnection.qml - Dex/Portfolio/Portfolio.qml - Dex/Screens/Dashboard.qml - Dex/Screens/qmldir - Dex/Screens/Startup/ImportWallet.qml - Dex/Screens/Startup/Logging.qml - Dex/Screens/Startup/Login.qml - Dex/Screens/Startup/Main.qml - Dex/Screens/Startup/NewWallet.qml - Dex/Screens/Startup/WalletsView.qml - Dex/Settings/AddCustomCoinModal.qml - Dex/Settings/CamouflagePasswordModal.qml - Dex/Settings/Combo_fiat.qml - Dex/Settings/DeleteWalletModal.qml - Dex/Settings/Languages.qml - Dex/Settings/RecoverSeedModal.qml - Dex/Settings/SettingsButton.qml - Dex/Settings/SettingModal.qml - Dex/Settings/Settings.qml - Dex/Sidebar/Bottom.qml - Dex/Sidebar/Center.qml - Dex/Sidebar/FigurativeLine.qml - Dex/Sidebar/Line.qml - Dex/Sidebar/Main.qml - Dex/Sidebar/qmldir - Dex/Sidebar/Top.qml - Dex/Support/FAQLine.qml - Dex/Support/Support.qml - Dex/Themes/CurrentTheme.qml - Dex/Themes/DefaultTheme.js - Dex/Themes/qmldir - Dex/Themes/ThemeData.qml - Dex/Wallet/AddressBook.qml - Dex/Wallet/AddressBookAddContactAddressModal.qml - Dex/Wallet/AddressBookEditContactModal.qml - Dex/Wallet/AddressBookNewContactCategoryModal.qml - Dex/Wallet/AddressBookNewContactModal.qml - Dex/Wallet/AddressBookSendWalletSelector.qml - Dex/Wallet/AddressBookWalletTypeList.qml - Dex/Wallet/AddressBookWalletTypeListModal.qml - Dex/Wallet/AddressBookWalletTypeListRow.qml - Dex/Wallet/AddressList.qml - Dex/Wallet/ClaimFaucetResultModal.qml - Dex/Wallet/ClaimRewardsModal.qml - Dex/Wallet/EnableCoinModal.qml - Dex/Wallet/Main.qml - Dex/Wallet/ReceiveModal.qml - Dex/Wallet/SendModal.qml - Dex/Wallet/SendModalContactList.qml - Dex/Wallet/SendResult.qml - Dex/Wallet/Sidebar.qml - Dex/Wallet/SidebarItemDelegate.qml - Dex/Wallet/TransactionDetailsModal.qml - Dex/Wallet/Transactions.qml - Dex/Wallet/Wallet.qml - Dex/Portfolio/AmountChart.qml - Dex/Portfolio/AssetPieChart.qml - Dex/Portfolio/PieItem.qml - Dex/Portfolio/SmartChartView.qml - Dex/Portfolio/AssetsList.qml - Dex/main.qml - qtquickcontrols2.conf - Dex/Components/PopupManager.qml - - diff --git a/ci_tools_atomic_dex/ci_scripts/osx_script.sh b/ci_tools_atomic_dex/ci_scripts/osx_script.sh index 77d1c23a23..949442963e 100755 --- a/ci_tools_atomic_dex/ci_scripts/osx_script.sh +++ b/ci_tools_atomic_dex/ci_scripts/osx_script.sh @@ -1,8 +1,6 @@ #!/bin/bash brew update -brew tap-new $USER/local-nim -brew extract --version=1.4.8 nim $USER/local-nim brew unlink libtool wget https://raw.githubusercontent.com/Homebrew/homebrew-core/0fbd6e24c4122e18ade1ec6c5916cb21de14f352/Formula/libtool.rb @@ -12,7 +10,7 @@ brew install autoconf \ automake \ pkgconfig \ wget \ - nim@1.4.8 \ + nim \ ninja \ gnu-sed \ coreutils \ @@ -22,7 +20,7 @@ brew install autoconf \ pip3 install yq export CC=clang export CXX=clang++ -export MACOSX_DEPLOYMENT_TARGET=10.14 +export MACOSX_DEPLOYMENT_TARGET=10.15 # get curl #git clone https://github.com/KomodoPlatform/curl.git diff --git a/ci_tools_atomic_dex/ci_scripts/windows_script.ps1 b/ci_tools_atomic_dex/ci_scripts/windows_script.ps1 index f82af5a3db..c3b07f0f79 100644 --- a/ci_tools_atomic_dex/ci_scripts/windows_script.ps1 +++ b/ci_tools_atomic_dex/ci_scripts/windows_script.ps1 @@ -14,9 +14,16 @@ scoop cache rm git scoop cache rm cmake scoop cache rm ninja scoop cache rm llvm + $Env:QT_INSTALL_CMAKE_PATH = "C:\Qt\$Env:QT_VERSION\msvc2019_64" $Env:QT_ROOT = "C:\Qt" + +git clone https://github.com/KomodoPlatform/coins/ -b master +mkdir -p atomic_defi_design\assets\images\coins +Get-Item -Path "coins\icons\*.png" | Move-Item -Destination "atomic_defi_design\assets\images\coins" + mkdir build cd build -cmake -DCMAKE_BUILD_TYPE=Release -GNinja ../ + +cmake -DCMAKE_BUILD_TYPE="$Env:CMAKE_BUILD_TYPE" -GNinja ../ ninja install diff --git a/ci_tools_atomic_dex/installer/osx/config/config.xml.in b/ci_tools_atomic_dex/installer/osx/config/config.xml.in index 94ce96cd9b..7b601889c4 100644 --- a/ci_tools_atomic_dex/installer/osx/config/config.xml.in +++ b/ci_tools_atomic_dex/installer/osx/config/config.xml.in @@ -1,7 +1,7 @@ ${DEX_DISPLAY_NAME} - 0.5.5 + 0.5.7 ${DEX_DISPLAY_NAME} Installer ${DEX_WEBSITE} ${DEX_COMPANY} diff --git a/ci_tools_atomic_dex/installer/osx/packages/com.komodoplatform.atomicdex/meta/package.xml.in b/ci_tools_atomic_dex/installer/osx/packages/com.komodoplatform.atomicdex/meta/package.xml.in index 0f4899f2c3..06109f6ba9 100644 --- a/ci_tools_atomic_dex/installer/osx/packages/com.komodoplatform.atomicdex/meta/package.xml.in +++ b/ci_tools_atomic_dex/installer/osx/packages/com.komodoplatform.atomicdex/meta/package.xml.in @@ -2,8 +2,8 @@ ${DEX_DISPLAY_NAME} Install ${DEX_DISPLAY_NAME}. - 0.5.5 - 2021-12-06 + 0.5.7 + 2022-11-09 diff --git a/ci_tools_atomic_dex/installer/windows/config/config.xml.in b/ci_tools_atomic_dex/installer/windows/config/config.xml.in index 8b2c1c44d6..9fe11ef931 100644 --- a/ci_tools_atomic_dex/installer/windows/config/config.xml.in +++ b/ci_tools_atomic_dex/installer/windows/config/config.xml.in @@ -1,12 +1,12 @@ @DEX_DISPLAY_NAME@ - 0.5.5 + 0.5.7 @DEX_DISPLAY_NAME@ Installer @DEX_WEBSITE@ @DEX_COMPANY@ @DEX_INSTALL_TARGET_DIR_WIN64@/@DEX_DISPLAY_NAME@ - @DEX_TARGET_DIR@/@DEX_PROJECT_NAME@.exe + @DEX_TARGET_DIR@/bin/@DEX_PROJECT_NAME@.exe Run @DEX_DISPLAY_NAME@ now. @DEX_DISPLAY_NAME@ @DEX_MAINTENANCE_TOOL_NAME@ diff --git a/ci_tools_atomic_dex/installer/windows/packages/com.komodoplatform.atomicdex/meta/installscript.qs.in b/ci_tools_atomic_dex/installer/windows/packages/com.komodoplatform.atomicdex/meta/installscript.qs.in index cc11201d0d..204713cb6d 100644 --- a/ci_tools_atomic_dex/installer/windows/packages/com.komodoplatform.atomicdex/meta/installscript.qs.in +++ b/ci_tools_atomic_dex/installer/windows/packages/com.komodoplatform.atomicdex/meta/installscript.qs.in @@ -10,17 +10,17 @@ Component.prototype.createOperations = function() if (installer.value("os") === "win") { // Start Menu Shortcut component.addOperation("CreateShortcut", - "@DEX_TARGET_DIR@/@DEX_PROJECT_NAME@.exe", + "@DEX_TARGET_DIR@/bin/@DEX_PROJECT_NAME@.exe", "@DEX_START_MENU_DIR@/@DEX_DISPLAY_NAME@.lnk", - "workingDirectory=@DEX_TARGET_DIR@", + "workingDirectory=@DEX_TARGET_DIR@/bin", "iconPath=@DEX_ICON_DIR@", "iconId=0", "description=Start @DEX_DISPLAY_NAME@"); // Desktop Shortcut component.addOperation("CreateShortcut", - "@DEX_TARGET_DIR@/@DEX_PROJECT_NAME@.exe", + "@DEX_TARGET_DIR@/bin/@DEX_PROJECT_NAME@.exe", "@DEX_DESKTOP_DIR@/@DEX_DISPLAY_NAME@.lnk", - "workingDirectory=@DEX_TARGET_DIR@", + "workingDirectory=@DEX_TARGET_DIR@/bin", "iconPath=@DEX_ICON_DIR@", "iconId=0", "description=Start @DEX_DISPLAY_NAME@"); diff --git a/ci_tools_atomic_dex/installer/windows/packages/com.komodoplatform.atomicdex/meta/package.xml.in b/ci_tools_atomic_dex/installer/windows/packages/com.komodoplatform.atomicdex/meta/package.xml.in index 0f4899f2c3..1a0b0bc1c3 100644 --- a/ci_tools_atomic_dex/installer/windows/packages/com.komodoplatform.atomicdex/meta/package.xml.in +++ b/ci_tools_atomic_dex/installer/windows/packages/com.komodoplatform.atomicdex/meta/package.xml.in @@ -2,8 +2,8 @@ ${DEX_DISPLAY_NAME} Install ${DEX_DISPLAY_NAME}. - 0.5.5 - 2021-12-06 + 0.5.7 + 2022-10-24 diff --git a/ci_tools_atomic_dex/src/ci_tools_atomic_dex.nim b/ci_tools_atomic_dex/src/ci_tools_atomic_dex.nim index feb24df7e3..ab8425ffa5 100644 --- a/ci_tools_atomic_dex/src/ci_tools_atomic_dex.nim +++ b/ci_tools_atomic_dex/src/ci_tools_atomic_dex.nim @@ -16,11 +16,11 @@ Atomic Dex CI Tools. Usage: ci_tools_atomic_dex --install_vcpkg ci_tools_atomic_dex --install_dependencies - ci_tools_atomic_dex build (release|debug) [--osx_sdk=] [--compiler=] + ci_tools_atomic_dex build (Release|Debug) [--osx_sdk=] [--compiler=] ci_tools_atomic_dex clean (full|dependencies|build_dir) - ci_tools_atomic_dex generate (release|debug) [--osx_sdk=] [--compiler=] - ci_tools_atomic_dex bundle (release|debug) [--osx_sdk=] [--compiler=] - ci_tools_atomic_dex tests (release|debug) [--osx_sdk=] [--compiler=] + ci_tools_atomic_dex generate (Release|Debug) [--osx_sdk=] [--compiler=] + ci_tools_atomic_dex bundle (Release|Debug) [--osx_sdk=] [--compiler=] + ci_tools_atomic_dex tests (Release|Debug) [--osx_sdk=] [--compiler=] ci_tools_atomic_dex --version ci_tools_atomic_dex (-h | --help) @@ -32,30 +32,37 @@ Options: proc main() = let args = docopt(doc, version = "Atomic Dex CI Tools 0.0.1") vcpkg_prepare() + if args["--install_vcpkg"]: install_vcpkg() + elif args["--install_dependencies"]: download_packages() + elif args["generate"]: - if args["release"]: + if args["Release"]: generate_solution("Release", $args["--osx_sdk"], $args["--compiler"]) - elif args["debug"]: + elif args["Debug"]: generate_solution("Debug", $args["--osx_sdk"], $args["--compiler"]) + elif args["build"]: - if args["release"]: + if args["Release"]: build_atomic_qt("Release", $args["--osx_sdk"], $args["--compiler"]) - elif args["debug"]: + elif args["Debug"]: build_atomic_qt("Debug", $args["--osx_sdk"], $args["--compiler"]) + elif args["bundle"]: - if args["release"]: + if args["Release"]: bundle("Release", $args["--osx_sdk"], $args["--compiler"]) - elif args["debug"]: + elif args["Debug"]: bundle("Debug", $args["--osx_sdk"], $args["--compiler"]) + elif args["tests"]: - if args["release"]: + if args["Release"]: run_tests("Release", $args["--osx_sdk"], $args["--compiler"]) - elif args["debug"]: + elif args["Debug"]: run_tests("Debug", $args["--osx_sdk"], $args["--compiler"]) + elif args["clean"]: if args["full"]: clean("full") diff --git a/ci_tools_atomic_dex/src/clean.nim b/ci_tools_atomic_dex/src/clean.nim index a84a1ad28d..888368a376 100644 --- a/ci_tools_atomic_dex/src/clean.nim +++ b/ci_tools_atomic_dex/src/clean.nim @@ -1,13 +1,13 @@ import os proc remove_vcpkg()= - if os.existsDir("vcpkg-repo"): + if os.dirExists("vcpkg-repo"): os.removeDir("vcpkg-repo") proc remove_build()= - if os.existsDir("build-Debug"): + if os.dirExists("build-Debug"): os.removeDir("build-Debug") - if os.existsDir("build-Release"): + if os.dirExists("build-Release"): os.removeDir("build-Release") proc clean*(clean_type: string) = diff --git a/ci_tools_atomic_dex/src/generate.nim b/ci_tools_atomic_dex/src/generate.nim index 22cbb68233..d53b6a1ff8 100644 --- a/ci_tools_atomic_dex/src/generate.nim +++ b/ci_tools_atomic_dex/src/generate.nim @@ -6,7 +6,7 @@ import dependencies proc generate_solution*(build_type: string, osx_sdk_path: string, compiler_path: string) = download_packages() var full_name = "build-" & build_type - if not os.existsDir(os.getCurrentDir().joinPath(full_name)): + if not os.dirExists(os.getCurrentDir().joinPath(full_name)): echo "creating directory: " & full_name os.createDir(full_name) else: @@ -16,7 +16,7 @@ proc generate_solution*(build_type: string, osx_sdk_path: string, compiler_path: var cmd_line = "cmake -GNinja -DCMAKE_BUILD_TYPE=" & build_type & " " & os.getCurrentDir().parentDir().parentDir() when defined(osx): - if not osx_sdk_path.isNil() and osx_sdk_path != "nil": - cmd_line = cmd_line & " -DCMAKE_OSX_SYSROOT=" & osx_sdk_path & " -DCMAKE_OSX_DEPLOYMENT_TARGET=10.14 -DPREFER_BOOST_FILESYSTEM=ON" + if os.dirExists(osx_sdk_path): + cmd_line = cmd_line & " -DCMAKE_OSX_SYSROOT=" & osx_sdk_path & " -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15" echo "cmd line: " & cmd_line discard execCmd(cmd_line) diff --git a/ci_tools_atomic_dex/src/tests.nim b/ci_tools_atomic_dex/src/tests.nim index 0b8240610a..78ee2980ff 100644 --- a/ci_tools_atomic_dex/src/tests.nim +++ b/ci_tools_atomic_dex/src/tests.nim @@ -12,8 +12,26 @@ proc run_tests*(build_type: string, osx_sdk_path: string, compiler_path: string) generate_solution(build_type, osx_sdk_path, compiler_path) when defined(osx): + echo "CURRENT OSX FOLDER" echo os.getCurrentDir() - os.setCurrentDir(os.getCurrentDir().joinPath("bin").joinPath(os.getEnv("DEX_PROJECT_NAME") & "_tests.app").joinPath("Contents").joinPath("MacOS")) + discard osproc.execCmd("ls") + os.setCurrentDir(os.getCurrentDir().joinPath("bin")) + echo "CURRENT OSX FOLDER" + echo os.getCurrentDir() + discard osproc.execCmd("ls") + os.setCurrentDir(os.getCurrentDir().joinPath(os.getEnv("DEX_PROJECT_NAME") & "_tests.app")) + echo "CURRENT OSX FOLDER" + echo os.getCurrentDir() + discard osproc.execCmd("ls") + os.setCurrentDir(os.getCurrentDir().joinPath("Contents")) + echo "CURRENT OSX FOLDER" + echo os.getCurrentDir() + discard osproc.execCmd("ls") + os.setCurrentDir(os.getCurrentDir().joinPath("MacOS")) + echo "CURRENT OSX FOLDER" + echo os.getCurrentDir() + discard osproc.execCmd("ls") + # os.setCurrentDir(os.getCurrentDir().joinPath("bin").joinPath(os.getEnv("DEX_PROJECT_NAME") & "_tests.app").joinPath("Contents").joinPath("MacOS")) echo "Running AtomicDex Pro Unit tests" discard osproc.execCmd("./" & os.getEnv("DEX_PROJECT_NAME") & "_tests --reporters=xml --out=" & os.getEnv("DEX_PROJECT_NAME") & "-tests-result.xml -s") echo "Successfully Generated", os.getEnv("DEX_PROJECT_NAME"), "-tests-result.xml" diff --git a/ci_tools_atomic_dex/src/vcpkg.nim b/ci_tools_atomic_dex/src/vcpkg.nim index c679f29a8e..fca94fc080 100644 --- a/ci_tools_atomic_dex/src/vcpkg.nim +++ b/ci_tools_atomic_dex/src/vcpkg.nim @@ -5,10 +5,10 @@ var g_vcpkg_local_path* = "" var g_vcpkg_cmake_script_path* = "" proc check_if_vcpkg_exists*(): bool = - result = os.existsDir("vcpkg-repo") + result = os.dirExists("vcpkg-repo") proc build_vcpkg() = - if not os.existsFile(g_vcpkg_local_path): + if not os.fileExists(g_vcpkg_local_path): echo "building vcpkg" os.setCurrentDir("vcpkg-repo") when defined(windows): diff --git a/ci_tools_atomic_dex/util/compare_themes.py b/ci_tools_atomic_dex/util/compare_themes.py new file mode 100755 index 0000000000..40b5f097cd --- /dev/null +++ b/ci_tools_atomic_dex/util/compare_themes.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +import json +import requests + +''' +Purpose: Scans the light and dark theme json files for a list of whitelabel + branches, and compares them with the dev branch to identify theme + selectors which are obsolete or not present in the whitelabel branch. + +Usage: `./compare_themes.py` +''' + +REPO_URL = "https://raw.githubusercontent.com/KomodoPlatform/atomicDEX-Desktop" +BRANCHES = ['smartdex', 'GleecDEX', 'shibadex'] + + +def get_theme_url(branch, theme): + '''Returns a github url for a branch theme.''' + path = f"assets/themes/Default%20-%20{theme.title()}" + return f"{REPO_URL}/{branch}/{path}/colors.json" + + +def get_themes_data(branches): + '''Returns a dict of dark/light theme data for each branch.''' + themes = {} + for branch in branches+['dev']: + themes.update({branch: {}}) + for theme in ['light', 'dark']: + url = get_theme_url(branch, theme) + themes[branch].update({ + theme: requests.get(url).json() + }) + return themes + + +def get_selectors(themes, branch='dev'): + '''Returns a list of selectors within each theme for a branch.''' + return { + 'light': set(themes[branch]['light'].keys()), + 'dark': set(themes[branch]['dark'].keys()) + } + + +def compare_branch_themes(branches, show_results=True): + '''Scans whitelabel theme data to identify missing/obsolete selectors.''' + themes = get_themes_data(branches) + dev_selectors = get_selectors(themes, 'dev') + + for branch in branches: + for theme in ['light', 'dark']: + selectors = set(themes[branch][theme].keys()) + missing = dev_selectors[theme].difference(selectors) + themes[branch].update({ + f"missing_{theme}": missing, + f"obsolete_{theme}": selectors.difference(dev_selectors[theme]) + }) + if show_results: + output_results(themes, branch, theme) + + +def output_results(themes, branch, theme): + '''Outputs results for a branch to the console.''' + print(f"\n#### {branch} {theme} ####") + if len(themes[branch][f"obsolete_{theme}"]) == 0: + print(f"No obsolete selectors") + else: + for i in themes[branch][f"obsolete_{theme}"]: + print(f"Obsolete selector: {i}...") + + if len(themes[branch][f"missing_{theme}"]) == 0: + print(f"No obsolete selectors") + else: + for i in themes[branch][f"missing_{theme}"]: + dev_color = themes['dev'][theme][i] + for j in themes['dev'][theme]: + if dev_color == themes['dev'][theme][j]: + if j in themes[branch][theme]: + print(f"Missing {i}... Try {themes[branch][theme][j]}") + break + + +if __name__ == '__main__': + compare_branch_themes(BRANCHES, True) diff --git a/ci_tools_atomic_dex/vcpkg-custom-ports b/ci_tools_atomic_dex/vcpkg-custom-ports index 15ad59b292..f20c053d1b 160000 --- a/ci_tools_atomic_dex/vcpkg-custom-ports +++ b/ci_tools_atomic_dex/vcpkg-custom-ports @@ -1 +1 @@ -Subproject commit 15ad59b2928caaaac104702ee5b46d0ae5c3da71 +Subproject commit f20c053d1b47957af9c50aa34be45c69dfdcc1a4 diff --git a/cmake/compiler_prerequisites.cmake b/cmake/compiler_prerequisites.cmake index 41579fed1f..847dc1a911 100644 --- a/cmake/compiler_prerequisites.cmake +++ b/cmake/compiler_prerequisites.cmake @@ -7,14 +7,4 @@ endif () if (WIN32) add_definitions(-D_CRT_SECURE_NO_WARNINGS) -endif () - -if (PREFER_BOOST_FILESYSTEM) - message(STATUS "Boost filesystem over std::filesystem") - add_compile_definitions(PREFER_BOOST_FILESYSTEM) -endif () - -#if (PREFER_BOOST_OPTIONAL) -# message(STATUS "Boost optional over std::optional") -# add_compile_definitions(PREFER_BOOST_OPTIONAL) -#endif() \ No newline at end of file +endif () \ No newline at end of file diff --git a/cmake/compiler_targets.cmake b/cmake/compiler_targets.cmake index 2793d91d09..ecbe4a273b 100644 --- a/cmake/compiler_targets.cmake +++ b/cmake/compiler_targets.cmake @@ -52,7 +52,7 @@ target_compile_definitions(antara_optimize_settings INTERFACE $<$,$,$>:NDEBUG> $<$,$,$>:DEBUG> $<$,$,$>:NDEBUG> - $<$,$,$>:-DEBUG> + $<$,$,$>:DEBUG> $<$,$,$>:NDEBUG> $<$,$,$>:DEBUG> ) diff --git a/cmake/dex_generate_qrc.cmake b/cmake/dex_generate_qrc.cmake new file mode 100644 index 0000000000..e242abb7d3 --- /dev/null +++ b/cmake/dex_generate_qrc.cmake @@ -0,0 +1,40 @@ +function(dex_generate_qrc directory output) + cmake_parse_arguments( + GENERATE_QRC + "" + "PATH_PREFIX" + "FILES_TO_EXCLUDE;FILES" + ${ARGN} + ) + + set(resources) + file(GLOB_RECURSE resources ${directory}/* ${directory}/*/*) + + file(WRITE ${directory}/qml.qrc "\n") + file(APPEND ${directory}/qml.qrc " \n") + foreach(res ${resources}) + set(excluded FALSE) + foreach(file_to_exclude ${GENERATE_QRC_FILES_TO_EXCLUDE}) + set(find_res) + string(FIND ${res} ${file_to_exclude} find_res) + if (${find_res} GREATER -1) + set(excluded TRUE) + break() + endif () + endforeach() + if (excluded) + continue() + endif () + string(REPLACE ${directory}/ "" res ${res}) + file(APPEND ${directory}/qml.qrc " ${res}\n") + endforeach() + foreach(res ${GENERATE_QRC_FILES}) + string(REPLACE ${directory}/ "" res ${res}) + file(APPEND ${directory}/qml.qrc " ${res}\n") + endforeach() + file(APPEND ${directory}/qml.qrc " \n") + file(APPEND ${directory}/qml.qrc "\n") + + set(${output} ${directory}/qml.qrc PARENT_SCOPE) + +endfunction() \ No newline at end of file diff --git a/cmake/install/linux/linux_post_install.cmake b/cmake/install/linux/linux_post_install.cmake index e0b7c1690a..23eae65e00 100644 --- a/cmake/install/linux/linux_post_install.cmake +++ b/cmake/install/linux/linux_post_install.cmake @@ -5,20 +5,26 @@ execute_process(COMMAND bash -c "echo -n `git rev-parse --short HEAD`" OUTPUT_VARIABLE VERSION_ID ) +message(STATUS "PROJECT_ROOT_DIR (before readjusting) -> ${PROJECT_ROOT_DIR}") + get_filename_component(PROJECT_ROOT_DIR ${CMAKE_SOURCE_DIR} DIRECTORY) -if (EXISTS ${PROJECT_ROOT_DIR}/build-Release) +if (EXISTS ${PROJECT_ROOT_DIR}/build-Release OR EXISTS ${PROJECT_ROOT_DIR}/build-Debug) message(STATUS "from ci tools, readjusting") get_filename_component(PROJECT_ROOT_DIR ${PROJECT_ROOT_DIR} DIRECTORY) endif () -message(STATUS "PROJECT_ROOT_DIR -> ${PROJECT_ROOT_DIR}") set(PROJECT_QML_DIR ${PROJECT_ROOT_DIR}/atomic_defi_design/Dex) -message(STATUS "PROJECT_QML_DIR -> ${PROJECT_QML_DIR}") set(PROJECT_APP_DIR AntaraAtomicDexAppDir) set(PROJECT_APP_PATH ${CMAKE_SOURCE_DIR}/bin/${PROJECT_APP_DIR}) set(PROJECT_BIN_PATH ${PROJECT_APP_PATH}/usr/bin/${DEX_PROJECT_NAME}) set(PROJECT_LIB_PATH ${PROJECT_APP_PATH}/usr/lib) set(TARGET_APP_PATH ${PROJECT_ROOT_DIR}/bundled/linux) + +message(STATUS "VCPKG package manager enabled") +message(STATUS "PROJECT_ROOT_DIR (after readjusting) -> ${PROJECT_ROOT_DIR}") +message(STATUS "PROJECT_QML_DIR -> ${PROJECT_QML_DIR}") +message(STATUS "VERSION_ID -> ${VERSION_ID}") + if (EXISTS ${PROJECT_APP_PATH}) message(STATUS "PROJECT_APP_PATH path is -> ${PROJECT_APP_PATH}") message(STATUS "PROJECT_BIN_PATH path is -> ${PROJECT_BIN_PATH}") @@ -28,16 +34,13 @@ else () message(FATAL_ERROR "Didn't find ${PROJECT_APP_PATH}") endif () -message(STATUS "VCPKG package manager enabled") set(LINUX_DEPLOY_PATH ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/linux_misc/linuxdeployqt-7-x86_64.AppImage) - if (EXISTS ${LINUX_DEPLOY_PATH}) message(STATUS "linuxdeployqt path is -> ${LINUX_DEPLOY_PATH}") else () message(FATAL_ERROR "Didn't find ${LINUX_DEPLOY_PATH}") endif () - message(STATUS "Copying required libraries for QtWebEngine") list(APPEND LIST_LIBS "/usr/lib/x86_64-linux-gnu/libsmime3.so" @@ -49,26 +52,35 @@ list(APPEND LIST_LIBS "/usr/lib/x86_64-linux-gnu/nss/libnssdbm3.so" "/usr/lib/x86_64-linux-gnu/nss/libsoftokn3.chk" "/usr/lib/x86_64-linux-gnu/nss/libsoftokn3.so") + file(COPY ${PROJECT_APP_PATH}/usr/share/icons/default/64x64/apps/dex-logo-64.png DESTINATION ${PROJECT_APP_PATH}) file(COPY ${PROJECT_APP_PATH}/usr/share/applications/dex.desktop DESTINATION ${PROJECT_APP_PATH}) + foreach (current_lib ${LIST_LIBS}) message(STATUS "copying ${current_lib} to ${PROJECT_LIB_PATH}") file(COPY ${current_lib} DESTINATION ${PROJECT_LIB_PATH}) endforeach () + message(STATUS "Executing linuxdeployqt to fix dependencies") -message(STATUS "Executing cmd: [${LINUX_DEPLOY_PATH} ${PROJECT_BIN_PATH} -qmldir=${PROJECT_QML_DIR} -bundle-non-qt-libs -exclude-libs="libnss3.so,libnssutil3.so" -unsupported-allow-new-glibc -no-copy-copyright-files -verbose=1 -extra-plugins=iconengines,platformthemes/libqgtk3.so -appimage]") -execute_process(COMMAND ${LINUX_DEPLOY_PATH} ${PROJECT_BIN_PATH} -qmldir=${PROJECT_QML_DIR} -bundle-non-qt-libs -exclude-libs="libnss3.so,libnssutil3.so" -unsupported-allow-new-glibc -no-copy-copyright-files -verbose=1 -extra-plugins=iconengines,platformthemes/libqgtk3.so -appimage +message(STATUS "Executing cmd: [${LINUX_DEPLOY_PATH} ${PROJECT_BIN_PATH} -qmldir=${PROJECT_QML_DIR} -bundle-non-qt-libs -exclude-libs='libnss3.so,libnssutil3.so' -unsupported-allow-new-glibc -no-copy-copyright-files -verbose=1 -extra-plugins=iconengines,platformthemes/libqgtk3.so -appimage]") +execute_process(COMMAND ${LINUX_DEPLOY_PATH} ${PROJECT_BIN_PATH} -qmldir=${PROJECT_QML_DIR} -bundle-non-qt-libs -exclude-libs='libnss3.so,libnssutil3.so' -unsupported-allow-new-glibc -no-copy-copyright-files -verbose=1 -extra-plugins=iconengines,platformthemes/libqgtk3.so -appimage WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE) + +message(STATUS "Renaming ${CMAKE_SOURCE_DIR}/${DEX_PROJECT_NAME}-${VERSION_ID}-x86_64.AppImage to ${CMAKE_SOURCE_DIR}/${DEX_PROJECT_NAME}-linux-${VERSION_ID}-x86_64.AppImage") +file(RENAME ${CMAKE_SOURCE_DIR}/${DEX_PROJECT_NAME}-${VERSION_ID}-x86_64.AppImage ${CMAKE_SOURCE_DIR}/${DEX_PROJECT_NAME}-linux-${VERSION_ID}-x86_64.AppImage) + message(STATUS "Copying ${PROJECT_APP_PATH} to ${TARGET_APP_PATH}/${PROJECT_APP_DIR}") file(COPY ${PROJECT_APP_PATH} DESTINATION ${TARGET_APP_PATH}) execute_process(COMMAND zip -r ${DEX_PROJECT_NAME}-linux-${VERSION_ID}.zip AntaraAtomicDexAppDir WORKING_DIRECTORY ${TARGET_APP_PATH} ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE) + execute_process(COMMAND tar --zstd -cf ${DEX_PROJECT_NAME}-linux-${VERSION_ID}.tar.zst AntaraAtomicDexAppDir WORKING_DIRECTORY ${TARGET_APP_PATH} ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE) -file(COPY ${CMAKE_SOURCE_DIR}/${DEX_PROJECT_NAME}-${VERSION_ID}-x86_64.AppImage DESTINATION ${TARGET_APP_PATH}) \ No newline at end of file + +file(COPY ${CMAKE_SOURCE_DIR}/${DEX_PROJECT_NAME}-linux-${VERSION_ID}-x86_64.AppImage DESTINATION ${TARGET_APP_PATH}) diff --git a/cmake/install/macos/dex_install.cmake b/cmake/install/macos/dex_install.cmake index 158c4f73aa..c472d7684d 100644 --- a/cmake/install/macos/dex_install.cmake +++ b/cmake/install/macos/dex_install.cmake @@ -4,8 +4,8 @@ if (APPLE) MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_NAME}" RESOURCE ${ICON} MACOSX_BUNDLE_ICON_FILE dex-logo - MACOSX_BUNDLE_SHORT_VERSION_STRING 0.5.5 - MACOSX_BUNDLE_LONG_VERSION_STRING 0.5.5 + MACOSX_BUNDLE_SHORT_VERSION_STRING 0.5.7 + MACOSX_BUNDLE_LONG_VERSION_STRING 0.5.7 MACOSX_BUNDLE_INFO_PLIST "${PROJECT_SOURCE_DIR}/cmake/MacOSXBundleInfo.plist.in") add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND diff --git a/cmake/install/macos/macos_notarize.sh b/cmake/install/macos/macos_notarize.sh index 0b68c86797..4413004d0a 100755 --- a/cmake/install/macos/macos_notarize.sh +++ b/cmake/install/macos/macos_notarize.sh @@ -20,7 +20,7 @@ if ! command -v xq >/dev/null ; then fi OPTS=-h -LONGOPTS=app-specific-password:,apple-id:,primary-bundle-id:,target-binary:,help +LONGOPTS=app-specific-password:,apple-id:,primary-bundle-id:,target-binary:,asc-public-id:,help ! PARSED=$(getopt --options=$OPTS --longoptions=$LONGOPTS --name "$0" -- "$@" ) if [[ ${PIPESTATUS[0]} -ne 0 ]]; then @@ -51,6 +51,10 @@ while true; do TARGET_BINARY=$2 shift 2 ;; + --asc-public-id) + ASC_PUBLIC_ID=$2 + shift 2 + ;; -h|--help) echo "Usage: $0 --app-specific-password= --apple-id= --primary-bundle-id= --target-binary=" echo "Example: $0 --app-specific-password=\$DDEV_MACOS_APP_PASSWORD --apple-id=accounts@drud.com --primary-bundle-id=com.ddev.ddev --target-binary=.gotmp/bin/darwin_amd64/ddev" @@ -72,7 +76,7 @@ fi echo "before xcrun" # Submit the zipball and get REQUEST_UUID -SUBMISSION_INFO=$(xcrun altool --notarize-app --primary-bundle-id=${PRIMARY_BUNDLE_ID} -u ${APPLE_ID} -p ${APP_SPECIFIC_PASSWORD} --file ${TARGET_BINARY}.zip 2>&1) ; +SUBMISSION_INFO=$(xcrun altool --notarize-app --primary-bundle-id=${PRIMARY_BUNDLE_ID} --asc-public-id=${ASC_PUBLIC_ID} -u ${APPLE_ID} -p ${APP_SPECIFIC_PASSWORD} --file ${TARGET_BINARY}.zip) ; if [ $? != 0 ]; then printf "Submission failed: $SUBMISSION_INFO \n" diff --git a/cmake/install/macos/osx_post_install.cmake b/cmake/install/macos/osx_post_install.cmake index b01cc75062..bd42ae336c 100644 --- a/cmake/install/macos/osx_post_install.cmake +++ b/cmake/install/macos/osx_post_install.cmake @@ -1,38 +1,43 @@ include(${CMAKE_CURRENT_LIST_DIR}/../../project.metadata.cmake) +message(STATUS "OSX POST INSTALL CMAKE") +message(STATUS "PROJECT_ROOT_DIR (before readjusting) -> ${PROJECT_ROOT_DIR}") + get_filename_component(PROJECT_ROOT_DIR ${CMAKE_SOURCE_DIR} DIRECTORY) if (EXISTS ${PROJECT_ROOT_DIR}/build-Release OR EXISTS ${PROJECT_ROOT_DIR}/build-Debug) message(STATUS "from ci tools, readjusting") get_filename_component(PROJECT_ROOT_DIR ${PROJECT_ROOT_DIR} DIRECTORY) endif () -message(STATUS "PROJECT_ROOT_DIR -> ${PROJECT_ROOT_DIR}") -set(PROJECT_QML_DIR ${PROJECT_ROOT_DIR}/atomic_defi_design/Dex) -message(STATUS "PROJECT_QML_DIR -> ${PROJECT_QML_DIR}") -message(STATUS "bin dir -> ${CMAKE_CURRENT_SOURCE_DIR}/bin") +set(BIN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/bin) set(TARGET_APP_PATH ${PROJECT_ROOT_DIR}/bundled/osx/) set(PROJECT_APP_DIR ${DEX_PROJECT_NAME}.app) -set(PROJECT_APP_PATH ${CMAKE_SOURCE_DIR}/bin/${PROJECT_APP_DIR}) -if (EXISTS ${PROJECT_APP_PATH}) - message(STATUS "PROJECT_APP_PATH path is -> ${PROJECT_APP_PATH}") -else () - message(FATAL_ERROR "Didn't find PROJECT_APP_PATH -> ${PROJECT_APP_PATH}") -endif () - +set(PROJECT_APP_PATH ${BIN_DIR}/${PROJECT_APP_DIR}) +set(PROJECT_QML_DIR ${PROJECT_ROOT_DIR}/atomic_defi_design/Dex) +set(MAC_DEPLOY_PATH $ENV{QT_ROOT}/clang_64/bin/macdeployqt) message(STATUS "VCPKG package manager enabled") +message(STATUS "QT_ROOT -> ${QT_ROOT}") +message(STATUS "BIN_DIR -> ${BIN_DIR}") +message(STATUS "TARGET_APP_PATH -> ${TARGET_APP_PATH}") +message(STATUS "PROJECT_APP_DIR -> ${PROJECT_APP_DIR}") +message(STATUS "PROJECT_QML_DIR -> ${PROJECT_QML_DIR}") +message(STATUS "PROJECT_ROOT_DIR (after readjusting) -> ${PROJECT_ROOT_DIR}") -message(STATUS "Using QT tools from $HOME/QT") -set(MAC_DEPLOY_PATH $ENV{QT_ROOT}/clang_64/bin/macdeployqt) +if (EXISTS ${PROJECT_APP_PATH}) + message(STATUS "PROJECT_APP_PATH -> ${PROJECT_APP_PATH}") +else () + message(FATAL_ERROR "Didn't find PROJECT_APP_PATH") +endif () if (EXISTS ${MAC_DEPLOY_PATH}) - message(STATUS "macdeployqt path is -> ${MAC_DEPLOY_PATH}") + message(STATUS "MAC_DEPLOY_PATH -> ${MAC_DEPLOY_PATH}") else () - message(FATAL_ERROR "Didn't find macdeployqt") + message(FATAL_ERROR "Didn't find MAC_DEPLOY_PATH") endif () +message(STATUS "CREATING DMG") if (NOT EXISTS ${CMAKE_SOURCE_DIR}/bin/${DEX_PROJECT_NAME}.dmg) - ##------------------------------------------- message(STATUS "${MAC_DEPLOY_PATH} ${PROJECT_APP_PATH} -qmldir=${PROJECT_QML_DIR} -always-overwrite -sign-for-notarization=$ENV{MAC_SIGN_IDENTITY} -verbose=3") execute_process( COMMAND @@ -41,9 +46,6 @@ if (NOT EXISTS ${CMAKE_SOURCE_DIR}/bin/${DEX_PROJECT_NAME}.dmg) ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE ) - ##------------------------------------------- - - ##------------------------------------------- message(STATUS "Fixing QTWebengineProcess") set(QTWEBENGINE_BUNDLED_PATH ${PROJECT_APP_PATH}/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app/Contents/MacOS/QtWebEngineProcess) message(STATUS "Executing: [install_name_tool -add_rpath @executable_path/../../../../../../Frameworks ${QTWEBENGINE_BUNDLED_PATH}]") @@ -52,7 +54,7 @@ if (NOT EXISTS ${CMAKE_SOURCE_DIR}/bin/${DEX_PROJECT_NAME}.dmg) ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE) - execute_process(COMMAND codesign --deep --force -v -s "$ENV{MAC_SIGN_IDENTITY}" -o runtime --timestamp ${PROJECT_APP_PATH}/Contents/Resources/assets/tools/mm2/mm2 + execute_process(COMMAND codesign --deep --force -v -s "$ENV{MAC_SIGN_IDENTITY}" -o runtime --timestamp ${PROJECT_APP_PATH}/Contents/Resources/assets/tools/mm2/${DEX_API} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE) @@ -68,7 +70,6 @@ if (NOT EXISTS ${CMAKE_SOURCE_DIR}/bin/${DEX_PROJECT_NAME}.dmg) ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE) - ##------------------------------------------- message(STATUS "Packaging the DMG") set(PACKAGER_PATH ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/dmg-packager/package.sh) if (EXISTS ${PACKAGER_PATH}) @@ -87,7 +88,7 @@ if (NOT EXISTS ${CMAKE_SOURCE_DIR}/bin/${DEX_PROJECT_NAME}.dmg) ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE) - execute_process(COMMAND ${PROJECT_ROOT_DIR}/cmake/install/macos/macos_notarize.sh --app-specific-password=$ENV{APPLE_ATOMICDEX_PASSWORD} --apple-id=$ENV{APPLE_ID} --primary-bundle-id=com.komodoplatform.atomicdex --target-binary=${CMAKE_SOURCE_DIR}/bin/${DEX_PROJECT_NAME}.dmg + execute_process(COMMAND ${PROJECT_ROOT_DIR}/cmake/install/macos/macos_notarize.sh --asc-public-id=$ENV{ASC_PUBLIC_ID} --app-specific-password=$ENV{APPLE_ATOMICDEX_PASSWORD} --apple-id=$ENV{APPLE_ID} --primary-bundle-id=com.komodoplatform.atomicdex --target-binary=${CMAKE_SOURCE_DIR}/bin/${DEX_PROJECT_NAME}.dmg WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE) @@ -97,13 +98,13 @@ endif () file(COPY ${CMAKE_SOURCE_DIR}/bin/${DEX_PROJECT_NAME}.dmg DESTINATION ${TARGET_APP_PATH}) -get_filename_component(QT_ROOT_DIR $ENV{QT_ROOT} DIRECTORY) -set(IFW_BINDIR ${QT_ROOT_DIR}/Tools/QtInstallerFramework/4.3/bin) +get_filename_component(QT_ROOT_DIR $ENV{QT_ROOT} DIRECTORY) +set(IFW_BINDIR ${QT_ROOT_DIR}/Tools/QtInstallerFramework/4.5/bin) message(STATUS "IFW_BIN PATH IS ${IFW_BINDIR}") if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/bin/${DEX_PROJECT_NAME}.7z) - message(STATUS "Generating ${DEX_PROJECT_NAME}.7z with [${IFW_BINDIR}/archivegen ${DEX_PROJECT_NAME}.7z ${DEX_PROJECT_NAME}.app] from directory: ${CMAKE_CURRENT_SOURCE_DIR}/bin") + message(STATUS "command is: [${IFW_BINDIR}/archivegen ${DEX_PROJECT_NAME}.7z ${PROJECT_APP_PATH} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin]") execute_process(COMMAND - ${IFW_BINDIR}/archivegen ${DEX_PROJECT_NAME}.7z ${DEX_PROJECT_NAME}.app + ${IFW_BINDIR}/archivegen ${DEX_PROJECT_NAME}.7z ${PROJECT_APP_PATH} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE) @@ -111,9 +112,11 @@ else() message(STATUS "${DEX_PROJECT_NAME}.7z already created - skipping") endif() +message(STATUS "Copying ${CMAKE_CURRENT_SOURCE_DIR}/bin/${DEX_PROJECT_NAME}.7z TO ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/osx/packages/com.komodoplatform.atomicdex/data") + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/bin/${DEX_PROJECT_NAME}.7z DESTINATION ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/osx/packages/com.komodoplatform.atomicdex/data) -execute_process(COMMAND ${IFW_BINDIR}/binarycreator -c ./config/config.xml -p ./packages/ ${DEX_PROJECT_NAME}_installer -s $ENV{MAC_SIGN_IDENTITY} +execute_process(COMMAND ${IFW_BINDIR}/binarycreator -c ./config/config.xml -p ./packages/ ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/osx/${DEX_PROJECT_NAME}_installer -s $ENV{MAC_SIGN_IDENTITY} WORKING_DIRECTORY ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/osx ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE) @@ -123,14 +126,17 @@ execute_process(COMMAND codesign --deep --force -v -s "$ENV{MAC_SIGN_IDENTITY}" ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE) -execute_process(COMMAND ${PROJECT_ROOT_DIR}/cmake/install/macos/macos_notarize.sh --app-specific-password=$ENV{APPLE_ATOMICDEX_PASSWORD} --apple-id=$ENV{APPLE_ID} --primary-bundle-id=com.komodoplatform.atomicdex --target-binary=${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/osx/${DEX_PROJECT_NAME}_installer.app +execute_process(COMMAND ${PROJECT_ROOT_DIR}/cmake/install/macos/macos_notarize.sh --asc-public-id=$ENV{ASC_PUBLIC_ID} --app-specific-password=$ENV{APPLE_ATOMICDEX_PASSWORD} --apple-id=$ENV{APPLE_ID} --primary-bundle-id=com.komodoplatform.atomicdex --target-binary=${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/osx/${DEX_PROJECT_NAME}_installer.app WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE) file(COPY ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/osx/${DEX_PROJECT_NAME}_installer.app DESTINATION ${TARGET_APP_PATH}) -execute_process(COMMAND ${IFW_BINDIR}/archivegen ${DEX_PROJECT_NAME}_installer.7z ${DEX_PROJECT_NAME}_installer.app + +execute_process(COMMAND ${IFW_BINDIR}/archivegen ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/osx/${DEX_PROJECT_NAME}_installer.7z ${DEX_PROJECT_NAME}_installer.app WORKING_DIRECTORY ${TARGET_APP_PATH} ECHO_OUTPUT_VARIABLE - ECHO_ERROR_VARIABLE) \ No newline at end of file + ECHO_ERROR_VARIABLE) + +file(COPY ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/osx/${DEX_PROJECT_NAME}_installer.7z DESTINATION ${TARGET_APP_PATH}) diff --git a/cmake/install/windows/windows_post_install.cmake b/cmake/install/windows/windows_post_install.cmake index 5613a15b0b..a477153535 100644 --- a/cmake/install/windows/windows_post_install.cmake +++ b/cmake/install/windows/windows_post_install.cmake @@ -1,25 +1,32 @@ include(${CMAKE_CURRENT_LIST_DIR}/../../project.metadata.cmake) +message(STATUS "===== Starting Windows Post Install =====") +message(STATUS "PROJECT_ROOT_DIR (before readjusting) -> ${PROJECT_ROOT_DIR}") get_filename_component(PROJECT_ROOT_DIR ${CMAKE_SOURCE_DIR} DIRECTORY) -if (EXISTS ${PROJECT_ROOT_DIR}/build-Release) +if (EXISTS ${PROJECT_ROOT_DIR}/build-Release OR EXISTS ${PROJECT_ROOT_DIR}/build-Debug) message(STATUS "from ci tools, readjusting") get_filename_component(PROJECT_ROOT_DIR ${PROJECT_ROOT_DIR} DIRECTORY) endif () +message(STATUS "PROJECT_ROOT_DIR (after readjusting) -> ${PROJECT_ROOT_DIR}") -message(STATUS "PROJECT_ROOT_DIR -> ${PROJECT_ROOT_DIR}") - -set(PROJECT_APP_DIR bin) -set(PROJECT_APP_PATH ${CMAKE_SOURCE_DIR}/${PROJECT_APP_DIR}) +set(PROJECT_APP_PATH ${CMAKE_SOURCE_DIR}/bin) set(TARGET_APP_PATH ${PROJECT_ROOT_DIR}/bundled/windows) +message(STATUS "VCPKG package manager enabled") +message(STATUS "PROJECT_QML_DIR -> ${PROJECT_QML_DIR}") +message(STATUS "CMAKE_SOURCE_DIR -> ${CMAKE_SOURCE_DIR}") +message(STATUS "CMAKE_CURRENT_SOURCE_DIR -> ${CMAKE_CURRENT_SOURCE_DIR}") +message(STATUS "DEX_PROJECT_NAME -> ${DEX_PROJECT_NAME}") + if (EXISTS ${PROJECT_APP_PATH}) - message(STATUS "PROJECT_APP_PATH path is -> ${PROJECT_APP_PATH}") - message(STATUS "TARGET_APP_PATH path is -> ${TARGET_APP_PATH}") + message(STATUS "PROJECT_APP_PATH path -> ${PROJECT_APP_PATH}") + message(STATUS "TARGET_APP_PATH path -> ${TARGET_APP_PATH}") else () message(FATAL_ERROR "Didn't find ${PROJECT_APP_PATH}") endif () if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/bin.zip) + message(STATUS "Creating bin.zip...") execute_process(COMMAND powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::CreateFromDirectory('bin', 'bin.zip'); }" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ECHO_OUTPUT_VARIABLE @@ -31,7 +38,7 @@ endif() if (NOT EXISTS ${TARGET_APP_PATH}/bin.zip) message(STATUS "Copying ${CMAKE_SOURCE_DIR}/bin.zip to ${TARGET_APP_PATH}/${DEX_PROJECT_NAME}.zip") - file(COPY ${CMAKE_SOURCE_DIR}/bin.zip DESTINATION ${TARGET_APP_PATH}) + file(COPY ${CMAKE_SOURCE_DIR}/bin.zip DESTINATION ${TARGET_APP_PATH}/${DEX_PROJECT_NAME}.zip) else() message(STATUS "${TARGET_APP_PATH}/${DEX_PROJECT_NAME}.zip exists - skipping") endif() @@ -40,15 +47,21 @@ message(STATUS "Embedding the manifest") if (NOT EXISTS ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/windows/packages/com.komodoplatform.atomicdex/data/${DEX_PROJECT_NAME}.exe.manifest) message(WARNING "${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/windows/packages/com.komodoplatform.atomicdex/data/${DEX_PROJECT_NAME}.exe.manifest doesn't exist - aborting") endif() -file(COPY ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/windows/packages/com.komodoplatform.atomicdex/data/${DEX_PROJECT_NAME}.exe.manifest DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) +file(COPY ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/windows/packages/com.komodoplatform.atomicdex/data/${DEX_PROJECT_NAME}.exe.manifest DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) + #FILE(GLOB CURDIR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/ ${CMAKE_CURRENT_SOURCE_DIR}/bin/*) -#message(STATUS "curdir: ${CURDIR}") + +message(STATUS "curdir: ${CURDIR}") + #message(STATUS "Executing: [mt.exe -manifest \"${DEX_PROJECT_NAME}.exe.manifest\" -outputresource:\"${DEX_PROJECT_NAME}.exe\";\#1] from directory: ${CMAKE_CURRENT_SOURCE_DIR}/bin") + set(DEX_OUT "${CMAKE_CURRENT_SOURCE_DIR}\\bin\\${DEX_PROJECT_NAME}.exe") set(DEX_IN "${CMAKE_CURRENT_SOURCE_DIR}\\bin\\${DEX_PROJECT_NAME}.exe.manifest") cmake_path(CONVERT ${DEX_OUT} TO_NATIVE_PATH_LIST DEX_OUT_NATIVE) cmake_path(CONVERT ${DEX_IN} TO_NATIVE_PATH_LIST DEX_IN_NATIVE) + #message(STATUS "mt.exe -manifest ${DEX_IN_NATIVE} -outputresource:${DEX_OUT_NATIVE}") + execute_process(COMMAND powershell.exe -File ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/ci_scripts/mt_wrapper.ps1 ${DEX_IN} ${DEX_OUT} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin ECHO_ERROR_VARIABLE @@ -58,12 +71,19 @@ execute_process(COMMAND powershell.exe -File ${PROJECT_ROOT_DIR}/ci_tools_atomic message(STATUS "manifest output: ${MANIFEST_RESULT} ${MANIFEST_OUTPUT} ${MANIFEST_ERROR}") message(STATUS "Creating Installer") -set(IFW_BINDIR $ENV{QT_ROOT}/Tools/QtInstallerFramework/4.3/bin) +set(IFW_BINDIR $ENV{QT_ROOT}/Tools/QtInstallerFramework/4.5/bin) message(STATUS "IFW_BIN PATH IS ${IFW_BINDIR}") -if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/bin/${DEX_PROJECT_NAME}.7z) - message(STATUS "command is: [${IFW_BINDIR}/archivegen.exe ${DEX_PROJECT_NAME}.7z .]") - execute_process(COMMAND ${IFW_BINDIR}/archivegen.exe ${DEX_PROJECT_NAME}.7z . - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin +if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${DEX_PROJECT_NAME}.7z) + message(STATUS "Contents of folder: ls ${CMAKE_CURRENT_SOURCE_DIR}") + execute_process(COMMAND ls "${CMAKE_CURRENT_SOURCE_DIR}") + message(STATUS "Contents of folder: ls ${CMAKE_CURRENT_SOURCE_DIR}/bin") + execute_process(COMMAND ls "${CMAKE_CURRENT_SOURCE_DIR}/bin") + message(STATUS "Contents of folder: ls ${CMAKE_CURRENT_SOURCE_DIR}/bundled") + execute_process(COMMAND ls "${CMAKE_CURRENT_SOURCE_DIR}/bundled") + message(STATUS "command is: [${IFW_BINDIR}/archivegen.exe ${DEX_PROJECT_NAME}.7z ${PROJECT_APP_PATH} WORKING_DIRECTORY ${PROJECT_ROOT_DIR}/bundled]") + execute_process(COMMAND + ${IFW_BINDIR}/archivegen.exe ${DEX_PROJECT_NAME}.7z ${PROJECT_APP_PATH} + WORKING_DIRECTORY ${PROJECT_ROOT_DIR}/bundled ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE RESULT_VARIABLE ARCHIVE_RESULT @@ -74,10 +94,18 @@ else() message(STATUS "${DEX_PROJECT_NAME}.7z already exists skipping") endif() -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/bin/${DEX_PROJECT_NAME}.7z DESTINATION ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/windows/packages/com.komodoplatform.atomicdex/data) +message(STATUS "Contents of folder: ls ${PROJECT_APP_PATH}") +execute_process(COMMAND ls "${PROJECT_APP_PATH}") + +file(COPY ${PROJECT_ROOT_DIR}/bundled/${DEX_PROJECT_NAME}.7z DESTINATION ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/windows/packages/com.komodoplatform.atomicdex/data) execute_process(COMMAND ${IFW_BINDIR}/binarycreator.exe -c ./config/config.xml -p ./packages/ ${DEX_PROJECT_NAME}_installer.exe WORKING_DIRECTORY ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/windows ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE) -file(COPY ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/windows/${DEX_PROJECT_NAME}_installer.exe DESTINATION ${TARGET_APP_PATH}) \ No newline at end of file +file(COPY ${PROJECT_ROOT_DIR}/ci_tools_atomic_dex/installer/windows/${DEX_PROJECT_NAME}_installer.exe DESTINATION ${TARGET_APP_PATH}) + +message(STATUS "Contents of folder: ls ${TARGET_APP_PATH}") +execute_process(COMMAND ls "${TARGET_APP_PATH}") + +message(STATUS "===== Windows Post Install Complete =====") diff --git a/cmake/project.metadata.cmake b/cmake/project.metadata.cmake index 162b6daf8c..a838dd9f6a 100644 --- a/cmake/project.metadata.cmake +++ b/cmake/project.metadata.cmake @@ -1,4 +1,7 @@ # Default project values +set(DEX_API "mm2") +set(DEX_RPCPORT 7783) +set(DEX_RPC "http://127.0.0.1:7783") set(DEX_PROJECT_NAME "firodex") set(DEX_DISPLAY_NAME "Firo Dex") set(DEX_MAINTENANCE_TOOL_NAME "Firo Dex Maintenance Tool") @@ -18,13 +21,20 @@ if (APPLE) else () set(DEX_APPDATA_FOLDER "firodex") endif () -message(STATUS "APPDATA folder is ${DEX_APPDATA_FOLDER}") - if (UNIX AND NOT APPLE) set(DEX_LINUX_APP_ID "dex.desktop") endif () # Erases default project values with environment variables if they exist. +if (DEFINED ENV{DEX_API}) + set(DEX_API $ENV{DEX_API}) +endif () +if (DEFINED ENV{DEX_RPCPORT}) + set(DEX_RPCPORT $ENV{DEX_RPCPORT}) +endif () +if (DEFINED ENV{DEX_RPC}) + set(DEX_RPC $ENV{DEX_RPC}) +endif () if (DEFINED ENV{DEX_PROJECT_NAME}) set(DEX_PROJECT_NAME $ENV{DEX_PROJECT_NAME}) endif () @@ -37,9 +47,31 @@ endif () if (DEFINED ENV{DEX_WEBSITE}) set(DEX_WEBSITE $ENV{DEX_WEBSITE}) endif () +if (DEFINED ENV{PROJECT_ROOT}) + set(PROJECT_ROOT $ENV{PROJECT_ROOT}) +else () + set(PROJECT_ROOT ${CMAKE_SOURCE_DIR}) +endif () +if (DEFINED ENV{CMAKE_BUILD_TYPE}) + set(CMAKE_BUILD_TYPE $ENV{CMAKE_BUILD_TYPE}) +endif () +if (DEFINED ENV{PROJECT_QML_DIR}) + set(PROJECT_QML_DIR $ENV{PROJECT_QML_DIR}) +endif () + # Shows project metadata -message(STATUS "Project Metadata: ${DEX_PROJECT_NAME}.${DEX_DISPLAY_NAME}.${DEX_COMPANY}.${DEX_WEBSITE}") +message(STATUS "Project Metadata:") +message(STATUS "DEX_APPDATA_FOLDER --> ${DEX_APPDATA_FOLDER}") +message(STATUS "CMAKE_BUILD_TYPE --> ${CMAKE_BUILD_TYPE}") +message(STATUS "DEX_PROJECT_NAME --> ${DEX_PROJECT_NAME}") +message(STATUS "DEX_DISPLAY_NAME --> ${DEX_DISPLAY_NAME}") +message(STATUS "DEX_COMPANY --> ${DEX_COMPANY}") +message(STATUS "DEX_WEBSITE --> ${DEX_WEBSITE}") +message(STATUS "CMAKE_SOURCE_DIR --> ${CMAKE_SOURCE_DIR}") +message(STATUS "PROJECT_ROOT --> ${PROJECT_ROOT}") + + # Generates files which need to be configured with custom variables from env/CMake. macro(generate_dex_project_metafiles) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 25ab4e6aa4..531c27e8d6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,5 @@ include(DEX_NEW_LIB) +include(dex_generate_qrc) # Core target DEX_NEW_LIB(core INTERFACE @@ -13,7 +14,7 @@ DEX_NEW_LIB(core INTERFACE $<$:NOMINMAX> $<$:SPDLOG_WCHAR_TO_UTF8_SUPPORT> _TURN_OFF_PLATFORM_STRING - DEX_NAME="${DEX_DISPLAY_NAME}" DEX_WEBSITE_URL="${DEX_WEBSITE}" + DEX_API="${DEX_API}" DEX_RPC="${DEX_RPC}" DEX_RPCPORT="${DEX_RPCPORT}" DEX_NAME="${DEX_DISPLAY_NAME}" DEX_WEBSITE_URL="${DEX_WEBSITE}" DEX_SUPPORT_URL="${DEX_SUPPORT_PAGE}" DEX_DISCORD_URL="${DEX_DISCORD}" DEX_TWITTER_URL="${DEX_TWITTER}" DEX_PRIMARY_COIN="${DEX_PRIMARY_COIN}" DEX_SECOND_PRIMARY_COIN="${DEX_SECOND_PRIMARY_COIN}" #DEX_COMMON_DATA_FOLDER="${DEX_COMMON_DATA_FOLDER}" DEX_PROJECT_NAME="${DEX_PROJECT_NAME}" DEX_COMPANY_NAME="${DEX_COMPANY_NAME}" @@ -22,6 +23,7 @@ DEX_NEW_LIB(core INTERFACE INTERFACE_DEFS ENTT_API_EXPORT) target_precompile_headers(${PROJECT_NAME}_core INTERFACE core/atomicdex/pch.hpp) + if (APPLE) set_source_files_properties(core/atomicdex/platform/osx/manager.mm PROPERTIES SKIP_PRECOMPILE_HEADERS ON) macro(adex_add_framework fwname appname) @@ -51,6 +53,8 @@ set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM TRUE) set(TS_FILES ${CMAKE_SOURCE_DIR}/atomic_defi_design/assets/languages/atomic_defi_en.ts ${CMAKE_SOURCE_DIR}/atomic_defi_design/assets/languages/atomic_defi_fr.ts + ${CMAKE_SOURCE_DIR}/atomic_defi_design/assets/languages/atomic_defi_de.ts + ${CMAKE_SOURCE_DIR}/atomic_defi_design/assets/languages/atomic_defi_es.ts ${CMAKE_SOURCE_DIR}/atomic_defi_design/assets/languages/atomic_defi_tr.ts ${CMAKE_SOURCE_DIR}/atomic_defi_design/assets/languages/atomic_defi_ru.ts) set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION ${CMAKE_SOURCE_DIR}/atomic_defi_design/assets/languages) @@ -62,6 +66,17 @@ qt5_create_translation(QM_FILES message(STATUS "QM FILES -> ${QM_FILES}") message(STATUS "TS FILES -> ${TS_FILES}") +set(qml_qrc) +set(assets_qrc) +set(imports_qrc ${CMAKE_SOURCE_DIR}/atomic_defi_design/imports/qml.qrc) +dex_generate_qrc(${CMAKE_SOURCE_DIR}/atomic_defi_design/Dex qml_qrc + PATH_PREFIX "Dex" + FILES_TO_EXCLUDE ".gitignore;.DS_Store;.qrc") +dex_generate_qrc(${CMAKE_SOURCE_DIR}/atomic_defi_design/assets assets_qrc + PATH_PREFIX "assets" + FILES_TO_EXCLUDE ".gitignore;.DS_Store;CONTRIBUTING.txt;FONTLOG.txt;LICENCE-FAQ.txt;LICENCE.txt;README.txt;TRADEMARKS.txt;.ts;.qm;.qrc" + FILES "languages/atomic_defi_en.qm;languages/atomic_defi_es.qm;languages/atomic_defi_de.qm;languages/atomic_defi_fr.qm;languages/atomic_defi_ru.qm;languages/atomic_defi_tr.qm") + # Main executable add_executable(${PROJECT_NAME} MACOSX_BUNDLE @@ -73,8 +88,9 @@ add_executable(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/cmake/install/windows/dex.rc ##! QRC - ${CMAKE_SOURCE_DIR}/atomic_defi_design/qml.qrc - ${CMAKE_SOURCE_DIR}/atomic_defi_design/imports/qml.qrc + ${qml_qrc} + ${assets_qrc} + ${imports_qrc} ##! Linguistic ${QM_FILES} @@ -92,19 +108,30 @@ endif () # Testing executable add_executable(${PROJECT_NAME}_tests MACOSX_BUNDLE ${ICON} + tests/atomic.dex.qt.utilities.tests.cpp + tests/atomic.dex.provider.cex.prices.api.tests.cpp + tests/atomic.dex.provider.cex.prices.tests.cpp tests/atomic.dex.tests.cpp tests/atomic.dex.wallet.config.tests.cpp - tests/atomic.dex.provider.cex.prices.tests.cpp - tests/atomic.dex.qt.utilities.tests.cpp + ##! 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.fraction.tests.cpp + tests/api/mm2/mm2.rpc.trade.preimage.tests.cpp + + ##! CFG tests/config/coins.cfg.tests.cpp + ##! API tests/api/coingecko/coingecko.tests.cpp tests/api/komodo_prices/komodo.prices.tests.cpp tests/api/mm2/mm2.rpc.trade.preimage.tests.cpp tests/api/mm2/mm2.fraction.tests.cpp - #tests/api/github/github.api.tests.cpp - #tests/api/checksum/checksum.api.tests.cpp + tests/api/mm2/enable_bch_with_tokens_rpc_tests.cpp ##! Utilities tests/utilities/qt.utilities.tests.cpp @@ -116,7 +143,10 @@ add_executable(${PROJECT_NAME}_tests MACOSX_BUNDLE ${ICON} ##! Models tests/models/qt.addressbook.contact.model.tests.cpp - tests/atomic.dex.provider.cex.prices.api.tests.cpp) + ##! Utilities + tests/utilities/qt.utilities.tests.cpp + tests/utilities/global.utilities.tests.cpp) + target_link_libraries(${PROJECT_NAME}_tests PUBLIC ${PROJECT_NAME}::core diff --git a/src/app/app.cpp b/src/app/app.cpp index f47a8e2e0b..ee80584c2e 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -22,6 +22,7 @@ //! QT #include #include +#include #include #include #include @@ -40,7 +41,6 @@ #include "app.hpp" #include "atomicdex/services/exporter/exporter.service.hpp" #include "atomicdex/services/mm2/auto.update.maker.order.service.hpp" -//#include "atomicdex/services/price/coingecko/coingecko.provider.hpp" #include "atomicdex/services/price/komodo_prices/komodo.prices.provider.hpp" #include "atomicdex/services/price/coingecko/coingecko.wallet.charts.hpp" #include "atomicdex/services/price/coinpaprika/coinpaprika.provider.hpp" @@ -54,8 +54,7 @@ namespace namespace atomic_dex { - void - atomic_dex::application::change_state([[maybe_unused]] int visibility) + void atomic_dex::application::change_state([[maybe_unused]] int visibility) { /*#ifdef __APPLE__ { @@ -66,8 +65,7 @@ namespace atomic_dex #endif*/ } - bool - atomic_dex::application::enable_coins(const QStringList& coins) + bool atomic_dex::application::enable_coins(const QStringList& coins) { auto enableable_coins_count = entity_registry_.template ctx().value("MaximumNbCoinsEnabled").toULongLong(); if (enableable_coins_count < coins.size() + get_portfolio_page()->get_global_cfg()->get_enabled_coins().size()) @@ -79,54 +77,66 @@ namespace atomic_dex coins_std.reserve(coins.size()); atomic_dex::mm2_service& mm2 = get_mm2(); std::unordered_set extra_coins; - for (auto&& coin: coins) { + for (auto&& coin : coins) + { auto coin_info = mm2.get_coin_info(coin.toStdString()); - if (coin_info.has_parent_fees_ticker && coin_info.ticker != coin_info.fees_ticker) + + if (coin_info.has_parent_fees_ticker && + coin_info.ticker != coin_info.fees_ticker && + !coins.contains(QString::fromStdString(coin_info.fees_ticker))) { auto coin_parent_info = mm2.get_coin_info(coin_info.fees_ticker); - if (!coin_parent_info.currently_enabled && !coin_parent_info.active && extra_coins.insert(coin_parent_info.ticker).second) + // todo: why can it be empty when it has been found ? + // refactor coins enabling logic!!! + if (coin_parent_info.ticker != "") { - SPDLOG_INFO("Adding extra coin: {} to enable", coin_parent_info.ticker); + if (!coin_parent_info.currently_enabled && !coin_parent_info.active && extra_coins.insert(coin_parent_info.ticker).second) + { + SPDLOG_INFO("Adding extra coin: {} to enable", coin_parent_info.ticker); + } } } coins_std.push_back(coin.toStdString()); } - for (auto&& extra_coin : extra_coins) { coins_std.push_back(extra_coin); } - mm2.enable_multiple_coins(coins_std); - + mm2.enable_coins(coins_std); return true; } - bool - atomic_dex::application::enable_coin(const QString& coin) + bool atomic_dex::application::enable_coin(const QString& coin) { return enable_coins(QStringList{coin}); } - bool - application::disable_coins(const QStringList& coins) + bool application::disable_coins(const QStringList& coins) { QString primary_coin = QString::fromStdString(g_primary_dex_coin); QString secondary_coin = QString::fromStdString(g_second_primary_dex_coin); QStringList coins_copy; const auto& mm2 = system_manager_.get_system(); - for (auto&& coin: coins) + for (auto&& coin : coins) { const auto coin_info = mm2.get_coin_info(coin.toStdString()); bool has_parent_fees = coin_info.has_parent_fees_ticker; if (not get_orders()->swap_is_in_progress(coin) && coin != primary_coin && coin != secondary_coin) { - if (has_parent_fees) + if (!get_mm2().is_zhtlc_coin_ready(coin.toStdString())) { - coins_copy.push_front(coin); + this->dispatcher_.trigger(coin.toStdString(), "Can't disable until fully activated."); } else { - coins_copy.push_back(coin); + if (has_parent_fees) + { + coins_copy.push_front(coin); + } + else + { + coins_copy.push_back(coin); + } } } } @@ -137,7 +147,7 @@ namespace atomic_dex system_manager_.get_system().disable_coins(coins_copy); system_manager_.get_system().disable_coins(coins_copy); coins_std.reserve(coins_copy.size()); - for (auto&& coin: coins_copy) + for (auto&& coin : coins_copy) { if (QString::fromStdString(get_mm2().get_current_ticker()) == coin && m_primary_coin_fully_enabled) { @@ -152,8 +162,7 @@ namespace atomic_dex return true; } - bool - application::disable_no_balance_coins() + bool application::disable_no_balance_coins() { auto* portfolio_page = get_portfolio_page(); auto* portfolio_mdl = portfolio_page->get_portfolio(); @@ -170,8 +179,7 @@ namespace atomic_dex return disable_coins(coins_to_disable); } - bool - application::has_coins_with_balance() + bool application::has_coins_with_balance() { auto* portfolio_page = get_portfolio_page(); auto* portfolio_mdl = portfolio_page->get_portfolio(); @@ -181,14 +189,135 @@ namespace atomic_dex return ranges::any_of(portfolio_data, functor); } - bool - atomic_dex::application::first_run() + bool atomic_dex::application::first_run() { return qt_wallet_manager::get_wallets().empty(); } - void - application::launch() + void atomic_dex::application::reset_coin_cfg() + { + using namespace std::string_literals; + const std::string wallet_name = qt_wallet_manager::get_default_wallet_name().toStdString(); + const std::string wallet_cfg_file = std::string(atomic_dex::get_raw_version()) + "-coins"s + "."s + wallet_name + ".json"s; + std::string wallet_custom_cfg_filename = "custom-tokens."s + wallet_name + ".json"s; + const fs::path wallet_custom_cfg_path{utils::get_atomic_dex_config_folder() / wallet_custom_cfg_filename}; + const fs::path wallet_cfg_path{utils::get_atomic_dex_config_folder() / wallet_cfg_file}; + const fs::path mm2_coins_file_path{atomic_dex::utils::get_current_configs_path() / "coins.json"}; + const fs::path ini_file_path = atomic_dex::utils::get_current_configs_path() / "cfg.ini"; + const fs::path cfg_json_file_path = atomic_dex::utils::get_current_configs_path() / "cfg.json"; + const fs::path logo_path = atomic_dex::utils::get_logo_path(); + const fs::path theme_path = atomic_dex::utils::get_themes_path(); + + const auto functor_remove = [](auto&& path_to_remove) + { + if (fs::exists(path_to_remove)) + { + std::error_code ec; + if (fs::is_directory(path_to_remove)) + { + fs::remove_all(path_to_remove, ec); + } + else + { + fs::remove(path_to_remove, ec); + } + if (ec) + { + LOG_PATH("error when removing {}", path_to_remove); + SPDLOG_ERROR("error: {}", ec.message()); + } + else + { + LOG_PATH("Successfully removed {}", path_to_remove); + } + } + }; + + if (fs::exists(wallet_cfg_path)) + { + nlohmann::json coin_config_json_data; + std::unordered_set active_coins_registry; + QFile coins_file; + coins_file.setFileName(std_path_to_qstring(wallet_cfg_path)); + coins_file.open(QIODevice::ReadOnly | QIODevice::Text); + + //! Read Contents + coin_config_json_data = nlohmann::json::parse(QString(coins_file.readAll()).toStdString()); + coins_file.close(); + + //! Get the active coins + for (auto&& [key, value]: coin_config_json_data.items()) + { + if (value["active"]) { active_coins_registry.insert(key); } + } + + // remove old coins file + functor_remove(std::move(wallet_cfg_path)); + + //! Copy default coins file + const auto cfg_path = ag::core::assets_real_path() / "config"; + std::string filename = std::string(atomic_dex::get_raw_version()) + "-coins.json"; + fs::copy(cfg_path / filename, wallet_cfg_path); + QFile default_coins_file; + + //! Open coins file + default_coins_file.setFileName(std_path_to_qstring(wallet_cfg_path)); + default_coins_file.open(QIODevice::ReadOnly | QIODevice::Text); + + //! Read default coins contents + nlohmann::json default_coin_config_json_data; + default_coin_config_json_data = nlohmann::json::parse(QString(default_coins_file.readAll()).toStdString()); + default_coins_file.close(); + + //! set active coins again + for (auto&& key: active_coins_registry) + { + try + { + if (default_coin_config_json_data.contains(key)) + { + default_coin_config_json_data[key]["active"] = true; + } + } + catch (const std::exception& error) + { + SPDLOG_ERROR("Exception caught: {}", error.what()); + } + } + + //! Write + QFile output_coins_file; + //SPDLOG_DEBUG("Data written: ", default_coin_config_json_data.dump(4)); + output_coins_file.setFileName(std_path_to_qstring(wallet_cfg_path)); + output_coins_file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); + output_coins_file.write(QString::fromStdString(default_coin_config_json_data.dump(4)).toUtf8()); + output_coins_file.close(); + } + + if (fs::exists(wallet_custom_cfg_path)) + { + nlohmann::json custom_config_json_data = utils::read_json_file(wallet_custom_cfg_path); + + //! Modify + for (auto&& [key, value]: custom_config_json_data.items()) { value["active"] = false; } + + //! Write + QFile file; + file.setFileName(std_path_to_qstring(wallet_custom_cfg_path)); + file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); + file.write(QString::fromStdString(custom_config_json_data.dump()).toUtf8()); + file.close(); + } + functor_remove(std::move(mm2_coins_file_path)); + functor_remove(std::move(cfg_json_file_path)); + functor_remove(std::move(logo_path)); + functor_remove(std::move(theme_path)); + // Uncomment if you want to reset fiat/language/theme + // functor_remove(std::move(ini_file_path)); + atomic_dex::application::restart(); + } + + void application::launch() { SPDLOG_INFO("Launch the application"); this->system_manager_.start(); @@ -197,8 +326,7 @@ namespace atomic_dex timer->start(g_timeout_q_timer_ms); } - QString - atomic_dex::application::get_mnemonic() + QString atomic_dex::application::get_mnemonic() { std::array data{}; boost::random_device device; @@ -211,8 +339,7 @@ namespace atomic_dex return output; } - void - application::tick() + void application::tick() { this->process_one_frame(); if (m_event_actions[events_action::need_a_full_refresh_of_mm2]) @@ -231,6 +358,7 @@ namespace atomic_dex while (not m_portfolio_queue.empty()) { const char* ticker_cstr = nullptr; + bool add_to_init(true); m_portfolio_queue.pop(ticker_cstr); std::string ticker(ticker_cstr); if (ticker == g_primary_dex_coin) @@ -241,7 +369,17 @@ namespace atomic_dex { this->m_secondary_coin_fully_enabled = true; } - to_init.push_back(ticker); + //! TODO: figure out why sometimes ZHTLC coins end up in here twice. When they do, without this check it crashes. + if (std::find(to_init.begin(), to_init.end(), ticker) != to_init.end()) { + SPDLOG_DEBUG("Ticker {} is already in vector", ticker); + add_to_init = false; + } + else { + SPDLOG_DEBUG("Ticker {} is not already in vector", ticker); + } + if (add_to_init) { + to_init.push_back(ticker); + } std::free((void*)ticker_cstr); } @@ -293,32 +431,27 @@ namespace atomic_dex } } - mm2_service& - application::get_mm2() + mm2_service& application::get_mm2() { return this->system_manager_.get_system(); } - entt::dispatcher& - application::get_dispatcher() + entt::dispatcher& application::get_dispatcher() { return this->dispatcher_; } - const entt::registry& - application::get_registry() const + const entt::registry& application::get_registry() const { return this->entity_registry_; } - entt::registry& - application::get_registry() + entt::registry& application::get_registry() { return this->entity_registry_; } - void - application::post_handle_settings() + void application::post_handle_settings() { QSettings& settings = get_registry().ctx(); if (settings.value("AutomaticUpdateOrderBot", false).toBool()) @@ -336,7 +469,7 @@ namespace atomic_dex application::application(QObject* pParent) : QObject(pParent) { - fs::path settings_path = (atomic_dex::utils::get_current_configs_path() / "cfg.ini"); + std::filesystem::path settings_path = (atomic_dex::utils::get_current_configs_path() / "cfg.ini"); #if defined(_WIN32) || defined(WIN32) this->entity_registry_.set(QString::fromStdWString(settings_path.wstring()), QSettings::IniFormat); #else @@ -373,15 +506,15 @@ namespace atomic_dex // system_manager_.create_system(system_manager_); //system_manager_.create_system(system_manager_); system_manager_.create_system(); - auto& self_update_system = system_manager_.create_system(); -#if !defined(Q_OS_WINDOWS) - self_update_system.disable(); -#endif + system_manager_.create_system(); system_manager_.create_system(system_manager_); system_manager_.create_system(system_manager_); system_manager_.create_system( system_manager_, m_event_actions.at(events_action::about_to_exit_app), portfolio_system.get_portfolio(), this); + + system_manager_.create_system(system_manager_, this->dispatcher_, this); + connect_signals(); if (qt_wallet_manager::is_there_a_default_wallet()) { @@ -407,36 +540,37 @@ namespace atomic_dex } } - bool - application::do_i_have_enough_funds(const QString& ticker, const QString& amount) const + bool application::do_i_have_enough_funds(const QString& ticker, const QString& amount) const { t_float_50 amount_f = safe_float(amount.toStdString()); return get_mm2().do_i_have_enough_funds(ticker.toStdString(), amount_f); } - const mm2_service& - application::get_mm2() const + const mm2_service& application::get_mm2() const { return this->system_manager_.get_system(); } - QString - application::get_balance(const QString& coin) + QJsonObject application::get_zhtlc_status(const QString& coin) + { + QJsonObject res = nlohmann_json_object_to_qt_json_object(get_mm2().get_zhtlc_status(coin.toStdString())); + return res; + } + + QString application::get_balance(const QString& coin) { std::error_code ec; auto res = get_mm2().my_balance(coin.toStdString(), ec); return QString::fromStdString(res); } - void - application::on_mm2_initialized_event([[maybe_unused]] const mm2_initialized& evt) + void application::on_mm2_initialized_event([[maybe_unused]] const mm2_initialized& evt) { SPDLOG_DEBUG("{} l{}", __FUNCTION__, __LINE__); system_manager_.get_system().set_status("enabling_coins"); } - void - application::refresh_orders_and_swaps() + void application::refresh_orders_and_swaps() { auto& mm2 = get_mm2(); if (mm2.is_mm2_running()) @@ -445,8 +579,7 @@ namespace atomic_dex } } - bool - application::disconnect() + bool application::disconnect() { //! Clears pending events while (not this->m_actions_queue.empty()) @@ -498,14 +631,13 @@ namespace atomic_dex auto& wallet_manager = this->system_manager_.get_system(); wallet_manager.just_set_wallet_name(""); - this->m_secondary_coin_fully_enabled = false; this->m_primary_coin_fully_enabled = false; + this->m_secondary_coin_fully_enabled = false; system_manager_.get_system().set_status("None"); - return fs::remove(utils::get_atomic_dex_config_folder() / "default.wallet"); + return std::filesystem::remove(utils::get_atomic_dex_config_folder() / "default.wallet"); } - void - application::connect_signals() + void application::connect_signals() { SPDLOG_INFO("connecting signals"); qobject_cast(m_manager_models.at("notifications"))->connect_signals(); @@ -519,8 +651,7 @@ namespace atomic_dex // get_dispatcher().sink().connect<&application::on_process_swaps_finished_event>(*this); } - void - application::set_qt_app(std::shared_ptr app, QQmlApplicationEngine* engine) + void application::set_qt_app(std::shared_ptr app, QQmlApplicationEngine* engine) { this->m_app = app; connect(m_app.get(), SIGNAL(aboutToQuit()), this, SLOT(exit_handler())); @@ -530,12 +661,11 @@ namespace atomic_dex settings_system.init_lang(); } - QString - application::recover_fund(const QString& uuid) + QString application::recover_fund(const QString& uuid) { QString result; - ::mm2::api::recover_funds_of_swap_request request{.swap_uuid = uuid.toStdString()}; + mm2::recover_funds_of_swap_request request{.swap_uuid = uuid.toStdString()}; auto res = get_mm2().get_mm2_client().rpc_recover_funds(std::move(request)); result = QString::fromStdString(res.raw_result); @@ -759,10 +889,20 @@ namespace atomic_dex //! update checker namespace atomic_dex { - self_update_service* - application::get_self_update_service() const + update_checker_service* application::get_update_checker_service() const + { + auto ptr = const_cast(std::addressof(system_manager_.get_system())); + assert(ptr != nullptr); + return ptr; + } +} // namespace atomic_dex + +//! update checker +namespace atomic_dex +{ + zcash_params_service* application::get_zcash_params_service() const { - auto ptr = const_cast(std::addressof(system_manager_.get_system())); + auto ptr = const_cast(std::addressof(system_manager_.get_system())); assert(ptr != nullptr); return ptr; } diff --git a/src/app/app.hpp b/src/app/app.hpp index 82c1b11af0..297f25150d 100644 --- a/src/app/app.hpp +++ b/src/app/app.hpp @@ -48,7 +48,9 @@ #include "atomicdex/services/ip/ip.checker.service.hpp" #include "atomicdex/services/mm2/mm2.service.hpp" #include "atomicdex/services/price/global.provider.hpp" -#include "atomicdex/services/update/self.update.service.hpp" +#include "atomicdex/services/update/update.checker.service.hpp" +#include "atomicdex/services/update/zcash.params.service.hpp" +#include "atomicdex/utilities/qt.utilities.hpp" namespace ag = antara::gaming; @@ -62,7 +64,7 @@ namespace atomic_dex Q_OBJECT //! Properties - Q_PROPERTY(addressbook_page* addressbook_pg READ get_addressbook_page NOTIFY addressbookPageChanged) + Q_PROPERTY(addressbook_page* addressbookPg READ get_addressbook_page NOTIFY addressbookPageChanged) Q_PROPERTY(orders_model* orders_mdl READ get_orders NOTIFY ordersChanged) Q_PROPERTY(portfolio_page_ptr portfolio_pg READ get_portfolio_page NOTIFY portfolioPageChanged) Q_PROPERTY(notification_manager* notification_mgr READ get_notification_manager) @@ -73,7 +75,8 @@ namespace atomic_dex Q_PROPERTY(wallet_page* wallet_pg READ get_wallet_page NOTIFY walletPageChanged) Q_PROPERTY(settings_page* settings_pg READ get_settings_page NOTIFY settingsPageChanged) Q_PROPERTY(qt_wallet_manager* wallet_mgr READ get_wallet_mgr NOTIFY walletMgrChanged) - Q_PROPERTY(self_update_service* self_update_service READ get_self_update_service NOTIFY selfUpdateServiceChanged) + Q_PROPERTY(update_checker_service* updateCheckerService READ get_update_checker_service NOTIFY updateCheckerServiceChanged) + Q_PROPERTY(zcash_params_service* zcash_params READ get_zcash_params_service NOTIFY zcashParamsServiceChanged) //! Private function void connect_signals(); @@ -102,65 +105,57 @@ namespace atomic_dex std::atomic_bool m_primary_coin_fully_enabled{false}; public: - //! Deleted operation application(application& other) = delete; application(application&& other) = delete; application& operator=(application& other) = delete; application& operator=(application&& other) = delete; - //! Constructor explicit application(QObject* pParent = nullptr) ; - ~application() final = default; + ~application() final = default; - //! Post constructor void post_handle_settings(); - //! entt::dispatcher events - void on_ticker_balance_updated_event(const ticker_balance_updated&) ; - void on_fiat_rate_updated(const fiat_rate_updated&) ; - void on_coin_fully_initialized_event(const coin_fully_initialized&) ; - void on_mm2_initialized_event(const mm2_initialized&) ; - void on_process_orders_and_swaps_finished_event(const process_swaps_and_orders_finished&) ; - - //! Properties Getter - mm2_service& get_mm2() ; - [[nodiscard]] const mm2_service& get_mm2() const ; - entt::dispatcher& get_dispatcher() ; - const entt::registry& get_registry() const ; - entt::registry& get_registry() ; - [[nodiscard]] addressbook_page* get_addressbook_page() const ; - [[nodiscard]] portfolio_page* get_portfolio_page() const ; - [[nodiscard]] wallet_page* get_wallet_page() const ; - orders_model* get_orders() const ; - notification_manager* get_notification_manager() const ; - trading_page* get_trading_page() const ; - settings_page* get_settings_page() const ; - qt_wallet_manager* get_wallet_mgr() const ; - internet_service_checker* get_internet_checker() const ; - ip_service_checker* get_ip_checker() const ; - self_update_service* get_self_update_service() const; - exporter_service* get_exporter_service() const ; - - //! Properties Setter - void set_qt_app(std::shared_ptr app, QQmlApplicationEngine* qml_engine) ; - - //! Launch the internal loop for the SDK. + void on_ticker_balance_updated_event(const ticker_balance_updated&); + void on_fiat_rate_updated(const fiat_rate_updated&); + void on_coin_fully_initialized_event(const coin_fully_initialized&); + void on_mm2_initialized_event(const mm2_initialized&); + void on_process_orders_and_swaps_finished_event(const process_swaps_and_orders_finished&); + + mm2_service& get_mm2(); + [[nodiscard]] const mm2_service& get_mm2() const; + entt::dispatcher& get_dispatcher(); + const entt::registry& get_registry() const; + entt::registry& get_registry(); + [[nodiscard]] addressbook_page* get_addressbook_page() const; + [[nodiscard]] portfolio_page* get_portfolio_page() const; + [[nodiscard]] wallet_page* get_wallet_page() const; + orders_model* get_orders() const; + notification_manager* get_notification_manager() const; + trading_page* get_trading_page() const; + settings_page* get_settings_page() const; + qt_wallet_manager* get_wallet_mgr() const; + internet_service_checker* get_internet_checker() const; + ip_service_checker* get_ip_checker() const; + update_checker_service* get_update_checker_service() const; + [[nodiscard]] zcash_params_service* get_zcash_params_service() const; + exporter_service* get_exporter_service() const; + + void set_qt_app(std::shared_ptr app, QQmlApplicationEngine* qml_engine); + void launch(); - //! Bind to the QML Worlds Q_INVOKABLE static void restart(); - //! Wallet Manager QML API Bindings, this internally call the `atomic_dex::qt_wallet_manager` + // Wallet Manager QML API Bindings, this internally call the `atomic_dex::qt_wallet_manager` Q_INVOKABLE bool is_pin_cfg_enabled() const ; - //! Misc Q_INVOKABLE static QString to_eth_checksum_qt(const QString& eth_lowercase_address); Q_INVOKABLE static void change_state(int visibility); //! Portfolio QML API Bindings Q_INVOKABLE QString recover_fund(const QString& uuid); - //! Others + Q_INVOKABLE void reset_coin_cfg(); Q_INVOKABLE void refresh_orders_and_swaps(); Q_INVOKABLE static QString get_mnemonic(); Q_INVOKABLE static bool first_run(); @@ -168,6 +163,7 @@ namespace atomic_dex Q_INVOKABLE bool enable_coins(const QStringList& coins); Q_INVOKABLE bool enable_coin(const QString& coin); Q_INVOKABLE QString get_balance(const QString& coin); + Q_INVOKABLE QJsonObject get_zhtlc_status(const QString& coin); Q_INVOKABLE [[nodiscard]] bool do_i_have_enough_funds(const QString& ticker, const QString& amount) const; Q_INVOKABLE bool disable_coins(const QStringList& coins); Q_INVOKABLE bool disable_no_balance_coins(); @@ -175,7 +171,6 @@ namespace atomic_dex Q_INVOKABLE QString get_fiat_from_amount(const QString& ticker, const QString& amount); signals: - //! Signals to the QML Worlds void walletMgrChanged(); void coinInfoChanged(); void onWalletDefaultNameChanged(); @@ -184,7 +179,8 @@ namespace atomic_dex void portfolioPageChanged(); void walletPageChanged(); void ordersChanged(); - void selfUpdateServiceChanged(); + void updateCheckerServiceChanged(); + void zcashParamsServiceChanged(); void tradingPageChanged(); void settingsPageChanged(); void internetCheckerChanged(); diff --git a/src/app/main.prerequisites.hpp b/src/app/main.prerequisites.hpp index 284a67f247..ebb8a79841 100644 --- a/src/app/main.prerequisites.hpp +++ b/src/app/main.prerequisites.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2023 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -57,6 +57,7 @@ //! Project Headers #include "app.hpp" #include "atomicdex/constants/qt.wallet.enums.hpp" +#include "atomicdex/constants/dex.constants.hpp" #include "atomicdex/models/qt.portfolio.model.hpp" #include "atomicdex/utilities/kill.hpp" #include "atomicdex/utilities/qt.utilities.hpp" @@ -104,7 +105,7 @@ static void signal_handler(int signal) { SPDLOG_ERROR("sigabort received, cleaning mm2"); - atomic_dex::kill_executable("mm2"); + atomic_dex::kill_executable(atomic_dex::g_dex_api); #if defined(linux) || defined(__APPLE__) boost::stacktrace::safe_dump_to("./backtrace.dump"); std::ifstream ifs("./backtrace.dump"); @@ -119,7 +120,7 @@ connect_signals_handler() { SPDLOG_INFO("connecting signal SIGABRT to the signal handler"); #if defined(linux) || defined(__APPLE__) - if (fs::exists("./backtrace.dump")) + if (std::filesystem::exists("./backtrace.dump")) { // there is a backtrace std::ifstream ifs("./backtrace.dump"); @@ -129,7 +130,7 @@ connect_signals_handler() // cleaning up ifs.close(); - fs::remove("./backtrace.dump"); + std::filesystem::remove("./backtrace.dump"); } #endif std::signal(SIGABRT, &signal_handler); @@ -158,20 +159,37 @@ static void clean_previous_run() { SPDLOG_INFO("cleaning previous mm2 instance"); - atomic_dex::kill_executable("mm2"); + atomic_dex::kill_executable(atomic_dex::g_dex_api); } -static void -init_logging() +static void init_logging() { - auto logger = atomic_dex::utils::register_logger(); - if (spdlog::get("log_mt") == nullptr) - { - spdlog::register_logger(logger); - spdlog::set_default_logger(logger); - spdlog::set_level(spdlog::level::trace); - spdlog::set_pattern("[%T] [%^%l%$] [%s:%#] [%t]: %v"); - } + constexpr size_t qsize_spdlog = 10240; + constexpr size_t spdlog_thread_count = 2; + constexpr size_t spdlog_max_file_size = 7777777; + constexpr size_t spdlog_max_file_rotation = 3; + + std::filesystem::path path = atomic_dex::utils::get_atomic_dex_current_log_file(); + spdlog::init_thread_pool(qsize_spdlog, spdlog_thread_count); + auto tp = spdlog::thread_pool(); + auto stdout_sink = std::make_shared(); + +#if defined(_WIN32) || defined(WIN32) + auto rotating_sink = std::make_shared(path.wstring(), spdlog_max_file_size, spdlog_max_file_rotation); +#else + auto rotating_sink = std::make_shared(path.string(), spdlog_max_file_size, spdlog_max_file_rotation); +#endif + +#if defined(DEBUG) || defined(_WIN32) || defined(WIN32) + std::vector sinks{stdout_sink, rotating_sink}; +#else + std::vector sinks{rotating_sink}; +#endif + auto logger = std::make_shared("log_mt", sinks.begin(), sinks.end(), tp, spdlog::async_overflow_policy::block); + spdlog::register_logger(logger); + spdlog::set_default_logger(logger); + spdlog::set_level(spdlog::level::trace); + spdlog::set_pattern("[%T] [%^%l%$] [%s:%#] [%t]: %v"); } static void @@ -224,7 +242,7 @@ init_timezone_db() try { using namespace std::string_literals; - auto install_db_tz_path = std::make_unique(ag::core::assets_real_path() / "tools" / "timezone" / "tzdata"); + auto install_db_tz_path = std::make_unique(ag::core::assets_real_path() / "tools" / "timezone" / "tzdata"); date::set_install(install_db_tz_path->string()); SPDLOG_INFO("Timezone db successfully initialized"); } @@ -238,49 +256,49 @@ init_timezone_db() static void setup_default_themes() { - const fs::path theme_path = atomic_dex::utils::get_themes_path(); - fs::path original_theme_path{ag::core::assets_real_path() / "themes"}; - fs_error_code ec; + const std::filesystem::path theme_path = atomic_dex::utils::get_themes_path(); + std::filesystem::path original_theme_path{ag::core::assets_real_path() / "themes"}; + std::error_code ec; LOG_PATH_CMP("Checking for setup default themes - theme_path: {} original_theme_path: {}", theme_path, original_theme_path); LOG_PATH("copying default themes into directory: {}", theme_path); - //fs::remove_all(theme_path); - fs::copy(original_theme_path, theme_path, fs::copy_options::recursive | fs::copy_options::overwrite_existing, ec); + //std::filesystem::remove_all(theme_path); + std::filesystem::copy(original_theme_path, theme_path, std::filesystem::copy_options::recursive | std::filesystem::copy_options::overwrite_existing, ec); if (ec) { - SPDLOG_ERROR("fs::error: {}", ec.message()); + SPDLOG_ERROR("std::filesystem::error: {}", ec.message()); } ec.clear(); //! Logo { - const fs::path logo_path = atomic_dex::utils::get_logo_path(); - fs::path original_logo_path{ag::core::assets_real_path() / "logo"}; + const std::filesystem::path logo_path = atomic_dex::utils::get_logo_path(); + std::filesystem::path original_logo_path{ag::core::assets_real_path() / "logo"}; LOG_PATH_CMP("Checking for setup default logo - logo_path: {} original_logo_path: {}", logo_path, original_logo_path); - //fs::remove_all(logo_path); - fs::copy(original_logo_path, logo_path, fs::copy_options::recursive | fs::copy_options::overwrite_existing, ec); + //std::filesystem::remove_all(logo_path); + std::filesystem::copy(original_logo_path, logo_path, std::filesystem::copy_options::recursive | std::filesystem::copy_options::overwrite_existing, ec); LOG_PATH("copying default logo into directory: {}", logo_path); if (ec) { - SPDLOG_ERROR("fs::error: {}", ec.message()); + SPDLOG_ERROR("std::filesystem::error: {}", ec.message()); } } } static void -check_settings_reconfiguration(const fs::path& path) +check_settings_reconfiguration(const std::filesystem::path& path) { SPDLOG_INFO("Checking for settings ini reconfiguration"); using namespace atomic_dex::utils; using namespace atomic_dex; - const fs::path previous_path = get_atomic_dex_data_folder() / get_precedent_raw_version() / "configs" / "cfg.ini"; - if (fs::exists(previous_path) && !fs::exists(path)) + const std::filesystem::path previous_path = get_atomic_dex_data_folder() / get_precedent_raw_version() / "configs" / "cfg.ini"; + if (std::filesystem::exists(previous_path) && !std::filesystem::exists(path)) { - fs_error_code ec; + std::error_code ec; LOG_PATH_CMP("Copying {} to {}", previous_path, path); - fs::copy(previous_path, path, ec); + std::filesystem::copy(previous_path, path, ec); if (ec) { SPDLOG_ERROR("error occured when copying previous cfg.ini : {}", ec.message()); @@ -288,7 +306,7 @@ check_settings_reconfiguration(const fs::path& path) SPDLOG_INFO("Deleting previous cfg after reconfiguring it"); ec.clear(); - fs::remove_all(get_atomic_dex_data_folder() / get_precedent_raw_version(), ec); + std::filesystem::remove_all(get_atomic_dex_data_folder() / get_precedent_raw_version(), ec); if (ec) { SPDLOG_ERROR("error occured when deleting previous path"); @@ -322,7 +340,7 @@ handle_settings(QSettings& settings) #endif create_settings_functor("AutomaticUpdateOrderBot", QVariant(false)); create_settings_functor("WalletChartsCategory", qint32(WalletChartsCategories::OneMonth)); - create_settings_functor("AvailableLang", QStringList{"en", "fr", "tr", "ru"}); + create_settings_functor("AvailableLang", QStringList{"en", "es", "fr", "de", "tr", "ru"}); create_settings_functor("CurrentLang", QString("en")); create_settings_functor("2FA", 0); create_settings_functor("MaximumNbCoinsEnabled", 50); @@ -334,10 +352,10 @@ inline int run_app(int argc, char** argv) { #if !defined(ATOMICDEX_HOT_RELOAD) - SPDLOG_INFO("Installing qt_message_handler"); + SPDLOG_DEBUG("Installing qt_message_handler"); qInstallMessageHandler(&qt_message_handler); #endif - SPDLOG_INFO( + SPDLOG_DEBUG( "SSL: {} {} {}", QSslSocket::supportsSsl(), QSslSocket::sslLibraryBuildVersionString().toStdString(), QSslSocket::sslLibraryVersionString().toStdString()); @@ -346,11 +364,11 @@ run_app(int argc, char** argv) qputenv("QT_ENABLE_GLYPH_CACHE_WORKAROUND", "1"); qputenv("QML_USE_GLYPHCACHE_WORKAROUND", "1"); - fs::path old_path = fs::path(std::getenv("HOME")) / ".atomic_qt"; - fs::path target_path = atomic_dex::utils::get_atomic_dex_data_folder(); - SPDLOG_INFO("{} exists -> {}", old_path.string(), fs::exists(old_path)); - SPDLOG_INFO("{} exists -> {}", target_path.string(), fs::exists(target_path)); - if (fs::exists(old_path) && !fs::exists(target_path)) + std::filesystem::path old_path = std::filesystem::path(std::getenv("HOME")) / ".atomic_qt"; + std::filesystem::path target_path = atomic_dex::utils::get_atomic_dex_data_folder(); + SPDLOG_INFO("{} exists -> {}", old_path.string(), std::filesystem::exists(old_path)); + SPDLOG_INFO("{} exists -> {}", target_path.string(), std::filesystem::exists(target_path)); + if (std::filesystem::exists(old_path) && !std::filesystem::exists(target_path)) { SPDLOG_INFO("Renaming: {} to {}", old_path.string(), target_path.string()); QDir dir; @@ -368,7 +386,7 @@ run_app(int argc, char** argv) init_sodium(); clean_previous_run(); setup_default_themes(); - fs::path settings_path = (atomic_dex::utils::get_current_configs_path() / "cfg.ini"); + std::filesystem::path settings_path = (atomic_dex::utils::get_current_configs_path() / "cfg.ini"); check_settings_reconfiguration(settings_path); init_dpi(); diff --git a/src/core/atomicdex/api/github/github.api.cpp b/src/core/atomicdex/api/github/github.api.cpp deleted file mode 100644 index 81da7421fb..0000000000 --- a/src/core/atomicdex/api/github/github.api.cpp +++ /dev/null @@ -1,85 +0,0 @@ -//! 3rdParty -#include - -//! Project -#include "github.api.hpp" - -namespace atomic_dex::github_api -{ - const std::string api_remote_url{"https://api.github.com/"}; - const auto api_client = std::make_unique(FROM_STD_STR(api_remote_url)); - const std::string github_url{"https://github.com/"}; - const auto github_client = std::make_unique(FROM_STD_STR(github_url)); - - pplx::task get_repository_releases_async(const repository_releases_request& request) - { - web::http::http_request http_request; - web::uri_builder uri_builder; - - uri_builder.append_path(FROM_STD_STR("repos")); - uri_builder.append_path(FROM_STD_STR(request.owner)); - uri_builder.append_path(FROM_STD_STR(request.repository)); - uri_builder.append_path(FROM_STD_STR("releases")); - http_request.set_request_uri(uri_builder.to_uri()); - http_request.set_method(web::http::methods::GET); - return api_client->request(http_request); - } - - // Returns the asset element of the release which corresponds to your OS. - const auto get_matching_os_asset = [](const nlohmann::json& answer) - { - for (auto& asset : answer.at("assets")) - { - std::string asset_download_url = asset.at("browser_download_url"); - - if (asset_download_url.find( -#ifdef __APPLE__ - "osx.dmg" -#elif __linux__ - "linux.AppImage" -#elif _WIN32 - "windows.zip" -#endif - ) != std::string::npos) - { - return asset; - } - } - throw std::runtime_error("get_repository_releases_from_http_response: Cannot found a proper download url."); - }; - - std::vector get_repository_releases_from_http_response(const web::http::http_response& resp) - { - std::vector result{}; - const auto json_answer = nlohmann::json::parse(TO_STD_STR(resp.extract_string(true).get())); - - result.reserve(json_answer.size()); - for (auto& release_obj : json_answer) - { - const auto asset = get_matching_os_asset(release_obj); - - result.push_back(repository_release{ - .url = asset.at("browser_download_url"), - .assets_url = release_obj.at("assets_url"), - .name = asset.at("name"), - .tag_name = release_obj.at("tag_name")}); - } - return result; - } - - repository_release get_last_repository_release_from_http_response(const web::http::http_response& resp) - { - const std::string string_answer = TO_STD_STR(resp.extract_string(true).get()); - const auto json_answer = nlohmann::json::parse(string_answer); - - if (json_answer.empty()) - { - return repository_release{}; - } - - const auto asset = get_matching_os_asset(json_answer.at(0)); - - return repository_release{.url = asset.at("browser_download_url"), .assets_url = json_answer.at(0).at("assets_url"), - .name = asset.at("name"), .tag_name = json_answer.at(0).at("tag_name")}; - } -} diff --git a/src/core/atomicdex/api/github/github.api.hpp b/src/core/atomicdex/api/github/github.api.hpp deleted file mode 100644 index 67e71fad2d..0000000000 --- a/src/core/atomicdex/api/github/github.api.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -//! Std -#include //> std::string -#include //> std::vector - -//! Project -#include "atomicdex/utilities/cpprestsdk.utilities.hpp" - -namespace atomic_dex::github_api -{ - // Request sent to fetch a GitHub repository's releases. - struct repository_releases_request - { - std::string owner; - std::string repository; - }; - - // Sends a request to GitHub to fetch every existing release of a valid repository. - [[nodiscard]] pplx::task get_repository_releases_async(const repository_releases_request& request); - - // GitHub repository release information. - struct repository_release - { - std::string url; - std::string assets_url; - std::string name; - std::string tag_name; - }; - - // Parses the http response returned by `get_repository_releases_async`. Be careful, resp must have returned 200. - [[nodiscard]] std::vector get_repository_releases_from_http_response(const web::http::http_response& resp); - - // Parses only the first release returned by `get_repository_releases_async`. Be careful, resp must have returned 200. - [[nodiscard]] repository_release get_last_repository_release_from_http_response(const web::http::http_response& resp); - - struct download_repository_release_request - { - std::string owner; - std::string repository; - std::string tag_name; - std::string name; - }; -} diff --git a/src/core/atomicdex/api/komodo_prices/komodo.prices.cpp b/src/core/atomicdex/api/komodo_prices/komodo.prices.cpp index c403ee2966..65ca7505bb 100644 --- a/src/core/atomicdex/api/komodo_prices/komodo.prices.cpp +++ b/src/core/atomicdex/api/komodo_prices/komodo.prices.cpp @@ -79,8 +79,8 @@ namespace atomic_dex::komodo_prices::api { web::http::http_request req; req.set_method(web::http::methods::GET); - SPDLOG_INFO("url: {}", TO_STD_STR(g_komodo_prices_client->base_uri().to_string()) + "api/v2/tickers?expire_at=600"); - req.set_request_uri(FROM_STD_STR("/api/v2/tickers?expire_at=600")); + SPDLOG_INFO("url: {}", TO_STD_STR(g_komodo_prices_client->base_uri().to_string()) + "api/v2/tickers?expire_at=21600"); + req.set_request_uri(FROM_STD_STR("/api/v2/tickers?expire_at=21600")); return fallback ? g_komodo_prices_client_fallback->request(req) : g_komodo_prices_client->request(req); } } // namespace atomic_dex::komodo_prices::api diff --git a/src/core/atomicdex/api/mm2/balance.infos.cpp b/src/core/atomicdex/api/mm2/balance.infos.cpp new file mode 100644 index 0000000000..73c1c8753c --- /dev/null +++ b/src/core/atomicdex/api/mm2/balance.infos.cpp @@ -0,0 +1,31 @@ +/****************************************************************************** + * Copyright © 2013-2022 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. * + * * + ******************************************************************************/ + +//! Dependencies Headers +#include + +// Project Headers +#include "balance.infos.hpp" + +namespace atomic_dex::mm2 +{ + void + from_json(const nlohmann::json& j, balance_infos& answer) + { + answer.spendable = j.at("spendable").get(); + answer.unspendable = j.at("unspendable").get(); + } +} // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/balance.infos.hpp b/src/core/atomicdex/api/mm2/balance.infos.hpp new file mode 100644 index 0000000000..5173db0f8a --- /dev/null +++ b/src/core/atomicdex/api/mm2/balance.infos.hpp @@ -0,0 +1,31 @@ +/****************************************************************************** + * Copyright © 2013-2022 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 + +namespace atomic_dex::mm2 +{ + struct balance_infos + { + std::string spendable; + std::string unspendable; + }; + + void from_json(const nlohmann::json& j, balance_infos& answer); +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/balance_info.cpp b/src/core/atomicdex/api/mm2/balance_info.cpp new file mode 100644 index 0000000000..dde88b26a0 --- /dev/null +++ b/src/core/atomicdex/api/mm2/balance_info.cpp @@ -0,0 +1,12 @@ +#include + +#include "balance_info.hpp" + +namespace atomic_dex::mm2 +{ + void from_json(const nlohmann::json& j, balance_info& in) + { + j.at("spendable").get_to(in.spendable); + j.at("unspendable").get_to(in.unspendable); + } +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/balance_info.hpp b/src/core/atomicdex/api/mm2/balance_info.hpp new file mode 100644 index 0000000000..f40047c368 --- /dev/null +++ b/src/core/atomicdex/api/mm2/balance_info.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include + +#include //> nlohmann::json + +namespace atomic_dex::mm2 +{ + struct balance_info + { + std::string spendable; + std::string unspendable; + }; + + void from_json(const nlohmann::json& j, balance_info& in); +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/enable_bch_with_tokens_rpc.cpp b/src/core/atomicdex/api/mm2/enable_bch_with_tokens_rpc.cpp new file mode 100644 index 0000000000..26b248f4a1 --- /dev/null +++ b/src/core/atomicdex/api/mm2/enable_bch_with_tokens_rpc.cpp @@ -0,0 +1,81 @@ +#include + +#include "enable_bch_with_tokens_rpc.hpp" + +namespace atomic_dex::mm2 +{ + void to_json(nlohmann::json& j, const enable_bch_with_tokens_request_rpc& in) + { + j["ticker"] = in.ticker; + j["bchd_urls"] = in.bchd_urls; + j["tx_history"] = in.tx_history; + j["allow_slp_unsafe_conf"] = in.allow_slp_unsafe_conf.value_or(false); + j["mode"] = in.mode; + j["slp_tokens_requests"] = in.slp_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(); + if (in.address_format.has_value()) + j["address_format"] = in.address_format.value(); + if (in.utxo_merge_params.has_value()) + j["utxo_merge_params"] = in.utxo_merge_params.value(); + } + + void to_json(nlohmann::json& j, const enable_bch_with_tokens_request_rpc::mode_t& in) + { + j["rpc"] = in.rpc; + j["rpc_data"] = in.rpc_data; + } + + void to_json(nlohmann::json& j, const enable_bch_with_tokens_request_rpc::mode_t::data& in) + { + 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) + { + out.current_block = json["current_block"]; + out.bch_addresses_infos = json["bch_addresses_infos"].get(); + out.slp_addresses_infos = json["slp_addresses_infos"].get(); + } + + void from_json(const nlohmann::json& json, enable_bch_with_tokens_result_rpc::derivation_method_t& out) + { + out.type = json["type"]; + } + + void from_json(const nlohmann::json& json, enable_bch_with_tokens_result_rpc::bch_address_infos_t& out) + { + out.derivation_method = json["derivation_method"]; + out.pubkey = json["pubkey"]; + out.balances = json["balances"]; + } + + void from_json(const nlohmann::json& json, enable_bch_with_tokens_result_rpc::slp_address_infos_t& out) + { + out.derivation_method = json["derivation_method"]; + out.pubkey = json["pubkey"]; + out.balances = json["balances"].get(); + } +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/enable_bch_with_tokens_rpc.hpp b/src/core/atomicdex/api/mm2/enable_bch_with_tokens_rpc.hpp new file mode 100644 index 0000000000..88f8f66cd7 --- /dev/null +++ b/src/core/atomicdex/api/mm2/enable_bch_with_tokens_rpc.hpp @@ -0,0 +1,96 @@ +#pragma once + +#include + +#include "rpc.hpp" +#include "balance_info.hpp" +#include "atomicdex/config/electrum.cfg.hpp" + +namespace atomic_dex::mm2 +{ + struct enable_bch_with_tokens_rpc + { + static constexpr auto endpoint = "enable_bch_with_tokens"; + static constexpr bool is_v2 = true; + + struct expected_request_type + { + struct mode_t + { + struct data { std::vector servers; }; + + std::string rpc{"Electrum"}; + data rpc_data; + }; + struct slp_token_request_t + { + 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}; + std::vector bchd_urls; + mode_t mode; + bool tx_history{true}; + std::vector slp_tokens_requests; + std::optional required_confirmations; + std::optional requires_notarization; + std::optional address_format; + std::optional utxo_merge_params; + }; + + struct expected_result_type + { + struct derivation_method_t { std::string type; }; + struct bch_address_infos_t + { + derivation_method_t derivation_method; + std::string pubkey; + balance_info balances; + }; + struct slp_address_infos_t + { + derivation_method_t derivation_method; + std::string pubkey; + std::unordered_map balances; + }; + + std::size_t current_block; + std::unordered_map bch_addresses_infos; + std::unordered_map slp_addresses_infos; + }; + + using expected_error_type = rpc_basic_error_type; + + expected_request_type request; + std::optional result; + std::optional error; + }; + + using enable_bch_with_tokens_request_rpc = enable_bch_with_tokens_rpc::expected_request_type; + using enable_bch_with_tokens_result_rpc = enable_bch_with_tokens_rpc::expected_result_type; + using enable_bch_with_tokens_error_rpc = enable_bch_with_tokens_rpc::expected_error_type; + + 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 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); + void from_json(const nlohmann::json& json, enable_bch_with_tokens_result_rpc::slp_address_infos_t& out); +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/enable_slp_rpc.cpp b/src/core/atomicdex/api/mm2/enable_slp_rpc.cpp new file mode 100644 index 0000000000..314005d743 --- /dev/null +++ b/src/core/atomicdex/api/mm2/enable_slp_rpc.cpp @@ -0,0 +1,28 @@ +#include + +#include "enable_slp_rpc.hpp" + +namespace atomic_dex::mm2 +{ + void to_json(nlohmann::json& j, const enable_slp_rpc_request& request) + { + j["ticker"] = request.ticker; + if (request.activation_params.required_confirmations) + { + j["activation_params"]["required_confirmations"] = *request.activation_params.required_confirmations; + } + else + { + j["activation_params"] = nlohmann::json::object(); + } + } + + void from_json(const nlohmann::json& j, enable_slp_rpc_result& in) + { + j.at("token_id").get_to(in.token_id); + j.at("platform_coin").get_to(in.platform_coin); + j.at("required_confirmations").get_to(in.required_confirmations); + j.at("token_id").get_to(in.token_id); + j.at("balances").get_to>(in.balances); + } +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/enable_slp_rpc.hpp b/src/core/atomicdex/api/mm2/enable_slp_rpc.hpp new file mode 100644 index 0000000000..f3bce14e44 --- /dev/null +++ b/src/core/atomicdex/api/mm2/enable_slp_rpc.hpp @@ -0,0 +1,62 @@ +/****************************************************************************** + * Copyright © 2013-2022 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 + +#include //> nlohmann::json + +#include "rpc.hpp" +#include "balance_info.hpp" + +namespace atomic_dex::mm2 +{ + struct enable_slp_rpc + { + static constexpr auto endpoint = "enable_slp"; + static constexpr bool is_v2 = true; + + struct expected_request_type + { + std::string ticker; + struct { std::optional required_confirmations; } activation_params; + }; + + struct expected_result_type + { + std::string token_id; + std::string platform_coin; + int required_confirmations; + std::unordered_map balances; + }; + + using expected_error_type = rpc_basic_error_type; + + expected_request_type request; + std::optional result; + std::optional error; + }; + + using enable_slp_rpc_request = enable_slp_rpc::expected_request_type; + using enable_slp_rpc_result = enable_slp_rpc::expected_result_type; + using enable_slp_rpc_error = enable_slp_rpc::expected_error_type; + + void to_json(nlohmann::json& j, const enable_slp_rpc_request& request); + void from_json(const nlohmann::json& j, enable_slp_rpc_result& in); +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/format.address.cpp b/src/core/atomicdex/api/mm2/format.address.cpp new file mode 100644 index 0000000000..e860019e11 --- /dev/null +++ b/src/core/atomicdex/api/mm2/format.address.cpp @@ -0,0 +1,31 @@ +/****************************************************************************** + * Copyright © 2013-2022 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. * + * * + ******************************************************************************/ + +//! Dependencies Headers +#include + +//! Project Headers +#include "format.address.hpp" + +namespace atomic_dex::mm2 +{ + void + to_json(nlohmann::json& j, const format_address& cfg) + { + j["format"] = cfg.format; + j["network"] = cfg.network; + } +} // 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/format.address.hpp new file mode 100644 index 0000000000..c6f9db230c --- /dev/null +++ b/src/core/atomicdex/api/mm2/format.address.hpp @@ -0,0 +1,31 @@ +/****************************************************************************** + * Copyright © 2013-2022 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 + +namespace atomic_dex::mm2 +{ + struct format_address + { + std::string format; + std::string network; + }; + + void to_json(nlohmann::json& j, const format_address& cfg); +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/fraction.cpp b/src/core/atomicdex/api/mm2/fraction.cpp index 705e82e620..0bcdc944fc 100644 --- a/src/core/atomicdex/api/mm2/fraction.cpp +++ b/src/core/atomicdex/api/mm2/fraction.cpp @@ -1,19 +1,12 @@ -// -// Created by Roman Szterg on 13/02/2021. -// - -//! Deps #include -//! Project Headers #include "atomicdex/api/mm2/fraction.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { - void - from_json(const nlohmann::json& j, fraction& fraction) + void from_json(const nlohmann::json& j, mm2::fraction& fraction) { j.at("denom").get_to(fraction.denom); j.at("numer").get_to(fraction.numer); } -} // namespace mm2::api \ No newline at end of file +} // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/fraction.fwd.hpp b/src/core/atomicdex/api/mm2/fraction.fwd.hpp index 751790ad4a..8b0b7bb20c 100644 --- a/src/core/atomicdex/api/mm2/fraction.fwd.hpp +++ b/src/core/atomicdex/api/mm2/fraction.fwd.hpp @@ -1,6 +1,6 @@ #pragma once -namespace mm2::api +namespace atomic_dex::mm2 { struct fraction; } \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/fraction.hpp b/src/core/atomicdex/api/mm2/fraction.hpp index c1a8895e2d..c197c8a478 100644 --- a/src/core/atomicdex/api/mm2/fraction.hpp +++ b/src/core/atomicdex/api/mm2/fraction.hpp @@ -1,13 +1,11 @@ #pragma once -//! STD #include -//! Deps #include #include -namespace mm2::api +namespace atomic_dex::mm2 { struct fraction { @@ -15,5 +13,5 @@ namespace mm2::api std::string numer; }; - ENTT_API void from_json(const nlohmann::json& j, fraction& fraction); + ENTT_API void from_json(const nlohmann::json& j, mm2::fraction& fraction); } \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/generic.error.cpp b/src/core/atomicdex/api/mm2/generic.error.cpp index 4c0f6ab146..85943adcf6 100644 --- a/src/core/atomicdex/api/mm2/generic.error.cpp +++ b/src/core/atomicdex/api/mm2/generic.error.cpp @@ -1,13 +1,8 @@ -// -// Created by Sztergbaum Roman on 08/06/2021. -// - #include "atomicdex/api/mm2/generic.error.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { - void - from_json(const nlohmann::json& j, generic_answer_error& res) + void from_json(const nlohmann::json& j, generic_answer_error& res) { j.at("error").get_to(res.error); j.at("error_path").get_to(res.error_path); @@ -15,4 +10,4 @@ namespace mm2::api j.at("error_type").get_to(res.error_type); j.at("error_data").get_to(res.error_data); } -} // namespace mm2::api \ No newline at end of file +} // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/generic.error.hpp b/src/core/atomicdex/api/mm2/generic.error.hpp index a7de90b803..7be792aae5 100644 --- a/src/core/atomicdex/api/mm2/generic.error.hpp +++ b/src/core/atomicdex/api/mm2/generic.error.hpp @@ -6,7 +6,7 @@ //! Deps #include -namespace mm2::api +namespace atomic_dex::mm2 { struct generic_answer_error { @@ -18,4 +18,4 @@ namespace mm2::api }; void from_json(const nlohmann::json& j, generic_answer_error& res); -} // namespace mm2::api \ No newline at end of file +} // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/generics.cpp b/src/core/atomicdex/api/mm2/generics.cpp index 6920b12069..58ec61a052 100644 --- a/src/core/atomicdex/api/mm2/generics.cpp +++ b/src/core/atomicdex/api/mm2/generics.cpp @@ -30,7 +30,7 @@ #include "atomicdex/api/mm2/rpc.validate.address.hpp" #include "atomicdex/api/mm2/rpc.recover.funds.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { template void @@ -56,4 +56,4 @@ namespace mm2::api 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); template void extract_rpc_json_answer(const nlohmann::json& j, recover_funds_of_swap_answer& answer); -} // namespace mm2::api \ No newline at end of file +} // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/generics.hpp b/src/core/atomicdex/api/mm2/generics.hpp index 5c40f63053..f8dc01c009 100644 --- a/src/core/atomicdex/api/mm2/generics.hpp +++ b/src/core/atomicdex/api/mm2/generics.hpp @@ -18,7 +18,7 @@ #include -namespace mm2::api +namespace atomic_dex::mm2 { template void diff --git a/src/core/atomicdex/api/mm2/rpc.get.public.key.cpp b/src/core/atomicdex/api/mm2/get_public_key_rpc.cpp similarity index 86% rename from src/core/atomicdex/api/mm2/rpc.get.public.key.cpp rename to src/core/atomicdex/api/mm2/get_public_key_rpc.cpp index 966f4d911a..fe8559710b 100644 --- a/src/core/atomicdex/api/mm2/rpc.get.public.key.cpp +++ b/src/core/atomicdex/api/mm2/get_public_key_rpc.cpp @@ -14,15 +14,18 @@ * * ******************************************************************************/ -// Deps Headers #include -// Project Headers -#include "rpc.get.public.key.hpp" +#include "get_public_key_rpc.hpp" namespace atomic_dex::mm2 { - void from_json(const nlohmann::json& json, get_public_key_answer& in) + void to_json(nlohmann::json& j, const get_public_key_rpc_request& request) + { + + } + + void from_json(const nlohmann::json& json, get_public_key_rpc_result& in) { json.at("public_key").get_to(in.public_key); } diff --git a/src/core/atomicdex/api/mm2/get_public_key_rpc.hpp b/src/core/atomicdex/api/mm2/get_public_key_rpc.hpp new file mode 100644 index 0000000000..fefb0235e2 --- /dev/null +++ b/src/core/atomicdex/api/mm2/get_public_key_rpc.hpp @@ -0,0 +1,54 @@ +/****************************************************************************** + * Copyright © 2013-2022 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 + +#include + +#include "rpc.hpp" + +namespace atomic_dex::mm2 +{ + struct get_public_key_rpc + { + static constexpr auto endpoint = "get_public_key"; + static constexpr bool is_v2 = true; + + struct expected_request_type{}; + + struct expected_result_type + { + std::string public_key; + }; + + using expected_error_type = rpc_basic_error_type; + + expected_request_type request; + std::optional result; + std::optional error; + }; + + using get_public_key_rpc_request = get_public_key_rpc::expected_request_type; + using get_public_key_rpc_result = get_public_key_rpc::expected_result_type; + using get_public_key_rpc_error = get_public_key_rpc::expected_error_type; + + void to_json([[maybe_unused]] nlohmann::json& j, const get_public_key_rpc_request&); + void from_json(const nlohmann::json& json, get_public_key_rpc_result& in); +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/mm2.client.cpp b/src/core/atomicdex/api/mm2/mm2.client.cpp index 0b51757b58..381cb28822 100644 --- a/src/core/atomicdex/api/mm2/mm2.client.cpp +++ b/src/core/atomicdex/api/mm2/mm2.client.cpp @@ -14,15 +14,20 @@ * * ******************************************************************************/ -// Deps Headers +#include + #include -// Project Headers -#include "atomicdex/api/mm2/mm2.client.hpp" -#include "atomicdex/api/mm2/mm2.hpp" -#include "atomicdex/api/mm2/rpc.tx.history.hpp" -#include "rpc.get.public.key.hpp" +#include "enable_slp_rpc.hpp" +#include "get_public_key_rpc.hpp" +#include "enable_bch_with_tokens_rpc.hpp" +#include "my_tx_history_rpc.hpp" +#include "my_tx_history_v1_rpc.hpp" +#include "mm2.client.hpp" +#include "mm2.hpp" +#include "atomicdex/constants/dex.constants.hpp" #include "rpc.hpp" +#include "rpc.tx.history.hpp" namespace { @@ -31,49 +36,60 @@ namespace t_http_client generate_client() { - web::http::client::http_client_config cfg; using namespace std::chrono_literals; - cfg.set_timeout(30s); - return web::http::client::http_client(FROM_STD_STR(::mm2::api::g_endpoint), cfg); + + constexpr auto client_timeout = 30s; + web::http::client::http_client_config cfg; + + cfg.set_timeout(client_timeout); + return {FROM_STD_STR(atomic_dex::g_dex_rpc), cfg}; } - template + template web::http::http_request make_request(typename Rpc::expected_request_type data_req = {}) { web::http::http_request request; - nlohmann::json json_req = {{"method", Rpc::endpoint}, {"userpass", mm2::api::get_rpc_password()}}; + nlohmann::json json_req = {{"method", Rpc::endpoint}, {"userpass", atomic_dex::mm2::get_rpc_password()}}; + nlohmann::json json_data; + nlohmann::to_json(json_data, data_req); request.set_method(web::http::methods::POST); if (Rpc::is_v2) { json_req["mmrpc"] = "2.0"; - json_req.push_back({"params", data_req}); + json_req.push_back({"params", json_data}); } else { - json_req.insert(json_req.end(), nlohmann::json(data_req)); + json_req.insert(json_req.end(), json_data); } request.set_body(json_req.dump()); return request; } - template - typename Rpc::expected_answer_type make_answer(const web::http::http_response& answer) + template + Rpc process_rpc_answer(const web::http::http_response& answer) { + Rpc rpc; auto json_answer = nlohmann::json::parse(TO_STD_STR(answer.extract_string(true).get())); + if (Rpc::is_v2) { - return json_answer.at("result").get(); + if (answer.status_code() == 200) + rpc.result = json_answer.at("result").get(); + else + rpc.error = json_answer.get(); } - return json_answer.get(); + else + rpc.result = json_answer.get(); + return rpc; } } // namespace -namespace atomic_dex +namespace atomic_dex::mm2 { template - RpcReturnType - mm2_client::rpc_process_answer(const web::http::http_response& resp, const std::string& rpc_command) + RpcReturnType mm2_client::rpc_process_answer(const web::http::http_response& resp, const std::string& rpc_command) { std::string body = TO_STD_STR(resp.extract_string(true).get()); SPDLOG_INFO("resp code for rpc_command {} is {}", rpc_command, resp.status_code()); @@ -116,7 +132,7 @@ namespace atomic_dex catch (const std::exception& error) { SPDLOG_ERROR( - "{} l{} f[{}], exception caught {} for rpc {}, body: {}", __FUNCTION__, __LINE__, fs::path(__FILE__).filename().string(), error.what(), + "{} l{} f[{}], exception caught {} for rpc {}, body: {}", __FUNCTION__, __LINE__, std::filesystem::path(__FILE__).filename().string(), error.what(), rpc_command, body); answer.rpc_result_code = -1; answer.raw_result = error.what(); @@ -135,18 +151,31 @@ namespace atomic_dex return resp; } - template <::mm2::api::rpc ApiCallType> - void mm2_client::process_rpc_async(const std::function& on_rpc_processed) + template + void mm2_client::process_rpc_async(const std::function& on_rpc_processed) { - auto request = make_request(); + 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(typename Rpc::expected_request_type request, const std::function& on_rpc_processed) + { + auto http_request = make_request(request); generate_client() - .request(request, m_token_source.get_token()) - .template then([on_rpc_processed](const web::http::http_response& resp) + .request(http_request, m_token_source.get_token()) + .template then([on_rpc_processed, request](const web::http::http_response& resp) { try { - auto answer = make_answer(resp); - on_rpc_processed(answer); + auto rpc = process_rpc_answer(resp); + rpc.request = request; + on_rpc_processed(rpc); } catch (const std::exception& ex) { @@ -155,8 +184,6 @@ namespace atomic_dex }); } - template void mm2_client::process_rpc_async(const std::function&); - void mm2_client::stop() { @@ -167,11 +194,11 @@ namespace atomic_dex TAnswer mm2_client::process_rpc(TRequest&& request, std::string rpc_command) { - SPDLOG_INFO("Processing rpc call: {}", rpc_command); + SPDLOG_DEBUG("Processing rpc call: {}", rpc_command); - nlohmann::json json_data = ::mm2::api::template_request(rpc_command); + nlohmann::json json_data = mm2::template_request(rpc_command); - ::mm2::api::to_json(json_data, request); + mm2::to_json(json_data, request); auto json_copy = json_data; json_copy["userpass"] = "*******"; @@ -198,5 +225,5 @@ namespace atomic_dex } } // namespace atomic_dex -template mm2::api::tx_history_answer atomic_dex::mm2_client::rpc_process_answer(const web::http::http_response& resp, const std::string& rpc_command); -template mm2::api::disable_coin_answer atomic_dex::mm2_client::rpc_process_answer(const web::http::http_response& resp, const std::string& rpc_command); \ No newline at end of file +template atomic_dex::mm2::tx_history_answer atomic_dex::mm2::mm2_client::rpc_process_answer(const web::http::http_response& resp, const std::string& rpc_command); +template atomic_dex::mm2::disable_coin_answer atomic_dex::mm2::mm2_client::rpc_process_answer(const web::http::http_response& resp, const std::string& rpc_command); \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/mm2.client.hpp b/src/core/atomicdex/api/mm2/mm2.client.hpp index fb86964b2f..22f9a94c89 100644 --- a/src/core/atomicdex/api/mm2/mm2.client.hpp +++ b/src/core/atomicdex/api/mm2/mm2.client.hpp @@ -12,7 +12,7 @@ #include "rpc.recover.funds.hpp" #include "rpc.hpp" -namespace atomic_dex +namespace atomic_dex::mm2 { class ENTT_API mm2_client { @@ -28,8 +28,10 @@ namespace atomic_dex //! API pplx::task async_rpc_batch_standalone(nlohmann::json batch_array); - template - void process_rpc_async(const std::function& on_rpc_processed); + template + void process_rpc_async(const std::function& on_rpc_processed); + template + void process_rpc_async(typename Rpc::expected_request_type request, const std::function& on_rpc_processed); //! Synced template diff --git a/src/core/atomicdex/api/mm2/mm2.cpp b/src/core/atomicdex/api/mm2/mm2.cpp index b9beab57dc..d889bd07d1 100644 --- a/src/core/atomicdex/api/mm2/mm2.cpp +++ b/src/core/atomicdex/api/mm2/mm2.cpp @@ -23,9 +23,11 @@ #include "atomicdex/api/mm2/rpc.convertaddress.hpp" #include "atomicdex/api/mm2/rpc.min.volume.hpp" #include "atomicdex/api/mm2/rpc.orderbook.hpp" +#include "atomicdex/api/mm2/rpc.recover.funds.hpp" #include "atomicdex/api/mm2/rpc.trade.preimage.hpp" #include "atomicdex/api/mm2/rpc.validate.address.hpp" #include "atomicdex/api/mm2/rpc.withdraw.hpp" +#include "atomicdex/api/mm2/rpc2.withdraw_status.hpp" #include "atomicdex/api/mm2/rpc.recover.funds.hpp" #include "atomicdex/pages/qt.settings.page.hpp" #include "atomicdex/services/price/global.provider.hpp" @@ -167,7 +169,7 @@ namespace } } // namespace -namespace mm2::api +namespace atomic_dex::mm2 { void to_json(nlohmann::json& j, const send_raw_transaction_request& cfg) @@ -285,7 +287,7 @@ namespace mm2::api .base_amount = action == "Sell" ? base_amount : rel_amount, .rel_amount = action == "Sell" ? rel_amount : base_amount, .order_type = is_maker ? "maker" : "taker", - .human_date = QString::fromStdString(atomic_dex::utils::to_human_date(time_key / 1000, "%F %T")), + .human_date = QString::fromStdString(atomic_dex::utils::to_human_date(time_key / 1000, "%F %T")), .unix_timestamp = static_cast(time_key), .order_id = QString::fromStdString(key), .order_status = "matching", @@ -428,7 +430,7 @@ namespace mm2::api { const nlohmann::json& j_evt = content.at("event"); auto timestamp = content.at("timestamp").get(); - std::string human_date = atomic_dex::utils::to_human_date(timestamp / 1000, "%F %H:%M:%S"); + std::string human_date = atomic_dex::utils::to_human_date(timestamp / 1000, "%F %H:%M:%S"); auto evt_type = j_evt.at("type").get(); auto rate_bundler = @@ -473,6 +475,15 @@ namespace mm2::api jf_evt["time_diff"] = res; event_timestamp_registry["Started"] = ts2; // Started finished at this time total_time_in_ms += res; + + if (jf_evt.at("data").contains("taker_payment_lock")) + { + contents.paymentLock = jf_evt.at("data").at("taker_payment_lock").get() * 1000; + } + else if (jf_evt.at("data").contains("maker_payment_lock")) + { + contents.paymentLock = jf_evt.at("data").at("maker_payment_lock").get() * 1000; + } } if (idx > 0) @@ -584,7 +595,7 @@ namespace mm2::api nlohmann::json json_data = template_request("version"); try { - auto client = std::make_unique(FROM_STD_STR("http://127.0.0.1:7783")); + 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()); @@ -697,24 +708,25 @@ namespace mm2::api return answer; } - template mm2::api::withdraw_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); - template mm2::api::my_orders_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); - template mm2::api::orderbook_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); - template mm2::api::trade_fee_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); - template mm2::api::max_taker_vol_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); - template mm2::api::min_volume_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); - template mm2::api::my_recent_swaps_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); - template mm2::api::active_swaps_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); - template mm2::api::show_priv_key_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); - template mm2::api::trade_preimage_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); - template mm2::api::best_orders_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); - template mm2::api::validate_address_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); - template mm2::api::convert_address_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); - template mm2::api::recover_funds_of_swap_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); + 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); + template mm2::my_recent_swaps_answer rpc_process_answer_batch(nlohmann::json& json_answer, const std::string& rpc_command); + 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); void set_system_manager(ag::ecs::system_manager& system_manager) { g_system_mgr = std::addressof(system_manager); } -} // namespace mm2::api +} // namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/mm2.hpp b/src/core/atomicdex/api/mm2/mm2.hpp index 57b15785fd..ae8c9f170d 100644 --- a/src/core/atomicdex/api/mm2/mm2.hpp +++ b/src/core/atomicdex/api/mm2/mm2.hpp @@ -32,9 +32,8 @@ namespace ag = antara::gaming; -namespace mm2::api +namespace atomic_dex::mm2 { - inline constexpr const char* g_endpoint = "http://127.0.0.1:7783"; inline constexpr const char* g_etherscan_proxy_endpoint = "https://komodo.live:3334"; inline std::unique_ptr g_etherscan_proxy_http_client{ std::make_unique(FROM_STD_STR(g_etherscan_proxy_endpoint))}; @@ -239,16 +238,16 @@ namespace mm2::api void set_rpc_password(std::string rpc_password) ; const std::string& get_rpc_password() ; void set_system_manager(ag::ecs::system_manager& system_manager); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_my_orders_answer = ::mm2::api::my_orders_answer; - using t_broadcast_request = ::mm2::api::send_raw_transaction_request; - using t_my_recent_swaps_answer = ::mm2::api::my_recent_swaps_answer; - using t_my_recent_swaps_request = ::mm2::api::my_recent_swaps_request; - using t_active_swaps_request = ::mm2::api::active_swaps_request; - using t_active_swaps_answer = ::mm2::api::active_swaps_answer; - using t_get_trade_fee_request = ::mm2::api::trade_fee_request; - using t_get_trade_fee_answer = ::mm2::api::trade_fee_answer; + using t_my_orders_answer = mm2::my_orders_answer; + using t_broadcast_request = mm2::send_raw_transaction_request; + using t_my_recent_swaps_answer = mm2::my_recent_swaps_answer; + using t_my_recent_swaps_request = mm2::my_recent_swaps_request; + using t_active_swaps_request = mm2::active_swaps_request; + using t_active_swaps_answer = mm2::active_swaps_answer; + using t_get_trade_fee_request = mm2::trade_fee_request; + using t_get_trade_fee_answer = mm2::trade_fee_answer; } // namespace atomic_dex diff --git a/src/core/atomicdex/api/mm2/my_tx_history_rpc.cpp b/src/core/atomicdex/api/mm2/my_tx_history_rpc.cpp new file mode 100644 index 0000000000..6a0c86ef95 --- /dev/null +++ b/src/core/atomicdex/api/mm2/my_tx_history_rpc.cpp @@ -0,0 +1,31 @@ +// atomicdex-desktop +// Author(s): syl + +#include + +#include "my_tx_history_rpc.hpp" + +namespace atomic_dex::mm2 +{ + void to_json(nlohmann::json& j, const my_tx_history_request_rpc& in) + { + j["coin"] = in.coin; + j["limit"] = in.limit; + j["paging_options"] = nlohmann::json::object(); + if (in.paging_options.from_id) + { + j["paging_options"]["FromId"] = *in.paging_options.from_id; + } + if (in.paging_options.page_number) + { + j["paging_options"]["PageNumber"] = *in.paging_options.page_number; + } + } + + void from_json(const nlohmann::json& json, my_tx_history_result_rpc& out) + { + out.coin = json["coin"]; + out.current_block = json["current_block"]; + out.transactions = json["transactions"].get>(); + } +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/my_tx_history_rpc.hpp b/src/core/atomicdex/api/mm2/my_tx_history_rpc.hpp new file mode 100644 index 0000000000..ea308b14b6 --- /dev/null +++ b/src/core/atomicdex/api/mm2/my_tx_history_rpc.hpp @@ -0,0 +1,46 @@ +// atomicdex-desktop +// Author(s): syl + +#include + +#include "paging_options.hpp" +#include "transaction.data.hpp" +#include "rpc.hpp" + +#pragma once + +namespace atomic_dex::mm2 +{ + struct my_tx_history_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; + }; + + struct expected_result_type + { + std::string coin; + std::size_t current_block; + std::vector transactions; + }; + + using expected_error_type = rpc_basic_error_type; + + expected_request_type request; + std::optional result; + std::optional error; + }; + + 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; + + 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); +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/my_tx_history_v1_rpc.hpp b/src/core/atomicdex/api/mm2/my_tx_history_v1_rpc.hpp new file mode 100644 index 0000000000..8b85d28cc5 --- /dev/null +++ b/src/core/atomicdex/api/mm2/my_tx_history_v1_rpc.hpp @@ -0,0 +1,30 @@ +// atomicdex-desktop +// Author(s): syl + +#pragma once + +#include "rpc.hpp" +#include "rpc.tx.history.hpp" + +namespace atomic_dex::mm2 +{ + struct my_tx_history_v1_rpc + { + static constexpr auto endpoint = "my_tx_history"; + static constexpr bool is_v2 = false; + + using expected_request_type = tx_history_request; + + using expected_result_type = tx_history_answer_success; + + using expected_error_type = rpc_basic_error_type; + + expected_request_type request; + std::optional result; + std::optional error; + }; + + using my_tx_history_request_v1_rpc = my_tx_history_v1_rpc::expected_request_type; + using my_tx_history_result_v1_rpc = my_tx_history_v1_rpc::expected_result_type; + using my_tx_history_error_v1_rpc = my_tx_history_v1_rpc::expected_error_type; +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/orderbook.order.contents.cpp b/src/core/atomicdex/api/mm2/orderbook.order.contents.cpp index 2e0cb2f910..7c066603fd 100644 --- a/src/core/atomicdex/api/mm2/orderbook.order.contents.cpp +++ b/src/core/atomicdex/api/mm2/orderbook.order.contents.cpp @@ -21,54 +21,51 @@ //! Project Headers #include "atomicdex/api/mm2/orderbook.order.contents.hpp" #include "atomicdex/utilities/global.utilities.hpp" +#include "atomicdex/pages/qt.trading.page.hpp" +#include "atomicdex/services/mm2/mm2.service.hpp" +#include "atomicdex/services/price/orderbook.scanner.service.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { void from_json(const nlohmann::json& j, order_contents& contents) { - //SPDLOG_INFO("contents: {}", j.dump(4)); - j.at("coin").get_to(contents.coin); - j.at("address").get_to(contents.address); - j.at("price").get_to(contents.price); - // contents.price = t_float_50(contents.price).str(8, std::ios_base::fixed); - j.at("price_fraction").at("numer").get_to(contents.price_fraction_numer); - j.at("price_fraction").at("denom").get_to(contents.price_fraction_denom); - j.at("max_volume_fraction").at("numer").get_to(contents.max_volume_fraction_numer); - j.at("max_volume_fraction").at("denom").get_to(contents.max_volume_fraction_denom); - j.at("base_min_volume_fraction").at("numer").get_to(contents.base_min_volume_numer); - j.at("base_min_volume_fraction").at("denom").get_to(contents.base_min_volume_denom); - j.at("base_max_volume_fraction").at("numer").get_to(contents.base_max_volume_numer); - j.at("base_max_volume_fraction").at("denom").get_to(contents.base_max_volume_denom); - j.at("rel_min_volume_fraction").at("numer").get_to(contents.rel_min_volume_numer); - j.at("rel_min_volume_fraction").at("denom").get_to(contents.rel_min_volume_denom); - j.at("rel_max_volume_fraction").at("numer").get_to(contents.rel_max_volume_numer); - j.at("rel_max_volume_fraction").at("denom").get_to(contents.rel_max_volume_denom); + j.at("coin").get_to(contents.coin); + if (j.at("address").contains("address_data")) + { + j.at("address").at("address_data").get_to(contents.address); + } + else + { + contents.address = "Shielded"; + } - j.at("maxvolume").get_to(contents.maxvolume); j.at("pubkey").get_to(contents.pubkey); - j.at("age").get_to(contents.age); - j.at("zcredits").get_to(contents.zcredits); j.at("uuid").get_to(contents.uuid); j.at("is_mine").get_to(contents.is_mine); - if (j.contains("min_volume")) - { - contents.min_volume = j.at("min_volume").get(); - } - if (contents.price.find('.') != std::string::npos) - { - boost::trim_right_if(contents.price, boost::is_any_of("0")); - contents.price = contents.price; - } - j.at("base_max_volume").get_to(contents.base_max_volume); - j.at("base_min_volume").get_to(contents.base_min_volume); - j.at("rel_max_volume").get_to(contents.rel_max_volume); - j.at("rel_min_volume").get_to(contents.rel_min_volume); - contents.maxvolume = atomic_dex::utils::adjust_precision(contents.maxvolume); - t_float_50 total_f = safe_float(contents.price) * safe_float(contents.maxvolume); - contents.total = atomic_dex::utils::adjust_precision(total_f.str()); + j.at("price").at("decimal").get_to(contents.price); + j.at("price").at("fraction").at("numer").get_to(contents.price_fraction_numer); + j.at("price").at("fraction").at("denom").get_to(contents.price_fraction_denom); + + j.at("base_min_volume").at("decimal").get_to(contents.base_min_volume); + j.at("base_min_volume").at("fraction").at("numer").get_to(contents.base_min_volume_numer); + j.at("base_min_volume").at("fraction").at("denom").get_to(contents.base_min_volume_denom); + j.at("base_max_volume").at("decimal").get_to(contents.base_max_volume); + j.at("base_max_volume").at("fraction").at("numer").get_to(contents.base_max_volume_numer); + j.at("base_max_volume").at("fraction").at("denom").get_to(contents.base_max_volume_denom); + + j.at("rel_min_volume").at("decimal").get_to(contents.rel_min_volume); + j.at("rel_min_volume").at("fraction").at("numer").get_to(contents.rel_min_volume_numer); + j.at("rel_min_volume").at("fraction").at("denom").get_to(contents.rel_min_volume_denom); + j.at("rel_max_volume").at("decimal").get_to(contents.rel_max_volume); + j.at("rel_max_volume").at("fraction").at("numer").get_to(contents.rel_max_volume_numer); + j.at("rel_max_volume").at("fraction").at("denom").get_to(contents.rel_max_volume_denom); + + // Not in v2 RPC + // j.at("age").get_to(contents.age); + // j.at("zcredits").get_to(contents.zcredits); } std::string @@ -78,7 +75,6 @@ namespace mm2::api ss << "coin: " << coin << " "; ss << "address: " << address << " "; ss << "price: " << price << " "; - ss << "max_volume: " << maxvolume << " "; ss << "depth_percent: " << depth_percent << " "; ss << "base_max_volume: " << base_max_volume << " "; ss << "rel_max_volume: " << rel_max_volume << " "; @@ -86,4 +82,4 @@ namespace mm2::api ss << "rel_min_volume: " << rel_min_volume << " "; return ss.str(); } -} // namespace mm2::api \ No newline at end of file +} // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/orderbook.order.contents.hpp b/src/core/atomicdex/api/mm2/orderbook.order.contents.hpp index a97609de26..0f350e8dab 100644 --- a/src/core/atomicdex/api/mm2/orderbook.order.contents.hpp +++ b/src/core/atomicdex/api/mm2/orderbook.order.contents.hpp @@ -21,7 +21,7 @@ //! Deps #include -namespace mm2::api +namespace atomic_dex::mm2 { struct order_contents { @@ -30,9 +30,12 @@ namespace mm2::api std::string price; std::string price_fraction_numer; std::string price_fraction_denom; + std::string min_volume; + std::string min_volume_fraction_numer; + std::string min_volume_fraction_denom; + std::string max_volume; std::string max_volume_fraction_numer; std::string max_volume_fraction_denom; - std::string maxvolume; std::string base_min_volume; std::string base_min_volume_denom; std::string base_min_volume_numer; @@ -46,23 +49,22 @@ namespace mm2::api std::string rel_max_volume_denom; std::string rel_max_volume_numer; std::string pubkey; - std::size_t age; - std::size_t zcredits; + //std::size_t age; + //std::size_t zcredits; std::string total; std::string uuid; std::string depth_percent; bool is_mine; - std::string min_volume{"0"}; std::optional rel_coin{std::nullopt}; std::string to_string() const noexcept; }; void from_json(const nlohmann::json& j, order_contents& contents); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_order_contents = ::mm2::api::order_contents; + using t_order_contents = mm2::order_contents; using t_orders_contents = std::vector; -} // namespace atomic_dex \ No newline at end of file +} // namespace atomic_dex diff --git a/src/core/atomicdex/api/mm2/paging_options.cpp b/src/core/atomicdex/api/mm2/paging_options.cpp new file mode 100644 index 0000000000..a0f95fc001 --- /dev/null +++ b/src/core/atomicdex/api/mm2/paging_options.cpp @@ -0,0 +1,21 @@ +// atomicdex-desktop +// Author(s): syl + +#include + +#include "paging_options.hpp" + +namespace atomic_dex::mm2 +{ + void to_json(nlohmann::json& j, const paging_options& in) + { + if (in.from_id) + { + j["FromId"] = *in.from_id; + } + if (in.page_number) + { + j["PageNumber"] = *in.page_number; + } + } +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/paging_options.hpp b/src/core/atomicdex/api/mm2/paging_options.hpp new file mode 100644 index 0000000000..df3ba02200 --- /dev/null +++ b/src/core/atomicdex/api/mm2/paging_options.hpp @@ -0,0 +1,19 @@ +// atomicdex-desktop +// Author(s): syl + +#pragma once + +#include + +#include + +namespace atomic_dex::mm2 +{ + struct paging_options + { + std::optional from_id; + std::optional page_number; + }; + + void to_json(nlohmann::json& j, const paging_options& in); +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.balance.cpp b/src/core/atomicdex/api/mm2/rpc.balance.cpp index 47cb997823..02e85451e4 100644 --- a/src/core/atomicdex/api/mm2/rpc.balance.cpp +++ b/src/core/atomicdex/api/mm2/rpc.balance.cpp @@ -21,7 +21,7 @@ #include "atomicdex/api/mm2/rpc.balance.hpp" #include "atomicdex/utilities/global.utilities.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { void to_json(nlohmann::json& j, const balance_request& cfg) @@ -36,9 +36,5 @@ namespace mm2::api j.at("balance").get_to(cfg.balance); cfg.balance = atomic_dex::utils::adjust_precision(cfg.balance); j.at("coin").get_to(cfg.coin); - if (cfg.coin == "BCH") - { - cfg.address = cfg.address.substr(sizeof("bitcoincash")); - } } -} // namespace mm2::api \ No newline at end of file +} // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.balance.hpp b/src/core/atomicdex/api/mm2/rpc.balance.hpp index f4268b5f25..10c403fc12 100644 --- a/src/core/atomicdex/api/mm2/rpc.balance.hpp +++ b/src/core/atomicdex/api/mm2/rpc.balance.hpp @@ -18,7 +18,7 @@ #include -namespace mm2::api +namespace atomic_dex::mm2 { struct balance_request { @@ -37,10 +37,10 @@ namespace mm2::api void to_json(nlohmann::json& j, const balance_request& cfg); void from_json(const nlohmann::json& j, balance_answer& cfg); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_balance_request = ::mm2::api::balance_request; - using t_balance_answer = ::mm2::api::balance_answer; + using t_balance_request = mm2::balance_request; + using t_balance_answer = mm2::balance_answer; } // namespace atomic_dex \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.best.orders.cpp b/src/core/atomicdex/api/mm2/rpc.best.orders.cpp index cab39abea5..05c0027bb6 100644 --- a/src/core/atomicdex/api/mm2/rpc.best.orders.cpp +++ b/src/core/atomicdex/api/mm2/rpc.best.orders.cpp @@ -26,14 +26,16 @@ #include "atomicdex/api/mm2/rpc.best.orders.hpp" //! Implementation RPC [best_orders] -namespace mm2::api +namespace atomic_dex::mm2 { void to_json(nlohmann::json& j, const best_orders_request& req) { - j["coin"] = req.coin; - j["action"] = req.action; - j["volume"] = req.volume; + 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; } void @@ -45,15 +47,15 @@ namespace mm2::api } else { - for (auto&& [key, value]: j.items()) + for (auto&& [key, value]: j["orders"].items()) { - // SPDLOG_INFO("{} best orders size: {}", key, value.size()); //bool hit = false; std::unordered_set uuid_visited; for (auto&& cur_order: value) { order_contents contents; contents.rel_coin = key; + from_json(cur_order, contents); if (uuid_visited.emplace(contents.uuid).second) { @@ -61,15 +63,9 @@ namespace mm2::api } else { - //hit = true; SPDLOG_WARN("Order with uuid: {} already added - skipping", contents.uuid); } } - /*if (hit) - { - SPDLOG_WARN("mm2 answer duplicated: {}", value.dump()); - hit = false; - }*/ } } } @@ -80,4 +76,4 @@ namespace mm2::api extract_rpc_json_answer(j, answer); } -} // namespace mm2::api +} // namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/rpc.best.orders.hpp b/src/core/atomicdex/api/mm2/rpc.best.orders.hpp index c062e68e1a..a89e0729ee 100644 --- a/src/core/atomicdex/api/mm2/rpc.best.orders.hpp +++ b/src/core/atomicdex/api/mm2/rpc.best.orders.hpp @@ -25,7 +25,7 @@ //! Project Headers #include "atomicdex/api/mm2/orderbook.order.contents.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { struct best_orders_request { @@ -52,11 +52,11 @@ namespace mm2::api }; void from_json(const nlohmann::json& j, best_orders_answer& answer); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_best_orders_request = ::mm2::api::best_orders_request; - using t_best_orders_answer = ::mm2::api::best_orders_answer; - using t_best_orders_answer_success = ::mm2::api::best_orders_answer_success; + 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 diff --git a/src/core/atomicdex/api/mm2/rpc.buy.cpp b/src/core/atomicdex/api/mm2/rpc.buy.cpp index 4813ca1e75..09002a24f6 100644 --- a/src/core/atomicdex/api/mm2/rpc.buy.cpp +++ b/src/core/atomicdex/api/mm2/rpc.buy.cpp @@ -22,7 +22,7 @@ #include "atomicdex/api/mm2/generics.hpp" #include "atomicdex/api/mm2/rpc.buy.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { void from_json(const nlohmann::json& j, buy_answer_success& contents) @@ -76,4 +76,4 @@ namespace mm2::api SPDLOG_INFO("The order is not picked from orderbook we create it from volume = {}, price = {}", j.at("volume").dump(4), request.price); } } -} // namespace mm2::api \ No newline at end of file +} // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.buy.hpp b/src/core/atomicdex/api/mm2/rpc.buy.hpp index 0063c6315b..7475510754 100644 --- a/src/core/atomicdex/api/mm2/rpc.buy.hpp +++ b/src/core/atomicdex/api/mm2/rpc.buy.hpp @@ -26,7 +26,7 @@ //! Project Header #include -namespace mm2::api +namespace atomic_dex::mm2 { struct buy_request { @@ -64,11 +64,11 @@ namespace mm2::api }; void from_json(const nlohmann::json& j, buy_answer& answer); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_buy_request = ::mm2::api::buy_request; - using t_buy_answer = ::mm2::api::buy_answer; - using t_buy_answer_success = ::mm2::api::buy_answer_success; + using t_buy_request = mm2::buy_request; + using t_buy_answer = mm2::buy_answer; + using t_buy_answer_success = mm2::buy_answer_success; } // namespace atomic_dex \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.convertaddress.cpp b/src/core/atomicdex/api/mm2/rpc.convertaddress.cpp index 32f3f8fbf3..02dd0b5b71 100644 --- a/src/core/atomicdex/api/mm2/rpc.convertaddress.cpp +++ b/src/core/atomicdex/api/mm2/rpc.convertaddress.cpp @@ -9,10 +9,10 @@ #include "atomicdex/api/mm2/rpc.convertaddress.hpp" #include "atomicdex/api/mm2/generics.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { void - to_json(nlohmann::json& j, const mm2::api::convert_address_request& req) + to_json(nlohmann::json& j, const convert_address_request& req) { j["coin"] = req.coin; j["from"] = req.from; @@ -30,4 +30,4 @@ namespace mm2::api { extract_rpc_json_answer(j, answer); } -} // namespace mm2::api +} // namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/rpc.convertaddress.hpp b/src/core/atomicdex/api/mm2/rpc.convertaddress.hpp index 31e599d4bf..02f1553000 100644 --- a/src/core/atomicdex/api/mm2/rpc.convertaddress.hpp +++ b/src/core/atomicdex/api/mm2/rpc.convertaddress.hpp @@ -6,7 +6,7 @@ //! Deps #include -namespace mm2::api +namespace atomic_dex::mm2 { struct convert_address_request { @@ -33,11 +33,11 @@ namespace mm2::api }; void from_json(const nlohmann::json& j, convert_address_answer& answer); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_convert_address_request = ::mm2::api::convert_address_request; - using t_convert_address_answer = ::mm2::api::convert_address_answer; - using t_convert_address_answer_success = ::mm2::api::convert_address_answer_success; + using t_convert_address_request = mm2::convert_address_request; + using t_convert_address_answer = mm2::convert_address_answer; + using t_convert_address_answer_success = mm2::convert_address_answer_success; } // namespace atomic_dex \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.cpp b/src/core/atomicdex/api/mm2/rpc.cpp new file mode 100644 index 0000000000..af7f8abae3 --- /dev/null +++ b/src/core/atomicdex/api/mm2/rpc.cpp @@ -0,0 +1,15 @@ +#include + +#include "rpc.hpp" + +namespace atomic_dex::mm2 +{ + void from_json(const nlohmann::json& j, rpc_basic_error_type& in) + { + j.at("error").get_to(in.error); + j.at("error_path").get_to(in.error_path); + j.at("error_trace").get_to(in.error_trace); + j.at("error_type").get_to(in.error_type); + j.at("error_data").get_to(in.error_data); + } +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.disable.cpp b/src/core/atomicdex/api/mm2/rpc.disable.cpp index 7e193c196f..2317bcfb77 100644 --- a/src/core/atomicdex/api/mm2/rpc.disable.cpp +++ b/src/core/atomicdex/api/mm2/rpc.disable.cpp @@ -8,7 +8,7 @@ #include "atomicdex/api/mm2/generics.hpp" #include "atomicdex/api/mm2/rpc.disable.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { //! Serialization void @@ -29,4 +29,4 @@ namespace mm2::api { extract_rpc_json_answer(j, resp); } -} // namespace mm2::api \ No newline at end of file +} // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.disable.hpp b/src/core/atomicdex/api/mm2/rpc.disable.hpp index a845f71b09..10159e9b77 100644 --- a/src/core/atomicdex/api/mm2/rpc.disable.hpp +++ b/src/core/atomicdex/api/mm2/rpc.disable.hpp @@ -6,7 +6,7 @@ //! JSON FWD #include -namespace mm2::api +namespace atomic_dex::mm2 { struct disable_coin_request { @@ -31,10 +31,10 @@ namespace mm2::api }; void from_json(const nlohmann::json& j, disable_coin_answer& resp); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_disable_coin_request = ::mm2::api::disable_coin_request; - using t_disable_coin_answer = ::mm2::api::disable_coin_answer; -} \ No newline at end of file + using t_disable_coin_request = mm2::disable_coin_request; + using t_disable_coin_answer = mm2::disable_coin_answer; +} diff --git a/src/core/atomicdex/api/mm2/rpc.electrum.cpp b/src/core/atomicdex/api/mm2/rpc.electrum.cpp index 86d90c695d..dfea39b95b 100644 --- a/src/core/atomicdex/api/mm2/rpc.electrum.cpp +++ b/src/core/atomicdex/api/mm2/rpc.electrum.cpp @@ -21,24 +21,39 @@ #include "atomicdex/api/mm2/rpc.electrum.hpp" //! Implementation RPC [electrum] -namespace mm2::api +namespace atomic_dex::mm2 { //! Serialization void to_json(nlohmann::json& j, const electrum_request& cfg) { j["coin"] = cfg.coin_name; - j["servers"] = cfg.servers; j["tx_history"] = cfg.with_tx_history; + + if (!cfg.servers.empty()) + { + j["servers"] = cfg.servers; + } + if (cfg.coin_type == CoinType::QRC20) { j["swap_contract_address"] = cfg.is_testnet ? cfg.testnet_qrc_swap_contract_address : cfg.mainnet_qrc_swap_contract_address; j["fallback_swap_contract"] = cfg.is_testnet ? cfg.testnet_fallback_qrc_swap_contract_address : cfg.mainnet_fallback_qrc_swap_contract_address; } - if (cfg.address_format.has_value()) { + + if (cfg.bchd_urls.has_value()) { + j["bchd_urls"] = cfg.bchd_urls.value(); + j["allow_slp_unsafe_conf"] = cfg.allow_slp_unsafe_conf.value_or(false); + } + + if (cfg.address_format.has_value()) + { j["address_format"] = cfg.address_format.value(); } - //SPDLOG_INFO("electrum: {}", j.dump()); + if (cfg.merge_params.has_value()) + { + j["utxo_merge_params"] = cfg.merge_params.value(); + } } //! Deserialization @@ -49,4 +64,4 @@ namespace mm2::api j.at("balance").get_to(cfg.balance); j.at("result").get_to(cfg.result); } -} // namespace mm2::api \ No newline at end of file +} // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.electrum.hpp b/src/core/atomicdex/api/mm2/rpc.electrum.hpp index 4c206a9d91..1960e56ec3 100644 --- a/src/core/atomicdex/api/mm2/rpc.electrum.hpp +++ b/src/core/atomicdex/api/mm2/rpc.electrum.hpp @@ -23,20 +23,23 @@ #include "atomicdex/config/electrum.cfg.hpp" #include "atomicdex/constants/qt.coins.enums.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { struct electrum_request { - std::string coin_name; - std::vector servers; - CoinType coin_type; - bool is_testnet{false}; - bool with_tx_history{true}; - const std::string testnet_qrc_swap_contract_address{"0xba8b71f3544b93e2f681f996da519a98ace0107a"}; - const std::string testnet_fallback_qrc_swap_contract_address{testnet_qrc_swap_contract_address}; - const std::string mainnet_qrc_swap_contract_address{"0x2f754733acd6d753731c00fee32cb484551cc15d"}; - const std::string mainnet_fallback_qrc_swap_contract_address{mainnet_qrc_swap_contract_address}; - std::optional address_format; + std::string coin_name; + std::vector servers; + CoinType coin_type; + bool is_testnet{false}; + bool with_tx_history{true}; + const std::string testnet_qrc_swap_contract_address{"0xba8b71f3544b93e2f681f996da519a98ace0107a"}; + const std::string testnet_fallback_qrc_swap_contract_address{testnet_qrc_swap_contract_address}; + const std::string mainnet_qrc_swap_contract_address{"0x2f754733acd6d753731c00fee32cb484551cc15d"}; + const std::string mainnet_fallback_qrc_swap_contract_address{mainnet_qrc_swap_contract_address}; + std::optional address_format; + std::optional merge_params; + std::optional> bchd_urls; + std::optional allow_slp_unsafe_conf; }; struct electrum_answer @@ -51,10 +54,10 @@ namespace mm2::api void to_json(nlohmann::json& j, const electrum_request& cfg); void from_json(const nlohmann::json& j, electrum_answer& answer); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_electrum_request = ::mm2::api::electrum_request; - using t_electrum_answer = ::mm2::api::electrum_answer; + using t_electrum_request = mm2::electrum_request; + using t_electrum_answer = mm2::electrum_answer; } // namespace atomic_dex \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.enable.cpp b/src/core/atomicdex/api/mm2/rpc.enable.cpp index 73d56ead26..0722bb9c23 100644 --- a/src/core/atomicdex/api/mm2/rpc.enable.cpp +++ b/src/core/atomicdex/api/mm2/rpc.enable.cpp @@ -21,7 +21,7 @@ #include "atomicdex/api/mm2/rpc.enable.hpp" //! Implementation RPC [enable] -namespace mm2::api +namespace atomic_dex::mm2 { //! Serialization void @@ -51,17 +51,15 @@ namespace mm2::api case CoinType::Optimism: { j["urls"] = cfg.urls; - j["swap_contract_address"] = cfg.is_testnet ? cfg.optimism_erc_testnet_swap_contract_address : cfg.optimism_erc_swap_contract_address; - j["fallback_swap_contract"] = - cfg.is_testnet ? cfg.optimism_erc_testnet_fallback_swap_contract_address : cfg.optimism_erc_fallback_swap_contract_address; + j["swap_contract_address"] = cfg.optimism_erc_swap_contract_address; + j["fallback_swap_contract"] = cfg.optimism_erc_fallback_swap_contract_address; break; } case CoinType::Arbitrum: { j["urls"] = cfg.urls; - j["swap_contract_address"] = cfg.is_testnet ? cfg.arbitrum_erc_testnet_swap_contract_address : cfg.arbitrum_erc_swap_contract_address; - j["fallback_swap_contract"] = - cfg.is_testnet ? cfg.arbitrum_erc_testnet_fallback_swap_contract_address : cfg.arbitrum_erc_fallback_swap_contract_address; + j["swap_contract_address"] = cfg.arbitrum_erc_swap_contract_address; + j["fallback_swap_contract"] = cfg.arbitrum_erc_fallback_swap_contract_address; break; } case CoinType::BEP20: @@ -164,4 +162,4 @@ namespace mm2::api j.at("result").get_to(cfg.result); // SPDLOG_INFO("balance for {} is {}", cfg.address, cfg.balance); } -} // namespace mm2::api +} // namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/rpc.enable.hpp b/src/core/atomicdex/api/mm2/rpc.enable.hpp index a4616317a1..2b7d3274e3 100644 --- a/src/core/atomicdex/api/mm2/rpc.enable.hpp +++ b/src/core/atomicdex/api/mm2/rpc.enable.hpp @@ -22,7 +22,7 @@ //! Project Headers #include "atomicdex/constants/qt.coins.enums.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { //! Only for erc 20 struct enable_request @@ -77,12 +77,8 @@ namespace mm2::api const std::string matic_erc_testnet_fallback_swap_contract_address{"0x73c1Dd989218c3A154C71Fc08Eb55A24Bd2B3A10"}; const std::string optimism_erc_swap_contract_address{"0x9130b257d37a52e52f21054c4da3450c72f595ce"}; const std::string optimism_erc_fallback_swap_contract_address{"0x9130b257d37a52e52f21054c4da3450c72f595ce"}; - const std::string optimism_erc_testnet_swap_contract_address{"0x9130b257d37a52e52f21054c4da3450c72f595ce"}; - const std::string optimism_erc_testnet_fallback_swap_contract_address{"0x9130b257d37a52e52f21054c4da3450c72f595ce"}; const std::string arbitrum_erc_swap_contract_address{"0x9130b257d37a52e52f21054c4da3450c72f595ce"}; const std::string arbitrum_erc_fallback_swap_contract_address{"0x9130b257d37a52e52f21054c4da3450c72f595ce"}; - const std::string arbitrum_erc_testnet_swap_contract_address{"0x9130b257d37a52e52f21054c4da3450c72f595ce"}; - const std::string arbitrum_erc_testnet_fallback_swap_contract_address{"0x9130b257d37a52e52f21054c4da3450c72f595ce"}; const std::string sbch_erc_swap_contract_address{"0x25bF2AAB8749AD2e4360b3e0B738f3Cd700C4D68"}; const std::string sbch_erc_fallback_swap_contract_address{"0x25bF2AAB8749AD2e4360b3e0B738f3Cd700C4D68"}; const std::string sbch_erc_testnet_swap_contract_address{"0x25bF2AAB8749AD2e4360b3e0B738f3Cd700C4D68"}; @@ -115,10 +111,10 @@ namespace mm2::api }; void from_json(const nlohmann::json& j, const enable_answer& cfg); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_enable_request = ::mm2::api::enable_request; - using t_enable_answer = ::mm2::api::enable_answer; + using t_enable_request = mm2::enable_request; + using t_enable_answer = mm2::enable_answer; } // namespace atomic_dex diff --git a/src/core/atomicdex/api/mm2/rpc.hpp b/src/core/atomicdex/api/mm2/rpc.hpp index 517420762b..4573ed74fb 100644 --- a/src/core/atomicdex/api/mm2/rpc.hpp +++ b/src/core/atomicdex/api/mm2/rpc.hpp @@ -16,17 +16,31 @@ #pragma once -// Std Headers #include -// Project Headers +#include //> nlohmann::json + #include "../api.call.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { template concept rpc = requires(Rpc rpc) { - atomic_dex::api_call && Rpc::is_v2 && std::is_same_v; + atomic_dex::api_call && std::is_same_v; + rpc.request; + rpc.result; + rpc.error; }; + + struct rpc_basic_error_type + { + std::string error; + std::string error_path; + std::string error_trace; + std::string error_type; + std::string error_data; + }; + + void from_json(const nlohmann::json& j, rpc_basic_error_type& in); } diff --git a/src/core/atomicdex/api/mm2/rpc.max.taker.vol.cpp b/src/core/atomicdex/api/mm2/rpc.max.taker.vol.cpp index 554fafc374..c5f666a061 100644 --- a/src/core/atomicdex/api/mm2/rpc.max.taker.vol.cpp +++ b/src/core/atomicdex/api/mm2/rpc.max.taker.vol.cpp @@ -23,7 +23,7 @@ #include "atomicdex/utilities/global.utilities.hpp" //! Implementation RPC [max_taker_vol] -namespace mm2::api +namespace atomic_dex::mm2 { //! Serialization void @@ -42,7 +42,8 @@ namespace mm2::api { j.at("denom").get_to(cfg.denom); j.at("numer").get_to(cfg.numer); - //SPDLOG_INFO("max: {}", j.dump(4)); + // SPDLOG_INFO("max: {}", j.dump(4)); + t_rational rat(boost::multiprecision::cpp_int(cfg.numer), boost::multiprecision::cpp_int(cfg.denom)); t_float_50 res = rat.convert_to(); cfg.decimal = atomic_dex::utils::extract_large_float(res.str(50)); @@ -63,4 +64,4 @@ namespace mm2::api answer.result.value().coin = j.at("coin").get(); } } -} // namespace mm2::api \ No newline at end of file +} // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.max.taker.vol.hpp b/src/core/atomicdex/api/mm2/rpc.max.taker.vol.hpp index cb90104a9a..1f59d4a99f 100644 --- a/src/core/atomicdex/api/mm2/rpc.max.taker.vol.hpp +++ b/src/core/atomicdex/api/mm2/rpc.max.taker.vol.hpp @@ -23,7 +23,7 @@ //! Deps #include -namespace mm2::api +namespace atomic_dex::mm2 { struct max_taker_vol_request { @@ -52,11 +52,11 @@ namespace mm2::api }; void from_json(const nlohmann::json& j, max_taker_vol_answer& answer); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_max_taker_vol_request = ::mm2::api::max_taker_vol_request; - using t_max_taker_vol_answer = ::mm2::api::max_taker_vol_answer; - using t_max_taker_vol_answer_success = ::mm2::api::max_taker_vol_answer_success; + using t_max_taker_vol_request = mm2::max_taker_vol_request; + using t_max_taker_vol_answer = mm2::max_taker_vol_answer; + using t_max_taker_vol_answer_success = mm2::max_taker_vol_answer_success; } // namespace atomic_dex \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.min.volume.cpp b/src/core/atomicdex/api/mm2/rpc.min.volume.cpp index 25695efdf3..392813a3c8 100644 --- a/src/core/atomicdex/api/mm2/rpc.min.volume.cpp +++ b/src/core/atomicdex/api/mm2/rpc.min.volume.cpp @@ -5,7 +5,7 @@ #include "atomicdex/api/mm2/generics.hpp" #include "atomicdex/api/mm2/rpc.min.volume.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { void to_json(nlohmann::json& j, const min_volume_request& cfg) @@ -27,4 +27,4 @@ namespace mm2::api { extract_rpc_json_answer(j, answer); } -} // namespace mm2::api \ No newline at end of file +} // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.min.volume.hpp b/src/core/atomicdex/api/mm2/rpc.min.volume.hpp index d832f19910..3909384cd5 100644 --- a/src/core/atomicdex/api/mm2/rpc.min.volume.hpp +++ b/src/core/atomicdex/api/mm2/rpc.min.volume.hpp @@ -13,7 +13,7 @@ #include "atomicdex/api/mm2/rpc.min.volume.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { struct min_volume_request { @@ -39,11 +39,11 @@ namespace mm2::api }; void from_json(const nlohmann::json& j, min_volume_answer& answer); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_min_volume_request = ::mm2::api::min_volume_request; - using t_min_volume_answer = ::mm2::api::min_volume_answer; - using t_min_volume_answer_success = ::mm2::api::min_volume_answer_success; + using t_min_volume_request = mm2::min_volume_request; + using t_min_volume_answer = mm2::min_volume_answer; + using t_min_volume_answer_success = mm2::min_volume_answer_success; } // namespace atomic_dex \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.orderbook.cpp b/src/core/atomicdex/api/mm2/rpc.orderbook.cpp index 4c2f62bb61..a76afe8dcb 100644 --- a/src/core/atomicdex/api/mm2/rpc.orderbook.cpp +++ b/src/core/atomicdex/api/mm2/rpc.orderbook.cpp @@ -21,60 +21,88 @@ #include "atomicdex/api/mm2/rpc.orderbook.hpp" #include "atomicdex/utilities/global.utilities.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { void from_json(const nlohmann::json& j, orderbook_answer& answer) { using namespace date; + // SPDLOG_INFO("got orderbook data..."); - j.at("base").get_to(answer.base); - j.at("rel").get_to(answer.rel); - j.at("askdepth").get_to(answer.askdepth); - j.at("biddepth").get_to(answer.biddepth); - j.at("bids").get_to(answer.bids); - j.at("asks").get_to(answer.asks); - j.at("numasks").get_to(answer.numasks); - j.at("numbids").get_to(answer.numbids); - j.at("netid").get_to(answer.netid); - j.at("timestamp").get_to(answer.timestamp); + 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); answer.human_timestamp = atomic_dex::utils::to_human_date(answer.timestamp, "%Y-%m-%d %I:%M:%S"); t_float_50 result_asks_f(0); - for (auto&& cur_asks: answer.asks) { result_asks_f = result_asks_f + safe_float(cur_asks.maxvolume); } + for (auto&& cur_asks: answer.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; + cur_asks.max_volume = cur_asks.base_max_volume; + cur_asks.max_volume_fraction_numer = cur_asks.base_max_volume_numer; + cur_asks.max_volume_fraction_denom = cur_asks.base_max_volume_denom; + if (cur_asks.price.find('.') != std::string::npos) + { + boost::trim_right_if(cur_asks.price, boost::is_any_of("0")); + cur_asks.price = cur_asks.price; + } + cur_asks.max_volume = atomic_dex::utils::adjust_precision(cur_asks.max_volume); + t_float_50 total_f = safe_float(cur_asks.price) * safe_float(cur_asks.max_volume); + 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(); t_float_50 result_bids_f(0); for (auto& cur_bids: answer.bids) { - cur_bids.total = cur_bids.maxvolume; - t_float_50 new_volume = safe_float(cur_bids.maxvolume) / safe_float(cur_bids.price); - cur_bids.maxvolume = atomic_dex::utils::adjust_precision(new_volume.str()); - result_bids_f = result_bids_f + safe_float(cur_bids.maxvolume); - } + cur_bids.min_volume = cur_bids.base_min_volume; + cur_bids.min_volume_fraction_numer = cur_bids.base_min_volume_numer; + cur_bids.min_volume_fraction_denom = cur_bids.base_min_volume_denom; + cur_bids.max_volume = cur_bids.base_max_volume; + cur_bids.max_volume_fraction_numer = cur_bids.base_max_volume_numer; + cur_bids.max_volume_fraction_denom = cur_bids.base_max_volume_denom; + cur_bids.total = cur_bids.max_volume; + if (cur_bids.price.find('.') != std::string::npos) + { + boost::trim_right_if(cur_bids.price, boost::is_any_of("0")); + cur_bids.price = cur_bids.price; + } + cur_bids.max_volume = atomic_dex::utils::adjust_precision(cur_bids.max_volume); + t_float_50 total_f = safe_float(cur_bids.price) * safe_float(cur_bids.max_volume); + 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(); + for (auto&& cur_asks: answer.asks) { - t_float_50 percent_f = safe_float(cur_asks.maxvolume) / result_asks_f; + 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()); + // SPDLOG_INFO("cur_asks: {}", cur_asks.to_string()); } for (auto&& cur_bids: answer.bids) { - t_float_50 percent_f = safe_float(cur_bids.maxvolume) / result_bids_f; + 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()); - //SPDLOG_INFO("cur_bids: {}", cur_bids.to_string()); + // SPDLOG_INFO("cur_bids: {}", cur_bids.to_string()); } } void to_json(nlohmann::json& j, const orderbook_request& request) { - j["base"] = request.base; - j["rel"] = request.rel; + j["params"]["base"] = request.base; + j["params"]["rel"] = request.rel; } -} // namespace mm2::api +} // namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/rpc.orderbook.hpp b/src/core/atomicdex/api/mm2/rpc.orderbook.hpp index b12e1f46f1..8cd508c801 100644 --- a/src/core/atomicdex/api/mm2/rpc.orderbook.hpp +++ b/src/core/atomicdex/api/mm2/rpc.orderbook.hpp @@ -22,7 +22,7 @@ //! Project Headers #include "atomicdex/api/mm2/orderbook.order.contents.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { struct orderbook_request { @@ -34,8 +34,8 @@ namespace mm2::api struct orderbook_answer { - std::size_t askdepth; - std::size_t biddepth; + std::size_t askdepth{0}; + std::size_t biddepth{0}; std::vector asks; std::vector bids; std::string base; @@ -58,6 +58,6 @@ namespace mm2::api namespace atomic_dex { - using t_orderbook_request = ::mm2::api::orderbook_request; - using t_orderbook_answer = ::mm2::api::orderbook_answer; + using t_orderbook_request = mm2::orderbook_request; + using t_orderbook_answer = mm2::orderbook_answer; } \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.recover.funds.cpp b/src/core/atomicdex/api/mm2/rpc.recover.funds.cpp index 99df8d3009..e2a69f41fd 100644 --- a/src/core/atomicdex/api/mm2/rpc.recover.funds.cpp +++ b/src/core/atomicdex/api/mm2/rpc.recover.funds.cpp @@ -8,7 +8,7 @@ //! Project Headers #include "atomicdex/api/mm2/rpc.recover.funds.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { void to_json(nlohmann::json& j, const recover_funds_of_swap_request& cfg) diff --git a/src/core/atomicdex/api/mm2/rpc.recover.funds.hpp b/src/core/atomicdex/api/mm2/rpc.recover.funds.hpp index a79c431c34..d9e2daae9f 100644 --- a/src/core/atomicdex/api/mm2/rpc.recover.funds.hpp +++ b/src/core/atomicdex/api/mm2/rpc.recover.funds.hpp @@ -6,7 +6,7 @@ //! Deps #include -namespace mm2::api +namespace atomic_dex::mm2 { struct recover_funds_of_swap_request { @@ -34,10 +34,10 @@ namespace mm2::api }; void from_json(const nlohmann::json& j, recover_funds_of_swap_answer& answer); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_recover_funds_of_swap_request = ::mm2::api::recover_funds_of_swap_request; - using t_recover_funds_of_swap_answer = ::mm2::api::recover_funds_of_swap_answer; + using t_recover_funds_of_swap_request = mm2::recover_funds_of_swap_request; + using t_recover_funds_of_swap_answer = mm2::recover_funds_of_swap_answer; } // namespace atomic_dex \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.sell.cpp b/src/core/atomicdex/api/mm2/rpc.sell.cpp index 6546f5a018..8784dd5a1f 100644 --- a/src/core/atomicdex/api/mm2/rpc.sell.cpp +++ b/src/core/atomicdex/api/mm2/rpc.sell.cpp @@ -22,7 +22,7 @@ #include "atomicdex/api/mm2/generics.hpp" #include "atomicdex/api/mm2/rpc.sell.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { void to_json(nlohmann::json& j, const sell_request& request) @@ -91,4 +91,4 @@ namespace mm2::api { extract_rpc_json_answer(j, answer); } -} // namespace mm2::api \ No newline at end of file +} // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.sell.hpp b/src/core/atomicdex/api/mm2/rpc.sell.hpp index 3847d8052f..8c5e3d66b1 100644 --- a/src/core/atomicdex/api/mm2/rpc.sell.hpp +++ b/src/core/atomicdex/api/mm2/rpc.sell.hpp @@ -26,7 +26,7 @@ //! Project Headers #include "atomicdex/api/mm2/trading.order.contents.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { struct sell_request { @@ -66,11 +66,11 @@ namespace mm2::api }; void from_json(const nlohmann::json& j, sell_answer& answer); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_sell_request = ::mm2::api::sell_request; - using t_sell_answer = ::mm2::api::sell_answer; - using t_sell_answer_success = ::mm2::api::sell_answer_success; + using t_sell_request = mm2::sell_request; + using t_sell_answer = mm2::sell_answer; + using t_sell_answer_success = mm2::sell_answer_success; } // namespace atomic_dex \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.setprice.cpp b/src/core/atomicdex/api/mm2/rpc.setprice.cpp index f1a271e5f8..2b300d28dd 100644 --- a/src/core/atomicdex/api/mm2/rpc.setprice.cpp +++ b/src/core/atomicdex/api/mm2/rpc.setprice.cpp @@ -19,7 +19,7 @@ //! Project Headers #include "atomicdex/api/mm2/rpc.setprice.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { void to_json(nlohmann::json& j, const setprice_request& request) diff --git a/src/core/atomicdex/api/mm2/rpc.setprice.hpp b/src/core/atomicdex/api/mm2/rpc.setprice.hpp index c89898c5f3..fbf1964d6f 100644 --- a/src/core/atomicdex/api/mm2/rpc.setprice.hpp +++ b/src/core/atomicdex/api/mm2/rpc.setprice.hpp @@ -23,7 +23,7 @@ //! Deps #include -namespace mm2::api +namespace atomic_dex::mm2 { struct setprice_request { @@ -45,5 +45,5 @@ namespace mm2::api namespace atomic_dex { - using t_setprice_request = ::mm2::api::setprice_request; + using t_setprice_request = mm2::setprice_request; } \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.trade.preimage.cpp b/src/core/atomicdex/api/mm2/rpc.trade.preimage.cpp index 52c6abf987..b771be7a0d 100644 --- a/src/core/atomicdex/api/mm2/rpc.trade.preimage.cpp +++ b/src/core/atomicdex/api/mm2/rpc.trade.preimage.cpp @@ -21,7 +21,7 @@ #include "atomicdex/api/mm2/generics.hpp" #include "atomicdex/api/mm2/rpc.trade.preimage.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { //! Serialization void @@ -74,4 +74,4 @@ namespace mm2::api { extract_rpc_json_answer(j, answer); } -} // namespace mm2::api +} // namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/rpc.trade.preimage.fwd.hpp b/src/core/atomicdex/api/mm2/rpc.trade.preimage.fwd.hpp index 0e856976f5..1272653f43 100644 --- a/src/core/atomicdex/api/mm2/rpc.trade.preimage.fwd.hpp +++ b/src/core/atomicdex/api/mm2/rpc.trade.preimage.fwd.hpp @@ -16,13 +16,13 @@ #pragma once -namespace mm2::api +namespace atomic_dex::mm2 { struct trade_preimage_request; struct trade_preimage_answer; -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_trade_preimage_answer = ::mm2::api::trade_preimage_answer; + using t_trade_preimage_answer = mm2::trade_preimage_answer; } \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.trade.preimage.hpp b/src/core/atomicdex/api/mm2/rpc.trade.preimage.hpp index d83ed6d288..9f7b114934 100644 --- a/src/core/atomicdex/api/mm2/rpc.trade.preimage.hpp +++ b/src/core/atomicdex/api/mm2/rpc.trade.preimage.hpp @@ -27,7 +27,7 @@ //! Project Headers #include "atomicdex/api/mm2/fraction.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { struct trade_preimage_request { @@ -43,9 +43,9 @@ namespace mm2::api struct coin_fee { - std::string coin; - std::string amount; - fraction amount_fraction; + std::string coin; + std::string amount; + mm2::fraction amount_fraction; }; ENTT_API void from_json(const nlohmann::json& j, coin_fee& fee); @@ -71,11 +71,11 @@ namespace mm2::api }; ENTT_API void from_json(const nlohmann::json& j, trade_preimage_answer& answer); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_trade_preimage_request = ::mm2::api::trade_preimage_request; - using t_trade_preimage_answer = ::mm2::api::trade_preimage_answer; - using t_trade_preimage_answer_success = ::mm2::api::trade_preimage_answer_success; + using t_trade_preimage_request = mm2::trade_preimage_request; + using t_trade_preimage_answer = mm2::trade_preimage_answer; + using t_trade_preimage_answer_success = mm2::trade_preimage_answer_success; } // namespace atomic_dex diff --git a/src/core/atomicdex/api/mm2/rpc.tx.history.cpp b/src/core/atomicdex/api/mm2/rpc.tx.history.cpp index 42c6e4b378..246eb0750f 100644 --- a/src/core/atomicdex/api/mm2/rpc.tx.history.cpp +++ b/src/core/atomicdex/api/mm2/rpc.tx.history.cpp @@ -4,25 +4,36 @@ //! Project Headers #include "rpc.tx.history.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { - void - to_json(nlohmann::json& j, const tx_history_request& cfg) + void to_json(nlohmann::json& j, const tx_history_request& cfg) { - j["coin"] = cfg.coin; - j["limit"] = cfg.limit; + nlohmann::json obj = nlohmann::json::object(); + + obj["coin"] = cfg.coin; + obj["limit"] = cfg.limit; + if (cfg.paging_options.has_value() && j.contains("mmrpc") && j.at("mmrpc").get() == "2.0") + { + obj["paging_options"] = cfg.paging_options.value(); + } + if (j.contains("mmrpc") && j.at("mmrpc").get() == "2.0") + { + j["params"] = obj; + } + else + { + j.update(obj); + } } - void - from_json(const nlohmann::json& j, sync_status_additional_error& answer) + void from_json(const nlohmann::json& j, sync_status_additional_error& answer) { j.at("code").get_to(answer.code); j.at("message").get_to(answer.message); } - void - from_json(const nlohmann::json& j, sync_status_eth_erc_20_coins& answer) + void from_json(const nlohmann::json& j, sync_status_eth_erc_20_coins& answer) { j.at("blocks_left").get_to(answer.blocks_left); } @@ -94,4 +105,4 @@ namespace mm2::api answer.result = j.at("result").get(); } } -} \ No newline at end of file +} // namespace atomic_dex::mm2 \ 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 b81f23b624..6d287258aa 100644 --- a/src/core/atomicdex/api/mm2/rpc.tx.history.hpp +++ b/src/core/atomicdex/api/mm2/rpc.tx.history.hpp @@ -3,18 +3,18 @@ #include #include -//! Deps #include -//! Our Headers #include "transaction.data.hpp" +#include "paging_options.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { struct tx_history_request { - std::string coin; - std::size_t limit; + std::string coin; + std::size_t limit; + std::optional paging_options; }; void to_json(nlohmann::json& j, const tx_history_request& cfg); @@ -80,9 +80,9 @@ namespace mm2::api }; void from_json(const nlohmann::json& j, tx_history_answer& answer); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_tx_history_request = ::mm2::api::tx_history_request; + using t_tx_history_request = mm2::tx_history_request; } \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.update.maker.order.cpp b/src/core/atomicdex/api/mm2/rpc.update.maker.order.cpp index 12d8b83d46..cd90e60f70 100644 --- a/src/core/atomicdex/api/mm2/rpc.update.maker.order.cpp +++ b/src/core/atomicdex/api/mm2/rpc.update.maker.order.cpp @@ -8,10 +8,10 @@ //! Project Headers #include -namespace mm2::api +namespace atomic_dex::mm2 { void - to_json(nlohmann::json& j, const mm2::api::update_maker_order_request& request) + to_json(nlohmann::json& j, const mm2::update_maker_order_request& request) { j["uuid"] = request.uuid; j["new_price"] = request.new_price; @@ -41,4 +41,4 @@ namespace mm2::api j["rel_nota"] = request.rel_nota.value(); } } -} // namespace mm2::api +} // namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/rpc.update.maker.order.hpp b/src/core/atomicdex/api/mm2/rpc.update.maker.order.hpp index 8b9f27b0da..d1249a8b29 100644 --- a/src/core/atomicdex/api/mm2/rpc.update.maker.order.hpp +++ b/src/core/atomicdex/api/mm2/rpc.update.maker.order.hpp @@ -7,7 +7,7 @@ //! Deps #include -namespace mm2::api +namespace atomic_dex::mm2 { struct update_maker_order_request { @@ -23,9 +23,9 @@ namespace mm2::api }; void to_json(nlohmann::json& j, const update_maker_order_request& request); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_update_maker_order_request = ::mm2::api::update_maker_order_request; + using t_update_maker_order_request = mm2::update_maker_order_request; } \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.validate.address.cpp b/src/core/atomicdex/api/mm2/rpc.validate.address.cpp index da74be26b9..52a888967b 100644 --- a/src/core/atomicdex/api/mm2/rpc.validate.address.cpp +++ b/src/core/atomicdex/api/mm2/rpc.validate.address.cpp @@ -1,16 +1,12 @@ -// -// Created by Sztergbaum Roman on 22/05/2021. -// - #include #include "atomicdex/api/mm2/rpc.validate.address.hpp" #include "atomicdex/api/mm2/generics.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { void - to_json(nlohmann::json& j, const mm2::api::validate_address_request& req) + to_json(nlohmann::json& j, const mm2::validate_address_request& req) { j["coin"] = req.coin; j["address"] = req.address; @@ -30,4 +26,4 @@ namespace mm2::api { extract_rpc_json_answer(j, answer); } -} // namespace mm2::api +} // namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/rpc.validate.address.hpp b/src/core/atomicdex/api/mm2/rpc.validate.address.hpp index 00d6bd5221..9ca7fbc43f 100644 --- a/src/core/atomicdex/api/mm2/rpc.validate.address.hpp +++ b/src/core/atomicdex/api/mm2/rpc.validate.address.hpp @@ -6,7 +6,7 @@ //! Deps #include -namespace mm2::api +namespace atomic_dex::mm2 { struct validate_address_request { @@ -33,11 +33,11 @@ namespace mm2::api }; void from_json(const nlohmann::json& j, validate_address_answer& answer); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_validate_address_request = ::mm2::api::validate_address_request; - using t_validate_address_answer = ::mm2::api::validate_address_answer; - using t_validate_address_answer_success = ::mm2::api::validate_address_answer_success; + using t_validate_address_request = mm2::validate_address_request; + using t_validate_address_answer = mm2::validate_address_answer; + using t_validate_address_answer_success = mm2::validate_address_answer_success; } // namespace atomic_dex \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.withdraw.cpp b/src/core/atomicdex/api/mm2/rpc.withdraw.cpp index fbbb291aa0..a37bd5c91d 100644 --- a/src/core/atomicdex/api/mm2/rpc.withdraw.cpp +++ b/src/core/atomicdex/api/mm2/rpc.withdraw.cpp @@ -8,7 +8,7 @@ //! Our Headers #include "rpc.withdraw.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { void to_json(nlohmann::json& j, const withdraw_fees& cfg) @@ -24,6 +24,12 @@ namespace mm2::api j["gas_limit"] = cfg.gas_limit.value_or(40); j["gas_price"] = std::stoi(cfg.gas_price.value()); } + else if (cfg.type == "otherGas") + { + j["type"] = "EthGas"; + j["gas"] = cfg.gas_limit.value_or(55000); + j["gas_price"] = std::stoi(cfg.gas_price.value()); + } else { j["amount"] = cfg.amount.value(); @@ -72,4 +78,4 @@ namespace mm2::api } } } -} // namespace mm2::api \ No newline at end of file +} // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc.withdraw.hpp b/src/core/atomicdex/api/mm2/rpc.withdraw.hpp index 6dcf08c575..d424c7c825 100644 --- a/src/core/atomicdex/api/mm2/rpc.withdraw.hpp +++ b/src/core/atomicdex/api/mm2/rpc.withdraw.hpp @@ -10,7 +10,7 @@ #include "atomicdex/api/mm2/generic.error.hpp" #include "atomicdex/api/mm2/transaction.data.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { struct withdraw_fees { @@ -42,11 +42,11 @@ namespace mm2::api }; void from_json(const nlohmann::json& j, withdraw_answer& answer); -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_withdraw_request = ::mm2::api::withdraw_request; - using t_withdraw_fees = ::mm2::api::withdraw_fees; - using t_withdraw_answer = ::mm2::api::withdraw_answer; + using t_withdraw_request = mm2::withdraw_request; + using t_withdraw_fees = mm2::withdraw_fees; + using t_withdraw_answer = mm2::withdraw_answer; } // namespace atomic_dex \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/rpc2.init_withdraw.cpp b/src/core/atomicdex/api/mm2/rpc2.init_withdraw.cpp new file mode 100644 index 0000000000..b42ca76fb2 --- /dev/null +++ b/src/core/atomicdex/api/mm2/rpc2.init_withdraw.cpp @@ -0,0 +1,55 @@ +/****************************************************************************** + * Copyright © 2013-2022 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/rpc2.init_withdraw.hpp" + +//! Implementation 2.0 RPC [init_withdraw] +namespace atomic_dex::mm2 +{ + void + to_json(nlohmann::json& j, const init_withdraw_fees& request) + { + j["type"] = request.type; + j["amount"] = request.amount.value(); + } + + //! Serialization + void to_json(nlohmann::json& j, const init_withdraw_request& request) + { + nlohmann::json obj = nlohmann::json::object(); + + obj["params"]["coin"] = request.coin; + obj["params"]["to"] = request.to; + obj["params"]["amount"] = request.amount; + obj["params"]["max"] = request.max; + + if (request.fees.has_value()) + { + obj["params"]["fee"] = request.fees.value(); + } + j.update(obj); + } + + //! Deserialization + void from_json(const nlohmann::json& j, init_withdraw_answer& answer) + { + j.at("task_id").get_to(answer.task_id); + } +} // namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/rpc2.init_withdraw.hpp b/src/core/atomicdex/api/mm2/rpc2.init_withdraw.hpp new file mode 100644 index 0000000000..2f214f6de9 --- /dev/null +++ b/src/core/atomicdex/api/mm2/rpc2.init_withdraw.hpp @@ -0,0 +1,56 @@ +/****************************************************************************** + * Copyright © 2013-2022 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 + +//! Deps +#include + +namespace atomic_dex::mm2 +{ + struct init_withdraw_fees + { + std::string type; ///< UtxoFixed, UtxoPerKbyte, EthGas, Qrc20Gas + std::optional amount; ///< Utxo only + }; + + struct init_withdraw_request + { + std::string coin; + std::string to; + std::string amount; + std::optional fees{std::nullopt}; ///< ignored if std::nullopt + bool max{false}; + }; + + struct init_withdraw_answer + { + int task_id; + }; + + void to_json(nlohmann::json& j, const init_withdraw_request& request); + void from_json(const nlohmann::json& j, init_withdraw_answer& answer); +} + +namespace atomic_dex +{ + using t_init_withdraw_request = mm2::init_withdraw_request; + using t_init_withdraw_fees = mm2::init_withdraw_fees; + using t_init_withdraw_answer = mm2::init_withdraw_answer; +} // namespace atomic_dex diff --git a/src/core/atomicdex/api/mm2/rpc2.init_z_coin.cpp b/src/core/atomicdex/api/mm2/rpc2.init_z_coin.cpp new file mode 100644 index 0000000000..6c61b672eb --- /dev/null +++ b/src/core/atomicdex/api/mm2/rpc2.init_z_coin.cpp @@ -0,0 +1,41 @@ +/****************************************************************************** + * Copyright © 2013-2022 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/rpc2.init_z_coin.hpp" + +//! Implementation 2.0 RPC [init_z_coin] +namespace atomic_dex::mm2 +{ + //! Serialization + void to_json(nlohmann::json& j, const init_z_coin_request& request) + { + j["params"]["ticker"] = request.coin_name; + j["params"]["activation_params"]["mode"]["rpc"] = "Light"; + j["params"]["activation_params"]["mode"]["rpc_data"]["electrum_servers"] = request.servers; + j["params"]["activation_params"]["mode"]["rpc_data"]["light_wallet_d_servers"] = request.z_urls; + j["params"]["tx_history"] = request.with_tx_history; + } + + //! Deserialization + void from_json(const nlohmann::json& j, init_z_coin_answer& answer) + { + j.at("task_id").get_to(answer.task_id); + } +} // namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/rpc2.init_z_coin.hpp b/src/core/atomicdex/api/mm2/rpc2.init_z_coin.hpp new file mode 100644 index 0000000000..d7fe101369 --- /dev/null +++ b/src/core/atomicdex/api/mm2/rpc2.init_z_coin.hpp @@ -0,0 +1,54 @@ +/****************************************************************************** + * Copyright © 2013-2022 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 + +// Std Headers +#include + +// Deps Headers +#include + +//! Project Headers +#include "atomicdex/config/electrum.cfg.hpp" +#include "atomicdex/constants/qt.coins.enums.hpp" + +namespace atomic_dex::mm2 +{ + struct init_z_coin_request + { + std::string coin_name; + std::vector servers; + std::vector z_urls; + CoinType coin_type; + bool is_testnet{false}; + bool with_tx_history{false}; // Not yet in API + }; + + struct init_z_coin_answer + { + int task_id; + }; + + void to_json(nlohmann::json& j, const init_z_coin_request& request); + void from_json(const nlohmann::json& j, init_z_coin_answer& answer); +} + +namespace atomic_dex +{ + using t_init_z_coin_request = mm2::init_z_coin_request; + using t_init_z_coin_answer = mm2::init_z_coin_answer; +} // namespace atomic_dex diff --git a/src/core/atomicdex/api/mm2/rpc2.init_z_coin_status.cpp b/src/core/atomicdex/api/mm2/rpc2.init_z_coin_status.cpp new file mode 100644 index 0000000000..ded987e419 --- /dev/null +++ b/src/core/atomicdex/api/mm2/rpc2.init_z_coin_status.cpp @@ -0,0 +1,80 @@ +/****************************************************************************** + * Copyright © 2013-2022 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/rpc2.init_z_coin_status.hpp" + +//! Implementation 2.0 RPC [init_z_coin_status] +namespace atomic_dex::mm2 +{ + //! Serialization + void to_json(nlohmann::json& j, const init_z_coin_status_request& request) + { + j["params"]["task_id"] = request.task_id; + } + + //! Deserialization + void from_json(const nlohmann::json& j, init_z_coin_status_answer_success& answer) + { + j.at("result").at("status").get_to(answer.status); // [InProgress, Ready] + j.at("result").at("details").get_to(answer.details); + + if (j.at("result").at("details").contains("UpdatingBlocksCache")) + { + answer.current_scanned_block = j.at("result").at("details").at("UpdatingBlocksCache").at("current_scanned_block").get(); + answer.latest_block = j.at("result").at("details").at("UpdatingBlocksCache").at("latest_block").get(); + } + else if (j.at("result").at("details").contains("BuildingWalletDb")) + { + answer.current_scanned_block = j.at("result").at("details").at("BuildingWalletDb").at("current_scanned_block").get(); + answer.latest_block = j.at("result").at("details").at("BuildingWalletDb").at("latest_block").get(); + } + + if (j.at("result").at("details").contains("result")) + { + answer.coin = j.at("result").at("details").at("result").at("ticker").get(); + answer.current_block = j.at("result").at("details").at("result").at("current_block").get(); + + if (j.at("result").at("details").at("result").contains("wallet_balance")) + { + answer.wallet_type = j.at("result").at("details").at("result").at("wallet_balance").at("wallet_type").get(); + answer.address = j.at("result").at("details").at("result").at("wallet_balance").at("address").get(); + answer.spendable_balance = j.at("result").at("details").at("result").at("wallet_balance").at("balance").at("spendable").get(); + answer.unspendable_balance = j.at("result").at("details").at("result").at("wallet_balance").at("balance").at("unspendable").get(); + } + } + } + + void + from_json(const nlohmann::json& j, init_z_coin_status_answer& answer) + { + if (j.count("error") >= 1) + { + answer.error = j; + } + else + { + if (j.contains("result") && j.contains("mmrpc") && j.at("mmrpc").get() == "2.0") + { + answer.result = j.at("result").get(); + } + } + } +} // namespace atomic_dex::mm2 + diff --git a/src/core/atomicdex/api/mm2/rpc2.init_z_coin_status.hpp b/src/core/atomicdex/api/mm2/rpc2.init_z_coin_status.hpp new file mode 100644 index 0000000000..845c5e6356 --- /dev/null +++ b/src/core/atomicdex/api/mm2/rpc2.init_z_coin_status.hpp @@ -0,0 +1,69 @@ +/****************************************************************************** + * Copyright © 2013-2022 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 + +// Std Headers +#include + +// Deps Headers +#include + +//! Project Headers +#include "generic.error.hpp" + +namespace atomic_dex::mm2 +{ + struct init_z_coin_status_request + { + int task_id; + }; + + void to_json(nlohmann::json& j, const init_z_coin_status_request& request); + + struct init_z_coin_status_answer_success + { + std::string status{"disabled"}; + std::string details{"N/A"}; + std::optional coin; + std::optional address; + std::optional current_scanned_block; + std::optional latest_block; + std::optional current_block; + std::optional wallet_type; + std::optional spendable_balance; + std::optional unspendable_balance; + }; + + void from_json(const nlohmann::json& j, init_z_coin_status_answer_success& answer); + + struct init_z_coin_status_answer + { + std::optional result; + std::optional error; + std::string raw_result; ///< internal + int rpc_result_code; ///< internal + }; + + void from_json(const nlohmann::json& j, init_z_coin_status_answer& answer); +} + +namespace atomic_dex +{ + using t_init_z_coin_status_request = mm2::init_z_coin_status_request; + using t_init_z_coin_status_answer = mm2::init_z_coin_status_answer; + using t_init_z_coin_status_answer_success = mm2::init_z_coin_status_answer_success; +} // namespace atomic_dex diff --git a/src/core/atomicdex/api/mm2/rpc2.withdraw_status.cpp b/src/core/atomicdex/api/mm2/rpc2.withdraw_status.cpp new file mode 100644 index 0000000000..c38d5cfbe0 --- /dev/null +++ b/src/core/atomicdex/api/mm2/rpc2.withdraw_status.cpp @@ -0,0 +1,44 @@ +/****************************************************************************** + * Copyright © 2013-2022 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/rpc2.withdraw_status.hpp" + +//! Implementation 2.0 RPC [withdraw_status] +namespace atomic_dex::mm2 +{ + //! Serialization + void to_json(nlohmann::json& j, const withdraw_status_request& request) + { + j["params"]["task_id"] = request.task_id; + } + + //! Deserialization + void from_json(const nlohmann::json& j, withdraw_status_answer& answer) + { + if (j.count("error") >= 1) + { + answer.error = j; + } + else + { + answer.result = j.at("result").at("details").at("result").get(); + } + } +} // namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/rpc2.withdraw_status.hpp b/src/core/atomicdex/api/mm2/rpc2.withdraw_status.hpp new file mode 100644 index 0000000000..a5cb3f356c --- /dev/null +++ b/src/core/atomicdex/api/mm2/rpc2.withdraw_status.hpp @@ -0,0 +1,52 @@ +/****************************************************************************** + * Copyright © 2013-2022 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 + +//! Deps +#include + +//! Our Headers +#include "atomicdex/api/mm2/generic.error.hpp" +#include "atomicdex/api/mm2/transaction.data.hpp" + +namespace atomic_dex::mm2 +{ + struct withdraw_status_request + { + int task_id; + }; + + struct withdraw_status_answer + { + std::optional result; + std::optional error; + std::string raw_result; ///< internal + int rpc_result_code; ///< internal + }; + + void to_json(nlohmann::json& j, const withdraw_status_request& request); + void from_json(const nlohmann::json& j, withdraw_status_answer& answer); +} + +namespace atomic_dex +{ + using t_withdraw_status_request = mm2::withdraw_status_request; + using t_withdraw_status_answer = mm2::withdraw_status_answer; +} // namespace atomic_dex diff --git a/src/core/atomicdex/api/mm2/rpc2.z_coin_tx_history.cpp b/src/core/atomicdex/api/mm2/rpc2.z_coin_tx_history.cpp new file mode 100644 index 0000000000..0ae2232e10 --- /dev/null +++ b/src/core/atomicdex/api/mm2/rpc2.z_coin_tx_history.cpp @@ -0,0 +1,106 @@ +/****************************************************************************** + * Copyright © 2013-2022 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/rpc2.z_coin_tx_history.hpp" + +//! Implementation 2.0 RPC [z_coin_tx_history] +namespace atomic_dex::mm2 +{ + //! Serialization + void to_json(nlohmann::json& j, const z_tx_history_request& request) + { + j["params"]["coin"] = request.coin; + j["params"]["limit"] = request.limit; + //j["params"]["paging_options"]["PageNumber"] = request.page_number; + //j["params"]["paging_options"]["FromId"] = request.from_id; + } + + //! Deserialization + void + from_json(const nlohmann::json& j, sync_status_z_error& answer) + { // TODO: confirm the v2 error output uses this structure + j.at("code").get_to(answer.code); + j.at("message").get_to(answer.message); + } + + void + from_json(const nlohmann::json& j, sync_status_z_coins& answer) + { + j.at("transactions_left").get_to(answer.transactions_left); + } + + void + from_json(const nlohmann::json& j, sync_status_z_additional_infos& answer) + { + if (j.count("error") == 1) + { + answer.error = j.get(); + } // TODO check if 'blocks_left' or 'transactions_left' + else if (j.count("transactions_left") == 1) + { + answer.z_infos = j.get(); + } + } + + void + from_json(const nlohmann::json& j, t_z_sync_status& answer) + { + j.at("state").get_to(answer.state); + if (j.count("additional_info") == 1) + { + answer.additional_info = j.at("additional_info").get(); + } + } + + void + from_json(const nlohmann::json& j, z_tx_history_answer_success& answer) + { + if (j.contains("from_id")) + { + if (not j.at("from_id").is_null()) + j.at("from_id").get_to(answer.from_id); + } + if (j.contains("current_block")) + { + j.at("current_block").get_to(answer.current_block); + } + j.at("limit").get_to(answer.limit); + j.at("skipped").get_to(answer.skipped); + if (j.contains("sync_status")) + { + j.at("sync_status").get_to(answer.sync_status); + } + j.at("total").get_to(answer.total); + j.at("transactions").get_to(answer.transactions); + } + + void + from_json(const nlohmann::json& j, z_tx_history_answer& answer) + { + if (j.contains("error")) + { + answer.error = j.at("error").get(); + } + else + { + answer.result = j.at("result").get(); + } + } +} // namespace atomic_dex::mm2 diff --git a/src/core/atomicdex/api/mm2/rpc2.z_coin_tx_history.hpp b/src/core/atomicdex/api/mm2/rpc2.z_coin_tx_history.hpp new file mode 100644 index 0000000000..60c07671de --- /dev/null +++ b/src/core/atomicdex/api/mm2/rpc2.z_coin_tx_history.hpp @@ -0,0 +1,103 @@ +/****************************************************************************** + * Copyright © 2013-2022 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 + +// Std Headers +#include +#include + +// Deps Headers +#include + +//! Our Headers +#include "transaction.data.hpp" + +namespace atomic_dex::mm2 +{ + struct z_tx_history_request + { + std::string coin; + std::size_t limit; + //std::string from_id{''}; + //std::size_t page_number{1}; + }; + + void to_json(nlohmann::json& j, const z_tx_history_request& request); + + //"coin","current_block","transactions","sync_status","sync_status","id" + struct sync_status_z_error + { + std::string message; + int code; + }; + + void from_json(const nlohmann::json& j, sync_status_z_error& answer); + + struct sync_status_z_coins + { + std::size_t transactions_left; + }; + + void from_json(const nlohmann::json& j, sync_status_z_coins& answer); + + struct sync_status_z_additional_infos + { + std::optional error; + std::optional z_infos; + }; + + void from_json(const nlohmann::json& j, sync_status_z_additional_infos& answer); + + struct t_z_sync_status + { + std::string state; ///< NotEnabled, NotStarted, InProgress, Error, Finished + std::optional additional_info; + }; + + void from_json(const nlohmann::json& j, t_z_sync_status& answer); + + struct z_tx_history_answer_success + { + std::string from_id; // optional? + std::size_t skipped; + std::size_t limit; + std::size_t current_block; + std::size_t total_pages; + std::size_t page_number; + std::size_t total; + std::vector transactions; + t_z_sync_status sync_status; + }; + + void from_json(const nlohmann::json& j, z_tx_history_answer_success& answer); + + struct z_tx_history_answer + { + std::optional error; + std::optional result; + std::string raw_result; ///< internal + int rpc_result_code; ///< internal + }; + + void from_json(const nlohmann::json& j, z_tx_history_answer& answer); +} // namespace atomic_dex::mm2 + +namespace atomic_dex +{ + using t_z_tx_history_request = mm2::z_tx_history_request; + using t_z_tx_history_answer = mm2::z_tx_history_answer; +} // namespace atomic_dex diff --git a/src/core/atomicdex/api/mm2/trading.order.contents.cpp b/src/core/atomicdex/api/mm2/trading.order.contents.cpp index c371eba26a..3259863300 100644 --- a/src/core/atomicdex/api/mm2/trading.order.contents.cpp +++ b/src/core/atomicdex/api/mm2/trading.order.contents.cpp @@ -20,7 +20,7 @@ //! Project Headers #include -namespace mm2::api +namespace atomic_dex::mm2 { void from_json(const nlohmann::json& j, trading_order_contents& contents) diff --git a/src/core/atomicdex/api/mm2/trading.order.contents.hpp b/src/core/atomicdex/api/mm2/trading.order.contents.hpp index 917dbfb2f8..076b5923eb 100644 --- a/src/core/atomicdex/api/mm2/trading.order.contents.hpp +++ b/src/core/atomicdex/api/mm2/trading.order.contents.hpp @@ -22,7 +22,7 @@ //! Deps #include -namespace mm2::api +namespace atomic_dex::mm2 { struct trading_order_contents { diff --git a/src/core/atomicdex/api/mm2/transaction.data.cpp b/src/core/atomicdex/api/mm2/transaction.data.cpp index 4a67af8c21..54dbf4b2e8 100644 --- a/src/core/atomicdex/api/mm2/transaction.data.cpp +++ b/src/core/atomicdex/api/mm2/transaction.data.cpp @@ -1,24 +1,16 @@ -// -// Created by Sztergbaum Roman on 08/06/2021. -// - -//! Deps #include -//! Our Headers #include "atomicdex/api/mm2/transaction.data.hpp" #include "atomicdex/utilities/global.utilities.hpp" -namespace mm2::api +namespace atomic_dex::mm2 { - void - from_json(const nlohmann::json& j, fee_regular_coin& cfg) + void from_json(const nlohmann::json& j, fee_regular_coin& cfg) { j.at("amount").get_to(cfg.amount); } - void - from_json(const nlohmann::json& j, fee_erc_coin& cfg) + void from_json(const nlohmann::json& j, fee_erc_coin& cfg) { j.at("coin").get_to(cfg.coin); j.at("gas").get_to(cfg.gas); @@ -26,8 +18,7 @@ namespace mm2::api j.at("total_fee").get_to(cfg.total_fee); } - void - from_json(const nlohmann::json& j, fee_qrc_coin& cfg) + void from_json(const nlohmann::json& j, fee_qrc_coin& cfg) { j.at("coin").get_to(cfg.coin); j.at("gas_limit").get_to(cfg.gas_limit); @@ -36,8 +27,7 @@ namespace mm2::api j.at("total_gas_fee").get_to(cfg.total_gas_fee); } - void - from_json(const nlohmann::json& j, fees_data& cfg) + void from_json(const nlohmann::json& j, fees_data& cfg) { if (j.count("amount") == 1) { @@ -56,32 +46,73 @@ namespace mm2::api } } - void - from_json(const nlohmann::json& j, transaction_data& cfg) + void from_json(const nlohmann::json& j, transaction_data& cfg) { j.at("block_height").get_to(cfg.block_height); j.at("coin").get_to(cfg.coin); + j.at("from").get_to(cfg.from); + j.at("to").get_to(cfg.to); + j.at("tx_hash").get_to(cfg.tx_hash); + j.at("my_balance_change").get_to(cfg.my_balance_change); + j.at("received_by_me").get_to(cfg.received_by_me); + j.at("spent_by_me").get_to(cfg.spent_by_me); + j.at("timestamp").get_to(cfg.timestamp); + + // internal_id is numeric for ZHTLC - needs conversion + //if (j.contains("internal_id")) + //{ + // cfg.internal_id = j.at("internal_id").get(); + //} + if (j.at("timestamp").get() != 0) + { + cfg.timestamp = j.at("timestamp").get(); + } + else + { + using namespace std::chrono; + cfg.timestamp = duration_cast(system_clock::now().time_since_epoch()).count(); + } + if (j.contains("confirmations")) { cfg.confirmations = j.at("confirmations").get(); } - j.at("fee_details").get_to(cfg.fee_details); - j.at("from").get_to(cfg.from); - if (cfg.from.empty() && cfg.coin == "FIRO") + + if (cfg.from.empty()) { - cfg.from.emplace_back("Lelantusjsplit (Hidden)"); + if (cfg.coin == "FIRO") + { + cfg.from.emplace_back("Lelantusjsplit (Hidden)"); + } + else + { + cfg.from.emplace_back("Shielded"); + } + } + + // transaction_fee only in ZHTLC response + if (j.contains("transaction_fee")) + { + cfg.transaction_fee = j.at("transaction_fee").get(); + } + else if (j.contains("fee_details")) + { + j.at("fee_details").get_to(cfg.fee_details); + } + + // total_amount not in ZHTLC response + if (j.contains("total_amount")) + { + j.at("total_amount").get_to(cfg.total_amount); + } + + // tx_hex not in ZHTLC response + if (j.contains("tx_hex")) + { + j.at("tx_hex").get_to(cfg.tx_hex); } - j.at("internal_id").get_to(cfg.internal_id); - j.at("my_balance_change").get_to(cfg.my_balance_change); - j.at("received_by_me").get_to(cfg.received_by_me); - j.at("spent_by_me").get_to(cfg.spent_by_me); - j.at("timestamp").get_to(cfg.timestamp); - j.at("to").get_to(cfg.to); - j.at("total_amount").get_to(cfg.total_amount); - j.at("tx_hash").get_to(cfg.tx_hash); - j.at("tx_hex").get_to(cfg.tx_hex); std::string s = atomic_dex::utils::to_human_date(cfg.timestamp, "%e %b %Y, %H:%M"); cfg.timestamp_as_date = std::move(s); } -} // namespace mm2::api \ No newline at end of file +} // namespace atomic_dex::mm2 \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/transaction.data.hpp b/src/core/atomicdex/api/mm2/transaction.data.hpp index dfb844ceaa..9882c9a532 100644 --- a/src/core/atomicdex/api/mm2/transaction.data.hpp +++ b/src/core/atomicdex/api/mm2/transaction.data.hpp @@ -6,7 +6,7 @@ //! Deps #include -namespace mm2::api +namespace atomic_dex::mm2 { struct fee_regular_coin { @@ -38,9 +38,9 @@ namespace mm2::api struct fees_data { - std::optional normal_fees; ///< btc, kmd based coins - std::optional erc_fees; ///< eth based coins - std::optional qrc_fees; // Qtum based coin + std::optional normal_fees; ///< btc, kmd based coins + std::optional erc_fees; ///< eth based coins + std::optional qrc_fees; // Qtum based coin }; void from_json(const nlohmann::json& j, fees_data& cfg); @@ -51,17 +51,18 @@ namespace mm2::api std::vector from; std::vector to; fees_data fee_details; - std::optional confirmations; - std::string coin; std::size_t block_height; - std::string internal_id; + std::string coin; std::string spent_by_me; std::string received_by_me; std::string my_balance_change; - std::string total_amount; + std::string total_amount{"0"}; std::string tx_hash; std::string tx_hex; std::string timestamp_as_date; ///< human readeable timestamp + std::optional transaction_fee; + std::optional internal_id; + std::optional confirmations; }; void from_json(const nlohmann::json& j, transaction_data& cfg); diff --git a/src/core/atomicdex/api/mm2/utxo.merge.params.cpp b/src/core/atomicdex/api/mm2/utxo.merge.params.cpp new file mode 100644 index 0000000000..040ec7f473 --- /dev/null +++ b/src/core/atomicdex/api/mm2/utxo.merge.params.cpp @@ -0,0 +1,29 @@ +/****************************************************************************** + * Copyright © 2013-2022 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. * + * * + ******************************************************************************/ + +#include + +#include "utxo.merge.params.hpp" + +namespace atomic_dex::mm2 +{ + void to_json(nlohmann::json& j, const utxo_merge_params& cfg) + { + j["merge_at"] = cfg.merge_at; + j["check_every"] = cfg.check_every; + j["max_merge_at_once"] = cfg.max_merge_at_once; + } +} \ No newline at end of file diff --git a/src/core/atomicdex/api/mm2/utxo.merge.params.hpp b/src/core/atomicdex/api/mm2/utxo.merge.params.hpp new file mode 100644 index 0000000000..5c74faaa15 --- /dev/null +++ b/src/core/atomicdex/api/mm2/utxo.merge.params.hpp @@ -0,0 +1,31 @@ +/****************************************************************************** + * Copyright © 2013-2022 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 + +namespace atomic_dex::mm2 +{ + struct utxo_merge_params + { + 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); +} \ No newline at end of file diff --git a/src/core/atomicdex/config/addressbook.cfg.cpp b/src/core/atomicdex/config/addressbook.cfg.cpp index 8f01d08d98..fbcd97b28b 100644 --- a/src/core/atomicdex/config/addressbook.cfg.cpp +++ b/src/core/atomicdex/config/addressbook.cfg.cpp @@ -26,8 +26,8 @@ namespace atomic_dex { nlohmann::json load_addressbook_cfg(const std::string& wallet_name) { - const fs::path source_folder{utils::get_atomic_dex_addressbook_folder()}; - const fs::path in_path {source_folder / wallet_name}; + const std::filesystem::path source_folder{utils::get_atomic_dex_addressbook_folder()}; + const std::filesystem::path in_path {source_folder / wallet_name}; QFile ifs; QString content; nlohmann::json out; @@ -59,8 +59,8 @@ namespace atomic_dex void update_addressbook_cfg(const nlohmann::json& in, const std::string& wallet_name) { - const fs::path out_folder{utils::get_atomic_dex_addressbook_folder()}; - const fs::path out_path {out_folder / wallet_name}; + const std::filesystem::path out_folder{utils::get_atomic_dex_addressbook_folder()}; + const std::filesystem::path out_path {out_folder / wallet_name}; QFile output; utils::create_if_doesnt_exist(out_folder); diff --git a/src/core/atomicdex/config/app.cfg.cpp b/src/core/atomicdex/config/app.cfg.cpp index 693c84887f..c4b25502cb 100644 --- a/src/core/atomicdex/config/app.cfg.cpp +++ b/src/core/atomicdex/config/app.cfg.cpp @@ -33,7 +33,7 @@ namespace void upgrade_cfg(atomic_dex::cfg& config) { - fs::path cfg_path = atomic_dex::utils::get_current_configs_path() / "cfg.json"; + std::filesystem::path cfg_path = atomic_dex::utils::get_current_configs_path() / "cfg.json"; QFile file; file.setFileName(atomic_dex::std_path_to_qstring(cfg_path)); file.open(QIODevice::ReadOnly | QIODevice::Text); @@ -87,13 +87,13 @@ namespace atomic_dex load_cfg() { cfg out; - fs::path cfg_path = utils::get_current_configs_path() / "cfg.json"; - if (not fs::exists(cfg_path)) + std::filesystem::path cfg_path = utils::get_current_configs_path() / "cfg.json"; + if (not std::filesystem::exists(cfg_path)) { - fs::path original_cfg_path{ag::core::assets_real_path() / "config" / "cfg.json"}; + std::filesystem::path original_cfg_path{ag::core::assets_real_path() / "config" / "cfg.json"}; //! Copy our json to current version LOG_PATH_CMP("Copying app cfg: {} to {}", original_cfg_path, cfg_path); - fs::copy_file(original_cfg_path, cfg_path, get_override_options()); + std::filesystem::copy_file(original_cfg_path, cfg_path, std::filesystem::copy_options::overwrite_existing); } QFile file; diff --git a/src/core/atomicdex/config/coins.cfg.cpp b/src/core/atomicdex/config/coins.cfg.cpp index ec4f7ccaa8..b74b08a035 100644 --- a/src/core/atomicdex/config/coins.cfg.cpp +++ b/src/core/atomicdex/config/coins.cfg.cpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -14,162 +14,208 @@ * * ******************************************************************************/ -//! Deps +#include + #include +#include -//! Project Headers -#include "atomicdex/config/coins.cfg.hpp" +#include "coins.cfg.hpp" -namespace atomic_dex +namespace { - void - from_json(const nlohmann::json& j, coin_config& cfg) + CoinType get_coin_type_from_str(const std::string& coin_type) { - j.at("coin").get_to(cfg.ticker); - cfg.gui_ticker = j.contains("gui_coin") ? j.at("gui_coin").get() : cfg.ticker; - j.at("name").get_to(cfg.name); - j.at("type").get_to(cfg.type); - if (j.contains("mm2_backup")) + if (coin_type == "QRC-20") { - cfg.custom_backup = j.at("mm2_backup"); + return CoinType::QRC20; } - if (j.contains("electrum")) + if (coin_type == "ERC-20") { - cfg.electrum_urls = j.at("electrum").get>(); + return CoinType::ERC20; } - if (j.contains("nodes")) + if (coin_type == "UTXO") { - cfg.urls = j.at("nodes").get>(); + return CoinType::UTXO; } - cfg.is_claimable = j.count("is_claimable") > 0; - cfg.minimal_claim_amount = cfg.is_claimable ? j.at("minimal_claim_amount").get() : "0"; - j.at("active").get_to(cfg.active); - j.at("currently_enabled").get_to(cfg.currently_enabled); - if (j.contains("coinpaprika_id")) + if (coin_type == "Smart Chain") { - j.at("coinpaprika_id").get_to(cfg.coinpaprika_id); + return CoinType::SmartChain; } - else + if (coin_type == "BEP-20") { - cfg.coinpaprika_id = "test-coin"; + return CoinType::BEP20; } - if (j.contains("coingecko_id")) + if (coin_type == "SLP") { - j.at("coingecko_id").get_to(cfg.coingecko_id); + return CoinType::SLP; } - if (j.contains("is_custom_coin")) + if (coin_type == "Matic") { - cfg.is_custom_coin = true; + return CoinType::Matic; } - - if (j.contains("is_segwit_on")) + if (coin_type == "Optimism") { - cfg.segwit = true; - j.at("is_segwit_on").get_to(cfg.is_segwit_on); - SPDLOG_INFO("coin: {} support segwit with current_segwit mode: {}", cfg.ticker, cfg.is_segwit_on); + return CoinType::Optimism; } - - if (j.contains("alias_ticker")) + if (coin_type == "Arbitrum") { - cfg.alias_ticker = j.at("alias_ticker").get(); + return CoinType::Arbitrum; } - - j.at("explorer_url").get_to(cfg.explorer_url); - if (j.contains("explorer_tx_url")) + if (coin_type == "AVX-20") { - j.at("explorer_tx_url").get_to(cfg.tx_uri); + return CoinType::AVX20; } - if (j.contains("explorer_address_url")) + if (coin_type == "FTM-20") { - j.at("explorer_address_url").get_to(cfg.address_url); + return CoinType::FTM20; } - if (j.contains("is_testnet")) + if (coin_type == "HRC-20") { - cfg.is_testnet = j.at("is_testnet").get(); + return CoinType::HRC20; } - if (cfg.type == "QRC-20") + if (coin_type == "Ubiq") { - cfg.coin_type = CoinType::QRC20; + return CoinType::Ubiq; } - else if (cfg.type == "ERC-20") + if (coin_type == "KRC-20") { - cfg.coin_type = CoinType::ERC20; + return CoinType::KRC20; } - else if (cfg.type == "UTXO") + if (coin_type == "Moonriver") { - cfg.coin_type = CoinType::UTXO; + return CoinType::Moonriver; } - else if (cfg.type == "Smart Chain") + if (coin_type == "Moonbeam") { - cfg.coin_type = CoinType::SmartChain; + return CoinType::Moonbeam; } - else if (cfg.type == "BEP-20") + if (coin_type == "HecoChain") { - cfg.coin_type = CoinType::BEP20; + return CoinType::HecoChain; } - else if (cfg.type == "SLP") + if (coin_type == "SmartBCH") { - cfg.coin_type = CoinType::SLP; + return CoinType::SmartBCH; } - else if (cfg.type == "Matic") + if (coin_type == "Ethereum Classic") { - cfg.coin_type = CoinType::Matic; + return CoinType::EthereumClassic; } - else if (cfg.type == "Optimism") + if (coin_type == "RSK Smart Bitcoin") { - cfg.coin_type = CoinType::Optimism; + return CoinType::RSK; } - else if (cfg.type == "Arbitrum") + if (coin_type == "ZHTLC") { - cfg.coin_type = CoinType::Arbitrum; + return CoinType::ZHTLC; } - else if (cfg.type == "AVX-20") + SPDLOG_INFO("Invalid coin type: {}", coin_type); + return CoinType::Invalid; + // throw std::invalid_argument{"Undefined given coin type."}; + } +} + +namespace atomic_dex +{ + bool is_wallet_only(std::string ticker) + { + return std::any_of(g_wallet_only_coins.begin(), g_wallet_only_coins.end(), [ticker](std::string x) { return ticker == x; }); + } + bool is_default_coin(std::string ticker) + { + return std::any_of(g_default_coins.begin(), g_default_coins.end(), [ticker](std::string x) { return ticker == x; }); + } + + void + from_json(const nlohmann::json& j, coin_config& cfg) + { + j.at("coin").get_to(cfg.ticker); + j.at("name").get_to(cfg.name); + j.at("type").get_to(cfg.type); + cfg.coin_type = get_coin_type_from_str(cfg.type); + j.at("active").get_to(cfg.active); + j.at("explorer_url").get_to(cfg.explorer_url); + + cfg.gui_ticker = j.contains("gui_coin") ? j.at("gui_coin").get() : cfg.ticker; + cfg.minimal_claim_amount = cfg.is_claimable ? j.at("minimal_claim_amount").get() : "0"; + cfg.coinpaprika_id = j.contains("coinpaprika_id") ? j.at("coinpaprika_id").get() : "test-coin"; + cfg.coingecko_id = j.contains("coingecko_id") ? j.at("coingecko_id").get() : "test-coin"; + cfg.nomics_id = j.contains("nomics_id") ? j.at("nomics_id").get() : "test-coin"; + cfg.is_claimable = j.count("is_claimable") > 0; + cfg.is_custom_coin = j.contains("is_custom_coin") ? j.at("is_custom_coin").get() : false; + cfg.is_testnet = j.contains("is_testnet") ? j.at("is_testnet").get() : false; + cfg.wallet_only = is_wallet_only(cfg.ticker) ? is_wallet_only(cfg.ticker) : j.contains("wallet_only") ? j.at("wallet_only").get() : false; + cfg.default_coin = is_default_coin(cfg.ticker); + + if (j.contains("other_types")) { - cfg.coin_type = CoinType::AVX20; + std::vector other_types; + + j.at("other_types").get_to(other_types); + cfg.other_types = std::set(); + for (const auto& other_type : other_types) + { + cfg.other_types->emplace(get_coin_type_from_str(other_type)); + } } - else if (cfg.type == "FTM-20") + if (j.contains("utxo_merge")) { - cfg.coin_type = CoinType::FTM20; + cfg.utxo_merge = j.at("utxo_merge"); } - else if (cfg.type == "HRC-20") + if (j.contains("mm2_backup")) { - cfg.coin_type = CoinType::HRC20; + cfg.custom_backup = j.at("mm2_backup"); } - else if (cfg.type == "Ubiq") + if (j.contains("activation_status")) { - cfg.coin_type = CoinType::Ubiq; + cfg.activation_status = j.at("activation_status").get(); } - else if (cfg.type == "KRC-20") + if (j.contains("electrum")) { - cfg.coin_type = CoinType::KRC20; + cfg.electrum_urls = j.at("electrum").get>(); } - else if (cfg.type == "Moonriver") + // Used for SLP coins + if (j.contains("bchd_urls")) { - cfg.coin_type = CoinType::Moonriver; + cfg.bchd_urls = j.at("bchd_urls").get>(); } - else if (cfg.type == "Moonbeam") + if (j.contains("nodes")) + { + // Todo: this is bad, we are using 2 times the required memory. Something can be improved here. + cfg.urls = j.at("nodes").get>(); + cfg.eth_family_urls = std::vector(); + cfg.eth_family_urls.value().reserve(cfg.urls.value().size()); + for (const auto& url : cfg.urls.value()) + { + cfg.eth_family_urls->push_back(url.url); + } + } + if (j.contains("allow_slp_unsafe_conf")) { - cfg.coin_type = CoinType::Moonbeam; + cfg.allow_slp_unsafe_conf = j.at("allow_slp_unsafe_conf").get(); } - else if (cfg.type == "HecoChain") + // Used for ZHTLC coins + if (j.contains("light_wallet_d_servers")) { - cfg.coin_type = CoinType::HecoChain; + cfg.z_urls = j.at("light_wallet_d_servers").get>(); } - else if (cfg.type == "SmartBCH") + if (j.contains("is_segwit_on")) { - cfg.coin_type = CoinType::SmartBCH; + cfg.segwit = true; + j.at("is_segwit_on").get_to(cfg.is_segwit_on); + SPDLOG_INFO("coin: {} support segwit with current_segwit mode: {}", cfg.ticker, cfg.is_segwit_on); } - else if (cfg.type == "Ethereum Classic") + if (j.contains("alias_ticker")) { - cfg.coin_type = CoinType::EthereumClassic; + cfg.alias_ticker = j.at("alias_ticker").get(); } - else if (cfg.type == "RSK Smart Bitcoin") + if (j.contains("explorer_tx_url")) { - cfg.coin_type = CoinType::RSK; + j.at("explorer_tx_url").get_to(cfg.tx_uri); } - if (j.contains("wallet_only")) + if (j.contains("explorer_address_url")) { - cfg.wallet_only = j.at("wallet_only").get(); + j.at("explorer_address_url").get_to(cfg.address_url); } switch (cfg.coin_type) @@ -195,12 +241,12 @@ namespace atomic_dex break; case CoinType::Optimism: cfg.has_parent_fees_ticker = true; - cfg.fees_ticker = cfg.is_testnet.value() ? "ETHK-OPT20" : "ETH-OPT20"; + cfg.fees_ticker = "ETH-OPT20"; cfg.is_erc_family = true; break; case CoinType::Arbitrum: cfg.has_parent_fees_ticker = true; - cfg.fees_ticker = cfg.is_testnet.value() ? "ETHR-ARB20" : "ETH-ARB20"; + cfg.fees_ticker = "ETH-ARB20"; cfg.is_erc_family = true; break; case CoinType::AVX20: @@ -260,7 +306,16 @@ namespace atomic_dex break; case CoinType::SLP: cfg.has_parent_fees_ticker = true; - cfg.fees_ticker = "BCH"; + cfg.fees_ticker = cfg.is_testnet.value() ? "tBCH" : "BCH"; + break; + case CoinType::ZHTLC: + cfg.has_parent_fees_ticker = false; + cfg.is_zhtlc_family = true; + cfg.fees_ticker = cfg.ticker; + break; + case CoinType::Invalid: + cfg.has_parent_fees_ticker = false; + cfg.fees_ticker = cfg.ticker; break; default: cfg.has_parent_fees_ticker = false; @@ -268,4 +323,15 @@ namespace atomic_dex break; } } + + void print_coins(std::vector coins) + { + std::stringstream ss; + ss << "["; + for (auto&& coin: coins) { + ss << coin.ticker << " "; + } + ss << "]"; + SPDLOG_INFO("{}", ss.str()); + } } // namespace atomic_dex diff --git a/src/core/atomicdex/config/coins.cfg.hpp b/src/core/atomicdex/config/coins.cfg.hpp index e705630d4c..b612e2684e 100644 --- a/src/core/atomicdex/config/coins.cfg.hpp +++ b/src/core/atomicdex/config/coins.cfg.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -16,47 +16,55 @@ #pragma once -//! QT -#include - -//! STD #include +#include -//! Deps #include -//! Project #include "atomicdex/api/mm2/mm2.constants.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" +#include "atomicdex/constants/dex.constants.hpp" namespace atomic_dex { struct coin_config { - public: static constexpr const char* erc_gas_stations = "https://ethgasstation.info/json/ethgasAPI.json"; static constexpr const char* matic_gas_stations = "https://gasstation-mainnet.matic.network/"; using electrum_servers = std::vector; - using nodes = std::vector; - std::string ticker; - std::optional alias_ticker{std::nullopt}; - std::string gui_ticker; ///< Ticker displayed in the gui - std::string name; ///< nice name - std::optional electrum_urls; - std::optional urls; - bool is_claimable{false}; - std::string minimal_claim_amount{"0"}; - bool currently_enabled{false}; - bool active{false}; - std::string coinpaprika_id{"test-coin"}; - std::string coingecko_id{"test-coin"}; - bool is_custom_coin{false}; - std::string type; - std::vector explorer_url; ///< usefull for transaction, take this url and append transaction id + using nodes = std::vector; + using eth_family_url_list = std::vector; + using bchd_url_list = std::vector; + using light_wallet_d_servers = std::vector; ///< For ZHTLC + std::string ticker; + std::optional alias_ticker{std::nullopt}; + std::string gui_ticker; ///< Ticker displayed in the gui + std::string name; ///< nice name + std::optional utxo_merge{false}; + std::optional allow_slp_unsafe_conf; + std::optional urls; + std::optional eth_family_urls; + std::optional bchd_urls; + std::optional electrum_urls; + std::optional z_urls; + bool is_claimable{false}; + std::string minimal_claim_amount{"0"}; + bool currently_enabled{false}; + bool active{false}; + std::string coinpaprika_id{"test-coin"}; + std::string coingecko_id{"test-coin"}; + std::string nomics_id{"test-coin"}; + bool is_custom_coin{false}; + std::string type; + std::optional> other_types; + std::string explorer_url; ///< usefull for transaction, take this url and append transaction id std::string tx_uri{"tx/"}; std::string address_url{"address/"}; std::optional custom_backup; + nlohmann::json activation_status; std::optional is_testnet{false}; ///< True if testnet (tBTC, tQTUM, QRC-20 on testnet, tETH) CoinType coin_type; bool checked{false}; @@ -66,7 +74,13 @@ namespace atomic_dex bool segwit{false}; bool is_segwit_on{false}; bool is_erc_family{false}; + bool is_zhtlc_family{false}; + bool default_coin{false}; }; void from_json(const nlohmann::json& j, coin_config& cfg); + + void print_coins(std::vector coins); + bool is_wallet_only(std::string ticker); + bool is_default_coin(std::string ticker); } // namespace atomic_dex diff --git a/src/core/atomicdex/config/electrum.cfg.hpp b/src/core/atomicdex/config/electrum.cfg.hpp index cf587c418b..77e873c25d 100644 --- a/src/core/atomicdex/config/electrum.cfg.hpp +++ b/src/core/atomicdex/config/electrum.cfg.hpp @@ -27,6 +27,7 @@ namespace atomic_dex { std::string url; std::optional protocol{"TCP"}; + std::optional ws_url; std::optional disable_cert_verification{false}; }; diff --git a/src/core/atomicdex/config/enable.cfg.cpp b/src/core/atomicdex/config/enable.cfg.cpp new file mode 100644 index 0000000000..5e918c417c --- /dev/null +++ b/src/core/atomicdex/config/enable.cfg.cpp @@ -0,0 +1,45 @@ +/****************************************************************************** + * 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/config/enable.cfg.hpp" + +namespace atomic_dex +{ + void + to_json(nlohmann::json& j, const node& cfg) + { + j["url"] = cfg.url; + if (cfg.gui_auth.has_value()) + { + j["gui_auth"] = cfg.gui_auth.value(); + } + } + + void + from_json(const nlohmann::json& j, node& cfg) + { + j.at("url").get_to(cfg.url); + if (j.count("gui_auth") == 1) + { + cfg.gui_auth = j.at("gui_auth").get(); + } + } +} // namespace atomic_dex \ No newline at end of file diff --git a/src/core/atomicdex/utilities/fs.prerequisites.hpp b/src/core/atomicdex/config/enable.cfg.hpp similarity index 58% rename from src/core/atomicdex/utilities/fs.prerequisites.hpp rename to src/core/atomicdex/config/enable.cfg.hpp index e50558a2e6..7a56d35685 100644 --- a/src/core/atomicdex/utilities/fs.prerequisites.hpp +++ b/src/core/atomicdex/config/enable.cfg.hpp @@ -14,34 +14,21 @@ * * ******************************************************************************/ + #pragma once -//! Global Helpers -#if defined(PREFER_BOOST_FILESYSTEM) -# include -namespace fs = boost::filesystem; -using fs_error_code = boost::system::error_code; -# define ANTARA_BOOST_FILESYTEM -#else -# if __has_include() -# include -namespace fs = std::filesystem; -using fs_error_code = std::error_code; -# define ANTARA_STD_FILESYTEM -# elif __has_include() -# include -namespace fs = boost::filesystem; -using fs_error_code = boost::system::error_code; -# define ANTARA_BOOST_FILESYTEM -# endif -#endif +//! STD +#include +#include -constexpr auto -get_override_options() +namespace atomic_dex { -#if defined(ANTARA_STD_FILESYTEM) - return fs::copy_options::overwrite_existing; -#elif defined(ANTARA_BOOST_FILESYTEM) - return fs::copy_options::overwrite_existing; -#endif + struct node + { + std::string url; + std::optional gui_auth{false}; + }; + + void to_json(nlohmann::json& j, const node& cfg); + void from_json(const nlohmann::json& j, node& cfg); } \ No newline at end of file diff --git a/src/core/atomicdex/config/mm2.cfg.hpp b/src/core/atomicdex/config/mm2.cfg.hpp index 0213830ba8..832e0cf517 100644 --- a/src/core/atomicdex/config/mm2.cfg.hpp +++ b/src/core/atomicdex/config/mm2.cfg.hpp @@ -22,6 +22,7 @@ //! Headers #include "atomicdex/utilities/global.utilities.hpp" #include "atomicdex/version/version.hpp" +#include "atomicdex/constants/dex.constants.hpp" namespace atomic_dex { @@ -32,11 +33,12 @@ namespace atomic_dex { std::string gui{std::string(DEX_NAME) + " "s + atomic_dex::get_version()}; int64_t netid{7777}; + int64_t rpcport{atomic_dex::g_dex_rpcport}; std::vector seednodes{}; //std::vector seednodes{"195.201.91.96", "195.201.91.53", "168.119.174.126", "46.4.78.11", "46.4.87.18"}; //std::vector seednodes{"46.4.78.11", "46.4.87.18"}; #ifdef _WIN32 - std::string userhome{utils::u8string(fs::path(_wgetenv(L"HOMEPATH")))}; + std::string userhome{utils::u8string(std::filesystem::path(_wgetenv(L"HOMEPATH")))}; #else std::string userhome{std::getenv("HOME")}; #endif @@ -54,6 +56,7 @@ namespace atomic_dex { cfg.gui = j.at("gui").get(); cfg.netid = j.at("netid").get(); + cfg.rpcport = j.at("rpcport").get(); cfg.userhome = j.at("userhome").get(); cfg.passphrase = j.at("passphrase").get(); cfg.rpc_password = j.at("rpc_password").get(); @@ -66,6 +69,7 @@ namespace atomic_dex j = json::object(); j["gui"] = cfg.gui; j["netid"] = cfg.netid; + j["rpcport"] = cfg.rpcport; j["userhome"] = cfg.userhome; j["passphrase"] = cfg.passphrase; j["rpc_password"] = cfg.rpc_password; diff --git a/src/core/atomicdex/config/raw.mm2.coins.cfg.hpp b/src/core/atomicdex/config/raw.mm2.coins.cfg.hpp index 4ed9dc25c1..1a824cb140 100644 --- a/src/core/atomicdex/config/raw.mm2.coins.cfg.hpp +++ b/src/core/atomicdex/config/raw.mm2.coins.cfg.hpp @@ -10,7 +10,6 @@ //! Project #include "atomicdex/api/mm2/mm2.constants.hpp" -#include "atomicdex/utilities/fs.prerequisites.hpp" #include "atomicdex/utilities/global.utilities.hpp" #include "atomicdex/utilities/qt.utilities.hpp" @@ -243,14 +242,14 @@ namespace atomic_dex { SPDLOG_INFO("parse_raw_mm2_coins_file"); t_mm2_raw_coins_registry out; - fs::path file_path{atomic_dex::utils::get_current_configs_path() / "coins.json"}; - if (not fs::exists(file_path)) + std::filesystem::path file_path{atomic_dex::utils::get_current_configs_path() / "coins.json"}; + if (not std::filesystem::exists(file_path)) { - fs::path original_mm2_coins_path{ag::core::assets_real_path() / "tools" / "mm2" / "coins"}; + std::filesystem::path original_mm2_coins_path{ag::core::assets_real_path() / "tools" / "mm2" / "coins"}; //! Copy our json to current version LOG_PATH_CMP("Copying mm2 coins cfg: {} to {}", original_mm2_coins_path, file_path); - fs::copy_file(original_mm2_coins_path, file_path, get_override_options()); + std::filesystem::copy_file(original_mm2_coins_path, file_path, std::filesystem::copy_options::overwrite_existing); } QFile file; diff --git a/src/core/atomicdex/constants/dex.constants.hpp b/src/core/atomicdex/constants/dex.constants.hpp index 11f1a3e031..631975d3fe 100644 --- a/src/core/atomicdex/constants/dex.constants.hpp +++ b/src/core/atomicdex/constants/dex.constants.hpp @@ -2,7 +2,41 @@ namespace atomic_dex { + inline const char* g_dex_api{DEX_API}; + inline const std::string g_dex_rpc{DEX_RPC}; + inline const int64_t g_dex_rpcport{std::stoi(DEX_RPCPORT)}; inline const std::string g_primary_dex_coin{DEX_PRIMARY_COIN}; inline const std::string g_second_primary_dex_coin{DEX_SECOND_PRIMARY_COIN}; - inline const std::vector g_default_coins{g_primary_dex_coin, g_second_primary_dex_coin}; -} \ No newline at end of file + inline const std::vector g_default_coins{ + g_primary_dex_coin, + g_second_primary_dex_coin, + "BTC", + "BNB", + "ETH", + "DAI-BEP20", + "FIRO-BEP20", + "BUSD-BEP20", + "USDC-BEP20", + "USDT-BEP20" + }; + inline const std::vector g_wallet_only_coins{ + "ARRR-BEP20", + "RBTC", + "NVC", + "PAXG-ERC20", + "USDT-ERC20", + "BET", + "BOTS", + "CRYPTO", + "DEX", + "HODL", + "JUMBLR", + "MGW", + "MSHARK", + "PANGEA", + "REVS", + "SUPERNET", + "XPM", + "ATOM" + }; +} diff --git a/src/core/atomicdex/constants/qt.coins.enums.cpp b/src/core/atomicdex/constants/qt.coins.enums.cpp index 4e757d51ad..593777550d 100644 --- a/src/core/atomicdex/constants/qt.coins.enums.cpp +++ b/src/core/atomicdex/constants/qt.coins.enums.cpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/src/core/atomicdex/constants/qt.coins.enums.hpp b/src/core/atomicdex/constants/qt.coins.enums.hpp index 19e07af208..83f70bcc5e 100644 --- a/src/core/atomicdex/constants/qt.coins.enums.hpp +++ b/src/core/atomicdex/constants/qt.coins.enums.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -51,9 +51,11 @@ namespace atomic_dex SmartBCH = 17, EthereumClassic = 18, RSK = 19, - Disabled = 20, - All = 21, - Size = 22 + ZHTLC = 20, + Disabled = 21, + Invalid = 22, + All = 23, + Size = 24 }; Q_ENUM(CoinTypeEnum) diff --git a/src/core/atomicdex/constants/qt.trading.enums.hpp b/src/core/atomicdex/constants/qt.trading.enums.hpp index 01efb63d21..31d1d7bd42 100644 --- a/src/core/atomicdex/constants/qt.trading.enums.hpp +++ b/src/core/atomicdex/constants/qt.trading.enums.hpp @@ -52,15 +52,17 @@ namespace atomic_dex { None = 0, TotalFeesNotEnoughFunds = 1, ///< Not enough to pay any kind of fees - BalanceIsLessThanTheMinimalTradingAmount = 2, ///< max_trading_vol < 0.00777 + BalanceIsLessThanTheMinimalTradingAmount = 2, ///< max_trading_vol < min_trade_amount PriceFieldNotFilled = 3, ///< Price empty or 0 VolumeFieldNotFilled = 4, ///< Volume empty or 0 - VolumeIsLowerThanTheMinimum = 5, ///< Volume field < 0.00777 + VolumeIsLowerThanTheMinimum = 5, ///< Volume field < min_trade_amount ReceiveVolumeIsLowerThanTheMinimum = 6, LeftParentChainNotEnabled = 7, LeftParentChainNotEnoughBalance = 8, RightParentChainNotEnoughBalance = 9, RightParentChainNotEnabled = 10, + LeftZhtlcChainNotEnabled = 11, + RightZhtlcChainNotEnabled = 12, }; Q_ENUM(TradingErrorEnum) diff --git a/src/core/atomicdex/data/dex/orders.and.swaps.data.hpp b/src/core/atomicdex/data/dex/orders.and.swaps.data.hpp index c0d6ed535a..0cd153feb4 100644 --- a/src/core/atomicdex/data/dex/orders.and.swaps.data.hpp +++ b/src/core/atomicdex/data/dex/orders.and.swaps.data.hpp @@ -16,6 +16,8 @@ namespace atomic_dex using t_filtering_infos = filtering_infos; + // todo: please change the logic of this and its usage in mm2 service and other places. + // not happy with the current implementation we can do better struct orders_and_swaps { //! Registries diff --git a/src/core/atomicdex/data/dex/qt.orders.data.hpp b/src/core/atomicdex/data/dex/qt.orders.data.hpp index 9fa08b3d50..27f0859ed2 100644 --- a/src/core/atomicdex/data/dex/qt.orders.data.hpp +++ b/src/core/atomicdex/data/dex/qt.orders.data.hpp @@ -9,7 +9,7 @@ //! deps #include -namespace mm2::api +namespace atomic_dex::mm2 { struct order_swaps_data { @@ -46,6 +46,8 @@ namespace mm2::api //! eg: 1595406178 unsigned long long unix_timestamp; + unsigned long long paymentLock; + //! eg: b741646a-5738-4012-b5b0-dcd1375affd1 QString order_id; @@ -86,9 +88,9 @@ namespace mm2::api std::optional min_volume{std::nullopt}; std::optional conf_settings{std::nullopt}; }; -} // namespace mm2::api +} // namespace atomic_dex::mm2 namespace atomic_dex { - using t_order_swaps_data = mm2::api::order_swaps_data; + using t_order_swaps_data = mm2::order_swaps_data; } \ No newline at end of file diff --git a/src/core/atomicdex/data/wallet/qt.portfolio.data.hpp b/src/core/atomicdex/data/wallet/qt.portfolio.data.hpp index 766683ce0f..7cd0e32c8a 100644 --- a/src/core/atomicdex/data/wallet/qt.portfolio.data.hpp +++ b/src/core/atomicdex/data/wallet/qt.portfolio.data.hpp @@ -60,6 +60,9 @@ namespace atomic_dex //! eg: Komodo data rates QJsonArray trend_7d; + //! eg: Komodo data rates + QJsonObject activation_status; + //! Price provider QString price_provider; diff --git a/src/core/atomicdex/events/events.hpp b/src/core/atomicdex/events/events.hpp index 7e3bd704ce..d5e23753ce 100644 --- a/src/core/atomicdex/events/events.hpp +++ b/src/core/atomicdex/events/events.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -20,7 +20,6 @@ #include #include -//! Project Headers #include namespace atomic_dex @@ -30,17 +29,18 @@ namespace atomic_dex using gui_enter_trading = entt::tag<"gui_enter_trading"_hs>; using gui_leave_trading = entt::tag<"gui_leave_trading"_hs>; using mm2_initialized = entt::tag<"mm2_running_and_enabling"_hs>; - //using tx_fetch_finished = entt::tag<"gui_tx_fetch_finished"_hs>; using default_coins_enabled = entt::tag<"default_coins_enabled"_hs>; - // using process_swaps_and_orders_finished = entt::tag<"process_swaps_and_orders_finished"_hs>; using band_oracle_refreshed = entt::tag<"band_oracle_refreshed"_hs>; using current_currency_changed = entt::tag<"update_orders_and_swap_values"_hs>; using force_update_providers = entt::tag<"force_update_providers"_hs>; - using download_release_finished = entt::tag<"download_release_finished"_hs>; + using download_started = entt::tag<"download_started"_hs>; + using download_complete = entt::tag<"download_complete"_hs>; + using download_failed = entt::tag<"download_failed"_hs>; struct tx_fetch_finished { - bool with_error{false}; + bool with_error{false}; + std::string ticker; }; struct process_swaps_and_orders_finished @@ -48,21 +48,22 @@ namespace atomic_dex bool after_manual_reset{false}; }; - struct enabling_coin_failed + struct enabling_z_coin_status { std::string coin; std::string reason; }; - struct batch_failed + struct enabling_coin_failed { - std::string from; + std::string coin; std::string reason; }; - struct mismatch_configuration_custom_coin + struct disabling_coin_failed { std::string coin; + std::string reason; }; struct endpoint_nonreacheable diff --git a/src/core/atomicdex/filesystem.hpp b/src/core/atomicdex/filesystem.hpp index b6486953b7..5529af10b3 100644 --- a/src/core/atomicdex/filesystem.hpp +++ b/src/core/atomicdex/filesystem.hpp @@ -2,17 +2,17 @@ namespace atomic_dex { - inline fs::path get_appdata_folder() + inline std::filesystem::path get_appdata_folder() { return utils::get_atomic_dex_data_folder(); } - inline fs::path get_themes_folder() + inline std::filesystem::path get_themes_folder() { return utils::get_themes_path(); } - inline fs::path get_theme_folder(std::string theme_name) + inline std::filesystem::path get_theme_folder(std::string theme_name) { return utils::get_themes_path() / theme_name; } diff --git a/src/core/atomicdex/filesystem.qml.cpp b/src/core/atomicdex/filesystem.qml.cpp index 23d7c3d544..2162dc07b8 100644 --- a/src/core/atomicdex/filesystem.qml.cpp +++ b/src/core/atomicdex/filesystem.qml.cpp @@ -19,6 +19,6 @@ namespace atomic_dex bool filesystem::exists(QString path) { - return fs::exists(path.toStdString()); + return std::filesystem::exists(path.toStdString()); } } \ No newline at end of file diff --git a/src/core/atomicdex/managers/notification.manager.cpp b/src/core/atomicdex/managers/notification.manager.cpp index 48cb8de054..e57fb22971 100644 --- a/src/core/atomicdex/managers/notification.manager.cpp +++ b/src/core/atomicdex/managers/notification.manager.cpp @@ -37,24 +37,24 @@ namespace atomic_dex void notification_manager::connect_signals() { - m_dispatcher.sink().connect<¬ification_manager::on_batch_failed>(*this); m_dispatcher.sink().connect<¬ification_manager::on_swap_status_notification>(*this); m_dispatcher.sink().connect<¬ification_manager::on_balance_update_notification>(*this); + m_dispatcher.sink().connect<¬ification_manager::on_enabling_z_coin_status>(*this); m_dispatcher.sink().connect<¬ification_manager::on_enabling_coin_failed>(*this); + m_dispatcher.sink().connect<¬ification_manager::on_disabling_coin_failed>(*this); m_dispatcher.sink().connect<¬ification_manager::on_endpoint_nonreacheable>(*this); - m_dispatcher.sink().connect<¬ification_manager::on_mismatch_custom_coins_configuration>(*this); m_dispatcher.sink().connect<¬ification_manager::on_fatal_notification>(*this); } void notification_manager::disconnect_signals() { - m_dispatcher.sink().disconnect<¬ification_manager::on_batch_failed>(*this); m_dispatcher.sink().disconnect<¬ification_manager::on_swap_status_notification>(*this); m_dispatcher.sink().disconnect<¬ification_manager::on_balance_update_notification>(*this); m_dispatcher.sink().disconnect<¬ification_manager::on_enabling_coin_failed>(*this); + m_dispatcher.sink().disconnect<¬ification_manager::on_disabling_coin_failed>(*this); + m_dispatcher.sink().disconnect<¬ification_manager::on_enabling_z_coin_status>(*this); m_dispatcher.sink().disconnect<¬ification_manager::on_endpoint_nonreacheable>(*this); - m_dispatcher.sink().disconnect<¬ification_manager::on_mismatch_custom_coins_configuration>(*this); m_dispatcher.sink().disconnect<¬ification_manager::on_fatal_notification>(*this); } @@ -68,43 +68,44 @@ namespace atomic_dex } void - notification_manager::on_enabling_coin_failed(const enabling_coin_failed& evt) + notification_manager::on_enabling_z_coin_status(const enabling_z_coin_status& evt) { using namespace std::chrono; qint64 timestamp = duration_cast(system_clock::now().time_since_epoch()).count(); QString human_date = QString::fromStdString(utils::to_human_date(timestamp, "%e %b %Y, %H:%M")); - emit enablingCoinFailedStatus(QString::fromStdString(evt.coin), QString::fromStdString(evt.reason), human_date, timestamp); + emit enablingZCoinStatus(QString::fromStdString(evt.coin), QString::fromStdString(evt.reason), human_date, timestamp); } void - notification_manager::on_endpoint_nonreacheable(const endpoint_nonreacheable& evt) + notification_manager::on_enabling_coin_failed(const enabling_coin_failed& evt) { using namespace std::chrono; qint64 timestamp = duration_cast(system_clock::now().time_since_epoch()).count(); QString human_date = QString::fromStdString(utils::to_human_date(timestamp, "%e %b %Y, %H:%M")); - emit endpointNonReacheableStatus(QString::fromStdString(evt.base_uri), human_date, timestamp); + emit enablingCoinFailedStatus(QString::fromStdString(evt.coin), QString::fromStdString(evt.reason), human_date, timestamp); } + void - notification_manager::on_mismatch_custom_coins_configuration(const mismatch_configuration_custom_coin& evt) + notification_manager::on_disabling_coin_failed(const disabling_coin_failed& evt) { using namespace std::chrono; qint64 timestamp = duration_cast(system_clock::now().time_since_epoch()).count(); QString human_date = QString::fromStdString(utils::to_human_date(timestamp, "%e %b %Y, %H:%M")); - emit mismatchCustomCoinConfiguration(QString::fromStdString(evt.coin), human_date, timestamp); + emit disablingCoinFailedStatus(QString::fromStdString(evt.coin), QString::fromStdString(evt.reason), human_date, timestamp); } void - notification_manager::on_fatal_notification(const fatal_notification& evt) + notification_manager::on_endpoint_nonreacheable(const endpoint_nonreacheable& evt) { - emit fatalNotification(QString::fromStdString(evt.message)); + using namespace std::chrono; + qint64 timestamp = duration_cast(system_clock::now().time_since_epoch()).count(); + QString human_date = QString::fromStdString(utils::to_human_date(timestamp, "%e %b %Y, %H:%M")); + emit endpointNonReacheableStatus(QString::fromStdString(evt.base_uri), human_date, timestamp); } void - notification_manager::on_batch_failed(const batch_failed& evt) + notification_manager::on_fatal_notification(const fatal_notification& evt) { - using namespace std::chrono; - qint64 timestamp = duration_cast(system_clock::now().time_since_epoch()).count(); - QString human_date = QString::fromStdString(utils::to_human_date(timestamp, "%e %b %Y, %H:%M")); - emit batchFailed(QString::fromStdString(evt.reason), QString::fromStdString(evt.from), human_date, timestamp); + emit fatalNotification(QString::fromStdString(evt.message)); } } // namespace atomic_dex diff --git a/src/core/atomicdex/managers/notification.manager.hpp b/src/core/atomicdex/managers/notification.manager.hpp index 494fea2255..a6c201cf4f 100644 --- a/src/core/atomicdex/managers/notification.manager.hpp +++ b/src/core/atomicdex/managers/notification.manager.hpp @@ -40,18 +40,20 @@ namespace atomic_dex void disconnect_signals() ; //! Callbacks - void on_batch_failed(const batch_failed& evt);; void on_swap_status_notification(const swap_status_notification& evt); + void on_enabling_z_coin_status(const enabling_z_coin_status& evt); void on_enabling_coin_failed(const enabling_coin_failed& evt); + void on_disabling_coin_failed(const disabling_coin_failed& evt); void on_balance_update_notification(const balance_update_notification& evt); void on_endpoint_nonreacheable(const endpoint_nonreacheable& evt); - void on_mismatch_custom_coins_configuration(const mismatch_configuration_custom_coin& evt); void on_fatal_notification(const fatal_notification& evt); signals: void updateSwapStatus(QString old_swap_status, QString new_swap_status, QString swap_uuid, QString base_coin, QString rel_coin, QString human_date); void balanceUpdateStatus(bool am_i_sender, QString amount, QString ticker, QString human_date, qint64 timestamp); + void enablingZCoinStatus(QString coin, QString error, QString human_date, qint64 timestamp); void enablingCoinFailedStatus(QString coin, QString error, QString human_date, qint64 timestamp); + void disablingCoinFailedStatus(QString coin, QString error, QString human_date, qint64 timestamp); void endpointNonReacheableStatus(QString base_uri, QString human_date, qint64 timestamp); void mismatchCustomCoinConfiguration(QString asset, QString human_date, qint64 timestamp); void fatalNotification(QString message); diff --git a/src/core/atomicdex/managers/qt.wallet.manager.cpp b/src/core/atomicdex/managers/qt.wallet.manager.cpp index 51725b12e2..2bc6e4b22e 100644 --- a/src/core/atomicdex/managers/qt.wallet.manager.cpp +++ b/src/core/atomicdex/managers/qt.wallet.manager.cpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -39,11 +39,11 @@ namespace atomic_dex using namespace std::string_literals; if (wallet_name == "") { - fs::remove(utils::get_atomic_dex_config_folder() / "default.wallet"); + std::filesystem::remove(utils::get_atomic_dex_config_folder() / "default.wallet"); return; } - fs::path path = (utils::get_atomic_dex_config_folder() / "default.wallet"s); + std::filesystem::path path = (utils::get_atomic_dex_config_folder() / "default.wallet"s); QFile out; out.setFileName(std_path_to_qstring(path)); out.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); @@ -70,17 +70,17 @@ namespace atomic_dex else { using namespace std::string_literals; - const fs::path seed_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".seed"s); - const fs::path wallet_object_path = utils::get_atomic_dex_export_folder() / (wallet_name.toStdString() + ".wallet.json"s); + const std::filesystem::path seed_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".seed"s); + const std::filesystem::path wallet_object_path = utils::get_atomic_dex_export_folder() / (wallet_name.toStdString() + ".wallet.json"s); const std::string wallet_cfg_file = std::string(atomic_dex::get_raw_version()) + "-coins"s + "."s + wallet_name.toStdString() + ".json"s; - const fs::path wallet_cfg_path = utils::get_atomic_dex_config_folder() / wallet_cfg_file; + const std::filesystem::path wallet_cfg_path = utils::get_atomic_dex_config_folder() / wallet_cfg_file; - if (not fs::exists(wallet_cfg_path)) + if (not std::filesystem::exists(wallet_cfg_path)) { const auto cfg_path = ag::core::assets_real_path() / "config"; std::string filename = std::string(atomic_dex::get_raw_version()) + "-coins.json"; - fs::copy(cfg_path / filename, wallet_cfg_path); + std::filesystem::copy(cfg_path / filename, wallet_cfg_path); } // Encrypt seed @@ -110,7 +110,7 @@ namespace atomic_dex { QStringList out; - for (auto&& p: fs::directory_iterator((utils::get_atomic_dex_config_folder()))) + for (auto&& p: std::filesystem::directory_iterator((utils::get_atomic_dex_config_folder()))) { if (p.path().extension().string() == ".seed") { @@ -128,7 +128,7 @@ namespace atomic_dex bool qt_wallet_manager::is_there_a_default_wallet() { - return fs::exists(utils::get_atomic_dex_config_folder() / "default.wallet"); + return std::filesystem::exists(utils::get_atomic_dex_config_folder() / "default.wallet"); } QString @@ -137,7 +137,7 @@ namespace atomic_dex if (is_there_a_default_wallet()) { QFile ifs; - fs::path path = (utils::get_atomic_dex_config_folder() / "default.wallet"); + std::filesystem::path path = (utils::get_atomic_dex_config_folder() / "default.wallet"); ifs.setFileName(std_path_to_qstring(path)); ifs.open(QIODevice::ReadOnly | QIODevice::Text); QString out = ifs.readAll(); @@ -152,7 +152,7 @@ namespace atomic_dex qt_wallet_manager::delete_wallet(const QString& wallet_name) { using namespace std::string_literals; - return fs::remove(utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".seed"s)); + return std::filesystem::remove(utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".seed"s)); } bool @@ -169,7 +169,7 @@ namespace atomic_dex } } using namespace std::string_literals; - const fs::path seed_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".seed"s); + const std::filesystem::path seed_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".seed"s); auto seed = atomic_dex::decrypt(seed_path, key.data(), ec); if (ec == dextop_error::corrupted_file_or_wrong_password) { @@ -184,7 +184,7 @@ namespace atomic_dex { SPDLOG_INFO("Loading wallet configuration: {}", wallet_name); using namespace std::string_literals; - const fs::path wallet_object_path = utils::get_atomic_dex_export_folder() / (wallet_name + ".wallet.json"s); + const std::filesystem::path wallet_object_path = utils::get_atomic_dex_export_folder() / (wallet_name + ".wallet.json"s); QFile ifs; ifs.setFileName(std_path_to_qstring(wallet_object_path)); ifs.open(QIODevice::ReadOnly | QIODevice::Text); @@ -212,7 +212,7 @@ namespace atomic_dex { SPDLOG_INFO("update_wallet_cfg"); using namespace std::string_literals; - const fs::path wallet_object_path = utils::get_atomic_dex_export_folder() / (m_wallet_cfg.name + ".wallet.json"s); + const std::filesystem::path wallet_object_path = utils::get_atomic_dex_export_folder() / (m_wallet_cfg.name + ".wallet.json"s); QFile ofs; ofs.setFileName(std_path_to_qstring(wallet_object_path)); ofs.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text); @@ -298,17 +298,27 @@ namespace atomic_dex using namespace std::string_literals; const std::string wallet_cfg_file = std::string(atomic_dex::get_raw_version()) + "-coins"s + "."s + wallet_name.toStdString() + ".json"s; - const fs::path wallet_cfg_path = utils::get_atomic_dex_config_folder() / wallet_cfg_file; + const std::filesystem::path wallet_cfg_path = utils::get_atomic_dex_config_folder() / wallet_cfg_file; + bool valid_json = false; + if (std::filesystem::exists(wallet_cfg_path)) + { + QFile ifs; + ifs.setFileName(std_path_to_qstring(wallet_cfg_path)); + ifs.open(QIODevice::ReadOnly | QIODevice::Text); + std::string json_data = QString(ifs.readAll()).toUtf8().constData(); + valid_json = nlohmann::json::accept(json_data); + ifs.close(); + } - if (not fs::exists(wallet_cfg_path)) + if (!valid_json) { const auto cfg_path = ag::core::assets_real_path() / "config"; std::string filename = std::string(atomic_dex::get_raw_version()) + "-coins.json"; - fs::copy(cfg_path / filename, wallet_cfg_path); + std::filesystem::copy(cfg_path / filename, wallet_cfg_path, std::filesystem::copy_options::overwrite_existing); } - const fs::path seed_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".seed"s); + const std::filesystem::path seed_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".seed"s); auto seed = atomic_dex::decrypt(seed_path, key.data(), ec); if (ec == dextop_error::corrupted_file_or_wrong_password) { diff --git a/src/core/atomicdex/models/qt.addressbook.contact.model.cpp b/src/core/atomicdex/models/qt.addressbook.contact.model.cpp index 23965168a5..4464d0e674 100644 --- a/src/core/atomicdex/models/qt.addressbook.contact.model.cpp +++ b/src/core/atomicdex/models/qt.addressbook.contact.model.cpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -14,13 +14,10 @@ * * ******************************************************************************/ -// STD #include -// Qt #include -// Project #include "atomicdex/pages/qt.portfolio.page.hpp" #include "atomicdex/utilities/qt.utilities.hpp" #include "atomicdex/managers/addressbook.manager.hpp" //> addressbook_manager @@ -48,8 +45,7 @@ namespace atomic_dex // QAbstractListModel Functions namespace atomic_dex { - QVariant - addressbook_contact_model::data(const QModelIndex& index, int role) const + QVariant addressbook_contact_model::data(const QModelIndex& index, int role) const { if (!hasIndex(index.row(), index.column(), index.parent())) { @@ -72,14 +68,12 @@ namespace atomic_dex } } - int - addressbook_contact_model::rowCount([[maybe_unused]] const QModelIndex& parent) const + int addressbook_contact_model::rowCount([[maybe_unused]] const QModelIndex& parent) const { return m_address_entries.size(); } - QHash - addressbook_contact_model::roleNames() const + QHash addressbook_contact_model::roleNames() const { return { {AddressTypeRole, "address_type"}, @@ -92,37 +86,33 @@ namespace atomic_dex // Getters/Setters namespace atomic_dex { - const QString& - addressbook_contact_model::get_name() const + const QString& addressbook_contact_model::get_name() const { return m_name; } - void - addressbook_contact_model::set_name(const QString& name) + void addressbook_contact_model::set_name(const QString& name) { auto& addrbook_manager = m_system_manager.get_system(); if (name != m_name) { - if (!m_name.isEmpty()) + if (!name.isEmpty()) { addrbook_manager.change_contact_name(m_name.toStdString(), name.toStdString()); addrbook_manager.save_configuration(); + m_name = name; + emit nameChanged(); } - m_name = name; - emit nameChanged(); } } - const QStringList& - addressbook_contact_model::get_categories() const + const QStringList& addressbook_contact_model::get_categories() const { return m_categories; } - void - addressbook_contact_model::set_categories(QStringList categories) + void addressbook_contact_model::set_categories(QStringList categories) { m_categories = std::move(categories); emit categoriesChanged(); @@ -142,8 +132,7 @@ namespace atomic_dex // QML API namespace atomic_dex { - bool - addressbook_contact_model::add_category(const QString& category) + bool addressbook_contact_model::addCategory(const QString& category) { if (m_categories.contains(category)) { @@ -154,15 +143,13 @@ namespace atomic_dex return true; } - void - addressbook_contact_model::remove_category(const QString& category) + void addressbook_contact_model::removeCategory(const QString& category) { m_categories.removeOne(category); emit categoriesChanged(); } - bool - addressbook_contact_model::add_address_entry(QString type, QString key, QString value) + bool addressbook_contact_model::addAddressEntry(QString type, QString key, QString value) { // Returns false if the given key already exists. auto res = match(index(0), AddressTypeAndKeyRole, type + key, 1, Qt::MatchFlag::MatchExactly); @@ -182,8 +169,7 @@ namespace atomic_dex return true; } - void - addressbook_contact_model::remove_address_entry(const QString& type, const QString& key) + void addressbook_contact_model::removeAddressEntry(const QString& type, const QString& key) { auto res = match(index(0), AddressTypeAndKeyRole, type + key, 1, Qt::MatchFlag::MatchExactly); @@ -195,8 +181,7 @@ namespace atomic_dex } } - void - addressbook_contact_model::reload() + void addressbook_contact_model::reload() { // Clears model clear(); @@ -205,8 +190,7 @@ namespace atomic_dex populate(); } - void - addressbook_contact_model::save() + void addressbook_contact_model::save() { auto& addrbook_manager = m_system_manager.get_system(); diff --git a/src/core/atomicdex/models/qt.addressbook.contact.model.hpp b/src/core/atomicdex/models/qt.addressbook.contact.model.hpp index 07525ebae8..c07a4ffec3 100644 --- a/src/core/atomicdex/models/qt.addressbook.contact.model.hpp +++ b/src/core/atomicdex/models/qt.addressbook.contact.model.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -16,11 +16,9 @@ #pragma once -// 3rdParty Headers #include //> ENTT_API #include //> ag::ecs::system_manager -// Project Headers #include "qt.addressbook.contact.proxy.filter.model.hpp" namespace atomic_dex @@ -58,12 +56,12 @@ namespace atomic_dex [[nodiscard]] QHash roleNames() const final; // Getters/Setters - [[nodiscard]] const QString& get_name() const ; - void set_name(const QString& name) ; - [[nodiscard]] const QStringList& get_categories() const ; - void set_categories(QStringList categories) ; - [[nodiscard]] addressbook_contact_proxy_filter_model* get_proxy_filter() const ; - [[nodiscard]] const QVector& get_address_entries() const ; // Returns contact's current addresses. + [[nodiscard]] const QString& get_name() const; + void set_name(const QString& name); + [[nodiscard]] const QStringList& get_categories() const; + void set_categories(QStringList categories); + [[nodiscard]] addressbook_contact_proxy_filter_model* get_proxy_filter() const; + [[nodiscard]] const QVector& get_address_entries() const; // Returns contact's current addresses. // Loads this model data from the persistent data. void populate(); @@ -72,17 +70,17 @@ namespace atomic_dex void clear(); // QML API - Q_INVOKABLE bool add_category(const QString& category) ; // Adds a category to the current contact. - Q_INVOKABLE void remove_category(const QString& category) ; // Removes a category from the current contact. - Q_INVOKABLE bool add_address_entry(QString type, QString key, QString value) ; // Adds an address entry to the current contact. Returns false if the key already exists in the given wallet type, false otherwise. - Q_INVOKABLE void remove_address_entry(const QString& type, const QString& key) ; // Removes an address entry from the current contact. - Q_INVOKABLE void reload(); // Reinitializes data from the persistent data ignoring pending changes. - Q_INVOKABLE void save(); // Saves the current contact pending changes in the persistent data. + Q_INVOKABLE bool addCategory(const QString& category); // Adds a category to the current contact. + Q_INVOKABLE void removeCategory(const QString& category); // Removes a category from the current contact. + Q_INVOKABLE bool addAddressEntry(QString type, QString key, QString value); // Adds an address entry to the current contact. Returns false if the key already exists in the given wallet type, false otherwise. + Q_INVOKABLE void removeAddressEntry(const QString& type, const QString& key); // Removes an address entry from the current contact. + Q_INVOKABLE void reload(); // Reinitializes data from the persistent data ignoring pending changes. + Q_INVOKABLE void save(); // Saves the current contact pending changes in the persistent data. // QML API Properties Q_PROPERTY(QString name READ get_name WRITE set_name NOTIFY nameChanged) Q_PROPERTY(QStringList categories READ get_categories WRITE set_categories NOTIFY categoriesChanged) - Q_PROPERTY(addressbook_contact_proxy_filter_model* proxy_filter READ get_proxy_filter NOTIFY proxyFilterChanged) + Q_PROPERTY(addressbook_contact_proxy_filter_model* proxyFilter READ get_proxy_filter NOTIFY proxyFilterChanged) // QML API Properties Signals signals: diff --git a/src/core/atomicdex/models/qt.addressbook.contact.proxy.filter.model.hpp b/src/core/atomicdex/models/qt.addressbook.contact.proxy.filter.model.hpp index 24aee8ddd8..21c4279889 100644 --- a/src/core/atomicdex/models/qt.addressbook.contact.proxy.filter.model.hpp +++ b/src/core/atomicdex/models/qt.addressbook.contact.proxy.filter.model.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -49,8 +49,8 @@ namespace atomic_dex [[nodiscard]] bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const final; // Sorts address entries by type then by key. // QML API Properties - Q_PROPERTY(QString search_expression READ get_search_expression WRITE set_search_expression NOTIFY searchExpressionChanged) - Q_PROPERTY(QString filter_type READ get_filter_type WRITE set_filter_type NOTIFY filterTypeChanged) + Q_PROPERTY(QString searchExpression READ get_search_expression WRITE set_search_expression NOTIFY searchExpressionChanged) + Q_PROPERTY(QString filterType READ get_filter_type WRITE set_filter_type NOTIFY filterTypeChanged) // QML API Properties Signals signals: diff --git a/src/core/atomicdex/models/qt.addressbook.model.cpp b/src/core/atomicdex/models/qt.addressbook.model.cpp index 6a4d73cade..ed372b198d 100644 --- a/src/core/atomicdex/models/qt.addressbook.model.cpp +++ b/src/core/atomicdex/models/qt.addressbook.model.cpp @@ -90,7 +90,7 @@ namespace atomic_dex } void - addressbook_model::remove_contact(const QString& name) + addressbook_model::removeContact(const QString& name) { auto& addrbook_manager = m_system_manager.get_system(); auto res = match(index(0), NameRole, name, 1, Qt::MatchFlag::MatchExactly); @@ -105,7 +105,7 @@ namespace atomic_dex } } - bool addressbook_model::add_contact(const QString& name) + bool addressbook_model::addContact(const QString& name) { auto& addrbook_manager = m_system_manager.get_system(); diff --git a/src/core/atomicdex/models/qt.addressbook.model.hpp b/src/core/atomicdex/models/qt.addressbook.model.hpp index 252e773f3a..309d82bcd2 100644 --- a/src/core/atomicdex/models/qt.addressbook.model.hpp +++ b/src/core/atomicdex/models/qt.addressbook.model.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -68,8 +68,8 @@ namespace atomic_dex [[nodiscard]] addressbook_proxy_model* get_addressbook_proxy_mdl() const ; // QML API - Q_INVOKABLE bool add_contact(const QString& name); - Q_INVOKABLE void remove_contact(const QString& name); + Q_INVOKABLE bool addContact(const QString& name); + Q_INVOKABLE void removeContact(const QString& name); // QML API properties Q_PROPERTY(addressbook_proxy_model* proxy READ get_addressbook_proxy_mdl NOTIFY addressbookProxyChanged); diff --git a/src/core/atomicdex/models/qt.addressbook.proxy.filter.model.hpp b/src/core/atomicdex/models/qt.addressbook.proxy.filter.model.hpp index b2c59a5210..b7f3d2e01b 100644 --- a/src/core/atomicdex/models/qt.addressbook.proxy.filter.model.hpp +++ b/src/core/atomicdex/models/qt.addressbook.proxy.filter.model.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -51,12 +51,12 @@ namespace atomic_dex void set_type_filter(QString value) ; // QML Properties - Q_PROPERTY(QString search_exp READ get_search_exp WRITE set_search_exp NOTIFY search_expChanged) - Q_PROPERTY(QString type_filter READ get_type_filter WRITE set_type_filter NOTIFY typeFilterChanged) + Q_PROPERTY(QString searchExp READ get_search_exp WRITE set_search_exp NOTIFY searchExpChanged) + Q_PROPERTY(QString typeFilter READ get_type_filter WRITE set_type_filter NOTIFY typeFilterChanged) // QML Properties Signals signals: - void search_expChanged(); + void searchExpChanged(); void typeFilterChanged(); }; } // namespace atomic_dex 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 1012b7e9e5..6acc6c482d 100644 --- a/src/core/atomicdex/models/qt.global.coins.cfg.model.cpp +++ b/src/core/atomicdex/models/qt.global.coins.cfg.model.cpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -30,12 +30,14 @@ namespace { QJsonObject j{ {"active", coin.active}, + {"activation_status", atomic_dex::nlohmann_json_object_to_qt_json_object(coin.activation_status)}, {"is_claimable", coin.is_claimable}, {"minimal_balance_for_asking_rewards", QString::fromStdString(coin.minimal_claim_amount)}, {"ticker", QString::fromStdString(coin.ticker)}, {"name", QString::fromStdString(coin.name)}, {"type", QString::fromStdString(coin.type)}, - {"explorer_url", QJsonArray::fromStringList(atomic_dex::vector_std_string_to_qt_string_list(coin.explorer_url))}, + {"nomics_id", QString::fromStdString(coin.nomics_id)}, + {"explorer_url", QString::fromStdString(coin.explorer_url)}, {"tx_uri", QString::fromStdString(coin.tx_uri)}, {"address_uri", QString::fromStdString(coin.address_url)}, {"is_custom_coin", coin.is_custom_coin}, @@ -43,6 +45,7 @@ namespace {"has_parent_fees_ticker", coin.has_parent_fees_ticker}, {"is_testnet", coin.is_testnet.value_or(false)}, {"is_erc_family", coin.is_erc_family}, + {"is_zhtlc_family", coin.is_zhtlc_family}, {"is_wallet_only", coin.wallet_only}, {"fees_ticker", QString::fromStdString(coin.fees_ticker)}}; return j; @@ -95,6 +98,8 @@ namespace atomic_dex return item.currently_enabled; case Active: return item.active; + case ActivationStatus: + return atomic_dex::nlohmann_json_object_to_qt_json_object(item.activation_status); case IsCustomCoin: return item.is_custom_coin; case Type: @@ -212,8 +217,7 @@ namespace atomic_dex } template - void - global_coins_cfg_model::update_status(const TArray& tickers, bool status) + void global_coins_cfg_model::update_status(const TArray& tickers, bool status) { auto update_functor = [this, status](QModelIndexList res, [[maybe_unused]] const QString& ticker) { // SPDLOG_INFO("Changing Active/CurrentlyEnabled status to {} for ticker {}", status, ticker.toStdString()); @@ -322,6 +326,19 @@ namespace atomic_dex return m_proxies[CoinType::UTXO]; } + + global_coins_cfg_proxy_model* + global_coins_cfg_model::get_all_slp_proxy() const + { + return m_proxies[CoinType::SLP]; + } + + global_coins_cfg_proxy_model* + global_coins_cfg_model::get_all_zhtlc_proxy() const + { + return m_proxies[CoinType::ZHTLC]; + } + int global_coins_cfg_model::get_length() const { 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 e14f5bc208..f64b244322 100644 --- a/src/core/atomicdex/models/qt.global.coins.cfg.model.hpp +++ b/src/core/atomicdex/models/qt.global.coins.cfg.model.hpp @@ -55,7 +55,8 @@ namespace atomic_dex IsCustomCoin, Type, CoinType, - Checked + Checked, + ActivationStatus }; Q_ENUMS(CoinsRoles) @@ -85,16 +86,18 @@ namespace atomic_dex [[nodiscard]] global_coins_cfg_proxy_model* get_all_bep20_proxy() const; [[nodiscard]] global_coins_cfg_proxy_model* get_all_smartchains_proxy() const; [[nodiscard]] global_coins_cfg_proxy_model* get_all_utxo_proxy() const; + [[nodiscard]] global_coins_cfg_proxy_model* get_all_slp_proxy() const; + [[nodiscard]] global_coins_cfg_proxy_model* get_all_zhtlc_proxy() const; [[nodiscard]] int get_length() const; [[nodiscard]] int get_checked_nb() const; void set_checked_nb(int value); [[nodiscard]] const QStringList& get_all_coin_types() const; // QML API functions - Q_INVOKABLE QStringList get_checked_coins() const; - Q_INVOKABLE QVariant get_coin_info(const QString& ticker) const; - Q_INVOKABLE QString get_parent_coin(const QString& ticker) const; - Q_INVOKABLE bool is_coin_type(const QString& ticker) const; // Tells if the given string is a valid coin type (e.g. QRC-20) + [[nodiscard]] Q_INVOKABLE QStringList get_checked_coins() const; + [[nodiscard]] Q_INVOKABLE QVariant get_coin_info(const QString& ticker) const; + [[nodiscard]] Q_INVOKABLE QString get_parent_coin(const QString& ticker) const; + [[nodiscard]] Q_INVOKABLE bool is_coin_type(const QString& ticker) const; // Tells if the given string is a valid coin type (e.g. QRC-20) // QML API properties Q_PROPERTY(global_coins_cfg_proxy_model* all_disabled_proxy READ get_all_disabled_proxy NOTIFY all_disabled_proxyChanged) @@ -104,6 +107,8 @@ namespace atomic_dex Q_PROPERTY(global_coins_cfg_proxy_model* all_bep20_proxy READ get_all_bep20_proxy NOTIFY all_bep20_proxyChanged) Q_PROPERTY(global_coins_cfg_proxy_model* all_smartchains_proxy READ get_all_smartchains_proxy NOTIFY all_smartchains_proxyChanged) Q_PROPERTY(global_coins_cfg_proxy_model* all_utxo_proxy READ get_all_utxo_proxy NOTIFY all_utxo_proxyChanged) + Q_PROPERTY(global_coins_cfg_proxy_model* all_slp_proxy READ get_all_slp_proxy NOTIFY all_slp_proxyChanged) + Q_PROPERTY(global_coins_cfg_proxy_model* all_zhtlc_proxy READ get_all_zhtlc_proxy NOTIFY all_zhtlc_proxyChanged) Q_PROPERTY(int length READ get_length NOTIFY lengthChanged) Q_PROPERTY(int checked_nb READ get_checked_nb WRITE set_checked_nb NOTIFY checked_nbChanged) Q_PROPERTY(QStringList all_coin_types READ get_all_coin_types) @@ -117,6 +122,8 @@ namespace atomic_dex void all_bep20_proxyChanged(); void all_smartchains_proxyChanged(); void all_utxo_proxyChanged(); + void all_slp_proxyChanged(); + void all_zhtlc_proxyChanged(); void lengthChanged(); void checked_nbChanged(); diff --git a/src/core/atomicdex/models/qt.global.coins.cfg.proxy.filter.model.cpp b/src/core/atomicdex/models/qt.global.coins.cfg.proxy.filter.model.cpp index 5599adb226..b72dc71f48 100644 --- a/src/core/atomicdex/models/qt.global.coins.cfg.proxy.filter.model.cpp +++ b/src/core/atomicdex/models/qt.global.coins.cfg.proxy.filter.model.cpp @@ -38,7 +38,12 @@ namespace atomic_dex [[maybe_unused]] QModelIndex idx = this->sourceModel()->index(source_row, 0, source_parent); assert(this->sourceModel()->hasIndex(idx.row(), 0)); - if (m_type < CoinType::Disabled) + if (this->sourceModel()->data(idx, global_coins_cfg_model::CoinType) == static_cast(CoinType::Invalid)) + { + return false; + } + + else if (m_type < CoinType::Disabled) { if (this->sourceModel()->data(idx, global_coins_cfg_model::CoinType) != static_cast(m_type)) { diff --git a/src/core/atomicdex/models/qt.orderbook.model.cpp b/src/core/atomicdex/models/qt.orderbook.model.cpp index 65e4958a73..daf5353b75 100644 --- a/src/core/atomicdex/models/qt.orderbook.model.cpp +++ b/src/core/atomicdex/models/qt.orderbook.model.cpp @@ -104,8 +104,6 @@ namespace atomic_dex return QString::fromStdString(m_model_data.at(index.row()).price_fraction_denom); case PriceNumerRole: return QString::fromStdString(m_model_data.at(index.row()).price_fraction_numer); - case QuantityRole: - return QString::fromStdString(m_model_data.at(index.row()).maxvolume); case TotalRole: return QString::fromStdString(m_model_data.at(index.row()).total); case UUIDRole: @@ -114,10 +112,6 @@ namespace atomic_dex return m_model_data.at(index.row()).is_mine; case PercentDepthRole: return QString::fromStdString(m_model_data.at(index.row()).depth_percent); - case QuantityDenomRole: - return QString::fromStdString(m_model_data.at(index.row()).max_volume_fraction_denom); - case QuantityNumerRole: - return QString::fromStdString(m_model_data.at(index.row()).max_volume_fraction_numer); case BaseMinVolumeRole: return QString::fromStdString(m_model_data.at(index.row()).base_min_volume); case BaseMinVolumeDenomRole: @@ -163,7 +157,6 @@ namespace atomic_dex { taker_vol_std = "0"; } - // t_float_50 mm2_min_trade_vol = safe_float(trading_pg.get_mm2_min_trade_vol().toStdString()); t_float_50 taker_vol = safe_float(taker_vol_std); i_have_enough_funds = min_volume_f > 0 && taker_vol > min_volume_f; return i_have_enough_funds; @@ -254,7 +247,7 @@ namespace atomic_dex { return false; } - ::mm2::api::order_contents& order = m_model_data.at(index.row()); + mm2::order_contents& order = m_model_data.at(index.row()); switch (static_cast(role)) { case PriceRole: @@ -269,9 +262,6 @@ namespace atomic_dex case IsMineRole: order.is_mine = value.toBool(); break; - case QuantityRole: - order.maxvolume = value.toString().toStdString(); - break; case TotalRole: order.total = value.toString().toStdString(); break; @@ -281,12 +271,6 @@ namespace atomic_dex case PercentDepthRole: order.depth_percent = value.toString().toStdString(); break; - case QuantityDenomRole: - order.max_volume_fraction_denom = value.toString().toStdString(); - break; - case QuantityNumerRole: - order.max_volume_fraction_numer = value.toString().toStdString(); - break; case CoinRole: order.coin = value.toString().toStdString(); break; @@ -352,14 +336,11 @@ namespace atomic_dex return { {PriceRole, "price"}, {CoinRole, "coin"}, - {QuantityRole, "quantity"}, {TotalRole, "total"}, {UUIDRole, "uuid"}, {IsMineRole, "is_mine"}, {PriceDenomRole, "price_denom"}, {PriceNumerRole, "price_numer"}, - {QuantityDenomRole, "quantity_denom"}, - {QuantityNumerRole, "quantity_numer"}, {PercentDepthRole, "depth"}, {MinVolumeRole, "min_volume"}, {EnoughFundsToPayMinVolume, "enough_funds_to_pay_min_volume"}, @@ -411,7 +392,7 @@ namespace atomic_dex void - orderbook_model::initialize_order(const ::mm2::api::order_contents& order) + orderbook_model::initialize_order(const mm2::order_contents& order) { if (m_orders_id_registry.contains(order.uuid)) { @@ -450,7 +431,7 @@ namespace atomic_dex } void - orderbook_model::update_order(const ::mm2::api::order_contents& order) + orderbook_model::update_order(const mm2::order_contents& order) { if (const auto res = this->match(index(0, 0), UUIDRole, QString::fromStdString(order.uuid)); not res.isEmpty()) { @@ -461,7 +442,6 @@ namespace atomic_dex update_value(OrderbookRoles::PriceNumerRole, QString::fromStdString(order.price_fraction_numer), idx, *this); update_value(OrderbookRoles::PriceDenomRole, QString::fromStdString(order.price_fraction_denom), idx, *this); update_value(OrderbookRoles::IsMineRole, order.is_mine, idx, *this); - update_value(OrderbookRoles::QuantityRole, QString::fromStdString(order.maxvolume), idx, *this); update_value(OrderbookRoles::TotalRole, QString::fromStdString(order.total), idx, *this); update_value(OrderbookRoles::PercentDepthRole, QString::fromStdString(order.depth_percent), idx, *this); update_value(OrderbookRoles::BaseMinVolumeRole, QString::fromStdString(order.base_min_volume), idx, *this); @@ -488,7 +468,6 @@ namespace atomic_dex OrderbookRoles::PriceNumerRole, OrderbookRoles::PriceDenomRole, OrderbookRoles::IsMineRole, - OrderbookRoles::QuantityRole, OrderbookRoles::TotalRole, OrderbookRoles::PercentDepthRole, OrderbookRoles::BaseMinVolumeRole, @@ -541,19 +520,16 @@ namespace atomic_dex void orderbook_model::refresh_orderbook(const t_orders_contents& orderbook) { - auto refresh_functor = [this](const std::vector<::mm2::api::order_contents>& contents) + auto refresh_functor = [this](const std::vector& contents) { - // SPDLOG_INFO("refresh orderbook of size: {}", contents.size()); for (auto&& current_order: contents) { if (this->m_orders_id_registry.find(current_order.uuid) != this->m_orders_id_registry.end()) { - //! Update this->update_order(current_order); } else { - //! Insertion this->initialize_order(current_order); } } @@ -569,10 +545,6 @@ namespace atomic_dex auto res_list = this->match(index(0, 0), UUIDRole, QString::fromStdString(id)); if (not res_list.empty()) { - if (this->m_current_orderbook_kind == kind::best_orders) - { - // SPDLOG_INFO("Removing order with UUID: {}", id); - } this->removeRow(res_list.at(0).row()); to_remove.emplace(id); } @@ -626,7 +598,7 @@ namespace atomic_dex void orderbook_model::clear_orderbook() { - SPDLOG_INFO("clear orderbook"); + // SPDLOG_INFO("clear orderbook"); this->beginResetModel(); m_model_data = t_orders_contents{}; m_orders_id_registry.clear(); @@ -658,11 +630,8 @@ namespace atomic_dex const bool is_buy = trading_pg.get_market_mode() == MarketMode::Buy; out["coin"] = QString::fromStdString(is_buy ? order.rel_coin.value() : order.coin); out["price"] = QString::fromStdString(order.price); - out["quantity"] = QString::fromStdString(order.maxvolume); out["price_denom"] = QString::fromStdString(order.price_fraction_denom); out["price_numer"] = QString::fromStdString(order.price_fraction_numer); - out["quantity_denom"] = QString::fromStdString(order.max_volume_fraction_denom); - out["quantity_numer"] = QString::fromStdString(order.max_volume_fraction_numer); out["min_volume"] = QString::fromStdString(order.min_volume); out["base_min_volume"] = QString::fromStdString(order.base_min_volume); out["base_max_volume"] = QString::fromStdString(order.base_max_volume); diff --git a/src/core/atomicdex/models/qt.orderbook.model.hpp b/src/core/atomicdex/models/qt.orderbook.model.hpp index a9289ff937..6e320e68f9 100644 --- a/src/core/atomicdex/models/qt.orderbook.model.hpp +++ b/src/core/atomicdex/models/qt.orderbook.model.hpp @@ -52,14 +52,11 @@ namespace atomic_dex { PriceRole = Qt::UserRole + 1, // 257 CoinRole, - QuantityRole, TotalRole, UUIDRole, IsMineRole, PriceDenomRole, PriceNumerRole, - QuantityDenomRole, - QuantityNumerRole, PercentDepthRole, MinVolumeRole, EnoughFundsToPayMinVolume, @@ -105,8 +102,8 @@ namespace atomic_dex void betterOrderDetected(QVariantMap order_object); private: - void initialize_order(const ::mm2::api::order_contents& order); - void update_order(const ::mm2::api::order_contents& order); + void initialize_order(const mm2::order_contents& order); + void update_order(const mm2::order_contents& order); QVariantMap get_order_from_uuid(QString uuid); void check_for_better_order(trading_page& trading_pg, const QVariantMap& preferred_order, std::string uuid); diff --git a/src/core/atomicdex/models/qt.orderbook.proxy.model.cpp b/src/core/atomicdex/models/qt.orderbook.proxy.model.cpp index 08b7805a9b..16b1a350d4 100644 --- a/src/core/atomicdex/models/qt.orderbook.proxy.model.cpp +++ b/src/core/atomicdex/models/qt.orderbook.proxy.model.cpp @@ -48,8 +48,6 @@ namespace atomic_dex { case orderbook_model::PriceRole: return safe_float(left_data.toString().toStdString()) < safe_float(right_data.toString().toStdString()); - case orderbook_model::QuantityRole: - break; case orderbook_model::TotalRole: break; case orderbook_model::UUIDRole: @@ -62,10 +60,6 @@ namespace atomic_dex break; case orderbook_model::PercentDepthRole: break; - case orderbook_model::QuantityDenomRole: - break; - case orderbook_model::QuantityNumerRole: - break; case orderbook_model::CoinRole: break; case orderbook_model::MinVolumeRole: @@ -171,12 +165,10 @@ namespace atomic_dex const auto volume = provider.get_total_volume(utils::retrieve_main_ticker(ticker)); if (coin_info.ticker.empty() || coin_info.wallet_only) //< this means it's not present in our cfg - skipping { - SPDLOG_WARN("{} excluded empty", coin_info.ticker); return false; } if (is_cex_id_available && (rates > 100 || fiat_price <= 0 || ((safe_float(volume) < limit) && coin_info.coin_type != CoinType::SmartChain))) { - SPDLOG_WARN("{} excluded rates/fiat {} {} {}", coin_info.ticker, rates.str(), fiat_price.str(), volume); return false; } break; diff --git a/src/core/atomicdex/models/qt.orders.model.cpp b/src/core/atomicdex/models/qt.orders.model.cpp index 2c73a8b3b0..8a74a41fed 100644 --- a/src/core/atomicdex/models/qt.orders.model.cpp +++ b/src/core/atomicdex/models/qt.orders.model.cpp @@ -91,6 +91,9 @@ namespace atomic_dex case UnixTimestampRole: item.unix_timestamp = value.toULongLong(); break; + case PaymentLockRole: + item.paymentLock = value.toULongLong(); + break; case OrderIdRole: item.order_id = value.toString(); break; @@ -169,6 +172,8 @@ namespace atomic_dex return item.human_date; case UnixTimestampRole: return item.unix_timestamp; + case PaymentLockRole: + return item.paymentLock; case OrderIdRole: return item.order_id; case OrderStatusRole: @@ -232,6 +237,7 @@ namespace atomic_dex {IsMakerRole, "is_maker"}, {HumanDateRole, "date"}, {UnixTimestampRole, "timestamp"}, + {PaymentLockRole, "paymentLock"}, {OrderIdRole, "order_id"}, {OrderStatusRole, "order_status"}, {MakerPaymentIdRole, "maker_payment_id"}, @@ -418,6 +424,7 @@ namespace atomic_dex auto&& [prev_value, new_value, is_change] = update_value(OrdersRoles::OrderStatusRole, contents.order_status, idx, *this); update_value(OrdersRoles::UnixTimestampRole, contents.unix_timestamp, idx, *this); + update_value(OrdersRoles::PaymentLockRole, contents.paymentLock, idx, *this); auto&& [prev_value_d, new_value_d, _] = update_value(OrdersRoles::HumanDateRole, contents.human_date, idx, *this); if (is_change) { @@ -704,19 +711,24 @@ namespace atomic_dex this->set_recover_fund_busy(true); auto& mm2_system = m_system_manager.get_system(); nlohmann::json batch = nlohmann::json::array(); - nlohmann::json json_data = ::mm2::api::template_request("recover_funds_of_swap"); - mm2::api::recover_funds_of_swap_request req{.swap_uuid = uuid.toStdString()}; - ::mm2::api::to_json(json_data, req); + nlohmann::json json_data = mm2::template_request("recover_funds_of_swap"); + mm2::recover_funds_of_swap_request req{.swap_uuid = uuid.toStdString()}; + mm2::to_json(json_data, req); batch.push_back(json_data); + SPDLOG_DEBUG("recover_funds_of_swap request: {}", json_data.dump(-1)); + auto answer_functor = [this](web::http::http_response resp) { nlohmann::json j_out = nlohmann::json::object(); std::string body = TO_STD_STR(resp.extract_string(true).get()); + + SPDLOG_DEBUG("recover_funds_of_swap answer received: {}", body); + if (resp.status_code() == web::http::status_codes::OK) { auto answers = nlohmann::json::parse(body); - auto recover_answer = ::mm2::api::rpc_process_answer_batch(answers[0], "recover_funds_of_swap"); + auto recover_answer = mm2::rpc_process_answer_batch(answers[0], "recover_funds_of_swap"); if (recover_answer.result.has_value()) { auto answer = recover_answer.result.value(); diff --git a/src/core/atomicdex/models/qt.orders.model.hpp b/src/core/atomicdex/models/qt.orders.model.hpp index f8f0659000..b3dfbe7b83 100644 --- a/src/core/atomicdex/models/qt.orders.model.hpp +++ b/src/core/atomicdex/models/qt.orders.model.hpp @@ -66,6 +66,7 @@ namespace atomic_dex IsMakerRole, HumanDateRole, UnixTimestampRole, + PaymentLockRole, OrderIdRole, OrderStatusRole, MakerPaymentIdRole, diff --git a/src/core/atomicdex/models/qt.orders.proxy.model.cpp b/src/core/atomicdex/models/qt.orders.proxy.model.cpp index 0801b43a0c..b18f0cd7ed 100644 --- a/src/core/atomicdex/models/qt.orders.proxy.model.cpp +++ b/src/core/atomicdex/models/qt.orders.proxy.model.cpp @@ -63,6 +63,8 @@ namespace atomic_dex break; case orders_model::UnixTimestampRole: return left_data.toULongLong() < right_data.toULongLong(); + case orders_model::PaymentLockRole: + break; case orders_model::OrderIdRole: break; case orders_model::OrderStatusRole: @@ -276,7 +278,7 @@ namespace atomic_dex void orders_proxy_model::export_csv_visible_history(const QString& path) { - const fs::path csv_path = path.toStdString(); + const std::filesystem::path csv_path = path.toStdString(); SPDLOG_INFO("exporting csv with path: {}", csv_path.string()); std::ofstream ofs(csv_path.string(), std::ios::out | std::ios::trunc); int nb_items = this->rowCount(); diff --git a/src/core/atomicdex/models/qt.portfolio.model.cpp b/src/core/atomicdex/models/qt.portfolio.model.cpp index 6cb81c3cc0..24e70efad8 100644 --- a/src/core/atomicdex/models/qt.portfolio.model.cpp +++ b/src/core/atomicdex/models/qt.portfolio.model.cpp @@ -79,6 +79,7 @@ namespace atomic_dex .main_currency_price_for_one_unit = QString::fromStdString(price_service.get_rate_conversion(m_config->current_currency, coin.ticker, true)), .main_fiat_price_for_one_unit = QString::fromStdString(price_service.get_rate_conversion(m_config->current_fiat, coin.ticker)), .trend_7d = nlohmann_json_array_to_qt_json_array(provider.get_ticker_historical(coin.ticker)), + .activation_status = nlohmann_json_object_to_qt_json_object(coin.activation_status), .price_provider = QString::fromStdString(provider.get_price_provider(coin.ticker)), .price_last_timestamp = static_cast(provider.get_last_price_timestamp(coin.ticker)), .is_excluded = false, @@ -102,15 +103,13 @@ namespace atomic_dex bool portfolio_model::update_currency_values() { - SPDLOG_INFO("update_currency_values"); 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(); const auto coins = this->m_system_manager.get_system().get_global_cfg()->get_enabled_coins(); const std::string& currency = m_config->current_currency; const std::string& fiat = m_config->current_fiat; - tf::Executor executor; - tf::Taskflow taskflow; + for (auto&& [_, coin]: coins) { if (m_ticker_registry.find(coin.ticker) == m_ticker_registry.end()) @@ -118,43 +117,42 @@ namespace atomic_dex SPDLOG_WARN("ticker: {} not inserted yet in the model, skipping", coin.ticker); return false; } - auto update_functor = [coin = std::move(coin), &provider, &mm2_system, &price_service, currency, fiat, this]() + 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()) { - 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()) + 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)); + update_value(MainCurrencyBalanceRole, main_currency_balance_value, idx, *this); + const QString currency_price_for_one_unit = QString::fromStdString(price_service.get_rate_conversion(currency, ticker, true)); + update_value(MainCurrencyPriceForOneUnit, currency_price_for_one_unit, idx, *this); + const QString currency_fiat_for_one_unit = QString::fromStdString(price_service.get_rate_conversion(fiat, ticker, false)); + update_value(MainFiatPriceForOneUnit, currency_fiat_for_one_unit, idx, *this); + const QString price_provider = QString::fromStdString(provider.get_price_provider(ticker)); + update_value(PriceProvider, price_provider, idx, *this); + int last_price_timestamp = static_cast(provider.get_last_price_timestamp(ticker)); + update_value(LastPriceTimestamp, last_price_timestamp, idx, *this); + QString change24_h = retrieve_change_24h(provider, coin, *m_config, m_system_manager); + update_value(Change24H, change24_h, idx, *this); + const QString balance = QString::fromStdString(mm2_system.my_balance(coin.ticker, ec)); + auto&& [prev_balance, new_balance, is_change_b] = update_value(BalanceRole, balance, idx, *this); + const QString display = QString::fromStdString(coin.ticker) + " (" + balance + ")"; + update_value(Display, display, idx, *this); + // Not a good way to trigger notification, use websocket instead in the future. New was of enabling coins is not compatible. + if (is_change_b) { - 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)); - update_value(MainCurrencyBalanceRole, main_currency_balance_value, idx, *this); - const QString currency_price_for_one_unit = QString::fromStdString(price_service.get_rate_conversion(currency, ticker, true)); - update_value(MainCurrencyPriceForOneUnit, currency_price_for_one_unit, idx, *this); - const QString currency_fiat_for_one_unit = QString::fromStdString(price_service.get_rate_conversion(fiat, ticker, false)); - update_value(MainFiatPriceForOneUnit, currency_fiat_for_one_unit, idx, *this); - const QString price_provider = QString::fromStdString(provider.get_price_provider(ticker)); - update_value(PriceProvider, price_provider, idx, *this); - int last_price_timestamp = static_cast(provider.get_last_price_timestamp(ticker)); - update_value(LastPriceTimestamp, last_price_timestamp, idx, *this); - QString change24_h = retrieve_change_24h(provider, coin, *m_config, m_system_manager); - update_value(Change24H, change24_h, idx, *this); - const QString balance = QString::fromStdString(mm2_system.my_balance(coin.ticker, ec)); - auto&& [prev_balance, new_balance, is_change_b] = update_value(BalanceRole, balance, idx, *this); - const QString display = QString::fromStdString(coin.ticker) + " (" + balance + ")"; - update_value(Display, display, idx, *this); - // Not a good way to trigger notification, use websocket instead in the future. New was of enabling coins is not compatible. - if (is_change_b) - { - balance_update_handler(prev_balance.toString(), new_balance.toString(), QString::fromStdString(ticker)); - } - QJsonArray trend = nlohmann_json_array_to_qt_json_array(provider.get_ticker_historical(ticker)); - update_value(Trend7D, trend, idx, *this); - // SPDLOG_DEBUG("updated currency values of: {}", ticker); + balance_update_handler(prev_balance.toString(), new_balance.toString(), QString::fromStdString(ticker)); } - }; - taskflow.emplace(update_functor); + QJsonArray trend = nlohmann_json_array_to_qt_json_array(provider.get_ticker_historical(ticker)); + update_value(Trend7D, trend, idx, *this); + + auto coin_info = mm2_system.get_coin_info(ticker); + QJsonObject status = nlohmann_json_object_to_qt_json_object(coin_info.activation_status); + update_value(ActivationStatus, status, idx, *this); + // SPDLOG_DEBUG("updated currency values of: {}", ticker); + } } - executor.run(taskflow).wait(); return true; } @@ -207,6 +205,9 @@ namespace atomic_dex } QJsonArray trend = nlohmann_json_array_to_qt_json_array(provider.get_ticker_historical(ticker)); update_value(Trend7D, trend, idx, *this); + auto coin_info = mm2_system.get_coin_info(ticker); + QJsonObject status = nlohmann_json_object_to_qt_json_object(coin_info.activation_status); + update_value(ActivationStatus, status, idx, *this); if (ticker == mm2_system.get_current_ticker() && (is_change_b || is_change_mc || is_change_mcpfo)) { m_system_manager.get_system().refresh_ticker_infos(); @@ -243,6 +244,8 @@ namespace atomic_dex return item.main_fiat_price_for_one_unit; case NameRole: return item.name; + case ActivationStatus: + return item.activation_status; case Trend7D: return item.trend_7d; case Excluded: @@ -313,6 +316,9 @@ namespace atomic_dex case Trend7D: item.trend_7d = value.toJsonArray(); break; + case ActivationStatus: + item.activation_status = value.toJsonObject(); + break; case Excluded: item.is_excluded = value.toBool(); break; @@ -427,6 +433,7 @@ namespace atomic_dex {MainCurrencyPriceForOneUnit, "main_currency_price_for_one_unit"}, {MainFiatPriceForOneUnit, "main_fiat_price_for_one_unit"}, {Trend7D, "trend_7d"}, + {ActivationStatus, "activation_status"}, {Excluded, "excluded"}, {Display, "display"}, {NameAndTicker, "name_and_ticker"}, diff --git a/src/core/atomicdex/models/qt.portfolio.model.hpp b/src/core/atomicdex/models/qt.portfolio.model.hpp index ebec95b815..9ed6e57ff1 100644 --- a/src/core/atomicdex/models/qt.portfolio.model.hpp +++ b/src/core/atomicdex/models/qt.portfolio.model.hpp @@ -55,6 +55,7 @@ namespace atomic_dex MainCurrencyPriceForOneUnit, MainFiatPriceForOneUnit, Trend7D, + ActivationStatus, Excluded, Display, NameAndTicker, diff --git a/src/core/atomicdex/models/qt.portfolio.proxy.filter.model.cpp b/src/core/atomicdex/models/qt.portfolio.proxy.filter.model.cpp index 2e8a2c7bff..ad39cc4b49 100644 --- a/src/core/atomicdex/models/qt.portfolio.proxy.filter.model.cpp +++ b/src/core/atomicdex/models/qt.portfolio.proxy.filter.model.cpp @@ -56,6 +56,7 @@ namespace atomic_dex return safe_float(left_data.toString().toStdString()) < safe_float(right_data.toString().toStdString()); case portfolio_model::MainFiatPriceForOneUnit: case portfolio_model::Trend7D: + case portfolio_model::ActivationStatus: case portfolio_model::Excluded: case portfolio_model::Display: case portfolio_model::NameAndTicker: @@ -78,10 +79,10 @@ namespace atomic_dex bool portfolio_proxy_model::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { - QModelIndex idx = this->sourceModel()->index(source_row, 0, source_parent); + QModelIndex idx = this->sourceModel()->index(source_row, 0, source_parent); assert(this->sourceModel()->hasIndex(idx.row(), 0)); - QString ticker = this->sourceModel()->data(idx, atomic_dex::portfolio_model::TickerRole).toString(); - QString type = this->sourceModel()->data(idx, atomic_dex::portfolio_model::CoinType).toString(); + QString ticker = this->sourceModel()->data(idx, atomic_dex::portfolio_model::TickerRole).toString(); + QString type = this->sourceModel()->data(idx, atomic_dex::portfolio_model::CoinType).toString(); if (this->filterRole() == atomic_dex::portfolio_model::MultiTickerCurrentlyEnabled) { @@ -201,7 +202,11 @@ namespace atomic_dex void portfolio_proxy_model::set_with_fiat_balance(bool value) { - m_with_fiat_balance = value; + if (value != m_with_fiat_balance) + { + m_with_fiat_balance = value; + this->invalidateFilter(); + } } void diff --git a/src/core/atomicdex/models/qt.wallet.transactions.model.cpp b/src/core/atomicdex/models/transactions_model.cpp similarity index 88% rename from src/core/atomicdex/models/qt.wallet.transactions.model.cpp rename to src/core/atomicdex/models/transactions_model.cpp index 8b464b7229..26245134a0 100644 --- a/src/core/atomicdex/models/qt.wallet.transactions.model.cpp +++ b/src/core/atomicdex/models/transactions_model.cpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -14,8 +14,7 @@ * * ******************************************************************************/ -//! Project Headers -#include "atomicdex/models/qt.wallet.transactions.model.hpp" +#include "transactions_model.hpp" #include "atomicdex/managers/qt.wallet.manager.hpp" #include "atomicdex/pages/qt.settings.page.hpp" #include "atomicdex/services/price/global.provider.hpp" @@ -38,10 +37,10 @@ namespace atomic_dex this->m_model_proxy->sort(0); } - QHash - transactions_model::roleNames() const + QHash transactions_model::roleNames() const { - return { + return + { {AmountRole, "amount"}, {AmISenderRole, "am_i_sender"}, {DateRole, "date"}, @@ -55,18 +54,16 @@ namespace atomic_dex {BlockheightRole, "blockheight"}, {ConfirmationsRole, "confirmations"}, {UnconfirmedRole, "unconfirmed"}, - {TransactionNoteRole, "transaction_note"}}; + {TransactionNoteRole, "transaction_note"} + }; } - int - transactions_model::rowCount([[maybe_unused]] const QModelIndex& parent) const + int transactions_model::rowCount([[maybe_unused]] const QModelIndex& parent) const { - // return m_model_data.size(); return static_cast(m_file_count); } - bool - atomic_dex::transactions_model::setData(const QModelIndex& index, const QVariant& value, int role) + bool atomic_dex::transactions_model::setData(const QModelIndex& index, const QVariant& value, int role) { if (!hasIndex(index.row(), index.column(), index.parent()) || !value.isValid()) { @@ -119,8 +116,7 @@ namespace atomic_dex return true; } - QVariant - transactions_model::data(const QModelIndex& index, int role) const + QVariant transactions_model::data(const QModelIndex& index, int role) const { if (!hasIndex(index.row(), index.column(), index.parent())) { @@ -182,8 +178,7 @@ namespace atomic_dex return {}; } - void - atomic_dex::transactions_model::reset() + void atomic_dex::transactions_model::reset() { this->m_file_count = 0; this->beginResetModel(); @@ -192,13 +187,11 @@ namespace atomic_dex emit lengthChanged(); } - void - transactions_model::init_transactions(const t_transactions& transactions) + void transactions_model::init_transactions(const t_transactions& transactions) { if (m_model_data.size() == 0) { SPDLOG_DEBUG("first time initialization, inserting {} transactions", transactions.size()); - //! First time insertion beginResetModel(); m_model_data = transactions; m_file_count = transactions.size() < g_file_count_limit ? transactions.size() : g_file_count_limit; @@ -228,13 +221,13 @@ namespace atomic_dex emit lengthChanged(); } - void - atomic_dex::transactions_model::update_transaction(const tx_infos& tx) + void atomic_dex::transactions_model::update_transaction(const tx_infos& tx) { if (const auto res = this->match(this->index(0, 0), TxHashRole, QString::fromStdString(tx.tx_hash)); not res.isEmpty()) { - const QModelIndex& idx = res.at(0); - quint64 timestamp = tx.timestamp; + const QModelIndex& idx = res.at(0); + quint64 timestamp = tx.timestamp; + update_value(TimestampRole, timestamp, idx, *this); update_value(DateRole, QString::fromStdString(tx.date), idx, *this); update_value(ConfirmationsRole, static_cast(tx.confirmations), idx, *this); @@ -242,8 +235,7 @@ namespace atomic_dex } } - void - atomic_dex::transactions_model::update_or_insert_transactions(const t_transactions& transactions) + void atomic_dex::transactions_model::update_or_insert_transactions(const t_transactions& transactions) { if (m_model_data.size() > transactions.size()) { @@ -285,20 +277,17 @@ namespace atomic_dex } } - int - transactions_model::get_length() const + int transactions_model::get_length() const { return rowCount(); } - transactions_proxy_model* - transactions_model::get_transactions_proxy() const + transactions_proxy_model* transactions_model::get_transactions_proxy() const { return m_model_proxy; } - void - atomic_dex::transactions_model::fetchMore(const QModelIndex& parent) + void atomic_dex::transactions_model::fetchMore(const QModelIndex& parent) { if (parent.isValid()) { @@ -317,10 +306,8 @@ namespace atomic_dex emit lengthChanged(); } - bool - atomic_dex::transactions_model::canFetchMore([[maybe_unused]] const QModelIndex& parent) const + bool atomic_dex::transactions_model::canFetchMore([[maybe_unused]] const QModelIndex& parent) const { return (m_file_count < m_model_data.size()); } - } // namespace atomic_dex diff --git a/src/core/atomicdex/models/qt.wallet.transactions.model.hpp b/src/core/atomicdex/models/transactions_model.hpp similarity index 90% rename from src/core/atomicdex/models/qt.wallet.transactions.model.hpp rename to src/core/atomicdex/models/transactions_model.hpp index ef9c453851..b76b85a8fd 100644 --- a/src/core/atomicdex/models/qt.wallet.transactions.model.hpp +++ b/src/core/atomicdex/models/transactions_model.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -16,12 +16,10 @@ #pragma once -//! QT Headers #include #include -//! Project Headers -#include "atomicdex/models/qt.wallet.transactions.proxy.filter.model.hpp" +#include "transactions_proxy_model.hpp" #include "atomicdex/services/mm2/mm2.service.hpp" namespace atomic_dex @@ -29,6 +27,7 @@ namespace atomic_dex class transactions_model final : public QAbstractListModel { Q_OBJECT + Q_PROPERTY(int length READ get_length NOTIFY lengthChanged); Q_PROPERTY(transactions_proxy_model* proxy_mdl READ get_transactions_proxy NOTIFY transactionsProxyMdlChanged) @@ -37,7 +36,7 @@ namespace atomic_dex t_transactions m_model_data; std::size_t m_file_count{0}; - public: + public: enum TransactionsRoles { AmountRole = Qt::UserRole + 1, @@ -56,15 +55,15 @@ namespace atomic_dex TransactionNoteRole }; - transactions_model(ag::ecs::system_manager& system_manager, QObject* parent = nullptr) ; - ~transactions_model() final = default; + transactions_model(ag::ecs::system_manager& system_manager, QObject* parent = nullptr); + ~transactions_model() final = default; void reset(); void init_transactions(const t_transactions& transactions); void update_or_insert_transactions(const t_transactions& transactions); void update_transaction(const tx_infos& tx); - //! Override + // Override [[nodiscard]] QHash roleNames() const final; [[nodiscard]] QVariant data(const QModelIndex& index, int role) const final; [[nodiscard]] int rowCount(const QModelIndex& parent = QModelIndex()) const final; @@ -72,11 +71,11 @@ namespace atomic_dex void fetchMore(const QModelIndex& parent) final; bool canFetchMore(const QModelIndex& parent) const final; - //! Props - [[nodiscard]] int get_length() const ; - [[nodiscard]] transactions_proxy_model* get_transactions_proxy() const ; + // Getters + [[nodiscard]] int get_length() const; + [[nodiscard]] transactions_proxy_model* get_transactions_proxy() const; - signals: + signals: void lengthChanged(); void transactionsProxyMdlChanged(); }; diff --git a/src/core/atomicdex/models/qt.wallet.transactions.proxy.filter.model.cpp b/src/core/atomicdex/models/transactions_proxy_model.cpp similarity index 88% rename from src/core/atomicdex/models/qt.wallet.transactions.proxy.filter.model.cpp rename to src/core/atomicdex/models/transactions_proxy_model.cpp index d58b6da5e0..fcbc68ecbc 100644 --- a/src/core/atomicdex/models/qt.wallet.transactions.proxy.filter.model.cpp +++ b/src/core/atomicdex/models/transactions_proxy_model.cpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -14,9 +14,8 @@ * * ******************************************************************************/ -//! Project Headers -#include "atomicdex/models/qt.wallet.transactions.proxy.filter.model.hpp" -#include "atomicdex/models/qt.wallet.transactions.model.hpp" +#include "transactions_proxy_model.hpp" +#include "transactions_model.hpp" namespace atomic_dex { @@ -24,8 +23,7 @@ namespace atomic_dex { } - bool - transactions_proxy_model::lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const + bool transactions_proxy_model::lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const { int role = this->sortRole(); QVariant left_data = sourceModel()->data(source_left, role); diff --git a/src/core/atomicdex/models/qt.wallet.transactions.proxy.filter.model.hpp b/src/core/atomicdex/models/transactions_proxy_model.hpp similarity index 85% rename from src/core/atomicdex/models/qt.wallet.transactions.proxy.filter.model.hpp rename to src/core/atomicdex/models/transactions_proxy_model.hpp index a27cf8705f..ff6cdf9a54 100644 --- a/src/core/atomicdex/models/qt.wallet.transactions.proxy.filter.model.hpp +++ b/src/core/atomicdex/models/transactions_proxy_model.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -22,17 +22,14 @@ namespace atomic_dex { class transactions_proxy_model final : public QSortFilterProxyModel { - Q_OBJECT + Q_OBJECT - public: - //! Constructor + public: transactions_proxy_model(QObject* parent); + ~transactions_proxy_model() final = default; - //! Destructor - ~transactions_proxy_model() final = default; - - protected: - //! Override member functions + protected: + // Override [[nodiscard]] bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const final; }; } diff --git a/src/core/atomicdex/pages/qt.settings.page.cpp b/src/core/atomicdex/pages/qt.settings.page.cpp index bcbb52a64f..1183ad18cb 100644 --- a/src/core/atomicdex/pages/qt.settings.page.cpp +++ b/src/core/atomicdex/pages/qt.settings.page.cpp @@ -25,6 +25,8 @@ #include // Project Headers +#include "atomicdex/api/mm2/get_public_key_rpc.hpp" +#include "atomicdex/config/enable.cfg.hpp" #include "atomicdex/events/events.hpp" #include "atomicdex/managers/qt.wallet.manager.hpp" #include "atomicdex/models/qt.global.coins.cfg.model.hpp" @@ -35,7 +37,6 @@ #include "atomicdex/services/price/global.provider.hpp" #include "atomicdex/utilities/global.utilities.hpp" #include "atomicdex/utilities/qt.utilities.hpp" -#include "atomicdex/api/mm2/rpc.get.public.key.hpp" namespace { @@ -43,10 +44,10 @@ namespace { if (not icon_filepath.isEmpty()) { - const fs::path& suffix = fs::path(icon_filepath.toStdString()).extension(); - fs::copy_file( - icon_filepath.toStdString(), fs::path(icons_path_directory.toStdString()) / (boost::algorithm::to_lower_copy(ticker) + suffix.string()), - get_override_options()); + const std::filesystem::path& suffix = std::filesystem::path(icon_filepath.toStdString()).extension(); + std::filesystem::copy_file( + icon_filepath.toStdString(), std::filesystem::path(icons_path_directory.toStdString()) / (boost::algorithm::to_lower_copy(ticker) + suffix.string()), + std::filesystem::copy_options::overwrite_existing); } } } // anonymous namespace @@ -96,30 +97,43 @@ namespace atomic_dex { return QLocale::Language::Turkish; } - if (current_lang == "en") + else if (current_lang == "en") { return QLocale::Language::English; } - if (current_lang == "fr") + else if (current_lang == "es") + { + return QLocale::Language::Spanish; + } + else if (current_lang == "de") + { + return QLocale::Language::German; + } + else if (current_lang == "fr") { return QLocale::Language::French; } - if (current_lang == "ru") + else if (current_lang == "ru") { return QLocale::Language::Russian; } return QLocale::Language::AnyLanguage; }; + auto path = QString{":/assets/languages/atomic_defi_" + new_lang}; + SPDLOG_INFO("Locale before parsing AtomicDEX settings: {}", QLocale().name().toStdString()); QLocale::setDefault(get_locale(new_lang.toStdString())); SPDLOG_INFO("Locale after parsing AtomicDEX settings: {}", QLocale().name().toStdString()); - [[maybe_unused]] auto res = this->m_translator.load("atomic_defi_" + new_lang, QLatin1String(":/assets/languages")); - assert(res); + if (!this->m_translator.load(path)) + { + SPDLOG_ERROR("Failed to load {} translation in {}.qm", new_lang.toStdString(), path.toStdString()); + return; + } this->m_app->installTranslator(&m_translator); this->m_qml_engine->retranslate(); + SPDLOG_INFO("Successfully loaded {} translation in {}.qm", new_lang.toStdString(), path.toStdString()); emit onLangChanged(); - SPDLOG_INFO("Post lang changed"); } bool atomic_dex::settings_page::is_notification_enabled() const @@ -385,7 +399,7 @@ namespace atomic_dex out["adex_cfg"][ticker]["gui_coin"] = ticker; out["adex_cfg"][ticker]["name"] = body_json.at("qrc20").at("name").get(); out["adex_cfg"][ticker]["coingecko_id"] = coingecko_id.toStdString(); - out["adex_cfg"][ticker]["explorer_url"] = nlohmann::json::array({"https://explorer.qtum.org/"}); + out["adex_cfg"][ticker]["explorer_url"] = "https://explorer.qtum.org/"; out["adex_cfg"][ticker]["type"] = "QRC-20"; out["adex_cfg"][ticker]["active"] = true; out["adex_cfg"][ticker]["currently_enabled"] = false; @@ -414,7 +428,7 @@ namespace atomic_dex this->set_custom_token_data(nlohmann_json_object_to_qt_json_object(out)); this->set_fetching_custom_token_data_busy(false); }; - ::mm2::api::async_process_rpc_get(::mm2::api::g_qtum_proxy_http_client, "qrc_infos", url).then(answer_functor).then(&handle_exception_pplx_task); + mm2::async_process_rpc_get(mm2::g_qtum_proxy_http_client, "qrc_infos", url).then(answer_functor).then(&handle_exception_pplx_task); } void settings_page::process_token_add(const QString& contract_address, const QString& coingecko_id, const QString& icon_filepath, CoinType coin_type) @@ -428,17 +442,17 @@ namespace atomic_dex { case CoinTypeGadget::QRC20: return std::make_tuple( - &::mm2::api::g_qtum_proxy_http_client, "/contract/"s + contract_address.toStdString(), "QRC20"s, "QTUM"s, "QRC-20"s, "QTUM"s, "QRC20"s); + &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::api::g_etherscan_proxy_http_client, "/api/v1/token_infos/erc20/"s + contract_address.toStdString(), "ERC20"s, "ETH"s, "ERC-20"s, + &mm2::g_etherscan_proxy_http_client, "/api/v1/token_infos/erc20/"s + contract_address.toStdString(), "ERC20"s, "ETH"s, "ERC-20"s, "ETH"s, "ERC20"s); case CoinTypeGadget::BEP20: return std::make_tuple( - &::mm2::api::g_etherscan_proxy_http_client, "/api/v1/token_infos/bep20/"s + contract_address.toStdString(), "BEP20"s, "BNB"s, "BEP-20"s, + &mm2::g_etherscan_proxy_http_client, "/api/v1/token_infos/bep20/"s + contract_address.toStdString(), "BEP20"s, "BNB"s, "BEP-20"s, "BNB"s, "ERC20"s); default: - return std::make_tuple(&::mm2::api::g_etherscan_proxy_http_client, ""s, ""s, ""s, ""s, ""s, ""s); + return std::make_tuple(&mm2::g_etherscan_proxy_http_client, ""s, ""s, ""s, ""s, ""s, ""s); } }; auto&& [endpoint, url, type, platform, adex_platform, parent_chain, parent_type] = retrieve_functor_url(); @@ -493,7 +507,7 @@ namespace atomic_dex 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]["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; @@ -511,7 +525,7 @@ namespace atomic_dex this->set_custom_token_data(nlohmann_json_object_to_qt_json_object(out)); this->set_fetching_custom_token_data_busy(false); }; - ::mm2::api::async_process_rpc_get(*endpoint, "token_infos", url).then(answer_functor).then(&handle_exception_pplx_task); + mm2::async_process_rpc_get(*endpoint, "token_infos", url).then(answer_functor).then(&handle_exception_pplx_task); } void settings_page::submit() @@ -533,74 +547,6 @@ namespace atomic_dex m_qml_engine = engine; } - void settings_page::reset_coin_cfg() - { - using namespace std::string_literals; - const std::string wallet_name = qt_wallet_manager::get_default_wallet_name().toStdString(); - const std::string wallet_cfg_file = std::string(atomic_dex::get_raw_version()) + "-coins"s + "."s + wallet_name + ".json"s; - std::string wallet_custom_cfg_filename = "custom-tokens."s + wallet_name + ".json"s; - const fs::path wallet_custom_cfg_path{utils::get_atomic_dex_config_folder() / wallet_custom_cfg_filename}; - const fs::path wallet_cfg_path{utils::get_atomic_dex_config_folder() / wallet_cfg_file}; - const fs::path mm2_coins_file_path{atomic_dex::utils::get_current_configs_path() / "coins.json"}; - const fs::path ini_file_path = atomic_dex::utils::get_current_configs_path() / "cfg.ini"; - const fs::path cfg_json_file_path = atomic_dex::utils::get_current_configs_path() / "cfg.json"; - const fs::path logo_path = atomic_dex::utils::get_logo_path(); - const fs::path theme_path = atomic_dex::utils::get_themes_path(); - - - if (fs::exists(wallet_custom_cfg_path)) - { - nlohmann::json custom_config_json_data; - QFile fs; - fs.setFileName(std_path_to_qstring(wallet_custom_cfg_path)); - fs.open(QIODevice::ReadOnly | QIODevice::Text); - - //! Read Contents - custom_config_json_data = nlohmann::json::parse(QString(fs.readAll()).toStdString()); - fs.close(); - - //! Modify - for (auto&& [key, value]: custom_config_json_data.items()) { value["active"] = false; } - - //! Write - fs.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); - fs.write(QString::fromStdString(custom_config_json_data.dump()).toUtf8()); - fs.close(); - } - - const auto functor_remove = [](auto&& path_to_remove) - { - if (fs::exists(path_to_remove)) - { - fs_error_code ec; - if (fs::is_directory(path_to_remove)) - { - fs::remove_all(path_to_remove, ec); - } - else - { - fs::remove(path_to_remove, ec); - } - if (ec) - { - LOG_PATH("error when removing {}", path_to_remove); - SPDLOG_ERROR("error: {}", ec.message()); - } - else - { - LOG_PATH("Successfully removed {}", path_to_remove); - } - } - }; - - functor_remove(std::move(wallet_cfg_path)); - functor_remove(std::move(mm2_coins_file_path)); - functor_remove(std::move(ini_file_path)); - functor_remove(std::move(cfg_json_file_path)); - functor_remove(std::move(logo_path)); - functor_remove(std::move(theme_path)); - } - QStringList settings_page::retrieve_seed(const QString& wallet_name, const QString& password) { QStringList out; @@ -615,7 +561,7 @@ namespace atomic_dex } } using namespace std::string_literals; - const fs::path seed_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".seed"s); + const std::filesystem::path seed_path = utils::get_atomic_dex_config_folder() / (wallet_name.toStdString() + ".seed"s); auto seed = atomic_dex::decrypt(seed_path, key.data(), ec); if (ec == dextop_error::corrupted_file_or_wrong_password) { @@ -632,8 +578,8 @@ namespace atomic_dex const auto coins = cfg_mdl->get_enabled_coins(); for (auto&& [coin, coin_cfg]: coins) { - ::mm2::api::show_priv_key_request req{.coin = coin}; - nlohmann::json req_json = ::mm2::api::template_request("show_priv_key"); + mm2::show_priv_key_request req{.coin = coin}; + nlohmann::json req_json = mm2::template_request("show_priv_key"); to_json(req_json, req); batch.push_back(req_json); } @@ -648,7 +594,7 @@ namespace atomic_dex SPDLOG_WARN("Priv keys fetched, those are sensitive data."); for (auto&& answer: answers) { - auto show_priv_key_answer = ::mm2::api::rpc_process_answer_batch<::mm2::api::show_priv_key_answer>(answer, "show_priv_key"); + auto show_priv_key_answer = mm2::rpc_process_answer_batch(answer, "show_priv_key"); auto* portfolio_mdl = this->m_system_manager.get_system().get_portfolio(); const auto idx = portfolio_mdl->match( portfolio_mdl->index(0, 0), portfolio_model::TickerRole, QString::fromStdString(show_priv_key_answer.coin), 1, @@ -656,6 +602,9 @@ namespace atomic_dex if (not idx.empty()) { update_value(portfolio_model::PrivKey, QString::fromStdString(show_priv_key_answer.priv_key), idx.at(0), *portfolio_mdl); + std::error_code ec; + QString public_address = QString::fromStdString(m_system_manager.get_system().address(show_priv_key_answer.coin, ec)); + update_value(portfolio_model::Address, public_address, idx.at(0), *portfolio_mdl); } } } @@ -663,7 +612,7 @@ namespace atomic_dex }; mm2_system.get_mm2_client().async_rpc_batch_standalone(batch).then(answer_functor); } - return {QString::fromStdString(seed), QString::fromStdString(::mm2::api::get_rpc_password())}; + return {QString::fromStdString(seed), QString::fromStdString(mm2::get_rpc_password())}; } QString settings_page::get_version() @@ -678,7 +627,7 @@ namespace atomic_dex QString settings_page::get_mm2_version() { - return QString::fromStdString(::mm2::api::rpc_version()); + return QString::fromStdString(mm2::rpc_version()); } QString settings_page::get_export_folder() @@ -689,9 +638,12 @@ namespace atomic_dex void settings_page::fetchPublicKey() { auto& mm2_system = m_system_manager.get_system(); - auto get_pub_key_rpc_callback = [this](auto pub_key_answ) + auto get_pub_key_rpc_callback = [this](auto pub_key_rpc) { - public_key = QString::fromStdString(pub_key_answ.public_key); + if (pub_key_rpc.error) + public_key = tr("An error has occurred."); + else + public_key = QString::fromStdString(pub_key_rpc.result->public_key); fetching_public_key = false; emit publicKeyChanged(); emit fetchingPublicKeyChanged(); @@ -700,6 +652,6 @@ namespace atomic_dex fetching_public_key = true; emit fetchingPublicKeyChanged(); - mm2_system.get_mm2_client().process_rpc_async(get_pub_key_rpc_callback); + mm2_system.get_mm2_client().process_rpc_async(get_pub_key_rpc_callback); } } // namespace atomic_dex diff --git a/src/core/atomicdex/pages/qt.settings.page.hpp b/src/core/atomicdex/pages/qt.settings.page.hpp index 444d5e9247..d1dd6712cb 100644 --- a/src/core/atomicdex/pages/qt.settings.page.hpp +++ b/src/core/atomicdex/pages/qt.settings.page.hpp @@ -108,7 +108,6 @@ namespace atomic_dex Q_INVOKABLE void process_token_add(const QString& contract_address, const QString& coingecko_id, const QString& icon_filepath, CoinType coin_type); Q_INVOKABLE void process_qrc_20_token_add(const QString& contract_address, const QString& coingecko_id, const QString& icon_filepath); Q_INVOKABLE void submit(); - Q_INVOKABLE void reset_coin_cfg(); Q_INVOKABLE QStringList retrieve_seed(const QString& wallet_name, const QString& password); Q_INVOKABLE static QString get_mm2_version(); Q_INVOKABLE static QString get_log_folder(); diff --git a/src/core/atomicdex/pages/qt.trading.page.cpp b/src/core/atomicdex/pages/qt.trading.page.cpp index 380f0d6b11..1a4ecf6415 100644 --- a/src/core/atomicdex/pages/qt.trading.page.cpp +++ b/src/core/atomicdex/pages/qt.trading.page.cpp @@ -28,6 +28,7 @@ #include "atomicdex/services/mm2/mm2.service.hpp" #include "atomicdex/services/price/global.provider.hpp" #include "atomicdex/utilities/qt.utilities.hpp" +#include "atomicdex/utilities/qt.download.manager.hpp" //! Constructor / Destructor namespace atomic_dex @@ -75,12 +76,16 @@ namespace atomic_dex void trading_page::set_current_orderbook(const QString& base, const QString& rel) { + if (base.toStdString() == "" || rel.toStdString() == "") + { + return; + } 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()); return; } - SPDLOG_INFO("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(); @@ -89,8 +94,9 @@ namespace atomic_dex market_selector_mdl->set_base_selected_coin(m_market_mode == MarketMode::Sell ? base : rel); market_selector_mdl->set_rel_selected_coin(m_market_mode == MarketMode::Sell ? rel : base); - if (to_change) + if (to_change && m_current_trading_mode != TradingModeGadget::Simple) { + SPDLOG_DEBUG("set_current_orderbook"); this->get_orderbook_wrapper()->clear_orderbook(); this->clear_forms("set_current_orderbook"); } @@ -109,7 +115,7 @@ namespace atomic_dex void trading_page::on_gui_enter_dex() { - SPDLOG_INFO("Enter DEX"); + SPDLOG_DEBUG("Enter DEX"); dispatcher_.trigger(); if (this->m_system_manager.has_system() && m_system_manager.get_system().is_orderbook_thread_active()) { @@ -143,7 +149,7 @@ namespace atomic_dex t_float_50 rel_min_volume_f = safe_float(get_min_trade_vol().toStdString()); if (is_selected_order) { - SPDLOG_INFO( + SPDLOG_DEBUG( "max_volume: {} volume: {} order_volume: {}, order_volume_8_digit: {}, order_volume_8_digit_extracted: {}", m_max_volume.toStdString(), m_volume.toStdString(), m_preferred_order->at("base_max_volume").get(), utils::adjust_precision(m_preferred_order->at("base_max_volume").get()), @@ -175,7 +181,7 @@ namespace atomic_dex if (req.is_exact_selected_order_volume) { //! Selected order and we keep the exact volume (Basically swallow the order) - SPDLOG_INFO("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(); } @@ -183,25 +189,26 @@ 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_INFO("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_INFO("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; } } + nlohmann::json batch; - nlohmann::json buy_request = ::mm2::api::template_request("buy"); - ::mm2::api::to_json(buy_request, req); + nlohmann::json buy_request = mm2::template_request("buy"); + mm2::to_json(buy_request, req); batch.push_back(buy_request); buy_request["userpass"] = "*******"; //! Answer - SPDLOG_INFO("buy_request is : {}", buy_request.dump(4)); + SPDLOG_DEBUG("buy_request is : {}", buy_request.dump(4)); auto answer_functor = [this](const web::http::http_response& resp) { std::string body = TO_STD_STR(resp.extract_string(true).get()); @@ -273,8 +280,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_INFO("base_min_trade: {}, cur_min_trade: {}", base_min_trade.str(), cur_min_trade.str()); - SPDLOG_INFO( + 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{ @@ -295,7 +302,7 @@ namespace atomic_dex if (m_current_trading_mode == TradingModeGadget::Simple) { - SPDLOG_INFO("Simple trading mode, using FillOrKill order"); + SPDLOG_DEBUG("Simple trading mode, using FillOrKill order"); req.order_type = nlohmann::json::object(); req.order_type.value()["type"] = "FillOrKill"; req.min_volume = std::optional{std::nullopt}; @@ -307,9 +314,10 @@ namespace atomic_dex } auto max_taker_vol_json_obj = get_orderbook_wrapper()->get_base_max_taker_vol().toJsonObject(); + if (is_selected_order) { - SPDLOG_INFO( + SPDLOG_DEBUG( "The order is a selected order, treating it, input_vol: {} orderbook_max_vol {}", m_volume.toStdString(), orderbook_available_quantity.toStdString()); @@ -317,14 +325,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_INFO("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_INFO("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(); } @@ -332,13 +340,13 @@ namespace atomic_dex ///< let's forbid it in simple ///< view { - SPDLOG_INFO("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_INFO("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; } } @@ -352,12 +360,13 @@ namespace atomic_dex } nlohmann::json batch; - nlohmann::json sell_request = ::mm2::api::template_request("sell"); - ::mm2::api::to_json(sell_request, req); + nlohmann::json sell_request = mm2::template_request("sell"); + mm2::to_json(sell_request, req); batch.push_back(sell_request); sell_request["userpass"] = "******"; - SPDLOG_INFO("sell request: {}", sell_request.dump(4)); + SPDLOG_DEBUG("sell request: {}", sell_request.dump(4)); + //! Answer auto answer_functor = [this](web::http::http_response resp) { @@ -476,6 +485,7 @@ namespace atomic_dex { std::error_code ec; t_orderbook_answer result = mm2_system.get_orderbook(ec); + if (!ec) { auto* wrapper = get_orderbook_wrapper(); @@ -483,7 +493,8 @@ namespace atomic_dex if (m_models_actions[orderbook_need_a_reset] && this->m_current_trading_mode == TradingModeGadget::Pro) { - this->set_preferred_settings(); + // This goes to a function which looks like it is for bot trading. We dont need to run it at this stage. + // this->set_preferred_settings(); } else { @@ -589,11 +600,12 @@ namespace atomic_dex if (this->m_market_mode != market_mode) { this->m_market_mode = market_mode; - SPDLOG_INFO("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()); emit marketModeChanged(); + if (m_market_mode == MarketMode::Buy) { this->get_orderbook_wrapper()->get_best_orders()->get_orderbook_proxy()->sort(0, Qt::AscendingOrder); @@ -618,6 +630,7 @@ namespace atomic_dex { price = "0"; } + if (m_price != price) { m_price = std::move(price); @@ -656,12 +669,12 @@ namespace atomic_dex SPDLOG_WARN("MM2 service not available, required to clear forms - skipping"); return; } - SPDLOG_INFO("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_INFO("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); @@ -671,10 +684,11 @@ namespace atomic_dex { this->set_price("0"); this->set_max_volume("0"); - m_minimal_trading_amount = "0"; + m_minimal_trading_amount = "0.0001"; emit minTradeVolChanged(); this->set_volume("0"); } + this->set_total_amount("0"); this->set_trading_error(TradingError::None); this->m_preferred_order = std::nullopt; @@ -683,11 +697,14 @@ namespace atomic_dex this->m_post_clear_forms = true; this->set_selected_order_status(SelectedOrderStatus::None); this->reset_fees(); + this->determine_cex_rates(); emit cexPriceChanged(); emit invalidCexPriceChanged(); emit cexPriceReversedChanged(); emit feesChanged(); emit prefferedOrderChanged(); + emit priceChanged(); + emit priceReversedChanged(); } QString @@ -706,17 +723,13 @@ namespace atomic_dex volume = "0"; } m_volume = std::move(volume); - SPDLOG_INFO("volume is : [{}]", m_volume.toStdString()); + SPDLOG_DEBUG("volume is : [{}]", m_volume.toStdString()); this->determine_total_amount(); emit volumeChanged(); this->cap_volume(); this->get_orderbook_wrapper()->refresh_best_orders(); - if (!m_price.isEmpty() || m_price != "0") - { - this->determine_fees(); - } } } @@ -763,7 +776,7 @@ 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_INFO( + 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()) @@ -776,7 +789,7 @@ namespace atomic_dex { if (!m_preferred_order->at("capped").get()) { - SPDLOG_INFO("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)); } @@ -869,7 +882,7 @@ namespace atomic_dex auto max_volume = this->get_max_volume(); if (!max_volume.isEmpty() && max_volume != "0") { - SPDLOG_INFO("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()); } } @@ -922,6 +935,12 @@ namespace atomic_dex case TradingErrorGadget::RightParentChainNotEnabled: SPDLOG_WARN("last_trading_error is RightParentChainNotEnabled"); break; + case TradingErrorGadget::LeftZhtlcChainNotEnabled: + SPDLOG_WARN("last_trading_error is LeftZhtlcChainNotEnabled"); + break; + case TradingErrorGadget::RightZhtlcChainNotEnabled: + SPDLOG_WARN("last_trading_error is RightZhtlcChainNotEnabled"); + break; default: break; } @@ -1011,6 +1030,9 @@ namespace atomic_dex set_current_orderbook(base, rel); } } + this->determine_cex_rates(); + emit priceChanged(); + emit priceReversedChanged(); return true; } @@ -1025,36 +1047,37 @@ namespace atomic_dex return {}; } - void - trading_page::set_preferred_order(const QVariantMap& price_object) + void trading_page::set_preferred_order(const QVariantMap& price_object) { - if (auto preferred_order = nlohmann::json::parse(QString(QJsonDocument(QJsonObject::fromVariantMap(price_object)).toJson()).toStdString()); - preferred_order != m_preferred_order) + auto preferred_order = nlohmann::json::parse(QString(QJsonDocument(QJsonObject::fromVariantMap(price_object)).toJson()).toStdString()); + if (preferred_order == m_preferred_order) + { + return; + } + SPDLOG_DEBUG("preferred_order: {}", preferred_order.dump(-1)); + m_preferred_order = std::move(preferred_order); + emit prefferedOrderChanged(); + if (!m_preferred_order->empty() && m_preferred_order->contains("price")) { - SPDLOG_INFO("preferred_order: {}", preferred_order.dump(-1)); - m_preferred_order = std::move(preferred_order); - emit prefferedOrderChanged(); - if (!m_preferred_order->empty() && m_preferred_order->contains("price")) + m_preferred_order->operator[]("capped") = false; + this->set_price(QString::fromStdString(utils::format_float(safe_float(m_preferred_order->at("price").get())))); + this->determine_max_volume(); + QString min_vol = QString::fromStdString(utils::format_float(safe_float(m_preferred_order->at("base_min_volume").get()))); + this->set_min_trade_vol(min_vol); + + if (this->m_current_trading_mode == TradingModeGadget::Pro) { - m_preferred_order->operator[]("capped") = false; - this->set_price(QString::fromStdString(utils::format_float(safe_float(m_preferred_order->at("price").get())))); - this->determine_max_volume(); - QString min_vol = QString::fromStdString(utils::format_float(safe_float(m_preferred_order->at("base_min_volume").get()))); - this->set_min_trade_vol(min_vol); auto available_quantity = m_preferred_order->at("base_max_volume").get(); - if (this->m_current_trading_mode == TradingModeGadget::Pro) - { - this->set_volume(QString::fromStdString(utils::extract_large_float(available_quantity))); - } - else if (this->m_current_trading_mode == TradingModeGadget::Simple && m_preferred_order->contains("initial_input_volume")) - { - SPDLOG_INFO("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(); - this->determine_fees(); - emit preferredOrderChangeFinished(); + this->set_volume(QString::fromStdString(utils::extract_large_float(available_quantity))); + } + 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."); + this->set_volume(QString::fromStdString(m_preferred_order->at("initial_input_volume").get())); } + this->get_orderbook_wrapper()->refresh_best_orders(); + this->determine_fees(); + emit preferredOrderChangeFinished(); } } @@ -1131,33 +1154,54 @@ namespace atomic_dex SPDLOG_WARN("MM2 Service not available, cannot determine fees - skipping"); return; } - using namespace std::string_literals; const auto* market_pair = get_market_pairs_mdl(); + using namespace std::string_literals; auto& mm2 = this->m_system_manager.get_system(); + // TODO: there is a race condition that sometimes results in base == rel after switching base/rel tickers const auto base = market_pair->get_left_selected_coin().toStdString(); const auto rel = market_pair->get_right_selected_coin().toStdString(); const auto swap_method = m_market_mode == MarketMode::Sell ? "sell"s : "buy"s; + std::string volume = get_volume().toStdString(); + std::string price = get_price().toStdString(); + + if (base == rel) // trade_preimage::BaseEqualRel + { + return; + } + if (volume == "0") // trade_preimage::VolumeTooLow (can also occur if trade vol + fees is > balance) + { + return; + } + if (std::stof(price) < 0.00000001) // trade_preimage::PriceTooLow + { + return; + } t_trade_preimage_request req{ - .base_coin = base, .rel_coin = rel, .swap_method = swap_method, .volume = get_volume().toStdString(), .price = get_price().toStdString()}; + .base_coin = base, + .rel_coin = rel, + .swap_method = swap_method, + .volume = volume, + .price = price + }; nlohmann::json batch; - nlohmann::json preimage_request = ::mm2::api::template_request("trade_preimage"); - ::mm2::api::to_json(preimage_request, req); + nlohmann::json preimage_request = mm2::template_request("trade_preimage"); + mm2::to_json(preimage_request, req); batch.push_back(preimage_request); preimage_request["userpass"] = "******"; - SPDLOG_INFO("request: {}", preimage_request.dump(-1)); + 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("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); nlohmann::json answer = answers[0]; - auto trade_preimage_answer = ::mm2::api::rpc_process_answer_batch(answer, "trade_preimage"); + auto trade_preimage_answer = mm2::rpc_process_answer_batch(answer, "trade_preimage"); if (trade_preimage_answer.error.has_value()) { auto error_answer = trade_preimage_answer.error.value(); @@ -1165,6 +1209,7 @@ namespace atomic_dex fees["error"] = QString::fromStdString(error_answer); this->set_fees(fees); } + if (trade_preimage_answer.result.has_value()) { auto success_answer = trade_preimage_answer.result.value(); @@ -1186,7 +1231,6 @@ namespace atomic_dex fees["fee_to_send_taker_fee"] = QString::fromStdString(utils::adjust_precision(success_answer.fee_to_send_taker_fee.value().amount)); fees["fee_to_send_taker_fee_ticker"] = QString::fromStdString(success_answer.fee_to_send_taker_fee.value().coin); - for (auto&& cur: success_answer.total_fees) { if (!mm2.do_i_have_enough_funds(cur.at("coin").get(), safe_float(cur.at("required_balance").get()))) @@ -1226,6 +1270,7 @@ namespace atomic_dex const bool has_preferred_order = m_preferred_order.has_value(); const bool is_selected_min_max = has_preferred_order && m_preferred_order->at("base_min_volume").get() == m_preferred_order->at("base_max_volume").get(); + if (left_cfg.has_parent_fees_ticker && left_cfg.ticker != "QTUM") { const auto left_fee_cfg = mm2.get_coin_info(left_cfg.fees_ticker); @@ -1250,6 +1295,15 @@ namespace atomic_dex current_trading_error = TradingError::RightParentChainNotEnoughBalance; } } + else if (!mm2.is_zhtlc_coin_ready(left)) + { + current_trading_error = TradingError::LeftZhtlcChainNotEnabled; + } + else if (!mm2.is_zhtlc_coin_ready(right)) + { + current_trading_error = TradingError::RightZhtlcChainNotEnabled; + } + if (current_trading_error == TradingError::None) { if (max_balance_without_dust < safe_float(regular_min_taker_vol)) //get_left_selected_coin(); const auto& rel = market_selector->get_right_selected_coin(); + if (auto cex_price = QString::fromStdString(price_service.get_cex_rates(base.toStdString(), rel.toStdString())); cex_price != m_cex_price) { m_cex_price = std::move(cex_price); @@ -1413,17 +1472,16 @@ namespace atomic_dex //! KMD<->DOGE Buy -> base_min_vol, sell base_min_vol -> //! base_min_vol -> 0.0001 KMD //! rel_min_vol -> 10 DOGE - const auto& min_taker_vol = get_orderbook_wrapper()->get_base_min_taker_vol().toStdString(); - - if (t_float_50 min_vol_f = safe_float(min_taker_vol); safe_float(min_trade_vol.toStdString()) <= min_vol_f) - { - min_trade_vol = QString::fromStdString(min_taker_vol); - } + t_float_50 min_trade_vol_f = safe_float(min_trade_vol.toStdString()); + const auto& current_min_taker_vol = get_orderbook_wrapper()->get_current_min_taker_vol().toStdString(); + t_float_50 current_min_taker_vol_f = safe_float(current_min_taker_vol); + const auto& base_min_taker_vol = get_orderbook_wrapper()->get_base_min_taker_vol().toStdString(); + t_float_50 base_min_taker_vol_f = safe_float(base_min_taker_vol); - if (safe_float(get_orderbook_wrapper()->get_current_min_taker_vol().toStdString()) > safe_float(min_trade_vol.toStdString())) + if (min_trade_vol_f < base_min_taker_vol_f) { - SPDLOG_WARN("Spurious min_diff detected - overriding immediately"); - min_trade_vol = get_orderbook_wrapper()->get_current_min_taker_vol(); + min_trade_vol = QString::fromStdString(base_min_taker_vol); + min_trade_vol_f = base_min_taker_vol_f; } if (min_trade_vol != m_minimal_trading_amount) @@ -1459,7 +1517,7 @@ namespace atomic_dex void trading_page::reset_fees() { - SPDLOG_INFO("reset_fees"); + SPDLOG_DEBUG("reset_fees"); this->set_fees(QVariantMap()); this->determine_error_cases(); } @@ -1490,6 +1548,7 @@ namespace atomic_dex t_float_50 spread = settings.value("Spread", 1.0).toDouble(); t_float_50 min_volume_percent = settings.value("MinVolume", 10.0).toDouble() / 100; ///< min volume is always 10% of the order or more settings.endGroup(); + if (!is_disabled) { SPDLOG_WARN("{}/{} have trading settings - using them", left.toStdString(), right.toStdString()); diff --git a/src/core/atomicdex/pages/qt.trading.page.hpp b/src/core/atomicdex/pages/qt.trading.page.hpp index 2cf51f4a3c..ee1e87b557 100644 --- a/src/core/atomicdex/pages/qt.trading.page.hpp +++ b/src/core/atomicdex/pages/qt.trading.page.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -16,13 +16,11 @@ #pragma once -//! Deps +#include #include -//! QT #include -//! Project Headers #include "atomicdex/constants/qt.actions.hpp" #include "atomicdex/constants/qt.trading.enums.hpp" #include "atomicdex/events/events.hpp" @@ -36,11 +34,9 @@ namespace atomic_dex { class trading_page final : public QObject, public ag::ecs::pre_update_system { - private: - //! Q_Object definition Q_OBJECT - //! Q Properties definitions + // Q Properties definitions Q_PROPERTY(qt_orderbook_wrapper* orderbook READ get_orderbook_wrapper NOTIFY orderbookChanged) Q_PROPERTY(market_pairs* market_pairs_mdl READ get_market_pairs_mdl NOTIFY marketPairsChanged) Q_PROPERTY(qt_orders_widget* orders READ get_orders_widget NOTIFY ordersWidgetChanged) @@ -48,7 +44,7 @@ namespace atomic_dex Q_PROPERTY(bool buy_sell_rpc_busy READ is_buy_sell_rpc_busy WRITE set_buy_sell_rpc_busy NOTIFY buySellRpcStatusChanged) Q_PROPERTY(bool preimage_rpc_busy READ is_preimage_busy WRITE set_preimage_busy NOTIFY preImageRpcStatusChanged) - //! Trading logic + // Trading logic Q properties Q_PROPERTY(MarketMode market_mode READ get_market_mode WRITE set_market_mode NOTIFY marketModeChanged) Q_PROPERTY(TradingError last_trading_error READ get_trading_error WRITE set_trading_error NOTIFY tradingErrorChanged) Q_PROPERTY(TradingMode current_trading_mode READ get_current_trading_mode WRITE set_current_trading_mode NOTIFY tradingModeChanged) @@ -65,7 +61,6 @@ namespace atomic_dex Q_PROPERTY(QString cex_price READ get_cex_price NOTIFY cexPriceChanged) Q_PROPERTY(QString cex_price_reversed READ get_cex_price_reversed NOTIFY cexPriceReversedChanged) Q_PROPERTY(QString cex_price_diff READ get_cex_price_diff NOTIFY cexPriceDiffChanged) - // Q_PROPERTY(QString mm2_min_trade_vol READ get_mm2_min_trade_vol NOTIFY mm2MinTradeVolChanged) Q_PROPERTY(QString min_trade_vol READ get_min_trade_vol WRITE set_min_trade_vol NOTIFY minTradeVolChanged) Q_PROPERTY(bool invalid_cex_price READ get_invalid_cex_price NOTIFY invalidCexPriceChanged) Q_PROPERTY(bool skip_taker READ get_skip_taker WRITE set_skip_taker NOTIFY skipTakerChanged) @@ -116,9 +111,9 @@ namespace atomic_dex QString m_price{"0"}; QString m_volume{"0"}; QString m_max_volume{"0"}; - QString m_total_amount{"0"}; + QString m_total_amount{"0.00777"}; QString m_cex_price{"0"}; - QString m_minimal_trading_amount{"0"}; + QString m_minimal_trading_amount{"0.0001"}; std::optional m_preferred_order; boost::synchronized_value m_fees; bool m_skip_taker{false}; @@ -189,7 +184,6 @@ namespace atomic_dex [[nodiscard]] QString get_price_reversed() const; [[nodiscard]] QString get_price() const; void set_price(QString price); - //[[nodiscard]] QString get_mm2_min_trade_vol() const; [[nodiscard]] QString get_min_trade_vol() const; void set_min_trade_vol(QString min_trade_vol); [[nodiscard]] QString get_volume() const; diff --git a/src/core/atomicdex/pages/qt.wallet.page.cpp b/src/core/atomicdex/pages/qt.wallet.page.cpp index 2b801f81b9..ec0fd4e477 100644 --- a/src/core/atomicdex/pages/qt.wallet.page.cpp +++ b/src/core/atomicdex/pages/qt.wallet.page.cpp @@ -15,6 +15,8 @@ #include "atomicdex/api/mm2/rpc.electrum.hpp" #include "atomicdex/api/mm2/rpc.validate.address.hpp" #include "atomicdex/api/mm2/rpc.withdraw.hpp" +#include "atomicdex/api/mm2/rpc2.init_withdraw.hpp" +#include "atomicdex/api/mm2/rpc2.withdraw_status.hpp" #include "atomicdex/services/mm2/mm2.service.hpp" #include "atomicdex/services/price/global.provider.hpp" #include "atomicdex/services/price/komodo_prices/komodo.prices.provider.hpp" @@ -99,22 +101,21 @@ namespace atomic_dex //! Getters/Setters namespace atomic_dex { - QString - wallet_page::get_current_ticker() const + QString wallet_page::get_current_ticker() const { const auto& mm2_system = m_system_manager.get_system(); return QString::fromStdString(mm2_system.get_current_ticker()); } - void - wallet_page::set_current_ticker(const QString& ticker) + void wallet_page::set_current_ticker(const QString& ticker) { auto& mm2_system = m_system_manager.get_system(); + auto coin_info = mm2_system.get_coin_info(ticker.toStdString()); if (mm2_system.set_current_ticker(ticker.toStdString())) { SPDLOG_INFO("new ticker: {}", ticker.toStdString()); - this->set_tx_fetching_busy(true); m_transactions_mdl->reset(); + this->set_tx_fetching_busy(true); mm2_system.fetch_infos_thread(true, true); emit currentTickerChanged(); refresh_ticker_infos(); @@ -218,14 +219,12 @@ namespace atomic_dex } } - bool - atomic_dex::wallet_page::is_tx_fetching_busy() const + bool atomic_dex::wallet_page::is_tx_fetching_busy() const { return m_tx_fetching_busy; } - void - atomic_dex::wallet_page::set_tx_fetching_busy(bool status) + void atomic_dex::wallet_page::set_tx_fetching_busy(bool status) { if (m_tx_fetching_busy != status) { @@ -234,10 +233,22 @@ namespace atomic_dex } } - QVariant - wallet_page::get_ticker_infos() const + bool atomic_dex::wallet_page::is_tx_fetching_failed() const + { + return m_tx_fetching_failed; + } + + void atomic_dex::wallet_page::set_tx_fetching_failed(bool status) + { + if (m_tx_fetching_failed != status) + { + m_tx_fetching_failed = status; + emit txFetchingOutcomeChanged(); + } + } + + QVariant wallet_page::get_ticker_infos() const { - // SPDLOG_DEBUG("get_ticker_infos"); QJsonObject obj{ {"balance", "0"}, {"name", "Komodo"}, @@ -251,6 +262,7 @@ namespace atomic_dex {"tx_state", "InProgress"}, {"fiat_amount", "0.00"}, {"trend_7d", QJsonArray()}, + {"activation_status", QJsonObject()}, {"fee_ticker", DEX_PRIMARY_COIN}, {"blocks_left", 1}, {"transactions_left", 0}, @@ -274,27 +286,28 @@ namespace atomic_dex obj["type"] = QString::fromStdString(coin_info.type); obj["segwit_supported"] = coin_info.segwit; obj["is_segwit_on"] = coin_info.is_segwit_on; + obj["has_parent_fees_ticker"] = coin_info.has_parent_fees_ticker; + obj["fees_ticker"] = QString::fromStdString(coin_info.fees_ticker); obj["is_claimable"] = coin_info.is_claimable; obj["address"] = QString::fromStdString(mm2_system.address(ticker, ec)); obj["minimal_balance_for_asking_rewards"] = QString::fromStdString(coin_info.minimal_claim_amount); - obj["explorer_url"] = QString::fromStdString(coin_info.explorer_url[0]); + obj["explorer_url"] = QString::fromStdString(coin_info.explorer_url); obj["current_currency_ticker_price"] = QString::fromStdString(price_service.get_rate_conversion(config.current_currency, ticker, true)); obj["change_24h"] = retrieve_change_24h(provider, coin_info, config, m_system_manager); const auto& tx_state = mm2_system.get_tx_state(ec); obj["tx_state"] = QString::fromStdString(tx_state.state); obj["fiat_amount"] = QString::fromStdString(price_service.get_price_in_fiat(config.current_currency, ticker, ec)); + obj["activation_status"] = nlohmann_json_object_to_qt_json_object(coin_info.activation_status); obj["trend_7d"] = nlohmann_json_array_to_qt_json_array(provider.get_ticker_historical(ticker)); - // SPDLOG_INFO("fee_ticker of ticker :{} is {}", ticker, coin_info.fees_ticker); obj["fee_ticker"] = QString::fromStdString(coin_info.fees_ticker); obj["blocks_left"] = static_cast(tx_state.blocks_left); obj["transactions_left"] = static_cast(tx_state.transactions_left); obj["current_block"] = static_cast(tx_state.current_block); - obj["is_smartchain_test_coin"] = coin_info.ticker == "RICK" || coin_info.ticker == "MORTY"; + obj["is_smartchain_test_coin"] = coin_info.ticker == "RICK" || coin_info.ticker == "MORTY" || coin_info.ticker == "ZOMBIE"; std::error_code ec; qrcodegen::QrCode qr0 = qrcodegen::QrCode::encodeText(mm2_system.address(ticker, ec).c_str(), qrcodegen::QrCode::Ecc::MEDIUM); std::string svg = qr0.toSvgString(2); obj["qrcode_address"] = QString::fromStdString("data:image/svg+xml;base64,") + QString::fromStdString(svg).toLocal8Bit().toBase64(); - // SPDLOG_DEBUG("is_segwit_on {} segwit: {}", coin_info.is_segwit_on, coin_info.segwit); } return obj; } @@ -353,7 +366,7 @@ namespace atomic_dex reason = tr("Invalid checksum."); json_result["convertible"] = false; } - else if (reason.contains("has invalid prefixes")) + else if (reason.contains("has invalid prefixes") or reason.contains("Expected a valid P2PKH or P2SH prefix")) { reason = tr("%1 address has invalid prefixes.").arg(json_result["ticker"].toString()); } @@ -369,6 +382,19 @@ namespace atomic_dex emit validateAddressDataChanged(); } + QVariant + wallet_page::get_coin_enabling_status() const + { + return m_coin_enabling_status.get(); + } + + void + wallet_page::set_coin_enabling_status(QVariant rpc_data) + { + m_coin_enabling_status = rpc_data.toJsonObject(); + emit coinEnablingStatusChanged(); + } + QVariant wallet_page::get_rpc_claiming_data() const { @@ -477,112 +503,291 @@ namespace atomic_dex nlohmann::json batch = nlohmann::json::array(); auto& mm2_system = m_system_manager.get_system(); const auto& ticker = mm2_system.get_current_ticker(); - t_withdraw_request withdraw_req{.coin = ticker, .to = address.toStdString(), .amount = max ? "0" : amount.toStdString(), .max = max}; auto coin_info = mm2_system.get_coin_info(ticker); - if (with_fees) - { - qDebug() << fees_data; - auto json_fees = nlohmann::json::parse(QString(QJsonDocument(QVariant(fees_data).toJsonObject()).toJson()).toStdString()); - withdraw_req.fees = t_withdraw_fees{ - .type = "UtxoFixed", - .amount = json_fees.at("fees_amount").get(), - .gas_price = json_fees.at("gas_price").get(), - .gas_limit = json_fees.at("gas_limit").get()}; - if (coin_info.coin_type == CoinType::ERC20) + + if (coin_info.is_zhtlc_family) + { + t_init_withdraw_request init_withdraw_req{.coin = ticker, .to = address.toStdString(), .amount = max ? "0" : amount.toStdString(), .max = max}; + + if (with_fees) { - withdraw_req.fees->type = "EthGas"; + qDebug() << fees_data; + auto json_fees = nlohmann::json::parse(QString(QJsonDocument(QVariant(fees_data).toJsonObject()).toJson()).toStdString()); + init_withdraw_req.fees = t_init_withdraw_fees{ + .type = "UtxoFixed", + .amount = json_fees.at("fees_amount").get() + }; } - else if (coin_info.coin_type == CoinType::QRC20) + nlohmann::json json_data = mm2::template_request("init_withdraw", true); + + mm2::to_json(json_data, init_withdraw_req); + + batch.push_back(json_data); + std::string amount_std = amount.toStdString(); + + if (max) { - withdraw_req.fees->type = "Qrc20Gas"; + std::error_code ec; + amount_std = mm2_system.my_balance(ticker, ec); } - } - nlohmann::json json_data = ::mm2::api::template_request("withdraw", true); - ::mm2::api::to_json(json_data, withdraw_req); - // SPDLOG_DEBUG("final json: {}", json_data.dump(4)); - batch.push_back(json_data); - std::string amount_std = amount.toStdString(); - if (max) - { - std::error_code ec; - amount_std = mm2_system.my_balance(ticker, ec); - } - //! Answer - auto answer_functor = [this, coin_info, ticker, amount_std](web::http::http_response resp) - { - const auto& settings_system = m_system_manager.get_system(); - const auto& global_price_system = m_system_manager.get_system(); - const auto& current_fiat = settings_system.get_current_fiat().toStdString(); - std::string body = TO_STD_STR(resp.extract_string(true).get()); - SPDLOG_DEBUG("resp: {}", body); - if (resp.status_code() == 200 && body.find("error") == std::string::npos) + auto answer_functor = [this, coin_info, ticker, amount_std](web::http::http_response resp) { - auto answers = nlohmann::json::parse(body); - auto withdraw_answer = ::mm2::api::rpc_process_answer_batch(answers[0], "withdraw"); - nlohmann::json j_out = nlohmann::json::object(); - j_out["withdraw_answer"] = answers[0]["result"]; - j_out.at("withdraw_answer")["date"] = withdraw_answer.result.value().timestamp_as_date; + const auto& settings_system = m_system_manager.get_system(); + const auto& global_price_system = m_system_manager.get_system(); + const auto& current_fiat = settings_system.get_current_fiat().toStdString(); + auto answers = mm2::basic_batch_answer(resp); - // Add total amount in fiat currency. - if (coin_info.coinpaprika_id == "test-coin") + if (answers[0].contains("result")) { - j_out["withdraw_answer"]["total_amount_fiat"] = "0"; + if (answers[0]["result"].contains("task_id")) + { + auto task_id = answers[0].at("result").at("task_id").get(); + { + SPDLOG_DEBUG("Task ID: {}", task_id); + using namespace std::chrono_literals; + auto& mm2_system = m_system_manager.get_system(); + static std::size_t z_nb_try = 1; + nlohmann::json z_error = nlohmann::json::array(); + nlohmann::json z_batch_array = nlohmann::json::array(); + QString z_status; + t_withdraw_status_request z_request{.task_id = task_id}; + + nlohmann::json j = mm2::template_request("withdraw_status", true); + mm2::to_json(j, z_request); + z_batch_array.push_back(j); + + do { + pplx::task z_resp_task = mm2_system.get_mm2_client().async_rpc_batch_standalone(z_batch_array); + web::http::http_response z_resp = z_resp_task.get(); + auto z_answers = mm2::basic_batch_answer(z_resp); + z_error = z_answers; + z_status = QString::fromStdString(z_answers[0].at("result").at("status").get()); + + SPDLOG_DEBUG("[{}/120] Waiting for {} withdraw status [{}]...", z_nb_try, ticker, z_status.toUtf8().constData()); + if (z_status == "Ready") + { + break; + } + else + { + set_withdraw_status("Generating transaction... "); + } + std::this_thread::sleep_for(2s); + z_nb_try += 1; + + } while (z_nb_try < 120); + + try { + if (z_error[0].at("result").at("details").contains("error")) + { + SPDLOG_DEBUG("Error zhtlc withdraw_status {}: {} ", ticker, z_status.toUtf8().constData()); + z_status = QString::fromStdString(z_error[0].at("result").at("details").at("error").get()); + set_withdraw_status(z_status); + } + else if (z_nb_try == 120) + { + // TODO: Handle this case. + // There could be no error message if scanning takes too long. + // Either we force disable here, or schedule to check on it later + SPDLOG_DEBUG("Exited zhtlc withdraw loop after 120 tries"); + SPDLOG_DEBUG("Bad answer for [{}] zhtlc withdraw_status: {}", ticker, z_error[0].dump(4)); + set_withdraw_status("Timed out"); + } + else + { + auto withdraw_answer = mm2::rpc_process_answer_batch(z_error[0], "withdraw_status"); + nlohmann::json j_out = nlohmann::json::object(); + j_out["withdraw_answer"] = z_error[0]["result"]["details"]["result"]; + j_out.at("withdraw_answer")["date"] = withdraw_answer.result.value().timestamp_as_date; + + // Add total amount in fiat currency. + if (coin_info.coinpaprika_id == "test-coin") + { + j_out["withdraw_answer"]["total_amount_fiat"] = "0"; + } + else + { + j_out["withdraw_answer"]["total_amount_fiat"] = global_price_system.get_price_as_currency_from_amount(current_fiat, ticker, amount_std); + } + + // Add fees amount. + if (j_out.at("withdraw_answer").at("fee_details").contains("total_fee") && !j_out.at("withdraw_answer").at("fee_details").contains("amount")) + { + j_out["withdraw_answer"]["fee_details"]["amount"] = j_out["withdraw_answer"]["fee_details"]["total_fee"]; + } + if (j_out.at("withdraw_answer").at("fee_details").contains("miner_fee") && !j_out.at("withdraw_answer").at("fee_details").contains("amount")) + { + j_out["withdraw_answer"]["fee_details"]["amount"] = j_out["withdraw_answer"]["fee_details"]["miner_fee"]; + } + + // Add fees amount in fiat currency. + auto fee = j_out["withdraw_answer"]["fee_details"]["amount"].get(); + if (coin_info.coinpaprika_id == "test-coin") + { + j_out["withdraw_answer"]["fee_details"]["amount_fiat"] = "0"; + } + else + { + j_out["withdraw_answer"]["fee_details"]["amount_fiat"] = + global_price_system.get_price_as_currency_from_amount(current_fiat, coin_info.fees_ticker, fee); + } + SPDLOG_DEBUG("zhtlc set_rpc_send_data (else)"); + this->set_rpc_send_data(nlohmann_json_object_to_qt_json_object(j_out)); + set_withdraw_status("Complete"); + } + z_nb_try = 0; + } + catch (const std::exception& error) + { + set_withdraw_status(QString::fromStdString(error.what())); + SPDLOG_ERROR("exception caught in zhtlc withdraw_status: {}", error.what()); + } + } + } } else { - j_out["withdraw_answer"]["total_amount_fiat"] = global_price_system.get_price_as_currency_from_amount(current_fiat, ticker, amount_std); + std::string body = TO_STD_STR(resp.extract_string(true).get()); + auto error_json = QJsonObject({{"error_code", resp.status_code()}, {"error_message", QString::fromStdString(body)}}); + this->set_rpc_send_data(error_json); } + this->set_send_busy(false); + }; - // Add fees amount. - if (j_out.at("withdraw_answer").at("fee_details").contains("total_fee") && !j_out.at("withdraw_answer").at("fee_details").contains("amount")) + auto error_functor = [this](pplx::task previous_task) + { + try { - j_out["withdraw_answer"]["fee_details"]["amount"] = j_out["withdraw_answer"]["fee_details"]["total_fee"]; + previous_task.wait(); } - if (j_out.at("withdraw_answer").at("fee_details").contains("miner_fee") && !j_out.at("withdraw_answer").at("fee_details").contains("amount")) + catch (const std::exception& e) { - j_out["withdraw_answer"]["fee_details"]["amount"] = j_out["withdraw_answer"]["fee_details"]["miner_fee"]; + SPDLOG_ERROR("error caught in send: {}", e.what()); + auto error_json = QJsonObject({{"error_code", 500}, {"error_message", QString::fromStdString(e.what())}}); + this->set_rpc_send_data(error_json); + this->set_send_busy(false); } + }; + + //! Process + mm2_system.get_mm2_client().async_rpc_batch_standalone(batch).then(answer_functor).then(error_functor); + + } + else + { + t_withdraw_request withdraw_req{.coin = ticker, .to = address.toStdString(), .amount = max ? "0" : amount.toStdString(), .max = max}; - // Add fees amount in fiat currency. - auto fee = j_out["withdraw_answer"]["fee_details"]["amount"].get(); - if (coin_info.coinpaprika_id == "test-coin") + if (with_fees) + { + qDebug() << fees_data; + auto json_fees = nlohmann::json::parse(QString(QJsonDocument(QVariant(fees_data).toJsonObject()).toJson()).toStdString()); + withdraw_req.fees = t_withdraw_fees{ + .type = "UtxoFixed", + .amount = json_fees.at("fees_amount").get(), + .gas_price = json_fees.at("gas_price").get(), + .gas_limit = json_fees.at("gas_limit").get()}; + if (coin_info.coin_type == CoinType::ERC20) { - j_out["withdraw_answer"]["fee_details"]["amount_fiat"] = "0"; + withdraw_req.fees->type = "EthGas"; } - else + else if (coin_info.coin_type == CoinType::QRC20) { - j_out["withdraw_answer"]["fee_details"]["amount_fiat"] = - global_price_system.get_price_as_currency_from_amount(current_fiat, coin_info.fees_ticker, fee); + withdraw_req.fees->type = "Qrc20Gas"; + } + else if (coin_info.has_parent_fees_ticker) + { + withdraw_req.fees->type = "otherGas"; } - - this->set_rpc_send_data(nlohmann_json_object_to_qt_json_object(j_out)); - } - else - { - auto error_json = QJsonObject({{"error_code", resp.status_code()}, {"error_message", QString::fromStdString(body)}}); - this->set_rpc_send_data(error_json); } - this->set_send_busy(false); - }; + nlohmann::json json_data = mm2::template_request("withdraw", true); + mm2::to_json(json_data, withdraw_req); + // SPDLOG_DEBUG("final json: {}", json_data.dump(4)); + batch.push_back(json_data); - auto error_functor = [this](pplx::task previous_task) - { - try + std::string amount_std = amount.toStdString(); + if (max) { - previous_task.wait(); + std::error_code ec; + amount_std = mm2_system.my_balance(ticker, ec); } - catch (const std::exception& e) + + //! Answer + auto answer_functor = [this, coin_info, ticker, amount_std](web::http::http_response resp) { - SPDLOG_ERROR("error caught in send: {}", e.what()); - auto error_json = QJsonObject({{"error_code", 500}, {"error_message", QString::fromStdString(e.what())}}); - this->set_rpc_send_data(error_json); + const auto& settings_system = m_system_manager.get_system(); + const auto& global_price_system = m_system_manager.get_system(); + const auto& current_fiat = settings_system.get_current_fiat().toStdString(); + std::string body = TO_STD_STR(resp.extract_string(true).get()); + + if (resp.status_code() == 200 && body.find("error") == std::string::npos) + { + auto answers = nlohmann::json::parse(body); + auto withdraw_answer = mm2::rpc_process_answer_batch(answers[0], "withdraw"); + nlohmann::json j_out = nlohmann::json::object(); + j_out["withdraw_answer"] = answers[0]["result"]; + j_out.at("withdraw_answer")["date"] = withdraw_answer.result.value().timestamp_as_date; + + // Add total amount in fiat currency. + if (coin_info.coinpaprika_id == "test-coin") + { + j_out["withdraw_answer"]["total_amount_fiat"] = "0"; + } + else + { + j_out["withdraw_answer"]["total_amount_fiat"] = global_price_system.get_price_as_currency_from_amount(current_fiat, ticker, amount_std); + } + + // Add fees amount. + if (j_out.at("withdraw_answer").at("fee_details").contains("total_fee") && !j_out.at("withdraw_answer").at("fee_details").contains("amount")) + { + j_out["withdraw_answer"]["fee_details"]["amount"] = j_out["withdraw_answer"]["fee_details"]["total_fee"]; + } + if (j_out.at("withdraw_answer").at("fee_details").contains("miner_fee") && !j_out.at("withdraw_answer").at("fee_details").contains("amount")) + { + j_out["withdraw_answer"]["fee_details"]["amount"] = j_out["withdraw_answer"]["fee_details"]["miner_fee"]; + } + + // Add fees amount in fiat currency. + auto fee = j_out["withdraw_answer"]["fee_details"]["amount"].get(); + if (coin_info.coinpaprika_id == "test-coin") + { + j_out["withdraw_answer"]["fee_details"]["amount_fiat"] = "0"; + } + else + { + j_out["withdraw_answer"]["fee_details"]["amount_fiat"] = + global_price_system.get_price_as_currency_from_amount(current_fiat, coin_info.fees_ticker, fee); + } + + this->set_rpc_send_data(nlohmann_json_object_to_qt_json_object(j_out)); + } + else + { + auto error_json = QJsonObject({{"error_code", resp.status_code()}, {"error_message", QString::fromStdString(body)}}); + this->set_rpc_send_data(error_json); + } this->set_send_busy(false); - } - }; + }; - //! Process - mm2_system.get_mm2_client().async_rpc_batch_standalone(batch).then(answer_functor).then(error_functor); + auto error_functor = [this](pplx::task previous_task) + { + try + { + previous_task.wait(); + } + catch (const std::exception& e) + { + SPDLOG_ERROR("error caught in send: {}", e.what()); + auto error_json = QJsonObject({{"error_code", 500}, {"error_message", QString::fromStdString(e.what())}}); + this->set_rpc_send_data(error_json); + this->set_send_busy(false); + } + }; + + //! Process + mm2_system.get_mm2_client().async_rpc_batch_standalone(batch).then(answer_functor).then(error_functor); + } } void @@ -621,8 +826,8 @@ namespace atomic_dex const auto& ticker = mm2_system.get_current_ticker(); nlohmann::json batch = nlohmann::json::array(); t_broadcast_request broadcast_request{.tx_hex = tx_hex.toStdString(), .coin = ticker}; - nlohmann::json json_data = ::mm2::api::template_request("send_raw_transaction"); - ::mm2::api::to_json(json_data, broadcast_request); + nlohmann::json json_data = mm2::template_request("send_raw_transaction"); + mm2::to_json(json_data, broadcast_request); batch.push_back(json_data); //! Answer @@ -685,10 +890,10 @@ namespace atomic_dex auto& mm2_system = m_system_manager.get_system(); std::error_code ec; t_withdraw_request withdraw_req{.coin = "KMD", .to = mm2_system.address("KMD", ec), .amount = "0", .max = true}; - nlohmann::json json_data = ::mm2::api::template_request("withdraw", true); - ::mm2::api::to_json(json_data, withdraw_req); + nlohmann::json json_data = mm2::template_request("withdraw", true); + mm2::to_json(json_data, withdraw_req); batch.push_back(json_data); - json_data = ::mm2::api::template_request("kmd_rewards_info"); + json_data = mm2::template_request("kmd_rewards_info"); batch.push_back(json_data); auto answer_functor = [this](web::http::http_response resp) @@ -698,11 +903,11 @@ namespace atomic_dex if (resp.status_code() == static_cast(antara::app::http_code::ok) && body.find("error") == std::string::npos) { auto answers = nlohmann::json::parse(body); - auto withdraw_answer = ::mm2::api::rpc_process_answer_batch(answers[0], "withdraw"); + auto withdraw_answer = mm2::rpc_process_answer_batch(answers[0], "withdraw"); nlohmann::json j_out = nlohmann::json::object(); j_out["withdraw_answer"] = answers[0]["result"]; j_out.at("withdraw_answer")["date"] = withdraw_answer.result.value().timestamp_as_date; - auto kmd_rewards_answer = ::mm2::api::process_kmd_rewards_answer(answers[1]); + auto kmd_rewards_answer = mm2::process_kmd_rewards_answer(answers[1]); j_out["kmd_rewards_info"] = kmd_rewards_answer.result; this->set_rpc_claiming_data(nlohmann_json_object_to_qt_json_object(j_out)); } @@ -769,11 +974,10 @@ namespace atomic_dex void wallet_page::on_tx_fetch_finished(const tx_fetch_finished& evt) { - if (!evt.with_error) + if (!evt.with_error && QString::fromStdString(evt.ticker) == get_current_ticker()) { std::error_code ec; t_transactions transactions = m_system_manager.get_system().get_tx_history(ec); - // SPDLOG_INFO("transaction size: {}", transactions.size()); if (m_transactions_mdl->rowCount() == 0) { //! insert all transactions @@ -782,9 +986,16 @@ namespace atomic_dex else { //! Update tx (only unconfirmed) or insert (new tx) - // SPDLOG_DEBUG("updating / insert tx"); m_transactions_mdl->update_or_insert_transactions(transactions); } + if (ec) + { + this->set_tx_fetching_failed(true); + } + else + { + this->set_tx_fetching_failed(false); + } } else { @@ -807,7 +1018,7 @@ namespace atomic_dex void wallet_page::validate_address(QString address, QString ticker) { - SPDLOG_INFO("validate_address: {} - ticker: {}", address.toStdString(), ticker.toStdString()); + // SPDLOG_INFO("validate_address: {} - ticker: {}", address.toStdString(), ticker.toStdString()); auto& mm2_system = m_system_manager.get_system(); if (mm2_system.is_mm2_running()) { @@ -815,19 +1026,19 @@ namespace atomic_dex t_validate_address_request req{.coin = ticker.toStdString(), .address = address.toStdString()}; this->set_validate_address_busy(true); nlohmann::json batch = nlohmann::json::array(); - nlohmann::json json_data = ::mm2::api::template_request("validateaddress"); - ::mm2::api::to_json(json_data, req); + nlohmann::json json_data = mm2::template_request("validateaddress"); + mm2::to_json(json_data, req); batch.push_back(json_data); auto answer_functor = [this, ticker](web::http::http_response resp) { std::string body = TO_STD_STR(resp.extract_string(true).get()); - SPDLOG_DEBUG("resp validateaddress: {}", body); + // SPDLOG_DEBUG("resp validateaddress: {}", body); nlohmann::json j_out = nlohmann::json::object(); j_out["ticker"] = ticker.toStdString(); if (resp.status_code() == static_cast(antara::app::http_code::ok)) { auto answers = nlohmann::json::parse(body); - auto validate_answer = ::mm2::api::rpc_process_answer_batch(answers[0], "validateaddress"); + auto validate_answer = mm2::rpc_process_answer_batch(answers[0], "validateaddress"); if (validate_answer.result.has_value()) { auto res = validate_answer.result.value(); @@ -836,14 +1047,22 @@ namespace atomic_dex } else { + if (!m_system_manager.get_system().is_zhtlc_coin_ready(ticker.toStdString())) + { + j_out["reason"] = "Validation error: Coin not fully enabled"; + } + else + { + j_out["reason"] = "Validation error: Unknown"; + } + j_out["is_valid"] = false; - j_out["reason"] = "valideaddress unknown error"; } } else { j_out["is_valid"] = false; - j_out["reason"] = "valideaddress unknown error"; + j_out["reason"] = "Validation error: Problem with connection"; } this->set_validate_address_data(nlohmann_json_object_to_qt_json_object(j_out)); this->set_validate_address_busy(false); @@ -874,8 +1093,8 @@ namespace atomic_dex t_convert_address_request req{.coin = ticker.toStdString(), .from = from.toStdString(), .to_address_format = address_fmt}; this->set_convert_address_busy(true); nlohmann::json batch = nlohmann::json::array(); - nlohmann::json json_data = ::mm2::api::template_request("convertaddress"); - ::mm2::api::to_json(json_data, req); + nlohmann::json json_data = mm2::template_request("convertaddress"); + mm2::to_json(json_data, req); batch.push_back(json_data); auto answer_functor = [this](web::http::http_response resp) { @@ -884,7 +1103,7 @@ namespace atomic_dex if (resp.status_code() == static_cast(antara::app::http_code::ok)) { auto answers = nlohmann::json::parse(body); - auto convert_answer = ::mm2::api::rpc_process_answer_batch(answers[0], "convertaddress"); + auto convert_answer = mm2::rpc_process_answer_batch(answers[0], "convertaddress"); if (convert_answer.result.has_value()) { auto res = QString::fromStdString(convert_answer.result.value().address); @@ -897,6 +1116,19 @@ namespace atomic_dex } } + QString + wallet_page::get_withdraw_status() const + { + return m_withdraw_status.get(); + } + + void + wallet_page::set_withdraw_status(QString status) + { + m_withdraw_status = status; + emit withdrawStatusChanged(); + } + QString wallet_page::get_converted_address() const { @@ -941,8 +1173,8 @@ namespace atomic_dex address = mm2_system.address(ticker, ec); t_convert_address_request req{.coin = ticker, .from = address, .to_address_format = address_format}; nlohmann::json batch = nlohmann::json::array(); - nlohmann::json json_data = ::mm2::api::template_request("convertaddress"); - ::mm2::api::to_json(json_data, req); + nlohmann::json json_data = mm2::template_request("convertaddress"); + mm2::to_json(json_data, req); batch.push_back(json_data); json_data["userpass"] = "******"; SPDLOG_INFO("convertaddress request: {}", json_data.dump()); @@ -952,7 +1184,7 @@ namespace atomic_dex if (resp.status_code() == static_cast(antara::app::http_code::ok)) { auto answers = nlohmann::json::parse(body); - auto convert_answer = ::mm2::api::rpc_process_answer_batch(answers[0], "convertaddress"); + auto convert_answer = mm2::rpc_process_answer_batch(answers[0], "convertaddress"); if (convert_answer.result.has_value()) { return QString::fromStdString(convert_answer.result.value().address); @@ -973,9 +1205,9 @@ namespace atomic_dex //! Need disable + enable + refresh balance + refresh current coin info (address) + change segwit in cfg const auto ticker = get_current_ticker().toStdString(); nlohmann::json batch = nlohmann::json::array(); - nlohmann::json json_data = ::mm2::api::template_request("disable_coin"); + nlohmann::json json_data = mm2::template_request("disable_coin"); t_disable_coin_request req{.coin = ticker}; - ::mm2::api::to_json(json_data, req); + mm2::to_json(json_data, req); batch.push_back(json_data); //! Disable is in the batch @@ -988,8 +1220,8 @@ namespace atomic_dex electrum_req.address_format = nlohmann::json::object(); electrum_req.address_format.value()["format"] = "segwit"; } - nlohmann::json electrum_data = ::mm2::api::template_request("electrum"); - ::mm2::api::to_json(electrum_data, electrum_req); + nlohmann::json electrum_data = mm2::template_request("electrum"); + mm2::to_json(electrum_data, electrum_req); batch.push_back(electrum_data); electrum_data["userpass"] = "*******"; SPDLOG_INFO("electrum_req: {}", electrum_data.dump(-1)); @@ -1012,4 +1244,4 @@ namespace atomic_dex mm2_system.get_mm2_client().async_rpc_batch_standalone(batch).then(answer_functor).then(&handle_exception_pplx_task); } } -} // namespace atomic_dex +} // namespace atomic_dex \ No newline at end of file diff --git a/src/core/atomicdex/pages/qt.wallet.page.hpp b/src/core/atomicdex/pages/qt.wallet.page.hpp index 820f853637..033699279b 100644 --- a/src/core/atomicdex/pages/qt.wallet.page.hpp +++ b/src/core/atomicdex/pages/qt.wallet.page.hpp @@ -5,7 +5,7 @@ #include #include -#include "atomicdex/models/qt.wallet.transactions.model.hpp" +#include "atomicdex/models/transactions_model.hpp" namespace atomic_dex { @@ -48,12 +48,18 @@ namespace atomic_dex void set_rpc_broadcast_data(QString rpc_data); [[nodiscard]] QVariant get_rpc_send_data() const; void set_rpc_send_data(QVariant rpc_data); + [[nodiscard]] QVariant get_coin_enabling_status() const; + void set_coin_enabling_status(QVariant rpc_data); + [[nodiscard]] bool is_tx_fetching_failed() const; + void set_tx_fetching_failed(bool status); [[nodiscard]] bool is_tx_fetching_busy() const; void set_tx_fetching_busy(bool status); [[nodiscard]] bool is_convert_address_busy() const; void set_convert_address_busy(bool status); [[nodiscard]] bool is_validate_address_busy() const; void set_validate_address_busy(bool status); + [[nodiscard]] QString get_withdraw_status() const; + void set_withdraw_status(QString status); [[nodiscard]] QString get_converted_address() const; void set_converted_address(QString converted_address); [[nodiscard]] QVariant get_validate_address_data() const; @@ -92,6 +98,7 @@ namespace atomic_dex Q_PROPERTY(QVariant ticker_infos READ get_ticker_infos NOTIFY tickerInfosChanged) Q_PROPERTY(bool is_claiming_busy READ is_rpc_claiming_busy WRITE set_claiming_is_busy NOTIFY rpcClaimingStatusChanged) Q_PROPERTY(QVariant claiming_rpc_data READ get_rpc_claiming_data WRITE set_rpc_claiming_data NOTIFY claimingRpcDataChanged) + Q_PROPERTY(QVariant enable_status_rpc_data READ get_coin_enabling_status WRITE set_coin_enabling_status NOTIFY coinEnablingStatusChanged) Q_PROPERTY(bool is_claiming_faucet_busy READ is_claiming_faucet_busy WRITE set_claiming_faucet_is_busy NOTIFY claimingFaucetStatusChanged) Q_PROPERTY(QVariant claiming_faucet_rpc_data READ get_rpc_claiming_faucet_data WRITE set_rpc_claiming_faucet_data NOTIFY claimingFaucetRpcDataChanged) Q_PROPERTY(bool is_broadcast_busy READ is_broadcast_busy WRITE set_broadcast_busy NOTIFY broadCastStatusChanged) @@ -99,6 +106,7 @@ namespace atomic_dex Q_PROPERTY(bool is_send_busy READ is_send_busy WRITE set_send_busy NOTIFY sendStatusChanged) Q_PROPERTY(QVariant send_rpc_data READ get_rpc_send_data WRITE set_rpc_send_data NOTIFY sendDataChanged) Q_PROPERTY(bool tx_fetching_busy READ is_tx_fetching_busy WRITE set_tx_fetching_busy NOTIFY txFetchingStatusChanged) + Q_PROPERTY(bool tx_fetching_failed READ is_tx_fetching_failed WRITE set_tx_fetching_failed NOTIFY txFetchingOutcomeChanged) Q_PROPERTY(bool auth_succeeded READ has_auth_succeeded NOTIFY auth_succeededChanged) Q_PROPERTY(bool send_available READ is_send_available NOTIFY sendAvailableChanged) Q_PROPERTY(QString send_availability_state READ get_send_availability_state NOTIFY sendAvailabilityStateChanged) @@ -108,6 +116,7 @@ namespace atomic_dex Q_PROPERTY(QVariant validate_address_data READ get_validate_address_data WRITE set_validate_address_data NOTIFY validateAddressDataChanged) Q_PROPERTY(bool convert_address_busy READ is_convert_address_busy WRITE set_convert_address_busy NOTIFY convertAddressBusyChanged) Q_PROPERTY(QString converted_address READ get_converted_address WRITE set_converted_address NOTIFY convertedAddressChanged) + Q_PROPERTY(QString withdraw_status READ get_withdraw_status WRITE set_withdraw_status NOTIFY withdrawStatusChanged) // QML API Properties Signals signals: @@ -115,6 +124,7 @@ namespace atomic_dex void tickerInfosChanged(); void rpcClaimingStatusChanged(); void claimingRpcDataChanged(); + void coinEnablingStatusChanged(); void claimingFaucetStatusChanged(); void claimingFaucetRpcDataChanged(); void broadCastStatusChanged(); @@ -123,6 +133,7 @@ namespace atomic_dex void sendDataChanged(); void transactionsMdlChanged(); void txFetchingStatusChanged(); + void txFetchingOutcomeChanged(); void auth_succeededChanged(); void sendAvailabilityStateChanged(); void sendAvailableChanged(); @@ -132,6 +143,7 @@ namespace atomic_dex void validateAddressDataChanged(); void convertAddressBusyChanged(); void convertedAddressChanged(); + void withdrawStatusChanged(); private: ag::ecs::system_manager& m_system_manager; @@ -141,15 +153,18 @@ namespace atomic_dex std::atomic_bool m_is_broadcast_busy{false}; std::atomic_bool m_is_send_busy{false}; std::atomic_bool m_tx_fetching_busy{false}; + std::atomic_bool m_tx_fetching_failed{false}; std::atomic_bool m_validate_address_busy{false}; std::atomic_bool m_convert_address_busy{false}; + t_qt_synchronized_json m_coin_enabling_status; t_qt_synchronized_json m_claiming_rpc_result; t_qt_synchronized_json m_claiming_rpc_faucet_result; t_qt_synchronized_json m_send_rpc_result; t_qt_synchronized_string m_broadcast_rpc_result; t_qt_synchronized_json m_validate_address_result; t_qt_synchronized_string m_converted_address; + t_qt_synchronized_string m_withdraw_status; bool m_auth_succeeded; bool m_send_available{true}; QString m_send_availability_state; diff --git a/src/core/atomicdex/pages/widgets/dex/qt.orderbook.cpp b/src/core/atomicdex/pages/widgets/dex/qt.orderbook.cpp index 6c064b8143..3f9eb34d2d 100644 --- a/src/core/atomicdex/pages/widgets/dex/qt.orderbook.cpp +++ b/src/core/atomicdex/pages/widgets/dex/qt.orderbook.cpp @@ -38,7 +38,6 @@ namespace // If cur_min_volume in the UI < base_min_vol_threshold override if (cur_min_volume_f < base_min_vol_threshold) { - // SPDLOG_INFO("cur_min_taker_vol: {}", cur_taker_vol.toStdString()); trading_pg.set_min_trade_vol(cur_taker_vol); } } @@ -91,10 +90,12 @@ namespace atomic_dex } else if (m_best_orders->rowCount() == 0) { + // SPDLOG_INFO("[qt_orderbook_wrapper::refresh_orderbook] : reset_best_orders"); m_best_orders->reset_orderbook(data); } else { + // SPDLOG_INFO("[qt_orderbook_wrapper::refresh_orderbook] : refresh_best_orders"); m_best_orders->refresh_orderbook(data); } this->set_both_taker_vol(); @@ -171,12 +172,10 @@ namespace atomic_dex { if (safe_float(m_system_manager.get_system().get_volume().toStdString()) > 0) { - // SPDLOG_INFO("refresh best orders"); this->m_system_manager.get_system().process_best_orders(); } else { - SPDLOG_INFO("clear best orders"); get_best_orders()->clear_orderbook(); } } @@ -194,11 +193,8 @@ namespace atomic_dex t_order_contents order = m_best_orders->get_order_content(idx); out["coin"] = QString::fromStdString(is_buy ? order.rel_coin.value() : order.coin); out["price"] = QString::fromStdString(order.price); - out["quantity"] = QString::fromStdString(order.maxvolume); out["price_denom"] = QString::fromStdString(order.price_fraction_denom); out["price_numer"] = QString::fromStdString(order.price_fraction_numer); - out["quantity_denom"] = QString::fromStdString(order.max_volume_fraction_denom); - out["quantity_numer"] = QString::fromStdString(order.max_volume_fraction_numer); out["min_volume"] = QString::fromStdString(order.min_volume); out["base_min_volume"] = QString::fromStdString(order.base_min_volume); out["base_max_volume"] = QString::fromStdString(order.base_max_volume); diff --git a/src/core/atomicdex/pages/widgets/dex/qt.orders.widget.cpp b/src/core/atomicdex/pages/widgets/dex/qt.orders.widget.cpp index 878a3c627b..c4181ada48 100644 --- a/src/core/atomicdex/pages/widgets/dex/qt.orders.widget.cpp +++ b/src/core/atomicdex/pages/widgets/dex/qt.orders.widget.cpp @@ -42,20 +42,20 @@ namespace atomic_dex qt_orders_widget::common_cancel_all_orders(bool by_coin, const QString& ticker) { nlohmann::json batch = nlohmann::json::array(); - nlohmann::json cancel_request = ::mm2::api::template_request("cancel_all_orders"); + nlohmann::json cancel_request = mm2::template_request("cancel_all_orders"); if (by_coin && not ticker.isEmpty()) { - ::mm2::api::cancel_data cd; + mm2::cancel_data cd; cd.ticker = ticker.toStdString(); - ::mm2::api::cancel_all_orders_request req{{"Coin", cd}}; - ::mm2::api::to_json(cancel_request, req); + mm2::cancel_all_orders_request req{{"Coin", cd}}; + mm2::to_json(cancel_request, req); } else { - ::mm2::api::cancel_data cd; + mm2::cancel_data cd; cd.ticker = ticker.toStdString(); - ::mm2::api::cancel_all_orders_request req_all; - ::mm2::api::to_json(cancel_request, req_all); + mm2::cancel_all_orders_request req_all; + mm2::to_json(cancel_request, req_all); } batch.push_back(cancel_request); @@ -81,9 +81,9 @@ namespace atomic_dex nlohmann::json batch = nlohmann::json::array(); for (auto&& order_id: orders_id) { - ::mm2::api::cancel_all_orders_request req; - nlohmann::json cancel_request = ::mm2::api::template_request("cancel_order"); - ::mm2::api::cancel_order_request cancel_req{order_id.toStdString()}; + mm2::cancel_all_orders_request req; + nlohmann::json cancel_request = mm2::template_request("cancel_order"); + mm2::cancel_order_request cancel_req{order_id.toStdString()}; to_json(cancel_request, cancel_req); batch.push_back(cancel_request); } diff --git a/src/core/atomicdex/pch.hpp b/src/core/atomicdex/pch.hpp index 826f73d685..510acf6123 100644 --- a/src/core/atomicdex/pch.hpp +++ b/src/core/atomicdex/pch.hpp @@ -16,7 +16,7 @@ #pragma once -#include "atomicdex/utilities/fs.prerequisites.hpp" +#include constexpr std::size_t operator"" _sz(unsigned long long n) { return n; } diff --git a/src/core/atomicdex/services/exporter/exporter.service.cpp b/src/core/atomicdex/services/exporter/exporter.service.cpp index 46461044ba..6f59fcd42c 100644 --- a/src/core/atomicdex/services/exporter/exporter.service.cpp +++ b/src/core/atomicdex/services/exporter/exporter.service.cpp @@ -56,7 +56,7 @@ namespace atomic_dex exporter_service::export_swaps_history_to_csv(const QString& path) { std::string str_path = path.toStdString(); - fs::path csv_path = str_path; + std::filesystem::path csv_path = str_path; if (not csv_path.has_extension()) { @@ -66,7 +66,7 @@ namespace atomic_dex LOG_PATH("new csv path is: {}", csv_path); } nlohmann::json batch = nlohmann::json::array(); - nlohmann::json my_recent_swaps = ::mm2::api::template_request("my_recent_swaps"); + nlohmann::json my_recent_swaps = mm2::template_request("my_recent_swaps"); auto& mm2 = m_system_manager.get_system(); const auto swaps_data = mm2.get_orders_and_swaps(); t_my_recent_swaps_request request{ @@ -80,8 +80,8 @@ namespace atomic_dex batch.push_back(my_recent_swaps); auto answer_functor = [csv_path](web::http::http_response resp) { - auto answers = ::mm2::api::basic_batch_answer(resp); - const auto swap_answer = ::mm2::api::rpc_process_answer_batch(answers[0], "my_recent_swaps"); + auto answers = mm2::basic_batch_answer(resp); + const auto swap_answer = mm2::rpc_process_answer_batch(answers[0], "my_recent_swaps"); if (swap_answer.result.has_value()) { const auto result = swap_answer.result.value(); diff --git a/src/core/atomicdex/services/internet/internet.checker.service.cpp b/src/core/atomicdex/services/internet/internet.checker.service.cpp index 498dde173c..548cf80071 100644 --- a/src/core/atomicdex/services/internet/internet.checker.service.cpp +++ b/src/core/atomicdex/services/internet/internet.checker.service.cpp @@ -18,7 +18,6 @@ #include //! Our project -#include "atomicdex/constants/dex.constants.hpp" #include "atomicdex/services/internet/internet.checker.service.hpp" #include "atomicdex/services/mm2/mm2.service.hpp" #include "atomicdex/utilities/cpprestsdk.utilities.hpp" @@ -173,12 +172,12 @@ namespace atomic_dex { SPDLOG_INFO("mm2 is alive, checking if ware able to fetch a simple orderbook"); nlohmann::json batch = nlohmann::json::array(); - nlohmann::json current_request = ::mm2::api::template_request("orderbook"); + nlohmann::json current_request = mm2::template_request("orderbook", true); t_orderbook_request req_orderbook{.base = g_primary_dex_coin, .rel = g_second_primary_dex_coin}; - ::mm2::api::to_json(current_request, req_orderbook); + mm2::to_json(current_request, req_orderbook); batch.push_back(current_request); auto async_answer = mm2.get_mm2_client().async_rpc_batch_standalone(batch); - generic_treat_answer(async_answer, "http://127.0.0.1:7783", &internet_service_checker::is_mm2_endpoint_alive); + generic_treat_answer(async_answer, TO_STD_STR(atomic_dex::g_dex_rpc), &internet_service_checker::is_mm2_endpoint_alive); } else { diff --git a/src/core/atomicdex/services/internet/internet.checker.service.hpp b/src/core/atomicdex/services/internet/internet.checker.service.hpp index e22f4df1c8..12fd00ec49 100644 --- a/src/core/atomicdex/services/internet/internet.checker.service.hpp +++ b/src/core/atomicdex/services/internet/internet.checker.service.hpp @@ -58,7 +58,9 @@ namespace atomic_dex public: //! Constructor - explicit internet_service_checker(entt::registry& registry, ag::ecs::system_manager& system_manager, entt::dispatcher& dispatcher, QObject* parent = nullptr); + explicit internet_service_checker( + entt::registry& registry, ag::ecs::system_manager& system_manager, + entt::dispatcher& dispatcher, QObject* parent = nullptr); ~internet_service_checker() final = default; //! Public override diff --git a/src/core/atomicdex/services/mm2/auto.update.maker.order.service.cpp b/src/core/atomicdex/services/mm2/auto.update.maker.order.service.cpp index 9dc84e6aa0..eea078ba52 100644 --- a/src/core/atomicdex/services/mm2/auto.update.maker.order.service.cpp +++ b/src/core/atomicdex/services/mm2/auto.update.maker.order.service.cpp @@ -81,7 +81,7 @@ namespace atomic_dex nlohmann::json batch = nlohmann::json::array(); std::string new_price = get_new_price_from_order(data, spread); nlohmann::json conf_settings = data.conf_settings.value_or(nlohmann::json()); - nlohmann::json update_maker_order_json = ::mm2::api::template_request("update_maker_order"); + nlohmann::json update_maker_order_json = mm2::template_request("update_maker_order"); t_float_50 volume = safe_float(data.base_amount.toStdString()); t_float_50 min_volume = volume * min_volume_percent; t_update_maker_order_request request{ @@ -96,7 +96,7 @@ namespace atomic_dex request.base_confs = conf_settings.at("base_confs").get(); request.rel_confs = conf_settings.at("rel_confs").get(); } - ::mm2::api::to_json(update_maker_order_json, request); + mm2::to_json(update_maker_order_json, request); batch.push_back(update_maker_order_json); update_maker_order_json["userpass"] = ""; SPDLOG_INFO("request: {}", update_maker_order_json.dump(1)); @@ -106,15 +106,10 @@ namespace atomic_dex .then( []([[maybe_unused]] web::http::http_response resp) { - std::string body = TO_STD_STR(resp.extract_string(true).get()); - SPDLOG_INFO("status_code: {}", resp.status_code()); - if (resp.status_code() == 200) + if (resp.status_code() != 200) { - SPDLOG_INFO("order resp: {}", body); - } - else - { - SPDLOG_WARN("An error occured during update_maker_order: {}", body); + std::string body = TO_STD_STR(resp.extract_string(true).get()); + SPDLOG_ERROR("An error occured during update_maker_order (code: {}): {}", resp.status_code(), body); } }) .then(&handle_exception_pplx_task); @@ -124,16 +119,16 @@ namespace atomic_dex void auto_update_maker_order_service::internal_update() { - SPDLOG_INFO("update maker orders"); + SPDLOG_DEBUG("update maker orders"); const auto& mm2 = this->m_system_manager.get_system(); orders_and_swaps data = mm2.get_orders_and_swaps(); - auto cur = data.orders_and_swaps.cbegin(); - auto end = data.orders_and_swaps.cbegin() + data.nb_orders; - for (; cur != end; ++cur) + auto cur = data.orders_and_swaps.begin(); + auto end = data.orders_and_swaps.begin() + data.nb_orders; + for (; cur != end && cur != data.orders_and_swaps.end(); ++cur) { if (cur->is_maker) { - SPDLOG_INFO("Updating order: {}", cur->order_id.toStdString()); + SPDLOG_DEBUG("Updating order: {}", cur->order_id.toStdString()); this->update_order(*cur); } } diff --git a/src/core/atomicdex/services/mm2/auto.update.maker.order.service.hpp b/src/core/atomicdex/services/mm2/auto.update.maker.order.service.hpp index 9a50d68ead..b2fc78ae7a 100644 --- a/src/core/atomicdex/services/mm2/auto.update.maker.order.service.hpp +++ b/src/core/atomicdex/services/mm2/auto.update.maker.order.service.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * diff --git a/src/core/atomicdex/services/mm2/mm2.service.cpp b/src/core/atomicdex/services/mm2/mm2.service.cpp index d3f0265a8a..49250a8fa6 100644 --- a/src/core/atomicdex/services/mm2/mm2.service.cpp +++ b/src/core/atomicdex/services/mm2/mm2.service.cpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -14,53 +14,56 @@ * * ******************************************************************************/ -//! STD +#include #include +#include +#include -///! Qt +#include +#include #include #include #include -//! Project Headers -#include "atomicdex/api/mm2/mm2.constants.hpp" +#include "atomicdex/api/mm2/utxo.merge.params.hpp" #include "atomicdex/api/mm2/rpc.electrum.hpp" #include "atomicdex/api/mm2/rpc.enable.hpp" #include "atomicdex/api/mm2/rpc.min.volume.hpp" #include "atomicdex/api/mm2/rpc.tx.history.hpp" +#include "atomicdex/api/mm2/rpc2.z_coin_tx_history.hpp" +#include "atomicdex/api/mm2/rpc2.init_z_coin.hpp" +#include "atomicdex/api/mm2/rpc2.init_z_coin_status.hpp" #include "atomicdex/config/mm2.cfg.hpp" +#include "atomicdex/config/coins.cfg.hpp" +#include "atomicdex/constants/dex.constants.hpp" #include "atomicdex/managers/qt.wallet.manager.hpp" -#include "atomicdex/pages/qt.portfolio.page.hpp" #include "atomicdex/services/internet/internet.checker.service.hpp" #include "atomicdex/services/mm2/mm2.service.hpp" -#include "atomicdex/utilities/kill.hpp" ///< no delete #include "atomicdex/utilities/qt.utilities.hpp" -#include "atomicdex/utilities/stacktrace.prerequisites.hpp" +#include "atomicdex/utilities/kill.hpp" + +namespace ag = antara::gaming; -//! Anonymous functions namespace { - namespace ag = antara::gaming; - - void - check_for_reconfiguration(const std::string& wallet_name) + void check_for_reconfiguration(const std::string& wallet_name) { try { using namespace std::string_literals; SPDLOG_DEBUG("checking for reconfiguration"); - fs::path cfg_path = atomic_dex::utils::get_atomic_dex_config_folder(); + std::filesystem::path cfg_path = atomic_dex::utils::get_atomic_dex_config_folder(); std::string filename = std::string(atomic_dex::get_precedent_raw_version()) + "-coins." + wallet_name + ".json"; - fs::path precedent_version_cfg_path = cfg_path / filename; + std::filesystem::path precedent_version_cfg_path = cfg_path / filename; - if (fs::exists(precedent_version_cfg_path)) + if (std::filesystem::exists(precedent_version_cfg_path)) { //! There is a precedent configuration file SPDLOG_INFO("There is a precedent configuration file, upgrading the new one with precedent settings"); //! Old cfg to ifs - LOG_PATH("opening file: {}", precedent_version_cfg_path); + LOG_PATH("opening previous version coins file: {}", precedent_version_cfg_path); QFile ifs; ifs.setFileName(atomic_dex::std_path_to_qstring(precedent_version_cfg_path)); ifs.open(QIODevice::Text | QIODevice::ReadOnly); @@ -68,8 +71,8 @@ namespace precedent_config_json_data = nlohmann::json::parse(QString(ifs.readAll()).toStdString()); //! New cfg to ifs - fs::path actual_version_filepath = cfg_path / (std::string(atomic_dex::get_raw_version()) + "-coins."s + wallet_name + ".json"s); - LOG_PATH("opening file: {}", actual_version_filepath); + std::filesystem::path actual_version_filepath = cfg_path / (std::string(atomic_dex::get_raw_version()) + "-coins."s + wallet_name + ".json"s); + LOG_PATH("opening new version coins file: {}", actual_version_filepath); QFile actual_version_ifs; actual_version_ifs.setFileName(atomic_dex::std_path_to_qstring(actual_version_filepath)); actual_version_ifs.open(QIODevice::Text | QIODevice::ReadOnly); @@ -94,26 +97,26 @@ namespace } } - LOG_PATH("closing file: {}", precedent_version_cfg_path); + LOG_PATH("closing old version coins file: {}", precedent_version_cfg_path); ifs.close(); - LOG_PATH("closing file: {}", actual_version_filepath); + LOG_PATH("closing new version coins file: {}", actual_version_filepath); actual_version_ifs.close(); //! Write contents - LOG_PATH("opening file: {}", actual_version_filepath); + LOG_PATH("opening new version file: {}", actual_version_filepath); QFile ofs; ofs.setFileName(atomic_dex::std_path_to_qstring(actual_version_filepath)); ofs.open(QIODevice::Text | QIODevice::WriteOnly); ofs.write(QString::fromStdString(actual_config_data.dump()).toUtf8()); //! Delete old cfg - fs_error_code ec; - fs::remove(precedent_version_cfg_path, ec); + std::error_code ec; + std::filesystem::remove(precedent_version_cfg_path, ec); if (ec) { SPDLOG_ERROR("error: {}", ec.message()); } - LOG_PATH("closing file: {}", actual_version_filepath); + LOG_PATH("closing new version file: {}", actual_version_filepath); ofs.close(); } } @@ -123,34 +126,27 @@ namespace } } - void - update_coin_status( - const std::string& wallet_name, const std::vector& tickers, bool status, atomic_dex::t_coins_registry& registry, - std::shared_mutex& registry_mtx, std::string field_name = "active") + void update_coin_status(const std::string& wallet_name, const std::vector& tickers, bool status, + atomic_dex::t_coins_registry& registry, std::shared_mutex& registry_mtx, std::string field_name = "active") { + if (wallet_name == "") + { + return; + } + if (tickers.empty()) + { + SPDLOG_DEBUG("Tickers list empty, skipping update_coin_status"); + return; + } SPDLOG_INFO("Update coins status to: {} - field_name: {} - tickers: {}", status, field_name, fmt::join(tickers, ", ")); - fs::path cfg_path = atomic_dex::utils::get_atomic_dex_config_folder(); + std::filesystem::path cfg_path = atomic_dex::utils::get_atomic_dex_config_folder(); std::string filename = std::string(atomic_dex::get_raw_version()) + "-coins." + wallet_name + ".json"; std::string custom_tokens_filename = "custom-tokens." + wallet_name + ".json"; - fs::path custom_tokens_filepath = cfg_path / custom_tokens_filename; + std::filesystem::path custom_tokens_filepath = cfg_path / custom_tokens_filename; - QFile ifs; - ifs.setFileName(atomic_dex::std_path_to_qstring((cfg_path / filename))); - ifs.open(QIODevice::ReadOnly | QIODevice::Text); - - nlohmann::json config_json_data; - nlohmann::json custom_cfg_data; - - if (fs::exists(custom_tokens_filepath.c_str())) - { - QFile ifs_custom; - ifs_custom.setFileName(atomic_dex::std_path_to_qstring(custom_tokens_filepath)); - ifs_custom.open(QIODevice::ReadOnly | QIODevice::Text); - custom_cfg_data = nlohmann::json::parse(QString(ifs_custom.readAll()).toStdString()); - ifs_custom.close(); - } + nlohmann::json config_json_data = atomic_dex::utils::read_json_file(cfg_path / filename); + nlohmann::json custom_cfg_data = atomic_dex::utils::read_json_file(custom_tokens_filepath); - config_json_data = nlohmann::json::parse(QString(ifs.readAll()).toStdString()); { std::shared_lock lock(registry_mtx); for (auto&& ticker: tickers) @@ -175,8 +171,6 @@ namespace } } - ifs.close(); - //! Write contents QFile ofs; ofs.setFileName(atomic_dex::std_path_to_qstring((cfg_path / filename))); @@ -184,7 +178,6 @@ namespace ofs.write(QString::fromStdString(config_json_data.dump()).toUtf8()); ofs.close(); - //! Write contents if (!custom_cfg_data.empty()) { @@ -195,13 +188,13 @@ namespace ofs_custom.write(QString::fromStdString(custom_cfg_data.dump()).toUtf8()); ofs_custom.close(); } + SPDLOG_DEBUG("Coins file updated to set {}: {} | tickers: [{}]", field_name, status, fmt::join(tickers, ", ")); } -} // namespace +} namespace atomic_dex { - std::vector - mm2_service::retrieve_coins_informations() + std::vector mm2_service::retrieve_coins_informations() { std::vector cfg; SPDLOG_DEBUG("retrieve_coins_informations"); @@ -210,20 +203,38 @@ namespace atomic_dex const auto cfg_path = atomic_dex::utils::get_atomic_dex_config_folder(); std::string filename = std::string(atomic_dex::get_raw_version()) + "-coins." + m_current_wallet_name + ".json"; std::string custom_tokens_filename = "custom-tokens." + m_current_wallet_name + ".json"; - // SPDLOG_INFO("Retrieving Wallet information of {}", (cfg_path / filename).string()); LOG_PATH("Retrieving Wallet information of {}", (cfg_path / filename)); - auto retrieve_cfg_functor = [](fs::path path) -> std::unordered_map + auto retrieve_cfg_functor = [](std::filesystem::path path) -> std::unordered_map { if (exists(path)) { - QFile ifs; - ifs.setFileName(atomic_dex::std_path_to_qstring(path)); - ifs.open(QIODevice::ReadOnly | QIODevice::Text); - nlohmann::json config_json_data = nlohmann::json::parse(QString(ifs.readAll()).toStdString()); - auto res = config_json_data.get>(); - return res; + try + { + QFile ifs; + ifs.setFileName(atomic_dex::std_path_to_qstring(path)); + ifs.open(QIODevice::ReadOnly | QIODevice::Text); + nlohmann::json config_json_data = nlohmann::json::parse(QString(ifs.readAll()).toStdString()); + + //! Iterate through config + for (auto& [key, value]: config_json_data.items()) + { + //! Ensure default coin are marked as active + if (is_default_coin(key)) + { + config_json_data.at(key)["active"] = true; + } + } + + auto res = config_json_data.get>(); + return res; + } + catch (const std::exception& error) + { + SPDLOG_ERROR("exception caught: {}", error.what()); + } } + SPDLOG_DEBUG("Coins file does not exist!"); return {}; }; @@ -262,8 +273,7 @@ namespace atomic_dex SPDLOG_INFO("mm2_service created"); } - void - mm2_service::update() + void mm2_service::update() { using namespace std::chrono_literals; @@ -278,6 +288,24 @@ namespace atomic_dex if (s >= 5s) { + if (m_nb_update_required > 0) + { + auto coins = this->get_enabled_coins(); + std::vector tickers; + for (auto&& coin: coins) + { + if (!coin.active) + { + tickers.push_back(coin.ticker); + } + } + if (!tickers.empty()) + { + SPDLOG_INFO("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); + } + m_nb_update_required -= 1; + } fetch_current_orderbook_thread(false); batch_fetch_orders_and_swap(); m_orderbook_clock = std::chrono::high_resolution_clock::now(); @@ -301,14 +329,14 @@ namespace atomic_dex if (m_mm2_running) { SPDLOG_INFO("preparing mm2 stop batch request"); - nlohmann::json stop_request = ::mm2::api::template_request("stop"); + nlohmann::json stop_request = mm2::template_request("stop"); nlohmann::json batch = nlohmann::json::array(); batch.push_back(stop_request); SPDLOG_INFO("processing mm2 stop batch request"); pplx::task resp_task = m_mm2_client.async_rpc_batch_standalone(batch); web::http::http_response resp = resp_task.get(); SPDLOG_INFO("mm2 stop batch answer received"); - auto answers = ::mm2::api::basic_batch_answer(resp); + auto answers = mm2::basic_batch_answer(resp); if (answers[0].contains("result")) { mm2_stopped = answers[0].at("result").get() == "success"; @@ -323,7 +351,7 @@ namespace atomic_dex { SPDLOG_INFO("mm2 didn't stop yet with rpc stop, stopping process manually"); #if defined(_WIN32) || defined(WIN32) - atomic_dex::kill_executable("mm2"); + atomic_dex::kill_executable(atomic_dex::g_dex_api); #else /*const reproc::stop_actions stop_actions = { {reproc::stop::terminate, reproc::milliseconds(2000)}, @@ -348,14 +376,12 @@ namespace atomic_dex SPDLOG_INFO("mm2 service fully destroyed"); } - const std::atomic_bool& - mm2_service::is_mm2_running() const + const std::atomic_bool& mm2_service::is_mm2_running() const { return m_mm2_running; } - t_coins - mm2_service::get_enabled_coins() const + t_coins mm2_service::get_enabled_coins() const { t_coins destination; @@ -371,8 +397,7 @@ namespace atomic_dex return destination; } - t_coins - mm2_service::get_active_coins() const + t_coins mm2_service::get_active_coins() const { t_coins destination; @@ -388,17 +413,19 @@ namespace atomic_dex return destination; } - bool - mm2_service::disable_coin(const std::string& ticker, std::error_code& ec) + bool mm2_service::disable_coin(const std::string& ticker, std::error_code& ec) { coin_config coin_info = get_coin_info(ticker); if (not coin_info.currently_enabled) { + 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); if (answer.error.has_value()) { @@ -418,44 +445,572 @@ namespace atomic_dex ec = dextop_error::order_is_matched_at_the_moment; return false; } + return false; } - coin_info.currently_enabled = false; - { std::unique_lock lock(m_coin_cfg_mutex); m_coins_informations[ticker].currently_enabled = false; } - dispatcher_.trigger(ticker); return true; } - bool - mm2_service::enable_default_coins() + bool mm2_service::enable_default_coins() { std::atomic result{1}; auto coins = get_active_coins(); + + enable_coins(coins); + batch_fetch_orders_and_swap(); + this->dispatcher_.trigger(); + return result.load() == 1; + } - std::vector tickers; - tickers.reserve(coins.size()); - for (auto&& current_coin: coins) + void mm2_service::enable_coin(const std::string& ticker) + { + enable_coin(get_coin_info(ticker)); + } + + void mm2_service::enable_coin(const coin_config& coin_config) + { + enable_coins(t_coins{coin_config}); + } + + void mm2_service::enable_coins(const std::vector& tickers) + { + t_coins coins{}; + + for (const auto& ticker : tickers) { - SPDLOG_INFO("current_coin: {} is a default coin", current_coin.ticker); - tickers.push_back(current_coin.ticker); + coins.push_back(get_coin_info(ticker)); } + coins.erase(std::unique(coins.begin(), coins.end(), [](auto left, auto right) { return left.ticker == right.ticker; }), coins.end()); // Remove duplicates + enable_coins(coins); + } - batch_enable_coins(tickers, true); + void mm2_service::enable_coins(const t_coins& coins) + { + t_coins other_coins; + t_coins erc_family_coins; + t_coins slp_coins; + t_coins slp_testnet_coins; + t_coins zhtlc_coins; + + for (const auto& coin_config : coins) + { + if (coin_config.currently_enabled) + { + SPDLOG_WARN("{} cannot be enabled because it already is or being enabled.", coin_config.ticker); + } + else if (coin_config.coin_type == CoinType::SLP || (coin_config.other_types && coin_config.other_types->contains(CoinType::SLP))) + { + if (coin_config.is_testnet.value_or(false)) + { + slp_testnet_coins.push_back(coin_config); + } + else + { + slp_coins.push_back(coin_config); + } + } + else if (coin_config.coin_type == CoinType::ZHTLC) + { + zhtlc_coins.push_back(coin_config); + } + else if (coin_config.is_erc_family) + { + erc_family_coins.push_back(coin_config); + } + else + { + other_coins.push_back(coin_config); + } + } + if (other_coins.size() > 0) + { + enable_utxo_qrc20_coins(other_coins); + } + if (erc_family_coins.size() > 0) + { + enable_erc_family_coins(erc_family_coins); + } + if (slp_coins.size() > 0) + { + enable_slp_coins(slp_coins); + } + if (slp_testnet_coins.size() > 0) + { + enable_slp_testnet_coins(slp_testnet_coins); + } + if (zhtlc_coins.size() > 0) + { + enable_zhtlc(zhtlc_coins); + } + } - batch_fetch_orders_and_swap(); + void mm2_service::enable_erc_family_coin(const coin_config& coin_config) + { + enable_erc_family_coins(t_coins{coin_config}); + } - return result.load() == 1; + void mm2_service::enable_erc_family_coins(const t_coins& coins) + { + nlohmann::json batch_array = nlohmann::json::array(); + auto callback = [this, coins](const web::http::http_response& resp) + { + try + { + auto answers = mm2::basic_batch_answer(resp); + + if (answers.count("error") == 0) + { + std::size_t idx = 0; + t_coins activated_coins; + t_coins failed_coins; + + for (auto&& answer : answers) + { + auto [res, error] = this->process_batch_enable_answer(answer); + if (!res) + { + SPDLOG_DEBUG( + "bad answer for: [{}] -> removing it from enabling, idx: {}, tickers size: {}, answers size: {}", coins[idx].ticker, idx, + coins.size(), answers.size()); + if (error.find("already initialized") != std::string::npos) + { + SPDLOG_INFO("{} {}: ", coins[idx].ticker, error); + activated_coins.push_back(std::move(coins[idx])); + } + else + { + failed_coins.push_back(std::move(coins[idx])); + this->dispatcher_.trigger(coins[idx].ticker, error); + SPDLOG_ERROR(error); + } + } + else + { + activated_coins.push_back(std::move(coins[idx])); + this->process_balance_answer(answer); + } + idx += 1; + } + std::vector tickers; + for (auto&& coin: activated_coins) + { + m_coins_informations[coin.ticker].currently_enabled = true; + tickers.push_back(coin.ticker); + fetch_single_balance(coin); + } + dispatcher_.trigger(tickers); + + std::vector failed_tickers; + for (auto&& coin: failed_coins) + { + 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) + { + t_enable_request request + { + .coin_name = coin_config.ticker, + .urls = coin_config.eth_family_urls.value_or(std::vector{}), + .coin_type = coin_config.coin_type, + .is_testnet = coin_config.is_testnet.value_or(false), + .with_tx_history = false + }; + nlohmann::json j = mm2::template_request("enable"); + + mm2::to_json(j, request); + batch_array.push_back(j); + } + m_mm2_client.async_rpc_batch_standalone(batch_array) + .then(callback) + .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) + { + 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) + { + auto batch_array = nlohmann::json::array(); + auto callback = [this, coins](const web::http::http_response& resp) + { + try + { + auto answers = mm2::basic_batch_answer(resp); + + if (answers.count("error") == 0) + { + std::size_t idx = 0; + t_coins activated_coins; + t_coins failed_coins; + + for (auto&& answer : answers) + { + auto [res, error] = this->process_batch_enable_answer(answer); + if (!res) + { + SPDLOG_DEBUG( + "bad answer for: [{}] -> removing it from enabling, idx: {}, tickers size: {}, answers size: {}", coins[idx].ticker, idx, + coins.size(), answers.size()); + if (error.find("already initialized") != std::string::npos) + { + SPDLOG_INFO("{} {}: ", coins[idx].ticker, error); + activated_coins.push_back(std::move(coins[idx])); + } + else + { + failed_coins.push_back(std::move(coins[idx])); + this->dispatcher_.trigger(coins[idx].ticker, error); + SPDLOG_ERROR(error); + } + } + else + { + this->process_balance_answer(answer); + activated_coins.push_back(std::move(coins[idx])); + } + idx += 1; + } + + std::vector tickers; + for (auto&& coin: activated_coins) + { + m_coins_informations[coin.ticker].currently_enabled = true; + tickers.push_back(coin.ticker); + fetch_single_balance(coin); + } + dispatcher_.trigger(tickers); + + std::vector failed_tickers; + for (auto&& coin: failed_coins) + { + 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) + { + nlohmann::json j = mm2::template_request("electrum"); + t_electrum_request request + { + .coin_name = coin_config.ticker, + .servers = coin_config.electrum_urls.value_or(get_electrum_server_from_token(coin_config.ticker)), + .coin_type = coin_config.coin_type, + .is_testnet = coin_config.is_testnet.value_or(false), + .with_tx_history = true + }; + + if (coin_config.segwit && coin_config.is_segwit_on) + { + request.address_format = nlohmann::json::object(); + request.address_format.value()["format"] = "segwit"; + } + if (coin_config.utxo_merge.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::to_json(json_merge_params, merge_params); + request.merge_params = json_merge_params; + } + mm2::to_json(j, request); + batch_array.push_back(j); + } + m_mm2_client.async_rpc_batch_standalone(batch_array) + .then(callback) + .then([this, batch_array](pplx::task previous_task) { this->handle_exception_pplx_task(previous_task, "enable_qrc_family_coins", batch_array); }); + } + + void mm2_service::enable_slp_coin(coin_config coin_config) + { + enable_slp_coins(t_coins{std::move(coin_config)}); + } + + void mm2_service::enable_slp_coins(const t_coins& coins) + { + constexpr auto bch_ticker = "BCH"; + auto callback = [this](RpcRequest rpc) + { + if (rpc.error) + { + 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)); + m_coins_informations[rpc.request.ticker].currently_enabled = true; + dispatcher_.trigger(coin_fully_initialized{.tickers = {rpc.request.ticker}}); + if constexpr (std::is_same_v) + { + for (const auto& slp_coin_info : rpc.request.slp_tokens_requests) + { + SPDLOG_ERROR("{} {}: ", slp_coin_info.ticker, rpc.error->error_type); + fetch_single_balance(get_coin_info(slp_coin_info.ticker)); + m_coins_informations[slp_coin_info.ticker].currently_enabled = true; + dispatcher_.trigger(coin_fully_initialized{.tickers = {slp_coin_info.ticker}}); + } + } + } + else + { + 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)); + m_coins_informations[rpc.request.ticker].currently_enabled = true; + if constexpr (std::is_same_v) + { + for (const auto& slp_address_info : rpc.result->slp_addresses_infos) + { + for (const auto& balance : slp_address_info.second.balances) + { + dispatcher_.trigger(coin_fully_initialized{.tickers = {balance.first}}); + process_balance_answer(rpc); + m_coins_informations[balance.first].currently_enabled = true; + } + } + } + process_balance_answer(rpc); + } + this->m_nb_update_required += 1; + }; + + if (!has_coin(bch_ticker)) + { + static constexpr auto error = "{} is not present in the config. Cannot enable SLP tokens."; + + SPDLOG_ERROR(error); + this->dispatcher_.trigger(bch_ticker, fmt::format(error, bch_ticker)); + return; + } + + auto bch_info = get_coin_info(bch_ticker); + + if (bch_info.currently_enabled) + { + for (const auto& coin_config : coins) + { + mm2::enable_slp_rpc rpc{.request={.ticker = coin_config.ticker}}; + + if (coin_config.ticker == bch_info.ticker) + { + continue; + } + m_mm2_client.process_rpc_async(rpc.request, callback); + } + } + else + { + mm2::enable_bch_with_tokens_rpc rpc; + + rpc.request.ticker = bch_info.ticker; + rpc.request.allow_slp_unsafe_conf = bch_info.allow_slp_unsafe_conf.has_value() && bch_info.allow_slp_unsafe_conf.value(); + rpc.request.bchd_urls = bch_info.bchd_urls.value_or(std::vector{}); + rpc.request.mode.rpc_data.servers = bch_info.electrum_urls.value_or(std::vector{}); + for (const auto& coin_config : coins) + { + if (coin_config.ticker == bch_info.ticker) + { + continue; + } + rpc.request.slp_tokens_requests.push_back({.ticker = coin_config.ticker}); + } + m_mm2_client.process_rpc_async(rpc.request, callback); + } + } + + + void mm2_service::enable_slp_testnet_coin(coin_config coin_config) + { + enable_slp_testnet_coins(t_coins{std::move(coin_config)}); + } + + void mm2_service::enable_slp_testnet_coins(const t_coins& coins) + { + constexpr auto bch_ticker = "tBCH"; + auto callback = [this](RpcRequest rpc) + { + if (rpc.error) + { + 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)); + m_coins_informations[rpc.request.ticker].currently_enabled = true; + dispatcher_.trigger(coin_fully_initialized{.tickers = {rpc.request.ticker}}); + if constexpr (std::is_same_v) + { + for (const auto& slp_coin_info : rpc.request.slp_tokens_requests) + { + SPDLOG_ERROR("{} {}: ", slp_coin_info.ticker, rpc.error->error_type); + fetch_single_balance(get_coin_info(slp_coin_info.ticker)); + m_coins_informations[slp_coin_info.ticker].currently_enabled = true; + dispatcher_.trigger(coin_fully_initialized{.tickers = {slp_coin_info.ticker}}); + } + } + } + else + { + 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)); + m_coins_informations[rpc.request.ticker].currently_enabled = true; + if constexpr (std::is_same_v) + { + for (const auto& slp_address_info : rpc.result->slp_addresses_infos) + { + for (const auto& balance : slp_address_info.second.balances) + { + dispatcher_.trigger(coin_fully_initialized{.tickers = {balance.first}}); + process_balance_answer(rpc); + m_coins_informations[balance.first].currently_enabled = true; + } + } + } + process_balance_answer(rpc); + } + this->m_nb_update_required += 1; + }; + + if (!has_coin(bch_ticker)) + { + static constexpr auto error = "tBCH is not present in the config. Cannot enable SLP tokens."; + + SPDLOG_ERROR(error); + this->dispatcher_.trigger("SLP tokens", error); + return; + } + + auto bch_info = get_coin_info(bch_ticker); + + if (bch_info.currently_enabled) + { + for (const auto& coin_config : coins) + { + mm2::enable_slp_rpc rpc{.request={.ticker = coin_config.ticker}}; + + if (coin_config.ticker == bch_info.ticker) + { + continue; + } + m_mm2_client.process_rpc_async(rpc.request, callback); + } + } + else + { + mm2::enable_bch_with_tokens_rpc rpc; + + rpc.request.ticker = bch_info.ticker; + rpc.request.allow_slp_unsafe_conf = bch_info.allow_slp_unsafe_conf.has_value() && bch_info.allow_slp_unsafe_conf.value(); + rpc.request.bchd_urls = bch_info.bchd_urls.value_or(std::vector{}); + rpc.request.mode.rpc_data.servers = bch_info.electrum_urls.value_or(std::vector{}); + for (const auto& coin_config : coins) + { + if (coin_config.ticker == bch_info.ticker) + { + continue; + } + rpc.request.slp_tokens_requests.push_back({.ticker = coin_config.ticker}); + } + m_mm2_client.process_rpc_async(rpc.request, callback); + } + } + + void mm2_service::process_balance_answer(const mm2::enable_slp_rpc& rpc) + { + const auto& answer = rpc.result.value(); + mm2::balance_answer balance_answer; + + balance_answer.address = answer.balances.begin()->first; + balance_answer.balance = answer.balances.begin()->second.spendable; + balance_answer.coin = answer.platform_coin; + + { + std::unique_lock lock(m_balance_mutex); + m_balance_informations[balance_answer.coin] = std::move(balance_answer); + } + } + + void mm2_service::process_balance_answer(const mm2::enable_bch_with_tokens_rpc& rpc) + { + const auto& answer = rpc.result.value(); + { + mm2::balance_answer balance_answer; + + balance_answer.coin = rpc.request.ticker; + balance_answer.balance = answer.bch_addresses_infos.begin()->second.balances.spendable; + balance_answer.address = answer.bch_addresses_infos.begin()->first; + { + std::unique_lock lock(m_balance_mutex); + m_balance_informations[balance_answer.coin] = std::move(balance_answer); + } + } + for (auto [address, data] : answer.slp_addresses_infos) + { + if (data.balances.empty()) + { + continue; + } + + mm2::balance_answer balance_answer; + + balance_answer.coin = data.balances.begin()->first; + balance_answer.address = address; + balance_answer.balance = data.balances.begin()->second.spendable; + + { + std::unique_lock lock(m_balance_mutex); + m_balance_informations[balance_answer.coin] = std::move(balance_answer); + } + } + } + void mm2_service::disable_multiple_coins(const std::vector& tickers) { - SPDLOG_DEBUG("disable_multiple_coins"); for (const auto& ticker: tickers) { std::error_code ec; @@ -472,28 +1027,39 @@ namespace atomic_dex auto mm2_service::batch_balance_and_tx(bool is_a_reset, std::vector tickers, bool is_during_enabling, bool only_tx) { - // SPDLOG_INFO("batch_balance_and_tx"); (void)tickers; (void)is_during_enabling; auto&& [batch_array, tickers_idx, tokens_to_fetch] = prepare_batch_balance_and_tx(only_tx); return m_mm2_client.async_rpc_batch_standalone(batch_array) .then( - [this, tokens_to_fetch = tokens_to_fetch, is_a_reset, tickers](web::http::http_response resp) + [this, tokens_to_fetch = tokens_to_fetch, is_a_reset, tickers, batch_array = batch_array](web::http::http_response resp) { try { - auto answers = ::mm2::api::basic_batch_answer(resp); + auto answers = mm2::basic_batch_answer(resp); if (not answers.contains("error")) { - for (auto&& answer: answers) + for (auto i = 0ul; i < answers.size(); i++) { + auto& answer = answers[i]; + std::string ticker; + + if (batch_array[i].contains("mmrpc") && batch_array[i].at("mmrpc") == "2.0") + { + ticker = batch_array[i].at("params").at("coin"); + } + else + { + ticker = batch_array[i].at("coin"); + } + if (answer.contains("balance")) { this->process_balance_answer(answer); } else if (answer.contains("result")) { - this->process_tx_answer(answer); + this->process_tx_answer(answer, ticker); } else { @@ -530,20 +1096,36 @@ namespace atomic_dex std::vector tokens_to_fetch; const auto& ticker = get_current_ticker(); auto coin_info = get_coin_info(ticker); - if (!coin_info.is_erc_family) + + if (coin_info.is_erc_family) { - t_tx_history_request request{.coin = ticker, .limit = 5000}; - nlohmann::json j = ::mm2::api::template_request("my_tx_history"); - ::mm2::api::to_json(j, request); - batch_array.push_back(j); + tokens_to_fetch.push_back(ticker); } else { - tokens_to_fetch.push_back(ticker); + std::string method = "my_tx_history"; + std::size_t limit = 5000; + bool requires_v2 = false; + if (coin_info.is_zhtlc_family) + { + requires_v2 = true; + limit = 50; + method = "z_coin_tx_history"; + } + else if (coin_info.coin_type == CoinTypeGadget::SLP || coin_info.ticker == "tBCH" || coin_info.ticker == "BCH") + { + requires_v2 = true; + } + + t_tx_history_request request{.coin = ticker, .limit = limit}; + nlohmann::json j = mm2::template_request(method, requires_v2); + mm2::to_json(j, request); + batch_array.push_back(j); } + if (not only_tx) { - for (auto&& coin: enabled_coins) + for (auto&& coin : enabled_coins) { if (is_pin_cfg_enabled()) { @@ -553,9 +1135,10 @@ namespace atomic_dex continue; } } + SPDLOG_WARN("Getting balance for {} ", coin.ticker); t_balance_request balance_request{.coin = coin.ticker}; - nlohmann::json j = ::mm2::api::template_request("my_balance"); - ::mm2::api::to_json(j, balance_request); + nlohmann::json j = mm2::template_request("my_balance"); + mm2::to_json(j, balance_request); batch_array.push_back(j); tickers_idx.push_back(coin.ticker); } @@ -567,10 +1150,11 @@ namespace atomic_dex mm2_service::process_batch_enable_answer(const json& answer) { std::string error = answer.dump(4); + std::string data = answer.dump(); if (answer.contains("error") || answer.contains("Error") || error.find("error") != std::string::npos || error.find("Error") != std::string::npos) { - SPDLOG_DEBUG("bad answer json for enable/electrum details: {}", error); + SPDLOG_DEBUG("error: bad answer json for enable/electrum details: {}", error); return {false, error}; } @@ -584,104 +1168,46 @@ namespace atomic_dex return {true, ""}; } - SPDLOG_DEBUG("bad answer json for enable/electrum details: {}", error); - return {false, error}; - } - - void - mm2_service::batch_enable_coins(const std::vector& tickers, bool first_time) - { - nlohmann::json btc_kmd_batch = nlohmann::json::array(); - if (first_time) + if (answer.contains("result")) { - coin_config coin_info = get_coin_info(g_second_primary_dex_coin); - t_electrum_request request{.coin_name = coin_info.ticker, .servers = coin_info.electrum_urls.value(), .with_tx_history = true}; - if (coin_info.segwit && coin_info.is_segwit_on) + if (answer["result"].contains("task_id")) { - request.address_format = nlohmann::json::object(); - request.address_format.value()["format"] = "segwit"; + return {true, ""}; } - nlohmann::json j = ::mm2::api::template_request("electrum"); - ::mm2::api::to_json(j, request); - btc_kmd_batch.push_back(j); - coin_info = get_coin_info(g_primary_dex_coin); - t_electrum_request request_kmd{.coin_name = coin_info.ticker, .servers = coin_info.electrum_urls.value(), .with_tx_history = true}; - j = ::mm2::api::template_request("electrum"); - ::mm2::api::to_json(j, request_kmd); - btc_kmd_batch.push_back(j); } + SPDLOG_DEBUG("bad answer json for enable/electrum details: {}", error); - nlohmann::json batch_array = nlohmann::json::array(); - - std::vector copy_tickers; - - for (const auto& ticker: tickers) - { - if (ticker == g_primary_dex_coin || ticker == g_second_primary_dex_coin) - continue; - copy_tickers.push_back(ticker); - coin_config coin_info = get_coin_info(ticker); - - if (coin_info.currently_enabled) - { - continue; - } + return {false, error}; + } - if (!coin_info.is_erc_family) - { - t_electrum_request request{ - .coin_name = coin_info.ticker, - .servers = coin_info.electrum_urls.value_or(get_electrum_server_from_token(coin_info.ticker)), - .coin_type = coin_info.coin_type, - .is_testnet = coin_info.is_testnet.value_or(false), - .with_tx_history = true}; - if (coin_info.segwit && coin_info.is_segwit_on) - { - request.address_format = nlohmann::json::object(); - request.address_format.value()["format"] = "segwit"; - } - nlohmann::json j = ::mm2::api::template_request("electrum"); - ::mm2::api::to_json(j, request); - batch_array.push_back(j); - } - else - { - t_enable_request request{ - .coin_name = coin_info.ticker, - .urls = coin_info.urls.value_or(std::vector{}), - .coin_type = coin_info.coin_type, - .is_testnet = coin_info.is_testnet.value_or(false), - .with_tx_history = false}; - nlohmann::json j = ::mm2::api::template_request("enable"); - ::mm2::api::to_json(j, request); - // SPDLOG_INFO("enable request: {}", j.dump(4)); - batch_array.push_back(j); - } - //! If the coin is a custom coin and not present, then we have a config mismatch, we re-add it to the mm2 coins cfg but this need a app restart. - if (coin_info.is_custom_coin && !this->is_this_ticker_present_in_raw_cfg(coin_info.ticker)) - { - nlohmann::json empty = "{}"_json; - if (coin_info.custom_backup.has_value()) - { - SPDLOG_WARN("Configuration mismatch between mm2 cfg and coin cfg for ticker {}, readjusting...", coin_info.ticker); - this->add_new_coin(empty, coin_info.custom_backup.value()); - this->dispatcher_.trigger(coin_info.ticker); - } - } - } + void mm2_service::enable_zhtlc(const t_coins& coins) + { + auto request_functor = [this](coin_config coin_info) -> std::pair> + { + t_init_z_coin_request request{ + .coin_name = coin_info.ticker, + .servers = coin_info.electrum_urls.value_or(get_electrum_server_from_token(coin_info.ticker)), + .z_urls = coin_info.z_urls.value_or(std::vector{}), + .coin_type = coin_info.coin_type, + .is_testnet = coin_info.is_testnet.value_or(false), + .with_tx_history = false}; // Tx history not yet ready for ZHTLC + + nlohmann::json j = mm2::template_request("init_z_coin", true); + mm2::to_json(j, request); + nlohmann::json batch = nlohmann::json::array(); + batch.push_back(j); + return {batch, {coin_info.ticker}}; + }; - // SPDLOG_DEBUG("{}", batch_array.dump(4)); - auto functor = [this](nlohmann::json batch_array, std::vector tickers) + auto answer_functor = [this](nlohmann::json batch, std::vector tickers) { - m_mm2_client.async_rpc_batch_standalone(batch_array) + m_mm2_client.async_rpc_batch_standalone(batch) .then( [this, tickers](web::http::http_response resp) mutable { try { - SPDLOG_DEBUG("Enabling coin finished"); - auto answers = ::mm2::api::basic_batch_answer(resp); - SPDLOG_DEBUG("Enabling coin parsed"); + auto answers = mm2::basic_batch_answer(resp); if (answers.count("error") == 0) { @@ -690,87 +1216,251 @@ namespace atomic_dex for (auto&& answer: answers) { auto [res, error] = this->process_batch_enable_answer(answer); + if (!res) { SPDLOG_DEBUG( "bad answer for: [{}] -> removing it from enabling, idx: {}, tickers size: {}, answers size: {}", tickers[idx], idx, tickers.size(), answers.size()); - this->dispatcher_.trigger(tickers[idx], error); - to_remove.emplace(tickers[idx]); - if (error.find("already initialized") == std::string::npos) + if (error.find("CoinIsAlreadyActivated") != std::string::npos) + { + SPDLOG_ERROR(error); + 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!"); + } + else { - SPDLOG_WARN("Should set to false the active field in cfg for: {} - reason: {}", tickers[idx], error); + SPDLOG_ERROR(error); + to_remove.emplace(tickers[idx]); + this->dispatcher_.trigger(tickers[idx], error); } } - idx += 1; - if (res) + else if (answer.contains("result")) { - this->process_balance_answer(answer); + if (answer["result"].contains("task_id")) + { + auto task_id = answer.at("result").at("task_id").get(); + { + using namespace std::chrono_literals; + + static std::size_t z_nb_try = 0; + nlohmann::json z_error = nlohmann::json::array(); + nlohmann::json z_batch_array = nlohmann::json::array(); + t_init_z_coin_status_request z_request{.task_id = task_id}; + + SPDLOG_DEBUG("{} init_z_coin Task ID: {}", tickers[idx], task_id); + + nlohmann::json j = mm2::template_request("init_z_coin_status", true); + mm2::to_json(j, z_request); + z_batch_array.push_back(j); + std::string last_event = "none"; + std::string event = "none"; + + do { + pplx::task z_resp_task = m_mm2_client.async_rpc_batch_standalone(z_batch_array); + web::http::http_response z_resp = z_resp_task.get(); + auto z_answers = mm2::basic_batch_answer(z_resp); + z_error = z_answers; + + std::string status = z_answers[0].at("result").at("status").get(); + + if (status == "Ready") + { + m_coins_informations[tickers[idx]].activation_status = z_answers[0]; + if (z_answers[0].at("result").at("details").contains("error")) + { + if (z_answers[0].at("result").at("details").at("error").contains("error_type")) + { + if (z_answers[0].at("result").at("details").at("error").at("error_type") == "CoinIsAlreadyActivated") + { + continue; + } + } + event = z_answers[0].at("result").at("details").at("error").get(); + SPDLOG_DEBUG("Enabling [{}] error: {}", tickers[idx], event); + break; + } + SPDLOG_DEBUG("{} activation complete!", tickers[idx]); + 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; + break; + } + else + { + // todo(syl): many unused variables. + // fix that + if (z_answers[0].at("result").at("details").contains("UpdatingBlocksCache")) + { + event = "UpdatingBlocksCache"; + } + else if (z_answers[0].at("result").at("details").contains("BuildingWalletDb")) + { + event = "BuildingWalletDb"; + } + else + { + event = z_answers[0].at("result").at("details").get(); + } + + if (event != last_event) + { + SPDLOG_DEBUG("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; + } + + // todo(syl): refactor to a background task + std::this_thread::sleep_for(2s); + } + m_coins_informations[tickers[idx]].activation_status = z_answers[0]; + z_nb_try += 1; + + } while (z_nb_try < 1000); + + try { + if (z_error[0].at("result").at("details").contains("error")) + { + std::string zhtlc_error = z_error[0].at("result").at("details").at("error").get(); + SPDLOG_DEBUG("Error enabling {}: {} ", tickers[idx], zhtlc_error); + SPDLOG_DEBUG( + "Removing zhtlc from enabling, idx: {}, tickers size: {}, answers size: {}", + tickers[idx], idx, tickers.size(), answers.size() + ); + + this->dispatcher_.trigger(tickers[idx], event); + this->dispatcher_.trigger(tickers[idx], z_error[0].dump(4)); + to_remove.emplace(tickers[idx]); + } + else if (z_nb_try == 1000) + { + // TODO: Handle this case. + // There could be no error message if scanning takes too long. + // Either we force disable here, or schedule to check on it later + // If this happens, address will be "Invalid" and balance will be zero. + // We could save this ticker in a list to try `init_z_coin_status` again on it periodically until complete. + + SPDLOG_DEBUG("Exited zhtlc enable loop after 1000 tries"); + SPDLOG_DEBUG( + "Bad answer for zhtlc_error: [{}] -> idx: {}, tickers size: {}, answers size: {}", tickers[idx], idx, + tickers.size(), answers.size() + ); + this->dispatcher_.trigger(tickers[idx], z_error[0].dump(4)); + update_coin_status(this->m_current_wallet_name, tickers, false, m_coins_informations, m_coin_cfg_mutex); + to_remove.emplace(tickers[idx]); + } + else + { + this->dispatcher_.trigger(tickers[idx], "Complete!"); + } + } + catch (const std::exception& error) + { + SPDLOG_ERROR("exception caught in zhtlc batch_enable_coins: {}", error.what()); + } + } + } } + idx += 1; } - for (auto&& t: to_remove) { tickers.erase(std::remove(tickers.begin(), tickers.end(), t), tickers.end()); } + if (!to_remove.empty()) + { + std::vector disable_coins; + for (auto&& t: to_remove) { + tickers.erase(std::remove(tickers.begin(), tickers.end(), t), tickers.end()); + disable_coins.push_back(t); + } + update_coin_status(this->m_current_wallet_name, disable_coins, false, m_coins_informations, m_coin_cfg_mutex); + } if (!tickers.empty()) { - if (tickers == g_default_coins) - { - SPDLOG_INFO("Trigger default_coins_enabled"); - this->dispatcher_.trigger(); - batch_balance_and_tx(false, tickers, true); - } dispatcher_.trigger(tickers); if (tickers.size() == 1) { fetch_single_balance(get_coin_info(tickers[0])); } - // batch_balance_and_tx(false, tickers, true); + this->m_nb_update_required += 1; } } } catch (const std::exception& error) { SPDLOG_ERROR("exception caught in batch_enable_coins: {}", error.what()); - // update_coin_status(this->m_current_wallet_name, tickers, false, m_coins_informations, m_coin_cfg_mutex); + update_coin_status(this->m_current_wallet_name, tickers, false, m_coins_informations, m_coin_cfg_mutex); //! Emit event here } }) .then( - [this, tickers, batch_array](pplx::task previous_task) + [this, tickers, batch](pplx::task previous_task) { - this->handle_exception_pplx_task(previous_task, "batch_enable_coins", batch_array); - // update_coin_status(this->m_current_wallet_name, tickers, false, m_coins_informations, m_coin_cfg_mutex); + 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; }; - SPDLOG_DEBUG("starting async enabling coin"); - - if (not btc_kmd_batch.empty() && first_time) + for (auto&& coin: coins) { - functor(btc_kmd_batch, g_default_coins); + auto&& [request, coins_to_enable] = request_functor(coin); + // SPDLOG_INFO("{} {}", request.dump(4), coins_to_enable[0]); + answer_functor(request, coins_to_enable); } + } - if (!batch_array.empty()) + nlohmann::json mm2_service::get_zhtlc_status(const std::string coin) const + { + const auto coin_info = get_coin_info(coin); + if (coin_info.is_zhtlc_family) { - for (std::size_t idx = 0; idx < batch_array.size(); ++idx) - { - nlohmann::json single_batch = nlohmann::json::array(); - single_batch.push_back(batch_array.at(idx)); - functor(single_batch, {copy_tickers[idx]}); - } - // functor(batch_array, copy_tickers); + return coin_info.activation_status; } + return {}; } - void - mm2_service::enable_multiple_coins(const std::vector& tickers) + bool mm2_service::is_zhtlc_coin_ready(const std::string coin) const { - batch_enable_coins(tickers); - update_coin_status(this->m_current_wallet_name, tickers, true, m_coins_informations, m_coin_cfg_mutex); + const auto coin_info = get_coin_info(coin); + if (coin_info.is_zhtlc_family) + { + if (coin_info.activation_status.contains("result")) + { + SPDLOG_DEBUG("coin_info.activation_status {} {} :", coin, coin_info.activation_status.dump(4)); + if (coin_info.activation_status.at("result").contains("status")) + { + if (coin_info.activation_status.at("result").at("status") == "Ready") + { + if (coin_info.activation_status.at("result").contains("details")) + { + if (!coin_info.activation_status.at("result").at("details").contains("error")) + { + return true; + } + } + } + } + } + return false; + } + return true; } - coin_config - mm2_service::get_coin_info(const std::string& ticker) const + coin_config 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()) @@ -779,9 +1469,18 @@ namespace atomic_dex } return m_coins_informations.at(ticker); } + + bool mm2_service::is_coin_enabled(const std::string& ticker) const + { + return m_coins_informations[ticker].currently_enabled; + } + + bool mm2_service::has_coin(const std::string& ticker) const + { + return m_coins_informations.contains(ticker); + } - t_orderbook_answer - mm2_service::get_orderbook(t_mm2_ec& ec) const + t_orderbook_answer mm2_service::get_orderbook(t_mm2_ec& ec) const { auto&& [base, rel] = this->m_synchronized_ticker_pair.get(); const std::string pair = base + "/" + rel; @@ -799,8 +1498,7 @@ namespace atomic_dex return orderbook; } - nlohmann::json - mm2_service::prepare_batch_orderbook(bool is_a_reset) + nlohmann::json mm2_service::prepare_batch_orderbook(bool is_a_reset) { // SPDLOG_INFO("is_a_reset: {}", is_a_reset); auto&& [base, rel] = m_synchronized_ticker_pair.get(); @@ -808,18 +1506,18 @@ namespace atomic_dex return nlohmann::json::array(); nlohmann::json batch = nlohmann::json::array(); - auto generate_req = [&batch](std::string request_name, auto request) + auto generate_req = [&batch](std::string request_name, auto request, bool is_v2=false) { - nlohmann::json current_request = ::mm2::api::template_request(std::move(request_name)); - ::mm2::api::to_json(current_request, request); + nlohmann::json current_request = mm2::template_request(std::move(request_name), is_v2); + mm2::to_json(current_request, request); batch.push_back(current_request); }; - generate_req("orderbook", t_orderbook_request{.base = base, .rel = rel}); + generate_req("orderbook", t_orderbook_request{.base = base, .rel = rel}, true); if (is_a_reset) { - generate_req("max_taker_vol", ::mm2::api::max_taker_vol_request{.coin = base}); - generate_req("max_taker_vol", ::mm2::api::max_taker_vol_request{.coin = rel}); + 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}); } @@ -827,55 +1525,60 @@ namespace atomic_dex return batch; } - void - mm2_service::process_orderbook(bool is_a_reset) + void mm2_service::process_orderbook(bool is_a_reset) { auto batch = prepare_batch_orderbook(is_a_reset); if (batch.empty()) return; - // SPDLOG_DEBUG("batch request: {}", batch.dump(4)); - // auto&& [base, rel] = m_synchronized_ticker_pair.get(); auto answer_functor = [this, is_a_reset](web::http::http_response resp) { auto&& [base, rel] = m_synchronized_ticker_pair.get(); - auto answer = ::mm2::api::basic_batch_answer(resp); + auto answer = mm2::basic_batch_answer(resp); if (answer.is_array()) { - auto orderbook_answer = ::mm2::api::rpc_process_answer_batch(answer[0], "orderbook"); + if (answer.size() < 1) + { + SPDLOG_ERROR("Answer array did not contain enough elements"); + return; + } + + auto orderbook_answer = mm2::rpc_process_answer_batch(answer[0], "orderbook"); if (is_a_reset) { - auto base_max_taker_vol_answer = ::mm2::api::rpc_process_answer_batch<::mm2::api::max_taker_vol_answer>(answer[1], "max_taker_vol"); + if (answer.size() < 5) + { + 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"); if (base_max_taker_vol_answer.rpc_result_code == 200) { if (base == base_max_taker_vol_answer.result->coin) { this->m_synchronized_max_taker_vol->first = base_max_taker_vol_answer.result.value(); } - // t_float_50 base_res = t_float_50(this->m_synchronized_max_taker_vol->first.decimal) * m_balance_factor; - // this->m_synchronized_max_taker_vol->first.decimal = base_res.str(8); - // SPDLOG_INFO("max_taker_vol: {}", answer[1].dump(4)); } - auto rel_max_taker_vol_answer = ::mm2::api::rpc_process_answer_batch<::mm2::api::max_taker_vol_answer>(answer[2], "max_taker_vol"); + auto rel_max_taker_vol_answer = mm2::rpc_process_answer_batch(answer[2], "max_taker_vol"); if (rel_max_taker_vol_answer.rpc_result_code == 200) { if (rel == rel_max_taker_vol_answer.result->coin) { this->m_synchronized_max_taker_vol->second = rel_max_taker_vol_answer.result.value(); } - // t_float_50 rel_res = t_float_50(this->m_synchronized_max_taker_vol->second.decimal) * - // m_balance_factor; this->m_synchronized_max_taker_vol->second.decimal = rel_res.str(8); } - auto base_min_taker_vol_answer = ::mm2::api::rpc_process_answer_batch(answer[3], "min_trading_vol"); + auto base_min_taker_vol_answer = mm2::rpc_process_answer_batch(answer[3], "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::api::rpc_process_answer_batch(answer[4], "min_trading_vol"); + auto rel_min_taker_vol_answer = mm2::rpc_process_answer_batch(answer[4], "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(); @@ -895,8 +1598,7 @@ namespace atomic_dex .then([this, batch](pplx::task previous_task) { this->handle_exception_pplx_task(previous_task, "process_orderbook", batch); }); } - void - mm2_service::fetch_current_orderbook_thread(bool is_a_reset) + 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"); @@ -909,8 +1611,7 @@ namespace atomic_dex 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& cfg_infos) { nlohmann::json batch_array = nlohmann::json::array(); if (is_pin_cfg_enabled()) @@ -921,15 +1622,17 @@ namespace atomic_dex return; } } + t_balance_request balance_request{.coin = cfg_infos.ticker}; - nlohmann::json j = ::mm2::api::template_request("my_balance"); - ::mm2::api::to_json(j, balance_request); + nlohmann::json j = mm2::template_request("my_balance"); + mm2::to_json(j, balance_request); batch_array.push_back(j); + auto answer_functor = [this](web::http::http_response resp) { try { - auto answers = ::mm2::api::basic_batch_answer(resp); + auto answers = mm2::basic_batch_answer(resp); if (!answers.contains("error") && !answers[0].contains("error")) { this->process_balance_answer(answers[0]); @@ -940,6 +1643,7 @@ namespace atomic_dex SPDLOG_ERROR("exception in fetch_single_balance: {}", error.what()); } }; + auto error_functor = [this, batch = batch_array](pplx::task previous_task) { this->handle_exception_pplx_task(previous_task, "fetch_single_balance", batch); }; m_mm2_client.async_rpc_batch_standalone(batch_array).then(answer_functor).then(error_functor); @@ -948,7 +1652,6 @@ namespace atomic_dex void mm2_service::fetch_infos_thread(bool is_a_refresh, bool only_tx) { - SPDLOG_INFO("fetch_infos_thread"); if (only_tx) { batch_balance_and_tx(is_a_refresh, {}, false, only_tx); @@ -961,23 +1664,22 @@ namespace atomic_dex } } - void - mm2_service::spawn_mm2_instance(std::string wallet_name, std::string passphrase, bool with_pin_cfg) + void mm2_service::spawn_mm2_instance(std::string wallet_name, std::string passphrase, bool with_pin_cfg) { this->m_balance_factor = utils::determine_balance_factor(with_pin_cfg); SPDLOG_DEBUG("balance factor is: {}", m_balance_factor); - SPDLOG_DEBUG("{} l{} f[{}]", __FUNCTION__, __LINE__, fs::path(__FILE__).filename().string()); + SPDLOG_DEBUG("{} l{} f[{}]", __FUNCTION__, __LINE__, std::filesystem::path(__FILE__).filename().string()); this->m_current_wallet_name = std::move(wallet_name); this->dispatcher_.trigger(this->retrieve_coins_informations()); this->dispatcher_.trigger(); mm2_config cfg{.passphrase = std::move(passphrase), .rpc_password = atomic_dex::gen_random_password()}; - ::mm2::api::set_system_manager(m_system_manager); - ::mm2::api::set_rpc_password(cfg.rpc_password); + mm2::set_system_manager(m_system_manager); + mm2::set_rpc_password(cfg.rpc_password); json json_cfg; const auto tools_path = ag::core::assets_real_path() / "tools/mm2/"; nlohmann::to_json(json_cfg, cfg); - fs::path mm2_cfg_path = (fs::temp_directory_path() / "MM2.json"); + std::filesystem::path mm2_cfg_path = (std::filesystem::temp_directory_path() / "MM2.json"); QFile ofs; ofs.setFileName(std_path_to_qstring(mm2_cfg_path)); @@ -990,7 +1692,7 @@ namespace atomic_dex env.insert("MM_LOG", std_path_to_qstring(utils::get_mm2_atomic_dex_current_log_file())); env.insert("MM_COINS_PATH", std_path_to_qstring((utils::get_current_configs_path() / "coins.json"))); QProcess mm2_instance; - mm2_instance.setProgram(std_path_to_qstring((tools_path / "mm2"))); + mm2_instance.setProgram(std_path_to_qstring((tools_path / atomic_dex::g_dex_api))); mm2_instance.setWorkingDirectory(std_path_to_qstring(tools_path)); mm2_instance.setProcessEnvironment(env); bool started = mm2_instance.startDetached(); @@ -1006,7 +1708,7 @@ namespace atomic_dex { // std::this_thread:: using namespace std::chrono_literals; - auto check_mm2_alive = []() { return ::mm2::api::rpc_version() != "error occured during rpc_version"; }; + auto check_mm2_alive = []() { return mm2::rpc_version() != "error occured during rpc_version"; }; static std::size_t nb_try = 0; while (not check_mm2_alive()) @@ -1016,14 +1718,14 @@ namespace atomic_dex { SPDLOG_ERROR("MM2 not started correctly"); //! TODO: emit mm2_failed_initialization - fs::remove(mm2_cfg_path); + std::filesystem::remove(mm2_cfg_path); return; } std::this_thread::sleep_for(1s); } // m_mm2_client.connect_client(); - fs::remove(mm2_cfg_path); + std::filesystem::remove(mm2_cfg_path); SPDLOG_INFO("mm2 is initialized"); dispatcher_.trigger(); enable_default_coins(); @@ -1086,7 +1788,7 @@ namespace atomic_dex mm2_service::batch_fetch_orders_and_swap(bool after_manual_reset) { nlohmann::json batch = nlohmann::json::array(); - nlohmann::json my_orders_request = ::mm2::api::template_request("my_orders"); + nlohmann::json my_orders_request = mm2::template_request("my_orders"); batch.push_back(my_orders_request); @@ -1106,7 +1808,7 @@ namespace atomic_dex } //! First time fetch or current page - nlohmann::json my_swaps = ::mm2::api::template_request("my_recent_swaps"); + nlohmann::json my_swaps = mm2::template_request("my_recent_swaps"); t_my_recent_swaps_request request{ .limit = limit, .page_number = current_page, @@ -1119,7 +1821,7 @@ namespace atomic_dex batch.push_back(my_swaps); //! Active swaps - nlohmann::json active_swaps = ::mm2::api::template_request("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); @@ -1130,12 +1832,12 @@ namespace atomic_dex //! Parsing Resp orders_and_swaps result; - auto answers = ::mm2::api::basic_batch_answer(resp); + auto answers = mm2::basic_batch_answer(resp); //! Extract - const auto orders_answers = ::mm2::api::rpc_process_answer_batch(answers[0], "my_orders"); - const auto swap_answer = ::mm2::api::rpc_process_answer_batch(answers[1], "my_recent_swaps"); - const auto active_swaps_answer = ::mm2::api::rpc_process_answer_batch(answers[2], "active_swaps"); + const auto orders_answers = mm2::rpc_process_answer_batch(answers[0], "my_orders"); + const auto swap_answer = mm2::rpc_process_answer_batch(answers[1], "my_recent_swaps"); + const auto active_swaps_answer = mm2::rpc_process_answer_batch(answers[2], "active_swaps"); result.orders_and_swaps.reserve(orders_answers.orders.size() + limit); result.nb_orders = orders_answers.orders.size(); @@ -1196,10 +1898,9 @@ namespace atomic_dex .then([this, batch](pplx::task previous_task) { this->handle_exception_pplx_task(previous_task, "batch_fetch_orders_and_swap", batch); }); } - void - mm2_service::process_tx_tokenscan(const std::string& ticker, [[maybe_unused]] bool is_a_refresh) + void mm2_service::process_tx_tokenscan(const std::string& ticker, [[maybe_unused]] bool is_a_refresh) { - SPDLOG_DEBUG("process_tx ticker: {}", ticker); + SPDLOG_DEBUG("Process transactions of ticker: {}", ticker); std::error_code ec; using namespace std::string_literals; auto construct_url_functor = [this]( @@ -1271,16 +1972,16 @@ namespace atomic_dex }; std::string url = retrieve_api_functor(ticker, address(ticker, ec)); SPDLOG_INFO("url scan: {}", url); - ::mm2::api::async_process_rpc_get(::mm2::api::g_etherscan_proxy_http_client, "tx_history", url) + mm2::async_process_rpc_get(mm2::g_etherscan_proxy_http_client, "tx_history", url) .then( - [this, ticker](web::http::http_response resp) + [this, ticker](const web::http::http_response& resp) { - auto answer = m_mm2_client.rpc_process_answer<::mm2::api::tx_history_answer>(resp, "tx_history"); + auto answer = m_mm2_client.rpc_process_answer(resp, "tx_history"); if (answer.rpc_result_code != 200) { SPDLOG_ERROR("{}", answer.raw_result); - this->dispatcher_.trigger(); + this->dispatcher_.trigger(true, ticker); } else if (answer.rpc_result_code not_eq -1 and answer.result.has_value()) { @@ -1319,6 +2020,8 @@ namespace atomic_dex .timestamp = current.timestamp, .tx_hash = current.tx_hash, .fees = current.fee_details.normal_fees.has_value() ? current.fee_details.normal_fees.value().amount + : current.fee_details.qrc_fees.has_value() + ? current.fee_details.qrc_fees.value().miner_fee : current.fee_details.erc_fees.value().total_fee, .my_balance_change = current.my_balance_change, .total_amount = current.total_amount, @@ -1336,13 +2039,12 @@ namespace atomic_dex m_tx_informations->insert_or_assign(ticker, std::make_pair(out, state)); //! Dispatch - this->dispatcher_.trigger(); + this->dispatcher_.trigger(false, ticker); } }) .then( [this](pplx::task previous_task) { - this->dispatcher_.trigger(); this->handle_exception_pplx_task(previous_task, "process_tx_tokenscan", {}); }); } @@ -1357,7 +2059,7 @@ namespace atomic_dex if (this->m_mm2_running) { - SPDLOG_INFO("process_orderbook(true)"); + SPDLOG_DEBUG("process_orderbook(true)"); process_orderbook(true); } } @@ -1365,7 +2067,7 @@ namespace atomic_dex void mm2_service::on_gui_enter_trading([[maybe_unused]] const gui_enter_trading& evt) { - SPDLOG_DEBUG("{} l{} f[{}]", __FUNCTION__, __LINE__, fs::path(__FILE__).filename().string()); + SPDLOG_DEBUG("{} l{} f[{}]", __FUNCTION__, __LINE__, std::filesystem::path(__FILE__).filename().string()); m_orderbook_thread_active = true; } @@ -1373,7 +2075,7 @@ namespace atomic_dex void mm2_service::on_gui_leave_trading([[maybe_unused]] const gui_leave_trading& evt) { - SPDLOG_DEBUG("{} l{} f[{}]", __FUNCTION__, __LINE__, fs::path(__FILE__).filename().string()); + SPDLOG_DEBUG("{} l{} f[{}]", __FUNCTION__, __LINE__, std::filesystem::path(__FILE__).filename().string()); m_orderbook_thread_active = false; } @@ -1393,7 +2095,8 @@ namespace atomic_dex if (it == m_balance_informations.cend()) { ec = dextop_error::unknown_ticker; - return "Invalid"; + SPDLOG_INFO("Invalid Ticker {}", ticker); + return "Invalid Ticker"; } return it->second.address; @@ -1472,10 +2175,10 @@ namespace atomic_dex } void - mm2_service::process_tx_answer(const nlohmann::json& answer_json) + mm2_service::process_tx_answer(const nlohmann::json& answer_json, std::string ticker) { - ::mm2::api::tx_history_answer answer; - ::mm2::api::from_json(answer_json, answer); + mm2::tx_history_answer answer; + mm2::from_json(answer_json, answer); t_tx_state state; state.state = answer.result.value().sync_status.state; state.current_block = answer.result.value().current_block; @@ -1493,7 +2196,6 @@ namespace atomic_dex state.transactions_left = answer.result.value().sync_status.additional_info.value().regular_infos.value().transactions_left; } } - t_transactions out; out.reserve(answer.result.value().transactions.size()); @@ -1525,7 +2227,10 @@ namespace atomic_dex { current_info.fees = current.fee_details.qrc_fees->miner_fee; } - + else if (current.transaction_fee.has_value()) + { + current_info.fees = current.transaction_fee.value(); + } if (current_info.timestamp == 0) { using namespace std::chrono; @@ -1540,18 +2245,18 @@ namespace atomic_dex out.push_back(std::move(current_info)); } - //! History m_tx_informations->insert_or_assign("result", std::make_pair(out, state)); - this->dispatcher_.trigger(); + this->dispatcher_.trigger(false, std::move(ticker)); } + void mm2_service::process_balance_answer(const nlohmann::json& answer) { t_balance_answer answer_r; - ::mm2::api::from_json(answer, answer_r); - // SPDLOG_INFO("Successfully fetched ticker: {} balance: {} address: {}", answer_r.coin, answer_r.balance, answer_r.address); + + mm2::from_json(answer, answer_r); if (is_pin_cfg_enabled()) { std::shared_lock lock(m_balance_mutex); @@ -1561,19 +2266,16 @@ namespace atomic_dex return; } } - t_float_50 result = t_float_50(answer_r.balance) * m_balance_factor; answer_r.balance = result.str(8, std::ios_base::fixed); - // auto copy_coin = answer_r.coin; + { std::unique_lock lock(m_balance_mutex); m_balance_informations[answer_r.coin] = std::move(answer_r); } - // m_system_manager.get_system().get_portfolio()->update_balance_values({copy_coin}); } - mm2_client& - mm2_service::get_mm2_client() + mm2::mm2_client& mm2_service::get_mm2_client() { return m_mm2_client; } @@ -1603,22 +2305,12 @@ namespace atomic_dex if (not coin_cfg_json.empty() && not is_this_ticker_present_in_normal_cfg(coin_cfg_json.begin().key())) { SPDLOG_DEBUG("Adding entry : {} to adex current wallet coins file", coin_cfg_json.dump(4)); - fs::path cfg_path = utils::get_atomic_dex_config_folder(); - std::string filename = "custom-tokens." + m_current_wallet_name + ".json"; + std::filesystem::path cfg_path = utils::get_atomic_dex_config_folder(); + std::string filename = "custom-tokens." + m_current_wallet_name + ".json"; fs::path file_path = cfg_path / filename; - nlohmann::json config_json_data; - if (fs::exists(file_path)) - { - SPDLOG_DEBUG("reading contents of custom tokens cfg"); - QFile ifs; - ifs.setFileName(std_path_to_qstring(file_path)); - ifs.open(QIODevice::Text | QIODevice::ReadOnly); - - //! Read Contents - config_json_data = nlohmann::json::parse(QString(ifs.readAll()).toStdString()); - ifs.close(); - } + SPDLOG_DEBUG("reading contents of custom tokens cfg"); + nlohmann::json config_json_data = atomic_dex::utils::read_json_file(file_path); //! Modify contents config_json_data[coin_cfg_json.begin().key()] = coin_cfg_json.at(coin_cfg_json.begin().key()); @@ -1632,15 +2324,13 @@ namespace atomic_dex } if (not raw_coin_cfg_json.empty() && not is_this_ticker_present_in_raw_cfg(raw_coin_cfg_json.at("coin").get())) { - const fs::path mm2_cfg_path{atomic_dex::utils::get_current_configs_path() / "coins.json"}; - SPDLOG_DEBUG("Adding entry : {} to mm2 coins file {}", raw_coin_cfg_json.dump(4), mm2_cfg_path.string()); + const fs::path coins_json_path{atomic_dex::utils::get_current_configs_path() / "coins.json"}; + SPDLOG_DEBUG("Adding entry : {} to mm2 coins file {}", raw_coin_cfg_json.dump(4), coins_json_path.string()); QFile ifs; - ifs.setFileName(std_path_to_qstring(mm2_cfg_path)); + ifs.setFileName(std_path_to_qstring(coins_json_path)); ifs.open(QIODevice::ReadOnly | QIODevice::Text); - nlohmann::json config_json_data; - //! Read Contents - config_json_data = nlohmann::json::parse(QString(ifs.readAll()).toStdString()); + nlohmann::json config_json_data = atomic_dex::utils::read_json_file(coins_json_path); //! Modify contents config_json_data.push_back(raw_coin_cfg_json); @@ -1650,7 +2340,7 @@ namespace atomic_dex //! Write contents QFile ofs; - ofs.setFileName(std_path_to_qstring(mm2_cfg_path)); + ofs.setFileName(std_path_to_qstring(coins_json_path)); ofs.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); ofs.write(QString::fromStdString(config_json_data.dump()).toUtf8()); ofs.close(); @@ -1681,27 +2371,18 @@ namespace atomic_dex if (is_this_ticker_present_in_normal_cfg(ticker)) { SPDLOG_DEBUG("remove it from custom cfg: {}", ticker); - fs::path cfg_path = utils::get_atomic_dex_config_folder(); + std::filesystem::path cfg_path = utils::get_atomic_dex_config_folder(); std::string filename = "custom-tokens." + m_current_wallet_name + ".json"; - QFile ifs; - ifs.setFileName(std_path_to_qstring((cfg_path / filename))); - ifs.open(QIODevice::ReadOnly | QIODevice::Text); - nlohmann::json config_json_data; - - //! Read Contents - config_json_data = nlohmann::json::parse(QString(ifs.readAll()).toStdString()); + SPDLOG_DEBUG("reading contents of custom tokens cfg"); + nlohmann::json config_json_data = atomic_dex::utils::read_json_file(cfg_path / filename); { std::unique_lock lock(m_coin_cfg_mutex); this->m_coins_informations.erase(ticker); } - config_json_data.erase(config_json_data.find(ticker)); - //! Close - ifs.close(); - //! Write contents QFile ofs; ofs.setFileName(std_path_to_qstring((cfg_path / filename))); @@ -1713,9 +2394,9 @@ namespace atomic_dex if (is_this_ticker_present_in_raw_cfg(ticker)) { SPDLOG_DEBUG("remove it from mm2 cfg: {}", ticker); - fs::path mm2_cfg_path{atomic_dex::utils::get_current_configs_path() / "coins.json"}; + fs::path coins_json_path{atomic_dex::utils::get_current_configs_path() / "coins.json"}; QFile ifs; - ifs.setFileName(std_path_to_qstring(mm2_cfg_path)); + ifs.setFileName(std_path_to_qstring(coins_json_path)); ifs.open(QIODevice::ReadOnly | QIODevice::Text); nlohmann::json config_json_data; @@ -1731,7 +2412,7 @@ namespace atomic_dex //! Write contents QFile ofs; - ofs.setFileName(std_path_to_qstring(mm2_cfg_path)); + ofs.setFileName(std_path_to_qstring(coins_json_path)); ofs.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); ofs.write(QString::fromStdString(config_json_data.dump()).toUtf8()); ofs.close(); @@ -1789,11 +2470,7 @@ namespace atomic_dex } for (auto&& cur: request) cur["userpass"] = ""; SPDLOG_ERROR("pplx task error: {} from: {}, request: {}", e.what(), from, request.dump(4)); - // this->dispatcher_.trigger(from, e.what()); - //#if defined(linux) || defined(__APPLE__) - // SPDLOG_ERROR("stacktrace: {}", boost::stacktrace::to_string(boost::stacktrace::stacktrace())); - //#endif if (std::string(e.what()).find("Failed to read HTTP status line") != std::string::npos || std::string(e.what()).find("WinHttpReceiveResponse: 12002: The operation timed out") != std::string::npos) { @@ -1807,9 +2484,8 @@ namespace atomic_dex } } - void - mm2_service::change_segwit_status(std::string ticker, bool status) + void mm2_service::change_segwit_status(std::string ticker, bool status) { update_coin_status(this->m_current_wallet_name, {ticker}, status, m_coins_informations, m_coin_cfg_mutex, "is_segwit_on"); } -} // namespace atomic_dex +} // namespace atomic_dex \ No newline at end of file diff --git a/src/core/atomicdex/services/mm2/mm2.service.hpp b/src/core/atomicdex/services/mm2/mm2.service.hpp index 654a4b7fbd..9b998f044d 100644 --- a/src/core/atomicdex/services/mm2/mm2.service.hpp +++ b/src/core/atomicdex/services/mm2/mm2.service.hpp @@ -1,36 +1,32 @@ /****************************************************************************** - * 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. * - * * - ******************************************************************************/ +* Copyright © 2013-2022 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 -//! Qt -#include - #include #include #include +#include -//! Deps +#include #include #include #include #include -//#include -//! Project Headers #include "atomicdex/api/mm2/mm2.client.hpp" #include "atomicdex/api/mm2/mm2.constants.hpp" #include "atomicdex/api/mm2/mm2.error.code.hpp" @@ -39,7 +35,8 @@ #include "atomicdex/api/mm2/rpc.max.taker.vol.hpp" #include "atomicdex/api/mm2/rpc.min.volume.hpp" #include "atomicdex/api/mm2/rpc.orderbook.hpp" -#include "atomicdex/config/coins.cfg.hpp" +#include "atomicdex/api/mm2/enable_bch_with_tokens_rpc.hpp" +#include "atomicdex/api/mm2/enable_slp_rpc.hpp" #include "atomicdex/config/raw.mm2.coins.cfg.hpp" #include "atomicdex/constants/dex.constants.hpp" #include "atomicdex/data/dex/orders.and.swaps.data.hpp" @@ -49,220 +46,232 @@ namespace atomic_dex { - namespace bm = boost::multiprecision; - namespace ag = antara::gaming; - - template - 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; - - //! Constants - inline constexpr const std::size_t g_tx_max_limit{50}; - - class ENTT_API mm2_service final : public ag::ecs::pre_update_system - { - public: - using t_pair_max_vol = std::pair; - using t_pair_min_vol = std::pair; - - private: - //! Private typedefs - 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_orders_and_swaps = boost::synchronized_value; - using t_synchronized_ticker_pair = boost::synchronized_value>; - using t_synchronized_max_taker_vol = boost::synchronized_value; - using t_synchronized_min_taker_vol = boost::synchronized_value; - using t_synchronized_ticker = boost::synchronized_value; - - ag::ecs::system_manager& m_system_manager; - - //! Client - // std::shared_ptr m_mm2_client{nullptr}; - // pplx::cancellation_token_source m_token_source; - mm2_client m_mm2_client; - - //! Process - //reproc::process m_mm2_instance; - - //! Current ticker - t_synchronized_ticker m_current_ticker{g_primary_dex_coin}; - - //! Current orderbook - t_synchronized_ticker_pair m_synchronized_ticker_pair{std::make_pair(g_primary_dex_coin, g_second_primary_dex_coin)}; - t_synchronized_max_taker_vol m_synchronized_max_taker_vol; - t_synchronized_min_taker_vol m_synchronized_min_taker_vol; - - //! Timers - t_mm2_time_point m_orderbook_clock; - t_mm2_time_point m_info_clock; - - //! Atomicity / Threads - std::atomic_bool m_mm2_running{false}; - std::atomic_bool m_orderbook_thread_active{false}; - std::thread m_mm2_init_thread; - - //! Current wallet name - std::string m_current_wallet_name; - - //! 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; - - //! Concurrent Registry. - 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_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()}; - - //! Balance factor - double m_balance_factor{1.0}; - - //! Refresh the orderbook registry (internal) - nlohmann::json prepare_batch_orderbook(bool is_a_reset); - - //! Batch balance / tx - std::tuple, std::vector> prepare_batch_balance_and_tx(bool only_tx = false) const; - auto batch_balance_and_tx(bool is_a_reset, std::vector tickers = {}, bool is_during_enabling = false, bool only_tx = false); - void process_balance_answer(const nlohmann::json& answer); - void process_tx_answer(const nlohmann::json& answer_json); - void process_tx_tokenscan(const std::string& ticker, bool is_a_refresh); - void fetch_single_balance(const coin_config& 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(); - - void handle_exception_pplx_task(pplx::task previous_task, const std::string& from, nlohmann::json batch); - - public: - //! Constructor - explicit mm2_service(entt::registry& registry, ag::ecs::system_manager& system_manager); - - //! Delete useless operator - mm2_service(const mm2_service& other) = delete; - mm2_service(const mm2_service&& other) = delete; - mm2_service& operator=(const mm2_service& other) = delete; - mm2_service& operator=(const mm2_service&& other) = delete; - - //! Destructor - ~mm2_service() final; - - //! Events - void on_refresh_orderbook(const orderbook_refresh& evt); - - void on_gui_enter_trading(const gui_enter_trading& evt); - - void on_gui_leave_trading(const gui_leave_trading& evt); - - //! Spawn mm2 instance with given seed - void spawn_mm2_instance(std::string wallet_name, std::string passphrase, bool with_pin_cfg = false); - - //! Refresh the current info (internally call process_balance and process_tx) - void fetch_infos_thread(bool is_a_fresh = true, bool only_tx = false); - - //! Enable coins - bool enable_default_coins(); - - //! Batch Enable coins - void batch_enable_coins(const std::vector& tickers, bool first_time = false); - - //! Enable multiple coins - void enable_multiple_coins(const std::vector& tickers); - - //! 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); - [[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; - - //! Disable a single coin - bool disable_coin(const std::string& ticker, std::error_code& ec); - - //! Disable multiple coins, prefer this function if you want persistent disabling - void disable_multiple_coins(const std::vector& tickers); - - //! Called every ticks, and execute tasks if the timer expire. - void update() final; - - //! Retrieve public address of the given ticker - std::string address(const std::string& ticker, t_mm2_ec& ec) const; + namespace bm = boost::multiprecision; + namespace ag = antara::gaming; + + template + 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; + + class ENTT_API mm2_service final : public ag::ecs::pre_update_system + { + public: + using t_pair_max_vol = std::pair; + using t_pair_min_vol = std::pair; + + private: + 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_orders_and_swaps = boost::synchronized_value; + using t_synchronized_ticker_pair = boost::synchronized_value>; + using t_synchronized_max_taker_vol = boost::synchronized_value; + using t_synchronized_min_taker_vol = boost::synchronized_value; + using t_synchronized_ticker = boost::synchronized_value; + + ag::ecs::system_manager& m_system_manager; + + mm2::mm2_client m_mm2_client; + + //! Current ticker + t_synchronized_ticker m_current_ticker{g_primary_dex_coin}; + + //! Current orderbook + t_synchronized_ticker_pair m_synchronized_ticker_pair{std::make_pair(g_primary_dex_coin, g_second_primary_dex_coin)}; + t_synchronized_max_taker_vol m_synchronized_max_taker_vol; + t_synchronized_min_taker_vol m_synchronized_min_taker_vol; + + //! Timers + t_mm2_time_point m_orderbook_clock; + t_mm2_time_point m_info_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::thread m_mm2_init_thread; + + //! Current wallet name + std::string m_current_wallet_name; + + //! 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; + + //! Concurrent Registry. + 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_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()}; + + //! Balance factor + double m_balance_factor{1.0}; + + //! Refresh the orderbook registry (internal) + nlohmann::json prepare_batch_orderbook(bool is_a_reset); + + //! Batch balance / tx + std::tuple, std::vector> prepare_batch_balance_and_tx(bool only_tx = false) const; + auto batch_balance_and_tx(bool is_a_reset, std::vector tickers = {}, bool is_during_enabling = false, bool only_tx = false); + 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); + + //! + 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(); + + void handle_exception_pplx_task(pplx::task previous_task, const std::string& from, nlohmann::json batch); + + public: + //! Constructor + explicit mm2_service(entt::registry& registry, ag::ecs::system_manager& system_manager); + + //! Delete useless operator + mm2_service(const mm2_service& other) = delete; + mm2_service(const mm2_service&& other) = delete; + mm2_service& operator=(const mm2_service& other) = delete; + mm2_service& operator=(const mm2_service&& other) = delete; + + //! Destructor + ~mm2_service() final; + + //! Events + void on_refresh_orderbook(const orderbook_refresh& evt); + + void on_gui_enter_trading(const gui_enter_trading& evt); + + void on_gui_leave_trading(const gui_leave_trading& evt); + + //! Spawn mm2 instance with given seed + void spawn_mm2_instance(std::string wallet_name, std::string passphrase, bool with_pin_cfg = false); + + //! Refresh the current info (internally call process_balance and process_tx) + void fetch_infos_thread(bool is_a_fresh = true, bool only_tx = false); + + // Coins enabling functions + bool enable_default_coins(); // Enables required coins + coins enabled in the config + 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); + 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_coins(const t_coins& coins); + void enable_utxo_qrc20_coin(coin_config coin_config); + void enable_utxo_qrc20_coins(const t_coins& coins); + void enable_slp_coin(coin_config coin_config); + void enable_slp_coins(const t_coins& coins); + void enable_slp_testnet_coin(coin_config coin_config); + void enable_slp_testnet_coins(const t_coins& coins); + void enable_zhtlc(const t_coins& coins); + + // Balances processing functions + void process_balance_answer(const mm2::enable_bch_with_tokens_rpc& rpc); // Called after enabling SLP coins along tBCH/BCH. + void process_balance_answer(const mm2::enable_slp_rpc& rpc); // Called after enabling an SLP coin. + + 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); + [[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; + [[nodiscard]] nlohmann::json get_zhtlc_status(const std::string coin) const; + + + //! Disable a single coin + bool disable_coin(const std::string& ticker, std::error_code& ec); - //! Is MM2 Process correctly running ? - [[nodiscard]] const std::atomic_bool& is_mm2_running() const; + //! Disable multiple coins, prefer this function if you want persistent disabling + void disable_multiple_coins(const std::vector& tickers); + + //! Called every ticks, and execute tasks if the timer expire. + void update() final; + + //! Retrieve public address of the given ticker + std::string address(const std::string& ticker, t_mm2_ec& ec) const; - //! Retrieve my balance for a given ticker as a string. - [[nodiscard]] std::string my_balance(const std::string& ticker, t_mm2_ec& ec) const; + //! Is MM2 Process correctly running ? + [[nodiscard]] const std::atomic_bool& is_mm2_running() const; - //! Refresh the current orderbook (internally call process_orderbook) - void fetch_current_orderbook_thread(bool is_a_reset = false); + //! Retrieve my balance for a given ticker as a string. + [[nodiscard]] std::string my_balance(const std::string& ticker, t_mm2_ec& ec) const; - void process_orderbook(bool is_a_reset = false); + //! Refresh the current orderbook (internally call process_orderbook) + void fetch_current_orderbook_thread(bool is_a_reset = false); - //! Last 50 transactions maximum - [[nodiscard]] t_transactions get_tx_history(t_mm2_ec& ec) const; + void process_orderbook(bool is_a_reset = false); - //! Last 50 transactions maximum - [[nodiscard]] t_tx_state get_tx_state(t_mm2_ec& ec) const; + //! Last 50 transactions maximum + [[nodiscard]] t_transactions get_tx_history(t_mm2_ec& ec) const; - //! Get coins that are currently enabled - [[nodiscard]] t_coins get_enabled_coins() const; + //! Last 50 transactions maximum + [[nodiscard]] t_tx_state get_tx_state(t_mm2_ec& ec) const; - //! Get coins that are active, but may be not enabled - [[nodiscard]] t_coins get_active_coins() const; + //! Get coins that are currently enabled + [[nodiscard]] t_coins get_enabled_coins() const; - //! Get Specific info about one coin - [[nodiscard]] coin_config get_coin_info(const std::string& ticker) const; + //! Get coins that are active, but may be not enabled + [[nodiscard]] t_coins get_active_coins() const; - //! Get Current orderbook - [[nodiscard]] t_orderbook_answer get_orderbook(t_mm2_ec& ec) const; + //! Get Specific info about one coin + [[nodiscard]] coin_config 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; + + // Tells if the given is coin is present inside the config. + [[nodiscard]] bool has_coin(const std::string& ticker) const; - //! Get Swaps - [[nodiscard]] orders_and_swaps get_orders_and_swaps() const; + //! Get Current orderbook + [[nodiscard]] t_orderbook_answer get_orderbook(t_mm2_ec& ec) const; - //! Get balance with locked funds for a given ticker as a boost::multiprecision::cpp_dec_float_50. - [[nodiscard]] t_float_50 get_balance(const std::string& ticker) const; + //! Get Swaps + [[nodiscard]] orders_and_swaps get_orders_and_swaps() const; - //! Return true if we the balance of the `ticker` > amount, false otherwise. - [[nodiscard]] bool do_i_have_enough_funds(const std::string& ticker, const t_float_50& amount) const; + //! Get balance with locked funds for a given ticker as a boost::multiprecision::cpp_dec_float_50. + [[nodiscard]] t_float_50 get_balance(const std::string& ticker) const; - [[nodiscard]] bool is_orderbook_thread_active() const; + //! Return true if we the balance of the `ticker` > amount, false otherwise. + [[nodiscard]] bool do_i_have_enough_funds(const std::string& ticker, const t_float_50& amount) const; - [[nodiscard]] nlohmann::json get_raw_mm2_ticker_cfg(const std::string& ticker) const; + [[nodiscard]] bool is_orderbook_thread_active() const; - [[nodiscard]] t_pair_max_vol get_taker_vol() const; - [[nodiscard]] t_pair_min_vol get_min_vol() const; + [[nodiscard]] nlohmann::json get_raw_mm2_ticker_cfg(const std::string& ticker) const; - //! Pin cfg api - [[nodiscard]] bool is_pin_cfg_enabled() const; - void reset_fake_balance_to_zero(const std::string& ticker); - void decrease_fake_balance(const std::string& ticker, const std::string& amount); - void batch_fetch_orders_and_swap(bool after_manual_reset = false); - void add_orders_answer(t_my_orders_answer answer); + [[nodiscard]] t_pair_max_vol get_taker_vol() const; + [[nodiscard]] t_pair_min_vol get_min_vol() const; - //! Async API - mm2_client& get_mm2_client(); - //[[nodiscard]] pplx::cancellation_token get_cancellation_token() const; + //! Pin cfg api + [[nodiscard]] bool is_pin_cfg_enabled() const; + void reset_fake_balance_to_zero(const std::string& ticker); + void decrease_fake_balance(const std::string& ticker, const std::string& amount); + void batch_fetch_orders_and_swap(bool after_manual_reset = false); + + //! Async API + mm2::mm2_client& get_mm2_client(); - //! Wallet api - [[nodiscard]] std::string get_current_ticker() const; - bool set_current_ticker(const std::string& ticker); + //! Wallet api + [[nodiscard]] std::string get_current_ticker() const; + bool set_current_ticker(const std::string& ticker); - //! Pagination - void set_orders_and_swaps_pagination_infos(std::size_t current_page = 1, std::size_t limit = 50, t_filtering_infos infos = {}); + //! Pagination + void set_orders_and_swaps_pagination_infos(std::size_t current_page = 1, std::size_t limit = 50, t_filtering_infos infos = {}); - void change_segwit_status(std::string ticker, bool status); - }; + void change_segwit_status(std::string ticker, bool status); + }; } // namespace atomic_dex REFL_AUTO(type(atomic_dex::mm2_service)) diff --git a/src/core/atomicdex/services/mm2/mm2_events.hpp b/src/core/atomicdex/services/mm2/mm2_events.hpp new file mode 100644 index 0000000000..2329a147f9 --- /dev/null +++ b/src/core/atomicdex/services/mm2/mm2_events.hpp @@ -0,0 +1,19 @@ +// atomicdex-desktop +// Author(s): syl + +#pragma once + +#include + +#include "atomicdex/api/mm2/transaction.data.hpp" + +namespace atomic_dex::mm2 +{ + struct transactions_fetched_event + { + std::string ticker; + std::vector transactions; + bool has_error; + std::string error_msg; + }; +} \ No newline at end of file diff --git a/src/core/atomicdex/services/price/global.provider.cpp b/src/core/atomicdex/services/price/global.provider.cpp index 4f3d8110db..966b67dd48 100644 --- a/src/core/atomicdex/services/price/global.provider.cpp +++ b/src/core/atomicdex/services/price/global.provider.cpp @@ -210,16 +210,22 @@ namespace atomic_dex { t_float_50 rate(1); { - std::shared_lock lock(m_coin_rate_mutex); - rate = t_float_50(m_coin_rate_providers.at(fiat)); ///< Retrieve BTC or KMD rate let's say for USD + if (m_coin_rate_providers.contains(fiat)) + { + std::shared_lock lock(m_coin_rate_mutex); + rate = t_float_50(m_coin_rate_providers.at(fiat)); ///< Retrieve BTC or KMD rate let's say for USD + } } t_float_50 tmp_current_price = t_float_50(current_price) * rate; current_price = tmp_current_price.str(); } else if (fiat != "USD") { - t_float_50 tmp_current_price = t_float_50(current_price) * m_other_fiats_rates->at("rates").at(fiat).get(); - current_price = tmp_current_price.str(); + if (m_other_fiats_rates->contains("rates")) + { + t_float_50 tmp_current_price = t_float_50(current_price) * m_other_fiats_rates->at("rates").at(fiat).get(); + current_price = tmp_current_price.str(); + } } } else @@ -227,8 +233,11 @@ namespace atomic_dex //! We use oracle if (is_this_currency_a_fiat(m_cfg, fiat) && fiat != "USD") { - t_float_50 tmp_current_price = t_float_50(current_price) * m_other_fiats_rates->at("rates").at(fiat).get(); - current_price = tmp_current_price.str(); + if (m_other_fiats_rates->contains("rates")) + { + t_float_50 tmp_current_price = t_float_50(current_price) * m_other_fiats_rates->at("rates").at(fiat).get(); + current_price = tmp_current_price.str(); + } } else if (!is_this_currency_a_fiat(m_cfg, fiat) && is_oracle_ready) @@ -264,6 +273,7 @@ namespace atomic_dex SPDLOG_ERROR("Exception caught in get_rate_conversion: {} - fiat: {} - ticker: {}", error.what(), fiat, ticker); return "0.00"; } + return "0.00"; } std::string diff --git a/src/core/atomicdex/services/price/orderbook.scanner.service.cpp b/src/core/atomicdex/services/price/orderbook.scanner.service.cpp index ee724bd698..ca6fbce557 100644 --- a/src/core/atomicdex/services/price/orderbook.scanner.service.cpp +++ b/src/core/atomicdex/services/price/orderbook.scanner.service.cpp @@ -40,16 +40,17 @@ namespace atomic_dex { if (m_rpc_busy) { - //SPDLOG_INFO("process_best_orders is busy - skipping"); + // SPDLOG_INFO("process_best_orders is busy - skipping"); return; } - //SPDLOG_INFO("process_best_orders processing"); + + // SPDLOG_INFO("process_best_orders processing"); if (m_system_manager.has_system()) { auto& mm2_system = m_system_manager.get_system(); if (mm2_system.is_mm2_running() && mm2_system.is_orderbook_thread_active()) { - //SPDLOG_INFO("process_best_orders"); + // 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(); @@ -59,12 +60,12 @@ namespace atomic_dex //! Prepare request nlohmann::json batch = nlohmann::json::array(); - nlohmann::json best_orders_req_json = ::mm2::api::template_request("best_orders"); + 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)); + // 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(); @@ -74,7 +75,7 @@ namespace atomic_dex if (resp.status_code() == 200) { auto answers = nlohmann::json::parse(body); - auto best_order_answer = ::mm2::api::rpc_process_answer_batch(answers[0], "best_orders"); + auto best_order_answer = mm2::rpc_process_answer_batch(answers[0], "best_orders"); if (best_order_answer.result.has_value()) { this->m_best_orders_infos = best_order_answer.result.value(); diff --git a/src/core/atomicdex/services/update/self.update.service.cpp b/src/core/atomicdex/services/update/self.update.service.cpp deleted file mode 100644 index 9d33f780ef..0000000000 --- a/src/core/atomicdex/services/update/self.update.service.cpp +++ /dev/null @@ -1,325 +0,0 @@ -//! Std -#include -#include //> std::isdigit -#include - -//! Qt -#include //> qApp -#include -#include -#include -#include - -//! System -#if defined(Q_OS_LINUX) -# include -# include -#endif - -//! 3rdParty -#include - -//! Project -#include "atomicdex/utilities/global.utilities.hpp" //> utils::u8string() -#include "atomicdex/utilities/cpprestsdk.utilities.hpp" //> download_file() -#include "atomicdex/utilities/qt.utilities.hpp" //> to_sha256() -#include "atomicdex/version/version.hpp" //> get_version() -#include "atomicdex/api/checksum/checksum.api.hpp" -#include "self.update.service.hpp" - -namespace atomic_dex -{ - const auto update_archive_path{antara::gaming::core::binary_real_path().parent_path() / ".update_archive"}; - - self_update_service::self_update_service(entt::registry& entity_registry) : system(entity_registry), m_download_mgr(dispatcher_) - { - remove_update_files(); - dispatcher_.sink().connect<&self_update_service::on_download_release_finished>(*this); - dispatcher_.sink().connect<&self_update_service::on_download_release_progressed>(*this); -#if !defined (Q_OS_WINDOWS) - fetch_last_release_info(); -#endif - } - - void - self_update_service::update() - { - using namespace std::chrono_literals; - - const auto now = std::chrono::high_resolution_clock::now(); - const auto s = std::chrono::duration_cast(now - m_update_clock); - if (s >= 1h) - { - fetch_last_release_info(); - m_update_clock = std::chrono::high_resolution_clock::now(); - } - } - - void - self_update_service::fetch_last_release_info() - { - // If an update is already in preparation, just returns. - if (m_update_downloading || m_update_ready.get() || is_update_needed()) - { - return; - } - - auto releases_request = github_api::repository_releases_request{.owner = DEX_REPOSITORY_OWNER, .repository = DEX_REPOSITORY_NAME}; - github_api::get_repository_releases_async(releases_request) - .then([this](web::http::http_response resp) { - if (resp.status_code() == 200) - { - auto last_release = github_api::get_last_repository_release_from_http_response(resp); - m_last_release_info = last_release; - emit last_release_tag_nameChanged(); - emit update_neededChanged(); - } - }) - .then(&handle_exception_pplx_task); - } - - void - self_update_service::download_update() - { - auto release_info = m_last_release_info.get(); - auto download_request = github_api::download_repository_release_request{ - .owner = DEX_REPOSITORY_OWNER, .repository = DEX_REPOSITORY_NAME, .tag_name = release_info.tag_name, .name = release_info.name}; - - auto url = fmt::format( - "https://github.com/{}/{}/{}/{}/{}/{}", download_request.owner, download_request.repository, "releases", "download", download_request.tag_name, - download_request.name); - m_download_mgr.do_download(QUrl(QString::fromStdString(url))); - m_update_downloading = true; - emit updateDownloadingChanged(); - } - - void - self_update_service::perform_update() - { - // Checks update file integrity by comparing checksum - { - QFile file{QString::fromStdString(m_download_mgr.get_last_download_path().string())}; - std::string hashed; - - file.open(QIODevice::ReadOnly); - hashed = sha256_qstring_from_qt_byte_array(file.readAll()).toStdString(); - file.close(); - - checksum::api::get_latest_checksum() - .then([this, hashed](std::string valid_hash) - { - if (hashed != valid_hash) - { - m_update_ready = false; - emit update_readyChanged(); - m_update_downloading = false; - emit updateDownloadingChanged(); - m_update_files_invalid = true; - emit invalidUpdateFilesChanged(); - } - else - { - m_update_files_invalid = false; - } - }).wait(); - if (m_update_files_invalid) - { - return; - } - } - - const auto& cmd = qApp->arguments()[0]; - [[maybe_unused]] const auto& args = qApp->arguments(); - [[maybe_unused]] const auto& dir_path = qApp->applicationDirPath(); - qApp->quit(); - bool res = false; - - // Installs update for MacOS. -#if defined(Q_OS_MACOS) - try - { - const auto image_mount_path = fs::path("/Volumes") / DEX_PROJECT_NAME; - const auto image_mount_cmd = - fmt::format("hdiutil attach -mountpoint {} {}", image_mount_path.c_str(), m_download_mgr.get_last_download_path().c_str()); - const auto image_unmount_cmd = fmt::format("hdiutil detach {}", image_mount_path.c_str()); - - //! Mounting - SPDLOG_INFO("Executing: {}", image_mount_cmd); - std::system(image_mount_cmd.c_str()); - - //! Retrieve App path - fs::path app_path = ag::core::binary_real_path().parent_path().parent_path().parent_path(); - - //! Deleting old - SPDLOG_INFO("Deleting: {}", app_path.c_str()); - fs::remove_all(app_path); - - //! Copying - SPDLOG_INFO("Copying: {} to {}", (image_mount_path / (std::string(DEX_PROJECT_NAME) + ".app")).c_str(), app_path.c_str()); - fs::copy(image_mount_path / (std::string(DEX_PROJECT_NAME) + ".app"), app_path, fs::copy_options::recursive); - - //! Unmount - SPDLOG_INFO("Executing: {}", image_unmount_cmd); - std::system(image_unmount_cmd.c_str()); - - //! DL download tmp path - SPDLOG_INFO("Removing: {}", m_download_mgr.get_last_download_path().c_str()); - fs::remove(m_download_mgr.get_last_download_path()); - } - catch (std::exception& ex) - { - SPDLOG_ERROR(ex.what()); - } - qDebug() << "cmd: " << cmd; - res = QProcess::startDetached(cmd, args, dir_path); -#elif defined(Q_OS_LINUX) - try - { - const char* appimage{nullptr}; - if (appimage = std::getenv("APPIMAGE"); appimage != nullptr) - { - SPDLOG_INFO("APPIMAGE path is {}", appimage); - } - if (appimage == nullptr || not QString(appimage).contains(DEX_PROJECT_NAME)) - { - SPDLOG_INFO("Need to handle zip"); - } - else - { - SPDLOG_INFO("Need to handle appimage"); - - SPDLOG_INFO("Changing rights of the downloaded appimage"); - char mode[] = "0755"; - int i; - i = strtol(mode, 0, 8); - chmod(m_download_mgr.get_last_download_path().c_str(), i); - - //! Download old appimage - SPDLOG_INFO("Removing old appimage: {}", appimage); - fs::remove(appimage); - - SPDLOG_INFO("Copying new appimage: {} to {}", m_download_mgr.get_last_download_path().c_str(), fs::path(appimage).parent_path().c_str()); - fs::copy(m_download_mgr.get_last_download_path(), fs::path(appimage).parent_path()); - - SPDLOG_INFO("Removing: {}", m_download_mgr.get_last_download_path().c_str()); - fs::remove(m_download_mgr.get_last_download_path()); - - auto release_info = m_last_release_info.get(); - QString path((fs::path(appimage).parent_path() / release_info.name).c_str()); - - SPDLOG_INFO("Starting: {}", path.toStdString()); - QProcess::startDetached(path, qApp->arguments()); - } - } - catch (const std::exception& error) - { - SPDLOG_ERROR("{}", error.what()); - } -#elif defined(Q_OS_WIN) - try - { - const auto binary_path = antara::gaming::core::binary_real_path(); - const auto current_install_folder = binary_path.parent_path(); - const auto unzip_cmd = fmt::format("powershell.exe -nologo -noprofile -command \"Expand-Archive -Path {} -DestinationPath {} -Force\"", - m_download_mgr.get_last_download_path().string(), current_install_folder.string()); - - for (const auto& file : fs::recursive_directory_iterator(current_install_folder)) - { - if (file.path().extension() == ".dll" || file.path().extension() == ".exe" || file.path().extension() == ".qmlc" || file.path().extension() == ".jsc") - { - fs::rename(file.path(), file.path().string() + ".old"); - } - } - std::system(unzip_cmd.c_str()); - res = QProcess::startDetached(cmd, args, dir_path); - } - catch (std::exception& ex) - { - SPDLOG_ERROR(ex.what()); - } -#endif - - // Restarts application. - if (!res) - { - SPDLOG_ERROR("Couldn't start a new process"); - } - else - { - SPDLOG_INFO("Successfully restarted the app"); - } - } - - QString - self_update_service::get_last_release_tag_name() const noexcept - { - return QString::fromStdString(m_last_release_info.get().tag_name); - } - - bool - self_update_service::is_update_needed() const noexcept - { - auto tag = m_last_release_info.get().tag_name; - try - { - tag.erase(std::remove_if(tag.begin(), tag.end(), [](char c) { return not std::isdigit(c); }), tag.end()); - return std::stoi(tag) > get_num_version(); - } - catch (std::exception& ex) - { - SPDLOG_ERROR(ex.what()); - return false; - } - } - - bool - self_update_service::is_update_downloading() const noexcept - { - return m_update_downloading; - } - - float self_update_service::get_update_download_progress() const noexcept - { - return m_update_download_progress; - } - - bool - self_update_service::is_update_ready() const noexcept - { - return m_update_ready.get(); - } - - bool self_update_service::are_update_files_invalid() const noexcept - { - return m_update_files_invalid; - } - - void self_update_service::on_download_release_progressed(qt_download_progressed download_progressed) - { - m_update_download_progress = download_progressed.progress; - emit updateDownloadProgressChanged(); - } - - void - self_update_service::on_download_release_finished([[maybe_unused]] const download_release_finished& evt) - { - SPDLOG_DEBUG("Successfully downloaded last release to {}", utils::u8string(m_download_mgr.get_last_download_path())); - m_update_downloading = false; - emit updateDownloadingChanged(); - m_update_ready = true; - emit update_readyChanged(); - } - - void self_update_service::remove_update_files() const noexcept - { - const auto current_install_folder = antara::gaming::core::binary_real_path().parent_path(); - - for (auto file : fs::recursive_directory_iterator(current_install_folder)) - { - if (file.path().extension().string() == ".old") - { - fs::remove(file.path()); - } - } - } -} // namespace atomic_dex \ No newline at end of file diff --git a/src/core/atomicdex/services/update/self.update.service.hpp b/src/core/atomicdex/services/update/self.update.service.hpp deleted file mode 100644 index ccd44609f7..0000000000 --- a/src/core/atomicdex/services/update/self.update.service.hpp +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -//! Qt -#include -#include - -//! 3rdParty -#include -#include - -//! Project -#include "atomicdex/api/github/github.api.hpp" -#include "atomicdex/utilities/qt.download.manager.hpp" -#include "atomicdex/events/events.hpp" - -namespace atomic_dex -{ - class self_update_service : public QObject, public ag::ecs::pre_update_system - { - Q_OBJECT - - Q_PROPERTY(QString last_release_tag_name READ get_last_release_tag_name NOTIFY last_release_tag_nameChanged) - Q_PROPERTY(bool update_needed READ is_update_needed NOTIFY update_neededChanged) - Q_PROPERTY(bool update_downloading READ is_update_downloading NOTIFY updateDownloadingChanged) - Q_PROPERTY(float update_download_progress READ get_update_download_progress NOTIFY updateDownloadProgressChanged) - Q_PROPERTY(bool update_ready READ is_update_ready NOTIFY update_readyChanged) - Q_PROPERTY(bool invalid_update_files READ are_update_files_invalid NOTIFY invalidUpdateFilesChanged) - - boost::synchronized_value m_last_release_info; - bool m_update_downloading{false}; - float m_update_download_progress{0.0F}; - boost::synchronized_value m_update_ready{false}; - bool m_update_files_invalid{false}; - - // Clock used to time the `update()` loop of this ecs system. - std::chrono::high_resolution_clock::time_point m_update_clock; - - // Download manager used to download latest release. - qt_download_manager m_download_mgr; - - public: - explicit self_update_service(entt::registry& entity_registry); - - // ecs::pre_update_system::update implementation - // Basically it calls `fetch_last_release_info()` every hour. - void update(); - - // Fetches last release info and notifies the frontend if a new release is available. - // Notification happens by modifying Q_PROPERTY `update_info`. - Q_INVOKABLE void fetch_last_release_info(); - - // Downloads last release. - Q_INVOKABLE void download_update(); - - // Updates the program to the latest release (downloaded by self_update_service::download_update()). - // Updating might fail if `check_update_files_integrity()` sets `m_update_files_invalid` to true - Q_INVOKABLE void perform_update(); - - // Returns the fetched release tag name. - [[nodiscard]] QString get_last_release_tag_name() const noexcept; - - // Compares fetched last release version to this build version then tells if an update can be downloaded or not. - [[nodiscard]] bool is_update_needed() const noexcept; - - // Tells if an update is downloading. - [[nodiscard]] bool is_update_downloading() const noexcept; - - // Returns the current progress of the update downloading. - [[nodiscard]] float get_update_download_progress() const noexcept; - - [[nodiscard]] bool is_update_ready() const noexcept; - - [[nodiscard]] bool are_update_files_invalid() const noexcept; - - // Removes files used for recent update. - void remove_update_files() const noexcept; - - //! Events - void on_download_release_progressed(qt_download_progressed download_progressed); - void on_download_release_finished([[maybe_unused]] const download_release_finished& evt); - - signals: - void last_release_tag_nameChanged(); - void update_neededChanged(); - void updateDownloadingChanged(); - void updateDownloadProgressChanged(); - void update_readyChanged(); - void invalidUpdateFilesChanged(); - }; -} - -REFL_AUTO(type(atomic_dex::self_update_service)); \ No newline at end of file diff --git a/src/core/atomicdex/services/update/update.checker.service.cpp b/src/core/atomicdex/services/update/update.checker.service.cpp index e4e1930179..db89277ca7 100644 --- a/src/core/atomicdex/services/update/update.checker.service.cpp +++ b/src/core/atomicdex/services/update/update.checker.service.cpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -14,17 +14,14 @@ * * ******************************************************************************/ -//! PCH #include "atomicdex/pch.hpp" -//! Qt #include +#include -//! Deps #include #include -//! Project headers #include "atomicdex/events/events.hpp" #include "atomicdex/services/update/update.checker.service.hpp" #include "atomicdex/utilities/cpprestsdk.utilities.hpp" @@ -35,28 +32,27 @@ namespace constexpr const char* g_komodolive_endpoint = "https://komodo.live/adexproversion"; t_http_client_ptr g_komodolive_client{std::make_unique(FROM_STD_STR(g_komodolive_endpoint))}; - pplx::task - async_check_retrieve() + pplx::task async_check_retrieve() { nlohmann::json json_data{{"currentVersion", atomic_dex::get_raw_version()}}; return g_komodolive_client->request(create_json_post_request(std::move(json_data))); } - nlohmann::json - get_update_status_rpc(web::http::http_response resp_http) + nlohmann::json get_update_info_rpc(web::http::http_response resp_http) { using namespace std::string_literals; nlohmann::json resp; + nlohmann::json result; if (resp_http.status_code() != 200) { - resp["status"] = "cannot reach the endpoint: "s + g_komodolive_endpoint; + result["status"] = (QObject::tr("Cannot reach the endpoint: ") + g_komodolive_endpoint).toStdString(); } else { resp = nlohmann::json::parse(TO_STD_STR(resp_http.extract_string(true).get())); } - resp["rpc_code"] = resp_http.status_code(); - resp["current_version"] = atomic_dex::get_raw_version(); + result["rpcCode"] = resp_http.status_code(); + result["currentVersion"] = atomic_dex::get_raw_version(); if (resp_http.status_code() == 200) { bool update_needed = false; @@ -67,24 +63,26 @@ namespace boost::algorithm::trim_left_if(current_version_str, boost::is_any_of("0")); boost::algorithm::trim_left_if(endpoint_version, boost::is_any_of("0")); update_needed = std::stoi(current_version_str) < std::stoi(endpoint_version); - resp["update_needed"] = update_needed; + result["updateNeeded"] = update_needed; + result["newVersion"] = resp["new_version"]; + result["downloadUrl"] = resp["download_url"]; + result["changelog"] = resp["changelog"]; + result["status"] = resp["status"]; } - return resp; + return result; } -} // namespace +} + namespace atomic_dex { - //! Constructor - update_service_checker::update_service_checker(entt::registry& registry, QObject* parent) : QObject(parent), system(registry) + update_checker_service::update_checker_service(entt::registry& registry, QObject* parent) : QObject(parent), system(registry) { m_update_clock = std::chrono::high_resolution_clock::now(); - m_update_status = nlohmann::json::object(); - fetch_update_status(); + m_update_info = nlohmann::json::object(); + fetch_update_info(); } - //! Public override - void - update_service_checker::update() + void update_checker_service::update() { using namespace std::chrono_literals; @@ -92,30 +90,31 @@ namespace atomic_dex const auto s = std::chrono::duration_cast(now - m_update_clock); if (s >= 1h) { - fetch_update_status(); + fetch_update_info(); m_update_clock = std::chrono::high_resolution_clock::now(); } } - //! Private api - void - update_service_checker::fetch_update_status() + void update_checker_service::fetch_update_info() { - SPDLOG_DEBUG("{} l{} f[{}]", __FUNCTION__, __LINE__, fs::path(__FILE__).filename().string()); - SPDLOG_INFO("fetching update status"); + if (is_fetching) + return; + is_fetching = true; + emit isFetchingChanged(); async_check_retrieve() .then([this](web::http::http_response resp) { - this->m_update_status = get_update_status_rpc(resp); - emit updateStatusChanged(); + this->m_update_info = get_update_info_rpc(resp); + is_fetching = false; + emit isFetchingChanged(); + emit updateInfoChanged(); }) .then(&handle_exception_pplx_task); } - QVariant - update_service_checker::get_update_status() const + QVariant update_checker_service::get_update_info() const { - nlohmann::json status = *m_update_status; - QJsonDocument doc = QJsonDocument::fromJson(QString::fromStdString(status.dump()).toUtf8()); + nlohmann::json info = *m_update_info; + QJsonDocument doc = QJsonDocument::fromJson(QString::fromStdString(info.dump()).toUtf8()); return doc.toVariant(); } } // namespace atomic_dex diff --git a/src/core/atomicdex/services/update/update.checker.service.hpp b/src/core/atomicdex/services/update/update.checker.service.hpp index 0a9883b950..b6c6eed91f 100644 --- a/src/core/atomicdex/services/update/update.checker.service.hpp +++ b/src/core/atomicdex/services/update/update.checker.service.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -16,53 +16,45 @@ #pragma once -//! Qt #include #include -//! Deps #include #include -//! Project Headers #include namespace atomic_dex { - class update_service_checker final : public QObject, public ag::ecs::pre_update_system + class update_checker_service final : public QObject, public ag::ecs::pre_update_system { Q_OBJECT - Q_PROPERTY(QVariant update_status READ get_update_status NOTIFY updateStatusChanged) + Q_PROPERTY(QVariant updateInfo READ get_update_info NOTIFY updateInfoChanged) + Q_PROPERTY(bool isFetching READ get_is_fetching NOTIFY isFetchingChanged) - //! Private typedefs using t_update_time_point = std::chrono::high_resolution_clock::time_point; using t_json_synchronized = boost::synchronized_value; - //! Private members - t_json_synchronized m_update_status; - t_update_time_point m_update_clock; + t_json_synchronized m_update_info; + t_update_time_point m_update_clock; + boost::synchronized_value is_fetching; - //! Private API - void fetch_update_status() ; - - signals: - void updateStatusChanged(); + void fetch_update_info(); public: - [[deprecated("Use self_update_service instead.")]] - //! Constructor - explicit update_service_checker(entt::registry& registry, QObject* parent = nullptr); + explicit update_checker_service(entt::registry& registry, QObject* parent = nullptr); + ~update_checker_service() final = default; - //! Destructor - ~update_service_checker() final = default; + void update() final; - //! Public override - void update() final; + [[nodiscard]] QVariant get_update_info() const; + [[nodiscard]] bool get_is_fetching() const noexcept { return *is_fetching; } - //! Properties - [[nodiscard]] QVariant get_update_status() const ; + signals: + void updateInfoChanged(); + void isFetchingChanged(); }; } // namespace atomic_dex -REFL_AUTO(type(atomic_dex::update_service_checker)) +REFL_AUTO(type(atomic_dex::update_checker_service)) diff --git a/src/core/atomicdex/services/update/zcash.params.service.cpp b/src/core/atomicdex/services/update/zcash.params.service.cpp new file mode 100644 index 0000000000..39f83d1d04 --- /dev/null +++ b/src/core/atomicdex/services/update/zcash.params.service.cpp @@ -0,0 +1,151 @@ +/****************************************************************************** + * Copyright © 2013-2022 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. * + * * + ******************************************************************************/ + + +#include +#include + +#include +#include +#include + +#include "atomicdex/pch.hpp" +#include "atomicdex/services/update/zcash.params.service.hpp" +#include "atomicdex/utilities/global.utilities.hpp" +#include "atomicdex/utilities/qt.download.manager.hpp" + +namespace atomic_dex +{ + zcash_params_service::zcash_params_service( + entt::registry& registry, ag::ecs::system_manager& system_manager, + entt::dispatcher& dispatcher, QObject* parent) : + QObject(parent), system(registry), + m_system_manager(system_manager), m_dispatcher(dispatcher) + { + m_update_clock = std::chrono::high_resolution_clock::now(); + m_update_info = nlohmann::json::object(); + } + + void zcash_params_service::update() + { + using namespace std::chrono_literals; + + const auto now = std::chrono::high_resolution_clock::now(); + const auto s = std::chrono::duration_cast(now - m_update_clock); + if (s >= 1s) + { + // TODO: We could use this for an ETA + } + } + + std::filesystem::path zcash_params_service::get_zcash_params_folder() + { + std::filesystem::path zcash_params_path; +#if defined(_WIN32) || defined(WIN32) + std::wstring out = _wgetenv(L"APPDATA"); + zcash_params_path = std::filesystem::path(out) / "ZcashParams"; +#elif defined(__APPLE__) + zcash_params_path = std::filesystem::path(std::getenv("HOME")) / "Library" / "Application Support" / "ZcashParams"; +#else + zcash_params_path = std::filesystem::path(std::getenv("HOME")) / (std::string(".zcash-params")); +#endif + return zcash_params_path; + } + + void zcash_params_service::download_zcash_params() + { + m_is_downloading = true; + using namespace std::chrono_literals; + const std::filesystem::path folder = this->get_zcash_params_folder(); + + if (not std::filesystem::exists(folder)) + { + std::filesystem::create_directories(folder); + } + + std::string zcash_params[2] = { + "https://z.cash/downloads/sapling-spend.params", + "https://z.cash/downloads/sapling-output.params" + }; + + for(const std::string &url: zcash_params) + { + std::string filename = atomic_dex::utils::u8string(std::filesystem::path(url).filename()); + if (filename.find("deprecated-sworn-elves") > -1) + { + filename = "sprout-proving.key"; + } + SPDLOG_INFO("Downloading {}...", filename); + qt_downloader* downloader = new qt_downloader(m_dispatcher); + downloader->do_download(QUrl(QString::fromStdString(url)), filename, folder); + connect(downloader, &qt_downloader::downloadStatusChanged, this, &zcash_params_service::set_combined_download_status); + } + } + + bool + zcash_params_service::is_downloading() + { + return m_is_downloading; + } + + void + zcash_params_service::enable_after_download(const QString& coin) + { + m_enable_after_download.append(coin); + } + + void + zcash_params_service::clear_enable_after_download() + { + m_enable_after_download.clear(); + } + + QStringList + zcash_params_service::get_enable_after_download() + { + return m_enable_after_download; + } + + QString + zcash_params_service::get_combined_download_progress() + { + foreach(const QString& key, m_combined_download_status.keys()) { + double val = m_combined_download_status.value(key).toDouble(); + if (val < 1) + { + break; + } + m_is_downloading = false; + } + return QString(QJsonDocument(m_combined_download_status).toJson()); + } + + QJsonObject + zcash_params_service::get_combined_download_status() const + { + return m_combined_download_status; + } + + void + zcash_params_service::set_combined_download_status(QJsonObject& status) + { + QString filename = status.value("filename").toString(); + m_combined_download_status.insert(filename, status.value("progress")); + // SPDLOG_INFO("Filename: {} {}%", filename.toUtf8().constData(), std::to_string(status.value("progress").toDouble())); + emit combinedDownloadStatusChanged(); + } + +} // namespace atomic_dex diff --git a/src/core/atomicdex/services/update/zcash.params.service.hpp b/src/core/atomicdex/services/update/zcash.params.service.hpp new file mode 100644 index 0000000000..d77cd453d1 --- /dev/null +++ b/src/core/atomicdex/services/update/zcash.params.service.hpp @@ -0,0 +1,78 @@ +/****************************************************************************** + * Copyright © 2013-2022 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 +#include + +#include +#include +#include +#include + +#include "atomicdex/pch.hpp" + + +namespace atomic_dex +{ + class zcash_params_service final : public QObject, public ag::ecs::pre_update_system + { + Q_OBJECT + + Q_PROPERTY(QJsonObject m_combined_download_status READ get_combined_download_status NOTIFY combinedDownloadStatusChanged) + + using t_update_time_point = std::chrono::high_resolution_clock::time_point; + using t_json_synchronized = boost::synchronized_value; + + ag::ecs::system_manager& m_system_manager; + entt::dispatcher& m_dispatcher; + t_json_synchronized m_update_info; + t_update_time_point m_update_clock; + QJsonObject m_combined_download_status; + bool m_is_downloading{false}; + QStringList m_enable_after_download; + + void fetch_update_info(); + + public: + explicit zcash_params_service( + entt::registry& registry, ag::ecs::system_manager& system_manager, + entt::dispatcher& dispatcher, QObject* parent = nullptr); + ~zcash_params_service() final = default; + + void update() final; + + Q_INVOKABLE void enable_after_download(const QString& coin); + Q_INVOKABLE QStringList get_enable_after_download(); + Q_INVOKABLE void clear_enable_after_download(); + Q_INVOKABLE void download_zcash_params(); + Q_INVOKABLE bool is_downloading(); + Q_INVOKABLE QString get_combined_download_progress(); + [[nodiscard]] QJsonObject get_combined_download_status() const; + [[nodiscard]] std::filesystem::path get_zcash_params_folder(); + + signals: + void combinedDownloadStatusChanged(); + + public slots: + void set_combined_download_status(QJsonObject& status); + }; +} // namespace atomic_dex + +REFL_AUTO(type(atomic_dex::zcash_params_service)) diff --git a/src/core/atomicdex/utilities/cpprestsdk.utilities.hpp b/src/core/atomicdex/utilities/cpprestsdk.utilities.hpp index 02241015d6..5da61abb47 100644 --- a/src/core/atomicdex/utilities/cpprestsdk.utilities.hpp +++ b/src/core/atomicdex/utilities/cpprestsdk.utilities.hpp @@ -30,8 +30,6 @@ # define FROM_STD_STR(utf8str) utf8str #endif -#include "fs.prerequisites.hpp" - using t_http_client_ptr = std::unique_ptr; using t_http_client = web::http::client::http_client; using t_http_request = web::http::http_request; diff --git a/src/core/atomicdex/utilities/global.utilities.cpp b/src/core/atomicdex/utilities/global.utilities.cpp index 85d078a04b..d17b2036d8 100644 --- a/src/core/atomicdex/utilities/global.utilities.cpp +++ b/src/core/atomicdex/utilities/global.utilities.cpp @@ -10,6 +10,8 @@ //! Qt Headers #include #include +#include + //! Project Headers #include "atomicdex/utilities/global.utilities.hpp" @@ -17,11 +19,6 @@ namespace { - constexpr size_t g_qsize_spdlog = 10240; - constexpr size_t g_spdlog_thread_count = 2; - constexpr size_t g_spdlog_max_file_size = 7777777; - constexpr size_t g_spdlog_max_file_rotation = 3; - std::string dex_sha256(const std::string& str) { @@ -61,13 +58,13 @@ namespace atomic_dex::utils } bool - create_if_doesnt_exist(const fs::path& path) + create_if_doesnt_exist(const std::filesystem::path& path) { - if (not fs::exists(path)) + if (not std::filesystem::exists(path)) { LOG_PATH("creating directory {}", path); //SPDLOG_INFO("creating directory {}", path.string()); - fs::create_directories(path); + std::filesystem::create_directories(path); return true; } return false; @@ -87,27 +84,24 @@ namespace atomic_dex::utils return distr(gen); } - fs::path + std::filesystem::path get_atomic_dex_data_folder() { - fs::path appdata_path; + std::filesystem::path appdata_path; #if defined(_WIN32) || defined(WIN32) std::wstring out = _wgetenv(L"APPDATA"); - appdata_path = fs::path(out) / DEX_APPDATA_FOLDER; + appdata_path = std::filesystem::path(out) / DEX_APPDATA_FOLDER; #elif defined(__APPLE__) - appdata_path = fs::path(std::getenv("HOME")) / "Library" / "Application Support" / DEX_APPDATA_FOLDER; + appdata_path = std::filesystem::path(std::getenv("HOME")) / "Library" / "Application Support" / DEX_APPDATA_FOLDER; #else - appdata_path = fs::path(std::getenv("HOME")) / (std::string(".") + std::string(DEX_APPDATA_FOLDER)); + appdata_path = std::filesystem::path(std::getenv("HOME")) / (std::string(".") + std::string(DEX_APPDATA_FOLDER)); #endif return appdata_path; } std::string - u8string(const fs::path& p) + u8string(const std::filesystem::path& p) { -#if defined(PREFER_BOOST_FILESYSTEM) - return p.string(); -#else auto res = p.u8string(); auto functor = [](auto&& r) { @@ -121,10 +115,9 @@ namespace atomic_dex::utils } }; return functor(res); -#endif } - fs::path + std::filesystem::path get_atomic_dex_addressbook_folder() { const auto fs_addr_book_path = get_atomic_dex_data_folder() / "addressbook"; @@ -132,7 +125,7 @@ namespace atomic_dex::utils return fs_addr_book_path; } - fs::path + std::filesystem::path get_runtime_coins_path() { const auto fs_coins_path = get_atomic_dex_data_folder() / "custom_coins_icons"; @@ -140,7 +133,7 @@ namespace atomic_dex::utils return fs_coins_path; } - fs::path + std::filesystem::path get_atomic_dex_logs_folder() { const auto fs_logs_path = get_atomic_dex_data_folder() / "logs"; @@ -148,7 +141,7 @@ namespace atomic_dex::utils return fs_logs_path; } - ENTT_API fs::path + ENTT_API std::filesystem::path get_atomic_dex_current_log_file() { using namespace std::chrono; @@ -156,11 +149,11 @@ namespace atomic_dex::utils static auto timestamp = duration_cast(system_clock::now().time_since_epoch()).count(); static date::sys_seconds tp{seconds{timestamp}}; static std::string s = date::format("%Y-%m-%d-%H-%M-%S", tp); - static const fs::path log_path = get_atomic_dex_logs_folder() / (s + ".log"); + static const std::filesystem::path log_path = get_atomic_dex_logs_folder() / (s + ".log"); return log_path; } - fs::path + std::filesystem::path get_mm2_atomic_dex_current_log_file() { using namespace std::chrono; @@ -168,11 +161,11 @@ namespace atomic_dex::utils static auto timestamp = duration_cast(system_clock::now().time_since_epoch()).count(); static date::sys_seconds tp{seconds{timestamp}}; static std::string s = date::format("%Y-%m-%d-%H-%M-%S", tp); - static const fs::path log_path = get_atomic_dex_logs_folder() / (s + ".mm2.log"); + static const std::filesystem::path log_path = get_atomic_dex_logs_folder() / (s + ".mm2.log"); return log_path; } - fs::path + std::filesystem::path get_atomic_dex_config_folder() { const auto fs_cfg_path = get_atomic_dex_data_folder() / "config"; @@ -180,7 +173,7 @@ namespace atomic_dex::utils return fs_cfg_path; } - fs::path + std::filesystem::path get_atomic_dex_export_folder() { const auto fs_export_folder = get_atomic_dex_data_folder() / "exports"; @@ -188,7 +181,7 @@ namespace atomic_dex::utils return fs_export_folder; } - fs::path + std::filesystem::path get_atomic_dex_current_export_recent_swaps_file() { return get_atomic_dex_export_folder() / ("swap-export.json"); @@ -224,7 +217,7 @@ namespace atomic_dex::utils address = final_eth_address; } - fs::path + std::filesystem::path get_current_configs_path() { const auto fs_raw_mm2_shared_folder = get_atomic_dex_data_folder() / get_raw_version() / "configs"; @@ -232,32 +225,6 @@ namespace atomic_dex::utils return fs_raw_mm2_shared_folder; } - std::shared_ptr - register_logger() - { - //! Log Initialization - fs::path path = atomic_dex::utils::get_atomic_dex_current_log_file(); - spdlog::init_thread_pool(g_qsize_spdlog, g_spdlog_thread_count); - auto tp = spdlog::thread_pool(); - auto stdout_sink = std::make_shared(); - -#if defined(_WIN32) || defined(WIN32) - auto rotating_sink = std::make_shared(path.wstring(), g_spdlog_max_file_size, g_spdlog_max_file_rotation); -#else - auto rotating_sink = std::make_shared(path.string(), g_spdlog_max_file_size, g_spdlog_max_file_rotation); -#endif - - std::vector sinks{stdout_sink, rotating_sink}; - auto logger = std::make_shared("log_mt", sinks.begin(), sinks.end(), tp, spdlog::async_overflow_policy::block); - spdlog::register_logger(logger); - spdlog::set_default_logger(logger); - spdlog::set_level(spdlog::level::trace); - spdlog::set_pattern("[%T] [%^%l%$] [%s:%#] [%t]: %v"); - SPDLOG_INFO("Logger successfully initialized"); - - return logger; - } - std::string extract_large_float(const std::string& current) { @@ -268,18 +235,18 @@ namespace atomic_dex::utils return current; } - fs::path + std::filesystem::path get_themes_path() { - fs::path theme_path = get_atomic_dex_data_folder() / "themes"; + std::filesystem::path theme_path = get_atomic_dex_data_folder() / "themes"; create_if_doesnt_exist(theme_path); return theme_path; } - fs::path + std::filesystem::path get_logo_path() { - fs::path logo_path = get_atomic_dex_data_folder() / "logo"; + std::filesystem::path logo_path = get_atomic_dex_data_folder() / "logo"; create_if_doesnt_exist(logo_path); return logo_path; } @@ -306,4 +273,28 @@ namespace atomic_dex::utils } return out; } + + nlohmann::json + read_json_file(std::filesystem::path filepath) + { + nlohmann::json valid_json_data; + + if (std::filesystem::exists(filepath)) + { + QFile ifs; +#if defined(_WIN32) || defined(WIN32) + ifs.setFileName(QString::fromStdWString(filepath.wstring())); +#else + ifs.setFileName(QString::fromStdString(filepath.string())); +#endif + ifs.open(QIODevice::ReadOnly | QIODevice::Text); + std::string json_str = QString(ifs.readAll()).toUtf8().constData(); + if (nlohmann::json::accept(json_str)) + { + valid_json_data = nlohmann::json::parse(json_str); + } + ifs.close(); + } + return valid_json_data; + } } // namespace atomic_dex::utils diff --git a/src/core/atomicdex/utilities/global.utilities.hpp b/src/core/atomicdex/utilities/global.utilities.hpp index 185fcfea12..0f48d63790 100644 --- a/src/core/atomicdex/utilities/global.utilities.hpp +++ b/src/core/atomicdex/utilities/global.utilities.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -16,15 +16,13 @@ #pragma once -//! STD #include +#include -//! Deps #include ///< date::format #include ///< date::make_zoned #include ///< ENTT_API -#include "fs.prerequisites.hpp" #include "safe.float.hpp" #include "atomicdex/config/coins.cfg.hpp" #include "log.prerequisites.hpp" @@ -38,8 +36,8 @@ namespace atomic_dex::utils std::string extract_large_float(const std::string& current); //! Fs helpers - bool create_if_doesnt_exist(const fs::path& path); - std::string u8string(const fs::path& path); + bool create_if_doesnt_exist(const std::filesystem::path& path); + std::string u8string(const std::filesystem::path& path); //std::string u8string(const std::wstring& p); //std::string wstring_to_utf8(const std::wstring& str); //std::string to_utf8(const wchar_t* w); @@ -65,35 +63,36 @@ namespace atomic_dex::utils } } - ENTT_API fs::path get_atomic_dex_data_folder(); + ENTT_API std::filesystem::path get_atomic_dex_data_folder(); /// \brief Gets the path where addressbook configs are stored. - /// \return An fs::path object. - [[nodiscard]] fs::path get_atomic_dex_addressbook_folder(); + /// \return An std::filesystem::path object. + [[nodiscard]] std::filesystem::path get_atomic_dex_addressbook_folder(); - fs::path get_runtime_coins_path() ; + std::filesystem::path get_runtime_coins_path() ; - fs::path get_atomic_dex_logs_folder() ; + std::filesystem::path get_atomic_dex_logs_folder() ; - ENTT_API fs::path get_atomic_dex_current_log_file(); - ENTT_API std::shared_ptr register_logger(); + ENTT_API std::filesystem::path get_atomic_dex_current_log_file(); - ENTT_API fs::path get_current_configs_path(); + ENTT_API std::filesystem::path get_current_configs_path(); - fs::path get_mm2_atomic_dex_current_log_file(); + std::filesystem::path get_mm2_atomic_dex_current_log_file(); - fs::path get_atomic_dex_config_folder(); + std::filesystem::path get_atomic_dex_config_folder(); + + nlohmann::json read_json_file(std::filesystem::path filepath); //std::string minimal_trade_amount_str(); //const t_float_50 minimal_trade_amount(); - fs::path get_atomic_dex_export_folder(); + std::filesystem::path get_atomic_dex_export_folder(); - fs::path get_atomic_dex_current_export_recent_swaps_file(); + std::filesystem::path get_atomic_dex_current_export_recent_swaps_file(); - ENTT_API fs::path get_themes_path(); - ENTT_API fs::path get_logo_path(); + 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); diff --git a/src/core/atomicdex/utilities/kill.cpp b/src/core/atomicdex/utilities/kill.cpp index 55fa3c5221..b4b225b3fc 100644 --- a/src/core/atomicdex/utilities/kill.cpp +++ b/src/core/atomicdex/utilities/kill.cpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2023 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -14,6 +14,9 @@ * * ******************************************************************************/ +#include +#include + //! PCH Headers #include "atomicdex/pch.hpp" @@ -26,11 +29,30 @@ namespace atomic_dex kill_executable(const char* exec_name) { #if defined(__APPLE__) || defined(__linux__) - std::string cmd_line = "killall " + std::string(exec_name); - std::system(cmd_line.c_str()); + std::string cmd_line_check = "pgrep " + std::string(exec_name); + std::string response = execute(cmd_line_check); + if (response != "") + { + std::string cmd_line = "killall " + std::string(exec_name); + std::string response = execute(cmd_line); + } #else std::string cmd_line = "taskkill /F /IM " + std::string(exec_name) + ".exe /T"; - std::system(cmd_line.c_str()); + std::string response = execute(cmd_line); #endif } + + std::string + execute(const std::string& command) + { + system((command + " > temp.txt").c_str()); + + std::ifstream ifs("temp.txt"); + std::string ret{ std::istreambuf_iterator(ifs), std::istreambuf_iterator() }; + ifs.close(); // must close the inout stream so the file can be cleaned up + if (std::remove("temp.txt") != 0) { + SPDLOG_DEBUG("Error deleting temporary file"); + } + return ret; + } } // namespace atomic_dex diff --git a/src/core/atomicdex/utilities/kill.hpp b/src/core/atomicdex/utilities/kill.hpp index 787013adbe..f295cb43b2 100644 --- a/src/core/atomicdex/utilities/kill.hpp +++ b/src/core/atomicdex/utilities/kill.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2023 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -21,4 +21,5 @@ namespace atomic_dex { ENTT_API void kill_executable(const char* exec_name); + std::string execute(const std::string& command); } diff --git a/src/core/atomicdex/utilities/log.prerequisites.hpp b/src/core/atomicdex/utilities/log.prerequisites.hpp index e15c7883db..09fd2333ed 100644 --- a/src/core/atomicdex/utilities/log.prerequisites.hpp +++ b/src/core/atomicdex/utilities/log.prerequisites.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2023 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -22,7 +22,11 @@ #endif #endif -#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE +#ifdef DEBUG + #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE +#else + #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO +#endif #include #include #include @@ -34,9 +38,9 @@ #endif #if defined(_WIN32) || defined(WIN32) -#define LOG_PATH(message, p) SPDLOG_INFO(L"" message, p.wstring()); -#define LOG_PATH_CMP(message, from, to) SPDLOG_INFO(L"" message, from.wstring(), to.wstring()); + #define LOG_PATH(message, p) SPDLOG_INFO(L"" message, p.wstring()); + #define LOG_PATH_CMP(message, from, to) SPDLOG_INFO(L"" message, from.wstring(), to.wstring()); #else -#define LOG_PATH(message, p) SPDLOG_INFO(message, p.string()); -#define LOG_PATH_CMP(message, from, to) SPDLOG_INFO(message, from.string(), to.string()); + #define LOG_PATH(message, p) SPDLOG_INFO(message, p.string()); + #define LOG_PATH_CMP(message, from, to) SPDLOG_INFO(message, from.string(), to.string()); #endif diff --git a/src/core/atomicdex/utilities/qt.download.manager.cpp b/src/core/atomicdex/utilities/qt.download.manager.cpp index 102aaaf00d..040eea5ea2 100644 --- a/src/core/atomicdex/utilities/qt.download.manager.cpp +++ b/src/core/atomicdex/utilities/qt.download.manager.cpp @@ -1,50 +1,69 @@ -// -// Created by Sztergbaum Roman on 04/04/2021. -// +/****************************************************************************** + * Copyright © 2013-2022 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. * + * * + ******************************************************************************/ #include //! Project #include "atomicdex/events/events.hpp" +#include "atomicdex/services/update/zcash.params.service.hpp" #include "atomicdex/utilities/global.utilities.hpp" -#include "qt.download.manager.hpp" +#include "atomicdex/utilities/qt.download.manager.hpp" namespace atomic_dex { - qt_download_manager::qt_download_manager(entt::dispatcher& dispatcher) : m_dispatcher(dispatcher) + qt_downloader::qt_downloader(entt::dispatcher& dispatcher) : m_dispatcher(dispatcher) { - SPDLOG_INFO("qt_download_manager created"); - connect(&m_manager, &QNetworkAccessManager::finished, this, &qt_download_manager::download_finished); + connect(&m_manager, &QNetworkAccessManager::finished, this, &qt_downloader::download_finished); } void - qt_download_manager::do_download(const QUrl& url) + qt_downloader::do_download(const QUrl& url, std::string filename, std::filesystem::path folder) { - m_current_filename = atomic_dex::utils::u8string(fs::path(url.toString().toStdString()).filename()); - m_last_downloaded_path = fs::temp_directory_path() / m_current_filename; + m_download_filename = filename; + m_download_status.insert("filename", QString::fromStdString(filename)); + m_download_path = folder / m_download_filename; QNetworkRequest request(url); request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy); QNetworkReply* reply = m_manager.get(request); - connect(reply, &QNetworkReply::downloadProgress, this, &qt_download_manager::download_progress); + connect(reply, &QNetworkReply::downloadProgress, this, &qt_downloader::download_progress); + m_download_reply = reply; m_current_downloads.append(reply); + m_dispatcher.trigger(); } void - qt_download_manager::download_progress(qint64 bytes_received, qint64 bytes_total) + qt_downloader::download_progress(qint64 bytes_received, qint64 bytes_total) { - m_current_progress = float(bytes_received) / float(bytes_total); - m_dispatcher.trigger(qt_download_progressed{m_current_progress}); - SPDLOG_INFO("bytes_received : {}, bytes_total: {}, percent {}%", bytes_received, bytes_total, m_current_progress * 100); + m_download_progress = float(bytes_received) / float(bytes_total); + m_download_status.insert("progress", m_download_progress); + emit downloadStatusChanged(m_download_status); + m_dispatcher.trigger(m_download_status); + // SPDLOG_INFO("{} bytes_received : {}, bytes_total: {}, percent {}%", m_download_filename, bytes_received, bytes_total, m_download_progress * 100); } void - qt_download_manager::download_finished(QNetworkReply* reply) + qt_downloader::download_finished(QNetworkReply* reply) { auto save_disk_functor = [this](QIODevice* data) { - QFile file(utils::u8string(m_last_downloaded_path).c_str()); + // Todo: handle download fail on front end + QFile file(utils::u8string(m_download_path).c_str()); if (!file.open(QIODevice::WriteOnly)) { - SPDLOG_ERROR("Could not open {} for writing: {}", utils::u8string(m_last_downloaded_path), file.errorString().toStdString()); + SPDLOG_ERROR("Could not open {} for writing: {}", utils::u8string(m_download_path), file.errorString().toStdString()); + m_dispatcher.trigger(); return false; } @@ -60,11 +79,11 @@ namespace atomic_dex } else { - SPDLOG_INFO("Successfully downloaded: {}", m_current_filename); + SPDLOG_INFO("Successfully downloaded: {}", m_download_filename); if (save_disk_functor(reply)) { - SPDLOG_INFO("Successfully saved {} to {}", url.toString().toStdString(), utils::u8string(m_last_downloaded_path)); - m_dispatcher.trigger(); + SPDLOG_INFO("Successfully saved {} to {}", url.toString().toStdString(), utils::u8string(m_download_path)); + m_dispatcher.trigger(); } } @@ -72,11 +91,23 @@ namespace atomic_dex reply->deleteLater(); } - fs::path - qt_download_manager::get_last_download_path() const + QNetworkReply* + qt_downloader::get_reply() const { - return m_last_downloaded_path; + return m_download_reply; } - qt_download_manager::~qt_download_manager() {} -} // namespace atomic_dex \ No newline at end of file + std::filesystem::path + qt_downloader::get_last_download_path() const + { + return m_download_path; + } + + QJsonObject + qt_downloader::get_download_status() const + { + return m_download_status; + } + + qt_downloader::~qt_downloader() {} +} // namespace atomic_dex diff --git a/src/core/atomicdex/utilities/qt.download.manager.hpp b/src/core/atomicdex/utilities/qt.download.manager.hpp index 5705fdf589..68823985d7 100644 --- a/src/core/atomicdex/utilities/qt.download.manager.hpp +++ b/src/core/atomicdex/utilities/qt.download.manager.hpp @@ -1,5 +1,22 @@ +/****************************************************************************** + * Copyright © 2013-2022 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 #include #include @@ -10,31 +27,37 @@ namespace atomic_dex { - class qt_download_manager : public QObject + class qt_downloader : public QObject { Q_OBJECT + Q_PROPERTY(QJsonObject download_status READ get_download_status NOTIFY downloadStatusChanged) + entt::dispatcher& m_dispatcher; QNetworkAccessManager m_manager; - std::string m_current_filename; - fs::path m_last_downloaded_path; + std::string m_download_filename; + std::filesystem::path m_download_path; QVector m_current_downloads; - float m_current_progress; + float m_download_progress; + QJsonObject m_download_status; + QNetworkReply* m_download_reply; public: - qt_download_manager(entt::dispatcher& dispatcher); - ~qt_download_manager(); + qt_downloader(entt::dispatcher& dispatcher); + ~qt_downloader(); + + void do_download(const QUrl& url, std::string filename, std::filesystem::path folder); + [[nodiscard]] std::filesystem::path get_last_download_path() const; + [[nodiscard]] QJsonObject get_download_status() const; + [[nodiscard]] QJsonObject get_combined_download_status() const; + [[nodiscard]] QNetworkReply* get_reply() const; - void do_download(const QUrl& url); - [[nodiscard]] fs::path get_last_download_path() const; + signals: + void downloadStatusChanged(QJsonObject &status); public slots: void download_finished(QNetworkReply* reply); void download_progress(qint64 bytes_received, qint64 bytes_total); }; - struct qt_download_progressed - { - float progress; - }; -} // namespace atomic_dex \ No newline at end of file +} // namespace atomic_dex diff --git a/src/core/atomicdex/utilities/qt.utilities.cpp b/src/core/atomicdex/utilities/qt.utilities.cpp index 9d091bb971..a2f9e0faac 100644 --- a/src/core/atomicdex/utilities/qt.utilities.cpp +++ b/src/core/atomicdex/utilities/qt.utilities.cpp @@ -81,7 +81,7 @@ namespace atomic_dex } QString - std_path_to_qstring(const fs::path& path) + std_path_to_qstring(const std::filesystem::path& path) { QString out; #if defined(_WIN32) || defined(WIN32) @@ -112,10 +112,10 @@ namespace atomic_dex qt_utilities::get_themes_list() const { QStringList out; - const fs::path theme_path = atomic_dex::utils::get_themes_path(); - for (auto&& cur: fs::directory_iterator(theme_path)) + const std::filesystem::path theme_path = atomic_dex::utils::get_themes_path(); + for (auto&& cur: std::filesystem::directory_iterator(theme_path)) { - if (!fs::exists(cur.path() / "colors.json")) continue; + if (!std::filesystem::exists(cur.path() / "colors.json")) continue; out << std_path_to_qstring(cur.path().filename()); } @@ -126,8 +126,8 @@ namespace atomic_dex qt_utilities::save_theme(const QString& filename, const QVariantMap& theme_object, bool overwrite) { bool result = true; - fs::path file_path = atomic_dex::utils::get_themes_path() / filename.toStdString() / "colors.json"; - if (!overwrite && fs::exists(file_path)) + std::filesystem::path file_path = atomic_dex::utils::get_themes_path() / filename.toStdString() / "colors.json"; + if (!overwrite && std::filesystem::exists(file_path)) { result = false; } @@ -150,8 +150,8 @@ namespace atomic_dex using namespace std::string_literals; // Loads color scheme. - fs::path file_path = atomic_dex::utils::get_themes_path() / theme_name.toStdString() / "colors.json"; - if (fs::exists(file_path)) + std::filesystem::path file_path = atomic_dex::utils::get_themes_path() / theme_name.toStdString() / "colors.json"; + if (std::filesystem::exists(file_path)) { LOG_PATH("load theme: {}", file_path); QFile file; diff --git a/src/core/atomicdex/utilities/qt.utilities.hpp b/src/core/atomicdex/utilities/qt.utilities.hpp index 036c8c0df7..cf905f1b08 100644 --- a/src/core/atomicdex/utilities/qt.utilities.hpp +++ b/src/core/atomicdex/utilities/qt.utilities.hpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2013-2021 The Komodo Platform Developers. * + * Copyright © 2013-2022 The Komodo Platform Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -16,7 +16,6 @@ #pragma once -//! QT Headers #include #include #include @@ -24,8 +23,8 @@ #include #include #include //> QCryptographicHash::hash, QCryptographicHash::Keccak_256 +#include -//! Project Headers #include "atomicdex/config/app.cfg.hpp" #include "atomicdex/config/coins.cfg.hpp" #include "atomicdex/config/wallet.cfg.hpp" @@ -33,9 +32,8 @@ namespace atomic_dex { - template - auto - update_value(int role, const QVariant& value, const QModelIndex& idx, TModel& model) + template + inline auto update_value(int role, const QVariant& value, const QModelIndex& idx, QtModel& model) { if (auto prev_value = model.data(idx, role); value != prev_value) { @@ -45,7 +43,7 @@ namespace atomic_dex return std::make_tuple(value, value, false); } - QString std_path_to_qstring(const fs::path& path); + QString std_path_to_qstring(const std::filesystem::path& path); QStringList vector_std_string_to_qt_string_list(const std::vector& vec); ENTT_API QStringList qt_variant_list_to_qt_string_list(const QVariantList& variant_list); QJsonArray nlohmann_json_array_to_qt_json_array(const nlohmann::json& j); @@ -54,8 +52,7 @@ namespace atomic_dex const atomic_dex::komodo_prices_provider& provider, const atomic_dex::coin_config& 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) + [[nodiscard]] QString inline sha256_qstring_from_qt_byte_array(const QByteArray& byte_array) { return QLatin1String(QCryptographicHash::hash(byte_array, QCryptographicHash::Sha256).toHex()); } diff --git a/src/core/atomicdex/utilities/security.utilities.cpp b/src/core/atomicdex/utilities/security.utilities.cpp index 20a866048d..d73a11fbb0 100644 --- a/src/core/atomicdex/utilities/security.utilities.cpp +++ b/src/core/atomicdex/utilities/security.utilities.cpp @@ -50,7 +50,7 @@ namespace atomic_dex t_password_key derive_password(const std::string& password, std::error_code& ec) { - SPDLOG_DEBUG("{} l{} f[{}]", __FUNCTION__, __LINE__, fs::path(__FILE__).filename().string()); + SPDLOG_DEBUG("{} l{} f[{}]", __FUNCTION__, __LINE__, std::filesystem::path(__FILE__).filename().string()); t_salt_array salt{}; t_password_key generated_crypto_key{}; @@ -71,9 +71,9 @@ namespace atomic_dex } void - encrypt(const fs::path& target_path, const char* mnemonic, const unsigned char* key) + encrypt(const std::filesystem::path& target_path, const char* mnemonic, const unsigned char* key) { - SPDLOG_DEBUG("{} l{} f[{}]", __FUNCTION__, __LINE__, fs::path(__FILE__).filename().string()); + SPDLOG_DEBUG("{} l{} f[{}]", __FUNCTION__, __LINE__, std::filesystem::path(__FILE__).filename().string()); std::array buf_in{}; std::array buf_out{}; @@ -98,9 +98,9 @@ namespace atomic_dex } std::string - decrypt(const fs::path& encrypted_file_path, const unsigned char* key, std::error_code& ec) + decrypt(const std::filesystem::path& encrypted_file_path, const unsigned char* key, std::error_code& ec) { - SPDLOG_DEBUG("{} l{} f[{}]", __FUNCTION__, __LINE__, fs::path(__FILE__).filename().string()); + SPDLOG_DEBUG("{} l{} f[{}]", __FUNCTION__, __LINE__, std::filesystem::path(__FILE__).filename().string()); std::array buf_in{}; std::array buf_out{}; diff --git a/src/core/atomicdex/utilities/security.utilities.hpp b/src/core/atomicdex/utilities/security.utilities.hpp index 683b617c42..502eaadd8f 100644 --- a/src/core/atomicdex/utilities/security.utilities.hpp +++ b/src/core/atomicdex/utilities/security.utilities.hpp @@ -24,8 +24,8 @@ namespace atomic_dex inline constexpr std::size_t g_key_len = crypto_secretstream_xchacha20poly1305_KEYBYTES; using t_password_key = std::array; t_password_key derive_password(const std::string& password, std::error_code& ec); - void encrypt(const fs::path& target_path, const char* mnemonic, const unsigned char* key); - std::string decrypt(const fs::path& encrypted_file_path, const unsigned char* key, std::error_code& ec); + void encrypt(const std::filesystem::path& target_path, const char* mnemonic, const unsigned char* key); + std::string decrypt(const std::filesystem::path& encrypted_file_path, const unsigned char* key, std::error_code& ec); bool is_valid_generated_rpc_password(const std::string& pass); std::string gen_random_password(); const char* get_regex_password_policy(); diff --git a/src/core/atomicdex/version/version.hpp b/src/core/atomicdex/version/version.hpp index 168d93b7eb..ee2e5373d4 100644 --- a/src/core/atomicdex/version/version.hpp +++ b/src/core/atomicdex/version/version.hpp @@ -21,24 +21,24 @@ namespace atomic_dex constexpr const char* get_version() { - return "0.5.5-beta"; + return "0.5.7-beta"; } constexpr int get_num_version() noexcept { - return 55; + return 57; } constexpr const char* get_raw_version() { - return "0.5.5"; + return "0.5.7"; } constexpr const char* get_precedent_raw_version() { - return "0.5.4"; + return "0.5.5"; } } // namespace atomic_dex diff --git a/src/tests/api/github/github.api.tests.cpp b/src/tests/api/github/github.api.tests.cpp deleted file mode 100644 index 95beb9a611..0000000000 --- a/src/tests/api/github/github.api.tests.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// Deps headers -#include -#include - -// Project headers -#include "atomicdex/api/github/github.api.hpp" -#include "atomicdex/version/version.hpp" - -TEST_CASE("Fetch last GitHub release and compare with current") -{ - atomic_dex::github_api::repository_releases_request request {.owner = "firoorg", .repository = "FiroDEX-Desktop"}; - atomic_dex::github_api::get_repository_releases_async(request) - .then([](web::http::http_response resp) - { - REQUIRE(resp.status_code() == static_cast(antara::app::http_code::ok)); - CHECK(atomic_dex::github_api::get_last_repository_release_from_http_response(resp).tag_name == atomic_dex::get_version()); - }) - .then(&handle_exception_pplx_task) - .wait(); -} \ No newline at end of file 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 new file mode 100644 index 0000000000..e11678a5c8 --- /dev/null +++ b/src/tests/api/mm2/enable_bch_with_tokens_rpc_tests.cpp @@ -0,0 +1,103 @@ +#include + +#include "atomicdex/api/mm2/enable_bch_with_tokens_rpc.hpp" + +TEST_CASE("enable_bch_with_tokens_request_rpc serialization") +{ + using namespace atomic_dex::mm2; + + nlohmann::json result; + enable_bch_with_tokens_request_rpc data + { + .ticker = "BCH", + .allow_slp_unsafe_conf = false, + .bchd_urls = {"https://bchd.imaginary.cash:8335/"}, + .mode = + { + .rpc = "Electrum", + .rpc_data = + { + .servers = { { .url = "electrum1.cipig.net:10055" }, { .url = "electrum1.cipig.net:20055", .protocol = "SSL" } } + } + }, + .tx_history = true, + .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 } + }; + + nlohmann::to_json(result, data); + + CHECK_EQ(result["ticker"], "BCH"); + CHECK_FALSE(result["allow_slp_unsafe_conf"]); + CHECK_EQ(result["bchd_urls"].size(), 1); + CHECK_EQ(result["bchd_urls"][0].get(), "https://bchd.imaginary.cash:8335/"); + CHECK(result["tx_history"]); + CHECK_EQ(result["slp_tokens_requests"].size(), 1); + CHECK_EQ(result["slp_tokens_requests"][0]["ticker"], "ASLP"); + CHECK_EQ(result["slp_tokens_requests"][0]["required_confirmations"], 4); + CHECK_EQ(result["required_confirmations"], 5); + CHECK_FALSE(result["requires_notarization"]); + CHECK_EQ(result["address_format"]["format"], "cashaddress"); + CHECK_EQ(result["address_format"]["network"], "bitcoincash"); + CHECK_EQ(result["utxo_merge_params"]["merge_at"], 50); + CHECK_EQ(result["utxo_merge_params"]["check_every"], 10); + CHECK_EQ(result["utxo_merge_params"]["max_merge_at_once"], 25); +} + +TEST_CASE("enable_bch_with_tokens_result_rpc deserialization") +{ + using namespace atomic_dex::mm2; + + enable_bch_with_tokens_result_rpc result; + nlohmann::json json = nlohmann::json::parse(R"( + { + "current_block":1480481, + "bch_addresses_infos": { + "bitcoincash:qrf5vpn78s7rjexrjhlwyzzeg7gw98k7t5qx64fztj": { + "derivation_method": { + "type":"Iguana" + }, + "pubkey":"036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202c", + "balances": { + "spendable":"0.11398301", + "unspendable":"0.00001" + } + } + }, + "slp_addresses_infos": { + "simpleledger:qrf5vpn78s7rjexrjhlwyzzeg7gw98k7t5va3wuz4v":{ + "derivation_method": { + "type":"Iguana" + }, + "pubkey":"036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202c", + "balances": { + "ASLP":{ + "spendable":"5.2974", + "unspendable":"0" + } + } + } + } + })"); + + nlohmann::from_json(json, result); + + CHECK_EQ(result.current_block, 1480481); + CHECK_EQ(result.bch_addresses_infos.size(), 1); + CHECK(result.bch_addresses_infos.contains("bitcoincash:qrf5vpn78s7rjexrjhlwyzzeg7gw98k7t5qx64fztj")); + CHECK_EQ(result.bch_addresses_infos["bitcoincash:qrf5vpn78s7rjexrjhlwyzzeg7gw98k7t5qx64fztj"].derivation_method.type, "Iguana"); + CHECK_EQ(result.bch_addresses_infos["bitcoincash:qrf5vpn78s7rjexrjhlwyzzeg7gw98k7t5qx64fztj"].pubkey, "036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202c"); + CHECK_EQ(result.bch_addresses_infos["bitcoincash:qrf5vpn78s7rjexrjhlwyzzeg7gw98k7t5qx64fztj"].balances.spendable, "0.11398301"); + CHECK_EQ(result.bch_addresses_infos["bitcoincash:qrf5vpn78s7rjexrjhlwyzzeg7gw98k7t5qx64fztj"].balances.unspendable, "0.00001"); + CHECK_EQ(result.slp_addresses_infos.size(), 1); + CHECK(result.slp_addresses_infos.contains("simpleledger:qrf5vpn78s7rjexrjhlwyzzeg7gw98k7t5va3wuz4v")); + CHECK_EQ(result.slp_addresses_infos["simpleledger:qrf5vpn78s7rjexrjhlwyzzeg7gw98k7t5va3wuz4v"].derivation_method.type, "Iguana"); + CHECK_EQ(result.slp_addresses_infos["simpleledger:qrf5vpn78s7rjexrjhlwyzzeg7gw98k7t5va3wuz4v"].pubkey, "036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202c"); + CHECK_EQ(result.slp_addresses_infos["simpleledger:qrf5vpn78s7rjexrjhlwyzzeg7gw98k7t5va3wuz4v"].balances.size(), 1); + CHECK(result.slp_addresses_infos["simpleledger:qrf5vpn78s7rjexrjhlwyzzeg7gw98k7t5va3wuz4v"].balances.contains("ASLP")); + CHECK_EQ(result.slp_addresses_infos["simpleledger:qrf5vpn78s7rjexrjhlwyzzeg7gw98k7t5va3wuz4v"].balances["ASLP"].spendable, "5.2974"); + CHECK_EQ(result.slp_addresses_infos["simpleledger:qrf5vpn78s7rjexrjhlwyzzeg7gw98k7t5va3wuz4v"].balances["ASLP"].unspendable, "0"); +} \ 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 new file mode 100644 index 0000000000..358a240cdc --- /dev/null +++ b/src/tests/api/mm2/mm2.api.balance.infos.tests.cpp @@ -0,0 +1,36 @@ +/****************************************************************************** + * Copyright © 2013-2022 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 "doctest/doctest.h" +#include + +#include "atomicdex/api/mm2/balance.infos.hpp" + +TEST_CASE("mm2::balance_infos deserialization") +{ + const nlohmann::json json = R"( + { + "balances":{ + "spendable":"0.11398301", + "unspendable":"0.00001" + } + })"_json; + atomic_dex::mm2::balance_infos infos; + atomic_dex::mm2::from_json(json.at("balances"), infos); + CHECK_EQ(infos.spendable, "0.11398301"); + CHECK_EQ(infos.unspendable, "0.00001"); +} \ No newline at end of file diff --git a/src/tests/api/mm2/mm2.api.format.address.tests.cpp b/src/tests/api/mm2/mm2.api.format.address.tests.cpp new file mode 100644 index 0000000000..0866934bad --- /dev/null +++ b/src/tests/api/mm2/mm2.api.format.address.tests.cpp @@ -0,0 +1,36 @@ +/****************************************************************************** + * Copyright © 2013-2022 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 "doctest/doctest.h" +#include + +#include "atomicdex/api/mm2/format.address.hpp" + +TEST_CASE("mm2::address_format serialisation") +{ + const nlohmann::json expected_json = R"( + { + "format":"cashaddress", + "network":"bchtest" + } + )"_json; + atomic_dex::mm2::format_address request{.format = "cashaddress", .network = "bchtest"}; + nlohmann::json j; + + atomic_dex::mm2::to_json(j, request); + CHECK_EQ(j, expected_json); +} \ No newline at end of file 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 new file mode 100644 index 0000000000..383a45183f --- /dev/null +++ b/src/tests/api/mm2/mm2.api.utxo.merge.params.tests.cpp @@ -0,0 +1,36 @@ +/****************************************************************************** + * Copyright © 2013-2022 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 "doctest/doctest.h" +#include + +#include "atomicdex/api/mm2/utxo.merge.params.hpp" + +TEST_CASE("mm2::utxo_merge_params serialisation") +{ + const nlohmann::json expected_json = R"( + { + "merge_at":50, + "check_every":10, + "max_merge_at_once":25 + } + )"_json; + atomic_dex::mm2::utxo_merge_params 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); +} \ No newline at end of file diff --git a/src/tests/api/mm2/mm2.fraction.tests.cpp b/src/tests/api/mm2/mm2.fraction.tests.cpp index 2b5400574b..148edf607e 100644 --- a/src/tests/api/mm2/mm2.fraction.tests.cpp +++ b/src/tests/api/mm2/mm2.fraction.tests.cpp @@ -14,7 +14,7 @@ //! Project Headers #include "atomicdex/api/mm2/fraction.hpp" -TEST_CASE("mm2::api::fraction deserialisation") +TEST_CASE("atomic_dex::mm2::fraction deserialisation") { nlohmann::json fraction_json = R"( { @@ -22,8 +22,8 @@ TEST_CASE("mm2::api::fraction deserialisation") "numer": "333" } )"_json; - mm2::api::fraction fraction; - mm2::api::from_json(fraction_json, fraction); + atomic_dex::mm2::fraction fraction; + atomic_dex::mm2::from_json(fraction_json, fraction); CHECK_EQ(fraction.numer, "333"); CHECK_EQ(fraction.denom, "777"); diff --git a/src/tests/api/mm2/mm2.rpc.trade.preimage.tests.cpp b/src/tests/api/mm2/mm2.rpc.trade.preimage.tests.cpp index 97f6485368..1dce6caf12 100644 --- a/src/tests/api/mm2/mm2.rpc.trade.preimage.tests.cpp +++ b/src/tests/api/mm2/mm2.rpc.trade.preimage.tests.cpp @@ -234,37 +234,37 @@ namespace })"_json; } // namespace -TEST_CASE("mm2::api::preimage_request serialisation") +TEST_CASE("atomic_dex::mm2::preimage_request serialisation") { atomic_dex::t_trade_preimage_request request{.base_coin = "KMD", .rel_coin = "BTC", .swap_method = "buy", .volume = "10"}; nlohmann::json j; - mm2::api::to_json(j, request); + atomic_dex::mm2::to_json(j, request); CHECK_EQ(j, g_preimage_request_buy_kmd_btc); } -TEST_CASE("mm2::api::coin_fee deserialization") +TEST_CASE("atomic_dex::mm2::coin_fee deserialization") { - mm2::api::coin_fee answer; - mm2::api::from_json(g_coin_fee_answer, answer); + atomic_dex::mm2::coin_fee answer; + atomic_dex::mm2::from_json(g_coin_fee_answer, answer); CHECK_EQ("0.00042049", answer.amount); CHECK_EQ("BTC", answer.coin); CHECK_EQ("100000000", answer.amount_fraction.denom); } -TEST_CASE("mm2::api::preimage_answer_success deserialization from buy") +TEST_CASE("atomic_dex::mm2::preimage_answer_success deserialization from buy") { - mm2::api::trade_preimage_answer_success answer; - mm2::api::from_json(g_preimage_answer_success_buy, answer); + atomic_dex::mm2::trade_preimage_answer_success answer; + atomic_dex::mm2::from_json(g_preimage_answer_success_buy, answer); CHECK(answer.taker_fee.has_value()); CHECK(answer.fee_to_send_taker_fee.has_value()); } -TEST_SUITE("mm2::api::preimage_answer deserialization test suites") +TEST_SUITE("atomic_dex::mm2::preimage_answer deserialization test suites") { TEST_CASE("setprice BTC/RICK") { atomic_dex::t_trade_preimage_answer answer; - mm2::api::from_json(g_preimage_answer_setprice, answer); + atomic_dex::mm2::from_json(g_preimage_answer_setprice, answer); CHECK(answer.result.has_value()); CHECK_FALSE(answer.error.has_value()); CHECK_FALSE(answer.result.value().fee_to_send_taker_fee.has_value()); @@ -273,7 +273,7 @@ TEST_SUITE("mm2::api::preimage_answer deserialization test suites") TEST_CASE("buy BTC/RICK") { atomic_dex::t_trade_preimage_answer answer; - mm2::api::from_json(g_preimage_answer_buy, answer); + atomic_dex::mm2::from_json(g_preimage_answer_buy, answer); CHECK(answer.result.has_value()); CHECK_FALSE(answer.error.has_value()); CHECK(answer.result.value().fee_to_send_taker_fee.has_value()); @@ -282,7 +282,7 @@ TEST_SUITE("mm2::api::preimage_answer deserialization test suites") TEST_CASE("sell max BTC/RICK") { atomic_dex::t_trade_preimage_answer answer; - mm2::api::from_json(g_preimage_answer_sell_max, answer); + atomic_dex::mm2::from_json(g_preimage_answer_sell_max, answer); CHECK(answer.result.has_value()); CHECK_FALSE(answer.error.has_value()); CHECK(answer.result.value().fee_to_send_taker_fee.has_value()); @@ -291,7 +291,7 @@ TEST_SUITE("mm2::api::preimage_answer deserialization test suites") TEST_CASE("setprice ERC20 BAT/RICK") { atomic_dex::t_trade_preimage_answer answer; - mm2::api::from_json(g_preimage_answer_setprice_erc, answer); + atomic_dex::mm2::from_json(g_preimage_answer_setprice_erc, answer); CHECK(answer.result.has_value()); CHECK_FALSE(answer.error.has_value()); CHECK_FALSE(answer.result.value().fee_to_send_taker_fee.has_value()); @@ -323,7 +323,7 @@ TEST_SUITE("mm2::api::preimage_answer deserialization test suites") #include "atomicdex/api/mm2/mm2.hpp" #include "atomicdex/api/mm2/rpc.trade.preimage.hpp" ///< replace this one by your current rpc file */ -SCENARIO("mm2::api::preimage scenario") +SCENARIO("atomic_dex::mm2::preimage scenario") { /** * Checking that the test context is valid @@ -335,7 +335,7 @@ SCENARIO("mm2::api::preimage scenario") CHECK(batch.is_array()); //! Prepare request template - nlohmann::json request_json = ::mm2::api::template_request("trade_preimage"); + nlohmann::json request_json = atomic_dex::mm2::template_request("trade_preimage"); //! Retrieve mm2 service auto& mm2 = g_context->system_manager().get_system(); @@ -368,7 +368,7 @@ SCENARIO("mm2::api::preimage scenario") CHECK(batch.empty()); //! Give the concrete C++ type - here it's atomic_dex::t_trade_preimage_answer - return ::mm2::api::rpc_process_answer_batch(answers[0], "trade_preimage"); + return atomic_dex::mm2::rpc_process_answer_batch(answers[0], "trade_preimage"); }; //! A test with RICK/MORTY @@ -378,7 +378,7 @@ SCENARIO("mm2::api::preimage scenario") atomic_dex::t_trade_preimage_request request{.base_coin = "RICK", .rel_coin = "MORTY", .swap_method = "buy", .volume = "1", .price = "1"}; //! Transform request into json - ::mm2::api::to_json(request_json, request); + atomic_dex::mm2::to_json(request_json, request); //! Add it to the batch request batch.push_back(request_json); @@ -406,7 +406,7 @@ SCENARIO("mm2::api::preimage scenario") GIVEN("Preparing a wrong request RICK/NONEXISTENT coin") { atomic_dex::t_trade_preimage_request request{.base_coin = "RICK", .rel_coin = "NONEXISTENT", .swap_method = "buy", .volume = "1"}; - ::mm2::api::to_json(request_json, request); + atomic_dex::mm2::to_json(request_json, request); batch.push_back(request_json); auto copy_request = request_json; copy_request["userpass"] = ""; diff --git a/src/tests/atomic.dex.tests.cpp b/src/tests/atomic.dex.tests.cpp index 38b1f9bc22..936f62e1a8 100644 --- a/src/tests/atomic.dex.tests.cpp +++ b/src/tests/atomic.dex.tests.cpp @@ -34,7 +34,7 @@ main(int argc, char** argv) context.applyCommandLine(argc, argv); - atomic_dex::kill_executable("mm2"); + atomic_dex::kill_executable(atomic_dex::g_dex_api); QStringList args; const int ac = argc; diff --git a/src/tests/atomic.dex.tests.hpp b/src/tests/atomic.dex.tests.hpp index 17ae488894..93b3611a39 100644 --- a/src/tests/atomic.dex.tests.hpp +++ b/src/tests/atomic.dex.tests.hpp @@ -100,7 +100,7 @@ struct tests_context : public antara::gaming::world::app if (!found) { SPDLOG_INFO("Extra coins not enabled yet, enabling now"); - mm2.enable_multiple_coins(m_extra_coins); + mm2.enable_coins(m_extra_coins); } while (!m_extra_coins_ready) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } //! At this point BTC/KMD are enabled but we need ERC20 and QRC20 too / change login behaviour ? diff --git a/src/tests/config/coins.cfg.tests.cpp b/src/tests/config/coins.cfg.tests.cpp index 84f736f3d6..a968fa0af7 100644 --- a/src/tests/config/coins.cfg.tests.cpp +++ b/src/tests/config/coins.cfg.tests.cpp @@ -21,7 +21,7 @@ t_http_client_ptr g_komodolive_client{std::make_unique(FROM_S TEST_CASE("generate all coinpaprika possibilities") { #if defined(__APPLE__) - const auto resp = ::mm2::api::async_process_rpc_get(g_komodolive_client, "tickers", "/ticker").get(); + const auto resp = atomic_dex::mm2::async_process_rpc_get(g_komodolive_client, "tickers", "/ticker").get(); std::string body = TO_STD_STR(resp.extract_string(true).get()); nlohmann::json j_metrics = nlohmann::json::parse(body); nlohmann::json metrics = nlohmann::json::object(); @@ -31,7 +31,7 @@ TEST_CASE("generate all coinpaprika possibilities") } std::unordered_set visited; - fs::path cfg_path = antara::gaming::core::assets_real_path() / "config" / "0.4.2-coins.json"; + std::filesystem::path cfg_path = antara::gaming::core::assets_real_path() / "config" / "0.4.2-coins.json"; std::ifstream ifs(cfg_path.string()); nlohmann::json j; ifs >> j; diff --git a/src/tests/models/qt.addressbook.contact.model.tests.cpp b/src/tests/models/qt.addressbook.contact.model.tests.cpp index 4af6fb1c0e..1766bb4646 100644 --- a/src/tests/models/qt.addressbook.contact.model.tests.cpp +++ b/src/tests/models/qt.addressbook.contact.model.tests.cpp @@ -60,7 +60,7 @@ TEST_CASE("addressbook_contact_model") WHEN("A category is added") { - CHECK(contact_model.add_category("CEO") == true); + CHECK(contact_model.addCategory("CEO") == true); THEN("get_categories should return 5 categories") { @@ -88,7 +88,7 @@ TEST_CASE("addressbook_contact_model") WHEN("A category is removed") { - contact_model.remove_category("Friend"); + contact_model.removeCategory("Friend"); THEN("get_categories should return 3 categories") { diff --git a/src/tests/utilities/global.utilities.tests.cpp b/src/tests/utilities/global.utilities.tests.cpp index f257470229..fa39364f1d 100644 --- a/src/tests/utilities/global.utilities.tests.cpp +++ b/src/tests/utilities/global.utilities.tests.cpp @@ -35,14 +35,14 @@ TEST_CASE("atomic_dex::utils::get_atomic_dex_logs_folder()") { auto result = get_atomic_dex_logs_folder(); CHECK_FALSE(result.string().empty()); - CHECK(fs::exists(result)); + CHECK(std::filesystem::exists(result)); } TEST_CASE("atomic_dex::utils::get_atomic_dex_current_log_file()") { auto result = get_atomic_dex_current_log_file(); CHECK_FALSE(result.string().empty()); - CHECK_FALSE(fs::exists(result)); + CHECK_FALSE(std::filesystem::exists(result)); } TEST_CASE("atomic_dex::utils::adjust_precision()") @@ -54,12 +54,12 @@ TEST_CASE("atomic_dex::utils::adjust_precision()") TEST_CASE("atomic_dex::utils::create_if_doesnt_exist()") { - fs::path tmp_path = fs::temp_directory_path() / "fake_dir"; - CHECK_FALSE(fs::exists(tmp_path)); + std::filesystem::path tmp_path = std::filesystem::temp_directory_path() / "fake_dir"; + CHECK_FALSE(std::filesystem::exists(tmp_path)); CHECK(create_if_doesnt_exist(tmp_path)); - CHECK(fs::exists(tmp_path)); - fs::remove(tmp_path); - CHECK_FALSE(fs::exists(tmp_path)); + CHECK(std::filesystem::exists(tmp_path)); + std::filesystem::remove(tmp_path); + CHECK_FALSE(std::filesystem::exists(tmp_path)); } TEST_CASE("atomic_dex::utils::determine_balance_factor()") @@ -81,23 +81,21 @@ TEST_CASE("atomic_dex::utils::get_atomic_dex_addressbook_folder()") { auto result = get_atomic_dex_addressbook_folder(); CHECK_FALSE(result.string().empty()); - CHECK(fs::exists(result)); + CHECK(std::filesystem::exists(result)); } TEST_CASE("atomic_dex::utils::get_runtime_coins_path()") { auto result = get_runtime_coins_path(); CHECK_FALSE(result.string().empty()); - CHECK(fs::exists(result)); + CHECK(std::filesystem::exists(result)); } -TEST_CASE("atomic_dex::utils::register_logger()") { CHECK_NE(register_logger(), nullptr); } - TEST_CASE("atomic_dex::utils::get_current_configs_path()") { auto result = get_current_configs_path(); CHECK_FALSE(result.string().empty()); - CHECK(fs::exists(result)); + CHECK(std::filesystem::exists(result)); } TEST_CASE("atomic_dex::utils::retrieve_main_ticker()") @@ -122,7 +120,7 @@ TEST_CASE("generate_random_password") { using namespace std::string_literals; std::wstring other_path = L"C:\\Users\\Антон\\AppData\\Roaming\\atomic_qt\\0.4.3\\configs\\coins.json"s; - fs::path cur_path = other_path; + std::filesystem::path cur_path = other_path; CHECK_EQ(u8string(other_path), "C:\\Users\\Антон\\AppData\\Roaming\\atomic_qt\\0.4.3\\configs\\coins.json"s); CHECK_EQ(u8string(cur_path), "C:\\Users\\Антон\\AppData\\Roaming\\atomic_qt\\0.4.3\\configs\\coins.json"s); CHECK_EQ(to_utf8(cur_path.wstring().c_str()), "C:\\Users\\Антон\\AppData\\Roaming\\atomic_qt\\0.4.3\\configs\\coins.json"s); diff --git a/tools/linux/.gitignore b/tools/linux/.gitignore new file mode 100644 index 0000000000..18d999ecf4 --- /dev/null +++ b/tools/linux/.gitignore @@ -0,0 +1,2 @@ +linuxdeploy-x86_64.AppImage + diff --git a/vcpkg.json b/vcpkg.json index 040a73da17..7aa536cca7 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "atomicdex-desktop", - "version-string": "0.5.5", + "version-string": "0.5.7", "dependencies": [ "entt", "boost-multiprecision", diff --git a/wally/wally.dll b/wally/wally.dll deleted file mode 100644 index 0f90ef5249..0000000000 Binary files a/wally/wally.dll and /dev/null differ