Beispiel #1
0
    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
Beispiel #2
0
def gen_account_id() -> xdr_type.AccountID:
    private_key = PrivateKey.random()

    return xdr_type.AccountID(
        type=xdr_const.PUBLIC_KEY_TYPE_ED25519,
        ed25519=private_key.public_key.raw,
    )
Beispiel #3
0
    def test_random(self):
        priv = PrivateKey.random()
        kp = Keypair.from_seed(priv.stellar_seed)

        assert priv.public_key.stellar_address == kp.address().decode()
        assert priv.public_key.raw == kp.raw_public_key()
        assert priv.stellar_seed == kp.seed().decode()
        assert priv.raw == kp.raw_seed()
Beispiel #4
0
    def test_sign(self):
        resp = SignTransactionResponse(_generate_envelope())

        private_key = PrivateKey.random()
        resp.sign(private_key)

        # kp.verify throws an error if the signature doesn't match
        private_key.public_key.verify(resp.envelope.hash_meta(), resp.envelope.signatures[-1].signature)
    def test_create_program_address_invalid(self, mocker):
        invalid_key = PrivateKey.random().public_key.raw
        mock_hashlib = mocker.patch('agora.solana.address.hashlib')
        mock_hashlib.sha256.return_value.digest.return_value = invalid_key

        with pytest.raises(InvalidPublicKeyError):
            create_program_address(_PROGRAM_ID,
                                   ['Lil\''.encode(), 'Bits'.encode()])
Beispiel #6
0
    def _generate_create(
        subsidizer: PublicKey, wallet: PublicKey, mint: PublicKey
    ) -> Tuple[List[solana.Instruction], PublicKey]:
        addr = token.get_associated_account(wallet, mint)
        pub = PrivateKey.random().public_key

        instructions = [
            system.create_account(subsidizer, addr, token.PROGRAM_KEY, 10, token.ACCOUNT_SIZE),
            token.initialize_account(addr, mint, pub),
            token.set_authority(addr, pub, token.AuthorityType.CLOSE_ACCOUNT, subsidizer),
            token.set_authority(addr, pub, token.AuthorityType.ACCOUNT_HOLDER, wallet)
        ]
        return instructions, addr
