ui: Add rate lookup helper when creating offers.
This commit is contained in:
		
							parent
							
								
									54ad0e496c
								
							
						
					
					
						commit
						8a9f4f9e38
					
				@ -14,6 +14,7 @@ import base64
 | 
				
			|||||||
import random
 | 
					import random
 | 
				
			||||||
import shutil
 | 
					import shutil
 | 
				
			||||||
import struct
 | 
					import struct
 | 
				
			||||||
 | 
					import urllib.request
 | 
				
			||||||
import hashlib
 | 
					import hashlib
 | 
				
			||||||
import secrets
 | 
					import secrets
 | 
				
			||||||
import datetime as dt
 | 
					import datetime as dt
 | 
				
			||||||
@ -1036,6 +1037,9 @@ class BasicSwap(BaseApp):
 | 
				
			|||||||
            msg_buf.amount_negotiable = extra_options.get('amount_negotiable', False)
 | 
					            msg_buf.amount_negotiable = extra_options.get('amount_negotiable', False)
 | 
				
			||||||
            msg_buf.rate_negotiable = extra_options.get('rate_negotiable', False)
 | 
					            msg_buf.rate_negotiable = extra_options.get('rate_negotiable', False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if msg_buf.amount_negotiable or msg_buf.rate_negotiable:
 | 
				
			||||||
 | 
					                ensure(auto_accept_bids is False, 'Auto-accept unavailable when amount or rate are variable')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if 'from_fee_override' in extra_options:
 | 
					            if 'from_fee_override' in extra_options:
 | 
				
			||||||
                msg_buf.fee_rate_from = make_int(extra_options['from_fee_override'], self.ci(coin_from).exp())
 | 
					                msg_buf.fee_rate_from = make_int(extra_options['from_fee_override'], self.ci(coin_from).exp())
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
@ -5519,3 +5523,26 @@ class BasicSwap(BaseApp):
 | 
				
			|||||||
        if not self._network:
 | 
					        if not self._network:
 | 
				
			||||||
            return {'Error': 'Not Initialised'}
 | 
					            return {'Error': 'Not Initialised'}
 | 
				
			||||||
        return self._network.get_info()
 | 
					        return self._network.get_info()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def lookupRates(self, coin_from, coin_to):
 | 
				
			||||||
 | 
					        rv = {}
 | 
				
			||||||
 | 
					        ci_from = self.ci(int(coin_from))
 | 
				
			||||||
 | 
					        ci_to = self.ci(int(coin_to))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        name_from = ci_from.coin_name().lower()
 | 
				
			||||||
 | 
					        name_to = ci_to.coin_name().lower()
 | 
				
			||||||
 | 
					        url = 'https://api.coingecko.com/api/v3/simple/price?ids={},{}&vs_currencies=usd'.format(name_from, name_to)
 | 
				
			||||||
 | 
					        headers = {'User-Agent': 'Mozilla/5.0'}
 | 
				
			||||||
 | 
					        req = urllib.request.Request(url, headers=headers)
 | 
				
			||||||
 | 
					        js = json.loads(urllib.request.urlopen(req).read())
 | 
				
			||||||
 | 
					        rate = float(js[name_from]['usd']) / float(js[name_to]['usd'])
 | 
				
			||||||
 | 
					        js['rate'] = ci_to.format_amount(rate, conv_int=True, r=1)
 | 
				
			||||||
 | 
					        rv['coingecko'] = js
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        url = 'https://api.bittrex.com/api/v1.1/public/getticker?market={}-{}'.format(ci_from.ticker(), ci_to.ticker())
 | 
				
			||||||
 | 
					        headers = {'User-Agent': 'Mozilla/5.0'}
 | 
				
			||||||
 | 
					        req = urllib.request.Request(url, headers=headers)
 | 
				
			||||||
 | 
					        js = json.loads(urllib.request.urlopen(req).read())
 | 
				
			||||||
 | 
					        rv['bittrex'] = js
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return rv
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,11 @@
 | 
				
			|||||||
# -*- coding: utf-8 -*-
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Copyright (c) 2019 tecnovert
 | 
					# Copyright (c) 2019-2021 tecnovert
 | 
				
			||||||
# Distributed under the MIT software license, see the accompanying
 | 
					# Distributed under the MIT software license, see the accompanying
 | 
				
			||||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
 | 
					# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import urllib.request
 | 
					 | 
				
			||||||
import json
 | 
					import json
 | 
				
			||||||
 | 
					import urllib.request
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Explorer():
 | 
					class Explorer():
 | 
				
			||||||
 | 
				
			|||||||
@ -42,6 +42,8 @@ from .js_server import (
 | 
				
			|||||||
    js_network,
 | 
					    js_network,
 | 
				
			||||||
    js_revokeoffer,
 | 
					    js_revokeoffer,
 | 
				
			||||||
    js_smsgaddresses,
 | 
					    js_smsgaddresses,
 | 
				
			||||||
 | 
					    js_rates,
 | 
				
			||||||
 | 
					    js_rate,
 | 
				
			||||||
    js_index,
 | 
					    js_index,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from .ui import (
 | 
					from .ui import (
 | 
				
			||||||
@ -507,6 +509,12 @@ class HttpHandler(BaseHTTPRequestHandler):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if 'amt_to' in parsed_data and 'amt_from' in parsed_data:
 | 
					        if 'amt_to' in parsed_data and 'amt_from' in parsed_data:
 | 
				
			||||||
            parsed_data['rate'] = ci_from.make_int(parsed_data['amt_to'] / parsed_data['amt_from'], r=1)
 | 
					            parsed_data['rate'] = ci_from.make_int(parsed_data['amt_to'] / parsed_data['amt_from'], r=1)
 | 
				
			||||||
 | 
					            page_data['rate'] = ci_to.format_amount(parsed_data['rate'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        page_data['amt_var'] = True if have_data_entry(form_data, 'amt_var') else False
 | 
				
			||||||
 | 
					        parsed_data['amt_var'] = page_data['amt_var']
 | 
				
			||||||
 | 
					        page_data['rate_var'] = True if have_data_entry(form_data, 'rate_var') else False
 | 
				
			||||||
 | 
					        parsed_data['rate_var'] = page_data['rate_var']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if b'step1' in form_data:
 | 
					        if b'step1' in form_data:
 | 
				
			||||||
            if len(errors) == 0 and b'continue' in form_data:
 | 
					            if len(errors) == 0 and b'continue' in form_data:
 | 
				
			||||||
@ -616,6 +624,11 @@ class HttpHandler(BaseHTTPRequestHandler):
 | 
				
			|||||||
        if 'addr_to' in parsed_data:
 | 
					        if 'addr_to' in parsed_data:
 | 
				
			||||||
            extra_options['addr_send_to'] = parsed_data['addr_to']
 | 
					            extra_options['addr_send_to'] = parsed_data['addr_to']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if parsed_data.get('amt_var', False):
 | 
				
			||||||
 | 
					            extra_options['amount_negotiable'] = parsed_data['amt_var']
 | 
				
			||||||
 | 
					        if parsed_data.get('rate_var', False):
 | 
				
			||||||
 | 
					            extra_options['rate_negotiable'] = parsed_data['rate_var']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        offer_id = swap_client.postOffer(
 | 
					        offer_id = swap_client.postOffer(
 | 
				
			||||||
            parsed_data['coin_from'],
 | 
					            parsed_data['coin_from'],
 | 
				
			||||||
            parsed_data['coin_to'],
 | 
					            parsed_data['coin_to'],
 | 
				
			||||||
@ -1129,6 +1142,8 @@ class HttpHandler(BaseHTTPRequestHandler):
 | 
				
			|||||||
                            'network': js_network,
 | 
					                            'network': js_network,
 | 
				
			||||||
                            'revokeoffer': js_revokeoffer,
 | 
					                            'revokeoffer': js_revokeoffer,
 | 
				
			||||||
                            'smsgaddresses': js_smsgaddresses,
 | 
					                            'smsgaddresses': js_smsgaddresses,
 | 
				
			||||||
 | 
					                            'rate': js_rate,
 | 
				
			||||||
 | 
					                            'rates': js_rates,
 | 
				
			||||||
                            }.get(url_split[2], js_index)
 | 
					                            }.get(url_split[2], js_index)
 | 
				
			||||||
                return func(self, url_split, post_string, is_json)
 | 
					                return func(self, url_split, post_string, is_json)
 | 
				
			||||||
            except Exception as ex:
 | 
					            except Exception as ex:
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,7 @@ from .chainparams import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
from .ui import (
 | 
					from .ui import (
 | 
				
			||||||
    PAGE_LIMIT,
 | 
					    PAGE_LIMIT,
 | 
				
			||||||
 | 
					    getCoinType,
 | 
				
			||||||
    inputAmount,
 | 
					    inputAmount,
 | 
				
			||||||
    describeBid,
 | 
					    describeBid,
 | 
				
			||||||
    setCoinFilter,
 | 
					    setCoinFilter,
 | 
				
			||||||
@ -245,10 +246,6 @@ def js_revokeoffer(self, url_split, post_string, is_json):
 | 
				
			|||||||
    return bytes(json.dumps({'revoked_offer': offer_id.hex()}), 'UTF-8')
 | 
					    return bytes(json.dumps({'revoked_offer': offer_id.hex()}), 'UTF-8')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def js_index(self, url_split, post_string, is_json):
 | 
					 | 
				
			||||||
    return bytes(json.dumps(self.server.swap_client.getSummary()), 'UTF-8')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def js_smsgaddresses(self, url_split, post_string, is_json):
 | 
					def js_smsgaddresses(self, url_split, post_string, is_json):
 | 
				
			||||||
    swap_client = self.server.swap_client
 | 
					    swap_client = self.server.swap_client
 | 
				
			||||||
    if len(url_split) > 3:
 | 
					    if len(url_split) > 3:
 | 
				
			||||||
@ -276,3 +273,61 @@ def js_smsgaddresses(self, url_split, post_string, is_json):
 | 
				
			|||||||
            return bytes(json.dumps({'edited_address': address}), 'UTF-8')
 | 
					            return bytes(json.dumps({'edited_address': address}), 'UTF-8')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return bytes(json.dumps(swap_client.listAllSMSGAddresses()), 'UTF-8')
 | 
					    return bytes(json.dumps(swap_client.listAllSMSGAddresses()), 'UTF-8')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def js_rates(self, url_split, post_string, is_json):
 | 
				
			||||||
 | 
					    if post_string == '':
 | 
				
			||||||
 | 
					        raise ValueError('No post data')
 | 
				
			||||||
 | 
					    if is_json:
 | 
				
			||||||
 | 
					        post_data = json.loads(post_string)
 | 
				
			||||||
 | 
					        post_data['is_json'] = True
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        post_data = urllib.parse.parse_qs(post_string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sc = self.server.swap_client
 | 
				
			||||||
 | 
					    coin_from = get_data_entry(post_data, 'coin_from')
 | 
				
			||||||
 | 
					    coin_to = get_data_entry(post_data, 'coin_to')
 | 
				
			||||||
 | 
					    return bytes(json.dumps(sc.lookupRates(coin_from, coin_to)), 'UTF-8')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def js_rate(self, url_split, post_string, is_json):
 | 
				
			||||||
 | 
					    if post_string == '':
 | 
				
			||||||
 | 
					        raise ValueError('No post data')
 | 
				
			||||||
 | 
					    if is_json:
 | 
				
			||||||
 | 
					        post_data = json.loads(post_string)
 | 
				
			||||||
 | 
					        post_data['is_json'] = True
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        post_data = urllib.parse.parse_qs(post_string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sc = self.server.swap_client
 | 
				
			||||||
 | 
					    coin_from = getCoinType(get_data_entry(post_data, 'coin_from'))
 | 
				
			||||||
 | 
					    ci_from = sc.ci(coin_from)
 | 
				
			||||||
 | 
					    coin_to = getCoinType(get_data_entry(post_data, 'coin_to'))
 | 
				
			||||||
 | 
					    ci_to = sc.ci(coin_to)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Set amount to if rate is provided
 | 
				
			||||||
 | 
					    rate = get_data_entry_or(post_data, 'rate', None)
 | 
				
			||||||
 | 
					    if rate is not None:
 | 
				
			||||||
 | 
					        amt_from_str = get_data_entry_or(post_data, 'amt_from', None)
 | 
				
			||||||
 | 
					        amt_to_str = get_data_entry_or(post_data, 'amt_to', None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if amt_from_str is not None:
 | 
				
			||||||
 | 
					            rate = ci_to.make_int(rate, r=1)
 | 
				
			||||||
 | 
					            amt_from = inputAmount(amt_from_str, ci_from)
 | 
				
			||||||
 | 
					            amount_to = ci_to.format_amount(int((amt_from * rate) // ci_from.COIN()), r=1)
 | 
				
			||||||
 | 
					            return bytes(json.dumps({'amount_to': amount_to}), 'UTF-8')
 | 
				
			||||||
 | 
					        if amt_to_str is not None:
 | 
				
			||||||
 | 
					            rate = ci_from.make_int(1.0 / float(rate), r=1)
 | 
				
			||||||
 | 
					            amt_to = inputAmount(amt_to_str, ci_to)
 | 
				
			||||||
 | 
					            amount_from = ci_from.format_amount(int((amt_to * rate) // ci_to.COIN()), r=1)
 | 
				
			||||||
 | 
					            return bytes(json.dumps({'amount_from': amount_from}), 'UTF-8')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    amt_from = inputAmount(get_data_entry(post_data, 'amt_from'), ci_from)
 | 
				
			||||||
 | 
					    amt_to = inputAmount(get_data_entry(post_data, 'amt_to'), ci_to)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rate = ci_to.format_amount(ci_from.make_int(amt_to / amt_from, r=1))
 | 
				
			||||||
 | 
					    return bytes(json.dumps({'rate': rate}), 'UTF-8')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def js_index(self, url_split, post_string, is_json):
 | 
				
			||||||
 | 
					    return bytes(json.dumps(self.server.swap_client.getSummary()), 'UTF-8')
 | 
				
			||||||
 | 
				
			|||||||
@ -60,8 +60,15 @@
 | 
				
			|||||||
<option value="-1" {% if data.nb_addr_from=="-1" %} selected{% endif %}>-- New Address --</option>
 | 
					<option value="-1" {% if data.nb_addr_from=="-1" %} selected{% endif %}>-- New Address --</option>
 | 
				
			||||||
</select>
 | 
					</select>
 | 
				
			||||||
</td></tr>
 | 
					</td></tr>
 | 
				
			||||||
<tr><td>Minutes valid</td><td><input type="number" name="validmins" min="10" max="1440" value="{{ data.nb_validmins }}"></td></tr>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% if data.amount_negotiable == true %}
 | 
				
			||||||
 | 
					<tr><td>Amount</td><td><input type="text" name="bid_amount" value="{{ data.amt_from }}"></td></tr>
 | 
				
			||||||
 | 
					{% endif %}
 | 
				
			||||||
 | 
					{% if data.rate_negotiable == true %}
 | 
				
			||||||
 | 
					<tr><td>Rate</td><td><input type="text" name="bid_rate" value="{{ data.rate }}"></td></tr>
 | 
				
			||||||
 | 
					{% endif %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<tr><td>Minutes valid</td><td><input type="number" name="validmins" min="10" max="1440" value="{{ data.nb_validmins }}"></td></tr>
 | 
				
			||||||
<tr><td><input type="submit" name="sendbid" value="Send Bid"><input type="submit" name="cancel" value="Cancel"></td></tr>
 | 
					<tr><td><input type="submit" name="sendbid" value="Send Bid"><input type="submit" name="cancel" value="Cancel"></td></tr>
 | 
				
			||||||
</table>
 | 
					</table>
 | 
				
			||||||
{% else %}
 | 
					{% else %}
 | 
				
			||||||
 | 
				
			|||||||
@ -59,10 +59,13 @@
 | 
				
			|||||||
<option value="100"{% if data.fee_to_extra==100 %} selected{% endif %}>100%</option>
 | 
					<option value="100"{% if data.fee_to_extra==100 %} selected{% endif %}>100%</option>
 | 
				
			||||||
</select></td></tr>
 | 
					</select></td></tr>
 | 
				
			||||||
{% endif %}
 | 
					{% endif %}
 | 
				
			||||||
 | 
					</td><td>Rate</td><td><input type="text" id="rate" name="rate" value="{{ data.rate }}" readonly></td></tr>
 | 
				
			||||||
 | 
					<tr><td>Amount Variable</td><td colspan=3><input type="checkbox" id="amt_var" name="amt_var_" value="av" {% if data.amt_var==true %} checked="true"{% endif %} disabled></td></tr>
 | 
				
			||||||
 | 
					<tr><td>Rate Variable</td><td colspan=3><input type="checkbox" id="rate_var" name="rate_var_" value="rv" {% if data.rate_var==true %} checked="true"{% endif %} disabled></td></tr>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<tr class="padded_row"><td>Offer valid (hrs)</td><td><input type="number" name="validhrs" min="1" max="48" value="{{ data.validhrs }}" readonly></td></tr>
 | 
					<tr class="padded_row"><td>Offer valid (hrs)</td><td><input type="number" name="validhrs" min="1" max="48" value="{{ data.validhrs }}" readonly></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>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="true"{% endif %} disabled></td></tr>
 | 
					<tr><td>Auto Accept Bids</td><td colspan=3><input type="checkbox" id="autoaccept" name="autoaccept_" value="aa" {% if data.autoaccept==true %} checked="true"{% endif %} disabled></td></tr>
 | 
				
			||||||
</table>
 | 
					</table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<input name="submit_offer" type="submit" value="Confirm Offer">
 | 
					<input name="submit_offer" type="submit" value="Confirm Offer">
 | 
				
			||||||
@ -77,6 +80,12 @@
 | 
				
			|||||||
{% if data.autoaccept==true %}
 | 
					{% if data.autoaccept==true %}
 | 
				
			||||||
<input type="hidden" name="autoaccept" value="aa">
 | 
					<input type="hidden" name="autoaccept" value="aa">
 | 
				
			||||||
{% endif %}
 | 
					{% endif %}
 | 
				
			||||||
 | 
					{% if data.amt_var==true %}
 | 
				
			||||||
 | 
					<input type="hidden" name="amt_var" value="av">
 | 
				
			||||||
 | 
					{% endif %}
 | 
				
			||||||
 | 
					{% if data.rate_var==true %}
 | 
				
			||||||
 | 
					<input type="hidden" name="rate_var" value="rv">
 | 
				
			||||||
 | 
					{% endif %}
 | 
				
			||||||
</form>
 | 
					</form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</body></html>
 | 
					</body></html>
 | 
				
			||||||
 | 
				
			|||||||
@ -22,26 +22,112 @@
 | 
				
			|||||||
</select></td></tr>
 | 
					</select></td></tr>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<tr><td>Coin From</td><td>
 | 
					<tr><td>Coin From</td><td>
 | 
				
			||||||
<select name="coin_from"><option value="-1">-- Select Coin --</option>
 | 
					<select id="coin_from" name="coin_from" onchange="set_rate('coin_from');"><option value="-1">-- Select Coin --</option>
 | 
				
			||||||
{% for c in coins %}
 | 
					{% for c in coins %}
 | 
				
			||||||
<option{% if data.coin_from==c[0] %} selected{% endif %} value="{{ c[0] }}">{{ c[1] }}</option>
 | 
					<option{% if data.coin_from==c[0] %} selected{% endif %} value="{{ c[0] }}">{{ c[1] }}</option>
 | 
				
			||||||
{% endfor %}
 | 
					{% endfor %}
 | 
				
			||||||
</select>
 | 
					</select>
 | 
				
			||||||
</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>Amount From</td><td><input type="text" id="amt_from" name="amt_from" value="{{ data.amt_from }}" onchange="set_rate('amt_from');"></td><td>The amount you will send.</td></tr>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<tr><td>Coin To</td><td>
 | 
					<tr><td>Coin To</td><td>
 | 
				
			||||||
<select name="coin_to"><option value="-1">-- Select Coin --</option>
 | 
					<select id="coin_to" name="coin_to" onchange="set_rate('coin_to');"><option value="-1">-- Select Coin --</option>
 | 
				
			||||||
{% for c in coins %}
 | 
					{% for c in coins %}
 | 
				
			||||||
<option{% if data.coin_to==c[0] %} selected{% endif %}  value="{{ c[0] }}">{{ c[1] }}</option>
 | 
					<option{% if data.coin_to==c[0] %} selected{% endif %}  value="{{ c[0] }}">{{ c[1] }}</option>
 | 
				
			||||||
{% endfor %}
 | 
					{% endfor %}
 | 
				
			||||||
</select>
 | 
					</select>
 | 
				
			||||||
</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>Amount To</td><td><input type="text" id="amt_to" name="amt_to" value="{{ data.amt_to }}" onchange="set_rate('amt_to');"></td><td>The amount you will receive.</td></tr>
 | 
				
			||||||
 | 
					</td><td>Rate</td><td><input type="text" id="rate" name="rate" value="{{ data.rate }}" onchange="set_rate('rate');"></td><td>Lock Rate: <input type="checkbox" id="rate_lock" name="rate_lock" value="rl"></td></tr>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<tr><td>Amount Variable</td><td><input type="checkbox" id="amt_var" name="amt_var" value="av" {% if data.amt_var==true %} checked="true"{% endif %}></td></tr>
 | 
				
			||||||
 | 
					<tr><td>Rate Variable</td><td><input type="checkbox" id="rate_var" name="rate_var" value="rv" {% if data.rate_var==true %} checked="true"{% endif %}></td></tr>
 | 
				
			||||||
</table>
 | 
					</table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<input name="continue" type="submit" value="Continue">
 | 
					<input name="continue" type="submit" value="Continue">
 | 
				
			||||||
 | 
					<input name="check_rates" type="button" value="Lookup Rates" onclick='lookup_rates();'>
 | 
				
			||||||
<input type="hidden" name="formid" value="{{ form_id }}">
 | 
					<input type="hidden" name="formid" value="{{ form_id }}">
 | 
				
			||||||
<input type="hidden" name="step1" value="a">
 | 
					<input type="hidden" name="step1" value="a">
 | 
				
			||||||
</form>
 | 
					</form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p id="rates_display"></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<p><a href="/">home</a></p>
 | 
					<p><a href="/">home</a></p>
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					const xhr_rates = new XMLHttpRequest();
 | 
				
			||||||
 | 
					xhr_rates.onload = () => {
 | 
				
			||||||
 | 
					    if (xhr_rates.status == 200) {
 | 
				
			||||||
 | 
					        const obj = JSON.parse(xhr_rates.response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        inner_html = '<pre><code>' + JSON.stringify(obj, null, '  ') + '</code></pre>';
 | 
				
			||||||
 | 
					        document.getElementById('rates_display').innerHTML = inner_html;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const xhr_rate = new XMLHttpRequest();
 | 
				
			||||||
 | 
					xhr_rate.onload = () => {
 | 
				
			||||||
 | 
					    if (xhr_rate.status == 200) {
 | 
				
			||||||
 | 
					        const obj = JSON.parse(xhr_rate.response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (obj.hasOwnProperty('rate')) {
 | 
				
			||||||
 | 
					            document.getElementById('rate').value = obj['rate'];
 | 
				
			||||||
 | 
					        } else
 | 
				
			||||||
 | 
					        if (obj.hasOwnProperty('amount_to')) {
 | 
				
			||||||
 | 
					            document.getElementById('amt_to').value = obj['amount_to'];
 | 
				
			||||||
 | 
					        } else
 | 
				
			||||||
 | 
					        if (obj.hasOwnProperty('amount_from')) {
 | 
				
			||||||
 | 
					            document.getElementById('amt_from').value = obj['amount_from'];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function lookup_rates() {
 | 
				
			||||||
 | 
					    const coin_from = document.getElementById('coin_from').value;
 | 
				
			||||||
 | 
					    const coin_to = document.getElementById('coin_to').value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (coin_from == '-1' || coin_to == '-1') {
 | 
				
			||||||
 | 
					        alert('Coins from and to must be set first.');
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xhr_rates.open('POST', '/json/rates');
 | 
				
			||||||
 | 
					    xhr_rates.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
 | 
				
			||||||
 | 
					    xhr_rates.send('coin_from='+coin_from+'&coin_to='+coin_to);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function set_rate(value_changed) {
 | 
				
			||||||
 | 
					    const coin_from = document.getElementById('coin_from').value;
 | 
				
			||||||
 | 
					    const coin_to = document.getElementById('coin_to').value;
 | 
				
			||||||
 | 
					    const amt_from = document.getElementById('amt_from').value;
 | 
				
			||||||
 | 
					    const amt_to = document.getElementById('amt_to').value;
 | 
				
			||||||
 | 
					    const rate = document.getElementById('rate').value;
 | 
				
			||||||
 | 
					    const lock_rate = document.getElementById('rate_lock').checked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (coin_from == '-1' || coin_to == '-1') {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    params = 'coin_from='+coin_from+'&coin_to='+coin_to;
 | 
				
			||||||
 | 
					    if (value_changed == 'rate' || (lock_rate && value_changed == 'amt_from')) {
 | 
				
			||||||
 | 
					        if (amt_from == '' || rate == '') {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        params += '&rate='+rate+'&amt_from='+amt_from;
 | 
				
			||||||
 | 
					    } else
 | 
				
			||||||
 | 
					    if (lock_rate && value_changed == 'amt_to') {
 | 
				
			||||||
 | 
					        if (amt_to == '' || rate == '') {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        params += '&amt_to='+amt_to+'&rate='+rate;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        if (amt_from == '' || amt_to == '') {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        params += '&amt_from='+amt_from+'&amt_to='+amt_to;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xhr_rate.open('POST', '/json/rate');
 | 
				
			||||||
 | 
					    xhr_rate.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
 | 
				
			||||||
 | 
					    xhr_rate.send(params);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
</body></html>
 | 
					</body></html>
 | 
				
			||||||
 | 
				
			|||||||
@ -56,10 +56,15 @@
 | 
				
			|||||||
<option value="100"{% if data.fee_to_extra==100 %} selected{% endif %}>100%</option>
 | 
					<option value="100"{% if data.fee_to_extra==100 %} selected{% endif %}>100%</option>
 | 
				
			||||||
</select></td></tr>
 | 
					</select></td></tr>
 | 
				
			||||||
{% endif %}
 | 
					{% endif %}
 | 
				
			||||||
 | 
					</td><td>Rate</td><td><input type="text" id="rate" name="rate" value="{{ data.rate }}" readonly></td></tr>
 | 
				
			||||||
 | 
					<tr><td>Amount Variable</td><td colspan=3><input type="checkbox" id="amt_var" name="amt_var_" value="av" {% if data.amt_var==true %} checked="true"{% endif %} disabled></td></tr>
 | 
				
			||||||
 | 
					<tr><td>Rate Variable</td><td colspan=3><input type="checkbox" id="rate_var" name="rate_var_" value="rv" {% if data.rate_var==true %} checked="true"{% endif %} disabled></td></tr>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<tr class="padded_row"><td>Offer valid (hrs)</td><td><input type="number" name="validhrs" min="1" max="48" value="{{ data.validhrs }}"></td></tr>
 | 
					<tr class="padded_row"><td>Offer valid (hrs)</td><td><input type="number" name="validhrs" min="1" max="48" value="{{ data.validhrs }}"></td></tr>
 | 
				
			||||||
<tr><td>Contract locked (hrs)</td><td><input type="number" name="lockhrs" min="1" max="96" value="{{ data.lockhrs }}"></td>{% if data.swap_style != 'xmr' %}<td colspan=2>Participate txn will be locked for half the time.</td>{% endif %}</tr>
 | 
					<tr><td>Contract locked (hrs)</td><td><input type="number" name="lockhrs" min="1" max="96" value="{{ data.lockhrs }}"></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="true"{% endif %}></td></tr>
 | 
					<tr><td>Auto Accept Bids</td><td colspan=3><input type="checkbox" id="autoaccept" name="autoaccept" value="aa" {% if data.autoaccept==true %} checked="true"{% endif %}></td></tr>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</table>
 | 
					</table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<input name="check_offer" type="submit" value="Continue">
 | 
					<input name="check_offer" type="submit" value="Continue">
 | 
				
			||||||
@ -69,6 +74,12 @@
 | 
				
			|||||||
<input type="hidden" name="addr_from" value="{{ data.addr_from }}">
 | 
					<input type="hidden" name="addr_from" value="{{ data.addr_from }}">
 | 
				
			||||||
<input type="hidden" name="coin_from" value="{{ data.coin_from }}">
 | 
					<input type="hidden" name="coin_from" value="{{ data.coin_from }}">
 | 
				
			||||||
<input type="hidden" name="coin_to" value="{{ data.coin_to }}">
 | 
					<input type="hidden" name="coin_to" value="{{ data.coin_to }}">
 | 
				
			||||||
 | 
					{% if data.amt_var==true %}
 | 
				
			||||||
 | 
					<input type="hidden" name="amt_var" value="true">
 | 
				
			||||||
 | 
					{% endif %}
 | 
				
			||||||
 | 
					{% if data.rate_var==true %}
 | 
				
			||||||
 | 
					<input type="hidden" name="rate_var" value="true">
 | 
				
			||||||
 | 
					{% endif %}
 | 
				
			||||||
</form>
 | 
					</form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</body></html>
 | 
					</body></html>
 | 
				
			||||||
 | 
				
			|||||||
@ -313,7 +313,7 @@ def prepareCore(coin, version_pair, settings, data_dir):
 | 
				
			|||||||
    extractCore(coin, version_pair, settings, bin_dir, release_path)
 | 
					    extractCore(coin, version_pair, settings, bin_dir, release_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def prepareDataDir(coin, settings, chain, particl_mnemonic, use_containers=False)):
 | 
					def prepareDataDir(coin, settings, chain, particl_mnemonic, use_containers=False):
 | 
				
			||||||
    core_settings = settings['chainclients'][coin]
 | 
					    core_settings = settings['chainclients'][coin]
 | 
				
			||||||
    bin_dir = core_settings['bindir']
 | 
					    bin_dir = core_settings['bindir']
 | 
				
			||||||
    data_dir = core_settings['datadir']
 | 
					    data_dir = core_settings['datadir']
 | 
				
			||||||
 | 
				
			|||||||
@ -2,21 +2,22 @@
 | 
				
			|||||||
0.0.27
 | 
					0.0.27
 | 
				
			||||||
==============
 | 
					==============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Track failed and successful swaps by address
 | 
					- Track failed and successful swaps by address.
 | 
				
			||||||
 | 
					- Added rate lookup helper when creating offer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
0.0.26
 | 
					0.0.26
 | 
				
			||||||
==============
 | 
					==============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Added protocol version to order and bid messages
 | 
					- Added protocol version to order and bid messages.
 | 
				
			||||||
- Moved chain start heights to bid.
 | 
					- Moved chain start heights to bid.
 | 
				
			||||||
- Avoid scantxoutset for decred style swaps
 | 
					- Avoid scantxoutset for decred style swaps.
 | 
				
			||||||
- xmr: spend chain B lock tx will look for existing spends
 | 
					- xmr: spend chain B lock tx will look for existing spends.
 | 
				
			||||||
- xmrswaps:
 | 
					- xmrswaps:
 | 
				
			||||||
  - Setting state to 'Script tx redeemed' will trigger an attempt to redeem the scriptless lock tx.
 | 
					  - Setting state to 'Script tx redeemed' will trigger an attempt to redeem the scriptless lock tx.
 | 
				
			||||||
  - Node will wait for the chain B lock tx to reach a spendable depth before attempting to spend.
 | 
					  - Node will wait for the chain B lock tx to reach a spendable depth before attempting to spend.
 | 
				
			||||||
- ui: Sort settings page by coin name.
 | 
					- ui: Sort settings page by coin name.
 | 
				
			||||||
- ui, xmr: List of candidate remote XMR daemon urls can be set through the http ui
 | 
					- ui, xmr: List of candidate remote XMR daemon urls can be set through the http ui.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
0.0.25
 | 
					0.0.25
 | 
				
			||||||
@ -24,8 +25,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
- Fix extra 33 bytes in lock spend fee calculation.
 | 
					- Fix extra 33 bytes in lock spend fee calculation.
 | 
				
			||||||
- XMR swaps use watchonly addresses to save the lock tx to the wallet
 | 
					- XMR swaps use watchonly addresses to save the lock tx to the wallet
 | 
				
			||||||
  - Instead of scantxoutset
 | 
					  - Instead of scantxoutset.
 | 
				
			||||||
- Add missing check of leader's lock refund tx signature result
 | 
					- Add missing check of leader's lock refund tx signature result.
 | 
				
			||||||
- Blind part -> XMR swaps are possible:
 | 
					- Blind part -> XMR swaps are possible:
 | 
				
			||||||
  - The sha256 hash of the chain b view private key is used as the nonce for transactions requiring cooperation to sign.
 | 
					  - The sha256 hash of the chain b view private key is used as the nonce for transactions requiring cooperation to sign.
 | 
				
			||||||
  - Follower sends a public key in xmr_swap.dest_af.
 | 
					  - Follower sends a public key in xmr_swap.dest_af.
 | 
				
			||||||
@ -45,14 +46,14 @@
 | 
				
			|||||||
0.0.23
 | 
					0.0.23
 | 
				
			||||||
==============
 | 
					==============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Enables private offers
 | 
					- Enables private offers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
0.0.22
 | 
					0.0.22
 | 
				
			||||||
==============
 | 
					==============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Improved wallets page
 | 
					- Improved wallets page
 | 
				
			||||||
  - Consistent wallet order
 | 
					  - Consistent wallet order.
 | 
				
			||||||
  - Separated RPC calls into threads.
 | 
					  - Separated RPC calls into threads.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -67,5 +68,5 @@
 | 
				
			|||||||
0.0.6
 | 
					0.0.6
 | 
				
			||||||
==============
 | 
					==============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Experimental support for XMR swaps.
 | 
					- Experimental support for XMR swaps
 | 
				
			||||||
  - Single direction only, scriptless -> XMR
 | 
					  - Single direction only, scriptless -> XMR.
 | 
				
			||||||
 | 
				
			|||||||
@ -29,10 +29,10 @@ from basicswap.basicswap_util import (
 | 
				
			|||||||
    SEQUENCE_LOCK_BLOCKS,
 | 
					    SEQUENCE_LOCK_BLOCKS,
 | 
				
			||||||
    SEQUENCE_LOCK_TIME)
 | 
					    SEQUENCE_LOCK_TIME)
 | 
				
			||||||
from basicswap.util import (
 | 
					from basicswap.util import (
 | 
				
			||||||
    SerialiseNum,
 | 
					 | 
				
			||||||
    DeserialiseNum,
 | 
					 | 
				
			||||||
    make_int,
 | 
					    make_int,
 | 
				
			||||||
 | 
					    SerialiseNum,
 | 
				
			||||||
    format_amount,
 | 
					    format_amount,
 | 
				
			||||||
 | 
					    DeserialiseNum,
 | 
				
			||||||
    validate_amount)
 | 
					    validate_amount)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user