Beispiel #1
0
def create(ctx, account_type, testnet):
    """ Creates a new wallet
    """
    # txn_data_provider and related params come from the
    # global context.
    passphrase = ""
    if ctx.obj['passphrase']:
        # Let's prompt for a passphrase
        conf = "a"
        i = 0
        while passphrase != conf and i < 3:
            passphrase = getpass.getpass("Enter desired passphrase: ")
            conf = getpass.getpass("Confirm passphrase: ")
            i += 1

        if passphrase != conf:
            ctx.fail("Passphrases don't match. Quitting.")

    options = {
        "account_type": account_type,
        "passphrase": passphrase,
        "data_provider": ctx.obj['data_provider'],
        "testnet": testnet,
        "wallet_path": ctx.obj['wallet_path']
    }

    logger.info("Creating wallet with options: %r" % options)
    created = Two1Wallet.configure(options)

    if created:
        # Make sure it opens
        logger.info("Wallet created.")
        try:
            wallet = Two1Wallet(params_or_file=ctx.obj['wallet_path'],
                                data_provider=ctx.obj['data_provider'],
                                passphrase=passphrase)

            click.echo("Wallet successfully created!")

            adder = " (and your passphrase) " if passphrase else " "
            click.echo(
                "Your wallet can be recovered using the following set of words (in that order)."
            )
            click.echo("Please store them%ssafely." % adder)
            click.echo("\n%s\n" % wallet._orig_params['master_seed'])
        except Exception as e:
            logger.debug("Error opening created wallet: %s" % e)
            click.echo("Wallet was not created properly.")
            ctx.exit(code=3)
    else:
        ctx.fail("Wallet was not created.")
Beispiel #2
0
def load_wallet(wallet_path, data_provider, passphrase):
    """ Loads a wallet.

    Args:
        wallet_path (str): The path to the wallet to be loaded.
        data_provider (BaseProvider): A blockchain data provider object.
        passphrase (str): Passphrase to use to unlock the wallet if the
            wallet requires unlocking.
    """
    global wallet

    try:
        logger.debug("In load_wallet...")
        logger.debug("\twallet_path = %s" % wallet_path)
        logger.debug("\tdata_provider = %r" % data_provider)
        logger.debug("\tpassphrase = %r" % bool(passphrase))
        wallet['obj'] = Two1Wallet(params_or_file=wallet_path,
                                   data_provider=data_provider,
                                   passphrase=passphrase)
        wallet['locked'] = False
    except Exception as e:
        raise WalletNotLoadedError("Wallet loading failed: %s" % e)
