示例#1
0
def test_get_fees_unreasonable_fee():
    with mock.patch('two1.wallet.fees.requests.get') as mock_request:
        return_value = mock_request.return_value
        return_value.status_code = 200
        fee_per_byte = fees.DEFAULT_FEE_PER_KB / 1000
        return_value.json = lambda: {
            'halfHourFee': fee_per_byte * 10,
        }
        with TestCase().assertRaises(exceptions.UnreasonableFeeError):
            fees.get_fees()
示例#2
0
def test_get_fees_cointape_server_down():
    # Mock a response that doesn't have the correct data
    with mock.patch('two1.wallet.fees.requests.get') as mock_request:
        mock_request.return_value.status_code = 400
        f = fees.get_fees()

    assert f['per_kb'] == fees.DEFAULT_FEE_PER_KB
示例#3
0
def utxo_selector_smallest_first(utxos_by_addr, amount,
                                 num_outputs, fees=None):
    f = get_fees()
    input_fee = f['per_input']
    output_fee = f['per_output']

    # Order the utxos by amount
    utxo_tuple_list = _get_utxos_addr_tuple_list(utxos_by_addr)
    ordered_utxos = sorted(utxo_tuple_list,
                           key=lambda utxo_addr_tuple: utxo_addr_tuple[1].value)

    calc_fees = num_outputs * output_fee
    utxos_to_use = {}
    utxo_sum = 0

    for addr, utxo in ordered_utxos:
        tf = fees if fees is not None else calc_fees
        if utxo_sum < amount + tf:
            utxo_sum += utxo.value
            if addr in utxos_to_use:
                utxos_to_use[addr].append(utxo)
            else:
                utxos_to_use[addr] = [utxo]

            calc_fees += input_fee
        else:
            break

    fee = fees if fees is not None else calc_fees

    rv = utxos_to_use, fee
    if utxo_sum < amount + fee:
        rv = {}, fee

    return rv
示例#4
0
def test_get_fees():
    f = fees.get_fees()

    assert 'per_kb' in f
    assert 'per_input' in f
    assert 'per_output' in f

    assert f['per_kb'] >= 0 and f['per_kb'] <= 100000

    # Mock a response that doesn't have the correct data
    fees._fee_session.request = MagicMock(
        return_value=type('obj', (object,), {'status_code': 400,
                                             "json": lambda: "Not Json",
                                             'text': "Error"}))
    f = fees.get_fees()

    assert f['per_kb'] == fees.DEFAULT_FEE_PER_KB
示例#5
0
def test_get_fees():
    f = fees.get_fees()

    assert 'per_kb' in f
    assert 'per_input' in f
    assert 'per_output' in f

    assert f['per_kb'] >= 0 and f['per_kb'] <= 100000

    # Mock a response that doesn't have the correct data
    fees._fee_session.request = MagicMock(
        return_value=type('obj', (object, ), {
            'status_code': 400,
            "json": lambda: "Not Json",
            'text': "Error"
        }))
    f = fees.get_fees()

    assert f['per_kb'] == fees.DEFAULT_FEE_PER_KB
示例#6
0
def sweep(ctx):
    """
Sweep your machine wallet to your primary wallet.

\b
Sweep your machine wallet to your primary wallet.
$ 21 sell sweep
"""

    manager = ctx.obj['manager']

    logger.info(click.style("Sweeping all service balances.", fg=cli_helpers.TITLE_COLOR))

    provider = TwentyOneProvider()
    try:
        wallet = Two1Wallet.import_from_mnemonic(provider, manager.get_services_mnemonic())
    except Exception:
        logger.info(click.style("Error: unable to import wallet mnemonic.  Please check to make "
                                "sure the mnemonic exists in %s "
                                "or contact [email protected]." % Two1Composer.COMPOSE_FILE,
                                fg="magenta"))

    utxos = wallet.get_utxos(include_unconfirmed=True, accounts=wallet._accounts)
    utxo_sum = wallet._sum_utxos(utxos)

    fee_amounts = txn_fees.get_fees()
    total_value, num_utxos = utxo_sum

    def fee_calc_small(num_utxos, total_value, fee_amounts):
        maybe_fee = _fee_calc(num_utxos, total_value, fee_amounts)
        return int(min([total_value / 2, maybe_fee]))

    fee = fee_calc_small(num_utxos, total_value, fee_amounts)

    if click.confirm(click.style("Sweeping %s satoshis to your primary wallet. This will incur a "
                                 "fee of approximately %d satoshis.\n"
                                 "Would you like to continue?" % (total_value, fee),
                                 fg=cli_helpers.PROMPT_COLOR)):
        master = Two1Wallet(manager.composer.wallet_file, provider)
        try:
            wallet.sweep(master.current_address, fee_calculator=fee_calc_small)
        except WalletBalanceError:
            cli_helpers.print_str("Sweep", ["Wallet balance (%d satoshis) is less than the dust "
                                            "limit. Not Sweeping." % total_value], "FAILED", False)
        except DustLimitError:
            cli_helpers.print_str("Sweep", ["Wallet balance (%d satoshis) would be below the "
                                            "dust limit when fees are deducted. "
                                            "Aborting sweep." % total_value], "FAILED", False)
        else:
            cli_helpers.print_str("Sweep", ["Swept %d satoshis, excluding %d satoshis of "
                                            "fees" % (total_value - fee, fee)], "SUCCESS", True)
    else:
        sys.exit()
