More fixes and improvements

This commit is contained in:
Artur
2025-03-11 16:13:26 -03:00
parent 1aea8d47b4
commit 1d5e009ddc
17 changed files with 261 additions and 187 deletions

View File

@@ -2,12 +2,14 @@ BITCOIN_ELECTRUM_RPC_URL="http://btc-electrum:7000"
BITCOIN_ELECTRUM_RPC_USERNAME="user"
BITCOIN_ELECTRUM_RPC_PASSWORD=""
LITECOIN_ELECTRUM_RPC_URL="http://ltc-electrum:7000"
LITECOIN_MWEB_ELECTRUM_RPC_URL="http://ltc-mweb-electrum:7000"
LITECOIN_ELECTRUM_RPC_USERNAME="user"
LITECOIN_ELECTRUM_RPC_PASSWORD=""
BITCOIN_ELECTRUM_SERVER_ADDRESS=""
LITECOIN_ELECTRUM_SERVER_ADDRESS=""
BITCOIN_WALLET_SEED=""
LITECOIN_WALLET_SEED=""
LITECOIN_MWEB_WALLET_SEED=""
MONERO_DAEMON_ADDRESS=""
MONERO_RPC_URL=""
@@ -17,10 +19,6 @@ MONERO_WALLET_SEED=""
MONERO_WALLET_PASSWORD=""
MONERO_WALLET_HEIGHT=""
NBXPLORER_URL=""
NBXPLORER_USERNAME=""
NBXPLORER_PASSWORD=""
KRAKEN_API_KEY=""
KRAKEN_API_SECRET=""

View File

@@ -25,16 +25,33 @@ jobs:
git pull
echo "Starting..."
ELECTRUM_RPC_USERNAME="user" \
ELECTRUM_RPC_PASSWORD="${{ secrets.ELECTRUM_RPC_PASSWORD }}" \
BITCOIN_WALLET_SEED="${{ secrets.BITCOIN_WALLET_SEED }}" \
MONERO_DAEMON_ADDRESS="${{ secrets.MONERO_DAEMON_ADDRESS }}" \
MONERO_RPC_USERNAME="user" \
MONERO_RPC_PASSWORD="${{ secrets.MONERO_RPC_PASSWORD }}" \
MONERO_WALLET_SEED="${{ secrets.MONERO_WALLET_SEED }}" \
MONERO_WALLET_PASSWORD="${{ secrets.MONERO_WALLET_PASSWORD }}" \
MONERO_WALLET_HEIGHT="${{ secrets.MONERO_WALLET_HEIGHT }}" \
KRAKEN_API_KEY="${{ secrets.KRAKEN_API_KEY }}" \
KRAKEN_API_SECRET="${{ secrets.KRAKEN_API_SECRET }}" \
BITCOIN_ELECTRUM_RPC_USERNAME=user \
BITCOIN_ELECTRUM_RPC_PASSWORD=${{ secrets.BITCOIN_ELECTRUM_RPC_PASSWORD }} \
LITECOIN_ELECTRUM_RPC_USERNAME=user \
LITECOIN_ELECTRUM_RPC_PASSWORD=${{ secrets.LITECOIN_ELECTRUM_RPC_PASSWORD }} \
BITCOIN_ELECTRUM_SERVER_ADDRESS=${{ secrets.BITCOIN_ELECTRUM_SERVER_ADDRESS }} \
LITECOIN_ELECTRUM_SERVER_ADDRESS=${{ secrets.LITECOIN_ELECTRUM_SERVER_ADDRESS }} \
BITCOIN_WALLET_SEED=${{ secrets.BITCOIN_WALLET_SEED }} \
LITECOIN_WALLET_SEED=${{ secrets.LITECOIN_WALLET_SEED }} \
LITECOIN_MWEB_WALLET_SEED=${{ secrets.LITECOIN_MWEB_WALLET_SEED }} \
MONERO_DAEMON_ADDRESS=${{ secrets.MONERO_DAEMON_ADDRESS }} \
MONERO_RPC_URL=${{ secrets.MONERO_RPC_URL }} \
MONERO_RPC_USERNAME=user \
MONERO_RPC_PASSWORD=${{ secrets.MONERO_RPC_PASSWORD }} \
MONERO_WALLET_SEED=${{ secrets.MONERO_WALLET_SEED }} \
MONERO_WALLET_PASSWORD=${{ secrets.MONERO_WALLET_PASSWORD }} \
MONERO_WALLET_HEIGHT=${{ secrets.MONERO_WALLET_HEIGHT }} \
KRAKEN_API_KEY=${{ secrets.KRAKEN_API_KEY }} \
KRAKEN_API_SECRET=${{ secrets.KRAKEN_API_SECRET }} \
MAX_NETWORK_FEE_PERCENT=${{ secrets.MAX_NETWORK_FEE_PERCENT }} \
MAX_SLIPPAGE_PERCENT=${{ secrets.MAX_SLIPPAGE_PERCENT }} \
BITCOIN_FEE_SOURCE=${{ secrets.BITCOIN_FEE_SOURCE }} \
BITCOIN_FEE_RATE=${{ secrets.BITCOIN_FEE_RATE }} \
LITECOIN_FEE_SOURCE=${{ secrets.LITECOIN_FEE_SOURCE }} \
LITECOIN_FEE_RATE=${{ secrets.LITECOIN_FEE_RATE }} \
docker compose up -d --build
EOF

View File

