def send_payment_meets_travel_rule_threshold( sender: AccountResource, receiver: AccountResource, payment_command_states: List[str], currency: str, amount: int, receiver_reject_additional_kyc_data_request: bool = False, ) -> None: sender_initial = sender.balance(currency) receiver_initial = receiver.balance(currency) payee = receiver.generate_account_identifier() sender.send_payment(currency, amount, payee) def match_exchange_states() -> None: states = [] for e in receiver.events(): if e.type in [ "created_payment_command", "updated_payment_command" ]: payment_object = json.loads(e.data)["payment_object"] payment = offchain.from_dict(payment_object, offchain.PaymentObject) states.append( offchain.payment_state.MACHINE.match_state(payment).id) assert states == payment_command_states receiver.wait_for(match_exchange_states) if payment_command_states[-1] == "READY": sender.wait_for_balance(currency, sender_initial - amount) receiver.wait_for_balance(currency, receiver_initial + amount) else: sender.wait_for_balance(currency, sender_initial) receiver.wait_for_balance(currency, receiver_initial)
def test_send_payment_to_the_other_account_in_the_same_wallet( sender_account: AccountResource, target_client: RestClient, currency: str, amount: int, ) -> None: """ Test Plan: 1. Create 2 accounts in target wallet application, one for sender, one for receiver. 2. Generate valid receive payment account identifier from the receiver account. 3. Send payment from sender account to receiver account. 4. Expect send payment success; receiver account balance increased by the amount sent; sender account balance decreased by the amount sent. """ sender_initial_balance = sender_account.balance(currency) receiver_account = target_client.create_account() receiver_account_identifier = receiver_account.generate_account_identifier( ) sender_account.send_payment(currency, amount, payee=receiver_account_identifier) sender_account.wait_for_balance(currency, sender_initial_balance - amount) receiver_account.wait_for_balance(currency, amount)
def test_send_payment_with_valid_inputs_under_the_travel_rule_threshold( sender_account: AccountResource, receiver_account: AccountResource, amount: int, currency: str, ) -> None: """ Test Plan: 1. Generate valid receive payment account identifier. 2. Call send payment `POST /accounts/{account_id}/payments` with the account identifier. 3. Expect send payment success; receiver account balance increased by the amount sent; sender account balance decreased by the amount sent. """ initial_amount = sender_account.balance(currency) assert receiver_account.balance(currency) == 0 receiver_account_identifier = receiver_account.generate_account_identifier( ) sender_account.send_payment(currency=currency, amount=amount, payee=receiver_account_identifier) receiver_account.wait_for_balance(currency, amount) sender_account.wait_for_balance(currency, initial_amount - amount)
def test_send_payment_with_invalid_account_identifier_onchain_account_address_as_payee( sender_account: AccountResource, receiver_account: AccountResource, currency: str, hrp: str) -> None: """ Test Plan: 1. Generate valid receive payment account identifier. 2. Extract account onchain address and subaddress from receiving payment account identifier. 3. Use an invalid onchain account address and extracted subaddress to create a new account identifier. 4. Call send payment `POST /accounts/{account_id}/payments` with created account identifier. 5. Expect server response 400 client error, and sender account balance is not changed. """ initial_amount = sender_account.balance(currency) receiver_account_identifier = receiver_account.generate_account_identifier( ) _, subaddress = identifier.decode_account(receiver_account_identifier, hrp) invalid_account_address = LocalAccount().account_address invalid_account_identifier = identifier.encode_account( invalid_account_address, subaddress, hrp) with pytest.raises(requests.HTTPError, match="400 Client Error"): sender_account.send_payment(currency=currency, amount=amount, payee=invalid_account_identifier) assert sender_account.balance(currency) == initial_amount
def test_send_payment_with_invalid_account_identifier_as_payee( sender_account: AccountResource, currency: str) -> None: """ Test Plan: 1. Call send payment `POST /accounts/{account_id}/payments` with `invalid account identifier` as payee. 2. Expect server response 400 client error, and sender account balance is not changed. """ initial_amount = sender_account.balance(currency) with pytest.raises(requests.HTTPError, match="400 Client Error"): sender_account.send_payment(currency=currency, amount=amount, payee="invalid account identifier") assert sender_account.balance(currency) == initial_amount
def test_send_payment_with_invalid_currency(sender_account: AccountResource, receiver_account: AccountResource, invalid_currency: str) -> None: """ Test Plan: 1. Generate valid receive payment account identifier. 2. Call send payment `POST /accounts/{account_id}/payments` with invalid currency code. 3. Expect server response 400 client error, and sender account balance is not changed. """ initial_balances = sender_account.balances() receiver_account_identifier = receiver_account.generate_account_identifier( ) with pytest.raises(requests.HTTPError, match="400 Client Error"): sender_account.send_payment(currency=invalid_currency, amount=amount, payee=receiver_account_identifier) assert sender_account.balances() == initial_balances
def test_send_payment_with_an_amount_exceeding_account_balance( sender_account: AccountResource, receiver_account: AccountResource, currency: str) -> None: """ Test Plan: 1. Generate valid receive payment account identifier. 2. Get sender account balance. 3. Call send payment `POST /accounts/{account_id}/payments` with amount = sender account balance + 1. 4. Expect server response 400 client error, and sender account balance is not changed. """ initial_amount = sender_account.balance(currency) receiver_account_identifier = receiver_account.generate_account_identifier( ) amount = initial_amount + 1 with pytest.raises(requests.HTTPError, match="400 Client Error"): sender_account.send_payment(currency=currency, amount=amount, payee=receiver_account_identifier) assert sender_account.balance(currency) == initial_amount
def test_send_payment_with_invalid_account_identifier_checksum_as_payee( sender_account: AccountResource, receiver_account: AccountResource, currency: str) -> None: """ Test Plan: 1. Generate valid receive payment account identifier. 2. Manuplate valid account identifier's checksum chars. 3. Call send payment `POST /accounts/{account_id}/payments` with invalid account identifier. 4. Expect server response 400 client error, and sender account balance is not changed. """ initial_amount = sender_account.balance(currency) receiver_account_identifier = receiver_account.generate_account_identifier( ) invalid_account_identifier = receiver_account_identifier[:-6] + "000000" with pytest.raises(requests.HTTPError, match="400 Client Error"): sender_account.send_payment(currency=currency, amount=amount, payee=invalid_account_identifier) assert sender_account.balance(currency) == initial_amount
def test_receive_payment_with_refund_metadata_and_invalid_transaction_version( sender_account: AccountResource, receiver_account: AccountResource, currency: str, hrp: str, stub_config: AppConfig, diem_client: jsonrpc.Client, pending_income_account: AccountResource, invalid_refund_txn_version: int, ) -> None: """ When received a payment transaction with invalid refund metadata, it's up to wallet application to decide how to handle, this test makes sure the wallet application should be able to continue to receive following up valid payment transactions. Test Plan: 1. Generate a valid account identifier from receiver account as payee. 2. Submit payment transaction with refund metadata and invalid txn version. 3. Wait for the transaction executed successfully. 4. Send a valid payment to the account identifier. 5. Assert receiver account received the valid payment. """ receiver_account_identifier = receiver_account.generate_account_identifier( ) receiver_account_address = identifier.decode_account_address( receiver_account_identifier, hrp) reason = diem_types.RefundReason__OtherReason() metadata = txnmetadata.refund_metadata(invalid_refund_txn_version, reason) stub_config.account.submit_and_wait_for_txn( diem_client, stdlib.encode_peer_to_peer_with_metadata_script( currency=utils.currency_code(currency), amount=amount * 2, payee=receiver_account_address, metadata=metadata, metadata_signature=b"", ), ) assert receiver_account.balance(currency) == 0 pay = sender_account.send_payment(currency, amount, payee=receiver_account_identifier) wait_for_payment_transaction_complete(sender_account, pay.id) receiver_account.wait_for_balance(currency, amount)
def test_receive_payment_with_invalid_metadata( sender_account: AccountResource, receiver_account: AccountResource, currency: str, hrp: str, stub_config: AppConfig, diem_client: jsonrpc.Client, invalid_metadata: bytes, ) -> None: """When received a payment with invalid metadata, it is up to the wallet application how to handle it. This test makes sure target wallet application should continue to process valid transactions after received such an on-chain transaction. Test Plan: 1. Generate a valid account identifier from receiver account as payee. 2. Submit a p2p transaction with invalid metadata, and wait for it is executed. 3. Send a valid payment to the valid account identifier. 4. Assert receiver account received the valid payment. """ account_identifier = receiver_account.generate_account_identifier() receiver_account_address = identifier.decode_account_address( account_identifier, hrp) stub_config.account.submit_and_wait_for_txn( diem_client, stdlib.encode_peer_to_peer_with_metadata_script( currency=utils.currency_code(currency), amount=amount * 2, payee=receiver_account_address, metadata=invalid_metadata, metadata_signature=b"", ), ) assert receiver_account.balance(currency) == 0 pay = sender_account.send_payment(currency=currency, amount=amount, payee=account_identifier) wait_for_payment_transaction_complete(sender_account, pay.id) receiver_account.wait_for_balance(currency, amount)
def test_receive_payment_with_general_metadata_and_valid_from_and_to_subaddresses( sender_account: AccountResource, receiver_account: AccountResource, currency: str, amount: int, ) -> None: """ Test Plan: 1. Generate a valid account identifier from receiver account as payee. 2. Send a payment to the account identifier. 3. Wait for the transaction executed successfully. 4. Assert receiver account received the fund. """ payee = receiver_account.generate_account_identifier() pay = sender_account.send_payment(currency=currency, amount=amount, payee=payee) wait_for_payment_transaction_complete(sender_account, pay.id) receiver_account.wait_for_balance(currency, amount)
def test_receive_payment_with_travel_rule_metadata_and_valid_reference_id( sender_account: AccountResource, receiver_account: AccountResource, currency: str, travel_rule_threshold: int, ) -> None: """ Test Plan: 1. Generate a valid account identifier from receiver account as payee. 2. Send a payment meeting travel rule threshold to the account identifier. 3. Wait for the transaction executed successfully. 4. Assert receiver account received the fund. """ account_identifier = receiver_account.generate_account_identifier() pay = sender_account.send_payment(currency, travel_rule_threshold, payee=account_identifier) wait_for_payment_transaction_complete(sender_account, pay.id) receiver_account.wait_for_balance(currency, travel_rule_threshold)
def test_receive_payment_with_general_metadata_and_valid_from_and_to_subaddresses( sender_account: AccountResource, receiver_account: AccountResource, currency: str, hrp: str, amount: int, ) -> None: """ Test Plan: 1. Generate a valid payment URI from receiver account. 2. Send a payment to the payee from the valid payment URI. 3. Wait for the transaction executed successfully. 4. Assert receiver account received the fund. """ uri = receiver_account.generate_payment_uri() pay = sender_account.send_payment(currency=currency, amount=amount, payee=uri.intent(hrp).account_id) wait_for_payment_transaction_complete(sender_account, pay.id) receiver_account.wait_for_balance(currency, amount)
def test_receive_payment_with_travel_rule_metadata_and_valid_reference_id( sender_account: AccountResource, receiver_account: AccountResource, currency: str, hrp: str, travel_rule_threshold: int, ) -> None: """ Test Plan: 1. Generate a valid payment URI from receiver account. 2. Send a payment meeting travel rule threshold to the payee from the valid payment URI. 3. Wait for the transaction executed successfully. 4. Assert receiver account received the fund. """ uri = receiver_account.generate_payment_uri() pay = sender_account.send_payment(currency, travel_rule_threshold, payee=uri.intent(hrp).account_id) wait_for_payment_transaction_complete(sender_account, pay.id) receiver_account.wait_for_balance(currency, travel_rule_threshold)