async def main_loop():
    ledger_api = await connect_to_ledger_sim("localhost", 9868)
    selection = ""
    wallet = RLWallet()
    most_recent_header = None
    print_leaf()
    print()
    print("Welcome to your Chia Rate Limited Wallet.")
    print()
    my_pubkey_orig = wallet.get_next_public_key().serialize()
    wallet.pubkey_orig = my_pubkey_orig
    print("Your pubkey is: " + hexlify(my_pubkey_orig).decode('ascii'))

    while selection != "q":
        print()
        print(divider)
        print(" \u2447 Menu \u2447")
        print()
        tip = await ledger_api.get_tip()
        print("Block: ", tip["tip_index"])
        print()
        print("Select a function:")
        print("\u2448 1 Wallet Details")
        print("\u2448 2 View Funds")
        print("\u2448 3 Get Update")
        print("\u2448 4 *GOD MODE* Farm Block / Get Money")
        print("\u2448 5 Receive a new rate limited coin")
        print("\u2448 6 Send a new rate limited coin")
        print("\u2448 7 Spend from rate limited coin")
        print("\u2448 8 Add funds to existing rate limited coin")
        print("\u2448 9 Retrieve sent rate limited coin")
        print("\u2448 q Quit")
        print(divider)
        print()

        selection = input(prompt)
        if selection == "1":
            print_my_details(wallet)
        elif selection == "2":
            view_funds(wallet)
        elif selection == "3":
            most_recent_header = await update_ledger(wallet, ledger_api, most_recent_header)
        elif selection == "4":
            most_recent_header = await new_block(wallet, ledger_api)
        elif selection == "5":
            receive_rl_coin(wallet)
        elif selection == "6":
            await create_rl_coin(wallet, ledger_api)
        elif selection == "7":
            await spend_rl_coin(wallet, ledger_api)
        elif selection == "8":
            await add_funds_to_rl_coin(wallet, ledger_api)
        elif selection == "9":
            await retrieve_rate_limited_coin(wallet, ledger_api)
def test_rl_spend():
    remote = make_client_server()
    run = asyncio.get_event_loop().run_until_complete
    # A gives B some money, but B can only send that money to C (and generate change for itself)
    wallet_a = RLWallet()
    wallet_b = RLWallet()
    wallet_c = RLWallet()
    wallets = [wallet_a, wallet_b, wallet_c]

    limit = 10
    interval = 1
    commit_and_notify(remote, wallets, wallet_a)

    origin_coin = wallet_a.my_utxos.copy().pop()
    wallet_b_pk = wallet_b.get_next_public_key().serialize()
    wallet_b.set_origin(origin_coin)
    wallet_b.limit = limit
    wallet_b.interval = interval
    clawback_pk = wallet_a.get_next_public_key().serialize()
    clawback_pk = hexbytes(clawback_pk)
    wallet_b.rl_clawback_pk = clawback_pk
    rl_puzzle = wallet_b.rl_puzzle_for_pk(wallet_b_pk, limit, interval,
                                          origin_coin.name(), clawback_pk)
    rl_puzzlehash = ProgramHash(rl_puzzle)
    wallet_a.clawback_puzzlehash = rl_puzzlehash
    wallet_a.rl_receiver_pk = wallet_b_pk
    wallet_a.clawback_pk = clawback_pk
    wallet_a.clawback_interval = interval
    wallet_a.clawback_limit = limit
    wallet_a.clawback_origin = origin_coin.name()

    # wallet A is normal wallet, it sends coin that's rate limited to wallet B
    amount = 5000
    spend_bundle = wallet_a.generate_signed_transaction_with_origin(
        amount, rl_puzzlehash, origin_coin.name())
    _ = run(remote.push_tx(tx=spend_bundle))
    commit_and_notify(remote, wallets, Wallet())

    assert wallet_a.current_balance == 999995000
    assert wallet_b.current_rl_balance == 5000
    assert wallet_c.current_balance == 0

    # Now send some coins from b to c
    commit_and_notify(remote, wallets, Wallet())
    assert wallet_b.rl_available_balance() == 10
    commit_and_notify(remote, wallets, Wallet())
    assert wallet_b.rl_available_balance() == 20

    amount = 20
    spend_bundle = wallet_b.rl_generate_signed_transaction(
        amount, wallet_c.get_new_puzzlehash())
    _ = run(remote.push_tx(tx=spend_bundle))
    commit_and_notify(remote, wallets, Wallet())

    assert wallet_a.current_balance == 999995000
    assert wallet_b.current_rl_balance == 4980
    assert wallet_c.current_balance == 20

    spend_bundle = wallet_a.clawback_rl_coin()
    _ = run(remote.push_tx(tx=spend_bundle))
    commit_and_notify(remote, wallets, Wallet())
    assert wallet_a.current_balance == 999999980
    assert wallet_b.current_rl_balance == 0
    assert wallet_c.current_balance == 20
Exemple #3
0
def test_spending_over_limit():
    remote = make_client_server()
    run = asyncio.get_event_loop().run_until_complete
    # A gives B some money, but B can only send that money to C (and generate change for itself)
    wallet_a = RLWallet()
    wallet_b = RLWallet()
    wallet_c = RLWallet()
    wallets = [wallet_a, wallet_b, wallet_c]

    limit = 20
    interval = 2
    commit_and_notify(remote, wallets, wallet_a)

    origin_coin = wallet_a.my_utxos.copy().pop()
    wallet_b_pk = bytes(wallet_b.get_next_public_key())
    wallet_b.set_origin(origin_coin)
    wallet_b.limit = limit
    wallet_b.interval = interval
    clawback_pk = bytes(wallet_a.get_next_public_key())
    clawback_pk = hexbytes(clawback_pk)
    wallet_b.rl_clawback_pk = clawback_pk
    rl_puzzle = wallet_b.rl_puzzle_for_pk(wallet_b_pk, limit, interval,
                                          origin_coin.name(), clawback_pk)
    rl_puzzlehash = ProgramHash(rl_puzzle)
    wallet_a.clawback_puzzlehash = rl_puzzlehash
    wallet_a.rl_receiver_pk = wallet_b_pk
    wallet_a.clawback_pk = clawback_pk
    wallet_a.clawback_interval = interval
    wallet_a.clawback_limit = limit
    wallet_a.clawback_origin = origin_coin.name()

    # wallet A is normal wallet, it sends coin that's rate limited to wallet B
    amount = 5000
    spend_bundle = wallet_a.generate_signed_transaction_with_origin(
        amount, rl_puzzlehash, origin_coin.name())
    _ = run(remote.push_tx(tx=spend_bundle))
    commit_and_notify(remote, wallets, Wallet())

    assert wallet_a.current_balance == 999995000
    assert wallet_b.current_rl_balance == 5000
    assert wallet_c.current_balance == 0

    commit_and_notify(remote, wallets, Wallet())
    commit_and_notify(remote, wallets, Wallet())
    assert wallet_b.rl_available_balance() == 20

    amount = 30
    spend_bundle = wallet_b.rl_generate_signed_transaction(
        30, wallet_c.get_new_puzzlehash())
    _ = run(remote.push_tx(tx=spend_bundle))
    assert _.args[0].startswith(
        "exception: (<Err.ASSERT_BLOCK_AGE_EXCEEDS_FAILED: 13>")
    commit_and_notify(remote, wallets, Wallet())
    assert wallet_a.current_balance == 999995000
    assert wallet_b.current_rl_balance == 5000
    assert wallet_c.current_balance == 0