Ejemplo n.º 1
0
def test_rl_spend_all():
    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 = 100
    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 = 300
    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 == 999999700
    assert wallet_b.current_rl_balance == 300
    assert wallet_c.current_balance == 0

    commit_and_notify(remote, wallets, Wallet())
    assert wallet_b.rl_available_balance() == 100
    commit_and_notify(remote, wallets, Wallet())
    assert wallet_b.rl_available_balance() == 200
    commit_and_notify(remote, wallets, Wallet())
    assert wallet_b.rl_available_balance() == 300

    amount = 300
    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 == 999999700
    assert wallet_b.current_rl_balance == 0
    assert wallet_c.current_balance == 300
Ejemplo n.º 2
0
def test_pubkey_format():
    wallet = Wallet()
    pubkey = wallet.get_next_public_key()
    assert pu.pubkey_format(
        pubkey) == f"0x{hexlify(pubkey.serialize()).decode('ascii')}"
    assert pu.pubkey_format(pubkey.serialize(
    )) == f"0x{hexlify(pubkey.serialize()).decode('ascii')}"
    assert pu.pubkey_format(hexlify(pubkey.serialize()).decode(
        'ascii')) == f"0x{hexlify(pubkey.serialize()).decode('ascii')}"
    assert pu.pubkey_format(
        f"0x{hexlify(pubkey.serialize()).decode('ascii')}"
    ) == f"0x{hexlify(pubkey.serialize()).decode('ascii')}"
