Esempio n. 1
0
def green(debug, network, auth, config_dir, compact, watch_only, tor):
    """Command line interface for green gdk"""
    global context
    if context is not None:
        # Retain context over multiple commands in repl mode
        return

    if debug:
        logging.basicConfig(level=logging.DEBUG)

    config_dir = config_dir or os.path.expanduser(
        os.path.join('~', '.green-cli', network))
    try:
        os.makedirs(config_dir)
    except FileExistsError:
        pass

    gdk.init({})
    session = Session({'name': network, 'use_tor': tor})
    atexit.register(session.destroy)

    if watch_only:
        auth = 'watch-only'

    authenticator = get_authenticator(auth, config_dir)

    context = Context(config_dir, session, network, TwoFactorResolver(),
                      authenticator, compact)
Esempio n. 2
0
def green(**options):
    """Command line interface for Blockstream Green."""
    if context.configured:
        # In repl mode run configuration once only
        return

    if options['log_level']:
        py_log_level = {
            'error': logging.ERROR,
            'warning': logging.WARNING,
            'info': logging.INFO,
            'debug': logging.DEBUG,
        }[options['log_level']]

        logging.basicConfig(level=py_log_level)

    if options['config_dir'] is None:
        options['config_dir'] = _get_config_dir(options)
    os.makedirs(options['config_dir'], exist_ok=True)

    gdk.init({})

    if options['watch_only']:
        options['auth'] = 'watchonly'

    authenticator = _get_authenticator(options)
    context.configure(authenticator, options)
Esempio n. 3
0
def green(debug, network, auth, config_dir, compact):
    """Command line interface for green gdk"""
    global context
    if context is not None:
        # Retain context over multiple commands in repl mode
        return

    if debug:
        logging.basicConfig(level=logging.DEBUG)

    if network == 'mainnet':
        raise click.ClickException("This tool is not currently suitable for use on mainnet")

    config_dir = config_dir or os.path.expanduser(os.path.join('~', '.green-cli', network))
    try:
        os.makedirs(config_dir)
    except FileExistsError:
        pass

    gdk.init({})
    session = gdk.Session({'name': network})
    atexit.register(session.destroy)

    authenticator = get_authenticator(auth, config_dir)
    context = Context(session, network, TwoFactorResolver(), authenticator, compact)
Esempio n. 4
0
def download_file_gdk(hw_target, write_compressed, index_file, auto_select_fw):
    import greenaddress as gdk
    import base64
    import json

    # We need to pass the relevant root certificate
    with open(FWSERVER_CERTIFICATE_FILE, 'r') as cf:
        root_cert = cf.read()

    gdk.init({})
    session = gdk.Session({'name': 'mainnet'})

    # GET the index file from the firmware server which lists the
    # available firmwares
    url = f'{FWSERVER_URL_ROOT}/{hw_target}/{index_file}'
    logger.info(f'Downloading firmware index file {url} using gdk')
    params = {'method': 'GET', 'root_certificates': [root_cert], 'urls': [url]}
    rslt = gdk.http_request(session.session_obj, json.dumps(params))
    rslt = json.loads(rslt)
    assert 'body' in rslt, f'Cannot download index file {url}: {rslt.get("error")}'

    # Get the filename of the firmware to download
    fwname = get_fw_filename(rslt['body'], auto_select_fw)
    fwlen = get_expected_fw_length(fwname)

    # GET the selected firmware from the server in base64 encoding
    url = f'{FWSERVER_URL_ROOT}/{hw_target}/{fwname}'
    logger.info(f'Downloading firmware {url} using gdk')
    params['urls'] = [url]
    params['accept'] = 'base64'

    rslt = gdk.http_request(session.session_obj, json.dumps(params))
    rslt = json.loads(rslt)
    assert 'body' in rslt, f'Cannot download firmware file {url}: {rslt.get("error")}'

    fw_b64 = rslt['body']
    fwcmp = base64.b64decode(fw_b64)
    logger.info('Downloaded {len(fwcmp)} byte firmware')

    # If passed --write-compressed we write a copy of the compressed file
    if write_compressed:
        write_cmpfwfile(fwname, fwcmp)

    # Return
    return fwcmp, fwlen
