def get_view(view_name, args):
    if view_name == 'balances':
        return wallet.balances(args.address)
    elif view_name == 'asset':
        return wallet.asset(args.asset)
    elif view_name == 'wallet':
        return wallet.wallet()
    elif view_name == 'pending':
        return wallet.pending()
    elif view_name == 'getinfo':
        return util.api('get_running_info')
    elif view_name == 'getrows':
        method = 'get_{}'.format(args.table)
        if args.filter:
            filters = [tuple(f) for f in args.filter]
        else:
            filters = []
        params = {
            'filters': filters,
            'filterop': args.filter_op,
            'order_by': args.order_by,
            'order_dir': args.order_dir,
            'start_block': args.start_block,
            'end_block': args.end_block,
            'status': args.status,
            'limit': args.limit,
            'offset': args.offset
        }
        return util.api(method, params)
def wallet():
    wallet = {
        'addresses': {},
        'assets': {}
    }

    def add_total(address, asset, quantity):
        if quantity:
            if address not in wallet['addresses']:
                wallet['addresses'][address] = {}
            if asset not in wallet['assets']:
                wallet['assets'][asset]  = 0
            if asset not in wallet['addresses'][address]:
                wallet['addresses'][address][asset] = 0
            wallet['addresses'][address][asset] += quantity
            wallet['assets'][asset]  += quantity

    for bunch in get_shell_balances():
        address, shell_balance = bunch
        add_total(address, 'SCH', shell_balance)
        balances = api('get_balances', {'filters': [('address', '==', address),]})
        for balance in balances:
            asset = balance['asset']
            balance = D(value_out(balance['quantity'], asset))
            add_total(address, asset, balance)

    return wallet
def call(method, args, pubkey_resolver=None):
    """
        Unified function to call Wallet and Server API methods
        Should be used by applications like `shellparty-gui`

        :Example:

        import shellpartycli.clientapi
        clientapi.initialize(...)
        unsigned_hex = clientapi.call('create_send', {...}) 
        signed_hex =  clientapi.call('sign_raw_transaction', unsigned_hex)
        tx_hash = clientapi.call('send_raw_transaction', signed_hex)
    """
    if method in WALLET_METHODS:
        func = getattr(wallet, method)
        return func(**args)
    else:
        if method.startswith('create_'):
            # Get provided pubkeys from params.
            pubkeys = []
            for address_name in ['source', 'destination']:
                if address_name in args:
                    address = args[address_name]
                    if script.is_multisig(address) or address_name != 'destination':    # We don’t need the pubkey for a mono‐sig destination.
                        pubkeys += get_pubkeys(address, pubkey_resolver=pubkey_resolver)
            args['pubkey'] = pubkeys

        result = util.api(method, args)

        if method.startswith('create_'):
            messages.check_transaction(method, args, result)

        return result
def pending():
    addresses = []
    for bunch in get_shell_balances():
        addresses.append(bunch[0])
    filters = [
        ('tx0_address', 'IN', addresses),
        ('tx1_address', 'IN', addresses)
    ]
    awaiting_shells = api('get_order_matches', {'filters': filters, 'filterop': 'OR', 'status': 'pending'})
    return awaiting_shells
def balances(address):
    result = {
        'SCH': get_shell_balance(address)
    }
    balances = api('get_balances', {'filters': [('address', '==', address),]})
    for balance in balances:
        asset = balance['asset']
        balance = D(value_out(balance['quantity'], asset))
        result[asset] =  balance
    return result
