示例#1
0
def get_assets_supply(assets=[]):

    supplies = {}

    if 'XCP' in assets:
        supplies['XCP'] = (util.call_jsonrpc_api("get_supply", {'asset': 'XCP'})['result'], True)
        assets.remove('XCP')

    if 'BTC' in assets:
        supplies['BTC'] = (0, True)
        assets.remove('BTC')

    if len(assets) > 0:
        sql = '''SELECT asset, SUM(quantity) AS supply, divisible FROM issuances 
                 WHERE asset IN ({}) 
                 AND status = ?
                 GROUP BY asset
                 ORDER BY asset'''.format(','.join(['?' for e in range(0,len(assets))]))
        bindings = assets + ['valid']

        issuances = util.call_jsonrpc_api('sql', {'query': sql, 'bindings': bindings})['result']
        for issuance in issuances:
            supplies[issuance['asset']] = (issuance['supply'], issuance['divisible'])

    return supplies
示例#2
0
def get_assets_supply(assets=[]):

    supplies = {}

    if 'XCP' in assets:
        supplies['XCP'] = (util.call_jsonrpc_api("get_supply", {'asset': 'XCP'})['result'], True)
        assets.remove('XCP')

    if 'BTC' in assets:
        supplies['BTC'] = (0, True)
        assets.remove('BTC')

    if len(assets) > 0:
        sql = '''SELECT asset, SUM(quantity) AS supply, divisible FROM issuances 
                 WHERE asset IN ({}) 
                 AND status = ?
                 GROUP BY asset
                 ORDER BY asset'''.format(','.join(['?' for e in range(0, len(assets))]))
        bindings = assets + ['valid']

        issuances = util.call_jsonrpc_api('sql', {'query': sql, 'bindings': bindings})['result']
        for issuance in issuances:
            supplies[issuance['asset']] = (issuance['supply'], issuance['divisible'])

    return supplies
示例#3
0
 def get_optimal_fee_per_kb():
     fees = cache.get_value("FEE_PER_KB")
     if not fees:
         if config.BLOCKTRAIL_API_KEY:
             # query blocktrail API
             fees = util.get_url(
                 "https://api.blocktrail.com/v1/BTC/fee-per-kb?api_key={}".format(config.BLOCKTRAIL_API_KEY),
                 abort_on_error=True, is_json=True)
         else:
             # query bitcoind
             fees = {}
             fees['optimal'] = util.call_jsonrpc_api("fee_per_kb", {'conf_target': 3}, abort_on_error=True, use_cache=False)['result']
             fees['low_priority'] = util.call_jsonrpc_api("fee_per_kb", {'conf_target': 8}, abort_on_error=True, use_cache=False)['result']
         cache.set_value("FEE_PER_KB", fees, cache_period=60 * 5)  # cache for 5 minutes
     return fees
示例#4
0
def parse_base64_feed(base64_feed):
    decoded_feed = base64.b64decode(base64_feed)
    feed = json.loads(decoded_feed)
    if not isinstance(feed, dict) or "feed" not in feed:
        return False

    errors = util.is_valid_json(feed["feed"], config.FEED_SCHEMA)
    if len(errors) > 0:
        raise Exception("Invalid json: {}".format(", ".join(errors)))
    # get broadcast infos
    params = {
        "filters": {"field": "source", "op": "=", "value": feed["feed"]["address"]},
        "order_by": "tx_index",
        "order_dir": "DESC",
        "limit": 1,
    }
    broadcasts = util.call_jsonrpc_api("get_broadcasts", params)["result"]
    if len(broadcasts) == 0:
        raise Exception("invalid feed address")

    complete_feed = {}
    complete_feed["fee_fraction_int"] = broadcasts[0]["fee_fraction_int"]
    complete_feed["source"] = broadcasts[0]["source"]
    complete_feed["locked"] = broadcasts[0]["locked"]
    complete_feed["counters"] = get_feed_counters(broadcasts[0]["source"])
    complete_feed["info_data"] = sanitize_json_data(feed["feed"])

    feed["feed"] = complete_feed
    return feed
def bitcoind_rpc(command, params):
    return util.call_jsonrpc_api(
        command,
        params=params,
        endpoint=config.BACKEND_URL_NOAUTH,
        auth=config.BACKEND_AUTH,
        abort_on_error=True)['result']
示例#6
0
def get_asset_info(asset, at_dt=None):
    asset_info = config.mongo_db.tracked_assets.find_one({'asset': asset})
    
    if asset not in (config.XCP, config.BTC) and at_dt and asset_info['_at_block_time'] > at_dt:
        #get the asset info at or before the given at_dt datetime
        for e in reversed(asset_info['_history']): #newest to oldest
            if e['_at_block_time'] <= at_dt:
                asset_info = e
                break
        else: #asset was created AFTER at_dt
            asset_info = None
        if asset_info is None: return None
        assert asset_info['_at_block_time'] <= at_dt
      
    #modify some of the properties of the returned asset_info for BTC and XCP
    if asset == config.BTC:
        if at_dt:
            start_block_index, end_block_index = database.get_block_indexes_for_dates(end_dt=at_dt)
            asset_info['total_issued'] = blockchain.get_btc_supply(normalize=False, at_block_index=end_block_index)
            asset_info['total_issued_normalized'] = blockchain.normalize_quantity(asset_info['total_issued'])
        else:
            asset_info['total_issued'] = blockchain.get_btc_supply(normalize=False)
            asset_info['total_issued_normalized'] = blockchain.normalize_quantity(asset_info['total_issued'])
    elif asset == config.XCP:
        #BUG: this does not take end_dt (if specified) into account. however, the deviation won't be too big
        # as XCP doesn't deflate quickly at all, and shouldn't matter that much since there weren't any/much trades
        # before the end of the burn period (which is what is involved with how we use at_dt with currently)
        asset_info['total_issued'] = util.call_jsonrpc_api("get_supply", {'asset': 'XCP'}, abort_on_error=True)['result']
        asset_info['total_issued_normalized'] = blockchain.normalize_quantity(asset_info['total_issued'])
    if not asset_info:
        raise Exception("Invalid asset: %s" % asset)
    return asset_info
示例#7
0
def parse_base64_feed(base64_feed):
    decoded_feed = base64.b64decode(base64_feed)
    feed = json.loads(decoded_feed)
    if not isinstance(feed, dict) or 'feed' not in feed:
        return False

    errors = util.is_valid_json(feed['feed'], config.FEED_SCHEMA)
    if len(errors) > 0:
        raise Exception("Invalid json: {}".format(", ".join(errors)))
    # get broadcast infos
    params = {
        'filters': {
            'field': 'source',
            'op': '=',
            'value': feed['feed']['address']
        },
        'order_by': 'tx_index',
        'order_dir': 'DESC',
        'limit': 1
    }
    broadcasts = util.call_jsonrpc_api('get_broadcasts', params)['result']
    if len(broadcasts) == 0:
        raise Exception("invalid feed address")

    complete_feed = {}
    complete_feed['fee_fraction_int'] = broadcasts[0]['fee_fraction_int']
    complete_feed['source'] = broadcasts[0]['source']
    complete_feed['locked'] = broadcasts[0]['locked']
    complete_feed['counters'] = get_feed_counters(broadcasts[0]['source'])
    complete_feed['info_data'] = sanitize_json_data(feed['feed'])

    feed['feed'] = complete_feed
    return feed
示例#8
0
def get_pairs_with_orders(addresses=[], max_pairs=12):

    pairs_with_orders = []

    sources = '''AND source IN ({})'''.format(','.join(['?' for e in range(0,len(addresses))]))
        
    sql = '''SELECT (MIN(give_asset, get_asset) || '/' || MAX(give_asset, get_asset)) AS pair,
                    COUNT(*) AS order_count
             FROM orders
             WHERE give_asset != get_asset AND status = ? {} 
             GROUP BY pair 
             ORDER BY order_count DESC
             LIMIT ?'''.format(sources)
    
    bindings = ['open'] + addresses + [max_pairs]

    my_pairs = util.call_jsonrpc_api('sql', {'query': sql, 'bindings': bindings})['result']

    for my_pair in my_pairs:
        base_asset, quote_asset = util.assets_to_asset_pair(*tuple(my_pair['pair'].split("/")))
        top_pair = {
            'base_asset': base_asset,
            'quote_asset': quote_asset,
            'my_order_count': my_pair['order_count']
        }
        if my_pair['pair'] == 'BTC/XCP': # XCP/BTC always in first
            pairs_with_orders.insert(0, top_pair)
        else:
            pairs_with_orders.append(top_pair)

    return pairs_with_orders
