mirror of
https://github.com/RoboSats/robosats.git
synced 2025-07-28 13:03:36 +00:00
Add bitcoin RPC methods for onchain address validation (#198)
* Added params to connect to bitcoin core daemon. Needed by api.utils.validate_onchain_address() * Fixes issue#194 * Modified BITCOIND_RPCUSER and BITCOIND_RPCPASSWORD to default development environment * Modified BITCOIND_RPCURL port number to default development environment
This commit is contained in:
17
.env-sample
17
.env-sample
@ -8,6 +8,11 @@ LND_CERT_BASE64='LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNLVENDQWRDZ0F3SUJBZ0l
|
|||||||
# base64 ~/.lnd/data/chain/bitcoin/testnet/admin.macaroon | tr -d '\n'
|
# base64 ~/.lnd/data/chain/bitcoin/testnet/admin.macaroon | tr -d '\n'
|
||||||
LND_MACAROON_BASE64='AgEDbG5kAvgBAwoQsyI+PK+fyb7F2UyTeZ4seRIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgMt90uD6v4truTadWCjlppoeJ4hZrL1SBb09Y+4WOiI0='
|
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
|
# Postgresql Database
|
||||||
POSTGRES_NAME='postgres'
|
POSTGRES_NAME='postgres'
|
||||||
POSTGRES_USER='postgres'
|
POSTGRES_USER='postgres'
|
||||||
@ -16,7 +21,7 @@ POSTGRES_HOST='127.0.0.1'
|
|||||||
POSTGRES_PORT='5432'
|
POSTGRES_PORT='5432'
|
||||||
|
|
||||||
# Auto unlock LND password. Only used in development docker-compose environment.
|
# 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'
|
# To disable auto unlock, comment out 'wallet-unlock-password-file=/tmp/pwd' from 'docker/lnd/lnd.conf'
|
||||||
AUTO_UNLOCK_PWD='1234'
|
AUTO_UNLOCK_PWD='1234'
|
||||||
|
|
||||||
@ -73,18 +78,18 @@ RETRY_TIME = 1
|
|||||||
MAX_PUBLIC_ORDERS = 100
|
MAX_PUBLIC_ORDERS = 100
|
||||||
|
|
||||||
# Trade limits in satoshis
|
# Trade limits in satoshis
|
||||||
MIN_TRADE = 20000
|
MIN_TRADE = 20000
|
||||||
MAX_TRADE = 3000000
|
MAX_TRADE = 3000000
|
||||||
MAX_TRADE_BONDLESS_TAKER = 50000
|
MAX_TRADE_BONDLESS_TAKER = 50000
|
||||||
|
|
||||||
# For CLTV_expiry calculation
|
# For CLTV_expiry calculation
|
||||||
# Assume 8 min/block assumed
|
# Assume 8 min/block assumed
|
||||||
BLOCK_TIME = 8
|
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)
|
# 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
|
MAX_MINING_NETWORK_SPEEDUP_EXPECTED = 1.7
|
||||||
|
|
||||||
# Expiration time for locking collateral in SECONDS
|
# Expiration time for locking collateral in SECONDS
|
||||||
EXP_MAKER_BOND_INVOICE = 300
|
EXP_MAKER_BOND_INVOICE = 300
|
||||||
EXP_TAKER_BOND_INVOICE = 200
|
EXP_TAKER_BOND_INVOICE = 200
|
||||||
|
|
||||||
# Time a order is public in the book HOURS
|
# Time a order is public in the book HOURS
|
||||||
@ -114,7 +119,7 @@ DISABLE_ONCHAIN = False
|
|||||||
SWAP_FEE_SHAPE = 'exponential'
|
SWAP_FEE_SHAPE = 'exponential'
|
||||||
# EXPONENTIAL. fee (%) = MIN_SWAP_FEE + (MAX_SWAP_FEE - MIN_SWAP_FEE) * e ^ (-LAMBDA * onchain_liquidity_fraction)
|
# EXPONENTIAL. fee (%) = MIN_SWAP_FEE + (MAX_SWAP_FEE - MIN_SWAP_FEE) * e ^ (-LAMBDA * onchain_liquidity_fraction)
|
||||||
SWAP_LAMBDA = 8.8
|
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%.
|
# 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%)
|
# Minimum swap fee as fraction (1%)
|
||||||
MIN_SWAP_FEE = 0.01
|
MIN_SWAP_FEE = 0.01
|
||||||
@ -124,7 +129,7 @@ MIN_SWAP_POINT = 0.35
|
|||||||
MAX_SWAP_FEE = 0.1
|
MAX_SWAP_FEE = 0.1
|
||||||
# Liquidity split point (LN/onchain) at which we use MAX_SWAP_FEE
|
# Liquidity split point (LN/onchain) at which we use MAX_SWAP_FEE
|
||||||
MAX_SWAP_POINT = 0
|
MAX_SWAP_POINT = 0
|
||||||
# Min amount allowed for Swap
|
# Min amount allowed for Swap
|
||||||
MIN_SWAP_AMOUNT = 10000
|
MIN_SWAP_AMOUNT = 10000
|
||||||
|
|
||||||
# Reward tip. Reward for every finished trade in the referral program (Satoshis)
|
# Reward tip. Reward for every finished trade in the referral program (Satoshis)
|
||||||
|
75
api/utils.py
75
api/utils.py
@ -1,9 +1,14 @@
|
|||||||
import requests, ring, os
|
import json
|
||||||
from decouple import config
|
import os
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import coinaddrvalidator as addr
|
import requests
|
||||||
|
import ring
|
||||||
|
from decouple import config
|
||||||
|
|
||||||
from api.models import Order
|
from api.models import Order
|
||||||
|
|
||||||
|
|
||||||
def get_tor_session():
|
def get_tor_session():
|
||||||
session = requests.session()
|
session = requests.session()
|
||||||
# Tor uses the 9050 port as the default socks port
|
# 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'}
|
'https': 'socks5://127.0.0.1:9050'}
|
||||||
return session
|
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):
|
def validate_onchain_address(address):
|
||||||
'''
|
"""
|
||||||
Validates an onchain address
|
Validates an onchain address
|
||||||
'''
|
"""
|
||||||
|
|
||||||
validation = addr.validate('btc', address.encode('utf-8'))
|
|
||||||
|
|
||||||
if not validation.valid:
|
try:
|
||||||
return False, {
|
validation = bitcoind_rpc('validateaddress', [address])
|
||||||
"bad_address":
|
if not validation['isvalid']:
|
||||||
"Does not look like a valid address"
|
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 = {}
|
market_cache = {}
|
||||||
@ring.dict(market_cache, expire=3) # keeps in cache for 3 seconds
|
@ring.dict(market_cache, expire=3) # keeps in cache for 3 seconds
|
||||||
|
Reference in New Issue
Block a user