def test_reply_request(): resp = offchain.reply_request("cid") assert json.loads(offchain.to_json(resp)) == json.loads( """{ "cid": "cid", "_ObjectType": "CommandResponseObject", "status": "success" }""" ) resp = offchain.reply_request( "cid", offchain.OffChainErrorObject( type=offchain.OffChainErrorType.command_error, field="kyc_data", code="code1", message="message", ), ) assert json.loads(offchain.to_json(resp)) == json.loads( """{ "cid": "cid", "_ObjectType": "CommandResponseObject", "status": "failure", "error": { "type": "command_error", "code": "code1", "field": "kyc_data", "message": "message" } }""" )
def test_dumps_and_loads_response_command(): response = offchain.CommandResponseObject( status=offchain.CommandResponseStatus.success, cid="3185027f-0574-6f55-2668-3a38fdb5de98", ) assert offchain.from_json(offchain.to_json(response), offchain.CommandResponseObject) == response assert json.loads(offchain.to_json(response)) == json.loads("""{ "status": "success", "_ObjectType": "CommandResponseObject", "cid": "3185027f-0574-6f55-2668-3a38fdb5de98" }""") response = offchain.CommandResponseObject( status=offchain.CommandResponseStatus.failure, error=offchain.OffChainErrorObject( type=offchain.OffChainErrorType.command_error, code="code2", field="signature", message="abc", ), cid="3185027f-0574-6f55-2668-3a38fdb5de98", ) assert offchain.from_json(offchain.to_json(response), offchain.CommandResponseObject) == response assert json.loads(offchain.to_json(response)) == json.loads("""{ "status": "failure", "_ObjectType": "CommandResponseObject", "error": { "type": "command_error", "code": "code2", "field": "signature", "message": "abc" }, "cid": "3185027f-0574-6f55-2668-3a38fdb5de98" }""")
def test_create_an_account_with_valid_kyc_data_and_initial_deposit_balances( target_client: RestClient, currency: str ) -> None: minimum_kyc_data = offchain.to_json(offchain.individual_kyc_data()) account = target_client.create_account(kyc_data=minimum_kyc_data, balances={currency: 123}) assert account.id assert account.kyc_data == minimum_kyc_data
def _new_payment_command_transaction(command: offchain.PaymentCommand, status: TransactionStatus) -> Transaction: payment = command.payment sender_address, source_subaddress = _account_address_and_subaddress( payment.sender.address) destination_address, destination_subaddress = _account_address_and_subaddress( payment.receiver.address) source_id = get_account_id_from_subaddr(source_subaddress) destination_id = get_account_id_from_subaddr(destination_subaddress) return Transaction( type=TransactionType.OFFCHAIN, status=status, amount=payment.action.amount, currency=payment.action.currency, created_timestamp=datetime.utcnow(), source_id=source_id, source_address=sender_address, source_subaddress=source_subaddress, destination_id=destination_id, destination_address=destination_address, destination_subaddress=destination_subaddress, reference_id=command.reference_id(), command_json=offchain.to_json(command), )
def test_decode_account_kyc_data(): assert Account(id="1").kyc_data_object() == offchain.individual_kyc_data() sample = KycSample.gen("foo") account = Account(id="1", kyc_data=sample.minimum) assert account.kyc_data_object() assert offchain.to_json(account.kyc_data_object()) == sample.minimum
def test_reference_id_command_result_object(): # Test can encode and decode correct response format ref_id_command_result = offchain.ReferenceIDCommandResultObject( receiver_address="dm1p7ujcndcl7nudzwt8fglhx6wxnvqqqqqqqqqqqqelu3xv", ) response = offchain.CommandResponseObject( status=offchain.CommandResponseStatus.success, cid="3185027f-0574-6f55-2668-3a38fdb5de98", result=offchain.to_dict(ref_id_command_result), ) assert offchain.from_json(offchain.to_json(response), offchain.CommandResponseObject) == response assert offchain.from_json(offchain.to_json(response)) == response assert json.loads(offchain.to_json(response)) == json.loads("""{ "status": "success", "_ObjectType": "CommandResponseObject", "cid": "3185027f-0574-6f55-2668-3a38fdb5de98", "result": { "_ObjectType": "ReferenceIDCommandResponse", "receiver_address": "dm1p7ujcndcl7nudzwt8fglhx6wxnvqqqqqqqqqqqqelu3xv" } }""")
def offchain_action(txn, cmd, action) -> None: assert cmd.is_inbound() if action is None: return if action == offchain.Action.EVALUATE_KYC_DATA: new_cmd = _evaluate_kyc_data(cmd) txn.command_json = offchain.to_json(new_cmd) txn.status = _command_transaction_status( new_cmd, TransactionStatus.OFF_CHAIN_OUTBOUND) else: # todo: handle REVIEW_KYC_DATA and CLEAR_SOFT_MATCH raise ValueError( f"unsupported offchain action: {action}, command: {cmd}")
def validate_and_save(txn: Optional[Transaction]) -> Transaction: if txn: prior = _txn_payment_command(txn) if command == prior: return command.validate(prior) txn.command_json = offchain.to_json(command) txn.status = _command_transaction_status( command, TransactionStatus.OFF_CHAIN_INBOUND) else: txn = _new_payment_command_transaction( command, TransactionStatus.OFF_CHAIN_INBOUND) return txn
assert account.balance("XDX") == 0 @pytest.mark.parametrize("amount", [0, 1, 100, 10000000000]) @pytest.mark.parametrize("currency", ["XUS"]) def test_create_an_account_with_initial_deposit_balances(target_client: RestClient, currency: str, amount: int) -> None: account = target_client.create_account(kyc_data=None, balances={currency: amount}) assert account.id assert account.kyc_data is None assert account.balance(currency) == amount @pytest.mark.parametrize( # pyre-ignore "kyc_data", [ offchain.to_json(offchain.individual_kyc_data()), offchain.to_json(offchain.entity_kyc_data()), ], ) def test_create_an_account_with_minimum_valid_kyc_data(target_client: RestClient, kyc_data: str) -> None: account = target_client.create_account(kyc_data=kyc_data) assert account.id assert account.kyc_data == kyc_data def test_create_an_account_with_valid_kyc_data_and_initial_deposit_balances( target_client: RestClient, currency: str ) -> None: minimum_kyc_data = offchain.to_json(offchain.individual_kyc_data()) account = target_client.create_account(kyc_data=minimum_kyc_data, balances={currency: 123}) assert account.id
def test_to_json(factory): cmd = factory.new_sender_payment_command() assert cmd == offchain.from_json(offchain.to_json(cmd), offchain.PaymentCommand)
def test_dumps_and_loads_request_command(): kyc_data = offchain.individual_kyc_data( given_name="hello", surname="world", address=offchain.AddressObject(city="San Francisco"), national_id=offchain.NationalIdObject(id_value="234121234"), legal_entity_name="foo bar", ) assert offchain.from_json(offchain.to_json(kyc_data), offchain.KycDataObject) == kyc_data payment = offchain.PaymentObject( reference_id="4185027f-0574-6f55-2668-3a38fdb5de98", sender=offchain.PaymentActorObject( address="lbr1p7ujcndcl7nudzwt8fglhx6wxn08kgs5tm6mz4usw5p72t", status=offchain.StatusObject(status=offchain.Status.needs_kyc_data), kyc_data=kyc_data, metadata=["hello", "world"], ), receiver=offchain.PaymentActorObject( address="lbr1p7ujcndcl7nudzwt8fglhx6wxnvqqqqqqqqqqqqelu3xv", status=offchain.StatusObject( status=offchain.Status.abort, abort_code="code1", abort_message="code1 message", ), ), action=offchain.PaymentActionObject(amount=1_000_000_000_000, currency="XUS", timestamp=1604902048), original_payment_reference_id="0185027f-0574-6f55-2668-3a38fdb5de98", ) assert offchain.from_json(offchain.to_json(payment), offchain.PaymentObject) == payment request = offchain.CommandRequestObject( command_type=offchain.CommandType.PaymentCommand, command=offchain.to_dict( offchain.PaymentCommandObject( _ObjectType=offchain.CommandType.PaymentCommand, payment=payment, ) ), cid="3185027f-0574-6f55-2668-3a38fdb5de98", ) assert offchain.from_json(offchain.to_json(request), offchain.CommandRequestObject) == request assert offchain.from_json(offchain.to_json(request)) == request assert json.loads(offchain.to_json(request)) == json.loads( """{ "cid": "3185027f-0574-6f55-2668-3a38fdb5de98", "command_type": "PaymentCommand", "command": { "_ObjectType": "PaymentCommand", "payment": { "reference_id": "4185027f-0574-6f55-2668-3a38fdb5de98", "sender": { "address": "lbr1p7ujcndcl7nudzwt8fglhx6wxn08kgs5tm6mz4usw5p72t", "status": { "status": "needs_kyc_data" }, "kyc_data": { "type": "individual", "payload_version": 1, "given_name": "hello", "surname": "world", "address": { "city": "San Francisco" }, "national_id": { "id_value": "234121234" }, "legal_entity_name": "foo bar" }, "metadata": [ "hello", "world" ] }, "receiver": { "address": "lbr1p7ujcndcl7nudzwt8fglhx6wxnvqqqqqqqqqqqqelu3xv", "status": { "status": "abort", "abort_code": "code1", "abort_message": "code1 message" } }, "action": { "amount": 1000000000000, "currency": "XUS", "action": "charge", "timestamp": 1604902048 }, "original_payment_reference_id": "0185027f-0574-6f55-2668-3a38fdb5de98" } }, "_ObjectType": "CommandRequestObject" }""" )
def test_new_payment_request_and_object(factory): sender = LocalAccount.generate() receiver = LocalAccount.generate() payment = factory.new_payment_object(sender, receiver) request = offchain.new_payment_request(payment) reference_id = payment.reference_id assert reference_id assert_cid(request.cid) assert uuid.UUID(reference_id) assert "-" in reference_id payment = offchain.from_dict(request.command, offchain.PaymentCommandObject).payment address, subaddress = identifier.decode_account(payment.sender.address, identifier.TDM) assert subaddress is not None assert address == sender.account_address address, subaddress = identifier.decode_account(payment.receiver.address, identifier.TDM) assert subaddress is not None assert address == receiver.account_address expected = f"""{{ "cid": "{request.cid}", "command_type": "PaymentCommand", "command": {{ "_ObjectType": "PaymentCommand", "payment": {{ "reference_id": "{reference_id}", "sender": {{ "address": "{payment.sender.address}", "status": {{ "status": "needs_kyc_data" }}, "kyc_data": {{ "type": "individual", "payload_version": 1, "given_name": "Jack", "surname": "G", "address": {{ "city": "San Francisco" }} }} }}, "receiver": {{ "address": "{payment.receiver.address}", "status": {{ "status": "none" }} }}, "action": {{ "amount": 1000000000000, "currency": "XUS", "action": "charge", "timestamp": {payment.action.timestamp} }} }} }}, "_ObjectType": "CommandRequestObject" }}""" assert json.loads(offchain.to_json(request)) == json.loads(expected) assert request == offchain.from_json(expected, offchain.CommandRequestObject) assert request == offchain.from_json(expected)