示例#9
0
def get_pairs_with_orders(addresses=[], max_pairs=12):

    pairs_with_orders = []

    sources = '''AND source IN ({})'''.format(','.join(['?' for e in range(0, len(addresses))]))

    sql = '''SELECT (MIN(give_asset, get_asset) || '/' || MAX(give_asset, get_asset)) AS pair,
                    COUNT(*) AS order_count
             FROM orders
             WHERE give_asset != get_asset AND status = ? {} 
             GROUP BY pair 
             ORDER BY order_count DESC
             LIMIT ?'''.format(sources)

    bindings = ['open'] + addresses + [max_pairs]

    my_pairs = util.call_jsonrpc_api('sql', {'query': sql, 'bindings': bindings})['result']

    for my_pair in my_pairs:
        base_asset, quote_asset = util.assets_to_asset_pair(*tuple(my_pair['pair'].split("/")))
        top_pair = {
            'base_asset': base_asset,
            'quote_asset': quote_asset,
            'my_order_count': my_pair['order_count']
        }
        if my_pair['pair'] == 'BTC/XCP':  # XCP/BTC always in first
            pairs_with_orders.insert(0, top_pair)
        else:
            pairs_with_orders.append(top_pair)

    return pairs_with_orders
示例#10
0
def parse_base64_feed(base64_feed):
    decoded_feed = base64.b64decode(base64_feed)
    feed = json.loads(decoded_feed)
    if not isinstance(feed, dict) or 'feed' not in feed:
        return False
    
    errors = util.is_valid_json(feed['feed'], config.FEED_SCHEMA)
    if len(errors) > 0:
        raise Exception("Invalid json: {}".format(", ".join(errors)))
    # get broadcast infos
    params = {
        'filters': {
            'field': 'source',
            'op': '=',
            'value': feed['feed']['address']
        },
        'order_by': 'tx_index',
        'order_dir': 'DESC',
        'limit': 1
    }
    broadcasts = util.call_jsonrpc_api('get_broadcasts', params)['result']
    if len(broadcasts) == 0:
        raise Exception("invalid feed address")

    complete_feed = {}
    complete_feed['fee_fraction_int'] = broadcasts[0]['fee_fraction_int']
    complete_feed['source'] = broadcasts[0]['source']
    complete_feed['locked'] = broadcasts[0]['locked']
    complete_feed['counters'] = get_feed_counters(broadcasts[0]['source'])
    complete_feed['info_data'] = sanitize_json_data(feed['feed'])
    
    feed['feed'] = complete_feed
    return feed
示例#11
0
def get_feed(address_or_url = ''):
    conditions = {
        '$or': [{'source': address_or_url}, {'info_url': address_or_url}],
        'info_status': 'valid'
    }
    result = {}
    feeds = config.mongo_db.feeds.find(spec=conditions, projection={'_id': False}, limit=1)
    for feed in feeds:
        if 'targets' not in feed['info_data'] or ('type' in feed['info_data'] and feed['info_data']['type'] in ['all', 'cfd']):
            feed['info_data']['next_broadcast'] = util.next_interval_date(feed['info_data']['broadcast_date'])
            feed['info_data']['next_deadline'] = util.next_interval_date(feed['info_data']['deadline'])
        result = feed
        result['counters'] = get_feed_counters(feed['source'])
    
    if 'counters' not in result:
        params = {
            'filters': {
                'field': 'source',
                'op': '=',
                'value': address_or_url
            },
            'order_by': 'tx_index',
            'order_dir': 'DESC',
            'limit': 10
        }
        broadcasts = util.call_jsonrpc_api('get_broadcasts', params)['result']
        if broadcasts:
            return {
                'broadcasts': broadcasts,
                'counters': get_feed_counters(address_or_url)
            }
    return result
示例#12
0
    def proxy_to_counterpartyd(method='', params=[]):
        if method == 'sql':
            raise Exception("Invalid method")
        result = None
        cache_key = None

        if config.REDIS_ENABLE_APICACHE:  # check for a precached result and send that back instead
            assert config.REDIS_CLIENT
            cache_key = method + '||' + base64.b64encode(json.dumps(params).encode()).decode()
            #^ must use encoding (e.g. base64) since redis doesn't allow spaces in its key names
            # (also shortens the hashing key for better performance)
            result = config.REDIS_CLIENT.get(cache_key)
            if result:
                try:
                    result = json.loads(result)
                except Exception as e:
                    logging.warn("Error loading JSON from cache: %s, cached data: '%s'" % (e, result))
                    result = None  # skip from reading from cache and just make the API call

        if result is None:  # cache miss or cache disabled
            result = util.call_jsonrpc_api(method, params)
            if config.REDIS_ENABLE_APICACHE:  # cache miss
                assert config.REDIS_CLIENT
                config.REDIS_CLIENT.setex(cache_key, DEFAULT_COUNTERPARTYD_API_CACHE_PERIOD, json.dumps(result))
                #^TODO: we may want to have different cache periods for different types of data

        if 'error' in result:
            if result['error'].get('data', None):
                errorMsg = result['error']['data'].get('message', result['error']['message'])
                if isinstance(errorMsg, bytes):
                    errorMsg = str(errorMsg, 'utf-8')
            else:
                errorMsg = json.dumps(result['error'])
            raise Exception(errorMsg if errorMsg is not None else "UNKNOWN")
        return result['result']
示例#13
0
def gettransaction_batch(txhash_list):
    raw_txes = util.call_jsonrpc_api("getrawtransaction_batch", {
        'txhash_list': txhash_list,
        'verbose': True,
        'skip_missing': True}, abort_on_error=True)['result']
    txes = {}
    
    for tx_hash, tx in raw_txes.iteritems():
        if tx is None:
            txes[tx_hash] = None
            continue
        
        valueOut = 0
        for vout in tx['vout']:
            valueOut += vout['value']
        txes[tx_hash] = {
            'txid': tx_hash,
            'version': tx['version'],
            'locktime': tx['locktime'],
            'confirmations': tx['confirmations'] if 'confirmations' in tx else 0,
            'blocktime': tx['blocktime'] if 'blocktime' in tx else 0,
            'blockhash': tx['blockhash'] if 'blockhash' in tx else 0,
            'time': tx['time'] if 'time' in tx else 0,
            'valueOut': valueOut,
            'vin': tx['vin'],
            'vout': tx['vout']
        }
    return txes
示例#14
0
    def proxy_to_counterpartyd(method='', params=[]):
        if method == 'sql':
            raise Exception("Invalid method")
        result = None
        cache_key = None

        if config.REDIS_ENABLE_APICACHE:  # check for a precached result and send that back instead
            assert config.REDIS_CLIENT
            cache_key = method + '||' + base64.b64encode(json.dumps(params).encode()).decode()
            #^ must use encoding (e.g. base64) since redis doesn't allow spaces in its key names
            # (also shortens the hashing key for better performance)
            result = config.REDIS_CLIENT.get(cache_key)
            if result:
                try:
                    result = json.loads(result)
                except Exception as e:
                    logging.warn("Error loading JSON from cache: %s, cached data: '%s'" % (e, result))
                    result = None  # skip from reading from cache and just make the API call

        if result is None:  # cache miss or cache disabled
            result = util.call_jsonrpc_api(method, params)
            if config.REDIS_ENABLE_APICACHE:  # cache miss
                assert config.REDIS_CLIENT
                config.REDIS_CLIENT.setex(cache_key, DEFAULT_COUNTERPARTYD_API_CACHE_PERIOD, json.dumps(result))
                #^TODO: we may want to have different cache periods for different types of data

        if 'error' in result:
            if result['error'].get('data', None):
                errorMsg = result['error']['data'].get('message', result['error']['message'])
                if isinstance(errorMsg, bytes):
                    errorMsg = str(errorMsg, 'utf-8')
            else:
                errorMsg = json.dumps(result['error'])
            raise Exception(errorMsg if errorMsg is not None else "UNKNOWN")
        return result['result']