Esempio n. 5
0
def download_file_gdk(hw_target, write_compressed, release):
    import greenaddress as gdk
    import base64

    gdk.init({})
    session = gdk.Session({'name': 'mainnet'})

    # GET the index file from the firmware server which lists the
    # available firmwares
    url = f'{FWSERVER_URL_ROOT}/{hw_target}/{FWSERVER_INDEX_FILE}'
    logger.info(f'Downloading firmware index file {url} using gdk')
    params = {'method': 'GET', 'urls': [url]}
    rslt = gdk.http_request(session.session_obj, json.dumps(params))
    rslt = json.loads(rslt)
    assert 'body' in rslt, f'Cannot download index file {url}: {rslt.get("error")}'

    # Get the filename of the firmware to download
    release_data = json.loads(rslt['body'])[release]
    if not release_data:
        return None

    fwdata = get_fw_metadata(release_data)
    fwname = fwdata['filename']

    # GET the selected firmware from the server in base64 encoding
    url = f'{FWSERVER_URL_ROOT}/{hw_target}/{fwname}'
    logger.info(f'Downloading firmware {url} using gdk')
    params = {'method': 'GET', 'urls': [url], 'accept': 'base64'}
    rslt = gdk.http_request(session.session_obj, json.dumps(params))
    rslt = json.loads(rslt)
    assert 'body' in rslt, f'Cannot download firmware file {url}: {rslt.get("error")}'

    fw_b64 = rslt['body']
    fwcmp = base64.b64decode(fw_b64)
    logger.info(f'Downloaded {len(fwcmp)} byte firmware')

    # If passed --write-compressed we write a copy of the compressed file
    if write_compressed:
        cmpfilename = f'{COMP_FW_DIR}/{fwname}'
        fwtools.write(fwcmp, cmpfilename)

    # Return
    return fwdata['fwsize'], fwdata.get('patch_size'), fwcmp
Esempio n. 6
0
def green(**options):
    """Command line interface for Blockstream Green."""
    if context.configured:
        # In repl mode run configuration once only
        return

    if options['log_level']:
        py_log_level = {
            'error': logging.ERROR,
            'warn': logging.WARNING,
            'info': logging.INFO,
            'debug': logging.DEBUG,
        }[options['log_level']]

        logging.basicConfig(level=py_log_level)

    if options['config_dir'] is None:
        options['config_dir'] = _get_config_dir(options)
    os.makedirs(options['config_dir'], exist_ok=True)

    if options['datadir'] is None:
        options['datadir'] = os.path.join(options['config_dir'], 'gdk_datadir')
    os.makedirs(options['datadir'], exist_ok=True)

    if options['tordir'] is None:
        options['tordir'] = os.path.join(options['config_dir'], 'gdk_tordir')
    os.makedirs(options['tordir'], exist_ok=True)

    gdk.init({
        'log_level': options['gdk_log'],
        'datadir': options['datadir'],
        'tordir': options['tordir'],
    })

    if options['watch_only']:
        options['auth'] = 'watchonly'

    # Load additional config json file for the authenticator if required
    _normalise_auth_config(options)

    authenticator = _get_authenticator(options)
    context.configure(authenticator, options)
Esempio n. 7
0
def green(**options):
    """Command line interface for green gdk"""
    global context
    if context is not None:
        # Retain context over multiple commands in repl mode
        return

    session_params = {
        'name': options['network'],
        'use_tor': options['tor'],
        'log_level': options['gdk_log'],
    }

    if options['log_level']:
        py_log_level = {
            'error': logging.ERROR,
            'warning': logging.WARNING,
            'info': logging.INFO,
            'debug': logging.DEBUG,
        }[options['log_level']]

        logging.basicConfig(level=py_log_level)

    if options['config_dir'] is None:
        options['config_dir'] = _get_config_dir(options)
    try:
        os.makedirs(options['config_dir'])
    except FileExistsError:
        pass

    gdk.init({})
    session = Session(session_params)
    atexit.register(session.destroy)

    if options['watch_only']:
        options['auth'] = 'watchonly'

    authenticator = get_authenticator(options)

    authenticator = get_authenticator(options)
    context = Context(session, TwoFactorResolver(), authenticator, options)
