diff --git a/.env-sample b/.env-sample index 43f2f61f..65f13893 100644 --- a/.env-sample +++ b/.env-sample @@ -8,6 +8,11 @@ LND_CERT_BASE64='LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNLVENDQWRDZ0F3SUJBZ0l # base64 ~/.lnd/data/chain/bitcoin/testnet/admin.macaroon | tr -d '\n' LND_MACAROON_BASE64='AgEDbG5kAvgBAwoQsyI+PK+fyb7F2UyTeZ4seRIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgMt90uD6v4truTadWCjlppoeJ4hZrL1SBb09Y+4WOiI0=' +# Bitcoin Core Daemon RPC, used to validate addresses +BITCOIND_RPCURL = 'http://127.0.0.1:18332' +BITCOIND_RPCUSER = 'robodev' +BITCOIND_RPCPASSWORD = 'robodev' + # Postgresql Database POSTGRES_NAME='postgres' POSTGRES_USER='postgres' @@ -16,7 +21,7 @@ POSTGRES_HOST='127.0.0.1' POSTGRES_PORT='5432' # Auto unlock LND password. Only used in development docker-compose environment. -# It will fail starting up the node without it. +# It will fail starting up the node without it. # To disable auto unlock, comment out 'wallet-unlock-password-file=/tmp/pwd' from 'docker/lnd/lnd.conf' AUTO_UNLOCK_PWD='1234' @@ -73,18 +78,18 @@ RETRY_TIME = 1 MAX_PUBLIC_ORDERS = 100 # Trade limits in satoshis -MIN_TRADE = 20000 +MIN_TRADE = 20000 MAX_TRADE = 3000000 MAX_TRADE_BONDLESS_TAKER = 50000 -# For CLTV_expiry calculation +# For CLTV_expiry calculation # Assume 8 min/block assumed BLOCK_TIME = 8 # Safety multiplier in case of mining speed up (CLTV expiry will be times X larger than real time needs for locked bonds/escrow) MAX_MINING_NETWORK_SPEEDUP_EXPECTED = 1.7 # Expiration time for locking collateral in SECONDS -EXP_MAKER_BOND_INVOICE = 300 +EXP_MAKER_BOND_INVOICE = 300 EXP_TAKER_BOND_INVOICE = 200 # Time a order is public in the book HOURS @@ -114,7 +119,7 @@ DISABLE_ONCHAIN = False SWAP_FEE_SHAPE = 'exponential' # EXPONENTIAL. fee (%) = MIN_SWAP_FEE + (MAX_SWAP_FEE - MIN_SWAP_FEE) * e ^ (-LAMBDA * onchain_liquidity_fraction) SWAP_LAMBDA = 8.8 -# LINEAR. 4 parameters needed: min/max fees and min/max balance points. E.g. If 25% or more of liquidity +# LINEAR. 4 parameters needed: min/max fees and min/max balance points. E.g. If 25% or more of liquidity # is onchain the fee for swap is 2% (minimum), if it is 12% fee is 6%, and for 0% fee is 10%. # Minimum swap fee as fraction (1%) MIN_SWAP_FEE = 0.01 @@ -124,7 +129,7 @@ MIN_SWAP_POINT = 0.35 MAX_SWAP_FEE = 0.1 # Liquidity split point (LN/onchain) at which we use MAX_SWAP_FEE MAX_SWAP_POINT = 0 -# Min amount allowed for Swap +# Min amount allowed for Swap MIN_SWAP_AMOUNT = 10000 # Reward tip. Reward for every finished trade in the referral program (Satoshis) diff --git a/api/utils.py b/api/utils.py index d9314615..24178352 100644 --- a/api/utils.py +++ b/api/utils.py @@ -1,9 +1,14 @@ -import requests, ring, os -from decouple import config +import json +import os + import numpy as np -import coinaddrvalidator as addr +import requests +import ring +from decouple import config + from api.models import Order + def get_tor_session(): session = requests.session() # Tor uses the 9050 port as the default socks port @@ -11,36 +16,48 @@ def get_tor_session(): 'https': 'socks5://127.0.0.1:9050'} return session + +def bitcoind_rpc(method, params=None): + """ + Makes a RPC call to bitcoin core daemon + :param method: RPC method to call + :param params: list of params required by the calling RPC method + :return: + """ + + BITCOIND_RPCURL = config('BITCOIND_RPCURL') + BITCOIND_RPCUSER = config('BITCOIND_RPCUSER') + BITCOIND_RPCPASSWORD = config('BITCOIND_RPCPASSWORD') + + if params is None: + params = [] + + payload = json.dumps( + { + "jsonrpc": "2.0", + "id": "robosats", + "method": method, + "params": params + } + ) + return requests.post(BITCOIND_RPCURL, auth=(BITCOIND_RPCUSER, BITCOIND_RPCPASSWORD), data=payload).json()['result'] + + def validate_onchain_address(address): - ''' + """ Validates an onchain address - ''' - - validation = addr.validate('btc', address.encode('utf-8')) + """ - if not validation.valid: - return False, { - "bad_address": - "Does not look like a valid address" - } + try: + validation = bitcoind_rpc('validateaddress', [address]) + if not validation['isvalid']: + return False, {"bad_address": validation['error']} + except: + # TODO: log the exception ? + return False, {"bad_address": 'Unable to validate address, check bitcoind backend'} + + return True, None - NETWORK = str(config('NETWORK')) - if NETWORK == 'mainnet': - if validation.network == 'main': - return True, None - else: - return False, { - "bad_address": - "This is not a bitcoin mainnet address" - } - elif NETWORK == 'testnet': - if validation.network == 'test': - return True, None - else: - return False, { - "bad_address": - "This is not a bitcoin testnet address" - } market_cache = {} @ring.dict(market_cache, expire=3) # keeps in cache for 3 seconds