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