Esempio n. 8
0
    logger = logging.getLogger('jade')
    logger.setLevel(logging.DEBUG)
    logger.addHandler(jadehandler)

    logger = logging.getLogger('jade-device')
    logger.setLevel(logging.DEBUG)
    logger.addHandler(jadehandler)

# We can test with the gdk http_request() function if we have the wheel installed
http_request_fn = None
if USE_GDK_HTTP_CLIENT:
    import json
    import greenaddress as gdk

    gdk.init({})
    gdk_session = gdk.Session({'name': 'mainnet'})

    def http_request_fn(params):
        reply = gdk.http_request(gdk_session.session_obj, json.dumps(params))
        return json.loads(reply)


if len(sys.argv) > 1 and sys.argv[1] == 'ble':
    print('Fetching jade version info over BLE')
    serial_number = sys.argv[2] if len(sys.argv) > 2 else None
    create_jade_fn = JadeAPI.create_ble
    kwargs = {'serial_number': serial_number}
else:
    print('Fetching jade version info over serial')
    serial_device = sys.argv[2] if len(sys.argv) > 2 else None
Esempio n. 9
0
def main():

    # Our calls to GDK are wrapped in the gdk_wallet class, which should only be
    # created using either create_new_wallet, login_with_mnemonic or
    # login_with_pin methods. The example uses Bitcoin's testnet.

    # Initialize GDK.
    gdk.init({})

    # Wallet creation and login using Mnemonic
    # ========================================

    # To create a wallet with a Managed Assets account, pass a mnemonic
    # into the following. You can generate a 24 word mnemonic yourself or
    # have GDK generate it for you by leaving mnemonic as None.
    # You can choose to create a wallet that's covered by 2FA or not.
    # 2FA can be activated or deactivated at any point in time.
    """
    wallet = gdk_wallet.create_new_wallet(create_with_2fa_enabled=False, mnemonic=None)
    print(f'\nMnemonic: {wallet.mnemonic}')
    """

    # To login to an existing wallet you can either use the mnemonic or pin.
    # Later we'll see how to use a pin, for now we will use the mnemonic.
    mnemonic = 'your twenty four word mnemonic goes here with single spaced words'
    if not gdk.validate_mnemonic(mnemonic):
        raise Exception("Invalid mnemonic.")

    # Login to a GDK wallet session using the mnemonic.
    wallet = gdk_wallet.login_with_mnemonic(mnemonic)

    # We can now perform calls against the session, such as get balance for
    # the logged in wallet.
    balance = wallet.get_balance()
    print(f'\n{json.dumps(balance, indent=4)}')

    # Using a pin to encrypt the mnemonic and login
    # =============================================

    # You can also login using a pin. Setting the pin for the wallet returns
    # encrypted data that is saved to file. When you login with the pin, the
    # server will give you the key to decrypt the mnemonic which it uses to
    # login. If the pin is entered incorrectly 3 times the server will delete
    # the key and you must use the mnemonic to login.
    """
    # Before setting the pin, login with the wallet's mnemonic.
    wallet = gdk_wallet.login_with_mnemonic(mnemonic)
    # Then set the pin for the wallet, this saves encrypted data to file.
    # Don't use the example value below, set you own.
    pin = 123456
    # You only need to set the pin data once.
    wallet.set_pin(mnemonic, pin)
    # After setting the pin you can then login using pin and do not have to
    # enter the mnemonic again. The pin is used to decrypt the local file.
    wallet.login_with_pin(pin)
    """

    # Two factor authorization
    # ========================

    # You can add Two Factor Authentication (2FA) to a wallet when you create
    # it or enable or disable 2FA at a later date.
    # Check the current 2FA status for the wallet.
    twofactor_status = wallet.get_current_2fa_status()
    print(f'\n{json.dumps(twofactor_status, indent=4)}')

    # The example below will enable 2FA on an existing wallet and uses email by
    # default, which you can amend if you want.
    """
    try:
        wallet.twofactor_auth_enabled(False)
    except RuntimeError as e:
        # Will error if 2FA is already enabled
        print(f'\nError: {e}\n')
    """

    # Getting notification data from GDK to obtain the last block height
    # ==================================================================

    # The fetch_block_height example shows how to handle notification events
    # from Green by processing the notifications queue.
    block_height = wallet.fetch_block_height()
    print(f'\nCurrent Bitcoin block height: {block_height}')

    # Getting a new address
    # =====================

    address_info = wallet.get_new_address()
    print(f'Address: {address_info["address"]}')

    # Getting transaction data from Green using GDK
    # =============================================

    txs = wallet.get_wallet_transactions()
    for tx in txs:
        print(f'TRANSACTION ID      : {tx["txhash"]}')
        print(f'CONFIRMATION STATUS : {tx["confirmation_status"]}')
        print(f'BLOCK HEIGHT        : {tx["block_height"]}')
        print(f'TYPE                : {tx["type"]}')
        print(f'INPUT COUNT         : {len(tx["inputs"])}')
        print(f'OUTPUT COUNT        : {len(tx["outputs"])}\n')

    # Sending assets
    # ==============
    amount_sat = 1001
    address = 'destination address here'
    txid = wallet.send_to_address(amount_sat, address)
    if txid:
        print(f'\nTransaction sent. Txid: {txid}')
    else:
        print(f'\nTransaction failed. See error logging.')