示例#15
0
    def cached_function(*args, **kwargs):

        function_signature = hashlib.sha256(func.__name__ + str(args) +
                                            str(kwargs)).hexdigest()

        sql = "SELECT block_index FROM blocks ORDER BY block_index DESC LIMIT 1"
        block_index = util.call_jsonrpc_api('sql', {
            'query': sql,
            'bindings': []
        })['result'][0]['block_index']

        cached_result = config.mongo_db.counterblockd_cache.find_one({
            'block_index':
            block_index,
            'function':
            function_signature
        })

        if not cached_result or config.TESTNET:
            #logger.info("generate cache ({}, {}, {})".format(func.__name__, block_index, function_signature))
            try:
                result = func(*args, **kwargs)
                config.mongo_db.counterblockd_cache.insert({
                    'block_index':
                    block_index,
                    'function':
                    function_signature,
                    'result':
                    json.dumps(result)
                })
                return result
            except Exception, e:
                logger.exception(e)
示例#16
0
def gettransaction_batch(txhash_list):
    raw_txes = util.call_jsonrpc_api("getrawtransaction_batch", {
        'txhash_list': txhash_list,
        'verbose': True,
        'skip_missing': True
    },
                                     abort_on_error=True)['result']
    txes = {}

    for tx_hash, tx in raw_txes.iteritems():
        if tx is None:
            txes[tx_hash] = None
            continue

        valueOut = 0
        for vout in tx['vout']:
            valueOut += vout['value']
        txes[tx_hash] = {
            'txid': tx_hash,
            'version': tx['version'],
            'locktime': tx['locktime'],
            'confirmations':
            tx['confirmations'] if 'confirmations' in tx else 0,
            'blocktime': tx['blocktime'] if 'blocktime' in tx else 0,
            'blockhash': tx['blockhash'] if 'blockhash' in tx else 0,
            'time': tx['time'] if 'time' in tx else 0,
            'valueOut': valueOut,
            'vin': tx['vin'],
            'vout': tx['vout']
        }
    return txes
示例#17
0
def get_feed_counters(feed_address):
    counters = {}
    sql = 'SELECT COUNT(*) AS bet_count, SUM(wager_quantity) AS wager_quantity, SUM(wager_remaining) AS wager_remaining, status FROM bets '
    sql += 'WHERE feed_address=? GROUP BY status ORDER BY status DESC'
    bindings = [feed_address]
    params = {'query': sql, 'bindings': bindings}
    counters['bets'] = util.call_jsonrpc_api('sql', params)['result']
    return counters
示例#18
0
 def get_messagefeed_messages_by_index(message_indexes):
     msgs = util.call_jsonrpc_api("get_messages_by_index",
                                  {'message_indexes': message_indexes},
                                  abort_on_error=True)['result']
     events = []
     for m in msgs:
         events.append(messages.decorate_message_for_feed(m))
     return events
示例#19
0
def get_feed_counters(feed_address):
    counters = {}
    sql = "SELECT COUNT(*) AS bet_count, SUM(wager_quantity) AS wager_quantity, SUM(wager_remaining) AS wager_remaining, status FROM bets "
    sql += "WHERE feed_address=? GROUP BY status ORDER BY status DESC"
    bindings = [feed_address]
    params = {"query": sql, "bindings": bindings}
    counters["bets"] = util.call_jsonrpc_api("sql", params)["result"]
    return counters
示例#20
0
def get_normalized_balances(addresses):
    """
    This call augments counterparty's get_balances with a normalized_quantity field. It also will include any owned
    assets for an address, even if their balance is zero.
    NOTE: Does not retrieve BTC balance. Use get_address_info for that.
    """
    if not isinstance(addresses, list):
        raise Exception("addresses must be a list of addresses, even if it just contains one address")
    if not len(addresses):
        raise Exception("Invalid address list supplied")

    filters = []
    for address in addresses:
        filters.append({'field': 'address', 'op': '==', 'value': address})

    mappings = {}
    result = util.call_jsonrpc_api(
        "get_balances",
        {'filters': filters, 'filterop': 'or'}, abort_on_error=True)['result']

    isowner = {}
    owned_assets = config.mongo_db.tracked_assets.find(
        {'$or': [{'owner': a} for a in addresses]}, {'_history': 0, '_id': 0})
    for o in owned_assets:
        isowner[o['owner'] + o['asset']] = o

    data = []
    for d in result:
        if not d['quantity'] and ((d['address'] + d['asset']) not in isowner):
            continue  # don't include balances with a zero asset value
        asset_info = config.mongo_db.tracked_assets.find_one({'asset': d['asset']})
        divisible = True  # XCP and BTC
        if asset_info and 'divisible' in asset_info:
            divisible = asset_info['divisible']
        d['normalized_quantity'] = blockchain.normalize_quantity(d['quantity'], divisible)
        d['owner'] = (d['address'] + d['asset']) in isowner

        try:
            d['asset_longname'] = asset_info['asset_longname']
        except TypeError as e:
            d['asset_longname'] = d['asset']

        mappings[d['address'] + d['asset']] = d
        data.append(d)

    # include any owned assets for each address, even if their balance is zero
    for key in isowner:
        if key not in mappings:
            o = isowner[key]
            data.append({
                'address': o['owner'],
                'asset': o['asset'],
                'quantity': 0,
                'normalized_quantity': 0,
                'owner': True,
            })

    return data
示例#21
0
def get_unspent_txouts(source, return_confirmed=False):
    """returns a list of unspent outputs for a specific address
    @return: A list of dicts, with each entry in the dict having the following keys:
    """
    txouts = util.call_jsonrpc_api("get_unspent_txouts", {'address': source, 'unconfirmed': True}, abort_on_error=True)['result']
    if return_confirmed:
        return txouts, [output for output in txouts if output['confirmations'] > 0]
    else:
        return txouts
示例#22
0
 def get_last_n_messages(count=100):
     if count > 1000:
         raise Exception("The count is too damn high")
     message_indexes = list(range(max(config.state['last_message_index'] - count, 0) + 1, config.state['last_message_index'] + 1))
     msgs = util.call_jsonrpc_api(
         "get_messages_by_index", {'message_indexes': message_indexes}, abort_on_error=True)['result']
     for i in range(len(msgs)):
         msgs[i] = messages.decorate_message_for_feed(msgs[i])
     return msgs
示例#23
0
 def get_last_n_messages(count=100):
     if count > 1000:
         raise Exception("The count is too damn high")
     message_indexes = range(max(config.state['last_message_index'] - count, 0) + 1, config.state['last_message_index'] + 1)
     msgs = util.call_jsonrpc_api("get_messages_by_index",
         { 'message_indexes': message_indexes }, abort_on_error=True)['result']
     for i in xrange(len(msgs)):
         msgs[i] = messages.decorate_message_for_feed(msgs[i])
     return msgs
示例#24
0
def convert_armory_signedtx_to_raw_hex(signed_tx_ascii):
    endpoint = "http://127.0.0.1:%s/" % (ARMORY_UTXSVR_PORT_MAINNET
                                         if not config.TESTNET else
                                         ARMORY_UTXSVR_PORT_TESTNET)
    params = {'signed_tx_ascii': signed_tx_ascii}
    raw_tx_hex = util.call_jsonrpc_api("convert_signed_tx_to_raw_hex",
                                       params=params,
                                       endpoint=endpoint,
                                       abort_on_error=True)['result']
    return raw_tx_hex
