Count failed and successful bids by peer address.

This commit is contained in:
tecnovert 2021-11-15 01:26:43 +02:00
parent b152150932
commit 20c59663c1
No known key found for this signature in database
GPG key ID: 8ED6D8750C4E3F93
14 changed files with 348 additions and 64 deletions

View file

@ -1,3 +1,3 @@
name = "basicswap"
__version__ = "0.0.26"
__version__ = "0.0.27"

View file

@ -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)

View file

@ -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:

View file

@ -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)

View file

@ -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)

View file

@ -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 {

View file

@ -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'

View file

@ -15,12 +15,13 @@
{% else %}
<tr><td>Swap</td><td>{{ data.amt_from }} {{ data.ticker_from }} for {{ data.amt_to }} {{ data.ticker_to }}</td></tr>
{% endif %}
<tr><td>Bid Rate</td><td>{{ data.bid_rate }}</td></tr>
<tr><td>Bid State</td><td>{{ data.bid_state }}</td></tr>
<tr><td>State Description </td><td>{{ data.state_description }}</td></tr>
<tr><td>ITX State</td><td>{{ data.itx_state }}</td></tr>
<tr><td>PTX State</td><td>{{ data.ptx_state }}</td></tr>
<tr><td>Offer</td><td><a class="monospace" href="/offer/{{ data.offer_id }}">{{ data.offer_id }}</a></td></tr>
<tr><td>Address From</td><td class="monospace">{{ data.addr_from }}</td></tr>
<tr><td>Address From</td><td><a class="monospace" href="/identity/{{ data.addr_from }}">{{ data.addr_from }}</a></td></tr>
<tr><td>Proof of Funds</td><td>{{ data.proof_address }}</td></tr>
<tr><td>Created At</td><td>{{ data.created_at }}</td></tr>
<tr><td>Expired At</td><td>{{ data.expired_at }}</td></tr>

View file

@ -15,12 +15,13 @@
{% else %}
<tr><td>Swap</td><td>{{ data.amt_from }} {{ data.ticker_from }} for {{ data.amt_to }} {{ data.ticker_to }}</td></tr>
{% endif %}
<tr><td>Bid Rate</td><td>{{ data.bid_rate }}</td></tr>
<tr><td>Coin From</td><td>{{ data.coin_from }}</td></tr>
<tr><td>Coin To</td><td>{{ data.coin_to }}</td></tr>
<tr><td>Bid State</td><td>{{ data.bid_state }}</td></tr>
<tr><td>State Description </td><td>{{ data.state_description }}</td></tr>
<tr><td>Offer</td><td><a class="monospace" href="/offer/{{ data.offer_id }}">{{ data.offer_id }}</a></td></tr>
<tr><td>Address From</td><td class="monospace">{{ data.addr_from }}</td></tr>
<tr><td>Address From</td><td><a class="monospace" href="/identity/{{ data.addr_from }}">{{ data.addr_from }}</a></td></tr>
<tr><td>Created At</td><td>{{ data.created_at }}</td></tr>
<tr><td>Expired At</td><td>{{ data.expired_at }}</td></tr>
<tr><td>Sent</td><td>{{ data.was_sent }}</td></tr>

View file

@ -6,9 +6,14 @@
{% endif %}
<table>
<tr><th>At</th><th>Bid ID</th><th>Offer ID</th><th>Bid Status</th><th>ITX Status</th><th>PTX Status</th></tr>
<tr><th>At</th><th>Bid ID</th><th>Offer ID</th><th>Bid From</th><th>Bid Status</th><th>ITX Status</th><th>PTX Status</th></tr>
{% for b in bids %}
<tr><td>{{ b[0] }}</td><td><a class="monospace" href=/bid/{{ b[1] }}>{{ b[1] }}</a></td><td><a class="monospace" href=/offer/{{ b[2] }}>{{ b[2] }}</a></td><td>{{ b[3] }}</td><td>{{ b[4] }}</td><td>{{ b[5] }}</td></tr>
<tr>
<td>{{ b[0] }}</td>
<td><a class="monospace" href=/bid/{{ b[1] }}>{{ b[1] }}</a></td>
<td><a class="monospace" href=/offer/{{ b[2] }}>{{ b[2] }}</a></td>
<td><a class="monospace" href=/identity/{{ b[6] }}>{{ b[6] }}</a></td>
<td>{{ b[3] }}</td><td>{{ b[4] }}</td><td>{{ b[5] }}</td></tr>
{% endfor %}
</table>

View file

@ -0,0 +1,23 @@
{% include 'header.html' %}
<h3>Identity {{ data.identity_address }}</h3>
{% for m in messages %}
<p>{{ m }}</p>
{% endfor %}
<form method="post">
<table>
<tr><td>Successful Sent Bids</td><td>{{ data.num_sent_bids_successful }}</td></tr>
<tr><td>Successful Received Bids</td><td>{{ data.num_recv_bids_successful }}</td></tr>
<tr><td>Rejected Sent Bids</td><td>{{ data.num_sent_bids_rejected }}</td></tr>
<tr><td>Rejected Received Bids</td><td>{{ data.num_recv_bids_rejected }}</td></tr>
<tr><td>Failed Sent Bids</td><td>{{ data.num_sent_bids_failed }}</td></tr>
<tr><td>Failed Received Bids</td><td>{{ data.num_recv_bids_failed }}</td></tr>
</table>
<input type="hidden" name="formid" value="{{ form_id }}">
</form>
<p><a href="/">home</a></p>
</body></html>

View file

@ -20,10 +20,12 @@
<tr><td>Amount From</td><td>{{ data.amt_from }} {{ data.tla_from }}</td></tr>
<tr><td>Amount To</td><td>{{ data.amt_to }} {{ data.tla_to }}</td></tr>
<tr><td>Rate</td><td>{{ data.rate }} {{ data.amt_from }}/{{ data.tla_from }}</td></tr>
<tr><td>Amount Variable</td><td>{{ data.amount_negotiable }}</td></tr>
<tr><td>Rate Variable</td><td>{{ data.rate_negotiable }}</td></tr>
<tr><td>Script Lock Type</td><td>{{ data.lock_type }}</td></tr>
<tr><td>Script Lock Value</td><td>{{ data.lock_value }}</td></tr>
<tr><td>Address To</td><td>{{ data.addr_to }}</td></tr>
<tr><td>Address From</td><td>{{ data.addr_from }}</td></tr>
<tr><td>Address From</td><td><a class="monospace" href="/identity/{{ data.addr_from }}">{{ data.addr_from }}</a></td></tr>
<tr><td>Created At</td><td>{{ data.created_at | formatts }}</td></tr>
<tr><td>Expired At</td><td>{{ data.expired_at | formatts }}</td></tr>
<tr><td>Sent</td><td>{{ data.sent }}</td></tr>
@ -73,9 +75,9 @@
<h4>Bids</h4>
<table>
<tr><th>Bid ID</th><th>Bid Amount</th><th>Bid Status</th><th>ITX Status</th><th>PTX Status</th></tr>
<tr><th>Bid ID</th><th>Bid Amount</th><th>Bid Rate</th><th>Bid Status</th><th>Identity From</th></tr>
{% for b in bids %}
<tr><td><a class="monospace" href=/bid/{{ b[0] }}>{{ b[0] }}</a></td><td>{{ b[1] }}</td><td>{{ b[2] }}</td><td>{{ b[3] }}</td><td>{{ b[4] }}</td></tr>
<tr><td><a class="monospace" href=/bid/{{ b[0] }}>{{ b[0] }}</a></td><td>{{ b[1] }}</td><td>{{ b[3] }}</td><td>{{ b[2] }}</td><td><a class="monospace" href=/identity/{{ b[4] }}>{{ b[4] }}</a></td></tr>
{% endfor %}
</table>

View file

@ -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),

View file

@ -1,4 +1,10 @@
0.0.27
==============
- Track failed and successful swaps by address
0.0.26
==============