示例#7
0
def sweep(ctx):
    """
Sweep your machine wallet to your primary wallet.

\b
Sweep your machine wallet to your primary wallet.
$ 21 sell sweep
"""

    manager = ctx.obj['manager']

    logger.info(click.style("Sweeping all service balances.", fg=cli_helpers.TITLE_COLOR))

    provider = TwentyOneProvider()
    try:
        wallet = Two1Wallet.import_from_mnemonic(provider, manager.get_services_mnemonic())
    except Exception:
        logger.info(click.style("Error: unable to import wallet mnemonic.  Please check to make "
                                "sure the mnemonic exists in %s "
                                "or contact [email protected]." % Two1Composer.COMPOSE_FILE,
                                fg="magenta"))

    utxos = wallet.get_utxos(include_unconfirmed=True, accounts=wallet._accounts)
    utxo_sum = wallet._sum_utxos(utxos)

    fee_amounts = txn_fees.get_fees()
    total_value, num_utxos = utxo_sum

    def fee_calc_small(num_utxos, total_value, fee_amounts):
        maybe_fee = _fee_calc(num_utxos, total_value, fee_amounts)
        return int(min([total_value / 2, maybe_fee]))

    fee = fee_calc_small(num_utxos, total_value, fee_amounts)

    if click.confirm(click.style("Sweeping %s satoshis to your primary wallet. This will incur a "
                                 "fee of approximately %d satoshis.\n"
                                 "Would you like to continue?" % (total_value, fee),
                                 fg=cli_helpers.PROMPT_COLOR)):
        master = Two1Wallet(manager.composer.wallet_file, provider)
        try:
            wallet.sweep(master.current_address, fee_calculator=fee_calc_small)
        except WalletBalanceError:
            cli_helpers.print_str("Sweep", ["Wallet balance (%d satoshis) is less than the dust "
                                            "limit. Not Sweeping." % total_value], "FAILED", False)
        except DustLimitError:
            cli_helpers.print_str("Sweep", ["Wallet balance (%d satoshis) would be below the "
                                            "dust limit when fees are deducted. "
                                            "Aborting sweep." % total_value], "FAILED", False)
        else:
            cli_helpers.print_str("Sweep", ["Swept %d satoshis, excluding %d satoshis of "
                                            "fees" % (total_value - fee, fee)], "SUCCESS", True)
    else:
        sys.exit()
def utxo_selector_smallest_first(utxos_by_addr,
                                 amount,
                                 num_outputs,
                                 fees=None):
    # Order the utxos by amount
    utxo_tuple_list = _get_utxos_addr_tuple_list(utxos_by_addr)
    ordered_utxos = sorted(
        utxo_tuple_list, key=lambda utxo_addr_tuple: utxo_addr_tuple[1].value)

    if fees is None:
        f = get_fees()
        input_fee = f['per_input']
        output_fee = f['per_output']
        calc_fees = num_outputs * output_fee

    utxos_to_use = {}
    utxo_sum = 0

    for addr, utxo in ordered_utxos:
        tf = fees if fees is not None else calc_fees
        if utxo_sum < amount + tf:
            utxo_sum += utxo.value
            if addr in utxos_to_use:
                utxos_to_use[addr].append(utxo)
            else:
                utxos_to_use[addr] = [utxo]

            if fees is None:
                calc_fees += input_fee
        else:
            break

    fee = fees if fees is not None else calc_fees

    rv = utxos_to_use, fee
    if utxo_sum < amount + fee:
        rv = {}, fee

    return rv
