Update btc electrum, workaround for dynamic_fees config no longer available and add testnet autoforward support

This commit is contained in:
Keeqler
2025-11-18 19:27:44 -03:00
parent 1eda4f5956
commit 93940d6773
14 changed files with 230 additions and 106 deletions

View File

@@ -1,3 +1,6 @@
# Using TESTNET
TESTNET="1"
ELECTRUM_RPC_PASSWORD=""
BITCOIN_WALLET_SEED=""
BITCOIN_ELECTRUM_SERVER_ADDRESS=""
@@ -11,14 +14,16 @@ MONERO_WALLET_SEED=""
MONERO_WALLET_PASSWORD=""
MONERO_WALLET_HEIGHT=""
KRAKEN_API_KEY=""
KRAKEN_API_SECRET=""
MAX_NETWORK_FEE_PERCENT="5"
MAX_SLIPPAGE_PERCENT="0.5"
SETTLEMENT_CURRENCY="USD"
BITCOIN_FEE_SOURCE="https://mempool.space/api/v1/fees/recommended"
# Using TESTNET API
BITCOIN_FEE_SOURCE="https://mempool.space/testnet/api/v1/fees/recommended"
BITCOIN_FEE_RATE="halfHourFee"
LITECOIN_FEE_SOURCE="https://litecoinspace.org/api/v1/fees/recommended"
LITECOIN_FEE_SOURCE="https://litecoinspace.org/testnet/api/v1/fees/recommended"
LITECOIN_FEE_RATE="halfHourFee"
# If you are on testnet, you can leave this blank since autoconvert won't work
KRAKEN_API_KEY=""
KRAKEN_API_SECRET=""

View File

@@ -3,13 +3,14 @@ services:
build:
context: ./docker/btc-electrum
args:
VERSION: "4.5.5"
CHECKSUM_SHA512: "3bdfce2187466fff20fd67736bdf257bf95d3517de47043be411ccda558a442b8fd81d6a8da094a39a1db39a7339dcd4282e73a7f00cf6bbd70473d7ce456b0b"
VERSION: "4.6.2"
CHECKSUM_SHA512: "890c1fae4cd2da5f1fea3f07c1c6b537f9557177b86e23c40333ec83743ed46182ec74e43a27416a3eaa9704d87d0a1702d0a789b23467bcc68a17d638b43655"
container_name: btc-electrum
restart: unless-stopped
volumes:
- bitcoin-data:/home/electrum/.electrum
environment:
- TESTNET=${TESTNET}
- ELECTRUM_RPC_USER=user
- ELECTRUM_RPC_PASSWORD=${ELECTRUM_RPC_PASSWORD}
- ELECTRUM_SERVER_ADDRESS=${BITCOIN_ELECTRUM_SERVER_ADDRESS}
@@ -25,6 +26,7 @@ services:
volumes:
- litecoin-data:/home/electrum-ltc/.electrum
environment:
- TESTNET=${TESTNET}
- ELECTRUM_RPC_USER=user
- ELECTRUM_RPC_PASSWORD=${ELECTRUM_RPC_PASSWORD}
- ELECTRUM_SERVER_ADDRESS=${LITECOIN_ELECTRUM_SERVER_ADDRESS}
@@ -40,23 +42,24 @@ services:
volumes:
- litecoin-mweb-data:/home/electrum-ltc/.electrum
environment:
- TESTNET=${TESTNET}
- ELECTRUM_RPC_USER=user
- ELECTRUM_RPC_PASSWORD=${ELECTRUM_RPC_PASSWORD}
- ELECTRUM_SERVER_ADDRESS=${LITECOIN_ELECTRUM_SERVER_ADDRESS}
monero-wallet-rpc:
image: ghcr.io/sethforprivacy/simple-monero-wallet-rpc:latest
build:
context: ./docker/monero-wallet-rpc
restart: unless-stopped
container_name: monero-wallet-rpc
volumes:
- monero-wallet-rpc-data:/home/monero
command:
- "--trusted-daemon"
- "--rpc-bind-port=18082"
- "--rpc-login=user:${MONERO_RPC_PASSWORD}"
- "--daemon-address=${MONERO_DAEMON_ADDRESS}"
- "--wallet-dir=/home/monero/wallet"
- "--log-level=4"
- --trusted-daemon
- --rpc-bind-port=18082
- --rpc-login=user:${MONERO_RPC_PASSWORD}
- --daemon-address=${MONERO_DAEMON_ADDRESS}
- --wallet-dir=/home/monero/wallet
seed-importer:
build:
@@ -64,6 +67,7 @@ services:
container_name: seed-importer
environment:
- PYTHONUNBUFFERED=1
- TESTNET=${TESTNET}
- BITCOIN_ELECTRUM_RPC_URL=http://btc-electrum:7000
- LITECOIN_ELECTRUM_RPC_URL=http://ltc-electrum:7000
- LITECOIN_MWEB_ELECTRUM_RPC_URL=http://ltc-mweb-electrum:7000
@@ -91,6 +95,7 @@ services:
restart: unless-stopped
environment:
- PYTHONUNBUFFERED=1
- TESTNET=${TESTNET}
- BITCOIN_ELECTRUM_RPC_URL=http://btc-electrum:7000
- LITECOIN_ELECTRUM_RPC_URL=http://ltc-electrum:7000
- LITECOIN_MWEB_ELECTRUM_RPC_URL=http://ltc-mweb-electrum:7000
@@ -114,6 +119,7 @@ services:
restart: unless-stopped
environment:
- PYTHONUNBUFFERED=1
- TESTNET=${TESTNET}
- KRAKEN_API_KEY=${KRAKEN_API_KEY}
- KRAKEN_API_SECRET=${KRAKEN_API_SECRET}
command: python ./src/autoconvert.py

View File

@@ -15,7 +15,7 @@ RUN mkdir -p ${ELECTRUM_HOME}/.electrum && \
# 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 apk --no-cache add --virtual build-dependencies make gcc musl-dev libsecp256k1 libsecp256k1-dev libressl-dev autoconf automake libtool
RUN wget https://download.electrum.org/${ELECTRUM_VERSION}/Electrum-${ELECTRUM_VERSION}.tar.gz
RUN [ "${ELECTRUM_CHECKSUM_SHA512} Electrum-${ELECTRUM_VERSION}.tar.gz" = "$(sha512sum Electrum-${ELECTRUM_VERSION}.tar.gz)" ]
RUN echo -e "**************************\n SHA 512 Checksum OK\n**************************"

View File

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

View File

@@ -4,7 +4,7 @@ ARG VERSION
ARG CHECKSUM_SHA512
RUN apt update && \
apt install -y wget libfuse2 fuse3
apt install -y wget libfuse2 fuse3 python3-pyqt6
ENV ELECTRUM_VERSION=$VERSION
ENV ELECTRUM_USER=electrum

View File

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

View File

@@ -0,0 +1,5 @@
FROM ghcr.io/sethforprivacy/simple-monero-wallet-rpc:latest
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]

View File

@@ -0,0 +1,14 @@
#!/bin/sh
set -e
ADDITIONAL_FLAGS=""
if [ "$TESTNET" = "1" ]; then
ADDITIONAL_FLAGS="--testnet"
fi
set -- "monero-wallet-rpc" "--non-interactive" "--rpc-bind-ip=0.0.0.0" "--confirm-external-bind" $ADDITIONAL_FLAGS "$@"
# Start the daemon using fixuid
# to adjust permissions if needed
exec fixuid -q "$@"

View File

@@ -1,8 +1,7 @@
from typing import Literal, cast
import math
import traceback
import random
import time
import util
import env
@@ -86,28 +85,32 @@ def attempt_sell(asset, settlement_currency, settlement_kraken_ticker):
else:
print(f'No balance for {asset}; skipping')
if __name__ == '__main__':
if env.TESTNET == '1':
print('Testnet mode enabled. Autoconvert will now sleep forever.')
time.sleep(999999999)
while 1:
# First, get the settlement currency formatted correctly
settlement_currency = env.SETTLEMENT_CURRENCY
# https://support.kraken.com/hc/en-us/articles/360001206766-Bitcoin-currency-code-XBT-vs-BTC
if settlement_currency in ['AUD', 'CAD', 'EUR', 'GBP', 'JPY', 'USD']:
settlement_kraken_ticker = 'Z' + settlement_currency
elif settlement_currency in ['ETC', 'ETH', 'LTC', 'MLN', 'REP', 'XBT', 'XDG', 'XLM', 'XMR', 'XRP', 'ZEC']:
settlement_kraken_ticker = 'X' + settlement_currency
else:
settlement_kraken_ticker = settlement_currency
while 1:
# First, get the settlement currency formatted correctly
settlement_currency = env.SETTLEMENT_CURRENCY
# https://support.kraken.com/hc/en-us/articles/360001206766-Bitcoin-currency-code-XBT-vs-BTC
if settlement_currency in ['AUD', 'CAD', 'EUR', 'GBP', 'JPY', 'USD']:
settlement_kraken_ticker = 'Z' + settlement_currency
elif settlement_currency in ['ETC', 'ETH', 'LTC', 'MLN', 'REP', 'XBT', 'XDG', 'XLM', 'XMR', 'XRP', 'ZEC']:
settlement_kraken_ticker = 'X' + settlement_currency
else:
settlement_kraken_ticker = settlement_currency
# Then, initiate the selling process for each supported asset unless it's already the settlement currency
for asset in ['XBT', 'LTC', 'XMR']:
try:
if settlement_currency != asset:
attempt_sell(asset, settlement_currency, settlement_kraken_ticker)
else:
print(f'Not converting {asset} since it is already in the settlement currency')
except Exception as e:
print(util.get_time(), f'Error attempting to sell {asset}:')
print(traceback.format_exc())
# Then, initiate the selling process for each supported asset unless it's already the settlement currency
for asset in ['XBT', 'LTC', 'XMR']:
try:
if settlement_currency != asset:
attempt_sell(asset, settlement_currency, settlement_kraken_ticker)
else:
print(f'Not converting {asset} since it is already in the settlement currency')
except Exception as e:
print(util.get_time(), f'Error attempting to sell {asset}:')
print(traceback.format_exc())
delay = random.randint(30, 90)
time.sleep(delay)
delay = random.randint(30, 90)
time.sleep(delay)

View File

@@ -5,7 +5,7 @@ import traceback
import requests
import json
from constants import MIN_BITCOIN_SEND_AMOUNT, MIN_LITECOIN_SEND_AMOUNT, MIN_MONERO_SEND_AMOUNT
from constants import MIN_BITCOIN_SEND_AMOUNT_MAINNET, MIN_BITCOIN_SEND_AMOUNT_TESTNET, MIN_LITECOIN_SEND_AMOUNT_MAINNET, MIN_LITECOIN_SEND_AMOUNT_TESTNET, MIN_MONERO_SEND_AMOUNT_MAINNET, MIN_MONERO_SEND_AMOUNT_TESTNET
import util
import env
@@ -29,20 +29,25 @@ def get_fee_rate(coin: ElectrumCoin) -> int:
return requests.get(source).json()[rate]
def set_electrum_fee_rate(coin: ElectrumCoin, rate: int, dynamic: bool):
def set_electrum_fee_rate(coin: ElectrumCoin, rate: int = None, dynamic: bool = None):
if dynamic: # Fall back to the Electrum rate if there is an issue
util.request_electrum_rpc(coin, 'setconfig', ['dynamic_fees', True])
util.request_electrum_rpc(coin, 'setconfig', ['fee_policy.default', 'eta:3'])
elif rate:
util.request_electrum_rpc(coin, 'setconfig', ['fee_policy.default', f'feerate:{rate * 1000}'])
else:
util.request_electrum_rpc(coin, 'setconfig', ['dynamic_fees', False])
util.request_electrum_rpc(coin, 'setconfig', ['fee_per_kb', rate * 1000])
raise Exception('Either rate or dynamic=True must be provided')
def get_electrum_balance(coin: ElectrumCoin) -> float:
return float(util.request_electrum_rpc(coin, 'getbalance')['confirmed'])
def create_psbt(coin: ElectrumCoin, destination_address: str, unsigned = True) -> str:
def get_electrum_unused_address(coin: ElectrumCoin) -> str:
return util.request_electrum_rpc(coin, 'getunusedaddress')
def create_psbt(coin: ElectrumCoin, destination_address: str, fee_rate: int = None, unsigned = True) -> str:
params = {
'destination': destination_address,
'amount': '!',
'feerate': fee_rate,
'unsigned': unsigned # This way we can get the input amounts
}
@@ -51,14 +56,25 @@ def create_psbt(coin: ElectrumCoin, destination_address: str, unsigned = True) -
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:
def get_tx_output_amount(coin: ElectrumCoin, tx_id: str, output_index: int) -> int:
serialized_tx = util.request_electrum_rpc(coin, 'gettransaction', [tx_id])
tx = util.request_electrum_rpc(coin, 'deserialize', [serialized_tx])
for i, output in enumerate(tx['outputs']):
if i == output_index:
return output['value_sats']
raise Exception(f'Output {output_index} not found in {coin} transaction {tx_id}')
def get_total_psbt_fee(coin: ElectrumCoin, tx: dict) -> float:
inputs_sum_sats = 0
outputs_sum_sats = 0
for _input in psbt_data['inputs']:
inputs_sum_sats += cast(int, _input['value_sats'])
for _input in tx['inputs']:
input_amount = get_tx_output_amount(coin, _input['prevout_hash'], _input['prevout_n'])
inputs_sum_sats += input_amount
for _output in psbt_data['outputs']:
for _output in tx['outputs']:
outputs_sum_sats += cast(int, _output['value_sats'])
total_fee_sats = inputs_sum_sats - outputs_sum_sats
@@ -83,6 +99,9 @@ def get_monero_balance() -> float:
params = {'account_index': 0}
return util.request_monero_rpc('get_balance', params)['unlocked_balance'] / 1000000000000
def get_monero_unused_address() -> str:
return util.request_monero_rpc('get_address', {'account_index': 0})
def sweep_all_monero(address: str) -> None:
params = {
'account_index': 0,
@@ -122,25 +141,34 @@ 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
coin_to_min_send_mainnet: dict[ElectrumCoin, float] = {
'btc': MIN_BITCOIN_SEND_AMOUNT_MAINNET,
'ltc': MIN_LITECOIN_SEND_AMOUNT_MAINNET,
'ltc-mweb': MIN_LITECOIN_SEND_AMOUNT_MAINNET
}
min_send = coin_to_min_send[coin]
coin_to_min_send_testnet: dict[ElectrumCoin, float] = {
'btc': MIN_BITCOIN_SEND_AMOUNT_TESTNET,
'ltc': MIN_LITECOIN_SEND_AMOUNT_TESTNET,
'ltc-mweb': MIN_LITECOIN_SEND_AMOUNT_TESTNET
}
if balance < MIN_BITCOIN_SEND_AMOUNT:
min_send = coin_to_min_send_testnet[coin] if env.TESTNET == '1' else coin_to_min_send_mainnet[coin]
if balance < min_send:
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(coin)
set_electrum_fee_rate(coin, fee_rate, dynamic=False)
set_electrum_fee_rate(coin, fee_rate)
except:
set_electrum_fee_rate(coin, rate=0, dynamic=True)
set_electrum_fee_rate(coin, dynamic=True)
address = get_new_kraken_address(coin if coin != 'ltc-mweb' else 'ltc')
if env.TESTNET == '1':
address = get_electrum_unused_address(coin)
else:
address = get_new_kraken_address(coin if coin != 'ltc-mweb' else 'ltc')
# Electrum-ltc doesn't support deserializing mweb transactions, so we can't check total fee
if coin != 'ltc-mweb':
@@ -155,8 +183,8 @@ def attempt_electrum_autoforward(coin: ElectrumCoin):
raise http_error
psbt_data = get_psbt_data(coin, psbt)
total_fee = get_total_psbt_fee(psbt_data)
tx = get_psbt_data(coin, psbt)
total_fee = get_total_psbt_fee(coin, tx)
amount = balance
if total_fee / amount * 100 > env.MAX_NETWORK_FEE_PERCENT:
@@ -185,11 +213,17 @@ def attempt_electrum_autoforward(coin: ElectrumCoin):
def attempt_monero_autoforward():
balance = get_monero_balance()
if balance < MIN_MONERO_SEND_AMOUNT:
print(util.get_time(), f'Not enough XMR balance to autoforward. (Balance: {balance}, Min Send: {MIN_MONERO_SEND_AMOUNT})')
min_send = MIN_MONERO_SEND_AMOUNT_TESTNET if env.TESTNET == '1' else MIN_MONERO_SEND_AMOUNT_MAINNET
if balance < min_send:
print(util.get_time(), f'Not enough XMR balance to autoforward. (Balance: {balance}, Min Send: {min_send})')
return
address = get_new_kraken_address('xmr')
if env.TESTNET == '1':
address = get_monero_unused_address()
else:
address = get_new_kraken_address('xmr')
sweep_all_monero(address)
print(util.get_time(), f'Autoforwarded {balance} XMR to {address}!')

View File

@@ -1,3 +1,7 @@
MIN_BITCOIN_SEND_AMOUNT = 0.0001
MIN_LITECOIN_SEND_AMOUNT = 0.05
MIN_MONERO_SEND_AMOUNT = 0.03
MIN_BITCOIN_SEND_AMOUNT_MAINNET = 0.0001
MIN_LITECOIN_SEND_AMOUNT_MAINNET = 0.05
MIN_MONERO_SEND_AMOUNT_MAINNET = 0.03
MIN_BITCOIN_SEND_AMOUNT_TESTNET = 0.00001
MIN_LITECOIN_SEND_AMOUNT_TESTNET = 0.00001
MIN_MONERO_SEND_AMOUNT_TESTNET = 0.00001

View File

@@ -1,5 +1,7 @@
import os
TESTNET = os.getenv('TESTNET', '0')
BITCOIN_ELECTRUM_RPC_URL = os.getenv('BITCOIN_ELECTRUM_RPC_URL', '')
LITECOIN_ELECTRUM_RPC_URL = os.getenv('LITECOIN_ELECTRUM_RPC_URL', '')
LITECOIN_MWEB_ELECTRUM_RPC_URL = os.getenv('LITECOIN_MWEB_ELECTRUM_RPC_URL', '')

View File

@@ -1,24 +1,37 @@
from typing import Literal
from bip_utils import Bip39SeedGenerator, Bip84, Bip84Coins
import traceback
import util
import env
def get_xprv_from_mnemonic(coin: Literal['btc', 'ltc',], mnemonic: str ) -> str:
coin_type = Bip84Coins.BITCOIN if coin == 'btc' else Bip84Coins.LITECOIN
if env.TESTNET == '1':
coin_type = Bip84Coins.BITCOIN_TESTNET if coin == 'btc' else Bip84Coins.LITECOIN_TESTNET
else:
coin_type = Bip84Coins.BITCOIN if coin == 'btc' else Bip84Coins.LITECOIN
seed_bytes = Bip39SeedGenerator(mnemonic).Generate()
bip84_master_key = Bip84.FromSeed(seed_bytes, coin_type)
zprv = bip84_master_key.Purpose().Coin().Account(0).PrivateKey().ToExtended()
return zprv
def import_bitcoin_seed():
xprv = get_xprv_from_mnemonic('btc', env.BITCOIN_WALLET_SEED)
util.request_electrum_rpc('btc', 'restore', [xprv])
# Only support electrum format for testnet
if env.TESTNET == '1':
key = env.BITCOIN_WALLET_SEED
else:
key = get_xprv_from_mnemonic('btc', env.BITCOIN_WALLET_SEED)
util.request_electrum_rpc('btc', 'restore', [key])
def import_litecoin_seed():
xprv = get_xprv_from_mnemonic('ltc', env.LITECOIN_WALLET_SEED)
util.request_electrum_rpc('ltc', 'restore', [xprv])
# Only support electrum format for testnet
if env.TESTNET == '1':
key = env.LITECOIN_WALLET_SEED
else:
key = get_xprv_from_mnemonic('ltc', env.LITECOIN_WALLET_SEED)
util.request_electrum_rpc('ltc', 'restore', [key])
def import_litecoin_mweb_seed():
util.request_electrum_rpc('ltc-mweb', 'restore', [env.LITECOIN_MWEB_WALLET_SEED])
@@ -43,8 +56,12 @@ try:
util.request_electrum_rpc('btc', 'changegaplimit', [1000, 'iknowhatimdoing'])
print('Bitcoin seed has successfully been imported!')
except Exception as e:
print(util.get_time(), 'Error importing bitcoin seed:')
print(traceback.format_exc())
if 'Remove the existing wallet first!' in e.__str__():
print('Bitcoin wallet already exists. Skipping...')
else:
print(util.get_time(), 'Error importing bitcoin seed:')
print(traceback.format_exc())
try:
import_litecoin_seed()
@@ -52,8 +69,11 @@ try:
util.request_electrum_rpc('ltc', 'changegaplimit', [1000, 'iknowhatimdoing'])
print('Litecoin seed has successfully been imported!')
except Exception as e:
print(util.get_time(), 'Error importing litecoin seed:')
print(traceback.format_exc())
if 'Remove the existing wallet first!' in e.__str__():
print('Bitcoin wallet already exists. Skipping...')
else:
print(util.get_time(), 'Error importing litecoin seed:')
print(traceback.format_exc())
try:
import_litecoin_mweb_seed()
@@ -61,12 +81,18 @@ try:
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())
if 'Remove the existing wallet first!' in e.__str__():
print('Litecoin mimblewimble wallet already exists. Skipping...')
else:
print(util.get_time(), 'Error importing litecoin mimblewimble seed:')
print(traceback.format_exc())
try:
import_monero_seed()
print('Monero seed has successfully been imported!')
except Exception as e:
print(util.get_time(), 'Error importing monero seed:')
print(traceback.format_exc())
if 'Remove the existing wallet first!' in e.__str__():
print('Bitcoin wallet already exists. Skipping...')
else:
print(util.get_time(), 'Error importing monero seed:')
print(traceback.format_exc())

View File

@@ -9,7 +9,6 @@ import base64
import hmac
import json
import time
import env
def get_time() -> str:
@@ -109,6 +108,15 @@ def wait_for_rpc():
request_electrum_rpc('ltc', 'getinfo')
break
except:
time.sleep(10)
while 1:
try:
request_electrum_rpc('ltc-mweb', 'getinfo')
break
except:
time.sleep(10)
print('Waiting for Monero RPC...')