def create_armory_utx(unsigned_tx_hex, public_key_hex):
    endpoint = "http://%s:%s/" % (
        module_config["ARMORY_UTXSVR_HOST"],
        ARMORY_UTXSVR_PORT_MAINNET if not config.TESTNET else ARMORY_UTXSVR_PORT_TESTNET,
    )
    params = {"unsigned_tx_hex": unsigned_tx_hex, "public_key_hex": public_key_hex}
    utx_ascii = util.call_jsonrpc_api("serialize_unsigned_tx", params=params, endpoint=endpoint, abort_on_error=True)[
        "result"
    ]
    return utx_ascii
示例#26
0
def create_armory_utx(unsigned_tx_hex, public_key_hex):
    port = ARMORY_UTXSVR_PORT_MAINNET
    if config.TESTNET:
        port = ARMORY_UTXSVR_PORT_TESTNET
    elif config.REGTEST:
        port = ARMORY_UTXSVR_PORT_REGTEST
    endpoint = "http://%s:%s/" % (module_config['ARMORY_UTXSVR_HOST'], port)
    params = {'unsigned_tx_hex': unsigned_tx_hex, 'public_key_hex': public_key_hex}
    utx_ascii = util.call_jsonrpc_api("serialize_unsigned_tx", params=params, endpoint=endpoint, abort_on_error=True)['result']
    return utx_ascii
def convert_armory_signedtx_to_raw_hex(signed_tx_ascii):
    endpoint = "http://%s:%s/" % (
        module_config["ARMORY_UTXSVR_HOST"],
        ARMORY_UTXSVR_PORT_MAINNET if not config.TESTNET else ARMORY_UTXSVR_PORT_TESTNET,
    )
    params = {"signed_tx_ascii": signed_tx_ascii}
    raw_tx_hex = util.call_jsonrpc_api(
        "convert_signed_tx_to_raw_hex", params=params, endpoint=endpoint, abort_on_error=True
    )["result"]
    return raw_tx_hex
示例#28
0
def convert_armory_signedtx_to_raw_hex(signed_tx_ascii):
    port = ARMORY_UTXSVR_PORT_MAINNET
    if config.TESTNET:
        port = ARMORY_UTXSVR_PORT_TESTNET
    elif config.REGTEST:
        port = ARMORY_UTXSVR_PORT_REGTEST
    endpoint = "http://%s:%s/" % (module_config['ARMORY_UTXSVR_HOST'], port)
    params = {'signed_tx_ascii': signed_tx_ascii}
    raw_tx_hex = util.call_jsonrpc_api("convert_signed_tx_to_raw_hex", params=params, endpoint=endpoint, abort_on_error=True)['result']
    return raw_tx_hex
示例#29
0
def get_feed_counters(feed_address):
    counters = {}        
    sql  = 'SELECT COUNT(*) AS bet_count, SUM(wager_quantity) AS wager_quantity, SUM(wager_remaining) AS wager_remaining, status FROM bets '
    sql += 'WHERE feed_address=? GROUP BY status ORDER BY status DESC'
    bindings = [feed_address] 
    params = {
        'query': sql,
        'bindings': bindings
    }       
    counters['bets'] = util.call_jsonrpc_api('sql', params)['result']
    return counters;
示例#30
0
def get_block_info(block_index, prefetch=0):
    global blockinfo_cache
    if block_index in blockinfo_cache:
        return blockinfo_cache[block_index]
    blockinfo_cache.clear()
    blocks = util.call_jsonrpc_api(
        "get_blocks", {"block_indexes": range(block_index, block_index + prefetch)}, abort_on_error=True
    )["result"]
    for block in blocks:
        blockinfo_cache[block["block_index"]] = block
    return blockinfo_cache[block_index]
示例#31
0
def get_block_info(block_index, prefetch=0):
    global blockinfo_cache
    if block_index in blockinfo_cache:
        return blockinfo_cache[block_index]
    blockinfo_cache.clear()
    blocks = util.call_jsonrpc_api(
        'get_blocks',
        {'block_indexes': range(block_index, block_index + prefetch)},
        abort_on_error=True)['result']
    for block in blocks:
        blockinfo_cache[block['block_index']] = block
    return blockinfo_cache[block_index]
示例#32
0
def get_normalized_balances(addresses):
    """
    This call augments counterparty's get_balances with a normalized_quantity field. It also will include any owned
    assets for an address, even if their balance is zero. 
    NOTE: Does not retrieve BTC balance. Use get_address_info for that.
    """
    if not isinstance(addresses, list):
        raise Exception("addresses must be a list of addresses, even if it just contains one address")
    if not len(addresses):
        raise Exception("Invalid address list supplied")

    filters = []
    for address in addresses:
        filters.append({'field': 'address', 'op': '==', 'value': address})

    mappings = {}
    result = util.call_jsonrpc_api(
        "get_balances",
        {'filters': filters, 'filterop': 'or'}, abort_on_error=True)['result']

    isowner = {}
    owned_assets = config.mongo_db.tracked_assets.find(
        {'$or': [{'owner': a} for a in addresses]}, {'_history': 0, '_id': 0})
    for o in owned_assets:
        isowner[o['owner'] + o['asset']] = o

    data = []
    for d in result:
        if not d['quantity'] and ((d['address'] + d['asset']) not in isowner):
            continue  # don't include balances with a zero asset value
        asset_info = config.mongo_db.tracked_assets.find_one({'asset': d['asset']})
        divisible = True  # XCP and BTC
        if asset_info and 'divisible' in asset_info:
            divisible = asset_info['divisible']
        d['normalized_quantity'] = blockchain.normalize_quantity(d['quantity'], divisible)
        d['owner'] = (d['address'] + d['asset']) in isowner
        mappings[d['address'] + d['asset']] = d
        data.append(d)

    # include any owned assets for each address, even if their balance is zero
    for key in isowner:
        if key not in mappings:
            o = isowner[key]
            data.append({
                'address': o['owner'],
                'asset': o['asset'],
                'quantity': 0,
                'normalized_quantity': 0,
                'owner': True,
            })

    return data
示例#33
0
def get_bets(bet_type, feed_address, deadline, target_value=None, leverage=5040):
    limit = 50
    bindings = []
    sql = "SELECT * FROM bets WHERE counterwager_remaining>0 AND "
    sql += "bet_type=? AND feed_address=? AND leverage=? AND deadline=? "
    bindings += [bet_type, feed_address, leverage, deadline]
    if target_value != None:
        sql += "AND target_value=? "
        bindings.append(target_value)
    sql += "ORDER BY ((counterwager_quantity+0.0)/(wager_quantity+0.0)) ASC LIMIT ?"
    bindings.append(limit)
    params = {"query": sql, "bindings": bindings}
    return util.call_jsonrpc_api("sql", params)["result"]
示例#34
0
def create_armory_utx(unsigned_tx_hex, public_key_hex):
    endpoint = "http://127.0.0.1:%s/" % (ARMORY_UTXSVR_PORT_MAINNET
                                         if not config.TESTNET else
                                         ARMORY_UTXSVR_PORT_TESTNET)
    params = {
        'unsigned_tx_hex': unsigned_tx_hex,
        'public_key_hex': public_key_hex
    }
    utx_ascii = util.call_jsonrpc_api("serialize_unsigned_tx",
                                      params=params,
                                      endpoint=endpoint,
                                      abort_on_error=True)['result']
    return utx_ascii
示例#35
0
def get_block_info(block_index, prefetch=0, min_message_index=None):
    global blockinfo_cache
    if block_index in blockinfo_cache:
        return blockinfo_cache[block_index]
    
    blockinfo_cache.clear()
    blocks = util.call_jsonrpc_api('get_blocks',
                              {'block_indexes': range(block_index, block_index + prefetch),
                               'min_message_index': min_message_index},
                              abort_on_error=True)['result']
    for block in blocks:
        blockinfo_cache[block['block_index']] = block
    return blockinfo_cache[block_index]
示例#36
0
def get_unspent_txouts(source, return_confirmed=False):
    """returns a list of unspent outputs for a specific address
    @return: A list of dicts, with each entry in the dict having the following keys:
    """
    txouts = util.call_jsonrpc_api("get_unspent_txouts", {
        'address': source,
        'unconfirmed': True
    },
                                   abort_on_error=True)['result']
    if return_confirmed:
        return txouts, [
            output for output in txouts if output['confirmations'] > 0
        ]
    else:
        return txouts
