def test_get_transaction(self, grpc_channel, executor, no_retry_client): source, dest = [key.public_key for key in generate_keys(2)] transaction_id = b'someid' future = executor.submit(no_retry_client.get_transaction, transaction_id) agora_memo = AgoraMemo.new(1, TransactionType.SPEND, 0, b'') tx = Transaction.new(PrivateKey.random().public_key, [ memo.memo_instruction( base64.b64encode(agora_memo.val).decode('utf-8')), token.transfer(source, dest, PrivateKey.random().public_key, 100), ]) resp = tx_pb_v4.GetTransactionResponse( state=tx_pb_v4.GetTransactionResponse.State.SUCCESS, item=tx_pb_v4.HistoryItem( transaction_id=model_pb_v4.TransactionId( value=transaction_id, ), solana_transaction=model_pb_v4.Transaction( value=tx.marshal(), ), payments=[ tx_pb_v4.HistoryItem.Payment( source=model_pb_v4.SolanaAccountId(value=source.raw), destination=model_pb_v4.SolanaAccountId( value=dest.raw), amount=100, ) ], invoice_list=model_pb_v3.InvoiceList(invoices=[ model_pb_v3.Invoice(items=[ model_pb_v3.Invoice.LineItem(title='t1', amount=15), ]), ])), ) req = self._set_get_transaction_resp(grpc_channel, resp) assert req.transaction_id.value == transaction_id tx_data = future.result() assert tx_data.tx_id == transaction_id assert tx_data.transaction_state == TransactionState.SUCCESS assert len(tx_data.payments) == 1 assert not tx_data.error p = tx_data.payments[0] assert p.sender.raw == source.raw assert p.destination.raw == dest.raw assert p.tx_type == TransactionType.SPEND assert p.quarks == 100 assert p.invoice.to_proto().SerializeToString( ) == resp.item.invoice_list.invoices[0].SerializeToString() assert not p.memo
def _resolve(): return self._account_stub_v4.ResolveTokenAccounts( account_pb.ResolveTokenAccountsRequest( account_id=model_pb.SolanaAccountId(value=public_key.raw), include_account_info=include_account_info, ), metadata=self._metadata, timeout=_GRPC_TIMEOUT_SECONDS)
def _call_resolve(): response = self._account_stub.ResolveTokenAccounts( account_pb.ResolveTokenAccountsRequest( account_id=model_pb.SolanaAccountId(value=public_key.raw))) if not response.token_accounts: raise NoTokenAccountsError() return response
def _submit_request(): resp = self._account_stub_v4.GetAccountInfo( account_pb.GetAccountInfoRequest( account_id=model_pb.SolanaAccountId(value=public_key.raw), commitment=commitment.to_proto(), ), metadata=self._metadata, timeout=_GRPC_TIMEOUT_SECONDS) if resp.result == account_pb.GetAccountInfoResponse.Result.NOT_FOUND: raise AccountNotFoundError return AccountInfo.from_proto(resp.account_info)
def test_from_proto_stellar_text_memo(self): op_result = gen_payment_op_result(xdr_const.PAYMENT_UNDERFUNDED) result_xdr = gen_result_xdr(xdr_const.txFAILED, [op_result]) tx_src = gen_account_id() dest = gen_account_id() operations = [gen_payment_op(dest, amount=20)] envelope_xdr = gen_tx_envelope_xdr(tx_src, 1, operations, gen_text_memo(b'somememo')) history_item = tx_pb.HistoryItem( transaction_id=model_pb.TransactionId(value=b'somehash'), cursor=tx_pb.Cursor(value=b'cursor1'), stellar_transaction=model_pb.StellarTransaction( result_xdr=result_xdr, envelope_xdr=envelope_xdr, ), payments=[ tx_pb.HistoryItem.Payment( source=model_pb.SolanaAccountId(value=tx_src.ed25519), destination=model_pb.SolanaAccountId(value=dest.ed25519), amount=20, ), ], ) data = TransactionData.from_proto( history_item, tx_pb.GetTransactionResponse.State.SUCCESS) assert data.tx_id == b'somehash' assert data.transaction_state == TransactionState.SUCCESS assert len(data.payments) == 1 payment = data.payments[0] assert payment.sender.raw == tx_src.ed25519 assert payment.destination.raw == dest.ed25519 assert payment.tx_type == TransactionType.UNKNOWN assert payment.quarks == 20 assert not payment.invoice assert payment.memo == 'somememo'
def test_from_proto_solana_text_memo(self): source, dest, token_program = [ key.public_key for key in generate_keys(3) ] tx = Transaction.new(PrivateKey.random().public_key, [ memo_instruction('somememo'), transfer(source, dest, PrivateKey.random().public_key, 20), ]) history_item = tx_pb.HistoryItem( transaction_id=model_pb.TransactionId(value=b'somehash'), cursor=tx_pb.Cursor(value=b'cursor1'), solana_transaction=model_pb.Transaction(value=tx.marshal(), ), payments=[ tx_pb.HistoryItem.Payment( source=model_pb.SolanaAccountId(value=source.raw), destination=model_pb.SolanaAccountId(value=dest.raw), amount=20, ), ], ) data = TransactionData.from_proto( history_item, tx_pb.GetTransactionResponse.State.SUCCESS) assert data.tx_id == b'somehash' assert data.transaction_state == TransactionState.SUCCESS assert len(data.payments) == 1 payment = data.payments[0] assert payment.sender.raw == source.raw assert payment.destination.raw == dest.raw assert payment.tx_type == TransactionType.UNKNOWN assert payment.quarks == 20 assert not payment.invoice assert payment.memo == 'somememo'
def test_get_account_info(self, grpc_channel, executor, no_retry_client): private_key = PrivateKey.random() future = executor.submit(no_retry_client.get_solana_account_info, private_key.public_key) resp = account_pb_v4.GetAccountInfoResponse( account_info=account_pb_v4.AccountInfo( account_id=model_pb_v4.SolanaAccountId( value=private_key.public_key.raw), balance=10, )) req = self._set_get_account_info_resp(grpc_channel, resp) assert req.account_id.value == private_key.public_key.raw account_info = future.result() assert account_info.account_id == private_key.public_key assert account_info.balance == 10
def _request_airdrop(): resp = self._airdrop_stub_v4.RequestAirdrop( airdrop_pb.RequestAirdropRequest( account_id=model_pb.SolanaAccountId(value=public_key.raw), quarks=quarks, commitment=commitment.to_proto(), ), metadata=self._metadata, timeout=_GRPC_TIMEOUT_SECONDS) if resp.result == airdrop_pb.RequestAirdropResponse.Result.OK: return resp.signature.value if resp.result == airdrop_pb.RequestAirdropResponse.Result.NOT_FOUND: raise AccountNotFoundError() if resp.result == airdrop_pb.RequestAirdropResponse.INSUFFICIENT_KIN: raise InsufficientBalanceError() raise Error( f'unexpected response from airdrop service: {resp.result}')
def test_all(self, grpc_channel, executor): resolver = TokenAccountResolver( account_stub=account_pb_grpc.AccountStub(grpc_channel)) owner, token1, token2 = [key.public_key for key in generate_keys(3)] future = executor.submit(resolver.resolve_token_accounts, owner) md, request, rpc = grpc_channel.take_unary_unary( account_pb.DESCRIPTOR.services_by_name['Account']. methods_by_name['ResolveTokenAccounts']) rpc.terminate( account_pb.ResolveTokenAccountsResponse(token_accounts=[ model_pb.SolanaAccountId(value=key.raw) for key in [token1, token2] ]), (), grpc.StatusCode.OK, '') assert future.result() == [token1, token2] # ensure it's cached assert resolver.resolve_token_accounts(owner) == [token1, token2]
def _resolve(): return self._account_stub_v4.ResolveTokenAccounts( account_pb_v4.ResolveTokenAccountsRequest( account_id=model_pb_v4.SolanaAccountId( value=public_key.raw)))
def test_create_account_no_service_subsidizer(self, grpc_channel, executor, no_retry_client): private_key = PrivateKey.random() no_retry_client._response_cache.clear_all() future = executor.submit(no_retry_client.create_solana_account, private_key) md, request, rpc = grpc_channel.take_unary_unary( tx_pb_v4.DESCRIPTOR.services_by_name['Transaction']. methods_by_name['GetServiceConfig']) rpc.terminate( tx_pb_v4.GetServiceConfigResponse( token=model_pb_v4.SolanaAccountId(value=_token.raw), token_program=model_pb_v4.SolanaAccountId( value=_token_program.raw), ), (), grpc.StatusCode.OK, '') TestInternalClientV4._assert_metadata(md) with pytest.raises(NoSubsidizerError): future.result() subsidizer = PrivateKey.random() future = executor.submit(no_retry_client.create_solana_account, private_key, subsidizer=subsidizer) self._set_get_recent_blockhash_resp(grpc_channel) self._set_get_min_balance_response(grpc_channel) req = self._set_create_account_resp( grpc_channel, account_pb_v4.CreateAccountResponse()) tx = Transaction.unmarshal(req.transaction.value) assert len(tx.signatures) == 2 assert subsidizer.public_key.verify(tx.message.marshal(), tx.signatures[0]) assert private_key.public_key.verify(tx.message.marshal(), tx.signatures[1]) sys_create = decompile_create_account(tx.message, 0) assert sys_create.funder == subsidizer.public_key assert sys_create.address == private_key.public_key assert sys_create.owner == _token_program assert sys_create.lamports == _min_balance assert sys_create.size == token.ACCOUNT_SIZE token_init = decompile_initialize_account(tx.message, 1, _token_program) assert token_init.account == private_key.public_key assert token_init.mint == _token assert token_init.owner == private_key.public_key token_set_auth = decompile_set_authority(tx.message, 2, _token_program) assert token_set_auth.account == private_key.public_key assert token_set_auth.current_authority == private_key.public_key assert token_set_auth.authority_type == token.AuthorityType.CloseAccount assert token_set_auth.new_authority == subsidizer.public_key assert not future.result()
from agora.version import VERSION from tests.utils import generate_keys _recent_blockhash = bytes(HASH_LENGTH) _recent_blockhash_resp = tx_pb_v4.GetRecentBlockhashResponse( blockhash=model_pb_v4.Blockhash(value=_recent_blockhash)) _min_balance = 2039280 _min_balance_resp = tx_pb_v4.GetMinimumBalanceForRentExemptionResponse( lamports=_min_balance) _subsidizer = PrivateKey.random().public_key _token = PrivateKey.random().public_key _token_program = PrivateKey.random().public_key _service_config_resp = tx_pb_v4.GetServiceConfigResponse( subsidizer_account=model_pb_v4.SolanaAccountId(value=_subsidizer.raw), token=model_pb_v4.SolanaAccountId(value=_token.raw), token_program=model_pb_v4.SolanaAccountId(value=_token_program.raw), ) @pytest.fixture(scope='class') def grpc_channel(): return grpc_testing.channel([ account_pb_v4.DESCRIPTOR.services_by_name['Account'], airdrop_pb_v4.DESCRIPTOR.services_by_name['Airdrop'], tx_pb_v4.DESCRIPTOR.services_by_name['Transaction'], ], grpc_testing.strict_real_time) @pytest.fixture(scope='class', autouse=True)
def test_from_proto_stellar_agora_memo(self): op_result = gen_payment_op_result(xdr_const.PAYMENT_SUCCESS) result_xdr = gen_result_xdr(xdr_const.txSUCCESS, [op_result, op_result]) il = model_pb_v3.InvoiceList(invoices=[ model_pb_v3.Invoice(items=[ model_pb_v3.Invoice.LineItem(title='t1', amount=10), ]), model_pb_v3.Invoice(items=[ model_pb_v3.Invoice.LineItem(title='t1', amount=15), ]), ]) fk = InvoiceList.from_proto(il).get_sha_224_hash() memo = AgoraMemo.new(1, TransactionType.P2P, 0, fk) hash_memo = gen_hash_memo(memo.val) acc1 = gen_account_id() acc2 = gen_account_id() acc3 = gen_account_id() operations = [ gen_payment_op(acc2, src=acc1, amount=10), gen_payment_op(acc1, src=acc2, amount=15), ] envelope_xdr = gen_tx_envelope_xdr(acc3, 1, operations, hash_memo) history_item = tx_pb.HistoryItem( transaction_id=model_pb.TransactionId(value=b'somehash'), cursor=tx_pb.Cursor(value=b'cursor1'), stellar_transaction=model_pb.StellarTransaction( result_xdr=result_xdr, envelope_xdr=envelope_xdr, ), payments=[ tx_pb.HistoryItem.Payment( source=model_pb.SolanaAccountId(value=acc1.ed25519), destination=model_pb.SolanaAccountId(value=acc2.ed25519), amount=10, ), tx_pb.HistoryItem.Payment( source=model_pb.SolanaAccountId(value=acc2.ed25519), destination=model_pb.SolanaAccountId(value=acc1.ed25519), amount=15, ), ], invoice_list=il, ) data = TransactionData.from_proto( history_item, tx_pb.GetTransactionResponse.State.SUCCESS) assert data.tx_id == b'somehash' assert data.transaction_state == TransactionState.SUCCESS assert len(data.payments) == 2 payment1 = data.payments[0] assert payment1.sender.raw == acc1.ed25519 assert payment1.destination.raw == acc2.ed25519 assert payment1.tx_type == memo.tx_type() assert payment1.quarks == 10 assert (payment1.invoice.to_proto().SerializeToString() == il.invoices[0].SerializeToString()) assert not payment1.memo payment2 = data.payments[1] assert payment2.sender.raw == acc2.ed25519 assert payment2.destination.raw == acc1.ed25519 assert payment2.tx_type == TransactionType.P2P assert payment2.quarks == 15 assert (payment2.invoice.to_proto().SerializeToString() == il.invoices[1].SerializeToString()) assert not payment2.memo
def test_from_proto_solana_agora_memo(self): acc1, acc2, token_program = [ key.public_key for key in generate_keys(3) ] il = model_pb_v3.InvoiceList(invoices=[ model_pb_v3.Invoice(items=[ model_pb_v3.Invoice.LineItem(title='t1', amount=10), ]), model_pb_v3.Invoice(items=[ model_pb_v3.Invoice.LineItem(title='t1', amount=15), ]), ]) fk = InvoiceList.from_proto(il).get_sha_224_hash() agora_memo = AgoraMemo.new(1, TransactionType.P2P, 0, fk) tx = Transaction.new(PrivateKey.random().public_key, [ memo_instruction(base64.b64encode(agora_memo.val).decode('utf-8')), transfer(acc1, acc2, PrivateKey.random().public_key, 10), transfer(acc2, acc1, PrivateKey.random().public_key, 15), ]) history_item = tx_pb.HistoryItem( transaction_id=model_pb.TransactionId(value=b'somehash'), cursor=tx_pb.Cursor(value=b'cursor1'), solana_transaction=model_pb.Transaction(value=tx.marshal(), ), payments=[ tx_pb.HistoryItem.Payment( source=model_pb.SolanaAccountId(value=acc1.raw), destination=model_pb.SolanaAccountId(value=acc2.raw), amount=10, ), tx_pb.HistoryItem.Payment( source=model_pb.SolanaAccountId(value=acc2.raw), destination=model_pb.SolanaAccountId(value=acc1.raw), amount=15, ), ], invoice_list=il, ) data = TransactionData.from_proto( history_item, tx_pb.GetTransactionResponse.State.SUCCESS) assert data.tx_id == b'somehash' assert data.transaction_state == TransactionState.SUCCESS assert len(data.payments) == 2 payment1 = data.payments[0] assert payment1.sender.raw == acc1.raw assert payment1.destination.raw == acc2.raw assert payment1.tx_type == TransactionType.P2P assert payment1.quarks == 10 assert (payment1.invoice.to_proto().SerializeToString() == il.invoices[0].SerializeToString()) assert not payment1.memo payment2 = data.payments[1] assert payment2.sender.raw == acc2.raw assert payment2.destination.raw == acc1.raw assert payment2.tx_type == TransactionType.P2P assert payment2.quarks == 15 assert (payment2.invoice.to_proto().SerializeToString() == il.invoices[1].SerializeToString()) assert not payment2.memo
def test_resolve_token_accounts(self, grpc_channel, executor, no_retry_client): owner = PrivateKey.random().public_key close_authority = PrivateKey.random().public_key token_accounts = [priv.public_key for priv in generate_keys(2)] # account info not requested, only IDs available future = executor.submit(no_retry_client.resolve_token_accounts, owner, False) resp = account_pb_v4.ResolveTokenAccountsResponse(token_accounts=[ model_pb_v4.SolanaAccountId(value=token_account.raw) for token_account in token_accounts ]) req = self._set_resolve_token_accounts_resp(grpc_channel, resp) assert req.account_id.value == owner.raw assert not req.include_account_info token_account_infos = future.result() assert len(token_account_infos) == 2 for idx, token_account in enumerate(token_accounts): account_info = token_account_infos[idx] assert account_info.account_id == token_account assert not account_info.balance assert not account_info.owner assert not account_info.close_authority # account info not requested, account infos available future = executor.submit(no_retry_client.resolve_token_accounts, owner, False) resp = account_pb_v4.ResolveTokenAccountsResponse( token_account_infos=[ account_pb_v4.AccountInfo( account_id=model_pb_v4.SolanaAccountId( value=token_account.raw), ) for token_account in token_accounts ], token_accounts=[ model_pb_v4.SolanaAccountId(value=token_account.raw) for token_account in token_accounts ]) req = self._set_resolve_token_accounts_resp(grpc_channel, resp) assert req.account_id.value == owner.raw assert not req.include_account_info token_account_infos = future.result() assert len(token_account_infos) == 2 for idx, token_account in enumerate(token_accounts): account_info = token_account_infos[idx] assert account_info.account_id == token_account assert not account_info.balance assert not account_info.owner assert not account_info.close_authority # account info requested future = executor.submit(no_retry_client.resolve_token_accounts, owner, True) resp = account_pb_v4.ResolveTokenAccountsResponse(token_account_infos=[ account_pb_v4.AccountInfo( account_id=model_pb_v4.SolanaAccountId( value=token_account.raw), balance=10 + idx, owner=model_pb_v4.SolanaAccountId(value=owner.raw, ), close_authority=model_pb_v4.SolanaAccountId( value=close_authority.raw)) for idx, token_account in enumerate(token_accounts) ], ) req = self._set_resolve_token_accounts_resp(grpc_channel, resp) assert req.account_id.value == owner.raw assert req.include_account_info token_account_infos = future.result() assert len(token_account_infos) == 2 for idx, token_account in enumerate(token_accounts): account_info = token_account_infos[idx] assert account_info.account_id == token_account assert account_info.balance == 10 + idx assert account_info.owner == owner assert account_info.close_authority == close_authority # account info requested but not available future = executor.submit(no_retry_client.resolve_token_accounts, owner, True) resp = account_pb_v4.ResolveTokenAccountsResponse(token_accounts=[ model_pb_v4.SolanaAccountId(value=token_account.raw) for token_account in token_accounts ], ) req = self._set_resolve_token_accounts_resp(grpc_channel, resp) assert req.account_id.value == owner.raw assert req.include_account_info with pytest.raises(Error) as e: future.result() assert 'account info' in str(e)