@@ -24,8 +24,8 @@ Create a `.env` file as a copy of `.env.example` and set the values for the empt
| `KRAKEN_API_KEY` | Yes | - | Your API key from Kraken. |
| `KRAKEN_API_SECRET` | Yes | - | Your API secret from Kraken. |
| `MONERO_DAEMON_ADDRESS` | Yes | - | The address of a Monero daemon you own or trust. |
| `BTC_ELECTRUM_SERVER_ADDRESS` | **No** | - | The address of a Bitcoin Electrum server you own or trust. E.g.: `localhost:50001:t` (no SSL) or `my.electrum.server:50001:s` (SSL). By leaving this blank you're letting Electrum select a random server for you, which may be a privacy concern. |
| `LTC_ELECTRUM_SERVER_ADDRESS` | **No** | - | The address of a Litecoin Electrum server you own or trust. E.g.: `localhost:50001:t` (no SSL) or `my.electrum.server:50001:s` (SSL). By leaving this blank you're letting Electrum select a random server for you, which may be a privacy concern. |
| `BITCOIN_ELECTRUM_SERVER_ADDRESS` | **No** | - | The address of a Bitcoin Electrum server you own or trust. E.g.: `localhost:50001:t` (no SSL) or `my.electrum.server:50001:s` (SSL). By leaving this blank you're letting Electrum select a random server for you, which may be a privacy concern. |
| `LITECOIN_ELECTRUM_SERVER_ADDRESS` | **No** | - | The address of a Litecoin Electrum server you own or trust. E.g.: `localhost:50001:t` (no SSL) or `my.electrum.server:50001:s` (SSL). By leaving this blank you're letting Electrum select a random server for you, which may be a privacy concern. |
| `MAX_NETWORK_FEE_PERCENT` | **No** | `5` | The maximum accepted miner fee percent when auto-forwarding. Not applied to XMR. |
| `MAX_SLIPPAGE_PERCENT` | **No** | `0.5` | The maximum accepted slippage percent when auto-converting. |
| `BITCOIN_FEE_SOURCE` | **No** | `https://mempool.space/api/v1/fees/recommended` | The fee API source to use for Bitcoin transactions. |

View File

@@ -1,12 +1,14 @@
services:
btc-electrum:
build:
context: ./btc-electrum
context: ./docker/btc-electrum
args:
VERSION: "4.5.5"
CHECKSUM_SHA512: "3bdfce2187466fff20fd67736bdf257bf95d3517de47043be411ccda558a442b8fd81d6a8da094a39a1db39a7339dcd4282e73a7f00cf6bbd70473d7ce456b0b"
container_name: btc-electrum
restart: unless-stopped
volumes:
- btc-data:/home/electrum/.electrum
environment:
- ELECTRUM_RPC_USER=${BITCOIN_ELECTRUM_RPC_USERNAME}
- ELECTRUM_RPC_PASSWORD=${BITCOIN_ELECTRUM_RPC_PASSWORD}
@@ -14,19 +16,44 @@ services:
ltc-electrum:
build:
context: ./ltc-electrum
context: ./docker/ltc-electrum
args:
VERSION: "release-9"
CHECKSUM_SHA512: "bdf9edef38a34b087e4c70bb663ac111545d92b48aa4e2292438ebc93948ccc6f2c1b7e1b6384097ce13a8298919316e4b8863f0186764c0712245567aa4d73f"
CHECKSUM_SHA512: "62248d5eba9b7d67facb767ff35706ef3e3dcd69c6b6fb8fb67b09bc07e52193ecd59f122388d401e854385b2e2b31fd802a9f5d56464472d893f5bc1bd394af"
container_name: ltc-electrum
restart: unless-stopped
cap_add:
- SYS_ADMIN
devices:
- /dev/fuse:/dev/fuse
volumes:
- ltc-data:/home/electrum-ltc/.electrum
environment:
- ELECTRUM_RPC_USER=${LITECOIN_ELECTRUM_RPC_USERNAME}
- ELECTRUM_RPC_PASSWORD=${LITECOIN_ELECTRUM_RPC_PASSWORD}
- ELECTRUM_SERVER_ADDRESS=${LITECOIN_ELECTRUM_SERVER_ADDRESS}
# ltc-mweb-electrum:
# build:
# context: ./docker/ltc-electrum
# args:
# VERSION: "release-9"
# CHECKSUM_SHA512: "62248d5eba9b7d67facb767ff35706ef3e3dcd69c6b6fb8fb67b09bc07e52193ecd59f122388d401e854385b2e2b31fd802a9f5d56464472d893f5bc1bd394af"
# container_name: ltc-mweb-electrum
# restart: unless-stopped
# cap_add:
# - SYS_ADMIN
# devices:
# - "/dev/fuse"
# volumes:
# - ltc-mweb-data:/home/electrum-ltc/.electrum
# environment:
# - ELECTRUM_RPC_USER=${LITECOIN_ELECTRUM_RPC_USERNAME}
# - ELECTRUM_RPC_PASSWORD=${LITECOIN_ELECTRUM_RPC_PASSWORD}
# - ELECTRUM_SERVER_ADDRESS=${LITECOIN_ELECTRUM_SERVER_ADDRESS}
monero-wallet-rpc:
image: ghcr.io/sethforprivacy/simple-monero-wallet-rpc:latest
image: sethsimmons/simple-monero-wallet-rpc:latest
restart: unless-stopped
container_name: monero-wallet-rpc
volumes:
@@ -51,10 +78,12 @@ services:
- LITECOIN_ELECTRUM_RPC_URL=${LITECOIN_ELECTRUM_RPC_URL}
- LITECOIN_ELECTRUM_RPC_USERNAME=${LITECOIN_ELECTRUM_RPC_USERNAME}
- LITECOIN_ELECTRUM_RPC_PASSWORD=${LITECOIN_ELECTRUM_RPC_PASSWORD}
- LITECOIN_MWEB_ELECTRUM_RPC_URL=${LITECOIN_MWEB_ELECTRUM_RPC_URL}
- BITCOIN_ELECTRUM_SERVER_ADDRESS=${BITCOIN_ELECTRUM_SERVER_ADDRESS}
- LITECOIN_ELECTRUM_SERVER_ADDRESS=${LITECOIN_ELECTRUM_SERVER_ADDRESS}
- BITCOIN_WALLET_SEED=${BITCOIN_WALLET_SEED}
- LITECOIN_WALLET_SEED=${LITECOIN_WALLET_SEED}
- LITECOIN_MWEB_WALLET_SEED=${LITECOIN_MWEB_WALLET_SEED}
- MONERO_RPC_URL=http://monero-wallet-rpc:18082/json_rpc
- MONERO_RPC_USERNAME=${MONERO_RPC_USERNAME}
- MONERO_RPC_PASSWORD=${MONERO_RPC_PASSWORD}
@@ -62,6 +91,8 @@ services:
- MONERO_WALLET_PASSWORD=${MONERO_WALLET_PASSWORD}
- MONERO_WALLET_HEIGHT=${MONERO_WALLET_HEIGHT}
command: python ./src/seed-importer.py
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
- btc-electrum
- ltc-electrum
@@ -78,21 +109,17 @@ services:
- BITCOIN_ELECTRUM_RPC_USERNAME=${BITCOIN_ELECTRUM_RPC_USERNAME}
- BITCOIN_ELECTRUM_RPC_PASSWORD=${BITCOIN_ELECTRUM_RPC_PASSWORD}
- LITECOIN_ELECTRUM_RPC_URL=${LITECOIN_ELECTRUM_RPC_URL}
- LITECOIN_MWEB_ELECTRUM_RPC_URL=${LITECOIN_MWEB_ELECTRUM_RPC_URL}
- LITECOIN_ELECTRUM_RPC_USERNAME=${LITECOIN_ELECTRUM_RPC_USERNAME}
- LITECOIN_ELECTRUM_RPC_PASSWORD=${LITECOIN_ELECTRUM_RPC_PASSWORD}
- BITCOIN_ELECTRUM_SERVER_ADDRESS=${BITCOIN_ELECTRUM_SERVER_ADDRESS}
- LITECOIN_ELECTRUM_SERVER_ADDRESS=${LITECOIN_ELECTRUM_SERVER_ADDRESS}
- BITCOIN_WALLET_SEED=${BITCOIN_WALLET_SEED}
- LITECOIN_WALLET_SEED=${LITECOIN_WALLET_SEED}
- MONERO_RPC_URL=http://monero-wallet-rpc:18082/json_rpc
- MONERO_RPC_USERNAME=${MONERO_RPC_USERNAME}
- MONERO_RPC_PASSWORD=${MONERO_RPC_PASSWORD}
- MONERO_WALLET_SEED=${MONERO_WALLET_SEED}
- MONERO_WALLET_PASSWORD=${MONERO_WALLET_PASSWORD}
- MONERO_WALLET_HEIGHT=${MONERO_WALLET_HEIGHT}
- KRAKEN_API_KEY=${KRAKEN_API_KEY}
- KRAKEN_API_SECRET=${KRAKEN_API_SECRET}
command: python ./src/autoforward.py
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
- seed-importer
@@ -110,4 +137,7 @@ services:
- seed-importer
volumes:
btc-data:
ltc-data:
ltc-mweb-data:
monero-wallet-rpc-data:

