gui: Added confirm step and fee options.
Fee options only apply to the script coin side of xmr swaps.
This commit is contained in:
		
							parent
							
								
									5cd8286aa3
								
							
						
					
					
						commit
						b3c00efe16
					
				@ -970,7 +970,7 @@ class BasicSwap(BaseApp):
 | 
			
		||||
            raise ValueError('Unknown locktype')
 | 
			
		||||
 | 
			
		||||
    def postOffer(self, coin_from, coin_to, amount, rate, min_bid_amount, swap_type,
 | 
			
		||||
                  lock_type=SEQUENCE_LOCK_TIME, lock_value=48 * 60 * 60, auto_accept_bids=False, addr_send_from=None):
 | 
			
		||||
                  lock_type=SEQUENCE_LOCK_TIME, lock_value=48 * 60 * 60, auto_accept_bids=False, addr_send_from=None, extra_options={}):
 | 
			
		||||
        # Offer to send offer.amount_from of coin_from in exchange for offer.amount_from * offer.rate of coin_to
 | 
			
		||||
 | 
			
		||||
        assert(coin_from != coin_to), 'coin_from == coin_to'
 | 
			
		||||
@ -1009,6 +1009,30 @@ class BasicSwap(BaseApp):
 | 
			
		||||
            msg_buf.lock_value = lock_value
 | 
			
		||||
            msg_buf.swap_type = swap_type
 | 
			
		||||
 | 
			
		||||
            if 'from_fee_override' in extra_options:
 | 
			
		||||
                msg_buf.fee_rate_from = make_int(extra_options['from_fee_override'], self.ci(coin_from).exp())
 | 
			
		||||
            else:
 | 
			
		||||
                # TODO: conf_target = ci_from.settings.get('conf_target', 2)
 | 
			
		||||
                conf_target = 2
 | 
			
		||||
                if 'from_fee_conf_target' in extra_options:
 | 
			
		||||
                    conf_target = extra_options['from_fee_conf_target']
 | 
			
		||||
                fee_rate, fee_src = self.getFeeRateForCoin(coin_from, conf_target)
 | 
			
		||||
                if 'from_fee_multiplier_percent' in extra_options:
 | 
			
		||||
                    fee_rate *= extra_options['fee_multiplier'] / 100.0
 | 
			
		||||
                msg_buf.fee_rate_from = make_int(fee_rate, self.ci(coin_from).exp())
 | 
			
		||||
 | 
			
		||||
            if 'to_fee_override' in extra_options:
 | 
			
		||||
                msg_buf.fee_rate_to = make_int(extra_options['to_fee_override'], self.ci(coin_to).exp())
 | 
			
		||||
            else:
 | 
			
		||||
                # TODO: conf_target = ci_to.settings.get('conf_target', 2)
 | 
			
		||||
                conf_target = 2
 | 
			
		||||
                if 'to_fee_conf_target' in extra_options:
 | 
			
		||||
                    conf_target = extra_options['to_fee_conf_target']
 | 
			
		||||
                fee_rate, fee_src = self.getFeeRateForCoin(coin_to, conf_target)
 | 
			
		||||
                if 'to_fee_multiplier_percent' in extra_options:
 | 
			
		||||
                    fee_rate *= extra_options['fee_multiplier'] / 100.0
 | 
			
		||||
                msg_buf.fee_rate_to = make_int(fee_rate, self.ci(coin_to).exp())
 | 
			
		||||
 | 
			
		||||
            if swap_type == SwapTypes.XMR_SWAP:
 | 
			
		||||
                xmr_offer = XmrOffer()
 | 
			
		||||
 | 
			
		||||
@ -1018,18 +1042,8 @@ class BasicSwap(BaseApp):
 | 
			
		||||
                # Delay before the follower can spend from the chain a lock refund tx
 | 
			
		||||
                xmr_offer.lock_time_2 = getExpectedSequence(lock_type, lock_value, coin_from)
 | 
			
		||||
 | 
			
		||||
                # TODO: max fee warning?
 | 
			
		||||
                chain_client_settings = self.getChainClientSettings(coin_from)
 | 
			
		||||
                lock_tx_fee_premium = chain_client_settings.get('lock_tx_fee_premium', 0.0)
 | 
			
		||||
 | 
			
		||||
                xmr_offer.a_fee_rate = make_int(self.getFeeRateForCoin(coin_from) + lock_tx_fee_premium, self.ci(coin_from).exp())
 | 
			
		||||
 | 
			
		||||
                # Unused: TODO - Set priority?
 | 
			
		||||
                # xmr_offer.b_fee_rate = make_int(0.0012595, self.ci(coin_to).exp())
 | 
			
		||||
                xmr_offer.b_fee_rate = make_int(0.00002, self.ci(coin_to).exp())  # abs fee
 | 
			
		||||
 | 
			
		||||
                msg_buf.fee_rate_from = xmr_offer.a_fee_rate
 | 
			
		||||
                msg_buf.fee_rate_to = xmr_offer.b_fee_rate
 | 
			
		||||
                xmr_offer.a_fee_rate = msg_buf.fee_rate_from
 | 
			
		||||
                xmr_offer.b_fee_rate = msg_buf.fee_rate_to  # Unused: TODO - Set priority?
 | 
			
		||||
 | 
			
		||||
            offer_bytes = msg_buf.SerializeToString()
 | 
			
		||||
            payload_hex = str.format('{:02x}', MessageTypes.OFFER) + offer_bytes.hex()
 | 
			
		||||