示例#37
0
def get_user_bets(addresses=[], status="open"):
    params = {
        "filters": {"field": "source", "op": "IN", "value": addresses},
        "status": status,
        "order_by": "tx_index",
        "order_dir": "DESC",
        "limit": 100,
    }
    bets = util.call_jsonrpc_api("get_bets", params)["result"]

    sources = {}
    for bet in bets:
        sources[bet["feed_address"]] = True

    return {"bets": bets, "feeds": get_feeds_by_source_addresses(list(sources.keys()))}
示例#38
0
def get_bets(bet_type, feed_address, deadline, target_value=None, leverage=5040):
    limit = 50
    bindings = []       
    sql  = 'SELECT * FROM bets WHERE counterwager_remaining>0 AND '
    sql += 'bet_type=? AND feed_address=? AND leverage=? AND deadline=? '
    bindings += [bet_type, feed_address, leverage, deadline]
    if target_value != None:
        sql += 'AND target_value=? '
        bindings.append(target_value)
    sql += 'ORDER BY ((counterwager_quantity+0.0)/(wager_quantity+0.0)) ASC LIMIT ?';
    bindings.append(limit)
    params = {
        'query': sql,
        'bindings': bindings
    }   
    return util.call_jsonrpc_api('sql', params)['result']
示例#39
0
def get_block_info(block_index, prefetch=0, min_message_index=None):
    global block_info_cache
    if block_index in block_info_cache:
        return block_info_cache[block_index]

    block_info_cache.clear()
    blocks = util.call_jsonrpc_api(
        'get_blocks', {
            'block_indexes': list(range(block_index, block_index + prefetch)),
            'min_message_index': min_message_index
        },
        abort_on_error=True,
        use_cache=False)['result']
    for block in blocks:
        block_info_cache[block['block_index']] = block
    return block_info_cache[block_index]
示例#40
0
def get_escrowed_balances(addresses):
    addresses_holder = ','.join(['?' for e in range(0, len(addresses))])

    sql = '''SELECT (source || '_' || give_asset) AS source_asset, source AS address, give_asset AS asset, SUM(give_remaining) AS quantity
            FROM orders
            WHERE source IN ({}) AND status = ? AND give_asset != ?
            GROUP BY source_asset'''.format(addresses_holder)
    bindings = addresses + ['open', config.BTC]
    results = util.call_jsonrpc_api("sql", {'query': sql, 'bindings': bindings}, abort_on_error=True)['result']

    sql = '''SELECT (tx0_address || '_' || forward_asset) AS source_asset, tx0_address AS address, forward_asset AS asset, SUM(forward_quantity) AS quantity
             FROM order_matches
             WHERE tx0_address IN ({}) AND forward_asset != ? AND status = ?
             GROUP BY source_asset'''.format(addresses_holder)
    bindings = addresses + [config.BTC, 'pending']
    results += util.call_jsonrpc_api("sql", {'query': sql, 'bindings': bindings}, abort_on_error=True)['result']

    sql = '''SELECT (tx1_address || '_' || backward_asset) AS source_asset, tx1_address AS address, backward_asset AS asset, SUM(backward_quantity) AS quantity
             FROM order_matches
             WHERE tx1_address IN ({}) AND backward_asset != ? AND status = ?
             GROUP BY source_asset'''.format(addresses_holder)
    bindings = addresses + [config.BTC, 'pending']
    results += util.call_jsonrpc_api("sql", {'query': sql, 'bindings': bindings}, abort_on_error=True)['result']

    sql = '''SELECT source AS address, '{}' AS asset, SUM(wager_remaining) AS quantity
             FROM bets
             WHERE source IN ({}) AND status = ?
             GROUP BY address'''.format(config.XCP, addresses_holder)
    bindings = addresses + ['open']
    results += util.call_jsonrpc_api("sql", {'query': sql, 'bindings': bindings}, abort_on_error=True)['result']

    sql = '''SELECT tx0_address AS address, '{}' AS asset, SUM(forward_quantity) AS quantity
             FROM bet_matches
             WHERE tx0_address IN ({}) AND status = ?
             GROUP BY address'''.format(config.XCP, addresses_holder)
    bindings = addresses + ['pending']
    results += util.call_jsonrpc_api("sql", {'query': sql, 'bindings': bindings}, abort_on_error=True)['result']

    sql = '''SELECT tx1_address AS address, '{}' AS asset, SUM(backward_quantity) AS quantity
             FROM bet_matches
             WHERE tx1_address IN ({}) AND status = ?
             GROUP BY address'''.format(config.XCP, addresses_holder)
    bindings = addresses + ['pending']
    results += util.call_jsonrpc_api("sql", {'query': sql, 'bindings': bindings}, abort_on_error=True)['result']

    escrowed_balances = {}
    for order in results:
        if order['address'] not in escrowed_balances:
            escrowed_balances[order['address']] = {}
        if order['asset'] not in escrowed_balances[order['address']]:
            escrowed_balances[order['address']][order['asset']] = 0
        escrowed_balances[order['address']][order['asset']] += order['quantity']

    return escrowed_balances
示例#41
0
def get_escrowed_balances(addresses):
    addresses_holder = ','.join(['?' for e in range(0,len(addresses))])

    sql ='''SELECT (source || '_' || give_asset) AS source_asset, source AS address, give_asset AS asset, SUM(give_remaining) AS quantity
            FROM orders
            WHERE source IN ({}) AND status = ? AND give_asset != ?
            GROUP BY source_asset'''.format(addresses_holder)
    bindings = addresses + ['open', 'BTC']
    results = util.call_jsonrpc_api("sql", {'query': sql, 'bindings': bindings}, abort_on_error=True)['result']

    sql = '''SELECT (tx0_address || '_' || forward_asset) AS source_asset, tx0_address AS address, forward_asset AS asset, SUM(forward_quantity) AS quantity
             FROM order_matches
             WHERE tx0_address IN ({}) AND forward_asset != ? AND status = ?
             GROUP BY source_asset'''.format(addresses_holder)
    bindings = addresses + ['BTC', 'pending']
    results += util.call_jsonrpc_api("sql", {'query': sql, 'bindings': bindings}, abort_on_error=True)['result']

    sql = '''SELECT (tx1_address || '_' || backward_asset) AS source_asset, tx1_address AS address, backward_asset AS asset, SUM(backward_quantity) AS quantity
             FROM order_matches
             WHERE tx1_address IN ({}) AND backward_asset != ? AND status = ?
             GROUP BY source_asset'''.format(addresses_holder)
    bindings = addresses + ['BTC', 'pending']
    results += util.call_jsonrpc_api("sql", {'query': sql, 'bindings': bindings}, abort_on_error=True)['result']

    sql = '''SELECT source AS address, '{}' AS asset, SUM(wager_remaining) AS quantity
             FROM bets
             WHERE source IN ({}) AND status = ?
             GROUP BY address'''.format(config.XCP, addresses_holder)
    bindings = addresses + ['open']
    results += util.call_jsonrpc_api("sql", {'query': sql, 'bindings': bindings}, abort_on_error=True)['result']

    sql = '''SELECT tx0_address AS address, '{}' AS asset, SUM(forward_quantity) AS quantity
             FROM bet_matches
             WHERE tx0_address IN ({}) AND status = ?
             GROUP BY address'''.format(config.XCP, addresses_holder)
    bindings = addresses + ['pending']
    results += util.call_jsonrpc_api("sql", {'query': sql, 'bindings': bindings}, abort_on_error=True)['result']

    sql = '''SELECT tx1_address AS address, '{}' AS asset, SUM(backward_quantity) AS quantity
             FROM bet_matches
             WHERE tx1_address IN ({}) AND status = ?
             GROUP BY address'''.format(config.XCP, addresses_holder)
    bindings = addresses + ['pending']
    results += util.call_jsonrpc_api("sql", {'query': sql, 'bindings': bindings}, abort_on_error=True)['result']

    escrowed_balances = {}
    for order in results:
        if order['address'] not in escrowed_balances:
            escrowed_balances[order['address']] = {}
        if order['asset'] not in escrowed_balances[order['address']]:
            escrowed_balances[order['address']][order['asset']] = 0
        escrowed_balances[order['address']][order['asset']] += order['quantity']

    return escrowed_balances