View File

@@ -6,7 +6,6 @@ ARG CHECKSUM_SHA512
ENV ELECTRUM_VERSION=$VERSION
ENV ELECTRUM_USER=electrum
ENV ELECTRUM_HOME=/home/$ELECTRUM_USER
ENV ELECTRUM_NETWORK=mainnet
RUN adduser -D $ELECTRUM_USER
@@ -35,8 +34,8 @@ RUN mkdir -p /data \
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
USER $BTC_ELECTRUM_USER
WORKDIR $BTC_ELECTRUM_HOME
USER $BITCOIN_ELECTRUM_USER
WORKDIR $BITCOIN_ELECTRUM_HOME
VOLUME /data
EXPOSE 7000

View File

@@ -3,7 +3,7 @@ set -ex
trap 'pkill -TERM -P1; electrum stop; exit 0' SIGTERM
rm -f .electrum/daemon
rm -f .electrum/daemon .electrum/daemon_rpc_socket
electrum --offline setconfig rpcuser ${ELECTRUM_RPC_USER}
electrum --offline setconfig rpcpassword ${ELECTRUM_RPC_PASSWORD}
electrum --offline setconfig rpchost 0.0.0.0

View File

@@ -0,0 +1,25 @@
FROM ubuntu:latest
ARG VERSION
ARG CHECKSUM_SHA512
RUN apt update && \
apt install -y wget libfuse2 fuse3
ENV ELECTRUM_VERSION=$VERSION
ENV ELECTRUM_USER=electrum
ENV ELECTRUM_HOME=/home/$ELECTRUM_USER
ENV ELECTRUM_CHECKSUM_SHA512 $CHECKSUM_SHA512
RUN useradd -m $ELECTRUM_USER
USER $ELECTRUM_USER
WORKDIR $ELECTRUM_HOME
RUN wget https://github.com/ltcmweb/electrum-ltc/releases/download/${ELECTRUM_VERSION}/electrum-ltc-${ELECTRUM_VERSION}-x86_64.AppImage -O electrum-ltc.appimage
RUN [ "${ELECTRUM_CHECKSUM_SHA512} electrum-ltc.appimage" = "$(sha512sum electrum-ltc.appimage)" ]
RUN echo -e "**************************\n SHA 512 Checksum OK\n**************************"
COPY --chown=$ELECTRUM_USER:$ELECTRUM_USER ./docker-entrypoint.sh docker-entrypoint.sh
RUN chmod +x ./electrum-ltc.appimage ./docker-entrypoint.sh
EXPOSE 7000
ENTRYPOINT [ "./docker-entrypoint.sh" ]