Beispiel #7
0
    def test_get_account_info_not_found(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(
            result=account_pb_v4.GetAccountInfoResponse.Result.NOT_FOUND)
        req = self._set_get_account_info_resp(grpc_channel, resp)
        assert req.account_id.value == private_key.public_key.raw

        with pytest.raises(AccountNotFoundError):
            future.result()
Beispiel #8
0
    def test_request_airdrop(self, grpc_channel, executor, no_retry_client):
        public_key = PrivateKey.random().public_key
        future = executor.submit(no_retry_client.request_airdrop, public_key,
                                 100)

        tx_sig = b'somesig'
        resp = airdrop_pb_v4.RequestAirdropResponse(
            result=airdrop_pb_v4.RequestAirdropResponse.Result.OK,
            signature=model_pb_v4.TransactionSignature(value=tx_sig))
        req = self._set_request_airdrop_resp(grpc_channel, resp)
        assert req.account_id.value == public_key.raw
        assert req.quarks == 100

        assert future.result() == tx_sig
Beispiel #9
0
    def test_request_airdrop_not_found(self, grpc_channel, executor,
                                       no_retry_client):
        public_key = PrivateKey.random().public_key
        future = executor.submit(no_retry_client.request_airdrop, public_key,
                                 100)

        resp = airdrop_pb_v4.RequestAirdropResponse(
            result=airdrop_pb_v4.RequestAirdropResponse.Result.NOT_FOUND)
        req = self._set_request_airdrop_resp(grpc_channel, resp)
        assert req.account_id.value == public_key.raw
        assert req.quarks == 100

        with pytest.raises(AccountNotFoundError):
            future.result()
Beispiel #10
0
    def _gen_create_tx():
        private_key = PrivateKey.random()
        create_instruction, addr = token.create_associated_token_account(
            _subsidizer, private_key.public_key, _token)

        return solana.Transaction.new(_subsidizer, [
            create_instruction,
            token.set_authority(
                addr,
                private_key.public_key,
                token.AuthorityType.CLOSE_ACCOUNT,
                new_authority=_subsidizer,
            )
        ])
    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'
Beispiel #12
0
    def test_request_airdrop_insufficient_kin(self, grpc_channel, executor,
                                              no_retry_client):
        public_key = PrivateKey.random().public_key

        future = executor.submit(no_retry_client.request_airdrop, public_key,
                                 100)
        resp = airdrop_pb_v4.RequestAirdropResponse(
            result=airdrop_pb_v4.RequestAirdropResponse.Result.INSUFFICIENT_KIN
        )
        req = self._set_request_airdrop_resp(grpc_channel, resp)
        assert req.account_id.value == public_key.raw
        assert req.quarks == 100

        with pytest.raises(InsufficientBalanceError):
            future.result()
Beispiel #13
0
    def test_no_account_retry(self, grpc_channel, executor):
        resolver = TokenAccountResolver(
            account_stub=account_pb_grpc.AccountStub(grpc_channel),
            retry_strategies=[LimitStrategy(3)])

        owner = PrivateKey.random()
        future = executor.submit(resolver.resolve_token_accounts, owner)

        for _ in range(3):
            md, request, rpc = grpc_channel.take_unary_unary(
                account_pb.DESCRIPTOR.services_by_name['Account'].
                methods_by_name['ResolveTokenAccounts'])
            rpc.terminate(account_pb.ResolveTokenAccountsResponse(), (),
                          grpc.StatusCode.OK, '')

        assert future.result() == []
Beispiel #14
0
    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
Beispiel #15
0
    def test_create_account_errors(self, grpc_channel, executor,
                                   no_retry_client, result, error_type):
        private_key = PrivateKey.random()

        no_retry_client._response_cache.clear_all()
        future = executor.submit(no_retry_client.create_solana_account,
                                 private_key)

        self._set_get_service_config_resp(grpc_channel)
        self._set_get_recent_blockhash_resp(grpc_channel)
        self._set_get_min_balance_response(grpc_channel)

        resp = account_pb_v4.CreateAccountResponse(result=result)
        req = self._set_create_account_resp(grpc_channel, resp)

        tx = Transaction.unmarshal(req.transaction.value)
        assert len(tx.signatures) == 2
        assert tx.signatures[0] == bytes(SIGNATURE_LENGTH)
        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
        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

        with pytest.raises(error_type):
            future.result()
    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
Beispiel #17
0
 def test_find_program_address(self):
     for i in range(1000):
         assert find_program_address(PrivateKey.random().public_key,
                                     ['Lil\''.encode(), 'Bits'.encode()])
Beispiel #18
0
 def test_base58_roundtrip(self):
     priv = PrivateKey.random()
     assert PrivateKey.from_base58(priv.to_base58()) == priv
     assert priv.public_key.from_base58(priv.public_key.to_base58()) == priv.public_key
Beispiel #19
0
    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()
Beispiel #20
0
from agora.solana.system import decompile_create_account
from agora.solana.token import decompile_initialize_account, transfer, decompile_set_authority
from agora.solana.transaction import HASH_LENGTH, SIGNATURE_LENGTH
from agora.utils import user_agent
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'],
Beispiel #21
0
def generate_keys(amount) -> List[PrivateKey]:
    return [PrivateKey.random() for _ in range(amount)]
Beispiel #22
0
    def _resolve_and_submit_solana_payment(
        self, payment: Payment, commitment: Commitment, sender_resolution: AccountResolution,
        dest_resolution: AccountResolution, sender_create: bool
    ) -> SubmitTransactionResult:
        config = self._internal_client.get_service_config()
        if not config.subsidizer_account.value and not payment.subsidizer:
            raise NoSubsidizerError()

        subsidizer_id = (payment.subsidizer.public_key if payment.subsidizer else
                         PublicKey(config.subsidizer_account.value))

        result = self._submit_solana_payment_tx(payment, config, commitment)
        if result.errors and isinstance(result.errors.tx_error, AccountNotFoundError):
            transfer_source = None
            create_instructions = []
            create_signer = None
            resubmit = False

            if sender_resolution == AccountResolution.PREFERRED:
                token_account_infos = self._internal_client.resolve_token_accounts(payment.sender.public_key, False)
                if token_account_infos:
                    transfer_source = token_account_infos[0].account_id
                    resubmit = True

            if dest_resolution == AccountResolution.PREFERRED:
                token_account_infos = self._internal_client.resolve_token_accounts(payment.destination, False)
                if token_account_infos:
                    payment.destination = token_account_infos[0].account_id
                    resubmit = True
                elif sender_create:
                    lamports = self._internal_client.get_minimum_balance_for_rent_exception()
                    temp_key = PrivateKey.random()

                    original_dest = payment.destination
                    payment.destination = temp_key.public_key
                    create_instructions = [
                        system.create_account(
                            subsidizer_id,
                            temp_key.public_key,
                            token.PROGRAM_KEY,
                            lamports,
                            token.ACCOUNT_SIZE,
                        ),
                        token.initialize_account(
                            temp_key.public_key,
                            PublicKey(config.token.value),
                            temp_key.public_key,
                        ),
                        token.set_authority(
                            temp_key.public_key,
                            temp_key.public_key,
                            token.AuthorityType.CLOSE_ACCOUNT,
                            new_authority=subsidizer_id,
                        ),
                        token.set_authority(
                            temp_key.public_key,
                            temp_key.public_key,
                            token.AuthorityType.ACCOUNT_HOLDER,
                            new_authority=original_dest,
                        ),
                    ]
                    create_signer = temp_key
                    resubmit = True

            if resubmit:
                result = self._submit_solana_payment_tx(
                    payment,
                    config,
                    commitment,
                    transfer_source=transfer_source,
                    create_instructions=create_instructions,
                    create_signer=create_signer,
                )

        return result
Beispiel #23
0
import json
import token
from typing import List

from agora import solana
from agora.client import Environment
from agora.error import WebhookRequestError, InvoiceErrorReason
from agora.keys import PrivateKey
from agora.solana import token
from agora.webhook.create_account import CreateAccountRequest, CreateAccountResponse
from agora.webhook.events import Event
from agora.webhook.handler import WebhookHandler
from agora.webhook.sign_transaction import SignTransactionRequest, SignTransactionResponse
from tests.utils import generate_keys

_TEST_PRIVATE_KEY = PrivateKey.random()


class TestWebhookHandler:
    def test_is_valid_signature(self):
        secret = 'secret'
        handler = WebhookHandler(Environment.TEST, secret=secret)

        req_body = 'somebody'
        sig = base64.b64encode(
            hmac.new(secret.encode(), req_body.encode(),
                     hashlib.sha256).digest())

        assert handler.is_valid_signature(req_body, sig)

        other_sig = base64.b64encode(
Beispiel #24
0
    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)
Beispiel #25
0
from agora.keys import PrivateKey
from agora.solana.token import Command, initialize_account, decompile_initialize_account, transfer, decompile_transfer
from agora.solana.token.program import set_authority, AuthorityType, decompile_set_authority
from agora.solana.transaction import Transaction
from tests.utils import generate_keys

_token_program = PrivateKey.random().public_key


class TestTokenProgram:
    def test_initialize_account(self):
        public_keys = [key.public_key for key in generate_keys(3)]
        instruction = initialize_account(public_keys[0], public_keys[1], public_keys[2], _token_program)

        assert instruction.data == bytes([Command.INITIALIZE_ACCOUNT])
        assert instruction.accounts[0].is_signer
        assert instruction.accounts[0].is_writable
        for i in range(1, 4):
            assert not instruction.accounts[i].is_signer
            assert not instruction.accounts[i].is_writable

        tx = Transaction.unmarshal(Transaction.new(public_keys[0], [instruction]).marshal())
        decompiled = decompile_initialize_account(tx.message, 0, _token_program)
        assert decompiled.account == public_keys[0]
        assert decompiled.mint == public_keys[1]
        assert decompiled.owner == public_keys[2]

    def test_transfer(self):
        public_keys = [key.public_key for key in generate_keys(3)]
        instruction = transfer(public_keys[0], public_keys[1], public_keys[2], 123456789, _token_program)
import base64
from typing import Optional, Tuple

import pytest
from agoraapi.common.v3 import model_pb2

from agora import solana
from agora.error import InvoiceErrorReason
from agora.keys import PrivateKey
from agora.model import AgoraMemo, TransactionType
from agora.model.invoice import Invoice, InvoiceList
from agora.webhook.sign_transaction import SignTransactionRequest, SignTransactionResponse
from tests.utils import generate_keys

_SIGNING_KEY = PrivateKey.random()


class TestSignTransactionRequest:
    def test_from_json_kin_4(self):
        tx, il = _generate_tx(True)

        data = {
            'solana_transaction': base64.b64encode(tx.marshal()),
            'invoice_list': base64.b64encode(il.SerializeToString()),
        }

        req = SignTransactionRequest.from_json(data)
        assert len(req.payments) == 1
        assert req.payments[0].invoice == Invoice.from_proto(il.invoices[0])
        assert req.transaction == tx
Beispiel #27
0
 def generate_key():
     return PrivateKey.random()