def test_rest():
    m = mock_provider
    m.hd_master_key = master
    m.reset_mocks()

    m.set_num_used_accounts(1)
    m.set_num_used_addresses(account_index=0, n=1, change=0)
    m.set_num_used_addresses(account_index=0, n=2, change=1)

    m.set_txn_side_effect_for_hd_discovery()

    wallet = Two1Wallet(params_or_file=config,
                        data_provider=m,
                        passphrase=passphrase)

    # First 5 internal addresses of account 0
    # These can be gotten from https://dcpos.github.io/bip39/
    ext_addrs = [
        "1Kv1QLXekeE42rKhvZ41kHS1auE7R3t21o",
        "1CYhVFaBwmTQRQwdyLc4rq9HwaxdqtQ68G",
        "18KCKKB5MGs4Rqu4t8jL9Bkt9SAp7NpUvm",
        "1FqUrpUpqWfHoPVga4uMKYCPHHoApvNiPa",
        "12zb1hJP5WEHCSKz5LyoPM9iaCwXtTthRc"
    ]

    int_addrs = [
        "1Hiv6LroFmqcaVV9rhY6eNUjnFQh4y6kL7",
        "1GTUuNbgk4sv7LPQd2WqSP9PiinzeuBmay",
        "14fpkEZZ6QP3QEcQnfSjH7adkC2RsMuiZw",
        "1LPNyqqX6RU5b4oPumePR72tFfwiNUho4s",
        "1FqvNKJb8au82PhtGP8D1odXWVC1Ae4jN9"
    ]

    bad_addrs = [
        "1CEDwjjtYjCQUoRZQW9RUXHH5Ao7PWYKf",
        "1CbHFUNsyCzZSDu7hYae7HHqgzMjBfqoP9"
    ]

    paths = wallet.find_addresses(int_addrs + ext_addrs + bad_addrs)

    assert len(paths.keys()) == 10

    for i in range(5):
        # Hardened account key derivation, thus 0x80000000
        assert paths[ext_addrs[i]] == (0x80000000, 0, i)
        assert paths[int_addrs[i]] == (0x80000000, 1, i)

        # Check address belongs
        assert wallet.address_belongs(ext_addrs[i]) == "m/44'/0'/0'/0/%d" % i
        assert wallet.address_belongs(int_addrs[i]) == "m/44'/0'/0'/1/%d" % i

    for b in bad_addrs:
        assert b not in paths
        assert wallet.address_belongs(b) is None

    # Check that there's an account name
    assert wallet.get_account_name(0) == "default"

    # Check the balance
    assert wallet.balances == {'confirmed': 100000, 'total': 200000}

    # Check that we can get a new payout address
    ext_addr = wallet.get_payout_address("default")
    assert ext_addr == ext_addrs[1]
    assert wallet.accounts[0].last_indices[0] == 0

    # Check the balance again - should be the same
    m.set_num_used_addresses(0, 1, 0)
    assert wallet.balances == {'confirmed': 100000, 'total': 200000}

    # Try sending below the dust limit
    with pytest.raises(ValueError):
        wallet.send_to(address="14ocdLGpBp7Yv3gsPDszishSJUv3cpLqUM",
                       amount=544)

    # Try sending a non-integer amount (mistaken user tries to send in btc
    # instead of satoshi)
    with pytest.raises(exceptions.SatoshiUnitsError):
        wallet.send_to(address="14ocdLGpBp7Yv3gsPDszishSJUv3cpLqUM",
                       amount=0.0001)

    # Try sending more than we have and make sure it raises an exception
    with pytest.raises(exceptions.WalletBalanceError):
        wallet.send_to(address="14ocdLGpBp7Yv3gsPDszishSJUv3cpLqUM",
                       amount=10000000)

    # Should still fail when using unconfirmed if amount is greater
    # than unconfirmed balance
    with pytest.raises(exceptions.WalletBalanceError):
        wallet.send_to(address="14ocdLGpBp7Yv3gsPDszishSJUv3cpLqUM",
                       use_unconfirmed=True,
                       amount=10000000)

    # Should fail when not using unconfirmed txns and
    # confirmed < amount < unconfirmed.
    with pytest.raises(exceptions.WalletBalanceError):
        wallet.send_to(address="14ocdLGpBp7Yv3gsPDszishSJUv3cpLqUM",
                       use_unconfirmed=False,
                       amount=150000)

    # Should get past checking balance but raise a NotImplementedError
    with pytest.raises(NotImplementedError):
        wallet.send_to(address="14ocdLGpBp7Yv3gsPDszishSJUv3cpLqUM",
                       use_unconfirmed=False,
                       amount=7700)

    # Should get past checking balance but raise a signing error
    with pytest.raises(NotImplementedError):
        wallet.send_to(address="14ocdLGpBp7Yv3gsPDszishSJUv3cpLqUM",
                       use_unconfirmed=True,
                       amount=12581)

    # test number of addresses in spread_utxos
    with pytest.raises(ValueError):
        wallet.spread_utxos(threshold=500000, num_addresses=0, accounts=[])
    with pytest.raises(ValueError):
        wallet.spread_utxos(threshold=500000, num_addresses=101, accounts=[])

    # test units for spread_utxos
    with pytest.raises(exceptions.SatoshiUnitsError):
        wallet.spread_utxos(threshold=0.0001, num_addresses=1, accounts=[])

    # Finally check storing to a file
    params = {}
    with tempfile.NamedTemporaryFile(delete=True) as tf:
        wallet.to_file(tf)

        # Read it back
        tf.seek(0, 0)
        params = json.loads(tf.read().decode('utf-8'))

        # Check that the params match expected
        assert params['master_key'] == config['master_key']
        assert params['master_seed'] == config['master_seed']
        assert params['locked']
        assert params['key_salt'] == bytes_to_str(enc_key_salt)
        assert params['passphrase_hash'] == passphrase_hash
        assert params['account_type'] == "BIP44BitcoinMainnet"
        assert params['account_map']['default'] == 0
        assert len(params['accounts']) == 1
        assert params['accounts'][0]['last_payout_index'] == 0
        assert params['accounts'][0]['last_change_index'] == 1
        assert params['accounts'][0]['public_key'] == config['accounts'][0][
            'public_key']

        # Now create the wallet from the file
        with pytest.raises(exceptions.PassphraseError):
            w2 = Two1Wallet(params_or_file=tf.name,
                            data_provider=m,
                            passphrase='wrong_pass')

        # Now do with the correct passphrase
        m.set_txn_side_effect_for_hd_discovery()
        w2 = Two1Wallet(params_or_file=tf.name,
                        data_provider=m,
                        passphrase=passphrase)

        assert len(w2.accounts) == 1
        assert not w2._testnet

        acct = w2.accounts[0]
        assert acct.last_indices[0] == 0
        assert acct.last_indices[1] == 1
Beispiel #4
0
#!/usr/bin/env python3

from two1.wallet.two1_wallet import Two1Wallet
from two1.blockchain.twentyone_provider import TwentyOneProvider
from two1.bitcoin import utils
from two1.bitcoin import Script
from two1.bitcoin import Transaction, TransactionInput, TransactionOutput

# Create application objects

wallet = Two1Wallet(Two1Wallet.DEFAULT_WALLET_PATH, TwentyOneProvider())


def write_ew_message(msg):
    """Write a message to the blockchain."""
    print("write_ew_message({})" % msg)

    # Create a bitcoin script object with our message
    if len(msg) > 72:
        raise Exception('Message is too long and may not be accepted.')
    msg = "EW " + msg
    message_script = Script('OP_RETURN 0x{}'.format(utils.bytes_to_str(msg.encode())))

    # Define the fee we're willing to pay for the tx
    tx_fee = 11000

    # Get the first UTXO from our set that can cover the fee
    utxo = None
    for utxo_addr, utxos in wallet.get_utxos().items():
        for u in utxos:
            if u.value > tx_fee: