def test_dedup_signatures(stubbed_blockhash): """Test signature deduplication.""" acc1, acc2 = Account(), Account() transfer1 = sp.transfer(sp.TransferParams(from_pubkey=acc1.public_key(), to_pubkey=acc2.public_key(), lamports=123)) transfer2 = sp.transfer(sp.TransferParams(from_pubkey=acc1.public_key(), to_pubkey=acc2.public_key(), lamports=123)) txn = txlib.Transaction(recent_blockhash=stubbed_blockhash).add(transfer1, transfer2) txn.sign(acc1)
def test_transfer_signatures(stubbed_blockhash): """Test signing transfer transactions.""" acc1, acc2 = Account(), Account() transfer1 = sp.transfer(sp.TransferParams(from_pubkey=acc1.public_key(), to_pubkey=acc2.public_key(), lamports=123)) transfer2 = sp.transfer(sp.TransferParams(from_pubkey=acc2.public_key(), to_pubkey=acc1.public_key(), lamports=123)) txn = txlib.Transaction(recent_blockhash=stubbed_blockhash).add(transfer1, transfer2) txn.sign(acc1, acc2) expected = txlib.Transaction(recent_blockhash=stubbed_blockhash, signatures=txn.signatures).add( transfer1, transfer2 ) assert txn == expected
def test_dedup_signatures(stubbed_blockhash): """Test signature deduplication.""" kp1, kp2 = Keypair(), Keypair() transfer1 = sp.transfer( sp.TransferParams(from_pubkey=kp1.public_key, to_pubkey=kp2.public_key, lamports=123)) transfer2 = sp.transfer( sp.TransferParams(from_pubkey=kp1.public_key, to_pubkey=kp2.public_key, lamports=123)) txn = txlib.Transaction(recent_blockhash=stubbed_blockhash).add( transfer1, transfer2) txn.sign(kp1)
async def test_send_raw_transaction_and_get_balance(async_stubbed_sender, async_stubbed_receiver, test_http_client_async): """Test sending a raw transaction to localnet.""" # Get a recent blockhash resp = await test_http_client_async.get_recent_blockhash(Finalized) assert_valid_response(resp) recent_blockhash = resp["result"]["value"]["blockhash"] # Create transfer tx transfer lamports from stubbed sender to async_stubbed_receiver transfer_tx = Transaction(recent_blockhash=recent_blockhash).add( sp.transfer( sp.TransferParams(from_pubkey=async_stubbed_sender.public_key, to_pubkey=async_stubbed_receiver, lamports=1000))) # Sign transaction transfer_tx.sign(async_stubbed_sender) # Send raw transaction resp = await test_http_client_async.send_raw_transaction( transfer_tx.serialize()) assert_valid_response(resp) # Confirm transaction resp = await test_http_client_async.confirm_transaction(resp["result"]) # Check balances resp = await test_http_client_async.get_balance( async_stubbed_sender.public_key) assert_valid_response(resp) assert resp["result"]["value"] == 9999988000 resp = await test_http_client_async.get_balance(async_stubbed_receiver) assert_valid_response(resp) assert resp["result"]["value"] == 10000002000
def test_send_transaction_and_get_balance( stubbed_sender, stubbed_reciever, test_http_client ): # pylint: disable=redefined-outer-name # pylint: disable=redefined-outer-name """Test sending a transaction to localnet.""" # Create transfer tx to transfer lamports from stubbed sender to stubbed_reciever transfer_tx = sp.transfer( sp.TransferParams(from_pubkey=stubbed_sender.public_key(), to_pubkey=stubbed_reciever, lamports=1000) ) resp = test_http_client.send_transaction(transfer_tx, stubbed_sender) assert_valid_response(resp) # Confirm transaction resp = confirm_transaction(test_http_client, resp["result"]) assert_valid_response(resp) expected_meta = { "err": None, "fee": 5000, "postBalances": [9999994000, 954, 1], "preBalances": [10000000000, 0, 1], "status": {"Ok": None}, } assert resp["result"]["meta"] == expected_meta # Check balances resp = test_http_client.get_balance(stubbed_sender.public_key()) assert_valid_response(resp) assert resp["result"]["value"] == 9999994000 resp = test_http_client.get_balance(stubbed_reciever) assert_valid_response(resp) assert resp["result"]["value"] == 954
async def test_send_transaction_prefetched_blockhash( async_stubbed_sender_prefetched_blockhash, async_stubbed_receiver_prefetched_blockhash, test_http_client_async): """Test sending a transaction to localnet.""" # Create transfer tx to transfer lamports from stubbed sender to async_stubbed_receiver transfer_tx = Transaction().add( sp.transfer( sp.TransferParams( from_pubkey=async_stubbed_sender_prefetched_blockhash. public_key, to_pubkey=async_stubbed_receiver_prefetched_blockhash, lamports=1000, ))) resp = await test_http_client_async.send_transaction( transfer_tx, async_stubbed_sender_prefetched_blockhash) assert_valid_response(resp) # Confirm transaction await test_http_client_async.confirm_transaction(resp["result"]) # Check balances resp = await test_http_client_async.get_balance( async_stubbed_sender_prefetched_blockhash.public_key) assert_valid_response(resp) assert resp["result"]["value"] == 9999994000 resp = await test_http_client_async.get_balance( async_stubbed_receiver_prefetched_blockhash) assert_valid_response(resp) assert resp["result"]["value"] == 10000001000
def test_send_transaction_prefetched_blockhash( stubbed_sender_prefetched_blockhash, stubbed_receiver_prefetched_blockhash, test_http_client): """Test sending a transaction to localnet.""" # Create transfer tx to transfer lamports from stubbed sender to stubbed_receiver transfer_tx = Transaction().add( sp.transfer( sp.TransferParams( from_pubkey=stubbed_sender_prefetched_blockhash.public_key, to_pubkey=stubbed_receiver_prefetched_blockhash, lamports=1000, ))) recent_blockhash = test_http_client.parse_recent_blockhash( test_http_client.get_recent_blockhash(Finalized)) resp = test_http_client.send_transaction( transfer_tx, stubbed_sender_prefetched_blockhash, recent_blockhash=recent_blockhash) assert_valid_response(resp) # Confirm transaction test_http_client.confirm_transaction(resp["result"]) # Check balances resp = test_http_client.get_balance( stubbed_sender_prefetched_blockhash.public_key) assert_valid_response(resp) assert resp["result"]["value"] == 9999994000 resp = test_http_client.get_balance(stubbed_receiver_prefetched_blockhash) assert_valid_response(resp) assert resp["result"]["value"] == 10000001000
def test_serialize_unsigned_transaction(stubbed_blockhash, stubbed_reciever, stubbed_sender): """Test to serialize an unsigned transaction.""" transfer = sp.transfer( sp.TransferParams(from_pubkey=stubbed_sender.public_key(), to_pubkey=stubbed_reciever, lamports=49) ) txn = txlib.Transaction(recent_blockhash=stubbed_blockhash).add(transfer) assert len(txn.signatures) == 0 # Empty signature array fails with pytest.raises(AttributeError): txn.serialize() assert len(txn.signatures) == 0 # Serialize message assert b64encode(txn.serialize_message()) == ( b"AQABAxOY9ixtGkV8UbpqS189vS9p/KkyFiGNyJl+QWvRfZPK/UOfzLZnJ/KJxcbeO8So/l3V13dwvI/xXD7u3LFK8/wAAAAAAAAA" b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMSa53YDeCBU8Xqd7OpDtETroO2xLG8dMcbg5KhL8FLrAQICAAEMAgAAADEAAAAAAAAA" ) assert len(txn.instructions) == 1 # Signature array populated with null signatures fails with pytest.raises(AttributeError): txn.serialize() assert len(txn.signatures) == 1 # Properly signed transaction succeeds txn.sign(stubbed_sender) assert len(txn.instructions) == 1 expected_serialization = b64decode( b"AVuErQHaXv0SG0/PchunfxHKt8wMRfMZzqV0tkC5qO6owYxWU2v871AoWywGoFQr4z+q/7mE8lIufNl/kxj+nQ0BAAEDE5j2" b"LG0aRXxRumpLXz29L2n8qTIWIY3ImX5Ba9F9k8r9Q5/Mtmcn8onFxt47xKj+XdXXd3C8j/FcPu7csUrz/AAAAAAAAAAAAAAA" b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAxJrndgN4IFTxep3s6kO0ROug7bEsbx0xxuDkqEvwUusBAgIAAQwCAAAAMQAAAAAAAAA=" ) assert txn.serialize() == expected_serialization assert len(txn.signatures) == 1
def test_send_transaction_and_get_balance(stubbed_sender, stubbed_reciever, test_http_client): """Test sending a transaction to localnet.""" # Create transfer tx to transfer lamports from stubbed sender to stubbed_reciever transfer_tx = Transaction().add( sp.transfer( sp.TransferParams(from_pubkey=stubbed_sender.public_key(), to_pubkey=stubbed_reciever, lamports=1000) ) ) resp = test_http_client.send_transaction(transfer_tx, stubbed_sender) assert_valid_response(resp) # Confirm transaction resp = confirm_transaction(test_http_client, resp["result"]) assert_valid_response(resp) expected_meta = { "err": None, "fee": 5000, "innerInstructions": [], "logMessages": [ "Program 11111111111111111111111111111111 invoke [1]", "Program 11111111111111111111111111111111 success", ], "postBalances": [9999994000, 954, 1], "postTokenBalances": [], "preBalances": [10000000000, 0, 1], "preTokenBalances": [], "status": {"Ok": None}, } assert resp["result"]["meta"] == expected_meta # Check balances resp = test_http_client.get_balance(stubbed_sender.public_key()) assert_valid_response(resp) assert resp["result"]["value"] == 9999994000 resp = test_http_client.get_balance(stubbed_reciever) assert_valid_response(resp) assert resp["result"]["value"] == 954
def test_transfer(): """Test creating a transaction for transfer.""" params = sp.TransferParams(from_pubkey=Account().public_key(), to_pubkey=Account().public_key(), lamports=123) txn = sp.transfer(params) assert len(txn.instructions) == 1 assert sp.decode_transfer(txn.instructions[0]) == params
def test_transfer_signatures(stubbed_blockhash): """Test signing transfer transactions.""" kp1, kp2 = Keypair(), Keypair() transfer1 = sp.transfer( sp.TransferParams(from_pubkey=kp1.public_key, to_pubkey=kp2.public_key, lamports=123)) transfer2 = sp.transfer( sp.TransferParams(from_pubkey=kp2.public_key, to_pubkey=kp1.public_key, lamports=123)) txn = txlib.Transaction(recent_blockhash=stubbed_blockhash).add( transfer1, transfer2) txn.sign(kp1, kp2) expected = txlib.Transaction(recent_blockhash=stubbed_blockhash, signatures=txn.signatures).add( transfer1, transfer2) assert txn == expected
async def test_send_raw_transaction_and_get_balance(alt_stubbed_sender, alt_stubbed_receiver, test_http_client_async): """Test sending a raw transaction to localnet.""" # Get a recent blockhash resp = await test_http_client_async.get_recent_blockhash() assert_valid_response(resp) recent_blockhash = resp["result"]["value"]["blockhash"] # Create transfer tx transfer lamports from stubbed sender to alt_stubbed_receiver transfer_tx = Transaction(recent_blockhash=recent_blockhash).add( sp.transfer( sp.TransferParams(from_pubkey=alt_stubbed_sender.public_key(), to_pubkey=alt_stubbed_receiver, lamports=1000))) # Sign transaction transfer_tx.sign(alt_stubbed_sender) # Send raw transaction resp = await test_http_client_async.send_raw_transaction( transfer_tx.serialize()) assert_valid_response(resp) # Confirm transaction resp = await aconfirm_transaction(test_http_client_async, resp["result"]) assert_valid_response(resp) expected_meta = { "err": None, "fee": 5000, "innerInstructions": [], "logMessages": [ "Program 11111111111111111111111111111111 invoke [1]", "Program 11111111111111111111111111111111 success", ], "postBalances": [9999988000, 1954, 1], "postTokenBalances": [], "preBalances": [9999994000, 954, 1], "preTokenBalances": [], "rewards": [], "status": { "Ok": None }, } assert resp["result"]["meta"] == expected_meta # Check balances resp = await test_http_client_async.get_balance( alt_stubbed_sender.public_key()) assert_valid_response(resp) assert resp["result"]["value"] == 9999988000 resp = await test_http_client_async.get_balance(alt_stubbed_receiver) assert_valid_response(resp) assert resp["result"]["value"] == 1954
def test_sign_partial(stubbed_blockhash): """Test paritally sigining a transaction.""" acc1, acc2 = Account(), Account() transfer = sp.transfer(sp.TransferParams(from_pubkey=acc1.public_key(), to_pubkey=acc2.public_key(), lamports=123)) partial_txn = txlib.Transaction(recent_blockhash=stubbed_blockhash).add(transfer) partial_txn.sign_partial(acc1, acc2.public_key()) assert len(partial_txn.signature()) == txlib.SIG_LENGTH assert len(partial_txn.signatures) == 2 assert not partial_txn.signatures[1].signature partial_txn.add_signer(acc2) expected_txn = txlib.Transaction(recent_blockhash=stubbed_blockhash).add(transfer) expected_txn.sign(acc1, acc2) assert partial_txn == expected_txn
async def test_send_transaction_and_get_balance(alt_stubbed_sender, alt_stubbed_receiver, test_http_client_async): """Test sending a transaction to localnet.""" # Create transfer tx to transfer lamports from stubbed sender to alt_stubbed_receiver transfer_tx = Transaction().add( sp.transfer( sp.TransferParams(from_pubkey=alt_stubbed_sender.public_key(), to_pubkey=alt_stubbed_receiver, lamports=1000))) resp = await test_http_client_async.send_transaction( transfer_tx, alt_stubbed_sender) assert_valid_response(resp) # Confirm transaction resp = await aconfirm_transaction(test_http_client_async, resp["result"]) assert_valid_response(resp) expected_meta = { "err": None, "fee": 5000, "innerInstructions": [], "logMessages": [ "Program 11111111111111111111111111111111 invoke [1]", "Program 11111111111111111111111111111111 success", ], "postBalances": [9999994000, 954, 1], "postTokenBalances": [], "preBalances": [10000000000, 0, 1], "preTokenBalances": [], "rewards": [{ "commission": None, "lamports": -46, "postBalance": 954, "pubkey": "J3dxNj7nDRRqRRXuEMynDG57DkZK4jYRuv3Garmb1i98", "rewardType": "Rent", }], "status": { "Ok": None }, } assert resp["result"]["meta"] == expected_meta # Check balances resp = await test_http_client_async.get_balance( alt_stubbed_sender.public_key()) assert_valid_response(resp) assert resp["result"]["value"] == 9999994000 resp = await test_http_client_async.get_balance(alt_stubbed_receiver) assert_valid_response(resp) assert resp["result"]["value"] == 954
def test_wire_format_and_desrialize(stubbed_blockhash, stubbed_reciever, stubbed_sender): """Test serialize/derialize transaction to/from wire format.""" transfer = sp.transfer( sp.TransferParams(from_pubkey=stubbed_sender.public_key(), to_pubkey=stubbed_reciever, lamports=49) ) expected_txn = txlib.Transaction(recent_blockhash=stubbed_blockhash).add(transfer) expected_txn.sign(stubbed_sender) wire_txn = b64decode( b"AVuErQHaXv0SG0/PchunfxHKt8wMRfMZzqV0tkC5qO6owYxWU2v871AoWywGoFQr4z+q/7mE8lIufNl/kxj+nQ0BAAEDE5j2" b"LG0aRXxRumpLXz29L2n8qTIWIY3ImX5Ba9F9k8r9Q5/Mtmcn8onFxt47xKj+XdXXd3C8j/FcPu7csUrz/AAAAAAAAAAAAAAA" b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAxJrndgN4IFTxep3s6kO0ROug7bEsbx0xxuDkqEvwUusBAgIAAQwCAAAAMQAAAAAAAAA=" ) txn = txlib.Transaction.deserialize(wire_txn) assert txn == expected_txn assert wire_txn == expected_txn.serialize()
def test_sign_partial(stubbed_blockhash): """Test paritally sigining a transaction.""" kp1, kp2 = Keypair(), Keypair() transfer = sp.transfer( sp.TransferParams(from_pubkey=kp1.public_key, to_pubkey=kp2.public_key, lamports=123)) partial_txn = txlib.Transaction( recent_blockhash=stubbed_blockhash).add(transfer) partial_txn.sign_partial(kp1, kp2.public_key) assert len(partial_txn.signature()) == txlib.SIG_LENGTH assert len(partial_txn.signatures) == 2 assert not partial_txn.signatures[1].signature partial_txn.add_signer(kp2) expected_txn = txlib.Transaction( recent_blockhash=stubbed_blockhash).add(transfer) expected_txn.sign(kp1, kp2) assert partial_txn == expected_txn
def test_send_transaction_and_get_balance(stubbed_sender, stubbed_receiver, test_http_client): """Test sending a transaction to localnet.""" # Create transfer tx to transfer lamports from stubbed sender to stubbed_receiver transfer_tx = Transaction().add( sp.transfer( sp.TransferParams(from_pubkey=stubbed_sender.public_key, to_pubkey=stubbed_receiver, lamports=1000))) resp = test_http_client.send_transaction(transfer_tx, stubbed_sender) assert_valid_response(resp) # Confirm transaction test_http_client.confirm_transaction(resp["result"]) # Check balances resp = test_http_client.get_balance(stubbed_sender.public_key) assert_valid_response(resp) assert resp["result"]["value"] == 9999994000 resp = test_http_client.get_balance(stubbed_receiver) assert_valid_response(resp) assert resp["result"]["value"] == 10000001000
def _create_wrapped_native_account_args( program_id: PublicKey, owner: PublicKey, payer: Keypair, amount: int, skip_confirmation: bool, balance_needed: int, ) -> Tuple[PublicKey, Transaction, Keypair, Keypair, TxOpts]: new_keypair = Keypair() # Allocate memory for the account # Construct transaction txn = Transaction() txn.add( sp.create_account( sp.CreateAccountParams( from_pubkey=payer.public_key, new_account_pubkey=new_keypair.public_key, lamports=balance_needed, space=ACCOUNT_LAYOUT.sizeof(), program_id=program_id, ) ) ) txn.add( sp.transfer( sp.TransferParams(from_pubkey=payer.public_key, to_pubkey=new_keypair.public_key, lamports=amount) ) ) txn.add( spl_token.initialize_account( spl_token.InitializeAccountParams( account=new_keypair.public_key, mint=WRAPPED_SOL_MINT, owner=owner, program_id=program_id ) ) ) return new_keypair.public_key, txn, payer, new_keypair, TxOpts(skip_confirmation=skip_confirmation)
def test_transfer(): """Test creating a transaction for transfer.""" params = sp.TransferParams(from_pubkey=Account().public_key(), to_pubkey=Account().public_key(), lamports=123) assert sp.decode_transfer(sp.transfer(params)) == params
async def test_send_transaction_cached_blockhash( async_stubbed_sender_cached_blockhash, async_stubbed_receiver_cached_blockhash, test_http_client_async_cached_blockhash, ): """Test sending a transaction to localnet.""" # Create transfer tx to transfer lamports from stubbed sender to stubbed_receiver transfer_tx = Transaction().add( sp.transfer( sp.TransferParams( from_pubkey=async_stubbed_sender_cached_blockhash.public_key, to_pubkey=async_stubbed_receiver_cached_blockhash, lamports=1000, ))) assert len(test_http_client_async_cached_blockhash.blockhash_cache. unused_blockhashes) == 0 assert len(test_http_client_async_cached_blockhash.blockhash_cache. used_blockhashes) == 0 resp = await test_http_client_async_cached_blockhash.send_transaction( transfer_tx, async_stubbed_sender_cached_blockhash) # we could have got a new blockhash or not depending on network latency and luck assert len(test_http_client_async_cached_blockhash.blockhash_cache. unused_blockhashes) in (0, 1) assert len(test_http_client_async_cached_blockhash.blockhash_cache. used_blockhashes) == 1 assert_valid_response(resp) # Confirm transaction await test_http_client_async_cached_blockhash.confirm_transaction( resp["result"]) # Check balances resp = await test_http_client_async_cached_blockhash.get_balance( async_stubbed_sender_cached_blockhash.public_key) assert_valid_response(resp) assert resp["result"]["value"] == 9999994000 # Second transaction transfer_tx = Transaction().add( sp.transfer( sp.TransferParams( from_pubkey=async_stubbed_sender_cached_blockhash.public_key, to_pubkey=async_stubbed_receiver_cached_blockhash, lamports=2000, ))) resp = await test_http_client_async_cached_blockhash.get_balance( async_stubbed_receiver_cached_blockhash) assert_valid_response(resp) assert resp["result"]["value"] == 10000001000 resp = await test_http_client_async_cached_blockhash.send_transaction( transfer_tx, async_stubbed_sender_cached_blockhash) # we could have got a new blockhash or not depending on network latency and luck assert len(test_http_client_async_cached_blockhash.blockhash_cache. unused_blockhashes) in (0, 1) assert len(test_http_client_async_cached_blockhash.blockhash_cache. used_blockhashes) in (1, 2) assert_valid_response(resp) # Confirm transaction resp = await test_http_client_async_cached_blockhash.confirm_transaction( resp["result"]) # Check balances resp = await test_http_client_async_cached_blockhash.get_balance( async_stubbed_sender_cached_blockhash.public_key) assert_valid_response(resp) assert resp["result"]["value"] == 9999987000
def test_advance_nonce_and_transfer(): from_keypair = Keypair.from_secret_key( bytes([ 134, 123, 27, 208, 227, 175, 253, 99, 4, 81, 170, 231, 186, 141, 177, 142, 197, 139, 94, 6, 157, 2, 163, 89, 150, 121, 235, 86, 185, 22, 1, 233, 58, 133, 229, 39, 212, 71, 254, 72, 246, 45, 160, 156, 129, 199, 18, 189, 53, 143, 98, 72, 182, 106, 69, 29, 38, 145, 119, 190, 13, 105, 157, 112, ])) nonce_keypair = Keypair.from_secret_key( bytes([ 139, 81, 72, 75, 252, 57, 73, 247, 63, 130, 201, 76, 183, 43, 60, 197, 65, 154, 28, 240, 134, 0, 232, 108, 61, 123, 56, 26, 35, 201, 13, 39, 188, 128, 179, 175, 136, 5, 89, 185, 92, 183, 175, 131, 56, 53, 228, 11, 20, 34, 138, 148, 51, 27, 205, 76, 75, 148, 184, 34, 74, 129, 238, 225, ])) to_keypair = Keypair.from_secret_key( bytes([ 56, 246, 74, 56, 168, 158, 189, 97, 126, 149, 175, 70, 23, 14, 251, 206, 172, 69, 61, 247, 39, 226, 8, 68, 97, 159, 11, 196, 212, 57, 2, 1, 252, 124, 54, 3, 18, 109, 223, 27, 225, 28, 59, 202, 49, 248, 244, 17, 165, 33, 101, 59, 217, 79, 234, 217, 251, 85, 9, 6, 40, 0, 221, 10, ])) wire_txn = base64.b64decode( b"Abh4hJNaP/IUJlHGpQttaGNWkjOZx71uLEnVpT0SBaedmThsTogjsh87FW+EHeuJrsZii+tJbrq3oJ5UYXPzXwwBAAIFOoXl" b"J9RH/kj2LaCcgccSvTWPYki2akUdJpF3vg1pnXC8gLOviAVZuVy3r4M4NeQLFCKKlDMbzUxLlLgiSoHu4fx8NgMSbd8b4Rw7" b"yjH49BGlIWU72U/q2ftVCQYoAN0KBqfVFxksVo7gioRfc9KXiM8DXDFFshqzRNgGLqlAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" b"AAAAAAAAAAAAAAAAAE13Mu8zaQSpG0zzGHpG62nK56DbGhuS4kXMF/ChHY1jAgQDAQMABAQAAAAEAgACDAIAAACAhB4AAAAA" b"AA==") expected_txn = txlib.Transaction.deserialize(wire_txn) txn = txlib.Transaction(fee_payer=from_keypair.public_key) txn.recent_blockhash = "6DPp9aRRX6cLBqj5FepEvoccHFs3s8gUhd9t9ftTwAta" txn.add( sp.nonce_advance( sp.AdvanceNonceParams( nonce_pubkey=nonce_keypair.public_key, authorized_pubkey=from_keypair.public_key, ))) txn.add( sp.transfer( sp.TransferParams(from_pubkey=from_keypair.public_key, to_pubkey=to_keypair.public_key, lamports=2000000))) txn_hash = txn.serialize_message() txn.add_signature(from_keypair.public_key, from_keypair.sign(txn_hash).signature) assert txn == expected_txn