View File

@@ -0,0 +1,18 @@
#!/bin/bash
set -e
trap 'pkill -TERM -P1; electrum-ltc.appimage stop; exit 0' SIGTERM
rm -f $HOME/.electrum-ltc/daemon
./electrum-ltc.appimage --offline setconfig rpcuser ${ELECTRUM_RPC_USER}
./electrum-ltc.appimage --offline setconfig rpcpassword ${ELECTRUM_RPC_PASSWORD}
./electrum-ltc.appimage --offline setconfig rpchost 0.0.0.0
./electrum-ltc.appimage --offline setconfig rpcport 7000
if [ -n "${ELECTRUM_SERVER_ADDRESS}" ]; then
./electrum-ltc.appimage daemon -1 -s "${ELECTRUM_SERVER_ADDRESS}" "$@"
else
./electrum-ltc.appimage daemon "$@"
fi

View File

@@ -1,45 +0,0 @@
FROM python:3.12-alpine
ARG VERSION
ARG CHECKSUM_SHA512
ENV ELECTRUM_VERSION=$VERSION
ENV ELECTRUM_USER=electrum
ENV ELECTRUM_HOME=/home/$ELECTRUM_USER
ENV ELECTRUM_NETWORK=mainnet
RUN adduser -D $ELECTRUM_USER
RUN mkdir -p /data ${ELECTRUM_HOME} && \
ln -sf /data ${ELECTRUM_HOME}/.electrum && \
chown ${ELECTRUM_USER} ${ELECTRUM_HOME}/.electrum /data
# IMPORTANT: always verify gpg signature before changing a hash here!
ENV ELECTRUM_CHECKSUM_SHA512 $CHECKSUM_SHA512
RUN apk --no-cache add --virtual build-dependencies gcc musl-dev libsecp256k1 libsecp256k1-dev libressl-dev
RUN wget https://github.com/ltcmweb/electrum-ltc/archive/refs/tags/${ELECTRUM_VERSION}.tar.gz
RUN [ "${ELECTRUM_CHECKSUM_SHA512} ${ELECTRUM_VERSION}.tar.gz" = "$(sha512sum ${ELECTRUM_VERSION}.tar.gz)" ]
RUN echo -e "**************************\n SHA 512 Checksum OK\n**************************"
RUN tar -xzf ${ELECTRUM_VERSION}.tar.gz
RUN pip3 install cryptography google protobuf grpcio scrypt ${ELECTRUM_VERSION}.tar.gz
RUN rm ${ELECTRUM_VERSION}.tar.gz
RUN ln -s /usr/lib/libsecp256k1.so /usr/local/lib/python3.12/site-packages/electrum_ltc/libsecp256k1.so.0
RUN mkdir -p /data \
${ELECTRUM_HOME}/.electrum/wallets/ \
${ELECTRUM_HOME}/.electrum/testnet/wallets/ \
${ELECTRUM_HOME}/.electrum/regtest/wallets/ \
${ELECTRUM_HOME}/.electrum/simnet/wallets/ && \
ln -sf ${ELECTRUM_HOME}/.electrum/ /data && \
chown -R ${ELECTRUM_USER} ${ELECTRUM_HOME}/.electrum /data
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
USER $ELECTRUM_USER
WORKDIR $ELECTRUM_HOME
VOLUME /data
EXPOSE 7000
ENTRYPOINT ["docker-entrypoint.sh"]

View File

@@ -1,17 +0,0 @@
#!/usr/bin/env sh
set -ex
trap 'pkill -TERM -P1; electrum-ltc stop; exit 0' SIGTERM
rm -f .electrum/daemon
electrum-ltc --offline setconfig rpcuser ${ELECTRUM_RPC_USER}
electrum-ltc --offline setconfig rpcpassword ${ELECTRUM_RPC_PASSWORD}
electrum-ltc --offline setconfig rpchost 0.0.0.0
electrum-ltc --offline setconfig rpcport 7000
if [ -n "${LITECOIN_ELECTRUM_SERVER_ADDRESS}" ]; then
electrum-ltc daemon -1 -s "${LITECOIN_ELECTRUM_SERVER_ADDRESS}" "$@"
else
electrum-ltc daemon "$@"
fi

26
poetry.lock generated
View File

