Пример #1
0
def random_address_from_sil(address, sil_block_height=0, rng_block_height=0):
    if not valid_address(address):
        return {'error': 'Invalid address: %s' % address}

    return RandomAddress(address=address,
                         sil_block_height=sil_block_height).get(
                             source='SIL', rng_block_height=rng_block_height)
Пример #2
0
    def configure(self, **config):
        super(ReceivedTrigger, self).configure(**config)
        if 'address' in config and valid_address(config['address']):
            self.address = config['address']

        if 'amount' in config and valid_amount(config['amount']):
            self.amount = config['amount']
Пример #3
0
def get_sul(address, confirmations=1):
    if not valid_address(address):
        return {'error': 'Invalid address: ' + address}

    utxos_data = data.utxos(address=address, confirmations=confirmations)
    if 'utxos' in utxos_data:
        sul = utxos_to_sul(utxos_data['utxos'])
        return {'SUL': sul} if 'error' not in sul else {'error': sul['error']}
    else:
        return {'error': 'Unable to retrieve utxos of address %s' % address}
Пример #4
0
def random_address_from_lsl(address,
                            xpub,
                            sil_block_height=0,
                            rng_block_height=0):
    if not valid_address(address):
        return {'error': 'Invalid address: %s' % address}

    if not valid_xpub(xpub):
        return {'error': 'Invalid xpub: %s' % xpub}

    return RandomAddress(address=address,
                         xpub=xpub,
                         sil_block_height=sil_block_height).get(
                             source='LSL', rng_block_height=rng_block_height)
def sign_message(**data):
    if not all(key in data for key in ['address', 'message']):
        return {
            'success':
            False,
            'error':
            'Request data does not contain all required keys: address, message'
        }

    address = data['address']
    message = data['message']

    if not valid_address(address=address):
        return {'success': False, 'error': 'Invalid address: %s' % address}

    if len(message) > 255:
        return {
            'success': False,
            'error':
            'Message is too long, can not be longer than 255 characters.'
        }

    account, index = find_address_in_wallet(address=address)
    if account is None or index is None:
        private_key = find_single_address_in_wallet(address=address)

        if private_key is None:
            return {
                'success': False,
                'error': 'Address %s not found in hot wallet' % address
            }
    else:
        private_key = get_private_key_from_wallet(account=account,
                                                  index=index)[address]

    try:
        signature = sign_and_verify(private_key=private_key,
                                    address=address,
                                    message=message)
    except Exception as ex:
        return {'success': False, 'error': 'Unable to sign message: %s' % ex}

    return {
        'success': True,
        'signature': signature,
        'address': address,
        'message': message
    }
Пример #6
0
def get_sil(address, block_height=0):
    """
    Get the Simplified Inputs List (SIL)

    :param address: The address that received the transactions
    :param block_height: A block height (optional)
    :return: A dictionary containing the SIL and the explorer that provided the data
    """
    if not valid_address(address):
        return {'error': 'Invalid address: ' + address}

    txs_data = data.transactions(address)
    if 'transactions' in txs_data:
        return {'SIL': txs_2_sil(txs_data['transactions'], block_height)}
    else:
        return {'error': 'Unable to retrieve transactions of address %s' % address}
Пример #7
0
def get_profile(address, block_height=0):
    """
    Get the profile of an address

    :param address: The address
    :param block_height: A block height (optional)
    :return: A dict containing the profile and the explorer that provided the data
    """
    if not valid_address(address):
        return {'error': 'Invalid address: ' + address}

    txs_data = data.transactions(address)
    if 'transactions' in txs_data:
        return {'profile': txs_to_profile(txs_data['transactions'], address, block_height)}
    else:
        return {'error': 'Unable to retrieve transactions of address %s' % address}
