mirror of
https://github.com/basicswap/basicswap.git
synced 2024-12-31 15:59:28 +00:00
XMR amounts in http interface.
This commit is contained in:
parent
327394e81b
commit
2d4131d4ee
7 changed files with 72 additions and 18 deletions
|
@ -7,6 +7,7 @@
|
|||
from enum import IntEnum
|
||||
from .util import (
|
||||
COIN,
|
||||
format_amount
|
||||
)
|
||||
|
||||
XMR_COIN = 10 ** 12
|
||||
|
@ -193,7 +194,7 @@ chainparams = {
|
|||
|
||||
class CoinInterface:
|
||||
def format_amount(self, amount_int):
|
||||
return format_amount(feerate, self.exp())
|
||||
return format_amount(amount_int, self.exp())
|
||||
|
||||
def coin_name(self):
|
||||
return chainparams[self.coin_type()]['name'].capitalize()
|
||||
|
|
|
@ -17,8 +17,6 @@ from jinja2 import Environment, PackageLoader
|
|||
|
||||
from . import __version__
|
||||
from .util import (
|
||||
COIN,
|
||||
format8,
|
||||
make_int,
|
||||
dumpj,
|
||||
)
|
||||
|
@ -157,6 +155,8 @@ def describeBid(swap_client, bid, offer, edit_bid, show_txns):
|
|||
|
||||
coin_from = Coins(offer.coin_from)
|
||||
coin_to = Coins(offer.coin_to)
|
||||
ci_from = swap_client.ci(coin_from)
|
||||
ci_to = swap_client.ci(coin_to)
|
||||
ticker_from = swap_client.getTicker(coin_from)
|
||||
ticker_to = swap_client.getTicker(coin_to)
|
||||
|
||||
|
@ -189,8 +189,8 @@ def describeBid(swap_client, bid, offer, edit_bid, show_txns):
|
|||
state_description = ''
|
||||
|
||||
data = {
|
||||
'amt_from': format8(bid.amount),
|
||||
'amt_to': format8((bid.amount * offer.rate) // COIN),
|
||||
'amt_from': ci_from.format_amount(bid.amount),
|
||||
'amt_to': ci_to.format_amount((bid.amount * offer.rate) // ci_from.COIN()),
|
||||
'ticker_from': ticker_from,
|
||||
'ticker_to': ticker_to,
|
||||
'bid_state': strBidState(bid.state),
|
||||
|
@ -374,6 +374,8 @@ class HttpHandler(BaseHTTPRequestHandler):
|
|||
'error': w['error']
|
||||
})
|
||||
continue
|
||||
|
||||
ci = swap_client.ci(k)
|
||||
fee_rate = swap_client.getFeeRateForCoin(k)
|
||||
tx_vsize = swap_client.getContractSpendTxVSize(k)
|
||||
est_fee = (fee_rate * tx_vsize) / 1000
|
||||
|
@ -381,8 +383,8 @@ class HttpHandler(BaseHTTPRequestHandler):
|
|||
'name': w['name'],
|
||||
'version': w['version'],
|
||||
'cid': str(int(k)),
|
||||
'fee_rate': format8(fee_rate * COIN),
|
||||
'est_fee': format8(est_fee * COIN),
|
||||
'fee_rate': ci.format_amount(int(fee_rate * ci.COIN())),
|
||||
'est_fee': ci.format_amount(int(est_fee * ci.COIN())),
|
||||
'balance': w['balance'],
|
||||
'blocks': w['blocks'],
|
||||
'synced': w['synced'],
|
||||
|
@ -437,6 +439,7 @@ class HttpHandler(BaseHTTPRequestHandler):
|
|||
raise ValueError('Unknown Coin From')
|
||||
try:
|
||||
coin_to = Coins(int(form_data[b'coin_to'][0]))
|
||||
ci_to = swap_client.ci(coin_to)
|
||||
except Exception:
|
||||
raise ValueError('Unknown Coin To')
|
||||
|
||||
|
@ -444,7 +447,7 @@ class HttpHandler(BaseHTTPRequestHandler):
|
|||
value_to = inputAmount(form_data[b'amt_to'][0].decode('utf-8'))
|
||||
|
||||
min_bid = int(value_from)
|
||||
rate = int((value_to / value_from) * COIN)
|
||||
rate = int((value_to / value_from) * ci_to.COIN())
|
||||
autoaccept = True if b'autoaccept' in form_data else False
|
||||
lock_seconds = int(form_data[b'lockhrs'][0]) * 60 * 60
|
||||
# TODO: More accurate rate
|
||||
|
@ -516,8 +519,8 @@ class HttpHandler(BaseHTTPRequestHandler):
|
|||
'coin_from': ci_from.coin_name(),
|
||||
'coin_to': ci_to.coin_name(),
|
||||
'amt_from': ci_from.format_amount(offer.amount_from),
|
||||
'amt_to': ci_to.format_amount((offer.amount_from * offer.rate) // COIN),
|
||||
'rate': format8(offer.rate),
|
||||
'amt_to': ci_to.format_amount((offer.amount_from * offer.rate) // ci_from.COIN()),
|
||||
'rate': ci_to.format_amount(offer.rate),
|
||||
'lock_type': getLockName(offer.lock_type),
|
||||
'lock_value': offer.lock_value,
|
||||
'addr_from': offer.addr_from,
|
||||
|
@ -540,7 +543,7 @@ class HttpHandler(BaseHTTPRequestHandler):
|
|||
sent_bid_id=sent_bid_id,
|
||||
messages=messages,
|
||||
data=data,
|
||||
bids=[(b[1].hex(), format8(b[3]), strBidState(b[4]), strTxState(b[6]), strTxState(b[7])) for b in bids],
|
||||
bids=[(b[1].hex(), ci_from.format_amount(b[3]), strBidState(b[4]), strTxState(b[6]), strTxState(b[7])) for b in bids],
|
||||
addrs=None if show_bid_form is None else swap_client.listSmsgAddresses('bid'),
|
||||
form_id=os.urandom(8).hex(),
|
||||
), 'UTF-8')
|
||||
|
@ -583,6 +586,18 @@ class HttpHandler(BaseHTTPRequestHandler):
|
|||
|
||||
offers = swap_client.listOffers(sent, filters)
|
||||
|
||||
formatted_offers = []
|
||||
for o in offers:
|
||||
ci_from = swap_client.ci(Coins(o.coin_from))
|
||||
ci_to = swap_client.ci(Coins(o.coin_to))
|
||||
formatted_offers.append((
|
||||
time.strftime('%Y-%m-%d %H:%M', time.localtime(o.created_at)),
|
||||
o.offer_id.hex(),
|
||||
ci_from.coin_name(), ci_to.coin_name(),
|
||||
ci_from.format_amount(o.amount_from),
|
||||
ci_to.format_amount((o.amount_from * o.rate) // ci_from.COIN()),
|
||||
ci_to.format_amount(o.rate)))
|
||||
|
||||
template = env.get_template('offers.html')
|
||||
return bytes(template.render(
|
||||
title=self.server.title,
|
||||
|
@ -591,8 +606,7 @@ class HttpHandler(BaseHTTPRequestHandler):
|
|||
coins=listAvailableCoins(swap_client),
|
||||
messages=messages,
|
||||
filters=filters,
|
||||
offers=[(time.strftime('%Y-%m-%d %H:%M', time.localtime(o.created_at)),
|
||||
o.offer_id.hex(), getCoinName(Coins(o.coin_from)), getCoinName(Coins(o.coin_to)), format8(o.amount_from), format8((o.amount_from * o.rate) // COIN), format8(o.rate)) for o in offers],
|
||||
offers=formatted_offers,
|
||||
form_id=os.urandom(8).hex(),
|
||||
), 'UTF-8')
|
||||
|
||||
|
|
|
@ -81,6 +81,10 @@ class BTCInterface(CoinInterface):
|
|||
def coin_type():
|
||||
return Coins.BTC
|
||||
|
||||
@staticmethod
|
||||
def COIN():
|
||||
return COIN
|
||||
|
||||
@staticmethod
|
||||
def exp():
|
||||
return 8
|
||||
|
@ -118,9 +122,6 @@ class BTCInterface(CoinInterface):
|
|||
self._network = network
|
||||
self.blocks_confirmed = coin_settings['blocks_confirmed']
|
||||
|
||||
def coin_name(self):
|
||||
return chainparams[self.coin_type()]['name']
|
||||
|
||||
def testDaemonRPC(self):
|
||||
self.rpc_callback('getwalletinfo', [])
|
||||
|
||||
|
|
|
@ -37,6 +37,10 @@ class XMRInterface(CoinInterface):
|
|||
def coin_type():
|
||||
return Coins.XMR
|
||||
|
||||
@staticmethod
|
||||
def COIN():
|
||||
return XMR_COIN
|
||||
|
||||
@staticmethod
|
||||
def exp():
|
||||
return 12
|
||||
|
@ -279,6 +283,7 @@ class XMRInterface(CoinInterface):
|
|||
rv = self.rpc_wallet_cb('incoming_transfers', params)
|
||||
if 'transfers' in rv:
|
||||
for transfer in rv['transfers']:
|
||||
print('[rm] transfer', transfer)
|
||||
if transfer['tx_hash'] == txid \
|
||||
and (current_height is None or current_height - transfer['block_height'] > self.blocks_confirmed):
|
||||
return {'txid': transfer['tx_hash'], 'amount': transfer['amount'], 'height': transfer['block_height']}
|
||||
|
|
|
@ -276,6 +276,8 @@ def validate_amount(amount, scale=8):
|
|||
|
||||
|
||||
def format_amount(i, display_scale, scale=None):
|
||||
if not isinstance(i, int):
|
||||
raise ValueError('Amount must be an integer.') # Raise error instead of converting as amounts should always be integers
|
||||
if scale is None:
|
||||
scale = display_scale
|
||||
ep = 10 ** scale
|
||||
|
@ -284,7 +286,7 @@ def format_amount(i, display_scale, scale=None):
|
|||
remainder = n % ep
|
||||
if display_scale != scale:
|
||||
remainder %= (10 ** display_scale)
|
||||
rv = '{}.{:0>{prec}}'.format(quotient, remainder, prec=display_scale)
|
||||
rv = '{}.{:0>{scale}}'.format(quotient, remainder, scale=display_scale)
|
||||
if i < 0:
|
||||
rv = '-' + rv
|
||||
return rv
|
||||
|
|
|
@ -200,6 +200,20 @@ class Test(unittest.TestCase):
|
|||
amount_from = 100 * (10 ** scale_from)
|
||||
rate = 0.1 * (10 ** scale_to)
|
||||
|
||||
amount_to = int((amount_from * rate) // (10 ** scale_from))
|
||||
assert('100.00000000' == format_amount(amount_from, scale_from))
|
||||
assert('10.000000000000' == format_amount(amount_to, scale_to))
|
||||
|
||||
scale_from = 12
|
||||
scale_to = 8
|
||||
amount_from = 1 * (10 ** scale_from)
|
||||
rate = 12 * (10 ** scale_to)
|
||||
|
||||
amount_to = int((amount_from * rate) // (10 ** scale_from))
|
||||
assert('1.000000000000' == format_amount(amount_from, scale_from))
|
||||
assert('12.00000000' == format_amount(amount_to, scale_to))
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -81,6 +81,8 @@ XMR_BASE_ZMQ_PORT = 22792
|
|||
XMR_BASE_WALLET_RPC_PORT = 23792
|
||||
|
||||
PREFIX_SECRET_KEY_REGTEST = 0x2e
|
||||
|
||||
delay_event = threading.Event()
|
||||
stop_test = False
|
||||
|
||||
|
||||
|
@ -263,8 +265,9 @@ def make_rpc_func(node_id, base_rpc_port=BASE_RPC_PORT):
|
|||
|
||||
def signal_handler(sig, frame):
|
||||
global stop_test
|
||||
print('signal {} detected.'.format(sig))
|
||||
logging.info('signal {} detected.'.format(sig))
|
||||
stop_test = True
|
||||
delay_event.set()
|
||||
|
||||
|
||||
def waitForXMRNode(rpc_offset, max_tries=7):
|
||||
|
@ -531,6 +534,11 @@ class Test(unittest.TestCase):
|
|||
return
|
||||
raise ValueError('wait_for_bid timed out.')
|
||||
|
||||
def delay_for(self, delay_for=60):
|
||||
logging.info('Delaying for {} seconds.'.format(delay_for))
|
||||
delay_event.clear()
|
||||
delay_event.wait(delay_for)
|
||||
|
||||
def test_01_part_xmr(self):
|
||||
logging.info('---------- Test PART to XMR')
|
||||
swap_clients = self.swap_clients
|
||||
|
@ -557,6 +565,12 @@ class Test(unittest.TestCase):
|
|||
self.wait_for_bid(swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=180)
|
||||
self.wait_for_bid(swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True)
|
||||
|
||||
js_0_end = json.loads(urlopen('http://localhost:1800/json/wallets').read())
|
||||
end_xmr = float(js_0_end['6']['balance']) + float(js_0_end['6']['unconfirmed'])
|
||||
assert(end_xmr > 10.9 and end_xmr < 11.0)
|
||||
|
||||
self.delay_for(600)
|
||||
|
||||
def test_02_leader_recover_a_lock_tx(self):
|
||||
logging.info('---------- Test PART to XMR leader recovers coin a lock tx')
|
||||
swap_clients = self.swap_clients
|
||||
|
@ -658,6 +672,9 @@ class Test(unittest.TestCase):
|
|||
self.wait_for_bid(swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=180)
|
||||
self.wait_for_bid(swap_clients[1], bid_id, BidStates.SWAP_COMPLETED, sent=True)
|
||||
|
||||
def pass_06_delay(self):
|
||||
self.delay_for(60)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
Loading…
Reference in a new issue