示例#42
0
    def proxy_to_counterpartyd(method='', params=[]):
        if method == 'sql':
            raise Exception("Invalid method")
        result = None
        cache_key = None

        result = util.call_jsonrpc_api(method, params)

        if 'error' in result:
            if result['error'].get('data', None):
                errorMsg = result['error']['data'].get('message', result['error']['message'])
                if isinstance(errorMsg, bytes):
                    errorMsg = str(errorMsg, 'utf-8')
            else:
                errorMsg = json.dumps(result['error'])
            raise Exception(errorMsg if errorMsg is not None else "UNKNOWN")
        return result['result']
示例#43
0
def get_assets_info(assetsList):
    assets = assetsList  # TODO: change the parameter name at some point in the future...shouldn't be using camel case here
    if not isinstance(assets, list):
        raise Exception(
            "assets must be a list of asset names, even if it just contains one entry"
        )
    assets_info = []
    for asset in assets:
        # BTC and XCP.
        if asset in [config.BTC, config.XCP]:
            if asset == config.BTC:
                supply = blockchain.get_btc_supply(self.proxy, normalize=False)
            else:
                supply = util.call_jsonrpc_api("get_supply",
                                               {'asset': config.XCP},
                                               abort_on_error=True)['result']

            assets_info.append({
                'asset': asset,
                'owner': None,
                'divisible': True,
                'locked': False,
                'supply': supply,
                'description': '',
                'issuer': None
            })
            continue

        # User-created asset.
        tracked_asset = config.mongo_db.tracked_assets.find_one(
            {'asset': asset}, {
                '_id': 0,
                '_history': 0
            })
        if not tracked_asset:
            continue  # asset not found, most likely
        assets_info.append({
            'asset': asset,
            'owner': tracked_asset['owner'],
            'divisible': tracked_asset['divisible'],
            'locked': tracked_asset['locked'],
            'supply': tracked_asset['total_issued'],
            'description': tracked_asset['description'],
            'issuer': tracked_asset['owner']
        })
    return assets_info
示例#44
0
def get_market_orders(asset1, asset2, addresses=[], supplies=None, min_fee_provided=0.95, max_fee_required=0.95):

    base_asset, quote_asset = util.assets_to_asset_pair(asset1, asset2)
    if not supplies:
        supplies = get_assets_supply([asset1, asset2])

    market_orders = []
    buy_orders = []
    sell_orders = []

    sql = '''SELECT orders.*, blocks.block_time FROM orders INNER JOIN blocks ON orders.block_index=blocks.block_index 
             WHERE  status = ? '''
    bindings = ['open']

    if len(addresses) > 0:
        sql += '''AND source IN ({}) '''.format(','.join(['?' for e in range(0,len(addresses))]))
        bindings += addresses

    sql += '''AND give_remaining > 0 
              AND give_asset IN (?, ?) 
              AND get_asset IN (?, ?) 
              ORDER BY tx_index DESC'''

    bindings +=  [asset1, asset2, asset1, asset2]

    orders = util.call_jsonrpc_api('sql', {'query': sql, 'bindings': bindings})['result']

    for order in orders:
        market_order = {}

        exclude = False
        if order['give_asset'] == 'BTC':
            try:
                fee_provided = order['fee_provided'] / (order['give_quantity'] / 100)
                market_order['fee_provided'] = format(D(order['fee_provided']) / (D(order['give_quantity']) / D(100)), '.2f') 
            except Exception, e:
                fee_provided = min_fee_provided - 1 # exclude
            
            exclude = fee_provided < min_fee_provided

        elif order['get_asset'] == 'BTC':
            try:
                fee_required = order['fee_required'] / (order['get_quantity'] / 100)
                market_order['fee_required'] = format(D(order['fee_required']) / (D(order['get_quantity']) / D(100)), '.2f')
            except Exception, e:
                fee_required = max_fee_required + 1 # exclude    
示例#45
0
def find_user_bets(db, addresses, status='open'):
    params = {
        'filters': {
            'field': 'source',
            'op': 'IN',
            'value': addresses
        },
        'status': status,
        'order_by': 'tx_index',
        'order_dir': 'DESC',
        'limit': 100
    }
    bets = util.call_jsonrpc_api('get_bets', params)['result']

    sources = {}
    for bet in bets:
        sources[bet['feed_address']] = True

    return {'bets': bets, 'feeds': get_feeds_by_source(db, sources.keys())}
示例#46
0
    def cached_function(*args, **kwargs):
        sql = "SELECT block_index FROM blocks ORDER BY block_index DESC LIMIT 1"
        block_index = util.call_jsonrpc_api('sql', {'query': sql, 'bindings': []})['result'][0]['block_index']
        function_signature = hashlib.sha256(func.__name__ + str(args) + str(kwargs)).hexdigest()

        cached_result = config.mongo_db.counterblockd_cache.find_one({'block_index': block_index, 'function': function_signature})

        if not cached_result or config.TESTNET:
            #logger.info("generate cache ({}, {}, {})".format(func.__name__, block_index, function_signature))
            try:
                result = func(*args, **kwargs)
                config.mongo_db.counterblockd_cache.insert({
                    'block_index': block_index, 
                    'function': function_signature,
                    'result': json.dumps(result)
                })
                return result
            except Exception, e:
                logger.exception(e)
示例#47
0
    def cached_function(*args, **kwargs):

        function_signature = hashlib.sha256(func.__name__ + str(args) + str(kwargs)).hexdigest()

        sql = "SELECT block_index FROM blocks ORDER BY block_index DESC LIMIT 1"
        block_index = util.call_jsonrpc_api("sql", {"query": sql, "bindings": []})["result"][0]["block_index"]

        cached_result = config.mongo_db.counterblockd_cache.find_one(
            {"block_index": block_index, "function": function_signature}
        )

        if not cached_result or config.TESTNET:
            # logger.info("generate cache ({}, {}, {})".format(func.__name__, block_index, function_signature))
            try:
                result = func(*args, **kwargs)
                config.mongo_db.counterblockd_cache.insert(
                    {"block_index": block_index, "function": function_signature, "result": json.dumps(result)}
                )
                return result
            except Exception, e:
                logger.exception(e)
示例#48
0
def get_pair_price(base_asset, quote_asset, max_block_time=None, supplies=None):

    if not supplies:
        supplies = get_assets_supply([base_asset, quote_asset])

    sql = '''SELECT *, MAX(tx0_index, tx1_index) AS tx_index, blocks.block_time 
             FROM order_matches INNER JOIN blocks ON order_matches.block_index = blocks.block_index
             WHERE 
                forward_asset IN (?, ?) AND
                backward_asset IN (?, ?) '''
    bindings = [base_asset, quote_asset, base_asset, quote_asset]

    if max_block_time:
        sql += '''AND block_time <= ? '''
        bindings += [max_block_time]

    sql += '''ORDER BY tx_index DESC
             LIMIT 2'''
    
    order_matches = util.call_jsonrpc_api('sql', {'query': sql, 'bindings': bindings})['result']

    if len(order_matches) == 0:
        last_price = D(0.0)
    elif order_matches[0]['forward_asset'] == base_asset:
        last_price = calculate_price(order_matches[0]['forward_quantity'], order_matches[0]['backward_quantity'], supplies[order_matches[0]['forward_asset']][1], supplies[order_matches[0]['backward_asset']][1])
    else:
        last_price = calculate_price(order_matches[0]['backward_quantity'], order_matches[0]['forward_quantity'], supplies[order_matches[0]['backward_asset']][1], supplies[order_matches[0]['forward_asset']][1])

    trend = 0
    if len(order_matches) == 2:
        if order_matches[1]['forward_asset'] == base_asset:
            before_last_price = calculate_price(order_matches[0]['forward_quantity'], order_matches[0]['backward_quantity'], supplies[order_matches[0]['forward_asset']][1], supplies[order_matches[0]['backward_asset']][1])
        else:
            before_last_price = calculate_price(order_matches[0]['backward_quantity'], order_matches[0]['forward_quantity'], supplies[order_matches[0]['backward_asset']][1], supplies[order_matches[0]['forward_asset']][1])
        if last_price < before_last_price:
            trend = -1
        elif last_price > before_last_price:
            trend = 1

    return D(last_price), trend
