def new_payment_object(self, sender=LocalAccount.generate(), receiver=LocalAccount.generate()): amount = 1_000_000_000_000 currency = testnet.TEST_CURRENCY_CODE sender_account_id = identifier.encode_account( sender.account_address, identifier.gen_subaddress(), self.hrp()) sender_kyc_data = offchain.individual_kyc_data( given_name="Jack", surname="G", address=offchain.AddressObject(city="San Francisco"), ) receiver_account_id = identifier.encode_account( receiver.account_address, identifier.gen_subaddress(), self.hrp(), ) return offchain.new_payment_object( sender_account_id, sender_kyc_data, receiver_account_id, amount, currency, )
def test_account_identifier(): account = LocalAccount() assert account.account_identifier() == identifier.encode_account( account.account_address, None, account.hrp) subaddress = identifier.gen_subaddress() assert account.account_identifier(subaddress) == identifier.encode_account( account.account_address, subaddress, account.hrp)
def test_generate_keys(): account = LocalAccount() sig1 = account.private_key.sign(b"test") sig2 = account.compliance_key.sign(b"test") load_account = LocalAccount.from_dict(account.to_dict()) assert sig1 == load_account.private_key.sign(b"test") assert sig2 == load_account.compliance_key.sign(b"test")
def test_submit_failed(): client = testnet.create_client() parent_vasp = LocalAccount.generate() child_vasp = LocalAccount.generate() signed_txn = create_child_vasp_txn(parent_vasp, child_vasp) with pytest.raises(jsonrpc.JsonRpcError): client.submit(signed_txn)
def test_deserialize_error_for_invalid_signature(): account = LocalAccount.generate() response = offchain.CommandResponseObject( status=offchain.CommandResponseStatus.success, cid="3185027f05746f5526683a38fdb5de98", ) data = offchain.jws.serialize(response, account.private_key.sign) account2 = LocalAccount.generate() with pytest.raises(cryptography.exceptions.InvalidSignature): offchain.jws.deserialize( data, offchain.CommandResponseObject, account2.private_key.public_key().verify, )
def test_send_command_failed_by_invalid_jws_signature_and_retry_by_bg_job( monkeypatch, sender_app, receiver_app): intent_id = receiver_app.gen_intent_id("bar", AMOUNT) with monkeypatch.context() as m: m.setattr(sender_app, "compliance_key", LocalAccount.generate().compliance_key) sender_app.pay("foo", intent_id) assert len(sender_app.saved_commands) == 1 assert len(receiver_app.saved_commands) == 0 with pytest.raises(CommandResponseError) as err: sender_app.run_once_background_job() assert_response_command_error(err.value.resp, "invalid-jws-signature") assert len(sender_app.saved_commands) == 1 assert len(receiver_app.saved_commands) == 0 assert sender_app.run_once_background_job( ) == ActionResult.SEND_REQUEST_SUCCESS assert len(sender_app.saved_commands) == 1 assert len(receiver_app.saved_commands) == 1 # receiver_app continues the flow after error is recovered assert receiver_app.run_once_background_job() == ( Action.EVALUATE_KYC_DATA, ActionResult.PASS, )
def test_could_not_find_onchain_account_by_x_request_sender_address(sender_app, receiver_app): account = LocalAccount.generate() account_id = identifier.encode_account(account.account_address, None, sender_app.hrp) request = minimum_required_fields_request_sample(sender_app, receiver_app) request["command"]["payment"]["sender"]["address"] = account_id resp = send_request(request, sender_app, receiver_app, "failure", sender_address=account_id) assert_response_protocol_error(resp, "invalid_http_header")
def test_create_child_vasp(): client = testnet.create_client() faucet = testnet.Faucet(client) parent_vasp = faucet.gen_account() seq_num = client.get_account_sequence(parent_vasp.account_address) child_vasp = LocalAccount.generate() currency = testnet.TEST_CURRENCY_CODE raw_txn = diem_types.RawTransaction( sender=parent_vasp.account_address, sequence_number=seq_num, payload=diem_types.TransactionPayload__Script( stdlib.encode_create_child_vasp_account_script( coin_type=utils.currency_code(currency), child_address=child_vasp.account_address, auth_key_prefix=child_vasp.auth_key.prefix(), add_all_currencies=False, child_initial_balance=100_000_000, ) ), max_gas_amount=1_000_000, gas_unit_price=0, gas_currency_code=currency, expiration_timestamp_secs=int(time.time()) + 30, chain_id=testnet.CHAIN_ID, ) txn = parent_vasp.sign(raw_txn) client.submit(txn) executed_txn = client.wait_for_transaction(txn) assert executed_txn is not None
def test_submit_txn_when_both_ready(monkeypatch): user = OneUser.run(db_session, account_amount=100_000_000_000, account_currency=currency) amount = 10_000_000_000 receiver = LocalAccount.generate() subaddress = identifier.gen_subaddress() txn = save_outbound_transaction(user.account_id, receiver.account_address, subaddress, amount, currency) cmd = _txn_payment_command(txn) receiver_cmd = dataclasses.replace( cmd, my_actor_address=cmd.payment.receiver.address) receiver_ready_cmd = receiver_cmd.new_command( recipient_signature=b"recipient_signature".hex(), status=offchain.Status.ready_for_settlement, kyc_data=_user_kyc_data(user.account_id), ) with monkeypatch.context() as m: client = context.get().offchain_client m.setattr( client, "process_inbound_request", lambda _, c: client.create_inbound_payment_command( c.cid, c.payment), ) code, resp = process_inbound_command(cmd.payment.receiver.address, receiver_ready_cmd) assert code == 200 assert resp txn = get_transaction_by_reference_id(cmd.reference_id()) assert txn assert txn.status == TransactionStatus.OFF_CHAIN_INBOUND cmd = _txn_payment_command(txn) assert cmd.is_inbound(), str(cmd) process_offchain_tasks() db_session.refresh(txn) assert txn.status == TransactionStatus.OFF_CHAIN_READY # sync command and submit with monkeypatch.context() as m: m.setattr( context.get().offchain_client, "send_command", lambda cmd, _: offchain.reply_request(cmd.cid), ) m.setattr( context.get(), "p2p_by_travel_rule", jsonrpc_txn_sample, ) process_offchain_tasks() db_session.refresh(txn) assert txn.status == TransactionStatus.COMPLETED assert txn.sequence == 5 assert txn.blockchain_version == 3232
def test_get_parent_vasp_account_not_found(): client = testnet.create_client() faucet = testnet.Faucet(client) parent_vasp = LocalAccount.generate() with pytest.raises(jsonrpc.AccountNotFoundError): client.get_parent_vasp_account(parent_vasp.account_address)
def test_get_account_sequence(): client = testnet.create_client() seq = client.get_account_sequence(testnet.DESIGNATED_DEALER_ADDRESS) assert isinstance(seq, int) assert seq > 0 local = LocalAccount.generate() with pytest.raises(jsonrpc.AccountNotFoundError): client.get_account_sequence(local.account_address)
def create_child_vasp_txn(parent_vasp: LocalAccount, child_vasp: LocalAccount, seq: int = 0) -> diem_types.RawTransaction: script = stdlib.encode_create_child_vasp_account_script( coin_type=utils.currency_code(testnet.TEST_CURRENCY_CODE), child_address=child_vasp.account_address, auth_key_prefix=child_vasp.auth_key.prefix(), add_all_currencies=False, child_initial_balance=1_000_000, ) return parent_vasp.sign(create_transaction(parent_vasp, script, seq))
def add_child_vasp(self) -> jsonrpc.Transaction: child_vasp = LocalAccount.generate() self._children.append(child_vasp) return self._parent_vasp.submit_and_wait_for_txn( self._client, stdlib.encode_create_child_vasp_account_script( coin_type=utils.currency_code(testnet.TEST_CURRENCY_CODE), child_address=child_vasp.account_address, auth_key_prefix=child_vasp.auth_key.prefix(), add_all_currencies=False, child_initial_balance=2_000_000_000, ), )
def test_from_and_to_dict(): config = { "private_key": "ab70ae3aa603641f049a3356927d0ba836f775e862f559073a6281782479fd1e", "compliance_key": "f75b74a94250bda7abfab2045205e05c56e5dcba24ecea6aff75aac9463cdc2f", "hrp": "tdm", "txn_gas_currency_code": "XDX", "txn_max_gas_amount": 1000000, "txn_gas_unit_price": 0, "txn_expire_duration_secs": 30, } account = LocalAccount.from_dict(config) assert account.to_dict() == config
def test_serialize_deserialize(): account = LocalAccount.generate() response = offchain.CommandResponseObject( status=offchain.CommandResponseStatus.success, cid="3185027f05746f5526683a38fdb5de98", ) ret = offchain.jws.serialize(response, account.private_key.sign) resp = offchain.jws.deserialize( ret, offchain.CommandResponseObject, account.private_key.public_key().verify, ) assert resp == response
def generate(index: int) -> typing.Tuple[LocalAccount, Config]: port = 5090 + index base_url = f"http://localhost:{port}" account = LocalAccount.generate() conf = Config( wallet_custody_account_name=f"wallet{index}", vasp_compliance_key=ComplianceKey.generate().export_full(), vasp_address=account.account_address.to_hex(), offchain_service_port=port, base_url=base_url, json_rpc_url=testnet.JSON_RPC_URL, chain_id=testnet.CHAIN_ID.to_int(), gas_currency_code=testnet.TEST_CURRENCY_CODE, ) return (account, conf)
def generate(index: int) -> typing.Tuple[LocalAccount, Config]: port = 5000 + index base_url = f"http://localhost:{port}/api/offchain" account = LocalAccount.generate() conf = Config( wallet_custody_account_name=f"wallet{index}", vasp_compliance_key=utils.private_key_bytes( Ed25519PrivateKey.generate()).hex(), vasp_address=account.account_address.to_hex(), base_url=base_url, json_rpc_url=testnet.JSON_RPC_URL, chain_id=testnet.CHAIN_ID.to_int(), gas_currency_code=testnet.TEST_CURRENCY_CODE, ) return (account, conf)
def test_process_inbound_command(monkeypatch): hrp = context.get().config.diem_address_hrp() user = OneUser.run(db_session, account_amount=100_000_000_000, account_currency=currency) amount = 10_000_000_000 sender = LocalAccount.generate() sender_subaddress = identifier.gen_subaddress() receiver_subaddress = generate_new_subaddress(user.account_id) cmd = offchain.PaymentCommand.init( identifier.encode_account(sender.account_address, sender_subaddress, hrp), _user_kyc_data(user.account_id), identifier.encode_account(context.get().config.vasp_address, receiver_subaddress, hrp), amount, currency.value, ) with monkeypatch.context() as m: client = context.get().offchain_client m.setattr( client, "process_inbound_request", lambda _, cmd: client.create_inbound_payment_command( cmd.cid, cmd.payment), ) code, resp = process_inbound_command(cmd.payment.sender.address, cmd) assert code == 200 assert resp txn = get_transaction_by_reference_id(cmd.reference_id()) assert txn assert txn.status == TransactionStatus.OFF_CHAIN_INBOUND cmd = _txn_payment_command(txn) assert cmd.is_inbound(), str(cmd) with monkeypatch.context() as m: m.setattr( context.get().offchain_client, "send_command", lambda cmd, _: offchain.reply_request(cmd.cid), ) process_offchain_tasks() db_session.refresh(txn) assert txn.status == TransactionStatus.OFF_CHAIN_OUTBOUND
def test_get_parent_vasp_account(): client = testnet.create_client() faucet = testnet.Faucet(client) parent_vasp = faucet.gen_account() child_vasp = LocalAccount.generate() signed_txn = create_child_vasp_txn(parent_vasp, child_vasp) client.submit(signed_txn) client.wait_for_transaction(signed_txn) account = client.get_parent_vasp_account(child_vasp.account_address) expected_address = utils.account_address_hex(parent_vasp.account_address) assert account.address == expected_address account = client.get_parent_vasp_account(parent_vasp.account_address) assert account.address == expected_address
def test_decode_account_identifier(): account = LocalAccount() id1 = account.account_identifier() address, subaddress = account.decode_account_identifier(id1) assert address == account.account_address assert subaddress is None subaddress = identifier.gen_subaddress() id2 = account.account_identifier(subaddress) address, subaddress = account.decode_account_identifier(id2) assert address == account.account_address assert subaddress == subaddress
def test_submit_create_child_vasp(): client = testnet.create_client() faucet = testnet.Faucet(client) parent_vasp = faucet.gen_account() child_vasp = LocalAccount.generate() signed_txn = create_child_vasp_txn(parent_vasp, child_vasp) client.submit(signed_txn) executed_txn = client.wait_for_transaction(signed_txn) assert executed_txn is not None assert isinstance(executed_txn, jsonrpc.Transaction) assert executed_txn.vm_status.type == jsonrpc.VM_STATUS_EXECUTED # wait for transaction by signed txn hex string signed_txn_hex = signed_txn.bcs_serialize().hex() executed_txn = client.wait_for_transaction(signed_txn_hex) assert executed_txn is not None assert isinstance(executed_txn, jsonrpc.Transaction) assert executed_txn.vm_status.type == jsonrpc.VM_STATUS_EXECUTED # should include events assert len(executed_txn.events) > 0
def test_save_outbound_transaction(monkeypatch): user = OneUser.run(db_session, account_amount=100_000_000_000, account_currency=currency) amount = 10_000_000_000 receiver = LocalAccount.generate() subaddress = identifier.gen_subaddress() txn = save_outbound_transaction(user.account_id, receiver.account_address, subaddress, amount, currency) assert txn.id in get_account_transaction_ids(user.account_id) assert txn.reference_id is not None assert txn.command_json is not None with monkeypatch.context() as m: m.setattr( context.get().offchain_client, "send_command", lambda cmd, _: offchain.reply_request(cmd.cid), ) process_offchain_tasks() db_session.refresh(txn) assert txn.status == TransactionStatus.OFF_CHAIN_WAIT
def test_from_dict_generate_keys(): account = LocalAccount.from_dict({}) assert account assert account.private_key assert account.compliance_key
def test_from_private_key_hex(): account = LocalAccount.generate() hex_key = utils.private_key_bytes(account.private_key).hex() new_account = LocalAccount.from_private_key_hex(hex_key) assert utils.private_key_bytes(new_account.private_key).hex() == hex_key
if currency_balance > threshold_amount: print(f"which is enough!") else: print(f"need to refill...") if network_chainid == testnet.CHAIN_ID.value and private_key is None: print( f"running in TESTNET, using faucet to mint {refill_amount} {currency}... ", ) faucet = testnet.Faucet(diem_client) faucet.mint(auth_key, refill_amount, currency) else: # use DD private key to send P2P transaction to the watched account sender_account = LocalAccount( Ed25519PrivateKey.from_private_bytes( bytes.fromhex(private_key))) sender_account_info = diem_client.get_account( sender_account.account_address) sender_account_addr_hex = utils.account_address_hex( sender_account.account_address) script = stdlib.encode_peer_to_peer_with_metadata_script( currency=utils.currency_code(currency), payee=watched_account_addr, amount=refill_amount, metadata=txnmetadata.general_metadata( from_subaddress=utils.account_address_bytes( sender_account.account_address), to_subaddress=utils.account_address_bytes( watched_account_addr),
def generateAccount(parent_vasp, intialBalance): child_vasp = LocalAccount.generate() receipt = listAccount(parent_vasp, child_vasp, intialBalance) print("Account generated: ", receipt) return child_vasp
def test_account_not_found_error_when_get_base_url_and_compliance_key_for_invalid_account( ): client = testnet.create_client() account = LocalAccount.generate() with pytest.raises(jsonrpc.AccountNotFoundError): client.get_base_url_and_compliance_key(account.account_address)
def create_account(key): return LocalAccount(Ed25519PrivateKey.from_private_bytes(bytes.fromhex(key)))
def get_account( self, account_name: str = "test_default_account_name") -> LocalAccount: local_account = LocalAccount.generate() return local_account
def test_get_account_not_exist(): local_account = LocalAccount.generate() client = testnet.create_client() account = client.get_account(local_account.account_address) assert account is None