Пример #8
0
def get_lal(address, xpub, block_height=0):
    if not valid_address(address):
        return {'error': 'Invalid address: %s' % address}

    if not valid_xpub(xpub):
        return {'error': 'Invalid xpub: %s' % xpub}

    sil_data = get_sil(address, block_height)

    if 'SIL' in sil_data:
        sil = sil_data['SIL']
        linked_addresses = get_addresses_from_xpub(xpub, len(sil))

        lal = []
        for i in range(0, len(sil)):
            lal.append([sil[i][0], linked_addresses[i]])

        return {'LAL': lal}
    else:
        return {'error': 'Received invalid SIL data: %s' % sil_data}
Пример #9
0
    def __init__(self, *args, **kwargs):
        self.address = kwargs['address'] if 'address' in kwargs else None
        if self.address is not None and not valid_address(self.address):
            raise Exception('%s is not a valid address!' % self.address)

        self.message = kwargs['message'] if 'message' in kwargs else None
        self.signature = kwargs['signature'] if 'signature' in kwargs else None

        self.trigger_id = kwargs[
            'trigger_id'] if 'trigger_id' in kwargs else None
        self.trigger_type = kwargs[
            'trigger_type'] if 'trigger_type' in kwargs else None
        self.script = kwargs['script'] if 'script' in kwargs else None
        self.data = kwargs['data'] if 'data' in kwargs else None
        self.triggered = kwargs['triggered'] if 'triggered' in kwargs else None
        self.multi = kwargs['multi'] if 'multi' in kwargs else None
        self.description = kwargs[
            'description'] if 'description' in kwargs else None
        self.creator_name = kwargs[
            'creator_name'] if 'creator_name' in kwargs else None
        self.creator_email = kwargs[
            'creator_email'] if 'creator_email' in kwargs else None
        self.youtube = kwargs['youtube'] if 'youtube' in kwargs else None
        self.status = kwargs['status'] if 'status' in kwargs else None
        self.visibility = kwargs[
            'visibility'] if 'visibility' in kwargs else None
        self.created = kwargs['created'] if 'created' in kwargs else None
        self.actions = kwargs['actions'] if 'actions' in kwargs else None

        self.json = kwargs['json'] if 'json' in kwargs else None
        self.ipfs_hash = None
        self.ipfs_object = kwargs[
            'ipfs_object'] if 'ipfs_object' in kwargs else None
        self.text = None

        self.http_response = None
        self.new_actions = []

        if self.message is not None:
            self.process_message()
    def configure(self, **config):
        """
        Configure the action with given config settings

        :param config: A dict containing the configuration settings
                       - config['fee_address']               : An address to send the spellbook fee to
                       - config['fee_percentage']            : The percentage to calculate the spellbook fee
                       - config['wallet_type']               : The type of wallet (Single or BIP44)
                       - config['sending_address']           : The address that will be sending the transaction
                       - config['bip44_account']             : An account number of a BIP44 wallet
                       - config['bip44_index']               : An index number of a BIP44 account
                       - config['receiving_address']         : The address to receive the transaction
                       - config['receiving_xpub']            : The xpub key to derive the receiving addresses from
                       - config['amount']                    : The amount to send
                       - config['minimum_amount']            : The minimum amount that needs to be available
                       - config['registration_address']      : An address used for the registration of a SIL, LBL, LRL or LSL
                       - config['registration_block_height'] : An block height used for the registration of a SIL
                       - config['registration_xpub']         : An xpub key used for the registration of a LBL, LRL or LSL
                       - config['distribution']              : A dict containing a distribution (each address should be a key in the dict with the value being the share)
        """
        super(SendTransactionAction, self).configure(**config)
        if 'fee_address' in config and valid_address(config['fee_address']):
            self.fee_address = config['fee_address']

        if 'fee_percentage' in config and valid_percentage(
                config['fee_percentage']):
            self.fee_percentage = config['fee_percentage']

        if 'wallet_type' in config and config['wallet_type'] in [
                'Single', 'BIP44'
        ]:
            self.wallet_type = config['wallet_type']

        if 'sending_address' in config and valid_address(
                config['sending_address']):
            self.sending_address = config['sending_address']

        if 'bip44_account' in config:
            self.bip44_account = config['bip44_account']

        if 'bip44_index' in config:
            self.bip44_index = config['bip44_index']

        if 'receiving_address' in config and valid_address(
                config['receiving_address']):
            self.receiving_address = config['receiving_address']

        if 'receiving_xpub' in config and valid_xpub(config['receiving_xpub']):
            self.receiving_xpub = config['receiving_xpub']

        if 'amount' in config and valid_amount(config['amount']):
            self.amount = config['amount']

        if 'minimum_amount' in config and valid_amount(
                config['minimum_amount']):
            self.minimum_amount = config['minimum_amount']

        if 'op_return_data' in config and valid_op_return(
                config['op_return_data']):
            self.op_return_data = config['op_return_data']

        if 'change_address' in config and valid_address(
                config['change_address']):
            self.receiving_address = config['change_address']

        if 'transaction_type' in config and valid_transaction_type(
                config['transaction_type']):
            self.transaction_type = config['transaction_type']

        if 'minimum_output_value' in config and valid_amount(
                config['minimum_output_value']):
            self.minimum_output_value = config['minimum_output_value']

        if 'registration_address' in config and valid_address(
                config['registration_address']):
            self.registration_address = config['registration_address']

        if 'registration_block_height' in config and valid_block_height(
                config['registration_block_height']):
            self.registration_block_height = config[
                'registration_block_height']

        if 'registration_xpub' in config and valid_xpub(
                config['registration_xpub']):
            self.registration_xpub = config['registration_xpub']

        if 'distribution' in config and valid_distribution(
                config['distribution']):
            self.distribution = config['distribution']

        if 'tx_fee_type' in config and config['tx_fee_type'] in [
                'High', 'Medium', 'Low', 'Fixed'
        ]:
            self.tx_fee_type = config['tx_fee_type']

        if 'tx_fee' in config and valid_amount(
                config['tx_fee']) and self.tx_fee_type == 'Fixed':
            self.tx_fee = config['tx_fee']

        if 'utxo_confirmations' in config and valid_amount(
                config['utxo_confirmations']):
            self.utxo_confirmations = config['utxo_confirmations']

        if 'private_key' in config and valid_private_key(
                private_key=config['private_key']):
            self.private_key = config['private_key']

        # fill in the address in case of a BIP44 hot wallet
        if self.wallet_type == 'BIP44':
            self.sending_address = get_address_from_wallet(
                self.bip44_account, self.bip44_index)
    def get_distribution(self, transaction_type, sending_amount):
        if not valid_amount(sending_amount) or sending_amount == 0:
            LOG.error(
                'Unable to get distribution: invalid sending_amount: %s' %
                sending_amount)
            raise Exception(
                'Unable to get distribution: invalid sending_amount: %s' %
                sending_amount)

        if transaction_type == 'Send2Single':
            if not valid_address(self.receiving_address):
                LOG.error(
                    'Unable to get distribution: invalid receiving_address: %s'
                    % self.receiving_address)
                raise Exception(
                    'Unable to get distribution: invalid receiving_address: %s'
                    % self.receiving_address)
            distribution = {self.receiving_address: sending_amount}

        elif transaction_type == 'Send2Many':
            if not valid_distribution(self.distribution):
                LOG.error(
                    'Unable to get distribution: invalid distribution: %s' %
                    self.distribution)
                raise Exception(
                    'Unable to get distribution: invalid distribution: %s' %
                    self.distribution)
            distribution = self.distribution

        elif transaction_type == 'Send2SIL':
            if not valid_address(self.registration_address):
                LOG.error(
                    'Unable to get distribution: invalid registration_address: %s'
                    % self.registration_address)
                raise Exception(
                    'Unable to get distribution: invalid registration_address: %s'
                    % self.registration_address)
            if not valid_block_height(self.registration_block_height):
                LOG.error(
                    'Unable to get distribution: invalid registration_block_height: %s'
                    % self.registration_block_height)
                raise Exception(
                    'Unable to get distribution: invalid registration_block_height: %s'
                    % self.registration_block_height)

            data = get_sil(address=self.registration_address,
                           block_height=self.registration_block_height)
            if 'SIL' not in data:
                LOG.error('Unable to get distribution: invalid SIL data: %s' %
                          data)
                raise Exception('Unable to get distribution: invalid SIL: %s' %
                                data)
            distribution = {
                recipient[0]: recipient[1]
                for recipient in data['SIL']
            }

        elif transaction_type == 'Send2LBL':
            if not valid_address(self.registration_address):
                LOG.error(
                    'Unable to get distribution: invalid registration_address: %s'
                    % self.registration_address)
                raise Exception(
                    'Unable to get distribution: invalid registration_address: %s'
                    % self.registration_address)
            if not valid_xpub(self.registration_xpub):
                LOG.error(
                    'Unable to get distribution: invalid registration_xpub: %s'
                    % self.registration_xpub)
                raise Exception(
                    'Unable to get distribution: invalid registration_xpub: %s'
                    % self.registration_xpub)
            if not valid_block_height(self.registration_block_height):
                LOG.error(
                    'Unable to get distribution: invalid registration_block_height: %s'
                    % self.registration_block_height)
                raise Exception(
                    'Unable to get distribution: invalid registration_block_height: %s'
                    % self.registration_block_height)

            data = get_lbl(address=self.registration_address,
                           xpub=self.registration_xpub,
                           block_height=self.registration_block_height)
            if 'LBL' not in data:
                LOG.error('Unable to get distribution: invalid LBL data: %s' %
                          data)
                raise Exception('Unable to get distribution: invalid LBL: %s' %
                                data)
            distribution = {
                recipient[0]: recipient[1]
                for recipient in data['LBL']
            }

        elif transaction_type == 'Send2LRL':
            if not valid_address(self.registration_address):
                LOG.error(
                    'Unable to get distribution: invalid registration_address: %s'
                    % self.registration_address)
                raise Exception(
                    'Unable to get distribution: invalid registration_address: %s'
                    % self.registration_address)
            if not valid_xpub(self.registration_xpub):
                LOG.error(
                    'Unable to get distribution: invalid registration_xpub: %s'
                    % self.registration_xpub)
                raise Exception(
                    'Unable to get distribution: invalid registration_xpub: %s'
                    % self.registration_xpub)
            if not valid_block_height(self.registration_block_height):
                LOG.error(
                    'Unable to get distribution: invalid registration_block_height: %s'
                    % self.registration_block_height)
                raise Exception(
                    'Unable to get distribution: invalid registration_block_height: %s'
                    % self.registration_block_height)

            data = get_lrl(address=self.registration_address,
                           xpub=self.registration_xpub,
                           block_height=self.registration_block_height)
            if 'LRL' not in data:
                LOG.error('Unable to get distribution: invalid LRL data: %s' %
                          data)
                raise Exception('Unable to get distribution: invalid LRL: %s' %
                                data)
            distribution = {
                recipient[0]: recipient[1]
                for recipient in data['LRL']
            }

        elif transaction_type == 'Send2LSL':
            if not valid_address(self.registration_address):
                LOG.error(
                    'Unable to get distribution: invalid registration_address: %s'
                    % self.registration_address)
                raise Exception(
                    'Unable to get distribution: invalid registration_address: %s'
                    % self.registration_address)
            if not valid_xpub(self.registration_xpub):
                LOG.error(
                    'Unable to get distribution: invalid registration_xpub: %s'
                    % self.registration_xpub)
                raise Exception(
                    'Unable to get distribution: invalid registration_xpub: %s'
                    % self.registration_xpub)
            if not valid_block_height(self.registration_block_height):
                LOG.error(
                    'Unable to get distribution: invalid registration_block_height: %s'
                    % self.registration_block_height)
                raise Exception(
                    'Unable to get distribution: invalid registration_block_height: %s'
                    % self.registration_block_height)

            data = get_lsl(address=self.registration_address,
                           xpub=self.registration_xpub,
                           block_height=self.registration_block_height)
            if 'LSL' not in data:
                LOG.error('Unable to get distribution: invalid LSL data: %s' %
                          data)
                raise Exception('Unable to get distribution: invalid LSL: %s' %
                                data)
            distribution = {
                recipient[0]: recipient[1]
                for recipient in data['LSL']
            }

        elif transaction_type == 'Send2LAL':
            if not valid_address(self.sending_address):
                LOG.error(
                    'Unable to get distribution: invalid sending_address: %s' %
                    self.sending_address)
                raise Exception(
                    'Unable to get distribution: invalid sending_address: %s' %
                    self.sending_address)
            if not valid_xpub(self.registration_xpub):
                LOG.error(
                    'Unable to get distribution: invalid registration_xpub: %s'
                    % self.registration_xpub)
                raise Exception(
                    'Unable to get distribution: invalid registration_xpub: %s'
                    % self.registration_xpub)
            if not valid_block_height(self.registration_block_height):
                LOG.error(
                    'Unable to get distribution: invalid registration_block_height: %s'
                    % self.registration_block_height)
                raise Exception(
                    'Unable to get distribution: invalid registration_block_height: %s'
                    % self.registration_block_height)

            # The registration address of a LAL must always be the sending address
            data = get_lal(address=self.sending_address,
                           xpub=self.registration_xpub,
                           block_height=self.registration_block_height)
            if 'LAL' not in data:
                LOG.error('Unable to get distribution: invalid LAL data: %s' %
                          data)
                raise Exception('Unable to get distribution: invalid LAL: %s' %
                                data)

            LOG.info('LAL: %s' % data['LAL'])
            distribution = {}
            for utxo in self.unspent_outputs:
                prime_input_address_data = prime_input_address(
                    utxo.output_hash)
                prime_input_address_of_utxo = prime_input_address_data[
                    'prime_input_address'] if 'prime_input_address' in prime_input_address_data else None
                LOG.info('Prime input address of %s is %s' %
                         (utxo.output_hash, prime_input_address_of_utxo))

                linked_address = [
                    linked_address
                    for input_address, linked_address in data['LAL']
                    if input_address == prime_input_address_of_utxo
                ]
                # There should be exactly 1 linked address
                if len(linked_address) == 1:
                    distribution[linked_address[0]] = utxo.value
                else:
                    LOG.error(
                        'Something went wrong with the LAL: found %s linked addresses, should be exactly 1!'
                        % len(linked_address))
                    raise Exception(
                        'Something went wrong with the LAL: found %s linked addresses, should be exactly 1!'
                        % len(linked_address))

        else:
            raise NotImplementedError('Unknown transaction type %s' %
                                      transaction_type)

        LOG.info('distribution: %s' % distribution)
        return distribution