Ejemplo n.º 3
0
def test_standard_spend():
    remote = make_client_server()
    run = asyncio.get_event_loop().run_until_complete
    wallet_a = Wallet()
    wallet_b = Wallet()
    wallets = [wallet_a, wallet_b]
    commit_and_notify(remote, wallets, wallet_a)

    assert wallet_a.current_balance == 1000000000
    assert len(wallet_a.my_utxos) == 2
    assert wallet_b.current_balance == 0
    assert len(wallet_b.my_utxos) == 0
    # wallet a send to wallet b
    pubkey_puz_string = "(0x%s)" % hexlify(
        wallet_b.get_next_public_key().serialize()).decode('ascii')
    args = binutils.assemble(pubkey_puz_string)
    program = Program(
        clvm.eval_f(
            clvm.eval_f,
            binutils.assemble(
                wallet_a.generator_lookups[wallet_b.puzzle_generator_id]),
            args))
    puzzlehash = ProgramHash(program)

    amount = 5000
    spend_bundle = wallet_a.generate_signed_transaction(amount, puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    # give new wallet the reward to not complicate the one's we're tracking
    commit_and_notify(remote, wallets, Wallet())

    assert wallet_a.current_balance == 999995000
    assert wallet_b.current_balance == 5000
    assert len(wallet_b.my_utxos) == 1

    # wallet b sends back to wallet a
    pubkey_puz_string = "(0x%s)" % hexlify(
        wallet_a.get_next_public_key().serialize()).decode('ascii')
    args = binutils.assemble(pubkey_puz_string)
    program = Program(
        clvm.eval_f(
            clvm.eval_f,
            binutils.assemble(
                wallet_b.generator_lookups[wallet_a.puzzle_generator_id]),
            args))
    puzzlehash = ProgramHash(program)

    amount = 5000
    spend_bundle = wallet_b.generate_signed_transaction(amount, puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    # give new wallet the reward to not complicate the one's we're tracking
    commit_and_notify(remote, wallets, Wallet())
    assert wallet_a.current_balance == 1000000000
    assert wallet_b.current_balance == 0
def test_cp_with_permission():
    remote = make_client_server()
    run = asyncio.get_event_loop().run_until_complete

    wallet_a = CPWallet()
    wallet_b = CPWallet()
    wallet_c = CPWallet()
    wallets = [wallet_a, wallet_b, wallet_c]
    pub_a = hexbytes(wallet_a.get_next_public_key())
    pub_b = hexbytes(wallet_b.get_next_public_key())
    unlock_time = 5
    wallet_b.pubkey_permission = pub_a
    wallet_b.unlock_time = unlock_time
    wallet_a.pubkey_approval = pub_a
    b_puzzle = wallet_b.cp_puzzle(pub_b, pub_a, unlock_time)
    b_puzzlehash = ProgramHash(b_puzzle)

    commit_and_notify(remote, wallets, wallet_a)
    # Set time to 4, time needs to exceed 5, unless there is approval from authorizer
    _ = run(remote.skip_milliseconds(ms=uint64(4).to_bytes(4, 'big')))

    assert wallet_a.current_balance == 1000000000
    assert wallet_b.current_balance == 0
    assert wallet_c.current_balance == 0

    spend_bundle = wallet_a.generate_signed_transaction(1000, b_puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    commit_and_notify(remote, wallets, Wallet())

    assert wallet_a.current_balance == 999999000
    assert wallet_b.cp_balance == 1000
    assert wallet_c.current_balance == 0

    puzzlehash_c = wallet_c.get_new_puzzlehash()
    amount = 100
    mode = 2
    transaction = wallet_b.cp_generate_unsigned_transaction(
        puzzlehash_c, amount, mode)
    solution = transaction[0][1].solution
    approval_a = wallet_a.cp_approval_signature_for_transaction(solution).sig
    spend_bundle = wallet_b.cp_generate_signed_transaction_with_approval(
        puzzlehash_c, amount, approval_a)
    _ = run(remote.push_tx(tx=spend_bundle))
    commit_and_notify(remote, wallets, Wallet())

    assert wallet_a.current_balance == 999999000
    assert wallet_b.cp_balance == 900
    assert wallet_c.current_balance == 100
def test_cp_receive():
    remote = make_client_server()
    run = asyncio.get_event_loop().run_until_complete

    wallet_a = CPWallet()
    wallet_b = CPWallet()
    wallet_c = CPWallet()
    wallets = [wallet_a, wallet_b, wallet_c]
    pub_a = hexbytes(wallet_a.get_next_public_key())
    pub_b = hexbytes(wallet_b.get_next_public_key())
    wallet_b.pubkey_permission = pub_a
    wallet_b.unlock_time = 100
    b_puzzle = wallet_b.cp_puzzle(pub_b, pub_a, 100)
    b_puzzlehash = ProgramHash(b_puzzle)

    commit_and_notify(remote, wallets, wallet_a)

    assert wallet_a.current_balance == 1000000000
    assert wallet_b.current_balance == 0
    assert wallet_c.current_balance == 0

    spend_bundle = wallet_a.generate_signed_transaction(1000, b_puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    commit_and_notify(remote, wallets, Wallet())

    assert wallet_a.current_balance == 999999000
    assert wallet_b.cp_balance == 1000
    assert wallet_c.current_balance == 0
def test_cp_send_solo():
    remote = make_client_server()
    run = asyncio.get_event_loop().run_until_complete

    wallet_a = CPWallet()
    wallet_b = CPWallet()
    wallet_c = CPWallet()
    wallets = [wallet_a, wallet_b, wallet_c]
    pub_a = hexbytes(wallet_a.get_next_public_key())
    pub_b = hexbytes(wallet_b.get_next_public_key())
    wallet_b.pubkey_permission = pub_a
    wallet_b.unlock_time = 3
    b_puzzle = wallet_b.cp_puzzle(pub_b, pub_a, 3)
    b_puzzlehash = ProgramHash(b_puzzle)

    # Set ledger api to
    _ = run(remote.skip_milliseconds(ms=uint64(4).to_bytes(4, 'big')))

    commit_and_notify(remote, wallets, wallet_a)

    assert wallet_a.current_balance == 1000000000
    assert wallet_b.current_balance == 0
    assert wallet_c.current_balance == 0

    spend_bundle = wallet_a.generate_signed_transaction(1000, b_puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    commit_and_notify(remote, wallets, Wallet())

    assert wallet_a.current_balance == 999999000
    assert wallet_b.cp_balance == 1000
    assert wallet_c.current_balance == 0

    puzzlehash_c = wallet_c.get_new_puzzlehash()
    spend_bundle = wallet_b.cp_generate_signed_transaction(puzzlehash_c, 100)
    _ = run(remote.push_tx(tx=spend_bundle))
    commit_and_notify(remote, wallets, Wallet())

    assert wallet_a.current_balance == 999999000
    assert wallet_b.cp_balance == 900
    assert wallet_c.current_balance == 100
Ejemplo n.º 7
0
def test_standard_spend():
    remote = make_client_server()
    run = asyncio.get_event_loop().run_until_complete
    wallet_a = Wallet()
    wallet_b = Wallet()
    wallets = [wallet_a, wallet_b]
    commit_and_notify(remote, wallets, wallet_a)

    assert wallet_a.current_balance == 1000000000
    assert len(wallet_a.my_utxos) == 2
    assert wallet_b.current_balance == 0
    assert len(wallet_b.my_utxos) == 0
    # wallet a send to wallet b
    program = wallet_b.get_new_puzzle()
    puzzlehash = ProgramHash(program)

    amount = 5000
    spend_bundle = wallet_a.generate_signed_transaction(amount, puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    # give new wallet the reward to not complicate the one's we're tracking
    commit_and_notify(remote, wallets, Wallet())

    assert wallet_a.current_balance == 999995000
    assert wallet_b.current_balance == 5000
    assert len(wallet_b.my_utxos) == 1

    # wallet b sends back to wallet a
    puzzlehash = wallet_a.get_new_puzzlehash()

    amount = 5000
    spend_bundle = wallet_b.generate_signed_transaction(amount, puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    # give new wallet the reward to not complicate the one's we're tracking
    commit_and_notify(remote, wallets, Wallet())
    assert wallet_a.current_balance == 1000000000
    assert wallet_b.current_balance == 0
Ejemplo n.º 8
0
async def main_loop():
    ledger_api = await connect_to_ledger_sim("localhost", 9868)
    selection = ""
    wallet = Wallet()
    print(divider)
    print_leaf()
    r = await ledger_api.get_tip()
    most_recent_header = r['genesis_hash']
    while selection != "q":
        print(divider)
        view_funds(wallet)
        print(divider)
        print(start_list)
        print("Select a function:")
        print(f"{selectable} 1: Make Payment")
        print(f"{selectable} 2: Get Update")
        print(f"{selectable} 3: Farm Block")
        print(f"{selectable} 4: Print my details for somebody else")
        print(f"{selectable} 5: Set my wallet name")
        print(f"{selectable} 6: Initiate Authorised Payee")
        if qrcode:
            print(f"{selectable} 7: Make QR code")
            print(f"{selectable} 8: Payment to QR code")
        print(f"{selectable} q: Quit")
        print(close_list)
        selection = input(prompt)
        if selection == "1":
            r = await make_payment(wallet, ledger_api)
        elif selection == "2":
            most_recent_header = await update_ledger(wallet, ledger_api,
                                                     most_recent_header)
        elif selection == "3":
            most_recent_header = await farm_block(wallet, ledger_api,
                                                  most_recent_header)
        elif selection == "4":
            print_my_details(wallet)
        elif selection == "5":
            set_name(wallet)
        elif selection == "6":
            await initiate_ap(wallet, ledger_api)
        if qrcode:
            if selection == "7":
                make_QR(wallet)
            elif selection == "8":
                r = read_qr(wallet)
                if r is not None:
                    await ledger_api.push_tx(tx=r)
Ejemplo n.º 9
0
def test_future_utxos():
    remote = make_client_server()
    run = asyncio.get_event_loop().run_until_complete
    wallet_a = Wallet()
    wallet_b = Wallet()
    wallets = [wallet_a, wallet_b]
    commit_and_notify(remote, wallets, wallet_a)

    assert wallet_a.current_balance == 1000000000
    assert len(wallet_a.my_utxos) == 2
    assert wallet_b.current_balance == 0
    assert len(wallet_b.my_utxos) == 0

    amount = 5000
    puzzlehash = wallet_b.get_new_puzzlehash()
    spend_bundle = wallet_a.generate_signed_transaction(amount, puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    puzzlehash = wallet_b.get_new_puzzlehash()
    spend_bundle = wallet_a.generate_signed_transaction(amount, puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    puzzlehash = wallet_b.get_new_puzzlehash()
    spend_bundle = wallet_a.generate_signed_transaction(amount, puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))

    assert wallet_a.current_balance == 1000000000
    assert wallet_a.temp_balance == 999985000

    commit_and_notify(remote, wallets, Wallet())
    assert wallet_a.current_balance == 999985000
    assert wallet_b.current_balance == 15000
    assert len(wallet_b.my_utxos) == 3
    assert wallet_b.my_utxos.copy().pop().amount == 5000

    # test wallet spend multiple coins in one spendbundle
    puzzlehash = wallet_a.get_new_puzzlehash()
    spend_bundle = wallet_b.generate_signed_transaction(15000, puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    commit_and_notify(remote, wallets, Wallet())
    assert wallet_a.current_balance == 1000000000
    assert wallet_b.current_balance == 0
Ejemplo n.º 10
0
def test_spend_failure():
    remote = make_client_server()
    run = asyncio.get_event_loop().run_until_complete
    wallet_a = Wallet()
    wallet_b = Wallet()
    wallets = [wallet_a, wallet_b]
    amount = 5000
    # wallet a send to wallet b
    program = wallet_b.get_new_puzzle()
    puzzlehash = ProgramHash(program)
    spend_bundle = wallet_a.generate_signed_transaction(amount, puzzlehash)
    assert spend_bundle is None

    commit_and_notify(remote, wallets, wallet_a)
    amount = 50000000000000
    puzzlehash = wallet_b.get_new_puzzlehash()
    spend_bundle = wallet_a.generate_signed_transaction(amount, puzzlehash)
    assert spend_bundle is None
    amount = 999995000
    puzzlehash = wallet_b.get_new_puzzlehash()
    spend_bundle = wallet_a.generate_signed_transaction(amount, puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    assert wallet_a.temp_balance == 5000

    amount = 6000
    puzzlehash = wallet_b.get_new_puzzlehash()
    spend_bundle = wallet_a.generate_signed_transaction(amount, puzzlehash)
    assert spend_bundle is None

    amount = 4000
    puzzlehash = wallet_b.get_new_puzzlehash()
    spend_bundle = wallet_a.generate_signed_transaction(amount, puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    assert wallet_a.temp_balance == 1000
    commit_and_notify(remote, wallets, Wallet())
    assert wallet_a.current_balance == 1000
    assert wallet_a.temp_balance == 1000
Ejemplo n.º 11
0
def test_pubkey_format():
    wallet = Wallet()
    pubkey = wallet.get_next_public_key()
    assert pu.pubkey_format(pubkey) == f"0x{bytes(pubkey).hex()}"
Ejemplo n.º 12
0
def test_AP_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 = Wallet()
    wallet_b = APWallet()
    wallet_c = Wallet()
    wallet_d = Wallet()

    wallets = [wallet_a, wallet_b, wallet_c, wallet_d]

    a_pubkey = wallet_a.get_next_public_key().serialize()
    b_pubkey = wallet_b.get_next_public_key().serialize()
    APpuzzlehash = ap_wallet_a_functions.ap_get_new_puzzlehash(
        a_pubkey, b_pubkey)
    wallet_b.set_sender_values(APpuzzlehash, a_pubkey)
    wallet_b.set_approved_change_signature(
        ap_wallet_a_functions.ap_sign_output_newpuzzlehash(
            APpuzzlehash, wallet_a, a_pubkey))

    commit_and_notify(remote, wallets, wallet_a)

    assert wallet_a.current_balance == 1000000000
    assert len(wallet_a.my_utxos) == 2
    assert wallet_b.current_balance == 0
    assert len(wallet_b.my_utxos) == 0

    # Wallet A locks up the puzzle with information regarding B's pubkey
    amount = 5000
    spend_bundle = wallet_a.generate_signed_transaction(amount, APpuzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))

    commit_and_notify(remote, wallets, wallet_d)

    assert wallet_a.current_balance == 999995000
    assert wallet_b.current_balance == 5000
    assert len(wallet_b.my_utxos) == 1

    # Wallet A sends more money into Wallet B using the aggregation coin
    aggregation_puzzlehash = ap_wallet_a_functions.ap_get_aggregation_puzzlehash(
        APpuzzlehash)
    # amount = 80
    spend_bundle = wallet_a.generate_signed_transaction(
        5000, aggregation_puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    spend_bundle = wallet_d.generate_signed_transaction(
        3000, aggregation_puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))

    commit_and_notify(remote, wallets, Wallet())

    assert wallet_a.current_balance == 999990000
    assert wallet_b.temp_coin.amount == 13000
    assert wallet_c.current_balance == 0
    assert wallet_d.current_balance == 999997000
    assert len(wallet_b.my_utxos) == 1

    commit_and_notify(remote, wallets, Wallet())

    assert wallet_b.current_balance == 13000

    approved_puzhashes = [wallet_c.get_new_puzzlehash()]

    signatures = [
        ap_wallet_a_functions.ap_sign_output_newpuzzlehash(
            approved_puzhashes[0], wallet_a, a_pubkey)
    ]
    ap_output = [(approved_puzhashes[0], 4000)]
    spend_bundle = wallet_b.ap_generate_signed_transaction(
        ap_output, signatures)
    _ = run(remote.push_tx(tx=spend_bundle))
    commit_and_notify(remote, wallets, Wallet())

    assert wallet_a.current_balance == 999990000
    assert wallet_b.temp_coin.amount == 9000
    assert wallet_c.current_balance == 4000
    assert len(wallet_c.my_utxos) == 1
    assert wallet_d.current_balance == 999997000
    assert len(wallet_b.my_utxos) == 1

    # Spend from wallet_c freely

    puzzlehash = wallet_a.get_new_puzzlehash()
    spend_bundle = wallet_c.generate_signed_transaction(2000, puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    commit_and_notify(remote, wallets, Wallet())

    assert wallet_c.current_balance == 2000
    assert len(wallet_c.my_utxos) == 1
    assert wallet_a.current_balance == 999992000

    # Test spend more money than AP wallet's amount

    ap_output = [(approved_puzhashes[0], 10000)]
    spend_bundle = wallet_b.ap_generate_signed_transaction(
        ap_output, signatures)
    assert spend_bundle is None

    ap_output = [(approved_puzhashes[0], 6000)]
    spend_bundle = wallet_b.ap_generate_signed_transaction(
        ap_output, signatures)
    _ = run(remote.push_tx(tx=spend_bundle))

    # Try and over spend temp amount, but legal actual amount

    assert wallet_b.temp_coin.amount == 3000
    assert wallet_b.current_balance == 9000

    ap_output = [(approved_puzhashes[0], 6000)]
    spend_bundle = wallet_b.ap_generate_signed_transaction(
        ap_output, signatures)

    assert spend_bundle is None
    assert wallet_b.temp_coin.amount == 3000
    assert wallet_b.current_balance == 9000
Ejemplo n.º 13
0
def test_invalid_payee():
    # Only Wallet C is approved - now lets try to spend to Wallet D
    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 = Wallet()
    wallet_b = APWallet()
    wallet_c = Wallet()
    wallet_d = Wallet()
    wallets = [wallet_a, wallet_b, wallet_c, wallet_d]

    a_pubkey = wallet_a.get_next_public_key().serialize()
    b_pubkey = wallet_b.get_next_public_key().serialize()
    APpuzzlehash = ap_wallet_a_functions.ap_get_new_puzzlehash(
        a_pubkey, b_pubkey)
    wallet_b.set_sender_values(APpuzzlehash, a_pubkey)
    wallet_b.set_approved_change_signature(
        ap_wallet_a_functions.ap_sign_output_newpuzzlehash(
            APpuzzlehash, wallet_a, a_pubkey))

    commit_and_notify(remote, wallets, wallet_a)

    assert wallet_a.current_balance == 1000000000
    assert len(wallet_a.my_utxos) == 2
    assert wallet_b.current_balance == 0
    assert len(wallet_b.my_utxos) == 0

    # Wallet A locks up the puzzle with information regarding B's pubkey
    amount = 5000
    spend_bundle = wallet_a.generate_signed_transaction(amount, APpuzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))

    commit_and_notify(remote, wallets, wallet_d)

    assert wallet_a.current_balance == 999995000
    assert wallet_b.current_balance == 5000
    assert len(wallet_b.my_utxos) == 1

    approved_puzhashes = [wallet_c.get_new_puzzlehash()]
    signatures = [
        ap_wallet_a_functions.ap_sign_output_newpuzzlehash(
            approved_puzhashes[0], wallet_a, a_pubkey)
    ]

    ap_output = [(wallet_d.get_new_puzzlehash(), 2000)]

    spend_bundle = wallet_b.ap_generate_signed_transaction(
        ap_output, signatures)
    _ = run(remote.push_tx(tx=spend_bundle))
    commit_and_notify(remote, wallets, Wallet())
    assert wallet_a.current_balance == 999995000
    assert wallet_b.current_balance == 5000
    assert wallet_b.temp_coin.amount == 5000
    assert len(wallet_b.my_utxos) == 1
Ejemplo n.º 14
0
def test_spend_failure():
    remote = make_client_server()
    run = asyncio.get_event_loop().run_until_complete
    wallet_a = Wallet()
    wallet_b = Wallet()
    wallets = [wallet_a, wallet_b]
    amount = 5000
    # wallet a send to wallet b
    pubkey_puz_string = "(0x%s)" % hexlify(
        wallet_b.get_next_public_key().serialize()).decode('ascii')
    args = binutils.assemble(pubkey_puz_string)
    program = Program(
        clvm.eval_f(
            clvm.eval_f,
            binutils.assemble(
                wallet_a.generator_lookups[wallet_b.puzzle_generator_id]),
            args))
    puzzlehash = ProgramHash(program)
    spend_bundle = wallet_a.generate_signed_transaction(amount, puzzlehash)
    assert spend_bundle is None

    commit_and_notify(remote, wallets, wallet_a)
    amount = 50000000000000
    puzzlehash = wallet_b.get_new_puzzlehash()
    spend_bundle = wallet_a.generate_signed_transaction(amount, puzzlehash)
    assert spend_bundle is None
    amount = 999995000
    puzzlehash = wallet_b.get_new_puzzlehash()
    spend_bundle = wallet_a.generate_signed_transaction(amount, puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    assert wallet_a.temp_balance == 5000

    amount = 6000
    puzzlehash = wallet_b.get_new_puzzlehash()
    spend_bundle = wallet_a.generate_signed_transaction(amount, puzzlehash)
    assert spend_bundle is None

    amount = 4000
    puzzlehash = wallet_b.get_new_puzzlehash()
    spend_bundle = wallet_a.generate_signed_transaction(amount, puzzlehash)
    _ = run(remote.push_tx(tx=spend_bundle))
    assert wallet_a.temp_balance == 1000
    commit_and_notify(remote, wallets, Wallet())
    assert wallet_a.current_balance == 1000
    assert wallet_a.temp_balance == 1000