def get_pubkey_monosig(pubkeyhash, pubkey_resolver=input_pubkey):
    if wallet.is_valid(pubkeyhash):

        # If in wallet, get from wallet.
        logging.debug('Looking for public key for `{}` in wallet.'.format(pubkeyhash))
        if wallet.is_mine(pubkeyhash):
            pubkey = wallet.get_pubkey(pubkeyhash)
            if pubkey:
                return pubkey
        logging.debug('Public key for `{}` not found in wallet.'.format(pubkeyhash))

        # If in blockchain (and not in wallet), get from blockchain.
        logging.debug('Looking for public key for `{}` in blockchain.'.format(pubkeyhash))
        try:
            pubkey = util.api('search_pubkey', {'pubkeyhash': pubkeyhash, 'provided_pubkeys': None})
        except util.RPCError as e:
            pubkey = None
        if pubkey:
            return pubkey
        logging.debug('Public key for `{}` not found in blockchain.'.format(pubkeyhash))

        # If not in wallet and not in blockchain, get from user.
        answer = pubkey_resolver(pubkeyhash)
        if not answer:
            return None

        # Public Key or Private Key?
        is_fully_valid_pubkey = True
        try:
            is_fully_valid_pubkey = script.is_fully_valid(binascii.unhexlify(answer))
        except binascii.Error:
            is_fully_valid_pubkey = False
        if is_fully_valid_pubkey:
            logging.debug('Answer was a fully valid public key.')
            pubkey = answer
        else:
            logging.debug('Answer was not a fully valid public key. Assuming answer was a private key.')
            private_key = answer
            try:
                pubkey = script.private_key_to_public_key(private_key)
            except script.AltcoinSupportError:
                raise InputError('invalid private key')
        if pubkeyhash != script.pubkey_to_pubkeyhash(binascii.unhexlify(bytes(pubkey, 'utf-8'))):
            raise InputError('provided public or private key does not match the source address')

        return pubkey

    return None
def compose_transaction(args, message_name, param_names):
    args = prepare_args(args, message_name)
    common_params = common_args(args)
    params = extract_args(args, param_names)
    params.update(common_params)
    
    # Get provided pubkeys from params.
    pubkeys = []
    for address_name in ['source', 'destination']:
        if address_name in params:
            address = params[address_name]
            if script.is_multisig(address) or address_name != 'destination':    # We don’t need the pubkey for a mono‐sig destination.
                pubkeys += get_pubkeys(address)
    params['pubkey'] = pubkeys

    method = 'create_{}'.format(message_name)
    unsigned_tx_hex = util.api(method, params)
    
    # check_transaction(method, params, unsigned_tx_hex)

    return unsigned_tx_hex
def asset(asset_name):
    supply = api('get_supply', {'asset': asset_name})
    asset_id = api('get_assets', {'filters': [('asset_name', '==', asset_name),]})[0]['asset_id']
    asset_info = {
        'asset': asset_name,
        'supply': D(value_out(supply, asset_name)),
        'asset_id': asset_id
    }
    if asset_name in ['SHP', 'SCH']:
        asset_info.update({
            'owner': None,
            'divisible': True,
            'locked': False,
            'description': '',
            'issuer': None
        })
    else:
        issuances = api('get_issuances', {
            'filters': [('asset', '==', asset_name),], 
            'status': 'valid', 
            'order_by': 'tx_index', 
            'order_dir': 'DESC', 
        })
        if not issuances:
            raise WalletError('Asset not found')
        locked = False
        for issuance in issuances:
            if issuance['locked']:
                locked = True
        issuance = issuances[0]
        asset_info.update({
            'owner': issuance['issuer'],
            'divisible': bool(issuance['divisible']),
            'locked': locked,
            'description': issuance['description'],
            'issuer': issuance['issuer']
        })

    asset_info['balance'] = 0
    asset_info['addresses'] = {}

    for bunch in get_shell_balances():
        address, shell_balance = bunch
        if asset_name == 'SCH':
            balance = shell_balance
        else:
            balances = api('get_balances', {'filters': [('address', '==', address), ('asset', '==', asset_name)]})
            if balances:
                balance = balances[0]
                balance = D(value_out(balance['quantity'], asset_name))
            else:
                balance = 0
        if balance:
            asset_info['balance'] += balance
            asset_info['addresses'][address] = balance

    addresses = list(asset_info['addresses'].keys())

    if asset_name != 'SCH':
        all_sends = api('get_sends',  {'filters': [('source', 'IN', addresses), ('destination', 'IN', addresses)], 'filterop': 'OR', 'status': 'valid'})
        sends = []
        for send in all_sends:
            if send['asset'] == asset_name:
                if send['source'] in addresses and send['destination'] in addresses:
                    tx_type = 'in-wallet'
                elif send['source'] in addresses:
                    tx_type = 'send'
                elif send['destination'] in addresses:
                    tx_type = 'receive'
                send['type'] = tx_type
                send['quantity'] = D(value_out(send['quantity'], asset_name))
                sends.append(send)
        asset_info['sends'] = sends

    return asset_info