示例#49
0
def get_pair_price(base_asset, quote_asset, max_block_time=None, supplies=None):

    if not supplies:
        supplies = get_assets_supply([base_asset, quote_asset])

    sql = '''SELECT *, MAX(tx0_index, tx1_index) AS tx_index, blocks.block_time 
             FROM order_matches INNER JOIN blocks ON order_matches.block_index = blocks.block_index
             WHERE 
                forward_asset IN (?, ?) AND
                backward_asset IN (?, ?) '''
    bindings = [base_asset, quote_asset, base_asset, quote_asset]

    if max_block_time:
        sql += '''AND block_time <= ? '''
        bindings += [max_block_time]

    sql += '''ORDER BY tx_index DESC
             LIMIT 2'''

    order_matches = util.call_jsonrpc_api('sql', {'query': sql, 'bindings': bindings})['result']

    if len(order_matches) == 0:
        last_price = D(0.0)
    elif order_matches[0]['forward_asset'] == base_asset:
        last_price = calculate_price(order_matches[0]['forward_quantity'], order_matches[0]['backward_quantity'], supplies[order_matches[0]['forward_asset']][1], supplies[order_matches[0]['backward_asset']][1])
    else:
        last_price = calculate_price(order_matches[0]['backward_quantity'], order_matches[0]['forward_quantity'], supplies[order_matches[0]['backward_asset']][1], supplies[order_matches[0]['forward_asset']][1])

    trend = 0
    if len(order_matches) == 2:
        if order_matches[1]['forward_asset'] == base_asset:
            before_last_price = calculate_price(order_matches[0]['forward_quantity'], order_matches[0]['backward_quantity'], supplies[order_matches[0]['forward_asset']][1], supplies[order_matches[0]['backward_asset']][1])
        else:
            before_last_price = calculate_price(order_matches[0]['backward_quantity'], order_matches[0]['forward_quantity'], supplies[order_matches[0]['backward_asset']][1], supplies[order_matches[0]['forward_asset']][1])
        if last_price < before_last_price:
            trend = -1
        elif last_price > before_last_price:
            trend = 1

    return D(last_price), trend
示例#50
0
def get_user_bets(addresses = [], status="open"):
    params = {
        'filters': {
            'field': 'source',
            'op': 'IN',
            'value': addresses
        },
        'status': status,
        'order_by': 'tx_index',
        'order_dir': 'DESC',
        'limit': 100
    }
    bets = util.call_jsonrpc_api('get_bets', params)['result']

    sources = {}
    for bet in bets:
        sources[bet['feed_address']] = True
    
    return {
        'bets': bets,
        'feeds': get_feeds_by_source_addresses(sources.keys())
    }
示例#51
0
def get_assets_info(assetsList):
    assets = assetsList #TODO: change the parameter name at some point in the future...shouldn't be using camel case here
    if not isinstance(assets, list):
        raise Exception("assets must be a list of asset names, even if it just contains one entry")
    assets_info = []
    for asset in assets:
        # BTC and XCP.
        if asset in [config.BTC, config.XCP]:
            if asset == config.BTC:
                supply = blockchain.get_btc_supply(self.proxy, normalize=False)
            else:
                supply = util.call_jsonrpc_api("get_supply", {'asset': 'XCP'}, abort_on_error=True)['result']

            assets_info.append({
                'asset': asset,
                'owner': None,
                'divisible': True,
                'locked': False,
                'supply': supply,
                'description': '',
                'issuer': None
            })
            continue

        # User-created asset.
        tracked_asset = config.mongo_db.tracked_assets.find_one({'asset': asset}, {'_id': 0, '_history': 0})
        if not tracked_asset:
            continue #asset not found, most likely
        assets_info.append({
            'asset': asset,
            'owner': tracked_asset['owner'],
            'divisible': tracked_asset['divisible'],
            'locked': tracked_asset['locked'],
            'supply': tracked_asset['total_issued'],
            'description': tracked_asset['description'],
            'issuer': tracked_asset['owner']})
    return assets_info
示例#52
0
def get_feed(address_or_url=""):
    conditions = {"$or": [{"source": address_or_url}, {"info_url": address_or_url}], "info_status": "valid"}
    result = {}
    feeds = config.mongo_db.feeds.find(conditions, projection={"_id": False}, limit=1)
    for feed in feeds:
        if "targets" not in feed["info_data"] or (
            "type" in feed["info_data"] and feed["info_data"]["type"] in ["all", "cfd"]
        ):
            feed["info_data"]["next_broadcast"] = util.next_interval_date(feed["info_data"]["broadcast_date"])
            feed["info_data"]["next_deadline"] = util.next_interval_date(feed["info_data"]["deadline"])
        result = feed
        result["counters"] = get_feed_counters(feed["source"])

    if "counters" not in result:
        params = {
            "filters": {"field": "source", "op": "=", "value": address_or_url},
            "order_by": "tx_index",
            "order_dir": "DESC",
            "limit": 10,
        }
        broadcasts = util.call_jsonrpc_api("get_broadcasts", params)["result"]
        if broadcasts:
            return {"broadcasts": broadcasts, "counters": get_feed_counters(address_or_url)}
    return result
示例#53
0
def search_raw_transactions(address, unconfirmed=True):
    return util.call_jsonrpc_api("search_raw_transactions", {'address': address, 'unconfirmed': unconfirmed}, abort_on_error=True)['result']
示例#54
0
def get_market_orders(asset1, asset2, addresses=[], supplies=None, min_fee_provided=0.95, max_fee_required=0.95):

    base_asset, quote_asset = util.assets_to_asset_pair(asset1, asset2)
    if not supplies:
        supplies = get_assets_supply([asset1, asset2])

    market_orders = []
    buy_orders = []
    sell_orders = []

    sql = '''SELECT orders.*, blocks.block_time FROM orders INNER JOIN blocks ON orders.block_index=blocks.block_index
             WHERE  status = ? '''
    bindings = ['open']

    if len(addresses) > 0:
        sql += '''AND source IN ({}) '''.format(','.join(['?' for e in range(0, len(addresses))]))
        bindings += addresses

    sql += '''AND give_remaining > 0
              AND give_asset IN (?, ?)
              AND get_asset IN (?, ?)
              ORDER BY tx_index DESC'''

    bindings += [asset1, asset2, asset1, asset2]

    orders = util.call_jsonrpc_api('sql', {'query': sql, 'bindings': bindings})['result']

    for order in orders:
        market_order = {}

        exclude = False
        if order['give_asset'] == config.BTC:
            try:
                fee_provided = order['fee_provided'] / (order['give_quantity'] / 100)
                market_order['fee_provided'] = format(D(order['fee_provided']) / (D(order['give_quantity']) / D(100)), '.2f')
            except Exception as e:
                fee_provided = min_fee_provided - 1  # exclude

            exclude = fee_provided < min_fee_provided

        elif order['get_asset'] == config.BTC:
            try:
                fee_required = order['fee_required'] / (order['get_quantity'] / 100)
                market_order['fee_required'] = format(D(order['fee_required']) / (D(order['get_quantity']) / D(100)), '.2f')
            except Exception as e:
                fee_required = max_fee_required + 1  # exclude

            exclude = fee_required > max_fee_required

        if not exclude:
            if order['give_asset'] == base_asset:
                try:
                    price = calculate_price(order['give_quantity'], order['get_quantity'], supplies[order['give_asset']][1], supplies[order['get_asset']][1], 'SELL')
                except:
                    continue
                market_order['type'] = 'SELL'
                market_order['amount'] = order['give_remaining']
                market_order['total'] = D(order['give_remaining']) * D(price)
                if not supplies[order['give_asset']][1] and supplies[order['get_asset']][1]:
                    market_order['total'] = int(market_order['total'] * config.UNIT)
                elif supplies[order['give_asset']][1] and not supplies[order['get_asset']][1]:
                    market_order['total'] = int(market_order['total'] / config.UNIT)
                else:
                    market_order['total'] = int(market_order['total'])
            else:
                try:
                    price = calculate_price(order['get_quantity'], order['give_quantity'], supplies[order['get_asset']][1], supplies[order['give_asset']][1], 'BUY')
                except:
                    continue
                market_order['type'] = 'BUY'
                market_order['total'] = order['give_remaining']
                market_order['amount'] = D(order['give_remaining']) / D(price)
                if supplies[order['give_asset']][1] and not supplies[order['get_asset']][1]:
                    market_order['amount'] = int(market_order['amount'] / config.UNIT)
                elif not supplies[order['give_asset']][1] and supplies[order['get_asset']][1]:
                    market_order['amount'] = int(market_order['amount'] * config.UNIT)
                else:
                    market_order['amount'] = int(market_order['amount'])

            market_order['price'] = price

            if len(addresses) > 0:
                completed = format(((D(order['give_quantity']) - D(order['give_remaining'])) / D(order['give_quantity'])) * D(100), '.2f')
                market_order['completion'] = "{}%".format(completed)
                market_order['tx_index'] = order['tx_index']
                market_order['tx_hash'] = order['tx_hash']
                market_order['source'] = order['source']
                market_order['block_index'] = order['block_index']
                market_order['block_time'] = order['block_time']
                market_orders.append(market_order)
            else:
                if market_order['type'] == 'SELL':
                    sell_orders.append(market_order)
                else:
                    buy_orders.append(market_order)

    if len(addresses) == 0:
        market_orders = merge_same_price_orders(sell_orders) + merge_same_price_orders(buy_orders)

    return market_orders