@ -1243,13 +1257,13 @@ class BasicSwap(BaseApp):
 | 
			
		||||
    def getRelayFeeRateForCoin(self, coin_type):
 | 
			
		||||
        return self.callcoinrpc(coin_type, 'getnetworkinfo')['relayfee']
 | 
			
		||||
 | 
			
		||||
    def getFeeRateForCoin(self, coin_type):
 | 
			
		||||
    def getFeeRateForCoin(self, coin_type, conf_target=2):
 | 
			
		||||
        override_feerate = self.coin_clients[coin_type].get('override_feerate', None)
 | 
			
		||||
        if override_feerate:
 | 
			
		||||
            self.log.debug('Fee rate override used for %s: %f', str(coin_type), override_feerate)
 | 
			
		||||
            return override_feerate
 | 
			
		||||
            return override_feerate, 'override_feerate'
 | 
			
		||||
 | 
			
		||||
        return self.ci(coin_type).get_fee_rate()
 | 
			
		||||
        return self.ci(coin_type).get_fee_rate(conf_target)
 | 
			
		||||
 | 
			
		||||
    def estimateWithdrawFee(self, coin_type, fee_rate):
 | 
			
		||||
        if coin_type == Coins.XMR:
 | 
			
		||||
 | 
			
		||||
@ -203,8 +203,8 @@ class CoinInterface:
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self._unknown_wallet_seed = True
 | 
			
		||||
 | 
			
		||||
    def make_int(self, amount_in):
 | 
			
		||||
        return make_int(amount_in, self.exp())
 | 
			
		||||
    def make_int(self, amount_in, r=0):
 | 
			
		||||
        return make_int(amount_in, self.exp(), r=r)
 | 
			
		||||
 | 
			
		||||
    def format_amount(self, amount_in, conv_int=False):
 | 
			
		||||
        amount_int = make_int(amount_in, self.exp()) if conv_int else amount_in
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,6 @@ from jinja2 import Environment, PackageLoader
 | 
			
		||||
from . import __version__
 | 
			
		||||
from .util import (
 | 
			
		||||
    dumpj,
 | 
			
		||||
    make_int,
 | 
			
		||||
)
 | 
			
		||||
