async def create_all(client: AsyncClient, manager: Keypair, fee: Fee, referral_fee: int) -> Tuple[PublicKey, PublicKey]: stake_pool = Keypair() validator_list = Keypair() (pool_withdraw_authority, seed) = find_withdraw_authority_program_address( STAKE_POOL_PROGRAM_ID, stake_pool.public_key) reserve_stake = Keypair() await create_stake(client, manager, reserve_stake, pool_withdraw_authority, 1) pool_mint = Keypair() await create_mint(client, manager, pool_mint, pool_withdraw_authority) manager_fee_account = await create_associated_token_account( client, manager, manager.public_key, pool_mint.public_key, ) fee = Fee(numerator=1, denominator=1000) referral_fee = 20 await create( client, manager, stake_pool, validator_list, pool_mint.public_key, reserve_stake.public_key, manager_fee_account, fee, referral_fee) return (stake_pool.public_key, validator_list.public_key)
async def test_create_vote(async_client, payer): vote = Keypair() node = Keypair() await create_vote(async_client, payer, vote, node, payer.public_key, payer.public_key, 10) resp = await async_client.get_account_info(vote.public_key, commitment=Confirmed) assert PublicKey(resp['result']['value']['owner']) == VOTE_PROGRAM_ID
async def test_create_stake_pool(async_client, payer): stake_pool = Keypair() validator_list = Keypair() (pool_withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool.public_key) reserve_stake = Keypair() await create_stake(async_client, payer, reserve_stake, pool_withdraw_authority, 1) pool_mint = Keypair() await create_mint(async_client, payer, pool_mint, pool_withdraw_authority) manager_fee_account = await create_associated_token_account( async_client, payer, payer.public_key, pool_mint.public_key, ) fee = Fee(numerator=1, denominator=1000) referral_fee = 20 await create(async_client, payer, stake_pool, validator_list, pool_mint.public_key, reserve_stake.public_key, manager_fee_account, fee, referral_fee) resp = await async_client.get_account_info(stake_pool.public_key, commitment=Confirmed) assert resp['result']['value']['owner'] == str(STAKE_POOL_PROGRAM_ID) data = resp['result']['value']['data'] pool_data = StakePool.decode(data[0], data[1]) assert pool_data.manager == payer.public_key assert pool_data.staker == payer.public_key assert pool_data.stake_withdraw_bump_seed == seed assert pool_data.validator_list == validator_list.public_key assert pool_data.reserve_stake == reserve_stake.public_key assert pool_data.pool_mint == pool_mint.public_key assert pool_data.manager_fee_account == manager_fee_account assert pool_data.token_program_id == TOKEN_PROGRAM_ID assert pool_data.total_lamports == 0 assert pool_data.pool_token_supply == 0 assert pool_data.epoch_fee == fee assert pool_data.next_epoch_fee is None assert pool_data.preferred_deposit_validator is None assert pool_data.preferred_withdraw_validator is None assert pool_data.stake_deposit_fee == fee assert pool_data.stake_withdrawal_fee == fee assert pool_data.next_stake_withdrawal_fee is None assert pool_data.stake_referral_fee == referral_fee assert pool_data.sol_deposit_authority is None assert pool_data.sol_deposit_fee == fee assert pool_data.sol_referral_fee == referral_fee assert pool_data.sol_withdraw_authority is None assert pool_data.sol_withdrawal_fee == fee assert pool_data.next_sol_withdrawal_fee is None assert pool_data.last_epoch_pool_token_supply == 0 assert pool_data.last_epoch_total_lamports == 0
def test_create_account(): """Test creating a transaction for create account.""" params = sp.CreateAccountParams( from_pubkey=Keypair().public_key, new_account_pubkey=Keypair().public_key, lamports=123, space=1, program_id=PublicKey(1), ) assert sp.decode_create_account(sp.create_account(params)) == params
def validators(event_loop, async_client, payer) -> List[PublicKey]: num_validators = 3 validators = [] for i in range(num_validators): vote = Keypair() node = Keypair() event_loop.run_until_complete( create_vote(async_client, payer, vote, node, payer.public_key, payer.public_key, 10) ) validators.append(vote.public_key) return validators
async def test_authorize_stake(async_client, payer): stake = Keypair() new_authority = Keypair() await create_stake(async_client, payer, stake, payer.public_key, 1_000) await asyncio.gather( authorize(async_client, payer, payer, stake.public_key, new_authority.public_key, StakeAuthorize.STAKER), authorize(async_client, payer, payer, stake.public_key, new_authority.public_key, StakeAuthorize.WITHDRAWER)) await authorize(async_client, payer, new_authority, stake.public_key, payer.public_key, StakeAuthorize.WITHDRAWER)
async def program_subscribed( websocket: SolanaWsClientProtocol, test_http_client_async: AsyncClient) -> Tuple[Keypair, Keypair]: """Setup program subscription.""" program = Keypair() owned = Keypair() airdrop_resp = await test_http_client_async.request_airdrop( owned.public_key, AIRDROP_AMOUNT) await test_http_client_async.confirm_transaction(airdrop_resp["result"]) await websocket.program_subscribe(program.public_key) first_resp = await websocket.recv() subscription_id = first_resp.result yield program, owned await websocket.program_unsubscribe(subscription_id)
def test_dedup_signatures(stubbed_blockhash): """Test signature deduplication.""" kp1, kp2 = Keypair(), Keypair() transfer1 = sp.transfer( sp.TransferParams(from_pubkey=kp1.public_key, to_pubkey=kp2.public_key, lamports=123)) transfer2 = sp.transfer( sp.TransferParams(from_pubkey=kp1.public_key, to_pubkey=kp2.public_key, lamports=123)) txn = txlib.Transaction(recent_blockhash=stubbed_blockhash).add( transfer1, transfer2) txn.sign(kp1)
def test_assign(): """Test creating a transaction for assign.""" params = sp.AssignParams( account_pubkey=Keypair().public_key, program_id=PublicKey(1), ) assert sp.decode_assign(sp.assign(params)) == params
def test_allocate(): """Test creating a transaction for allocate.""" params = sp.AllocateParams( account_pubkey=Keypair().public_key, space=12345, ) assert sp.decode_allocate(sp.allocate(params)) == params
def test_verify_confirmed_block(stubbed_blockhash): """Test verifying signature in a confirmed block.""" kp0, kp1, kp2, kp3 = (Keypair() for _ in range(4)) # Create a couple signed transaction txn1 = txlib.Transaction(recent_blockhash=stubbed_blockhash).add( transfer( TransferParams(from_pubkey=kp0.public_key, to_pubkey=kp1.public_key, lamports=123))) txn1.sign(kp0) txn2 = txlib.Transaction(recent_blockhash=stubbed_blockhash).add( transfer( TransferParams(from_pubkey=kp2.public_key, to_pubkey=kp3.public_key, lamports=456))) txn2.sign(kp2) # Build confirmed_block with dummy data for blockhases and balances confirmed_block = { "blockhash": stubbed_blockhash, "previousBlockhash": stubbed_blockhash, "transactions": [ { "transaction": txn1, "meta": { "fee": 0, "preBalances": [100000, 100000, 1, 1, 1], "postBalances": [99877, 100123, 1, 1, 1], "status": { "Ok": None }, "err": None, }, }, { "transaction": txn2, "meta": { "fee": 0, "preBalances": [100000, 100000, 1, 1, 1], "postBalances": [99544, 100456, 1, 1, 1], "status": { "Ok": None }, "err": None, }, }, ], "rewards": [], } # Verify signatures in confirmed_block assert all(tx_with_meta["transaction"].verify_signatures() for tx_with_meta in confirmed_block["transactions"]) # Test block with bogus signature bogus_signature = txlib.SigPubkeyPair(kp2.public_key, bytes([9] * 64)) # pylint: disable=protected-access txn1.signatures[0] = bogus_signature bad_confirmed_block = confirmed_block bad_confirmed_block["transactions"][0]["transaction"] = txn1 assert not all(tx_with_meta["transaction"].verify_signatures() for tx_with_meta in confirmed_block["transactions"])
def _create_multisig_args( self, m: int, signers: List[PublicKey], balance_needed: int, ) -> Tuple[Transaction, Keypair, Keypair]: multisig_keypair = Keypair() txn = Transaction() txn.add( sp.create_account( sp.CreateAccountParams( from_pubkey=self.payer.public_key, new_account_pubkey=multisig_keypair.public_key, lamports=balance_needed, space=MULTISIG_LAYOUT.sizeof(), program_id=self.program_id, ) ) ) txn.add( spl_token.initialize_multisig( spl_token.InitializeMultisigParams( program_id=self.program_id, multisig=multisig_keypair.public_key, m=m, signers=signers, ) ) ) return txn, self.payer, multisig_keypair
async def test_airdrop(async_client): manager = Keypair() airdrop_lamports = 1_000_000 await system.actions.airdrop(async_client, manager.public_key, airdrop_lamports) resp = await async_client.get_balance(manager.public_key, commitment=Confirmed) assert resp['result']['value'] == airdrop_lamports
async def account_subscribed(stubbed_sender: Keypair, websocket: SolanaWsClientProtocol) -> PublicKey: """Setup account subscription.""" recipient = Keypair() await websocket.account_subscribe(recipient.public_key) first_resp = await websocket.recv() subscription_id = first_resp.result yield recipient.public_key await websocket.account_unsubscribe(subscription_id)
async def test_create_mint(async_client, payer): pool_mint = Keypair() await create_mint(async_client, payer, pool_mint, payer.public_key) await create_associated_token_account( async_client, payer, payer.public_key, pool_mint.public_key, )
def test_sign_partial(stubbed_blockhash): """Test paritally sigining a transaction.""" kp1, kp2 = Keypair(), Keypair() transfer = sp.transfer( sp.TransferParams(from_pubkey=kp1.public_key, to_pubkey=kp2.public_key, lamports=123)) partial_txn = txlib.Transaction( recent_blockhash=stubbed_blockhash).add(transfer) partial_txn.sign_partial(kp1, kp2.public_key) assert len(partial_txn.signature()) == txlib.SIG_LENGTH assert len(partial_txn.signatures) == 2 assert not partial_txn.signatures[1].signature partial_txn.add_signer(kp2) expected_txn = txlib.Transaction( recent_blockhash=stubbed_blockhash).add(transfer) expected_txn.sign(kp1, kp2) assert partial_txn == expected_txn
def test_transfer_signatures(stubbed_blockhash): """Test signing transfer transactions.""" kp1, kp2 = Keypair(), Keypair() transfer1 = sp.transfer( sp.TransferParams(from_pubkey=kp1.public_key, to_pubkey=kp2.public_key, lamports=123)) transfer2 = sp.transfer( sp.TransferParams(from_pubkey=kp2.public_key, to_pubkey=kp1.public_key, lamports=123)) txn = txlib.Transaction(recent_blockhash=stubbed_blockhash).add( transfer1, transfer2) txn.sign(kp1, kp2) expected = txlib.Transaction(recent_blockhash=stubbed_blockhash, signatures=txn.signatures).add( transfer1, transfer2) assert txn == expected
async def test_deposit_withdraw_stake(async_client, validators, payer, stake_pool_addresses, waiter): (stake_pool_address, validator_list_address) = stake_pool_addresses resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) data = resp['result']['value']['data'] stake_pool = StakePool.decode(data[0], data[1]) validator = next(iter(validators)) stake_amount = 1_000_000 stake = Keypair() await create_stake(async_client, payer, stake, payer.public_key, stake_amount) stake = stake.public_key await delegate_stake(async_client, payer, payer, stake, validator) resp = await async_client.get_account_info(stake, commitment=Confirmed) data = resp['result']['value']['data'] stake_state = StakeState.decode(data[0], data[1]) print(stake_state) await waiter.wait_for_next_epoch(async_client) await update_stake_pool(async_client, payer, stake_pool_address) token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) await deposit_stake(async_client, payer, stake_pool_address, validator, stake, token_account) pool_token_balance = await async_client.get_token_account_balance( token_account, Confirmed) pool_token_balance = pool_token_balance['result']['value']['amount'] resp = await async_client.get_minimum_balance_for_rent_exemption(STAKE_LEN) stake_rent_exemption = resp['result'] assert pool_token_balance == str(stake_amount + stake_rent_exemption) destination_stake = Keypair() await withdraw_stake(async_client, payer, payer, destination_stake, stake_pool_address, validator, payer.public_key, token_account, stake_amount) pool_token_balance = await async_client.get_token_account_balance( token_account, Confirmed) pool_token_balance = pool_token_balance['result']['value']['amount'] assert pool_token_balance == str(stake_rent_exemption)
async def test_logs_subscribe_mentions_filter( test_http_client_async: AsyncClient, websocket: SolanaWsClientProtocol, logs_subscribed_mentions_filter: None, ): """Test logs subscription with a mentions filter.""" recipient = Keypair().public_key await test_http_client_async.request_airdrop(recipient, AIRDROP_AMOUNT) main_resp = await websocket.recv() assert main_resp.result.value.logs[ 0] == "Program 11111111111111111111111111111111 invoke [1]"
async def signature_subscribed( websocket: SolanaWsClientProtocol, test_http_client_async: AsyncClient) -> Tuple[Keypair, Keypair]: """Setup signature subscription.""" recipient = Keypair() airdrop_resp = await test_http_client_async.request_airdrop( recipient.public_key, AIRDROP_AMOUNT) await websocket.signature_subscribe(airdrop_resp["result"]) first_resp = await websocket.recv() subscription_id = first_resp.result yield await websocket.signature_unsubscribe(subscription_id)
def test_allocate_with_seed(): """Test creating a transaction for allocate with seed.""" params = sp.AllocateWithSeedParams( account_pubkey=Keypair().public_key, base_pubkey=PublicKey(1), seed={ "length": 4, "chars": "gqln" }, space=65537, program_id=PublicKey(2), ) assert sp.decode_allocate_with_seed(sp.allocate(params)) == params
async def test_deposit_withdraw_sol(async_client, payer): fee = Fee(numerator=1, denominator=1000) referral_fee = 20 (stake_pool_address, validator_list_address) = await create_all(async_client, payer, fee, referral_fee) resp = await async_client.get_account_info(stake_pool_address, commitment=Confirmed) data = resp['result']['value']['data'] stake_pool = StakePool.decode(data[0], data[1]) token_account = get_associated_token_address(payer.public_key, stake_pool.pool_mint) deposit_amount = 100_000_000 await deposit_sol(async_client, payer, stake_pool_address, token_account, deposit_amount) pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) assert pool_token_balance['result']['value']['amount'] == str(deposit_amount) recipient = Keypair() await withdraw_sol(async_client, payer, token_account, stake_pool_address, recipient.public_key, deposit_amount) pool_token_balance = await async_client.get_token_account_balance(token_account, Confirmed) assert pool_token_balance['result']['value']['amount'] == str('0')
def test_create_account_with_seed(): """Test creating a an account with seed.""" params = sp.CreateAccountWithSeedParams( from_pubkey=Keypair().public_key, new_account_pubkey=PublicKey(3), base_pubkey=PublicKey(1), seed={ "length": 4, "chars": "gqln" }, lamports=123, space=4, program_id=PublicKey(2), ) assert sp.decode_create_account_with_seed( sp.create_account_with_seed(params)) == params
def _create_wrapped_native_account_args( program_id: PublicKey, owner: PublicKey, payer: Keypair, amount: int, skip_confirmation: bool, balance_needed: int, ) -> Tuple[PublicKey, Transaction, Keypair, Keypair, TxOpts]: new_keypair = Keypair() # Allocate memory for the account # Construct transaction txn = Transaction() txn.add( sp.create_account( sp.CreateAccountParams( from_pubkey=payer.public_key, new_account_pubkey=new_keypair.public_key, lamports=balance_needed, space=ACCOUNT_LAYOUT.sizeof(), program_id=program_id, ) ) ) txn.add( sp.transfer( sp.TransferParams(from_pubkey=payer.public_key, to_pubkey=new_keypair.public_key, lamports=amount) ) ) txn.add( spl_token.initialize_account( spl_token.InitializeAccountParams( account=new_keypair.public_key, mint=WRAPPED_SOL_MINT, owner=owner, program_id=program_id ) ) ) return new_keypair.public_key, txn, payer, new_keypair, TxOpts(skip_confirmation=skip_confirmation)
async def remove_validator_from_pool( client: AsyncClient, staker: Keypair, stake_pool_address: PublicKey, validator: PublicKey ): resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) data = resp['result']['value']['data'] stake_pool = StakePool.decode(data[0], data[1]) resp = await client.get_account_info(stake_pool.validator_list, commitment=Confirmed) data = resp['result']['value']['data'] validator_list = ValidatorList.decode(data[0], data[1]) validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator) destination_stake = Keypair() txn = Transaction() txn.add( sys.create_account( sys.CreateAccountParams( from_pubkey=staker.public_key, new_account_pubkey=destination_stake.public_key, lamports=0, # will get filled by split space=STAKE_LEN, program_id=STAKE_PROGRAM_ID, ) ) ) txn.add( sp.remove_validator_from_pool_with_vote( STAKE_POOL_PROGRAM_ID, stake_pool_address, stake_pool.staker, stake_pool.validator_list, staker.public_key, validator, validator_info.transient_seed_suffix_start, destination_stake.public_key ) ) await client.send_transaction( txn, staker, destination_stake, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed))
def _create_mint_args( conn: Union[Client, AsyncClient], payer: Keypair, mint_authority: PublicKey, decimals: int, program_id: PublicKey, freeze_authority: Optional[PublicKey], skip_confirmation: bool, balance_needed: int, cls: Union[Type[Token], Type[AsyncToken]], ) -> Tuple[Union[Token, AsyncToken], Transaction, Keypair, Keypair, TxOpts]: mint_keypair = Keypair() token = cls(conn, mint_keypair.public_key, program_id, payer) # type: ignore # Construct transaction txn = Transaction() txn.add( sp.create_account( sp.CreateAccountParams( from_pubkey=payer.public_key, new_account_pubkey=mint_keypair.public_key, lamports=balance_needed, space=MINT_LAYOUT.sizeof(), program_id=program_id, ) ) ) txn.add( spl_token.initialize_mint( spl_token.InitializeMintParams( program_id=program_id, mint=mint_keypair.public_key, decimals=decimals, mint_authority=mint_authority, freeze_authority=freeze_authority, ) ) ) return token, txn, payer, mint_keypair, TxOpts(skip_confirmation=skip_confirmation, skip_preflight=True)
def _create_account_args( self, owner: PublicKey, skip_confirmation: bool, balance_needed: int, ) -> Tuple[PublicKey, Transaction, Keypair, Keypair, TxOpts]: new_keypair = Keypair() # Allocate memory for the account # Construct transaction txn = Transaction() txn.add( sp.create_account( sp.CreateAccountParams( from_pubkey=self.payer.public_key, new_account_pubkey=new_keypair.public_key, lamports=balance_needed, space=ACCOUNT_LAYOUT.sizeof(), program_id=self.program_id, ) ) ) txn.add( spl_token.initialize_account( spl_token.InitializeAccountParams( account=new_keypair.public_key, mint=self.pubkey, owner=owner, program_id=self.program_id ) ) ) return ( new_keypair.public_key, txn, self.payer, new_keypair, TxOpts(skip_preflight=True, skip_confirmation=skip_confirmation), )
def test_new_keypair() -> None: """Test new keypair with random seed is created successfully.""" keypair = Keypair() assert len(keypair.secret_key) == 64 assert len(bytes(keypair.public_key)) == crypto_box_PUBLICKEYBYTES
def payer(event_loop, async_client) -> Keypair: payer = Keypair() airdrop_lamports = 10_000_000_000 event_loop.run_until_complete(airdrop(async_client, payer.public_key, airdrop_lamports)) return payer
def test_transfer(): """Test creating a transaction for transfer.""" params = sp.TransferParams(from_pubkey=Keypair().public_key, to_pubkey=Keypair().public_key, lamports=123) assert sp.decode_transfer(sp.transfer(params)) == params