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
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')}"
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
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
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)
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
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
def test_pubkey_format(): wallet = Wallet() pubkey = wallet.get_next_public_key() assert pu.pubkey_format(pubkey) == f"0x{bytes(pubkey).hex()}"
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
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
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