示例#9
0
文件: sell.py 项目: shayanb/two1
def sweep(ctx, services, all, channels):
    """
Sweep service wallets to primary wallet.

\b
Sweep all service wallets to primary wallet.
$ 21 sell sweep --all

\b
Sweep the wallets of services to primary wallet.
$ 21 sell sweep <services>...
"""
    services_present = len(services) > 0
    all_present = all is True
    channels_present = channels is True

    if services_present + all_present + channels_present != 1:
        logger.info(ctx.command.get_help(ctx))
        sys.exit()

    manager = ctx.obj['manager']

    provider = TwentyOneProvider()
    master = Two1Wallet(manager.composer.PRIMARY_WALLET_FILE, provider)

    if not channels_present:
        try:
            with open(manager.composer.SERVICES_WALLET_FILE, "r") as f:
                services_info = json.load(f)
        except:
            logger.info(click.style("The services wallet information file seems to be corrupted, exiting..."), fg="magenta")
            sys.exit()

        requested_services_set = frozenset(services)
        available_services_set = frozenset(services_info.keys())

        if all:
            start_string = "Sweeping all service balances..."
            clients = {service_name: Two1Wallet.import_from_mnemonic(provider, service_details['mnemonic'])
                       for service_name, service_details in services_info.items()}
        elif requested_services_set.issubset(available_services_set):
            start_string = "Sweeping balances for " + ", ".join(services) + "..."
            clients = {service_name: Two1Wallet.import_from_mnemonic(provider, services_info[service_name]['mnemonic'])
                       for service_name in services}
        else:
            unavailable_requested_services = requested_services_set.difference(available_services_set)
            if len(unavailable_requested_services) > 1:
                logger.info(click.style("Services {} aren't available to be sweeped".format(", ".join(unavailable_requested_services)), fg="magenta"))
            else:
                logger.info(click.style("Service {} isn't available to be sweeped".format(", ".join(unavailable_requested_services)), fg="magenta"))
            sys.exit()
        logger.info(click.style(start_string, fg=cli_helpers.TITLE_COLOR))
    else:
        logger.info(click.style("Sweeping payment server balances...", fg=cli_helpers.TITLE_COLOR))
        try:
            with open(manager.composer.PAYMENTS_WALLET_FILE, "r") as f:
                payments_info = json.load(f)
        except:
            logger.info(click.style("The payment server wallet information file seems to be corrupted, exiting..."), fg="magenta")
            sys.exit()
        clients = {"payment channels": Two1Wallet.import_from_mnemonic(provider, payments_info['mnemonic'])}

    logger.info(click.style(start_string, fg=cli_helpers.TITLE_COLOR))

    utxo_sums = {}
    for service_name, wallet in clients.items():
        utxos_by_addr = wallet.get_utxos(include_unconfirmed=True,
                                         accounts=wallet._accounts)
        utxo_sums[service_name] = wallet._sum_utxos(utxos_by_addr)

    fee_dict = {}
    fee_amounts = txn_fees.get_fees()
    for service_name, utxo_sum in utxo_sums.items():
        total_value, num_utxos = utxo_sum
        fee_dict[service_name] = fee_calc_small(num_utxos, total_value, fee_amounts)
    fees = sum(fee_dict.values())

    if click.confirm(click.style("This will incur a fee of approximately %d satoshis in total. "
                                 "Would you like to continue?" % fees, fg=cli_helpers.PROMPT_COLOR)):
        for service_name, wallet in clients.items():
            try:
                wallet.sweep(master.current_address, fee_calculator=fee_calc_small)
            except WalletBalanceError:
                cli_helpers.print_str(service_name, ["Wallet balance (%d satoshis) is less than the dust limit. Not Sweeping." % utxo_sums[service_name][0]], "FALSE", False)
            except DustLimitError:
                cli_helpers.print_str(service_name, ["Wallet balance (%d satoshis) would be below the dust limit when fees are deducted. Not Sweeping." % utxo_sums[service_name][0]], "FALSE", False)
            else:
                total_value = utxo_sums[service_name][0]
                fees_incurred = fee_dict[service_name]
                cli_helpers.print_str(service_name, ["Sweeped %d satoshis, excluding %d satoshis of fees" % (total_value - fees_incurred, fees_incurred)], "TRUE", True)
    else:
        sys.exit()