From 20c59663c17a58a92b1f0b699abaecccfd5d35f9 Mon Sep 17 00:00:00 2001 From: tecnovert Date: Mon, 15 Nov 2021 01:26:43 +0200 Subject: [PATCH] Count failed and successful bids by peer address. --- basicswap/__init__.py | 2 +- basicswap/basicswap.py | 103 ++++++++++++++++++- basicswap/basicswap_util.py | 3 + basicswap/db.py | 26 ++++- basicswap/http_server.py | 38 ++++++- basicswap/messages.proto | 28 ++++-- basicswap/messages_pb2.py | 159 ++++++++++++++++++++++-------- basicswap/templates/bid.html | 3 +- basicswap/templates/bid_xmr.html | 3 +- basicswap/templates/bids.html | 9 +- basicswap/templates/identity.html | 23 +++++ basicswap/templates/offer.html | 8 +- basicswap/ui.py | 1 + doc/release-notes.md | 6 ++ 14 files changed, 348 insertions(+), 64 deletions(-) create mode 100644 basicswap/templates/identity.html diff --git a/basicswap/__init__.py b/basicswap/__init__.py index 4fb23cb..d2adcf2 100644 --- a/basicswap/__init__.py +++ b/basicswap/__init__.py @@ -1,3 +1,3 @@ name = "basicswap" -__version__ = "0.0.26" +__version__ = "0.0.27" diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py index 543948f..4a09b4d 100644 --- a/basicswap/basicswap.py +++ b/basicswap/basicswap.py @@ -88,6 +88,7 @@ from .db import ( XmrSwap, XmrSplitData, Wallets, + KnownIdentity, ) from .base import BaseApp from .explorers import ( @@ -133,6 +134,12 @@ def validOfferStateToReceiveBid(offer_state): return False +def zeroIfNone(value): + if value is None: + return 0 + return value + + def threadPollChainState(swap_client, coin_type): while not swap_client.delay_event.is_set(): try: @@ -632,6 +639,28 @@ class BasicSwap(BaseApp): session.execute('ALTER TABLE offers ADD COLUMN protocol_version INTEGER') session.execute('ALTER TABLE transactions ADD COLUMN tx_data BLOB') db_version += 1 + elif current_version == 12: + session.execute(''' + CREATE TABLE knownidentities ( + record_id INTEGER NOT NULL, + address VARCHAR, + label VARCHAR, + publickey BLOB, + num_sent_bids_successful INTEGER, + num_recv_bids_successful INTEGER, + num_sent_bids_rejected INTEGER, + num_recv_bids_rejected INTEGER, + num_sent_bids_failed INTEGER, + num_recv_bids_failed INTEGER, + note VARCHAR, + updated_at BIGINT, + created_at BIGINT, + PRIMARY KEY (record_id))''') + session.execute('ALTER TABLE bids ADD COLUMN reject_code INTEGER') + session.execute('ALTER TABLE bids ADD COLUMN rate INTEGER') + session.execute('ALTER TABLE offers ADD COLUMN amount_negotiable INTEGER') + session.execute('ALTER TABLE offers ADD COLUMN rate_negotiable INTEGER') + db_version += 1 if current_version != db_version: self.db_version = db_version @@ -693,6 +722,25 @@ class BasicSwap(BaseApp): key_str = 'main_wallet_seedid_' + ci.coin_name().lower() self.setStringKV(key_str, root_hash.hex()) + def updateIdentityBidState(self, session, address, bid): + identity_stats = session.query(KnownIdentity).filter_by(address=address).first() + if not identity_stats: + identity_stats = KnownIdentity(address=address, created_at=int(time.time())) + + if bid.state == BidStates.SWAP_COMPLETED: + if bid.was_sent: + identity_stats.num_sent_bids_successful = zeroIfNone(identity_stats.num_sent_bids_successful) + 1 + else: + identity_stats.num_recv_bids_successful = zeroIfNone(identity_stats.num_recv_bids_successful) + 1 + elif bid.state in (BidStates.BID_ERROR, BidStates.XMR_SWAP_FAILED_REFUNDED, BidStates.XMR_SWAP_FAILED_SWIPED, BidStates.XMR_SWAP_FAILED): + if bid.was_sent: + identity_stats.num_sent_bids_failed = zeroIfNone(identity_stats.num_sent_bids_failed) + 1 + else: + identity_stats.num_recv_bids_failed = zeroIfNone(identity_stats.num_recv_bids_failed) + 1 + + identity_stats.updated_at = int(time.time()) + session.add(identity_stats) + def setIntKVInSession(self, str_key, int_val, session): kv = session.query(DBKVInt).filter_by(key=str_key).first() if not kv: @@ -828,6 +876,11 @@ class BasicSwap(BaseApp): elif SwapTypes.SELLER_FIRST: pass # No prevouts are locked + # Update identity stats + if bid.state in (BidStates.BID_ERROR, BidStates.XMR_SWAP_FAILED_REFUNDED, BidStates.XMR_SWAP_FAILED_SWIPED, BidStates.XMR_SWAP_FAILED, BidStates.SWAP_COMPLETED): + peer_address = offer.addr_from if bid.was_sent else bid.bid_addr + self.updateIdentityBidState(use_session, peer_address, bid) + finally: if session is None: use_session.commit() @@ -980,6 +1033,8 @@ class BasicSwap(BaseApp): msg_buf.lock_type = lock_type msg_buf.lock_value = lock_value msg_buf.swap_type = swap_type + msg_buf.amount_negotiable = extra_options.get('amount_negotiable', False) + msg_buf.rate_negotiable = extra_options.get('rate_negotiable', False) if 'from_fee_override' in extra_options: msg_buf.fee_rate_from = make_int(extra_options['from_fee_override'], self.ci(coin_from).exp()) @@ -1051,6 +1106,8 @@ class BasicSwap(BaseApp): lock_type=int(msg_buf.lock_type), lock_value=msg_buf.lock_value, swap_type=msg_buf.swap_type, + amount_negotiable=msg_buf.amount_negotiable, + rate_negotiable=msg_buf.rate_negotiable, addr_to=offer_addr_to, addr_from=offer_addr, @@ -1565,6 +1622,12 @@ class BasicSwap(BaseApp): valid_for_seconds = extra_options.get('valid_for_seconds', 60 * 10) self.validateBidValidTime(offer.swap_type, offer.coin_from, offer.coin_to, valid_for_seconds) + bid_rate = extra_options.get('bid_rate', offer.rate) + if not offer.amount_negotiable: + ensure(offer.amount_from == int(amount), 'Bid amount must match offer amount.') + if not offer.rate_negotiable: + ensure(offer.rate == bid_rate, 'Bid rate must match offer rate.') + self.mxDB.acquire() try: msg_buf = BidMessage() @@ -1572,6 +1635,7 @@ class BasicSwap(BaseApp): msg_buf.offer_msg_id = offer_id msg_buf.time_valid = valid_for_seconds msg_buf.amount = int(amount) # amount of coin_from + msg_buf.rate = bid_rate coin_from = Coins(offer.coin_from) coin_to = Coins(offer.coin_to) @@ -1614,6 +1678,7 @@ class BasicSwap(BaseApp): bid_id=bid_id, offer_id=offer_id, amount=msg_buf.amount, + rate=msg_buf.rate, pkhash_buyer=msg_buf.pkhash_buyer, proof_address=msg_buf.proof_address, @@ -1764,6 +1829,17 @@ class BasicSwap(BaseApp): session.remove() self.mxDB.release() + def getIdentity(self, address): + self.mxDB.acquire() + try: + session = scoped_session(self.session_factory) + identity = session.query(KnownIdentity).filter_by(address=address).first() + return identity + finally: + session.close() + session.remove() + self.mxDB.release() + def list_bid_events(self, bid_id, session): query_str = 'SELECT created_at, event_type, event_msg FROM eventlog ' + \ 'WHERE active_ind = 1 AND linked_type = {} AND linked_id = x\'{}\' '.format(TableTypes.BID, bid_id.hex()) @@ -1898,6 +1974,12 @@ class BasicSwap(BaseApp): ci_from = self.ci(coin_from) ci_to = self.ci(coin_to) + bid_rate = extra_options.get('bid_rate', offer.rate) + if not offer.amount_negotiable: + ensure(offer.amount_from == int(amount), 'Bid amount must match offer amount.') + if not offer.rate_negotiable: + ensure(offer.rate == bid_rate, 'Bid rate must match offer rate.') + self.checkSynced(coin_from, coin_to) msg_buf = XmrBidMessage() @@ -1905,6 +1987,7 @@ class BasicSwap(BaseApp): msg_buf.offer_msg_id = offer_id msg_buf.time_valid = valid_for_seconds msg_buf.amount = int(amount) # Amount of coin_from + msg_buf.rate = bid_rate address_out = self.getReceiveAddressFromPool(coin_from, offer_id, TxTypes.XMR_SWAP_A_LOCK) if coin_from == Coins.PART_BLIND: @@ -1990,6 +2073,7 @@ class BasicSwap(BaseApp): bid_id=xmr_swap.bid_id, offer_id=offer_id, amount=msg_buf.amount, + rate=msg_buf.rate, created_at=bid_created_at, contract_count=xmr_swap.contract_count, amount_to=(msg_buf.amount * offer.rate) // ci_from.COIN(), @@ -3594,6 +3678,8 @@ class BasicSwap(BaseApp): lock_type=int(offer_data.lock_type), lock_value=offer_data.lock_value, swap_type=offer_data.swap_type, + amount_negotiable=offer_data.amount_negotiable, + rate_negotiable=offer_data.rate_negotiable, addr_to=msg['to'], addr_from=msg['from'], @@ -3688,6 +3774,11 @@ class BasicSwap(BaseApp): self.validateBidValidTime(offer.swap_type, offer.coin_from, offer.coin_to, bid_data.time_valid) ensure(now <= msg['sent'] + bid_data.time_valid, 'Bid expired') + if not offer.amount_negotiable: + ensure(offer.amount_from == bid_data.amount, 'Bid amount must match offer amount.') + if not offer.rate_negotiable: + ensure(offer.rate == bid_data.rate, 'Bid rate must match offer rate.') + # TODO: Allow higher bids # assert(bid_data.rate != offer['data'].rate), 'Bid rate mismatch' @@ -3730,6 +3821,7 @@ class BasicSwap(BaseApp): offer_id=offer_id, protocol_version=bid_data.protocol_version, amount=bid_data.amount, + rate=bid_data.rate, pkhash_buyer=bid_data.pkhash_buyer, created_at=msg['sent'], @@ -3976,6 +4068,11 @@ class BasicSwap(BaseApp): self.validateBidValidTime(offer.swap_type, offer.coin_from, offer.coin_to, bid_data.time_valid) ensure(now <= msg['sent'] + bid_data.time_valid, 'Bid expired') + if not offer.amount_negotiable: + ensure(offer.amount_from == bid_data.amount, 'Bid amount must match offer amount.') + if not offer.rate_negotiable: + ensure(offer.rate == bid_data.rate, 'Bid rate must match offer rate.') + ensure(ci_to.verifyKey(bid_data.kbvf), 'Invalid chain B follower view key') ensure(ci_from.verifyPubkey(bid_data.pkaf), 'Invalid chain A follower public key') @@ -3989,6 +4086,7 @@ class BasicSwap(BaseApp): offer_id=offer_id, protocol_version=bid_data.protocol_version, amount=bid_data.amount, + rate=bid_data.rate, created_at=msg['sent'], amount_to=(bid_data.amount * offer.rate) // ci_from.COIN(), expire_at=msg['sent'] + bid_data.time_valid, @@ -5190,14 +5288,15 @@ class BasicSwap(BaseApp): session.remove() self.mxDB.release() - def listBids(self, sent=False, offer_id=None, for_html=False, filters={}): + def listBids(self, sent=False, offer_id=None, for_html=False, filters={}, with_identity_info=False): self.mxDB.acquire() try: rv = [] now = int(time.time()) session = scoped_session(self.session_factory) - query_str = 'SELECT bids.created_at, bids.expire_at, bids.bid_id, bids.offer_id, bids.amount, bids.state, bids.was_received, tx1.state, tx2.state, offers.coin_from FROM bids ' + \ + identity_fields = '' + query_str = 'SELECT bids.created_at, bids.expire_at, bids.bid_id, bids.offer_id, bids.amount, bids.state, bids.was_received, tx1.state, tx2.state, offers.coin_from, bids.rate, bids.bid_addr {} FROM bids '.format(identity_fields) + \ 'LEFT JOIN offers ON offers.offer_id = bids.offer_id ' + \ 'LEFT JOIN transactions AS tx1 ON tx1.bid_id = bids.bid_id AND tx1.tx_type = {} '.format(TxTypes.ITX) + \ 'LEFT JOIN transactions AS tx2 ON tx2.bid_id = bids.bid_id AND tx2.tx_type = {} '.format(TxTypes.PTX) diff --git a/basicswap/basicswap_util.py b/basicswap/basicswap_util.py index 526eb5f..8e6b928 100644 --- a/basicswap/basicswap_util.py +++ b/basicswap/basicswap_util.py @@ -84,6 +84,7 @@ class BidStates(IntEnum): BID_ABANDONED = auto() # Bid will no longer be processed BID_ERROR = auto() # An error occurred BID_STALLED_FOR_TEST = auto() + BID_REJECTED = auto() BID_STATE_UNKNOWN = auto() @@ -192,6 +193,8 @@ def strBidState(state): return 'Stalled (debug)' if state == BidStates.BID_ERROR: return 'Error' + if state == BidStates.BID_REJECTED: + return 'Rejected' if state == BidStates.XMR_SWAP_SCRIPT_COIN_LOCKED: return 'Script coin locked' if state == BidStates.XMR_SWAP_HAVE_SCRIPT_COIN_SPEND_TX: diff --git a/basicswap/db.py b/basicswap/db.py index 99827be..c104ffb 100644 --- a/basicswap/db.py +++ b/basicswap/db.py @@ -12,7 +12,7 @@ from enum import IntEnum, auto from sqlalchemy.ext.declarative import declarative_base -CURRENT_DB_VERSION = 12 +CURRENT_DB_VERSION = 13 Base = declarative_base() @@ -66,6 +66,9 @@ class Offer(Base): from_feerate = sa.Column(sa.BigInteger) to_feerate = sa.Column(sa.BigInteger) + amount_negotiable = sa.Column(sa.Boolean) + rate_negotiable = sa.Column(sa.Boolean) + # Local fields auto_accept_bids = sa.Column(sa.Boolean) withdraw_to_addr = sa.Column(sa.String) # Address to spend lock tx to - address from wallet if empty TODO @@ -105,6 +108,7 @@ class Bid(Base): pkhash_buyer = sa.Column(sa.LargeBinary) amount = sa.Column(sa.BigInteger) + rate = sa.Column(sa.BigInteger) accept_msg_id = sa.Column(sa.LargeBinary) pkhash_seller = sa.Column(sa.LargeBinary) @@ -128,6 +132,8 @@ class Bid(Base): chain_a_height_start = sa.Column(sa.Integer) # Height of script chain before the swap chain_b_height_start = sa.Column(sa.Integer) # Height of scriptless chain before the swap + reject_code = sa.Column(sa.Integer) + initiate_tx = None participate_tx = None xmr_a_lock_tx = None @@ -373,3 +379,21 @@ class Wallets(Base): amount = sa.Column(sa.BigInteger) updated_at = sa.Column(sa.BigInteger) created_at = sa.Column(sa.BigInteger) + + +class KnownIdentity(Base): + __tablename__ = 'knownidentities' + + record_id = sa.Column(sa.Integer, primary_key=True, autoincrement=True) + address = sa.Column(sa.String) + label = sa.Column(sa.String) + publickey = sa.Column(sa.LargeBinary) + num_sent_bids_successful = sa.Column(sa.Integer) + num_recv_bids_successful = sa.Column(sa.Integer) + num_sent_bids_rejected = sa.Column(sa.Integer) + num_recv_bids_rejected = sa.Column(sa.Integer) + num_sent_bids_failed = sa.Column(sa.Integer) + num_recv_bids_failed = sa.Column(sa.Integer) + note = sa.Column(sa.String) + updated_at = sa.Column(sa.BigInteger) + created_at = sa.Column(sa.BigInteger) diff --git a/basicswap/http_server.py b/basicswap/http_server.py index f0d11fa..79833ef 100644 --- a/basicswap/http_server.py +++ b/basicswap/http_server.py @@ -752,6 +752,8 @@ class HttpHandler(BaseHTTPRequestHandler): 'sent': 'True' if offer.was_sent else 'False', 'was_revoked': 'True' if offer.active_ind == 2 else 'False', 'show_bid_form': show_bid_form, + 'amount_negotiable': offer.amount_negotiable, + 'rate_negotiable': offer.rate_negotiable, } data.update(extend_data) @@ -780,7 +782,7 @@ class HttpHandler(BaseHTTPRequestHandler): sent_bid_id=sent_bid_id, messages=messages, data=data, - bids=[(b[2].hex(), ci_from.format_amount(b[4]), strBidState(b[5]), strTxState(b[7]), strTxState(b[8])) for b in bids], + bids=[(b[2].hex(), ci_from.format_amount(b[4]), strBidState(b[5]), ci_to.format_amount(b[10]), b[11]) for b in bids], addrs=None if show_bid_form is None else swap_client.listSmsgAddresses('bid'), form_id=os.urandom(8).hex(), ), 'UTF-8') @@ -960,7 +962,7 @@ class HttpHandler(BaseHTTPRequestHandler): h2=self.server.title, page_type='Sent' if sent else 'Received', bids=[(format_timestamp(b[0]), - b[2].hex(), b[3].hex(), strBidState(b[5]), strTxState(b[7]), strTxState(b[8])) for b in bids], + b[2].hex(), b[3].hex(), strBidState(b[5]), strTxState(b[7]), strTxState(b[8]), b[11]) for b in bids], ), 'UTF-8') def page_watched(self, url_split, post_string): @@ -1050,6 +1052,36 @@ class HttpHandler(BaseHTTPRequestHandler): network_addr=network_addr, ), 'UTF-8') + def page_identity(self, url_split, post_string): + assert(len(url_split) > 2), 'Address not specified' + identity_address = url_split[2] + swap_client = self.server.swap_client + + page_data = {'identity_address': identity_address} + messages = [] + + try: + identity = swap_client.getIdentity(identity_address) + if identity is None: + raise ValueError('Unknown address') + page_data['num_sent_bids_successful'] = identity.num_sent_bids_successful + page_data['num_recv_bids_successful'] = identity.num_recv_bids_successful + page_data['num_sent_bids_rejected'] = identity.num_sent_bids_rejected + page_data['num_recv_bids_rejected'] = identity.num_recv_bids_rejected + page_data['num_sent_bids_failed'] = identity.num_sent_bids_failed + page_data['num_recv_bids_failed'] = identity.num_recv_bids_failed + except Exception as e: + messages.append(e) + + template = env.get_template('identity.html') + return bytes(template.render( + title=self.server.title, + h2=self.server.title, + messages=messages, + data=page_data, + form_id=os.urandom(8).hex(), + ), 'UTF-8') + def page_shutdown(self, url_split, post_string): swap_client = self.server.swap_client swap_client.stopRunning() @@ -1158,6 +1190,8 @@ class HttpHandler(BaseHTTPRequestHandler): return self.page_watched(url_split, post_string) if url_split[1] == 'smsgaddresses': return self.page_smsgaddresses(url_split, post_string) + if url_split[1] == 'identity': + return self.page_identity(url_split, post_string) if url_split[1] == 'shutdown': return self.page_shutdown(url_split, post_string) return self.page_index(url_split) diff --git a/basicswap/messages.proto b/basicswap/messages.proto index 0a1ba4f..b606bd4 100644 --- a/basicswap/messages.proto +++ b/basicswap/messages.proto @@ -31,6 +31,8 @@ message OfferMessage { uint64 fee_rate_to = 15; uint32 protocol_version = 16; + bool amount_negotiable = 17; + bool rate_negotiable = 18; } /* Step 2, buyer -> seller */ @@ -40,11 +42,12 @@ message BidMessage { uint64 amount = 3; /* amount of amount_from bid is for */ /* optional */ - bytes pkhash_buyer = 4; /* buyer's address to receive amount_from */ - string proof_address = 5; - string proof_signature = 6; + uint64 rate = 4; + bytes pkhash_buyer = 5; /* buyer's address to receive amount_from */ + string proof_address = 6; + string proof_signature = 7; - uint32 protocol_version = 7; + uint32 protocol_version = 8; } /* Step 3, seller -> buyer */ @@ -59,20 +62,27 @@ message OfferRevokeMessage { bytes signature = 2; } +message BidRejectMessage { + bytes bid_msg_id = 1; + + uint32 reject_code = 2; +} + message XmrBidMessage { /* MSG1L, F -> L */ bytes offer_msg_id = 1; uint64 time_valid = 2; /* seconds bid is valid for */ uint64 amount = 3; /* amount of amount_from bid is for */ + uint64 rate = 4; - bytes pkaf = 4; + bytes pkaf = 5; - bytes kbvf = 5; - bytes kbsf_dleag = 6; + bytes kbvf = 6; + bytes kbsf_dleag = 7; - bytes dest_af = 7; + bytes dest_af = 8; - uint32 protocol_version = 8; + uint32 protocol_version = 9; } message XmrSplitMessage { diff --git a/basicswap/messages_pb2.py b/basicswap/messages_pb2.py index 5a5e317..d39ec42 100644 --- a/basicswap/messages_pb2.py +++ b/basicswap/messages_pb2.py @@ -19,7 +19,7 @@ DESCRIPTOR = _descriptor.FileDescriptor( syntax='proto3', serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x0emessages.proto\x12\tbasicswap\"\xf2\x03\n\x0cOfferMessage\x12\x11\n\tcoin_from\x18\x01 \x01(\r\x12\x0f\n\x07\x63oin_to\x18\x02 \x01(\r\x12\x13\n\x0b\x61mount_from\x18\x03 \x01(\x04\x12\x0c\n\x04rate\x18\x04 \x01(\x04\x12\x16\n\x0emin_bid_amount\x18\x05 \x01(\x04\x12\x12\n\ntime_valid\x18\x06 \x01(\x04\x12\x33\n\tlock_type\x18\x07 \x01(\x0e\x32 .basicswap.OfferMessage.LockType\x12\x12\n\nlock_value\x18\x08 \x01(\r\x12\x11\n\tswap_type\x18\t \x01(\r\x12\x15\n\rproof_address\x18\n \x01(\t\x12\x17\n\x0fproof_signature\x18\x0b \x01(\t\x12\x15\n\rpkhash_seller\x18\x0c \x01(\x0c\x12\x13\n\x0bsecret_hash\x18\r \x01(\x0c\x12\x15\n\rfee_rate_from\x18\x0e \x01(\x04\x12\x13\n\x0b\x66\x65\x65_rate_to\x18\x0f \x01(\x04\x12\x18\n\x10protocol_version\x18\x10 \x01(\r\"q\n\x08LockType\x12\x0b\n\x07NOT_SET\x10\x00\x12\x18\n\x14SEQUENCE_LOCK_BLOCKS\x10\x01\x12\x16\n\x12SEQUENCE_LOCK_TIME\x10\x02\x12\x13\n\x0f\x41\x42S_LOCK_BLOCKS\x10\x03\x12\x11\n\rABS_LOCK_TIME\x10\x04\"\xa6\x01\n\nBidMessage\x12\x14\n\x0coffer_msg_id\x18\x01 \x01(\x0c\x12\x12\n\ntime_valid\x18\x02 \x01(\x04\x12\x0e\n\x06\x61mount\x18\x03 \x01(\x04\x12\x14\n\x0cpkhash_buyer\x18\x04 \x01(\x0c\x12\x15\n\rproof_address\x18\x05 \x01(\t\x12\x17\n\x0fproof_signature\x18\x06 \x01(\t\x12\x18\n\x10protocol_version\x18\x07 \x01(\r\"V\n\x10\x42idAcceptMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x15\n\rinitiate_txid\x18\x02 \x01(\x0c\x12\x17\n\x0f\x63ontract_script\x18\x03 \x01(\x0c\"=\n\x12OfferRevokeMessage\x12\x14\n\x0coffer_msg_id\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c\"\xa4\x01\n\rXmrBidMessage\x12\x14\n\x0coffer_msg_id\x18\x01 \x01(\x0c\x12\x12\n\ntime_valid\x18\x02 \x01(\x04\x12\x0e\n\x06\x61mount\x18\x03 \x01(\x04\x12\x0c\n\x04pkaf\x18\x04 \x01(\x0c\x12\x0c\n\x04kbvf\x18\x05 \x01(\x0c\x12\x12\n\nkbsf_dleag\x18\x06 \x01(\x0c\x12\x0f\n\x07\x64\x65st_af\x18\x07 \x01(\x0c\x12\x18\n\x10protocol_version\x18\x08 \x01(\r\"T\n\x0fXmrSplitMessage\x12\x0e\n\x06msg_id\x18\x01 \x01(\x0c\x12\x10\n\x08msg_type\x18\x02 \x01(\r\x12\x10\n\x08sequence\x18\x03 \x01(\r\x12\r\n\x05\x64leag\x18\x04 \x01(\x0c\"\x80\x02\n\x13XmrBidAcceptMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x0c\n\x04pkal\x18\x03 \x01(\x0c\x12\x0c\n\x04kbvl\x18\x04 \x01(\x0c\x12\x12\n\nkbsl_dleag\x18\x05 \x01(\x0c\x12\x11\n\ta_lock_tx\x18\x06 \x01(\x0c\x12\x18\n\x10\x61_lock_tx_script\x18\x07 \x01(\x0c\x12\x18\n\x10\x61_lock_refund_tx\x18\x08 \x01(\x0c\x12\x1f\n\x17\x61_lock_refund_tx_script\x18\t \x01(\x0c\x12\x1e\n\x16\x61_lock_refund_spend_tx\x18\n \x01(\x0c\x12\x1d\n\x15\x61l_lock_refund_tx_sig\x18\x0b \x01(\x0c\"r\n\x17XmrBidLockTxSigsMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12$\n\x1c\x61\x66_lock_refund_spend_tx_esig\x18\x02 \x01(\x0c\x12\x1d\n\x15\x61\x66_lock_refund_tx_sig\x18\x03 \x01(\x0c\"X\n\x18XmrBidLockSpendTxMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x17\n\x0f\x61_lock_spend_tx\x18\x02 \x01(\x0c\x12\x0f\n\x07kal_sig\x18\x03 \x01(\x0c\"M\n\x18XmrBidLockReleaseMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x1d\n\x15\x61l_lock_spend_tx_esig\x18\x02 \x01(\x0c\x62\x06proto3' + serialized_pb=b'\n\x0emessages.proto\x12\tbasicswap\"\xa6\x04\n\x0cOfferMessage\x12\x11\n\tcoin_from\x18\x01 \x01(\r\x12\x0f\n\x07\x63oin_to\x18\x02 \x01(\r\x12\x13\n\x0b\x61mount_from\x18\x03 \x01(\x04\x12\x0c\n\x04rate\x18\x04 \x01(\x04\x12\x16\n\x0emin_bid_amount\x18\x05 \x01(\x04\x12\x12\n\ntime_valid\x18\x06 \x01(\x04\x12\x33\n\tlock_type\x18\x07 \x01(\x0e\x32 .basicswap.OfferMessage.LockType\x12\x12\n\nlock_value\x18\x08 \x01(\r\x12\x11\n\tswap_type\x18\t \x01(\r\x12\x15\n\rproof_address\x18\n \x01(\t\x12\x17\n\x0fproof_signature\x18\x0b \x01(\t\x12\x15\n\rpkhash_seller\x18\x0c \x01(\x0c\x12\x13\n\x0bsecret_hash\x18\r \x01(\x0c\x12\x15\n\rfee_rate_from\x18\x0e \x01(\x04\x12\x13\n\x0b\x66\x65\x65_rate_to\x18\x0f \x01(\x04\x12\x18\n\x10protocol_version\x18\x10 \x01(\r\x12\x19\n\x11\x61mount_negotiable\x18\x11 \x01(\x08\x12\x17\n\x0frate_negotiable\x18\x12 \x01(\x08\"q\n\x08LockType\x12\x0b\n\x07NOT_SET\x10\x00\x12\x18\n\x14SEQUENCE_LOCK_BLOCKS\x10\x01\x12\x16\n\x12SEQUENCE_LOCK_TIME\x10\x02\x12\x13\n\x0f\x41\x42S_LOCK_BLOCKS\x10\x03\x12\x11\n\rABS_LOCK_TIME\x10\x04\"\xb4\x01\n\nBidMessage\x12\x14\n\x0coffer_msg_id\x18\x01 \x01(\x0c\x12\x12\n\ntime_valid\x18\x02 \x01(\x04\x12\x0e\n\x06\x61mount\x18\x03 \x01(\x04\x12\x0c\n\x04rate\x18\x04 \x01(\x04\x12\x14\n\x0cpkhash_buyer\x18\x05 \x01(\x0c\x12\x15\n\rproof_address\x18\x06 \x01(\t\x12\x17\n\x0fproof_signature\x18\x07 \x01(\t\x12\x18\n\x10protocol_version\x18\x08 \x01(\r\"V\n\x10\x42idAcceptMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x15\n\rinitiate_txid\x18\x02 \x01(\x0c\x12\x17\n\x0f\x63ontract_script\x18\x03 \x01(\x0c\"=\n\x12OfferRevokeMessage\x12\x14\n\x0coffer_msg_id\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c\";\n\x10\x42idRejectMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x13\n\x0breject_code\x18\x02 \x01(\r\"\xb2\x01\n\rXmrBidMessage\x12\x14\n\x0coffer_msg_id\x18\x01 \x01(\x0c\x12\x12\n\ntime_valid\x18\x02 \x01(\x04\x12\x0e\n\x06\x61mount\x18\x03 \x01(\x04\x12\x0c\n\x04rate\x18\x04 \x01(\x04\x12\x0c\n\x04pkaf\x18\x05 \x01(\x0c\x12\x0c\n\x04kbvf\x18\x06 \x01(\x0c\x12\x12\n\nkbsf_dleag\x18\x07 \x01(\x0c\x12\x0f\n\x07\x64\x65st_af\x18\x08 \x01(\x0c\x12\x18\n\x10protocol_version\x18\t \x01(\r\"T\n\x0fXmrSplitMessage\x12\x0e\n\x06msg_id\x18\x01 \x01(\x0c\x12\x10\n\x08msg_type\x18\x02 \x01(\r\x12\x10\n\x08sequence\x18\x03 \x01(\r\x12\r\n\x05\x64leag\x18\x04 \x01(\x0c\"\x80\x02\n\x13XmrBidAcceptMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x0c\n\x04pkal\x18\x03 \x01(\x0c\x12\x0c\n\x04kbvl\x18\x04 \x01(\x0c\x12\x12\n\nkbsl_dleag\x18\x05 \x01(\x0c\x12\x11\n\ta_lock_tx\x18\x06 \x01(\x0c\x12\x18\n\x10\x61_lock_tx_script\x18\x07 \x01(\x0c\x12\x18\n\x10\x61_lock_refund_tx\x18\x08 \x01(\x0c\x12\x1f\n\x17\x61_lock_refund_tx_script\x18\t \x01(\x0c\x12\x1e\n\x16\x61_lock_refund_spend_tx\x18\n \x01(\x0c\x12\x1d\n\x15\x61l_lock_refund_tx_sig\x18\x0b \x01(\x0c\"r\n\x17XmrBidLockTxSigsMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12$\n\x1c\x61\x66_lock_refund_spend_tx_esig\x18\x02 \x01(\x0c\x12\x1d\n\x15\x61\x66_lock_refund_tx_sig\x18\x03 \x01(\x0c\"X\n\x18XmrBidLockSpendTxMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x17\n\x0f\x61_lock_spend_tx\x18\x02 \x01(\x0c\x12\x0f\n\x07kal_sig\x18\x03 \x01(\x0c\"M\n\x18XmrBidLockReleaseMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x1d\n\x15\x61l_lock_spend_tx_esig\x18\x02 \x01(\x0c\x62\x06proto3' ) @@ -59,8 +59,8 @@ _OFFERMESSAGE_LOCKTYPE = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=415, - serialized_end=528, + serialized_start=467, + serialized_end=580, ) _sym_db.RegisterEnumDescriptor(_OFFERMESSAGE_LOCKTYPE) @@ -185,6 +185,20 @@ _OFFERMESSAGE = _descriptor.Descriptor( message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='amount_negotiable', full_name='basicswap.OfferMessage.amount_negotiable', index=16, + number=17, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='rate_negotiable', full_name='basicswap.OfferMessage.rate_negotiable', index=17, + number=18, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), ], extensions=[ ], @@ -199,7 +213,7 @@ _OFFERMESSAGE = _descriptor.Descriptor( oneofs=[ ], serialized_start=30, - serialized_end=528, + serialized_end=580, ) @@ -233,29 +247,36 @@ _BIDMESSAGE = _descriptor.Descriptor( is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='pkhash_buyer', full_name='basicswap.BidMessage.pkhash_buyer', index=3, - number=4, type=12, cpp_type=9, label=1, + name='rate', full_name='basicswap.BidMessage.rate', index=3, + number=4, type=4, cpp_type=4, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='pkhash_buyer', full_name='basicswap.BidMessage.pkhash_buyer', index=4, + number=5, type=12, cpp_type=9, label=1, has_default_value=False, default_value=b"", message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='proof_address', full_name='basicswap.BidMessage.proof_address', index=4, - number=5, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='proof_signature', full_name='basicswap.BidMessage.proof_signature', index=5, + name='proof_address', full_name='basicswap.BidMessage.proof_address', index=5, number=6, type=9, cpp_type=9, label=1, has_default_value=False, default_value=b"".decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='protocol_version', full_name='basicswap.BidMessage.protocol_version', index=6, - number=7, type=13, cpp_type=3, label=1, + name='proof_signature', full_name='basicswap.BidMessage.proof_signature', index=6, + number=7, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='protocol_version', full_name='basicswap.BidMessage.protocol_version', index=7, + number=8, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, @@ -272,8 +293,8 @@ _BIDMESSAGE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=531, - serialized_end=697, + serialized_start=583, + serialized_end=763, ) @@ -318,8 +339,8 @@ _BIDACCEPTMESSAGE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=699, - serialized_end=785, + serialized_start=765, + serialized_end=851, ) @@ -357,8 +378,47 @@ _OFFERREVOKEMESSAGE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=787, - serialized_end=848, + serialized_start=853, + serialized_end=914, +) + + +_BIDREJECTMESSAGE = _descriptor.Descriptor( + name='BidRejectMessage', + full_name='basicswap.BidRejectMessage', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='bid_msg_id', full_name='basicswap.BidRejectMessage.bid_msg_id', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='reject_code', full_name='basicswap.BidRejectMessage.reject_code', index=1, + number=2, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=916, + serialized_end=975, ) @@ -392,36 +452,43 @@ _XMRBIDMESSAGE = _descriptor.Descriptor( is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='pkaf', full_name='basicswap.XmrBidMessage.pkaf', index=3, - number=4, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=b"", + name='rate', full_name='basicswap.XmrBidMessage.rate', index=3, + number=4, type=4, cpp_type=4, label=1, + has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='kbvf', full_name='basicswap.XmrBidMessage.kbvf', index=4, + name='pkaf', full_name='basicswap.XmrBidMessage.pkaf', index=4, number=5, type=12, cpp_type=9, label=1, has_default_value=False, default_value=b"", message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='kbsf_dleag', full_name='basicswap.XmrBidMessage.kbsf_dleag', index=5, + name='kbvf', full_name='basicswap.XmrBidMessage.kbvf', index=5, number=6, type=12, cpp_type=9, label=1, has_default_value=False, default_value=b"", message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='dest_af', full_name='basicswap.XmrBidMessage.dest_af', index=6, + name='kbsf_dleag', full_name='basicswap.XmrBidMessage.kbsf_dleag', index=6, number=7, type=12, cpp_type=9, label=1, has_default_value=False, default_value=b"", message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='protocol_version', full_name='basicswap.XmrBidMessage.protocol_version', index=7, - number=8, type=13, cpp_type=3, label=1, + name='dest_af', full_name='basicswap.XmrBidMessage.dest_af', index=7, + number=8, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='protocol_version', full_name='basicswap.XmrBidMessage.protocol_version', index=8, + number=9, type=13, cpp_type=3, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, @@ -438,8 +505,8 @@ _XMRBIDMESSAGE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=851, - serialized_end=1015, + serialized_start=978, + serialized_end=1156, ) @@ -491,8 +558,8 @@ _XMRSPLITMESSAGE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1017, - serialized_end=1101, + serialized_start=1158, + serialized_end=1242, ) @@ -586,8 +653,8 @@ _XMRBIDACCEPTMESSAGE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1104, - serialized_end=1360, + serialized_start=1245, + serialized_end=1501, ) @@ -632,8 +699,8 @@ _XMRBIDLOCKTXSIGSMESSAGE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1362, - serialized_end=1476, + serialized_start=1503, + serialized_end=1617, ) @@ -678,8 +745,8 @@ _XMRBIDLOCKSPENDTXMESSAGE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1478, - serialized_end=1566, + serialized_start=1619, + serialized_end=1707, ) @@ -717,8 +784,8 @@ _XMRBIDLOCKRELEASEMESSAGE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1568, - serialized_end=1645, + serialized_start=1709, + serialized_end=1786, ) _OFFERMESSAGE.fields_by_name['lock_type'].enum_type = _OFFERMESSAGE_LOCKTYPE @@ -727,6 +794,7 @@ DESCRIPTOR.message_types_by_name['OfferMessage'] = _OFFERMESSAGE DESCRIPTOR.message_types_by_name['BidMessage'] = _BIDMESSAGE DESCRIPTOR.message_types_by_name['BidAcceptMessage'] = _BIDACCEPTMESSAGE DESCRIPTOR.message_types_by_name['OfferRevokeMessage'] = _OFFERREVOKEMESSAGE +DESCRIPTOR.message_types_by_name['BidRejectMessage'] = _BIDREJECTMESSAGE DESCRIPTOR.message_types_by_name['XmrBidMessage'] = _XMRBIDMESSAGE DESCRIPTOR.message_types_by_name['XmrSplitMessage'] = _XMRSPLITMESSAGE DESCRIPTOR.message_types_by_name['XmrBidAcceptMessage'] = _XMRBIDACCEPTMESSAGE @@ -763,6 +831,13 @@ OfferRevokeMessage = _reflection.GeneratedProtocolMessageType('OfferRevokeMessag }) _sym_db.RegisterMessage(OfferRevokeMessage) +BidRejectMessage = _reflection.GeneratedProtocolMessageType('BidRejectMessage', (_message.Message,), { + 'DESCRIPTOR' : _BIDREJECTMESSAGE, + '__module__' : 'messages_pb2' + # @@protoc_insertion_point(class_scope:basicswap.BidRejectMessage) + }) +_sym_db.RegisterMessage(BidRejectMessage) + XmrBidMessage = _reflection.GeneratedProtocolMessageType('XmrBidMessage', (_message.Message,), { 'DESCRIPTOR' : _XMRBIDMESSAGE, '__module__' : 'messages_pb2' diff --git a/basicswap/templates/bid.html b/basicswap/templates/bid.html index 6e9783b..ea2cd5e 100644 --- a/basicswap/templates/bid.html +++ b/basicswap/templates/bid.html @@ -15,12 +15,13 @@ {% else %} Swap{{ data.amt_from }} {{ data.ticker_from }} for {{ data.amt_to }} {{ data.ticker_to }} {% endif %} +Bid Rate{{ data.bid_rate }} Bid State{{ data.bid_state }} State Description {{ data.state_description }} ITX State{{ data.itx_state }} PTX State{{ data.ptx_state }} Offer{{ data.offer_id }} -Address From{{ data.addr_from }} +Address From{{ data.addr_from }} Proof of Funds{{ data.proof_address }} Created At{{ data.created_at }} Expired At{{ data.expired_at }} diff --git a/basicswap/templates/bid_xmr.html b/basicswap/templates/bid_xmr.html index 55ac5ac..9e9a230 100644 --- a/basicswap/templates/bid_xmr.html +++ b/basicswap/templates/bid_xmr.html @@ -15,12 +15,13 @@ {% else %} Swap{{ data.amt_from }} {{ data.ticker_from }} for {{ data.amt_to }} {{ data.ticker_to }} {% endif %} +Bid Rate{{ data.bid_rate }} Coin From{{ data.coin_from }} Coin To{{ data.coin_to }} Bid State{{ data.bid_state }} State Description {{ data.state_description }} Offer{{ data.offer_id }} -Address From{{ data.addr_from }} +Address From{{ data.addr_from }} Created At{{ data.created_at }} Expired At{{ data.expired_at }} Sent{{ data.was_sent }} diff --git a/basicswap/templates/bids.html b/basicswap/templates/bids.html index 83e08fd..64d96c2 100644 --- a/basicswap/templates/bids.html +++ b/basicswap/templates/bids.html @@ -6,9 +6,14 @@ {% endif %} - + {% for b in bids %} - + + + + + + {% endfor %}
AtBid IDOffer IDBid StatusITX StatusPTX Status
AtBid IDOffer IDBid FromBid StatusITX StatusPTX Status
{{ b[0] }}{{ b[1] }}{{ b[2] }}{{ b[3] }}{{ b[4] }}{{ b[5] }}
{{ b[0] }}{{ b[1] }}{{ b[2] }}{{ b[6] }}{{ b[3] }}{{ b[4] }}{{ b[5] }}
diff --git a/basicswap/templates/identity.html b/basicswap/templates/identity.html new file mode 100644 index 0000000..c0390a9 --- /dev/null +++ b/basicswap/templates/identity.html @@ -0,0 +1,23 @@ +{% include 'header.html' %} + +

Identity {{ data.identity_address }}

+ +{% for m in messages %} +

{{ m }}

+{% endfor %} + +
+ + + + + + + + +
Successful Sent Bids{{ data.num_sent_bids_successful }}
Successful Received Bids{{ data.num_recv_bids_successful }}
Rejected Sent Bids{{ data.num_sent_bids_rejected }}
Rejected Received Bids{{ data.num_recv_bids_rejected }}
Failed Sent Bids{{ data.num_sent_bids_failed }}
Failed Received Bids{{ data.num_recv_bids_failed }}
+ +
+ +

home

+ diff --git a/basicswap/templates/offer.html b/basicswap/templates/offer.html index d8a7706..f6c1bac 100644 --- a/basicswap/templates/offer.html +++ b/basicswap/templates/offer.html @@ -20,10 +20,12 @@ Amount From{{ data.amt_from }} {{ data.tla_from }} Amount To{{ data.amt_to }} {{ data.tla_to }} Rate{{ data.rate }} {{ data.amt_from }}/{{ data.tla_from }} +Amount Variable{{ data.amount_negotiable }} +Rate Variable{{ data.rate_negotiable }} Script Lock Type{{ data.lock_type }} Script Lock Value{{ data.lock_value }} Address To{{ data.addr_to }} -Address From{{ data.addr_from }} +Address From{{ data.addr_from }} Created At{{ data.created_at | formatts }} Expired At{{ data.expired_at | formatts }} Sent{{ data.sent }} @@ -73,9 +75,9 @@

Bids

- + {% for b in bids %} - + {% endfor %}
Bid IDBid AmountBid StatusITX StatusPTX Status
Bid IDBid AmountBid RateBid StatusIdentity From
{{ b[0] }}{{ b[1] }}{{ b[2] }}{{ b[3] }}{{ b[4] }}
{{ b[0] }}{{ b[1] }}{{ b[3] }}{{ b[2] }}{{ b[4] }}
diff --git a/basicswap/ui.py b/basicswap/ui.py index 0b32ef7..6f9e36a 100644 --- a/basicswap/ui.py +++ b/basicswap/ui.py @@ -207,6 +207,7 @@ def describeBid(swap_client, bid, xmr_swap, offer, xmr_offer, bid_events, edit_b 'coin_to': ci_to.coin_name(), 'amt_from': ci_from.format_amount(bid.amount), 'amt_to': ci_to.format_amount((bid.amount * offer.rate) // ci_from.COIN()), + 'bid_rate': ci_to.format_amount(bid.rate), 'ticker_from': ticker_from, 'ticker_to': ticker_to, 'bid_state': strBidState(bid.state), diff --git a/doc/release-notes.md b/doc/release-notes.md index 2e22f30..e82197f 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -1,4 +1,10 @@ +0.0.27 +============== + +- Track failed and successful swaps by address + + 0.0.26 ==============