示例#55
0
def get_pairs(quote_asset='BITCRYSTALS', exclude_pairs=[], max_pairs=12, from_time=None):
            
    bindings = []
    
    sql = '''SELECT (CASE
                        WHEN forward_asset = ? THEN backward_asset
                        ELSE forward_asset
                    END) AS base_asset,
                    (CASE
                        WHEN backward_asset = ? THEN backward_asset
                        ELSE forward_asset
                    END) AS quote_asset,
                    (CASE
                        WHEN backward_asset = ? THEN (forward_asset || '/' || backward_asset)
                        ELSE (backward_asset || '/' || forward_asset)
                    END) AS pair,
                    (CASE
                        WHEN forward_asset = ? THEN backward_quantity
                        ELSE forward_quantity
                    END) AS bq,
                    (CASE
                        WHEN backward_asset = ? THEN backward_quantity
                        ELSE forward_quantity
                    END) AS qq '''
    if from_time:
        sql += ''', block_time '''

    sql += '''FROM order_matches '''
    bindings += [quote_asset, quote_asset, quote_asset, quote_asset, quote_asset]

    if from_time:
        sql += '''INNER JOIN blocks ON order_matches.block_index = blocks.block_index '''

    priority_quote_assets = []
    for priority_quote_asset in config.QUOTE_ASSETS:
        if priority_quote_asset != quote_asset:
            priority_quote_assets.append(priority_quote_asset)
        else:
            break

    if len(priority_quote_assets) > 0:
        asset_bindings = ','.join(['?' for e in range(0,len(priority_quote_assets))])
        sql += '''WHERE ((forward_asset = ? AND backward_asset NOT IN ({})) 
                         OR (forward_asset NOT IN ({}) AND backward_asset = ?)) '''.format(asset_bindings, asset_bindings)
        bindings += [quote_asset] + priority_quote_assets + priority_quote_assets + [quote_asset]
    else:
        sql += '''WHERE ((forward_asset = ?) OR (backward_asset = ?)) '''
        bindings += [quote_asset, quote_asset]

    if len(exclude_pairs) > 0:
        sql += '''AND pair NOT IN ({}) '''.format(','.join(['?' for e in range(0,len(exclude_pairs))]))
        bindings += exclude_pairs

    if from_time:
        sql += '''AND block_time > ? '''
        bindings += [from_time]

    sql += '''AND forward_asset != backward_asset
              AND status = ?'''

    bindings += ['completed', max_pairs]

    sql = '''SELECT base_asset, quote_asset, pair, SUM(bq) AS base_quantity, SUM(qq) AS quote_quantity 
             FROM ({}) 
             GROUP BY pair 
             ORDER BY quote_quantity DESC
             LIMIT ?'''.format(sql)

    return util.call_jsonrpc_api('sql', {'query': sql, 'bindings': bindings})['result']
示例#56
0
def get_market_trades(asset1, asset2, addresses=[], limit=50, supplies=None):
    limit = min(limit, 100)
    base_asset, quote_asset = util.assets_to_asset_pair(asset1, asset2)
    if not supplies:
        supplies = get_assets_supply([asset1, asset2])
    market_trades = []

    sources = ''
    bindings = ['expired']
    if len(addresses) > 0:
        placeholder = ','.join(['?' for e in range(0,len(addresses))])
        sources = '''AND (tx0_address IN ({}) OR tx1_address IN ({}))'''.format(placeholder, placeholder)
        bindings += addresses + addresses

    sql = '''SELECT order_matches.*, blocks.block_time FROM order_matches INNER JOIN blocks ON order_matches.block_index=blocks.block_index
             WHERE status != ? {}
                AND forward_asset IN (?, ?) 
                AND backward_asset IN (?, ?) 
             ORDER BY block_index DESC
             LIMIT ?'''.format(sources)

    bindings +=  [asset1, asset2, asset1, asset2, limit]

    order_matches = util.call_jsonrpc_api('sql', {'query': sql, 'bindings': bindings})['result']

    for order_match in order_matches:

        if order_match['tx0_address'] in addresses:
            trade = {}
            trade['match_id'] = order_match['id']
            trade['source'] = order_match['tx0_address']
            trade['countersource'] = order_match['tx1_address']
            trade['block_index'] = order_match['block_index']
            trade['block_time'] = order_match['block_time']
            trade['status'] = order_match['status']
            if order_match['forward_asset'] == base_asset:
                trade['type'] = 'SELL'
                trade['price'] = calculate_price(order_match['forward_quantity'], order_match['backward_quantity'], supplies[order_match['forward_asset']][1], supplies[order_match['backward_asset']][1], 'SELL')
                trade['amount'] = order_match['forward_quantity']
                trade['total'] = order_match['backward_quantity']
            else:
                trade['type'] = 'BUY'
                trade['price'] = calculate_price(order_match['backward_quantity'], order_match['forward_quantity'], supplies[order_match['backward_asset']][1], supplies[order_match['forward_asset']][1], 'BUY')
                trade['amount'] = order_match['backward_quantity']
                trade['total'] = order_match['forward_quantity']
            market_trades.append(trade)

        if len(addresses)==0 or order_match['tx1_address'] in addresses:
            trade = {}
            trade['match_id'] = order_match['id']
            trade['source'] = order_match['tx1_address']
            trade['countersource'] = order_match['tx0_address']
            trade['block_index'] = order_match['block_index']
            trade['block_time'] = order_match['block_time']
            trade['status'] = order_match['status']
            if order_match['backward_asset'] == base_asset:
                trade['type'] = 'SELL'
                trade['price'] = calculate_price(order_match['backward_quantity'], order_match['forward_quantity'], supplies[order_match['backward_asset']][1], supplies[order_match['forward_asset']][1], 'SELL')
                trade['amount'] = order_match['backward_quantity']
                trade['total'] = order_match['forward_quantity']
            else:
                trade['type'] = 'BUY'
                trade['price'] = calculate_price(order_match['forward_quantity'], order_match['backward_quantity'], supplies[order_match['forward_asset']][1], supplies[order_match['backward_asset']][1], 'BUY')
                trade['amount'] = order_match['forward_quantity']
                trade['total'] = order_match['backward_quantity']
            market_trades.append(trade)

    return market_trades