Esempio n. 10
0
def main():

    # Our calls to GDK are wrapped in the gdk_wallet class, which should only be
    # created using either create_new_wallet, login_with_mnemonic or
    # login_with_pin methods. The example uses the live Liquid network.

    # Initialize GDK.
    gdk.init({})

    # Wallet creation and login using Mnemonic
    # ========================================

    # To create a wallet with a Managed Assets account, pass a mnemonic
    # into the following. You can generate a 24 word mnemonic yourself or
    # have GDK generate it for you by leaving mnemonic as None.
    # You can choose to create a wallet that's covered by 2FA or not.
    # 2FA can be activated or deactivated at any point in time.
    """
    wallet = gdk_wallet.create_new_wallet(create_with_2fa_enabled=False, mnemonic=None)
    print(f'\nMnemonic: {wallet.mnemonic}')
    """
    # To login to an existing wallet you can either use the mnemonic or pin.
    # Later we'll see how to use a pin, for now we will use the mnemonic.
    mnemonic = 'your twenty four word mnemonic goes here with single spaced words'
    if not gdk.validate_mnemonic(mnemonic):
        raise Exception("Invalid mnemonic.")

    # Login to a GDK wallet session using the mnemonic.
    wallet = gdk_wallet.login_with_mnemonic(mnemonic)

    # We can now perform calls against the session, such as get balance for
    # the logged in Blockstream AMP Managed Assets account.
    balance = wallet.get_balance()
    print(f'\n{json.dumps(balance, indent=4)}')

    # Using a pin to encrypt the mnemonic and login
    # =============================================

    # You can also login using a pin. Setting the pin for the wallet returns
    # encrypted data that is saved to file. When you login with the pin, the
    # server will give you the key to decrypt the mnemonic which it uses to
    # login. If the pin is entered incorrectly 3 times the server will delete
    # the key and you must use the mnemonic to login.

    """
    # Before setting the pin, login with the wallet's mnemonic.
    wallet = gdk_wallet.login_with_mnemonic(mnemonic)
    # Then set the pin for the wallet, this saves encrypted data to file.
    # Don't use the example value below, set you own.
    pin = 123456
    # You only need to set the pin data once.
    wallet.set_pin(mnemonic, pin)
    # After setting the pin you can then login using pin and do not have to
    # enter the mnemonic again. The pin is used to decrypt the local file.
    wallet.login_with_pin(pin)
    """

    # Two factor authorization
    # ========================

    # You can add Two Factor Authentication (2FA) to a wallet when you create
    # it or enable or disable 2FA at a later date.
    # Check the current 2FA status for the wallet.
    twofactor_status = wallet.get_current_2fa_status()
    print(f'\n{json.dumps(twofactor_status, indent=4)}')

    # The example below will enable 2FA on an existing wallet and uses email by
    # default, which you can amend if you want.
    """
    try:
        wallet.twofactor_auth_enabled(False)
    except RuntimeError as e:
        # Will error if 2FA is already enabled
        print(f'\nError: {e}\n')
    """

    # Getting notification data from GDK to obtain the last block height
    # ==================================================================

    # The fetch_block_height example shows how to handle notification events
    # from Green by processing the notifications queue.
    block_height = wallet.fetch_block_height()
    print(f'\nCurrent Liquid block height: {block_height}')

    # Getting a new address and understanding pointers
    # ================================================

    # The new address returned will be confidential, whereas GDK transactions
    # will show the unconfidential address. For this reason, use the address
    # 'pointer' to identify it in transactions. The pointer plus sub account
    # index maps to a derivation path so you can use pointers within each
    # sub account to link confidential and unconfidential addresses. Be sure
    # to note that you must consider which sub account you are using when
    # using the pointer as an identifier like this.
    address_info = wallet.get_new_address()
    print(f'Address: {address_info["address"]}')
    print(f'Address pointer: {address_info["pointer"]}')

    # Each call creates a new address/pointer pair for the user.
    address_info = wallet.get_new_address()
    print(f'Address: {address_info["address"]}')
    print(f'Address pointer: {address_info["pointer"]}')

    # Getting transaction data from Green using GDK
    # =============================================

    txs = wallet.get_wallet_transactions()
    for tx in txs:
        print(f'TRANSACTION ID      : {tx["txhash"]}')
        print(f'CONFIRMATION STATUS : {tx["confirmation_status"]}')
        print(f'BLOCK HEIGHT        : {tx["block_height"]}')
        print(f'TYPE                : {tx["type"]}')
        print(f'INPUT COUNT         : {len(tx["inputs"])}')
        print(f'OUTPUT COUNT        : {len(tx["outputs"])}\n')

    # Sending assets
    # ==============

    # Please be aware that AMP issued assets are issued with a precision
    # that affects how the number of sats sent are converted to the number
    # of units of the asset itself. Please refer to the examples under
    # 'precision' on the following page for more details and examples:
    # https://docs.blockstream.com/blockstream-amp/api-tutorial.html#issuing-an-asset
    # If the asset is registered with the Liquid Assets Registry you can
    # check the precision using the following link, or check with the
    # asset's issuer:
    # https://blockstream.info/liquid/assets
    amount_sat = 1
    asset_id = 'asset id here'
    address = 'destination address here'
    txid = wallet.send_to_address(amount_sat, asset_id, address)
    if txid:
        print(f'\nTransaction sent. Txid: {txid}')
    else:
        print(f'\nTransaction failed. See error logging.')
Esempio n. 11
0
@app.route('/api/about', methods=['GET'])
@limiter.exempt
def api_about():
    data = about()
    return jsonify(data)


@app.route('/about', methods=['GET'])
@limiter.exempt
def url_about():
    data = about()
    return render_template('about', **data)


if __name__ == '__main__':
    init({})

    s = Session({"name": "testnet-liquid", "log_level": "info"})
    s.login_user({}, {'mnemonic': gdkMnemonic}).resolve()
    s.change_settings({"unit": "sats"}).resolve()
    subaccount = -1
    subaccounts = s.get_subaccounts().resolve()
    for sub in subaccounts['subaccounts']:
        if sub['name'] == gdkSubaccount:
            if sub['type'] != '2of2_no_recovery':
                pass
            subaccount = sub['pointer']
            break

    app.import_name = '.'
    app.run(host='0.0.0.0', port=8123)