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
Пример #4
0
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),
    )
Пример #5
0
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
Пример #6
0
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"
          }
        }""")
Пример #7
0
 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}")
Пример #8
0
 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)