from .chainparams import (
 | 
			
		||||
    chainparams,
 | 
			
		||||
@ -300,61 +299,186 @@ class HttpHandler(BaseHTTPRequestHandler):
 | 
			
		||||
            form_id=os.urandom(8).hex(),
 | 
			
		||||
        ), 'UTF-8')
 | 
			
		||||
 | 
			
		||||
    def postNewOffer(self, form_data):
 | 
			
		||||
    def parseOfferFormData(self, form_data):
 | 
			
		||||
        swap_client = self.server.swap_client
 | 
			
		||||
        addr_from = form_data[b'addr_from'][0].decode('utf-8')
 | 
			
		||||
        if addr_from == '-1':
 | 
			
		||||
            addr_from = None
 | 
			
		||||
 | 
			
		||||
        errors = []
 | 
			
		||||
        page_data = {}
 | 
			
		||||
        parsed_data = {}
 | 
			
		||||
 | 
			
		||||
        if b'addr_from' in form_data:
 | 
			
		||||
            page_data['addr_from'] = form_data[b'addr_from'][0].decode('utf-8')
 | 
			
		||||
            parsed_data['addr_from'] = None if page_data['addr_from'] == '-1' else page_data['addr_from']
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            coin_from = Coins(int(form_data[b'coin_from'][0]))
 | 
			
		||||
            page_data['coin_from'] = int(form_data[b'coin_from'][0])
 | 
			
		||||
            coin_from = Coins(page_data['coin_from'])
 | 
			
		||||
            ci_from = swap_client.ci(coin_from)
 | 
			
		||||
            parsed_data['coin_from'] = coin_from
 | 
			
		||||
        except Exception:
 | 
			
		||||
            raise ValueError('Unknown Coin From')
 | 
			
		||||
            errors.append('Unknown Coin From')
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            coin_to = Coins(int(form_data[b'coin_to'][0]))
 | 
			
		||||
            page_data['coin_to'] = int(form_data[b'coin_to'][0])
 | 
			
		||||
            coin_to = Coins(page_data['coin_to'])
 | 
			
		||||
            ci_to = swap_client.ci(coin_to)
 | 
			
		||||
            parsed_data['coin_to'] = coin_to
 | 
			
		||||
            if coin_to == Coins.XMR:
 | 
			
		||||
                page_data['swap_style'] = 'xmr'
 | 
			
		||||
        except Exception:
 | 
			
		||||
            raise ValueError('Unknown Coin To')
 | 
			
		||||
            errors.append('Unknown Coin To')
 | 
			
		||||
 | 
			
		||||
        value_from = inputAmount(form_data[b'amt_from'][0].decode('utf-8'), ci_from)
 | 
			
		||||
        value_to = inputAmount(form_data[b'amt_to'][0].decode('utf-8'), ci_to)
 | 
			
		||||
        page_data['fee_from_conf'] = int(form_data[b'fee_from_conf'][0])
 | 
			
		||||
        page_data['fee_from_extra'] = int(form_data[b'fee_from_extra'][0])
 | 
			
		||||
 | 
			
		||||
        min_bid = int(value_from)
 | 
			
		||||
        rate = int((value_to / value_from) * ci_from.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
 | 
			
		||||
        # assert(value_to == (value_from * rate) // COIN)
 | 
			
		||||
        parsed_data['fee_from_conf'] = page_data['fee_from_conf']
 | 
			
		||||
        parsed_data['fee_from_extra'] = page_data['fee_from_extra']
 | 
			
		||||
 | 
			
		||||
        if swap_client.coin_clients[coin_from]['use_csv'] and swap_client.coin_clients[coin_to]['use_csv']:
 | 
			
		||||
        page_data['fee_to_conf'] = int(form_data[b'fee_to_conf'][0])
 | 
			
		||||
        page_data['fee_to_extra'] = int(form_data[b'fee_to_extra'][0])
 | 
			
		||||
 | 
			
		||||
        parsed_data['fee_to_conf'] = page_data['fee_to_conf']
 | 
			
		||||
        parsed_data['fee_to_extra'] = page_data['fee_to_extra']
 | 
			
		||||
 | 
			
		||||
        if b'check_offer' in form_data:
 | 
			
		||||
            page_data['check_offer'] = True
 | 
			
		||||
        if b'submit_offer' in form_data:
 | 
			
		||||
            page_data['submit_offer'] = True
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            page_data['amt_from'] = form_data[b'amt_from'][0].decode('utf-8')
 | 
			
		||||
            parsed_data['amt_from'] = inputAmount(page_data['amt_from'], ci_from)
 | 
			
		||||
            parsed_data['min_bid'] = int(parsed_data['amt_from'])
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            errors.append('Amount From')
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            page_data['amt_to'] = form_data[b'amt_to'][0].decode('utf-8')
 | 
			
		||||
            parsed_data['amt_to'] = inputAmount(page_data['amt_to'], ci_to)
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            errors.append('Amount To')
 | 
			
		||||
 | 
			
		||||
        if 'amt_to' in parsed_data and 'amt_from' in parsed_data:
 | 
			
		||||
            parsed_data['rate'] = int((parsed_data['amt_to'] / parsed_data['amt_from']) * ci_from.COIN())
 | 
			
		||||
 | 
			
		||||
        page_data['lockhrs'] = int(form_data[b'lockhrs'][0])
 | 
			
		||||
        parsed_data['lock_seconds'] = page_data['lockhrs'] * 60 * 60
 | 
			
		||||
 | 
			
		||||
        page_data['autoaccept'] = True if b'autoaccept' in form_data else False
 | 
			
		||||
        parsed_data['autoaccept'] = page_data['autoaccept']
 | 
			
		||||
 | 
			
		||||
        if len(errors) == 0:
 | 
			
		||||
            if b'fee_rate_from' in form_data:
 | 
			
		||||
                page_data['from_fee_override'] = form_data[b'fee_rate_from'][0].decode('utf-8')
 | 
			
		||||
                parsed_data['from_fee_override'] = page_data['from_fee_override']
 | 
			
		||||
            else:
 | 
			
		||||
                from_fee_override, page_data['from_fee_src'] = swap_client.getFeeRateForCoin(parsed_data['coin_from'], page_data['fee_from_conf'])
 | 
			
		||||
                if page_data['fee_from_extra'] > 0:
 | 
			
		||||
                    from_fee_override += from_fee_override * (float(page_data['fee_from_extra']) / 100.0)
 | 
			
		||||
                page_data['from_fee_override'] = ci_from.format_amount(ci_from.make_int(from_fee_override, r=1))
 | 
			
		||||
                parsed_data['from_fee_override'] = page_data['from_fee_override']
 | 
			
		||||
 | 
			
		||||
            if b'fee_rate_to' in form_data:
 | 
			
		||||
                page_data['to_fee_override'] = form_data[b'fee_rate_to'][0].decode('utf-8')
 | 
			
		||||
                parsed_data['to_fee_override'] = page_data['to_fee_override']
 | 
			
		||||
            else:
 | 
			
		||||
                to_fee_override, page_data['to_fee_src'] = swap_client.getFeeRateForCoin(parsed_data['coin_to'], page_data['fee_to_conf'])
 | 
			
		||||
                if page_data['fee_to_extra'] > 0:
 | 
			
		||||
                    to_fee_override += to_fee_override * (float(page_data['fee_to_extra']) / 100.0)
 | 
			
		||||
 | 
			
		||||
                page_data['to_fee_override'] = ci_to.format_amount(ci_to.make_int(to_fee_override, r=1))
 | 
			
		||||
                parsed_data['to_fee_override'] = page_data['to_fee_override']
 | 
			
		||||
 | 
			
		||||
        return page_data, parsed_data, errors
 | 
			
		||||
 | 
			
		||||
    def postNewOfferFromParsed(self, parsed_data):
 | 
			
		||||
        swap_client = self.server.swap_client
 | 
			
		||||
 | 
			
		||||
        swap_type = SwapTypes.SELLER_FIRST
 | 
			
		||||
        if parsed_data['coin_to'] == Coins.XMR:
 | 
			
		||||
            swap_type = SwapTypes.XMR_SWAP
 | 
			
		||||
 | 
			
		||||
        if swap_client.coin_clients[parsed_data['coin_from']]['use_csv'] and swap_client.coin_clients[parsed_data['coin_to']]['use_csv']:
 | 
			
		||||
            lock_type = SEQUENCE_LOCK_TIME
 | 
			
		||||
        else:
 | 
			
		||||
            lock_type = ABS_LOCK_TIME
 | 
			
		||||
 | 
			
		||||
        swap_type = SwapTypes.SELLER_FIRST
 | 
			
		||||
        if coin_to == Coins.XMR:
 | 
			
		||||
            swap_type = SwapTypes.XMR_SWAP
 | 
			
		||||
        extra_options = {}
 | 
			
		||||
 | 
			
		||||
        offer_id = swap_client.postOffer(coin_from, coin_to, value_from, rate, min_bid, swap_type, lock_type=lock_type, lock_value=lock_seconds, auto_accept_bids=autoaccept, addr_send_from=addr_from)
 | 
			
		||||
        if 'fee_from_conf' in parsed_data:
 | 
			
		||||
            extra_options['from_fee_conf_target'] = parsed_data['fee_from_conf']
 | 
			
		||||
        if 'from_fee_multiplier_percent' in parsed_data:
 | 
			
		||||
            extra_options['from_fee_multiplier_percent'] = parsed_data['fee_from_extra']
 | 
			
		||||
        if 'from_fee_override' in parsed_data:
 | 
			
		||||
            extra_options['from_fee_override'] = parsed_data['from_fee_override']
 | 
			
		||||
 | 
			
		||||
        if 'fee_to_conf' in parsed_data:
 | 
			
		||||
            extra_options['to_fee_conf_target'] = parsed_data['fee_to_conf']
 | 
			
		||||
        if 'to_fee_multiplier_percent' in parsed_data:
 | 
			
		||||
            extra_options['to_fee_multiplier_percent'] = parsed_data['fee_to_extra']
 | 
			
		||||
        if 'to_fee_override' in parsed_data:
 | 
			
		||||
            extra_options['to_fee_override'] = parsed_data['to_fee_override']
 | 
			
		||||
 | 
			
		||||
        offer_id = swap_client.postOffer(
 | 
			
		||||
            parsed_data['coin_from'],
 | 
			
		||||
            parsed_data['coin_to'],
 | 
			
		||||
            parsed_data['amt_from'],
 | 
			
		||||
            parsed_data['rate'],
 | 
			
		||||
            parsed_data['min_bid'],
 | 
			
		||||
            swap_type,
 | 
			
		||||
            lock_type=lock_type,
 | 
			
		||||
            lock_value=parsed_data['lock_seconds'],
 | 
			
		||||
            auto_accept_bids=parsed_data['autoaccept'],
 | 
			
		||||
            addr_send_from=parsed_data['addr_from'],
 | 
			
		||||
            extra_options=extra_options)
 | 
			
		||||
        return offer_id
 | 
			
		||||
 | 
			
		||||
    def postNewOffer(self, form_data):
 | 
			
		||||
        page_data, parsed_data = self.parseOfferFormData(form_data)
 | 
			
		||||
        return self.postNewOfferFromParsed(parsed_data)
 | 
			
		||||
 | 
			
		||||
    def page_newoffer(self, url_split, post_string):
 | 
			
		||||
        swap_client = self.server.swap_client
 | 
			
		||||
 | 
			
		||||
        messages = []
 | 
			
		||||
        page_data = {}
 | 
			
		||||
        form_data = self.checkForm(post_string, 'newoffer', messages)
 | 
			
		||||
        if form_data:
 | 
			
		||||
            offer_id = self.postNewOffer(form_data)
 | 
			
		||||
            messages.append('<a href="/offer/' + offer_id.hex() + '">Sent Offer {}</a>'.format(offer_id.hex()))
 | 
			
		||||
 | 
			
		||||
        template = env.get_template('offer_new.html')
 | 
			
		||||
        if form_data:
 | 
			
		||||
            try:
 | 
			
		||||
                page_data, parsed_data, errors = self.parseOfferFormData(form_data)
 | 
			
		||||
                for e in errors:
 | 
			
		||||
                    messages.append('Error: {}'.format(str(e)))
 | 
			
		||||
            except Exception as e:
 | 
			
		||||
                messages.append('Error: {}'.format(str(e)))
 | 
			
		||||
 | 
			
		||||
        if len(messages) == 0 and 'submit_offer' in page_data:
 | 
			
		||||
            try:
 | 
			
		||||
                offer_id = self.postNewOfferFromParsed(parsed_data)
 | 
			
		||||
                messages.append('<a href="/offer/' + offer_id.hex() + '">Sent Offer {}</a>'.format(offer_id.hex()))
 | 
			
		||||
                page_data = {}
 | 
			
		||||
            except Exception as e:
 | 
			
		||||
                messages.append('Error: {}'.format(str(e)))
 | 
			
		||||
 | 
			
		||||
        if not page_data:
 | 
			
		||||
            # Set defaults
 | 
			
		||||
            page_data['fee_from_conf'] = 2
 | 
			
		||||
            page_data['fee_to_conf'] = 2
 | 
			
		||||
            page_data['lockhrs'] = 32
 | 
			
		||||
            page_data['autoaccept'] = True
 | 
			
		||||
 | 
			
		||||
        if len(messages) == 0 and 'check_offer' in page_data:
 | 
			
		||||
            template = env.get_template('offer_confirm.html')
 | 
			
		||||
        else:
 | 
			
		||||
            template = env.get_template('offer_new.html')
 | 
			
		||||
 | 
			
		||||
        return bytes(template.render(
 | 
			
		||||
            title=self.server.title,
 | 
			
		||||
            h2=self.server.title,
 | 
			
		||||
            messages=messages,
 | 
			
		||||
            coins=listAvailableCoins(swap_client),
 | 
			
		||||
            addrs=swap_client.listSmsgAddresses('offer'),
 | 
			
		||||
            data=page_data,
 | 
			
		||||
            form_id=os.urandom(8).hex(),
 | 
			
		||||
        ), 'UTF-8')
 | 
			
		||||
 | 
			
		||||
@ -412,10 +536,12 @@ class HttpHandler(BaseHTTPRequestHandler):
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if xmr_offer:
 | 
			
		||||
            int_fee_rate_now = make_int(ci_from.get_fee_rate(), ci_from.exp())
 | 
			
		||||
 | 
			
		||||
            int_fee_rate_now, fee_source = ci_from.get_fee_rate()
 | 
			
		||||
            data['xmr_type'] = True
 | 
			
		||||
            data['a_fee_rate'] = ci_from.format_amount(xmr_offer.a_fee_rate)
 | 
			
		||||
            data['a_fee_rate_verify'] = ci_from.format_amount(int_fee_rate_now)
 | 
			
		||||
            data['a_fee_rate_verify'] = ci_from.format_amount(int_fee_rate_now, conv_int=True)
 | 
			
		||||
            data['a_fee_rate_verify_src'] = fee_source
 | 
			
		||||
            data['a_fee_warn'] = xmr_offer.a_fee_rate < int_fee_rate_now
 | 
			
		||||
 | 
			
		||||
        if offer.was_sent:
 | 
			
		||||
 | 
			
		||||
@ -156,16 +156,16 @@ class BTCInterface(CoinInterface):
 | 
			
		||||
            args.append('bech32')
 | 
			
		||||
        return self.rpc_callback('getnewaddress', args)
 | 
			
		||||
 | 
			
		||||
    def get_fee_rate(self):
 | 
			
		||||
    def get_fee_rate(self, conf_target=2):
 | 
			
		||||
        try:
 | 
			
		||||
            return self.rpc_callback('estimatesmartfee', [2])['feerate']
 | 
			
		||||
            return self.rpc_callback('estimatesmartfee', [conf_target])['feerate'], 'estimatesmartfee'
 | 
			
		||||
        except Exception:
 | 
			
		||||
            try:
 | 
			
		||||
                fee_rate = self.rpc_callback('getwalletinfo')['paytxfee']
 | 
			
		||||
                fee_rate = self.rpc_callback('getwalletinfo')['paytxfee'], 'paytxfee'
 | 
			
		||||
                assert(fee_rate > 0.0), '0 feerate'
 | 
			
		||||
                return fee_rate
 | 
			
		||||
            except Exception:
 | 
			
		||||
                return self.rpc_callback('getnetworkinfo')['relayfee']
 | 
			
		||||
                return self.rpc_callback('getnetworkinfo')['relayfee'], 'relayfee'
 | 
			
		||||
 | 
			
		||||
    def decodeAddress(self, address):
 | 
			
		||||
        bech32_prefix = chainparams[self.coin_type()][self._network]['hrp']
 | 
			
		||||
 | 
			
		||||
@ -126,9 +126,9 @@ class XMRInterface(CoinInterface):
 | 
			
		||||
        self.rpc_wallet_cb('open_wallet', {'filename': self._wallet_filename})
 | 
			
		||||
        return self.rpc_wallet_cb('get_address')['address']
 | 
			
		||||
 | 
			
		||||
    def get_fee_rate(self):
 | 
			
		||||
    def get_fee_rate(self, conf_target=2):
 | 
			
		||||
        logging.warning('TODO - estimate fee rate?')
 | 
			
		||||
        return 0.0012595
 | 
			
		||||
        return 0.0, 'unused'
 | 
			
		||||
 | 
			
		||||
    def isValidKey(self, key_bytes):
 | 
			
		||||
        ki = b2i(key_bytes)
 | 
			
		||||
 | 
			
		||||
@ -53,7 +53,9 @@
 | 
			
		||||
{% if data.was_received == 'True' %}
 | 
			
		||||
<input name="accept_bid" type="submit" value="Accept Bid"><br/>
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% if data.can_abandon == true %}
 | 
			
		||||
<input name="abandon_bid" type="submit" value="Abandon Bid" onclick="confirmPopup()">
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% if data.show_txns %}
 | 
			
		||||
<input name="hide_txns" type="submit" value="Hide Info">
 | 
			
		||||
{% else %}
 | 
			
		||||
 | 
			
		||||
@ -36,9 +36,11 @@
 | 
			
		||||
<input name="edit_bid_submit" type="submit" value="Submit">
 | 
			
		||||
{% else %}
 | 
			
		||||
{% if data.was_received == 'True' %}
 | 
			
		||||
<input name="accept_bid" type="submit" value="Accept Bid"><br/>
 | 
			
		||||
<input name="accept_bid" type="submit" value="Accept Bid" onclick="confirmPopup(\"Accept\")"><br/>
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% if data.can_abandon == true %}
 | 
			
		||||
<input name="abandon_bid" type="submit" value="Abandon Bid" onclick="confirmPopup(\"Abandon\")">
 | 
			
		||||
{% endif %}
 | 
			
		||||
<input name="abandon_bid" type="submit" value="Abandon Bid" onclick="confirmPopup()">
 | 
			
		||||
{% if data.show_txns %}
 | 
			
		||||
<input name="hide_txns" type="submit" value="Hide Info">
 | 
			
		||||
{% else %}
 | 
			
		||||
@ -91,8 +93,8 @@
 | 
			
		||||
 | 
			
		||||
<p><a href="/">home</a></p>
 | 
			
		||||
<script>
 | 
			
		||||
function confirmPopup() {
 | 
			
		||||
    confirm("Are you sure?");
 | 
			
		||||
function confirmPopup(name) {
 | 
			
		||||
    confirm(name + " Bid - Are you sure?");
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
</body></html>
 | 
			
		||||
 | 
			
		||||
@ -33,7 +33,7 @@
 | 
			
		||||
 | 
			
		||||
{% if data.xmr_type == true %}
 | 
			
		||||
<tr><td>Chain A offer fee rate</td><td>{{ data.a_fee_rate }}</td></tr>
 | 
			
		||||
<tr><td>Chain A local fee rate</td><td>{{ data.a_fee_rate_verify }} {% if data.a_fee_warn == true %} WARNING {% endif %}</td></tr>
 | 
			
		||||
<tr><td>Chain A local fee rate</td><td>{{ data.a_fee_rate_verify }}, fee source: {{ data.a_fee_rate_verify_src }} {% if data.a_fee_warn == true %} WARNING {% endif %}</td></tr>
 | 
			
		||||
{% endif %}
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
@ -57,7 +57,7 @@
 | 
			
		||||
{% else %}
 | 
			
		||||
<input type="submit" name="newbid" value="New Bid">
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% if data.sent == 'True' %}
 | 
			
		||||
{% if data.sent == 'True' and data.was_revoked != true %}
 | 
			
		||||
<input name="revoke_offer" type="submit" value="Revoke Offer" onclick="confirmPopup()">
 | 
			
		||||
{% endif %}
 | 
			
		||||
<input type="hidden" name="formid" value="{{ form_id }}">
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										67
									
								
								basicswap/templates/offer_confirm.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								basicswap/templates/offer_confirm.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,67 @@
 | 
			
		||||
{% include 'header.html' %}
 | 
			
		||||
 | 
			
		||||
<h3>Confirm New Offer</h3>
 | 
			
		||||
{% for m in messages %}
 | 
			
		||||
<p>{{ m }}</p>
 | 
			
		||||
{% endfor %}
 | 
			
		||||
 | 
			
		||||
<form method="post">
 | 
			
		||||
 | 
			
		||||
<table>
 | 
			
		||||
<tr><td>Send From Address</td><td><select name="addr_from_" disabled>
 | 
			
		||||
{% for a in addrs %}
 | 
			
		||||
<option{% if data.addr_from==a %} selected{% endif %} value="{{ a }}">{{ a }}</option>
 | 
			
		||||
{% endfor %}
 | 
			
		||||
<option{% if data.addr_from=="-1" %} selected{% endif %} value="-1">-- New Address --</option>
 | 
			
		||||
</select></td></tr>
 | 
			
		||||
 | 
			
		||||
<tr><td>Coin From</td><td>
 | 
			
		||||
<select name="coin_from_" disabled><option value="-1">-- Select Coin --</option>
 | 
			
		||||
{% for c in coins %}
 | 
			
		||||
<option{% if data.coin_from==c[0] %} selected{% endif %} value="{{ c[0] }}">{{ c[1] }}</option>
 | 
			
		||||
{% endfor %}
 | 
			
		||||
</select>
 | 
			
		||||
</td><td>Amount From</td><td><input type="text" name="amt_from" value="{{ data.amt_from }}" readonly></td><td>The amount you will send.</td></tr>
 | 
			
		||||
</td><td>Fee Rate From</td><td><input name="fee_rate_from" value="{{ data.from_fee_override }}" readonly></td><td>Fee Rate Source</td><td>{{ data.from_fee_src }}</td></tr>
 | 
			
		||||
</td><td>Fee From Confirm Target</td><td><input type="number" name="fee_from_conf" min="1" max="32" value="{{ data.fee_from_conf }}" readonly></td></tr>
 | 
			
		||||
</td><td>Fee From Extra Fee</td><td>
 | 
			
		||||
<select name="fee_from_extra_" disabled>
 | 
			
		||||
<option value="0">None</option>
 | 
			
		||||
<option value="10"{% if data.fee_from_extra==10 %} selected{% endif %}>10%</option>
 | 
			
		||||
<option value="50"{% if data.fee_from_extra==50 %} selected{% endif %}>50%</option>
 | 
			
		||||
<option value="100"{% if data.fee_from_extra==100 %} selected{% endif %}>100%</option>
 | 
			
		||||
</select></td></tr>
 | 
			
		||||
 | 
			
		||||
<tr><td>Coin To</td><td>
 | 
			
		||||
<select name="coin_to_" disabled><option value="-1">-- Select Coin --</option>
 | 
			
		||||
{% for c in coins %}
 | 
			
		||||
<option{% if data.coin_to==c[0] %} selected{% endif %} value="{{ c[0] }}">{{ c[1] }}</option>
 | 
			
		||||
{% endfor %}
 | 
			
		||||
</select>
 | 
			
		||||
</td><td>Amount To</td><td><input type="text" name="amt_to" value="{{ data.amt_to }}" readonly></td><td>The amount you will receive.</td></tr>
 | 
			
		||||
</td><td>Fee Rate From</td><td><input name="fee_rate_to" value="{{ data.to_fee_override }}" readonly></td><td>Fee Rate Source</td><td>{{ data.to_fee_src }}</td></tr>
 | 
			
		||||
</td><td>Fee To Confirm Target</td><td><input type="number" name="fee_to_conf" min="1" max="32" value="{{ data.fee_to_conf }}" readonly></td></tr>
 | 
			
		||||
</td><td>Fee To Extra Fee</td><td>
 | 
			
		||||
<select name="fee_to_extra_" disabled>
 | 
			
		||||
<option value="0">None</option>
 | 
			
		||||
<option value="10"{% if data.fee_to_extra==10 %} selected{% endif %}>10%</option>
 | 
			
		||||
<option value="50"{% if data.fee_to_extra==50 %} selected{% endif %}>50%</option>
 | 
			
		||||
<option value="100"{% if data.fee_to_extra==100 %} selected{% endif %}>100%</option>
 | 
			
		||||
</select></td></tr>
 | 
			
		||||
 | 
			
		||||
<tr><td>Contract locked (hrs)</td><td><input type="number" name="lockhrs" min="1" max="64" value="{{ data.lockhrs }}" readonly></td>{% if data.swap_style != 'xmr' %}<td colspan=2>Participate txn will be locked for half the time.</td>{% endif %}</tr>
 | 
			
		||||
<tr><td>Auto Accept Bids</td><td colspan=3><input type="checkbox" name="autoaccept" value="aa" {% if data.autoaccept==true %} checked{% endif %} readonly></td></tr>
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
<input name="submit_offer" type="submit" value="Confirm Offer">
 | 
			
		||||
<input type="submit" value="Back">
 | 
			
		||||
<input type="hidden" name="formid" value="{{ form_id }}">
 | 
			
		||||
<input type="hidden" name="addr_from" value="{{ data.addr_from }}">
 | 
			
		||||
<input type="hidden" name="coin_from" value="{{ data.coin_from }}">
 | 
			
		||||
<input type="hidden" name="fee_from_extra" value="{{ data.fee_from_extra }}">
 | 
			
		||||
<input type="hidden" name="coin_to" value="{{ data.coin_to }}">
 | 
			
		||||
<input type="hidden" name="fee_to_extra" value="{{ data.fee_to_extra }}">
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
<p><a href="/">home</a></p>
 | 
			
		||||
</body></html>
 | 
			
		||||
@ -10,32 +10,48 @@
 | 
			
		||||
<table>
 | 
			
		||||
<tr><td>Send From Address</td><td><select name="addr_from">
 | 
			
		||||
{% for a in addrs %}
 | 
			
		||||
<option value="{{ a }}">{{ a }}</option>
 | 
			
		||||
<option{% if data.addr_from==a %} selected{% endif %} value="{{ a }}">{{ a }}</option>
 | 
			
		||||
{% endfor %}
 | 
			
		||||
<option value="-1">-- New Address --</option>
 | 
			
		||||
<option{% if data.addr_from=="-1" %} selected{% endif %} value="-1">-- New Address --</option>
 | 
			
		||||
</select></td></tr>
 | 
			
		||||
 | 
			
		||||
<tr><td>Coin From</td><td>
 | 
			
		||||
<select name="coin_from"><option value="-1">-- Select Coin --</option>
 | 
			
		||||
{% for c in coins %}
 | 
			
		||||
<option value="{{ c[0] }}">{{ c[1] }}</option>
 | 
			
		||||
<option{% if data.coin_from==c[0] %} selected{% endif %} value="{{ c[0] }}">{{ c[1] }}</option>
 | 
			
		||||
{% endfor %}
 | 
			
		||||
</select>
 | 
			
		||||
</td><td>Amount From</td><td><input type="text" name="amt_from"></td></tr>
 | 
			
		||||
</td><td>Amount From</td><td><input type="text" name="amt_from" value="{{ data.amt_from }}"></td><td>The amount you will send.</td></tr>
 | 
			
		||||
</td><td>Fee From Confirm Target</td><td><input type="number" name="fee_from_conf" min="1" max="32" value="{{ data.fee_from_conf }}"></td></tr>
 | 
			
		||||
</td><td>Fee From Extra Fee</td><td>
 | 
			
		||||
<select name="fee_from_extra">
 | 
			
		||||
<option value="0">None</option>
 | 
			
		||||
<option value="10"{% if data.fee_from_extra==10 %} selected{% endif %}>10%</option>
 | 
			
		||||
<option value="50"{% if data.fee_from_extra==50 %} selected{% endif %}>50%</option>
 | 
			
		||||
<option value="100"{% if data.fee_from_extra==100 %} selected{% endif %}>100%</option>
 | 
			
		||||
</select></td></tr>
 | 
			
		||||
 | 
			
		||||
<tr><td>Coin To</td><td>
 | 
			
		||||
<select name="coin_to"><option value="-1">-- Select Coin --</option>
 | 
			
		||||
{% for c in coins %}
 | 
			
		||||
<option value="{{ c[0] }}">{{ c[1] }}</option>
 | 
			
		||||
<option{% if data.coin_to==c[0] %} selected{% endif %}  value="{{ c[0] }}">{{ c[1] }}</option>
 | 
			
		||||
{% endfor %}
 | 
			
		||||
</select>
 | 
			
		||||
</td><td>Amount To</td><td><input type="text" name="amt_to"></td></tr>
 | 
			
		||||
</td><td>Amount To</td><td><input type="text" name="amt_to" value="{{ data.amt_to }}"></td><td>The amount you will receive.</td></tr>
 | 
			
		||||
</td><td>Fee To Confirm Target</td><td><input type="number" name="fee_to_conf" min="1" max="32" value="{{ data.fee_to_conf }}"></td></tr>
 | 
			
		||||
</td><td>Fee To Extra Fee</td><td>
 | 
			
		||||
<select name="fee_to_extra">
 | 
			
		||||
<option value="0">None</option>
 | 
			
		||||
<option value="10"{% if data.fee_to_extra==10 %} selected{% endif %}>10%</option>
 | 
			
		||||
<option value="50"{% if data.fee_to_extra==50 %} selected{% endif %}>50%</option>
 | 
			
		||||
<option value="100"{% if data.fee_to_extra==100 %} selected{% endif %}>100%</option>
 | 
			
		||||
</select></td></tr>
 | 
			
		||||
 | 
			
		||||
<tr><td>Contract locked (hrs)</td><td><input type="number" name="lockhrs" min="1" max="64" value="32"></td><td colspan=2>Participate txn will be locked for half the time.</td></tr>
 | 
			
		||||
<tr><td>Auto Accept Bids</td><td colspan=3><input type="checkbox" name="autoaccept" value="aa" checked></td></tr>
 | 
			
		||||
<tr><td>Contract locked (hrs)</td><td><input type="number" name="lockhrs" min="1" max="64" value="{{ data.lockhrs }}"></td><td colspan=2>Participate txn will be locked for half the time.</td></tr>
 | 
			
		||||
<tr><td>Auto Accept Bids</td><td colspan=3><input type="checkbox" name="autoaccept" value="aa" {% if data.autoaccept==true %} checked{% endif %}></td></tr>
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
<input type="submit" value="Submit">
 | 
			
		||||
<input name="check_offer" type="submit" value="Submit">
 | 
			
		||||
<input type="hidden" name="formid" value="{{ form_id }}">
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -142,6 +142,7 @@ def describeBid(swap_client, bid, xmr_swap, offer, xmr_offer, bid_events, edit_b
 | 
			
		||||
        'participate_tx': getTxIdHex(bid, TxTypes.PTX, ' ' + ticker_to),
 | 
			
		||||
        'participate_conf': 'None' if (not bid.participate_tx or not bid.participate_tx.conf) else bid.participate_tx.conf,
 | 
			
		||||
        'show_txns': show_txns,
 | 
			
		||||
        'can_abandon': True if bid.state not in (BidStates.BID_ABANDONED, BidStates.SWAP_COMPLETED) else False,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if edit_bid:
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,27 @@
 | 
			
		||||
 | 
			
		||||
## Update basicswap version
 | 
			
		||||
 | 
			
		||||
If installed through pip:
 | 
			
		||||
### Docker
 | 
			
		||||
 | 
			
		||||
Update only the code:
 | 
			
		||||
 | 
			
		||||
    basicswap]$ git pull
 | 
			
		||||
    $ cd docker
 | 
			
		||||
    $ docker-compose build
 | 
			
		||||
    $ export COINDATA_PATH=[PATH_TO]
 | 
			
		||||
    $ docker-compose up
 | 
			
		||||
 | 
			
		||||
If the dependencies and db format have changed the container must be built with `--no-cache` and the db file moved to a backup.
 | 
			
		||||
 | 
			
		||||
    basicswap]$ git pull
 | 
			
		||||
    $ cd docker
 | 
			
		||||
    $ docker-compose build --no-cache
 | 
			
		||||
    $ export COINDATA_PATH=[PATH_TO]
 | 
			
		||||
    $ mv --backup=numbered $COINDATA_PATH/db.sqlite $COINDATA_PATH/db_bkp.sqlite
 | 
			
		||||
    $ docker-compose up
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### If installed through pip:
 | 
			
		||||
 | 
			
		||||
    cd basicswap
 | 
			
		||||
    git pull
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user