Пример #12
0
# Create main parser
parser = argparse.ArgumentParser(
    description='Bitcoin Wand command line interface',
    formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('address', help='The address that is sending the message')
parser.add_argument(
    'message',
    help='The message itself OR name of the file that contains the message')
parser.add_argument('url', help='The url to send the request to')

# Parse arguments
args = parser.parse_args()

# Check if address is valid
if not valid_address(args.address):
    print('Invalid address: %s' % args.address)
    sys.exit(1)

data = {'address': args.address}

# Find the private key of the address in the hot wallet
account, index = find_address_in_wallet(
    address=data['address'], accounts=100
)  # Todo find better way to specify number of accounts to search
if account is None or index is None:
    print('Can not find address in wallet!')
    sys.exit(1)
else:
    private_key = get_private_key_from_wallet(account=account,
                                              index=index)[data['address']]
Пример #13
0
 def test_valid_address_testnet(self, address, expected, description):
     helpers.configurationhelpers.get_use_testnet = mock.MagicMock(return_value=True)
     print(description)
     assert validators.valid_address(address) == expected, description
 def configure(self, **config):
     super(SignedMessageTrigger, self).configure(**config)
     if 'address' in config and valid_address(config['address']):
         self.address = config['address']
     elif 'address' in config and config['address'] == '':
         self.address = None