Send a file to the given recipient, encrypted and signed with the
    given blockchain ID.
    Allow each recipient to receive the data on each of their hosts.
    Return {'status': True} on success, and upload to cloud storage
    Return {'error': ...} on error

def file_put( blockchain_id, hostname, recipient_blockchain_ids, data_name, input_path, passphrase=None, config_path=CONFIG_PATH, wallet_keys=None ):
    """
    Send a file to the given recipient, encrypted and signed with the
    given blockchain ID.
    Allow each recipient to receive the data on each of their hosts.
    Return {'status': True} on success, and upload to cloud storage
    Return {'error': ...} on error
    """
    fd, output_path = tempfile.mkstemp( prefix="blockstack-file-" )
    os.fchmod( fd, 0600 )
    os.close(fd)

    config_dir = os.path.dirname(config_path)
    client_config_path = os.path.join(config_dir, blockstack_client.CONFIG_FILENAME )

    all_recipients = []
    
    # make available to all other hosts for this blockchain_id
    my_hosts = file_list_hosts( blockchain_id, wallet_keys=wallet_keys, config_path=config_path )
    if 'error' in my_hosts:
        log.error("Failed to list hosts: %s" % my_hosts['error'])
        os.unlink(output_path)
        return {'error': 'Failed to look up sender keys'}

    if hostname in my_hosts:
        my_hosts.remove(hostname)

    all_recipients += [(blockchain_id, host) for host in my_hosts['hosts']]

    # make available to all hosts for each recipient 
    for recipient_blockchain_id in recipient_blockchain_ids:
        their_hosts = file_list_hosts( recipient_blockchain_id, wallet_keys=wallet_keys, config_path=config_path )
        if 'error' in their_hosts:
            log.error("Failed to list hosts for %s: %s" % (recipient_blockchain_id, their_hosts['error']))
            os.unlink(output_path)
            return {'error': 'Failed to look up recipient keys'}

        all_recipients += [(recipient_blockchain_id, host) for host in their_hosts['hosts']]

    # encrypt
    res = file_encrypt( blockchain_id, hostname, all_recipients, input_path, output_path, passphrase=passphrase, config_path=config_path, wallet_keys=wallet_keys )
    if 'error' in res:
        log.error("Failed to encrypt: %s" % res['error'])
        os.unlink(output_path)
        return {'error': 'Failed to encrypt'}

    # load up 
    with open(output_path, "r") as f:
        ciphertext = f.read()

    message = {'ciphertext': ciphertext, 'sender_key_id': res['sender_key_id']}

    # put to mutable storage 
    fq_data_name = file_fq_data_name( data_name ) 
    proxy = blockstack_client.get_default_proxy( config_path=client_config_path )

    res = blockstack_client.data_put( blockstack_client.make_mutable_data_url( blockchain_id, fq_data_name, None ), message, wallet_keys=wallet_keys, proxy=proxy )
    if 'error' in res:
        log.error("Failed to put data: %s" % res['error'])
        os.unlink(output_path)
        return {'error': 'Failed to replicate data'}

    os.unlink(output_path)
    return {'status': True}