@@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand.
[[package]]
name = "asn1crypto"
@@ -6,6 +6,7 @@ version = "1.5.1"
description = "Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP"
optional = false
python-versions = "*"
groups = ["main"]
files = [
{file = "asn1crypto-1.5.1-py2.py3-none-any.whl", hash = "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67"},
{file = "asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c"},
@@ -17,6 +18,7 @@ version = "2.9.3"
description = "Generation of mnemonics, seeds, private/public keys and addresses for different types of cryptocurrencies"
optional = false
python-versions = ">=3.7"
groups = ["main"]
files = [
{file = "bip_utils-2.9.3-py3-none-any.whl", hash = "sha256:ee26b8417a576c7f89b847da37316db01a5cece1994c1609d37fbeefb91ad45e"},
{file = "bip_utils-2.9.3.tar.gz", hash = "sha256:72a8c95484b57e92311b0b2a3d5195b0ce4395c19a0b157d4a289e8b1300f48a"},
@@ -41,6 +43,7 @@ version = "5.6.4"
description = "CBOR (de)serializer with extensive tag support"
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "cbor2-5.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c40c68779a363f47a11ded7b189ba16767391d5eae27fac289e7f62b730ae1fc"},
{file = "cbor2-5.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c0625c8d3c487e509458459de99bf052f62eb5d773cc9fc141c6a6ea9367726d"},
@@ -83,7 +86,7 @@ files = [
[package.extras]
benchmarks = ["pytest-benchmark (==4.0.0)"]
doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.3.0)", "typing-extensions"]
doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.3.0)", "typing-extensions ; python_version < \"3.12\""]
test = ["coverage (>=7)", "hypothesis", "pytest"]
[[package]]
@@ -92,6 +95,7 @@ version = "2024.8.30"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.6"
groups = ["main"]
files = [
{file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"},
{file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
@@ -103,6 +107,7 @@ version = "1.17.1"
description = "Foreign Function Interface for Python calling C code."
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"},
{file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"},
@@ -182,6 +187,7 @@ version = "3.3.2"
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
optional = false
python-versions = ">=3.7.0"
groups = ["main"]
files = [
{file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
{file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
@@ -281,6 +287,7 @@ version = "20.0.0"
description = "Cross-platform Python CFFI bindings for libsecp256k1"
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "coincurve-20.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d559b22828638390118cae9372a1bb6f6594f5584c311deb1de6a83163a0919b"},
{file = "coincurve-20.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33d7f6ebd90fcc550f819f7f2cce2af525c342aac07f0ccda46ad8956ad9d99b"},
@@ -347,6 +354,7 @@ version = "1.7"
description = "CRC Generator"
optional = false
python-versions = "*"
groups = ["main"]
files = [
{file = "crcmod-1.7.tar.gz", hash = "sha256:dc7051a0db5f2bd48665a990d3ec1cc305a466a77358ca4492826f41f283601e"},
]
@@ -357,6 +365,7 @@ version = "0.19.0"
description = "ECDSA cryptographic signature library (pure python)"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.6"
groups = ["main"]
files = [
{file = "ecdsa-0.19.0-py2.py3-none-any.whl", hash = "sha256:2cea9b88407fdac7bbeca0833b189e4c9c53f2ef1e1eaa29f6224dbc809b707a"},
{file = "ecdsa-0.19.0.tar.gz", hash = "sha256:60eaad1199659900dd0af521ed462b793bbdf867432b3948e87416ae4caf6bf8"},
@@ -375,6 +384,7 @@ version = "1.4.1"
description = "Ed25519 public-key signatures (BLAKE2b fork)"
optional = false
python-versions = "*"
groups = ["main"]
files = [
{file = "ed25519-blake2b-1.4.1.tar.gz", hash = "sha256:731e9f93cd1ac1a64649575f3519a99ffe0bb1e4cf7bf5f5f0be513a39df7363"},
]
@@ -385,6 +395,7 @@ version = "3.8"
description = "Internationalized Domain Names in Applications (IDNA)"
optional = false
python-versions = ">=3.6"
groups = ["main"]
files = [
{file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"},
{file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"},
@@ -396,6 +407,7 @@ version = "0.2.0"
description = "Python bindings for sr25519 library"
optional = false
python-versions = "*"
groups = ["main"]
files = [
{file = "py_sr25519_bindings-0.2.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:86cc1a571852a4f2ade827ebf211e066b23ab805d3e864cbe213a3d8cd53f7d5"},
{file = "py_sr25519_bindings-0.2.0-cp310-cp310-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:453c9088e39dd04b07bf3ada6c473a5349c4dfd965009a35124b2c807117eda8"},
@@ -477,6 +489,7 @@ version = "2.22"
description = "C parser in Python"
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"},
{file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"},
@@ -488,6 +501,7 @@ version = "3.20.0"
description = "Cryptographic library for Python"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
groups = ["main"]
files = [
{file = "pycryptodome-3.20.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:f0e6d631bae3f231d3634f91ae4da7a960f7ff87f2865b2d2b831af1dfb04e9a"},
{file = "pycryptodome-3.20.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:baee115a9ba6c5d2709a1e88ffe62b73ecc044852a925dcb67713a288c4ec70f"},
@@ -529,6 +543,7 @@ version = "1.5.0"
description = "Python binding to the Networking and Cryptography (NaCl) library"
optional = false
python-versions = ">=3.6"
groups = ["main"]
files = [
{file = "PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1"},
{file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92"},
@@ -555,6 +570,7 @@ version = "2.32.3"
description = "Python HTTP for Humans."
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
{file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
@@ -576,6 +592,7 @@ version = "1.16.0"
description = "Python 2 and 3 compatibility utilities"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
groups = ["main"]
files = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
@@ -587,18 +604,19 @@ version = "2.2.3"
description = "HTTP library with thread-safe connection pooling, file post, and more."
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"},
{file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"},
]
[package.extras]
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""]
h2 = ["h2 (>=4,<5)"]
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
zstd = ["zstandard (>=0.18.0)"]
[metadata]
lock-version = "2.0"
lock-version = "2.1"
python-versions = "^3.12"
content-hash = "312bfc0d67e89feee1abbdbabc31649ff525b844d43eeaa06d57b9e9d26fbf06"

View File

@@ -11,7 +11,6 @@ python = "^3.12"
requests = "^2.32.3"
bip-utils = "^2.9.3"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

View File

@@ -8,29 +8,46 @@ from constants import MIN_BITCOIN_SEND_AMOUNT, MIN_LITECOIN_SEND_AMOUNT, MIN_MON
import util
import env
def get_fee_rate(source: str, rate: str) -> int:
ElectrumCoin = Literal['btc', 'ltc', 'ltc-mweb']
def get_fee_rate(coin: ElectrumCoin) -> int:
coin_to_source: dict[ElectrumCoin, str] = {
'btc': env.BITCOIN_FEE_SOURCE,
'ltc': env.LITECOIN_FEE_SOURCE,
'ltc-mweb': env.LITECOIN_FEE_SOURCE
}
coin_to_rate: dict[ElectrumCoin, str] = {
'btc': env.BITCOIN_FEE_RATE,
'ltc': env.LITECOIN_FEE_RATE,
'ltc-mweb': env.LITECOIN_FEE_RATE
}
source = coin_to_source[coin]
rate = coin_to_rate[coin]
return requests.get(source).json()[rate]
def set_electrum_fee_rate(coin: Literal['btc', 'ltc'], rate: int, dynamic: bool):
def set_electrum_fee_rate(coin: ElectrumCoin, rate: int, dynamic: bool):
if dynamic: # Fall back to the Electrum rate if there is an issue
util.request_electrum_rpc(coin, 'setconfig', ['dynamic_fees', True])
else:
util.request_electrum_rpc(coin, 'setconfig', ['dynamic_fees', False])
util.request_electrum_rpc(coin, 'setconfig', ['fee_per_kb', rate * 1000])
def get_electrum_balance(coin: Literal['btc', 'ltc']) -> float:
def get_electrum_balance(coin: ElectrumCoin) -> float:
return float(util.request_electrum_rpc(coin, 'getbalance')['confirmed'])
def create_psbt(coin: Literal['btc', 'ltc'], destination_address: str) -> str:
def create_psbt(coin: ElectrumCoin, destination_address: str, unsigned = True) -> str:
params = {
'destination': destination_address,
'amount': '!',
'unsigned': True # This way we can get the input amounts
'unsigned': unsigned # This way we can get the input amounts
}
return util.request_electrum_rpc(coin, 'payto', params)
def get_psbt_data(coin: Literal['btc', 'ltc'], psbt: str) -> dict:
def get_psbt_data(coin: ElectrumCoin, psbt: str) -> dict:
return util.request_electrum_rpc(coin, 'deserialize', [psbt])
def get_total_psbt_fee(psbt_data: dict) -> float:
@@ -47,10 +64,10 @@ def get_total_psbt_fee(psbt_data: dict) -> float:
total_fee = total_fee_sats / 100000000
return total_fee
def sign_psbt(coin: Literal['btc', 'ltc'], psbt: str) -> str:
def sign_psbt(coin: ElectrumCoin, psbt: str) -> str:
return cast(str, util.request_electrum_rpc(coin, 'signtransaction', [psbt]))
def broadcast_electrum_tx(coin: Literal['btc', 'ltc'], signed_tx: str):
def broadcast_electrum_tx(coin: ElectrumCoin, signed_tx: str):
util.request_electrum_rpc(coin, 'broadcast', [signed_tx])
def get_monero_balance() -> float:
@@ -91,87 +108,62 @@ def get_new_kraken_address(asset: Literal['btc', 'ltc', 'xmr']) -> str:
raise Exception(f'Kraken did not return a new address: {json.dumps(result, indent=2)}')
def attempt_bitcoin_autoforward():
balance = get_electrum_balance('btc')
def attempt_electrum_autoforward(coin: ElectrumCoin):
coin_upper = coin.upper()
balance = get_electrum_balance(coin)
coin_to_min_send: dict[ElectrumCoin, float] = {
'btc': MIN_BITCOIN_SEND_AMOUNT,
'ltc': MIN_LITECOIN_SEND_AMOUNT,
'ltc-mweb': MIN_LITECOIN_SEND_AMOUNT
}
min_send = coin_to_min_send[coin]
if balance < MIN_BITCOIN_SEND_AMOUNT:
print(util.get_time(), f'Not enough Bitcoin balance to autoforward. (Balance: {balance}, Min Send: {MIN_BITCOIN_SEND_AMOUNT})')
print(util.get_time(), f'Not enough {coin_upper} balance to autoforward. (Balance: {balance}, Min. send: {min_send})')
return
try:
fee_rate = get_fee_rate(env.BITCOIN_FEE_SOURCE, env.BITCOIN_FEE_RATE)
set_electrum_fee_rate('btc', fee_rate, dynamic=False)
fee_rate = get_fee_rate(coin)
set_electrum_fee_rate(coin, fee_rate, dynamic=False)
except:
set_electrum_fee_rate('btc', rate=0, dynamic=True)
address = get_new_kraken_address('btc')
set_electrum_fee_rate(coin, rate=0, dynamic=True)
address = get_new_kraken_address(coin if coin != 'ltc-mweb' else 'ltc')
try:
psbt = create_psbt('btc', address)
except requests.exceptions.HTTPError as http_error:
response_json = cast(dict, http_error.response.json())
# Electrum-ltc doesn't support deserializing mweb transactions, so we can't check total fee
if coin != 'ltc-mweb':
try:
psbt = create_psbt(coin, address)
except requests.exceptions.HTTPError as http_error:
response_json = cast(dict, http_error.response.json())
if response_json.get('error', {}).get('data', {}).get('exception', '') == 'NotEnoughFunds()':
print(util.get_time(), f'Not autoforwarding due to high transaction fee.')
return
if response_json.get('error', {}).get('data', {}).get('exception', '') == 'NotEnoughFunds()':
print(util.get_time(), f'Not autoforwarding due to high transaction fee.')
return
raise http_error
raise http_error
psbt_data = get_psbt_data('btc', psbt)
total_fee = get_total_psbt_fee(psbt_data)
amount = balance
psbt_data = get_psbt_data(coin, psbt)
total_fee = get_total_psbt_fee(psbt_data)
amount = balance
if total_fee / amount * 100 > env.MAX_NETWORK_FEE_PERCENT:
print(util.get_time(), f'Not autoforwarding due to high transaction fee {total_fee} BTC.')
return
if total_fee / amount * 100 > env.MAX_NETWORK_FEE_PERCENT:
print(util.get_time(), f'Not autoforwarding due to high transaction fee ({total_fee} {coin_upper}).')
return
signed_tx = sign_psbt('btc', psbt)
broadcast_electrum_tx('btc', signed_tx)
signed_tx = sign_psbt(coin, psbt)
else:
signed_tx = create_psbt(coin, address, unsigned=False)
print(util.get_time(), f'Autoforwarded {amount} BTC to {address}!')
def attempt_litecoin_autoforward():
balance = get_electrum_balance('ltc')
if balance < MIN_LITECOIN_SEND_AMOUNT:
print(util.get_time(), f'Not enough Litecoin balance to autoforward. (Balance: {balance}, Min Send: {MIN_LITECOIN_SEND_AMOUNT})')
return
try:
fee_rate = get_fee_rate(env.LITECOIN_FEE_SOURCE, env.LITECOIN_FEE_RATE)
set_electrum_fee_rate('ltc', fee_rate, dynamic=False)
except:
set_electrum_fee_rate('ltc', rate=0, dynamic=True)
address = get_new_kraken_address('ltc')
try:
psbt = create_psbt('ltc', address)
except requests.exceptions.HTTPError as http_error:
response_json = cast(dict, http_error.response.json())
if response_json.get('error', {}).get('data', {}).get('exception', '') == 'NotEnoughFunds()':
print(util.get_time(), f'Not autoforwarding due to high transaction fee.')
return
raise http_error
psbt_data = get_psbt_data('ltc', psbt)
total_fee = get_total_psbt_fee(psbt_data)
amount = balance
if total_fee / amount * 100 > env.MAX_NETWORK_FEE_PERCENT:
print(util.get_time(), f'Not autoforwarding due to high transaction fee {total_fee} LTC.')
return
signed_tx = sign_psbt('ltc', psbt)
broadcast_electrum_tx('ltc', signed_tx)
print(util.get_time(), f'Autoforwarded {amount} LTC to {address}!')
broadcast_electrum_tx(coin, signed_tx)
print(util.get_time(), f'Autoforwarded {amount} {coin_upper} to {address}!')
def attempt_monero_autoforward():
balance = get_monero_balance()
if balance < MIN_MONERO_SEND_AMOUNT:
print(util.get_time(), f'Not enough Monero balance to autoforward. (Balance: {balance}, Min Send: {MIN_MONERO_SEND_AMOUNT})')
print(util.get_time(), f'Not enough XMR balance to autoforward. (Balance: {balance}, Min Send: {MIN_MONERO_SEND_AMOUNT})')
return
address = get_new_kraken_address('xmr')
@@ -183,21 +175,27 @@ util.wait_for_wallets()
while 1:
try:
attempt_bitcoin_autoforward()
attempt_electrum_autoforward('btc')
except Exception as e:
print(util.get_time(), 'Error autoforwarding bitcoin:')
print(util.get_time(), 'Error autoforwarding Bitcoin:')
print(traceback.format_exc())
try:
attempt_litecoin_autoforward()
attempt_electrum_autoforward('ltc')
except Exception as e:
print(util.get_time(), 'Error autoforwarding litecoin:')
print(traceback.format_exc())
# try:
# attempt_electrum_autoforward('ltc-mweb')
# except Exception as e:
# print(util.get_time(), 'Error autoforwarding Litecoin MWEB:')
# print(traceback.format_exc())
try:
attempt_monero_autoforward()
except Exception as e:
print(util.get_time(), 'Error autoforwarding monero:')
print(util.get_time(), 'Error autoforwarding Monero:')
print(traceback.format_exc())
sleep(60 * 5)

View File

@@ -1,3 +1,3 @@
MIN_BITCOIN_SEND_AMOUNT = 0.0001
MIN_LITECOIN_SEND_AMOUNT = 0.05
MIN_MONERO_SEND_AMOUNT = 0.03
MIN_MONERO_SEND_AMOUNT = 0.03

View File

@@ -6,10 +6,12 @@ BITCOIN_ELECTRUM_RPC_USERNAME = os.getenv('BITCOIN_ELECTRUM_RPC_USERNAME', '')
BITCOIN_ELECTRUM_RPC_PASSWORD = os.getenv('BITCOIN_ELECTRUM_RPC_PASSWORD', '')
LITECOIN_ELECTRUM_RPC_USERNAME = os.getenv('LITECOIN_ELECTRUM_RPC_USERNAME', '')
LITECOIN_ELECTRUM_RPC_PASSWORD = os.getenv('LITECOIN_ELECTRUM_RPC_PASSWORD', '')
LITECOIN_MWEB_ELECTRUM_RPC_URL = os.getenv('LITECOIN_MWEB_ELECTRUM_RPC_URL', '')
BITCOIN_ELECTRUM_SERVER_ADDRESS = os.getenv('BITCOIN_ELECTRUM_SERVER_ADDRESS', '')
LITECOIN_ELECTRUM_SERVER_ADDRESS = os.getenv('LITECOIN_ELECTRUM_SERVER_ADDRESS', '')
BITCOIN_WALLET_SEED = os.getenv('BITCOIN_WALLET_SEED', '')
LITECOIN_WALLET_SEED = os.getenv('LITECOIN_WALLET_SEED', '')
LITECOIN_MWEB_WALLET_SEED = os.getenv('LITECOIN_MWEB_WALLET_SEED', '')
MONERO_RPC_URL = os.getenv('MONERO_RPC_URL', 'http://monero-wallet-rpc:18082/json_rpc')
MONERO_RPC_USERNAME = os.getenv('MONERO_RPC_USERNAME', '')

View File

@@ -1,10 +1,11 @@
from typing import Literal
from bip_utils import Bip39SeedGenerator, Bip84, Bip84Coins
import traceback
import util
import env
def get_zprv_from_seed(coin: Literal['btc', 'ltc'], mnemonic: str ) -> str:
def get_xprv_from_mnemonic(coin: Literal['btc', 'ltc',], mnemonic: str ) -> str:
coin_type = Bip84Coins.BITCOIN if coin == 'btc' else Bip84Coins.LITECOIN
seed_bytes = Bip39SeedGenerator(mnemonic).Generate()
bip84_master_key = Bip84.FromSeed(seed_bytes, coin_type)
@@ -12,12 +13,15 @@ def get_zprv_from_seed(coin: Literal['btc', 'ltc'], mnemonic: str ) -> str:
return zprv
def import_bitcoin_seed():
zprv = get_zprv_from_seed('btc', env.BITCOIN_WALLET_SEED)
util.request_electrum_rpc('btc', 'restore', [zprv])
xprv = get_xprv_from_mnemonic('btc', env.BITCOIN_WALLET_SEED)
util.request_electrum_rpc('btc', 'restore', [xprv])
def import_litecoin_seed():
zprv = get_zprv_from_seed('ltc', env.LITECOIN_WALLET_SEED)
util.request_electrum_rpc('ltc', 'restore', [zprv])
xprv = get_xprv_from_mnemonic('ltc', env.LITECOIN_WALLET_SEED)
util.request_electrum_rpc('ltc', 'restore', [xprv])
def import_litecoin_mweb_seed():
util.request_electrum_rpc('ltc-mweb', 'restore', [env.LITECOIN_MWEB_WALLET_SEED])
def import_monero_seed():
params = {
@@ -51,6 +55,15 @@ except Exception as e:
print(util.get_time(), 'Error importing litecoin seed:')
print(traceback.format_exc())
# try:
# import_litecoin_mweb_seed()
# util.request_electrum_rpc('ltc-mweb', 'load_wallet')
# util.request_electrum_rpc('ltc-mweb', 'changegaplimit', [1000, 'iknowhatimdoing'])
# print('Litecoin mimblewimble seed has successfully been imported!')
# except Exception as e:
# print(util.get_time(), 'Error importing litecoin mimblewimble seed:')
# print(traceback.format_exc())
try:
import_monero_seed()
print('Monero seed has successfully been imported!')

View File

@@ -15,13 +15,20 @@ import env
def get_time() -> str:
return f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}]'
def request_electrum_rpc(coin: Literal['btc', 'ltc'], method: str, params: list | dict = []):
def request_electrum_rpc(coin: Literal['btc', 'ltc', 'ltc-mweb'], method: str, params: list | dict = []):
headers = {'content-type': 'application/json'}
if coin == 'btc':
auth = (env.BITCOIN_ELECTRUM_RPC_USERNAME, env.BITCOIN_ELECTRUM_RPC_PASSWORD)
else:
auth = (env.LITECOIN_ELECTRUM_RPC_USERNAME, env.LITECOIN_ELECTRUM_RPC_PASSWORD)
coin_to_auth = {
'btc': (env.BITCOIN_ELECTRUM_RPC_USERNAME, env.BITCOIN_ELECTRUM_RPC_PASSWORD),
'ltc': (env.LITECOIN_ELECTRUM_RPC_USERNAME, env.LITECOIN_ELECTRUM_RPC_PASSWORD),
'ltc-mweb': (env.LITECOIN_ELECTRUM_RPC_USERNAME, env.LITECOIN_ELECTRUM_RPC_PASSWORD)
}
coin_to_url = {
'btc': env.BITCOIN_ELECTRUM_RPC_URL,
'ltc': env.LITECOIN_ELECTRUM_RPC_URL,
'ltc-mweb': env.LITECOIN_MWEB_ELECTRUM_RPC_URL
}
data = {
'jsonrpc': '2.0',
@@ -31,10 +38,10 @@ def request_electrum_rpc(coin: Literal['btc', 'ltc'], method: str, params: list
}
response = requests.post(
env.BITCOIN_ELECTRUM_RPC_URL if coin == 'btc' else env.LITECOIN_ELECTRUM_RPC_URL,
coin_to_url[coin],
headers=headers,
data=json.dumps(data),
auth=auth
auth=coin_to_auth[coin]
)
response_json = response.json()
@@ -78,6 +85,9 @@ def open_bitcoin_wallet():
def open_litecoin_wallet():
request_electrum_rpc('ltc', 'load_wallet')
def open_litecoin_mweb_wallet():
request_electrum_rpc('ltc-mweb', 'load_wallet')
def open_monero_wallet() -> None:
params = {'filename': 'foo', 'password': env.MONERO_WALLET_PASSWORD}
request_monero_rpc('open_wallet', params)
@@ -130,6 +140,15 @@ def wait_for_wallets():
break
except:
time.sleep(10)
print('Waiting for Litecoin MWEB wallet...')
while 1:
try:
open_litecoin_mweb_wallet()
break
except:
time.sleep(10)
print('Waiting for Monero wallet...')