diff --git a/clients/py/requirements.txt b/clients/py/requirements.txt index de652117..a7489a2d 100644 --- a/clients/py/requirements.txt +++ b/clients/py/requirements.txt @@ -8,7 +8,7 @@ httpx==0.28.1 idna==3.10 jsonalias==0.1.1 sniffio==1.3.1 -solana==0.34.2 -solders==0.21.0 +solana==0.36.2 +solders==0.23.0 typing_extensions==4.12.2 -websockets==11.0.3 +websockets==13.1.0 diff --git a/clients/py/spl_token/actions.py b/clients/py/spl_token/actions.py index 99a03fd0..345d9dea 100644 --- a/clients/py/spl_token/actions.py +++ b/clients/py/spl_token/actions.py @@ -3,7 +3,7 @@ from solana.rpc.async_api import AsyncClient from solana.rpc.commitment import Confirmed from solana.rpc.types import TxOpts -from solana.transaction import Transaction +from solders.transaction import Transaction import solders.system_program as sys from spl.token.constants import TOKEN_PROGRAM_ID @@ -21,42 +21,47 @@ async def create_associated_token_account( owner: Pubkey, mint: Pubkey ) -> Pubkey: - txn = Transaction(fee_payer=payer.pubkey()) - create_txn = spl_token.create_associated_token_account( - payer=payer.pubkey(), owner=owner, mint=mint - ) - txn.add(create_txn) recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, payer, recent_blockhash=recent_blockhash, opts=OPTS) - return create_txn.accounts[1].pubkey + ix = spl_token.create_associated_token_account( + payer=payer.pubkey(), owner=owner, mint=mint + ) + txn = Transaction.new_signed_with_payer( + [ix], + signing_keypairs=[payer], + payer=payer.pubkey(), + recent_blockhash=recent_blockhash + ) + await client.send_transaction(txn, opts=OPTS) + return ix.accounts[1].pubkey async def create_mint(client: AsyncClient, payer: Keypair, mint: Keypair, mint_authority: Pubkey): - mint_balance = await AsyncToken.get_min_balance_rent_for_exempt_for_mint(client) print(f"Creating pool token mint {mint.pubkey()}") - txn = Transaction(fee_payer=payer.pubkey()) - txn.add( - sys.create_account( - sys.CreateAccountParams( - from_pubkey=payer.pubkey(), - to_pubkey=mint.pubkey(), - lamports=mint_balance, - space=MINT_LAYOUT.sizeof(), - owner=TOKEN_PROGRAM_ID, - ) - ) - ) - txn.add( - spl_token.initialize_mint( - spl_token.InitializeMintParams( - program_id=TOKEN_PROGRAM_ID, - mint=mint.pubkey(), - decimals=9, - mint_authority=mint_authority, - freeze_authority=None, + mint_balance = await AsyncToken.get_min_balance_rent_for_exempt_for_mint(client) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + txn = Transaction.new_signed_with_payer( + [ + sys.create_account( + sys.CreateAccountParams( + from_pubkey=payer.pubkey(), + to_pubkey=mint.pubkey(), + lamports=mint_balance, + space=MINT_LAYOUT.sizeof(), + owner=TOKEN_PROGRAM_ID, + ) + ), + spl_token.initialize_mint( + spl_token.InitializeMintParams( + program_id=TOKEN_PROGRAM_ID, + mint=mint.pubkey(), + decimals=9, + mint_authority=mint_authority, + freeze_authority=None, + ) ) - ) + ], + payer=payer.pubkey(), + recent_blockhash=recent_blockhash, + signing_keypairs=[payer, mint], ) - recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction( - txn, payer, mint, recent_blockhash=recent_blockhash, opts=OPTS) + await client.send_transaction(txn, opts=OPTS) diff --git a/clients/py/stake/actions.py b/clients/py/stake/actions.py index 1147a56d..aea8510b 100644 --- a/clients/py/stake/actions.py +++ b/clients/py/stake/actions.py @@ -6,7 +6,7 @@ from solana.rpc.commitment import Confirmed from solana.rpc.types import TxOpts from solders.sysvar import CLOCK, STAKE_HISTORY -from solana.transaction import Transaction +from solders.transaction import Transaction from stake.constants import STAKE_LEN, STAKE_PROGRAM_ID, SYSVAR_STAKE_CONFIG_ID from stake.state import Authorized, Lockup, StakeAuthorize @@ -19,64 +19,71 @@ async def create_stake(client: AsyncClient, payer: Keypair, stake: Keypair, authority: Pubkey, lamports: int): print(f"Creating stake {stake.pubkey()}") resp = await client.get_minimum_balance_for_rent_exemption(STAKE_LEN) - txn = Transaction(fee_payer=payer.pubkey()) - txn.add( - sys.create_account( - sys.CreateAccountParams( - from_pubkey=payer.pubkey(), - to_pubkey=stake.pubkey(), - lamports=resp.value + lamports, - space=STAKE_LEN, - owner=STAKE_PROGRAM_ID, - ) - ) - ) - txn.add( - st.initialize( - st.InitializeParams( - stake=stake.pubkey(), - authorized=Authorized( - staker=authority, - withdrawer=authority, - ), - lockup=Lockup( - unix_timestamp=0, - epoch=0, - custodian=SYSTEM_PROGRAM_ID, + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + txn = Transaction.new_signed_with_payer( + [ + sys.create_account( + sys.CreateAccountParams( + from_pubkey=payer.pubkey(), + to_pubkey=stake.pubkey(), + lamports=resp.value + lamports, + space=STAKE_LEN, + owner=STAKE_PROGRAM_ID, + ) + ), + st.initialize( + st.InitializeParams( + stake=stake.pubkey(), + authorized=Authorized( + staker=authority, + withdrawer=authority, + ), + lockup=Lockup( + unix_timestamp=0, + epoch=0, + custodian=SYSTEM_PROGRAM_ID, + ) ) ) - ) + ], + payer=payer.pubkey(), + signing_keypairs=[payer, stake], + recent_blockhash=recent_blockhash, ) - recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, payer, stake, recent_blockhash=recent_blockhash, opts=OPTS) + await client.send_transaction(txn, opts=OPTS) async def delegate_stake(client: AsyncClient, payer: Keypair, staker: Keypair, stake: Pubkey, vote: Pubkey): - txn = Transaction(fee_payer=payer.pubkey()) - txn.add( - st.delegate_stake( - st.DelegateStakeParams( - stake=stake, - vote=vote, - clock_sysvar=CLOCK, - stake_history_sysvar=STAKE_HISTORY, - stake_config_id=SYSVAR_STAKE_CONFIG_ID, - staker=staker.pubkey(), + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + signers = [payer, staker] if payer.pubkey() != staker.pubkey() else [payer] + txn = Transaction.new_signed_with_payer( + [ + st.delegate_stake( + st.DelegateStakeParams( + stake=stake, + vote=vote, + clock_sysvar=CLOCK, + stake_history_sysvar=STAKE_HISTORY, + stake_config_id=SYSVAR_STAKE_CONFIG_ID, + staker=staker.pubkey(), + ) ) - ) + ], + payer=payer.pubkey(), + signing_keypairs=signers, + recent_blockhash=recent_blockhash, ) - signers = [payer, staker] if payer.pubkey() != staker.pubkey() else [payer] - recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, *signers, recent_blockhash=recent_blockhash, opts=OPTS) + await client.send_transaction(txn, opts=OPTS) async def authorize( client: AsyncClient, payer: Keypair, authority: Keypair, stake: Pubkey, new_authority: Pubkey, stake_authorize: StakeAuthorize ): - txn = Transaction(fee_payer=payer.pubkey()) - txn.add( - st.authorize( + signers = [payer, authority] if payer.pubkey() != authority.pubkey() else [payer] + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + txn = Transaction.new_signed_with_payer( + [st.authorize( st.AuthorizeParams( stake=stake, clock_sysvar=CLOCK, @@ -84,8 +91,9 @@ async def authorize( new_authority=new_authority, stake_authorize=stake_authorize, ) - ) + )], + payer=payer.pubkey(), + signing_keypairs=signers, + recent_blockhash=recent_blockhash, ) - signers = [payer, authority] if payer.pubkey() != authority.pubkey() else [payer] - recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, *signers, recent_blockhash=recent_blockhash, opts=OPTS) + await client.send_transaction(txn, opts=OPTS) diff --git a/clients/py/stake_pool/actions.py b/clients/py/stake_pool/actions.py index 400f9252..a17301c8 100644 --- a/clients/py/stake_pool/actions.py +++ b/clients/py/stake_pool/actions.py @@ -6,7 +6,7 @@ from solana.rpc.commitment import Confirmed from solana.rpc.types import TxOpts from solders.sysvar import CLOCK, RENT, STAKE_HISTORY -from solana.transaction import Transaction +from solders.transaction import Transaction import solders.system_program as sys from spl.token.constants import TOKEN_PROGRAM_ID @@ -40,63 +40,68 @@ async def create(client: AsyncClient, manager: Keypair, manager_fee_account: Pubkey, fee: Fee, referral_fee: int): resp = await client.get_minimum_balance_for_rent_exemption(STAKE_POOL_LAYOUT.sizeof()) pool_balance = resp.value - txn = Transaction(fee_payer=manager.pubkey()) - txn.add( - sys.create_account( - sys.CreateAccountParams( - from_pubkey=manager.pubkey(), - to_pubkey=stake_pool.pubkey(), - lamports=pool_balance, - space=STAKE_POOL_LAYOUT.sizeof(), - owner=STAKE_POOL_PROGRAM_ID, - ) - ) - ) max_validators = 2950 # current supported max by the program, go big! validator_list_size = ValidatorList.calculate_validator_list_size(max_validators) resp = await client.get_minimum_balance_for_rent_exemption(validator_list_size) validator_list_balance = resp.value - txn.add( - sys.create_account( - sys.CreateAccountParams( - from_pubkey=manager.pubkey(), - to_pubkey=validator_list.pubkey(), - lamports=validator_list_balance, - space=validator_list_size, - owner=STAKE_POOL_PROGRAM_ID, - ) - ) - ) recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction( - txn, manager, stake_pool, validator_list, recent_blockhash=recent_blockhash, opts=OPTS) + txn = Transaction.new_signed_with_payer( + [ + sys.create_account( + sys.CreateAccountParams( + from_pubkey=manager.pubkey(), + to_pubkey=stake_pool.pubkey(), + lamports=pool_balance, + space=STAKE_POOL_LAYOUT.sizeof(), + owner=STAKE_POOL_PROGRAM_ID, + ) + ), + sys.create_account( + sys.CreateAccountParams( + from_pubkey=manager.pubkey(), + to_pubkey=validator_list.pubkey(), + lamports=validator_list_balance, + space=validator_list_size, + owner=STAKE_POOL_PROGRAM_ID, + ) + ), + ], + payer=manager.pubkey(), + recent_blockhash=recent_blockhash, + signing_keypairs=[manager, stake_pool, validator_list], + ) + await client.send_transaction(txn, opts=OPTS) (withdraw_authority, seed) = find_withdraw_authority_program_address( STAKE_POOL_PROGRAM_ID, stake_pool.pubkey()) - txn = Transaction(fee_payer=manager.pubkey()) - txn.add( - sp.initialize( - sp.InitializeParams( - program_id=STAKE_POOL_PROGRAM_ID, - stake_pool=stake_pool.pubkey(), - manager=manager.pubkey(), - staker=manager.pubkey(), - withdraw_authority=withdraw_authority, - validator_list=validator_list.pubkey(), - reserve_stake=reserve_stake, - pool_mint=pool_mint, - manager_fee_account=manager_fee_account, - token_program_id=TOKEN_PROGRAM_ID, - epoch_fee=fee, - withdrawal_fee=fee, - deposit_fee=fee, - referral_fee=referral_fee, - max_validators=max_validators, + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + txn = Transaction.new_signed_with_payer( + [ + sp.initialize( + sp.InitializeParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool.pubkey(), + manager=manager.pubkey(), + staker=manager.pubkey(), + withdraw_authority=withdraw_authority, + validator_list=validator_list.pubkey(), + reserve_stake=reserve_stake, + pool_mint=pool_mint, + manager_fee_account=manager_fee_account, + token_program_id=TOKEN_PROGRAM_ID, + epoch_fee=fee, + withdrawal_fee=fee, + deposit_fee=fee, + referral_fee=referral_fee, + max_validators=max_validators, + ) ) - ) + ], + payer=manager.pubkey(), + recent_blockhash=recent_blockhash, + signing_keypairs=[manager], ) - recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, manager, recent_blockhash=recent_blockhash, opts=OPTS) + await client.send_transaction(txn, opts=OPTS) async def create_all( @@ -135,20 +140,24 @@ async def add_validator_to_pool( resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) data = resp.value.data if resp.value else bytes() stake_pool = StakePool.decode(data) - txn = Transaction(fee_payer=staker.pubkey()) - txn.add( - sp.add_validator_to_pool_with_vote( - STAKE_POOL_PROGRAM_ID, - stake_pool_address, - stake_pool.staker, - stake_pool.validator_list, - stake_pool.reserve_stake, - validator, - None, - ) - ) recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, staker, recent_blockhash=recent_blockhash, opts=OPTS) + txn = Transaction.new_signed_with_payer( + [ + sp.add_validator_to_pool_with_vote( + STAKE_POOL_PROGRAM_ID, + stake_pool_address, + stake_pool.staker, + stake_pool.validator_list, + stake_pool.reserve_stake, + validator, + None, + ) + ], + payer=staker.pubkey(), + recent_blockhash=recent_blockhash, + signing_keypairs=[staker], + ) + await client.send_transaction(txn, opts=OPTS) async def remove_validator_from_pool( @@ -162,20 +171,24 @@ async def remove_validator_from_pool( data = resp.value.data if resp.value else bytes() validator_list = ValidatorList.decode(data) validator_info = next(x for x in validator_list.validators if x.vote_account_address == validator) - txn = Transaction(fee_payer=staker.pubkey()) - txn.add( - sp.remove_validator_from_pool_with_vote( - STAKE_POOL_PROGRAM_ID, - stake_pool_address, - stake_pool.staker, - stake_pool.validator_list, - validator, - validator_info.validator_seed_suffix or None, - validator_info.transient_seed_suffix, - ) - ) recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, staker, recent_blockhash=recent_blockhash, opts=OPTS) + txn = Transaction.new_signed_with_payer( + [ + sp.remove_validator_from_pool_with_vote( + STAKE_POOL_PROGRAM_ID, + stake_pool_address, + stake_pool.staker, + stake_pool.validator_list, + validator, + validator_info.validator_seed_suffix or None, + validator_info.transient_seed_suffix, + ) + ], + recent_blockhash=recent_blockhash, + signing_keypairs=[staker], + payer=staker.pubkey() + ) + await client.send_transaction(txn, opts=OPTS) async def deposit_sol( @@ -188,28 +201,32 @@ async def deposit_sol( (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) - txn = Transaction(fee_payer=funder.pubkey()) - txn.add( - sp.deposit_sol( - sp.DepositSolParams( - program_id=STAKE_POOL_PROGRAM_ID, - stake_pool=stake_pool_address, - withdraw_authority=withdraw_authority, - reserve_stake=stake_pool.reserve_stake, - funding_account=funder.pubkey(), - destination_pool_account=destination_token_account, - manager_fee_account=stake_pool.manager_fee_account, - referral_pool_account=destination_token_account, - pool_mint=stake_pool.pool_mint, - system_program_id=sys.ID, - token_program_id=stake_pool.token_program_id, - amount=amount, - deposit_authority=None, + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + txn = Transaction.new_signed_with_payer( + [ + sp.deposit_sol( + sp.DepositSolParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + withdraw_authority=withdraw_authority, + reserve_stake=stake_pool.reserve_stake, + funding_account=funder.pubkey(), + destination_pool_account=destination_token_account, + manager_fee_account=stake_pool.manager_fee_account, + referral_pool_account=destination_token_account, + pool_mint=stake_pool.pool_mint, + system_program_id=sys.ID, + token_program_id=stake_pool.token_program_id, + amount=amount, + deposit_authority=None, + ) ) - ) + ], + payer=funder.pubkey(), + recent_blockhash=recent_blockhash, + signing_keypairs=[funder], ) - recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, funder, recent_blockhash=recent_blockhash, opts=OPTS) + await client.send_transaction(txn, opts=OPTS) async def withdraw_sol( @@ -222,30 +239,34 @@ async def withdraw_sol( (withdraw_authority, seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) - txn = Transaction(fee_payer=owner.pubkey()) - txn.add( - sp.withdraw_sol( - sp.WithdrawSolParams( - program_id=STAKE_POOL_PROGRAM_ID, - stake_pool=stake_pool_address, - withdraw_authority=withdraw_authority, - source_transfer_authority=owner.pubkey(), - source_pool_account=source_token_account, - reserve_stake=stake_pool.reserve_stake, - destination_system_account=destination_system_account, - manager_fee_account=stake_pool.manager_fee_account, - pool_mint=stake_pool.pool_mint, - clock_sysvar=CLOCK, - stake_history_sysvar=STAKE_HISTORY, - stake_program_id=STAKE_PROGRAM_ID, - token_program_id=stake_pool.token_program_id, - amount=amount, - sol_withdraw_authority=None, + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + txn = Transaction.new_signed_with_payer( + [ + sp.withdraw_sol( + sp.WithdrawSolParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + withdraw_authority=withdraw_authority, + source_transfer_authority=owner.pubkey(), + source_pool_account=source_token_account, + reserve_stake=stake_pool.reserve_stake, + destination_system_account=destination_system_account, + manager_fee_account=stake_pool.manager_fee_account, + pool_mint=stake_pool.pool_mint, + clock_sysvar=CLOCK, + stake_history_sysvar=STAKE_HISTORY, + stake_program_id=STAKE_PROGRAM_ID, + token_program_id=stake_pool.token_program_id, + amount=amount, + sol_withdraw_authority=None, + ) ) - ) + ], + recent_blockhash=recent_blockhash, + payer=owner.pubkey(), + signing_keypairs=[owner], ) - recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, owner, recent_blockhash=recent_blockhash, opts=OPTS) + await client.send_transaction(txn, opts=OPTS) async def deposit_stake( @@ -274,53 +295,53 @@ async def deposit_stake( validator_info.validator_seed_suffix or None, ) - txn = Transaction(fee_payer=deposit_stake_authority.pubkey()) - txn.add( - st.authorize( - st.AuthorizeParams( - stake=deposit_stake, - clock_sysvar=CLOCK, - authority=deposit_stake_authority.pubkey(), - new_authority=stake_pool.stake_deposit_authority, - stake_authorize=StakeAuthorize.STAKER, - ) - ) - ) - txn.add( - st.authorize( - st.AuthorizeParams( - stake=deposit_stake, - clock_sysvar=CLOCK, - authority=deposit_stake_authority.pubkey(), - new_authority=stake_pool.stake_deposit_authority, - stake_authorize=StakeAuthorize.WITHDRAWER, - ) - ) - ) - txn.add( - sp.deposit_stake( - sp.DepositStakeParams( - program_id=STAKE_POOL_PROGRAM_ID, - stake_pool=stake_pool_address, - validator_list=stake_pool.validator_list, - deposit_authority=stake_pool.stake_deposit_authority, - withdraw_authority=withdraw_authority, - deposit_stake=deposit_stake, - validator_stake=validator_stake, - reserve_stake=stake_pool.reserve_stake, - destination_pool_account=destination_pool_account, - manager_fee_account=stake_pool.manager_fee_account, - referral_pool_account=destination_pool_account, - pool_mint=stake_pool.pool_mint, - clock_sysvar=CLOCK, - stake_history_sysvar=STAKE_HISTORY, - token_program_id=stake_pool.token_program_id, - stake_program_id=STAKE_PROGRAM_ID, + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + txn = Transaction.new_signed_with_payer( + [ + st.authorize( + st.AuthorizeParams( + stake=deposit_stake, + clock_sysvar=CLOCK, + authority=deposit_stake_authority.pubkey(), + new_authority=stake_pool.stake_deposit_authority, + stake_authorize=StakeAuthorize.STAKER, + ) + ), + st.authorize( + st.AuthorizeParams( + stake=deposit_stake, + clock_sysvar=CLOCK, + authority=deposit_stake_authority.pubkey(), + new_authority=stake_pool.stake_deposit_authority, + stake_authorize=StakeAuthorize.WITHDRAWER, + ) + ), + sp.deposit_stake( + sp.DepositStakeParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + validator_list=stake_pool.validator_list, + deposit_authority=stake_pool.stake_deposit_authority, + withdraw_authority=withdraw_authority, + deposit_stake=deposit_stake, + validator_stake=validator_stake, + reserve_stake=stake_pool.reserve_stake, + destination_pool_account=destination_pool_account, + manager_fee_account=stake_pool.manager_fee_account, + referral_pool_account=destination_pool_account, + pool_mint=stake_pool.pool_mint, + clock_sysvar=CLOCK, + stake_history_sysvar=STAKE_HISTORY, + token_program_id=stake_pool.token_program_id, + stake_program_id=STAKE_PROGRAM_ID, + ) ) - ) + ], + payer=deposit_stake_authority.pubkey(), + recent_blockhash=recent_blockhash, + signing_keypairs=[deposit_stake_authority], ) - recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, deposit_stake_authority, recent_blockhash=recent_blockhash, opts=OPTS) + await client.send_transaction(txn, opts=OPTS) async def withdraw_stake( @@ -355,43 +376,45 @@ async def withdraw_stake( rent_resp = await client.get_minimum_balance_for_rent_exemption(STAKE_LEN) stake_rent_exemption = rent_resp.value - txn = Transaction(fee_payer=payer.pubkey()) - txn.add( - sys.create_account( - sys.CreateAccountParams( - from_pubkey=payer.pubkey(), - to_pubkey=destination_stake.pubkey(), - lamports=stake_rent_exemption, - space=STAKE_LEN, - owner=STAKE_PROGRAM_ID, - ) - ) - ) - txn.add( - sp.withdraw_stake( - sp.WithdrawStakeParams( - program_id=STAKE_POOL_PROGRAM_ID, - stake_pool=stake_pool_address, - validator_list=stake_pool.validator_list, - withdraw_authority=withdraw_authority, - validator_stake=validator_stake, - destination_stake=destination_stake.pubkey(), - destination_stake_authority=destination_stake_authority, - source_transfer_authority=source_transfer_authority.pubkey(), - source_pool_account=source_pool_account, - manager_fee_account=stake_pool.manager_fee_account, - pool_mint=stake_pool.pool_mint, - clock_sysvar=CLOCK, - token_program_id=stake_pool.token_program_id, - stake_program_id=STAKE_PROGRAM_ID, - amount=amount, - ) - ) - ) signers = [payer, source_transfer_authority, destination_stake] \ if payer != source_transfer_authority else [payer, destination_stake] recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, *signers, recent_blockhash=recent_blockhash, opts=OPTS) + txn = Transaction.new_signed_with_payer( + [ + sys.create_account( + sys.CreateAccountParams( + from_pubkey=payer.pubkey(), + to_pubkey=destination_stake.pubkey(), + lamports=stake_rent_exemption, + space=STAKE_LEN, + owner=STAKE_PROGRAM_ID, + ) + ), + sp.withdraw_stake( + sp.WithdrawStakeParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + validator_list=stake_pool.validator_list, + withdraw_authority=withdraw_authority, + validator_stake=validator_stake, + destination_stake=destination_stake.pubkey(), + destination_stake_authority=destination_stake_authority, + source_transfer_authority=source_transfer_authority.pubkey(), + source_pool_account=source_pool_account, + manager_fee_account=stake_pool.manager_fee_account, + pool_mint=stake_pool.pool_mint, + clock_sysvar=CLOCK, + token_program_id=stake_pool.token_program_id, + stake_program_id=STAKE_PROGRAM_ID, + amount=amount, + ) + ) + ], + payer=payer.pubkey(), + recent_blockhash=recent_blockhash, + signing_keypairs=signers, + ) + await client.send_transaction(txn, opts=OPTS) async def update_stake_pool(client: AsyncClient, payer: Keypair, stake_pool_address: Pubkey): @@ -447,41 +470,50 @@ async def update_stake_pool(client: AsyncClient, payer: Keypair, stake_pool_addr if update_list_instructions: last_instruction = update_list_instructions.pop() for update_list_instruction in update_list_instructions: - txn = Transaction(fee_payer=payer.pubkey()) - txn.add(update_list_instruction) recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, payer, recent_blockhash=recent_blockhash, - opts=TxOpts(skip_confirmation=True, preflight_commitment=Confirmed)) - txn = Transaction(fee_payer=payer.pubkey()) - txn.add(last_instruction) - recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, payer, recent_blockhash=recent_blockhash, opts=OPTS) - txn = Transaction(fee_payer=payer.pubkey()) - txn.add( - sp.update_stake_pool_balance( - sp.UpdateStakePoolBalanceParams( - program_id=STAKE_POOL_PROGRAM_ID, - stake_pool=stake_pool_address, - withdraw_authority=withdraw_authority, - validator_list=stake_pool.validator_list, - reserve_stake=stake_pool.reserve_stake, - manager_fee_account=stake_pool.manager_fee_account, - pool_mint=stake_pool.pool_mint, - token_program_id=stake_pool.token_program_id, + txn = Transaction.new_signed_with_payer( + [update_list_instruction], + payer=payer.pubkey(), + recent_blockhash=recent_blockhash, + signing_keypairs=[payer], ) + await client.send_transaction(txn, opts=TxOpts(skip_confirmation=True, preflight_commitment=Confirmed)) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + txn = Transaction.new_signed_with_payer( + [last_instruction], + payer=payer.pubkey(), + recent_blockhash=recent_blockhash, + signing_keypairs=[payer], ) - ) - txn.add( - sp.cleanup_removed_validator_entries( - sp.CleanupRemovedValidatorEntriesParams( - program_id=STAKE_POOL_PROGRAM_ID, - stake_pool=stake_pool_address, - validator_list=stake_pool.validator_list, + await client.send_transaction(txn, opts=OPTS) + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + txn = Transaction.new_signed_with_payer( + [ + sp.update_stake_pool_balance( + sp.UpdateStakePoolBalanceParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + withdraw_authority=withdraw_authority, + validator_list=stake_pool.validator_list, + reserve_stake=stake_pool.reserve_stake, + manager_fee_account=stake_pool.manager_fee_account, + pool_mint=stake_pool.pool_mint, + token_program_id=stake_pool.token_program_id, + ) + ), + sp.cleanup_removed_validator_entries( + sp.CleanupRemovedValidatorEntriesParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + validator_list=stake_pool.validator_list, + ) ) - ) + ], + payer=payer.pubkey(), + recent_blockhash=recent_blockhash, + signing_keypairs=[payer], ) - recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, payer, recent_blockhash=recent_blockhash, opts=OPTS) + await client.send_transaction(txn, opts=OPTS) async def increase_validator_stake( @@ -524,17 +556,15 @@ async def increase_validator_stake( validator_stake_seed ) - txn = Transaction(fee_payer=payer.pubkey()) + instruction = None if ephemeral_stake_seed is not None: - # We assume there is an existing transient account that we will update (ephemeral_stake, _) = find_ephemeral_stake_program_address( STAKE_POOL_PROGRAM_ID, stake_pool_address, ephemeral_stake_seed) - txn.add( - sp.increase_additional_validator_stake( + instruction = sp.increase_additional_validator_stake( sp.IncreaseAdditionalValidatorStakeParams( program_id=STAKE_POOL_PROGRAM_ID, stake_pool=stake_pool_address, @@ -557,11 +587,8 @@ async def increase_validator_stake( ephemeral_stake_seed=ephemeral_stake_seed ) ) - ) - else: - txn.add( - sp.increase_validator_stake( + instruction = sp.increase_validator_stake( sp.IncreaseValidatorStakeParams( program_id=STAKE_POOL_PROGRAM_ID, stake_pool=stake_pool_address, @@ -582,11 +609,16 @@ async def increase_validator_stake( transient_stake_seed=transient_stake_seed, ) ) - ) signers = [payer, staker] if payer != staker else [payer] recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, *signers, recent_blockhash=recent_blockhash, opts=OPTS) + txn = Transaction.new_signed_with_payer( + [instruction], + payer=payer.pubkey(), + recent_blockhash=recent_blockhash, + signing_keypairs=signers, + ) + await client.send_transaction(txn, opts=OPTS) async def decrease_validator_stake( @@ -629,18 +661,15 @@ async def decrease_validator_stake( transient_stake_seed, ) - txn = Transaction(fee_payer=payer.pubkey()) - + instruction = None if ephemeral_stake_seed is not None: - # We assume there is an existing transient account that we will update (ephemeral_stake, _) = find_ephemeral_stake_program_address( STAKE_POOL_PROGRAM_ID, stake_pool_address, ephemeral_stake_seed) - txn.add( - sp.decrease_additional_validator_stake( + instruction = sp.decrease_additional_validator_stake( sp.DecreaseAdditionalValidatorStakeParams( program_id=STAKE_POOL_PROGRAM_ID, stake_pool=stake_pool_address, @@ -661,12 +690,8 @@ async def decrease_validator_stake( ephemeral_stake_seed=ephemeral_stake_seed ) ) - ) - else: - - txn.add( - sp.decrease_validator_stake_with_reserve( + instruction = sp.decrease_validator_stake_with_reserve( sp.DecreaseValidatorStakeWithReserveParams( program_id=STAKE_POOL_PROGRAM_ID, stake_pool=stake_pool_address, @@ -684,11 +709,16 @@ async def decrease_validator_stake( transient_stake_seed=transient_stake_seed, ) ) - ) signers = [payer, staker] if payer != staker else [payer] recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, *signers, recent_blockhash=recent_blockhash, opts=OPTS) + txn = Transaction.new_signed_with_payer( + [instruction], + payer=payer.pubkey(), + recent_blockhash=recent_blockhash, + signing_keypairs=signers, + ) + await client.send_transaction(txn, opts=OPTS) async def create_token_metadata(client: AsyncClient, payer: Keypair, stake_pool_address: Pubkey, @@ -700,27 +730,31 @@ async def create_token_metadata(client: AsyncClient, payer: Keypair, stake_pool_ (withdraw_authority, _seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) (token_metadata, _seed) = find_metadata_account(stake_pool.pool_mint) - txn = Transaction(fee_payer=payer.pubkey()) - txn.add( - sp.create_token_metadata( - sp.CreateTokenMetadataParams( - program_id=STAKE_POOL_PROGRAM_ID, - stake_pool=stake_pool_address, - manager=stake_pool.manager, - pool_mint=stake_pool.pool_mint, - payer=payer.pubkey(), - name=name, - symbol=symbol, - uri=uri, - withdraw_authority=withdraw_authority, - token_metadata=token_metadata, - metadata_program_id=METADATA_PROGRAM_ID, - system_program_id=sys.ID, + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + txn = Transaction.new_signed_with_payer( + [ + sp.create_token_metadata( + sp.CreateTokenMetadataParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + manager=stake_pool.manager, + pool_mint=stake_pool.pool_mint, + payer=payer.pubkey(), + name=name, + symbol=symbol, + uri=uri, + withdraw_authority=withdraw_authority, + token_metadata=token_metadata, + metadata_program_id=METADATA_PROGRAM_ID, + system_program_id=sys.ID, + ) ) - ) + ], + recent_blockhash=recent_blockhash, + payer=payer.pubkey(), + signing_keypairs=[payer], ) - recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, payer, recent_blockhash=recent_blockhash, opts=OPTS) + await client.send_transaction(txn, opts=OPTS) async def update_token_metadata(client: AsyncClient, payer: Keypair, stake_pool_address: Pubkey, @@ -732,22 +766,26 @@ async def update_token_metadata(client: AsyncClient, payer: Keypair, stake_pool_ (withdraw_authority, _seed) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) (token_metadata, _seed) = find_metadata_account(stake_pool.pool_mint) - txn = Transaction(fee_payer=payer.pubkey()) - txn.add( - sp.update_token_metadata( - sp.UpdateTokenMetadataParams( - program_id=STAKE_POOL_PROGRAM_ID, - stake_pool=stake_pool_address, - manager=stake_pool.manager, - pool_mint=stake_pool.pool_mint, - name=name, - symbol=symbol, - uri=uri, - withdraw_authority=withdraw_authority, - token_metadata=token_metadata, - metadata_program_id=METADATA_PROGRAM_ID, + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + txn = Transaction.new_signed_with_payer( + [ + sp.update_token_metadata( + sp.UpdateTokenMetadataParams( + program_id=STAKE_POOL_PROGRAM_ID, + stake_pool=stake_pool_address, + manager=stake_pool.manager, + pool_mint=stake_pool.pool_mint, + name=name, + symbol=symbol, + uri=uri, + withdraw_authority=withdraw_authority, + token_metadata=token_metadata, + metadata_program_id=METADATA_PROGRAM_ID, + ) ) - ) + ], + payer=payer.pubkey(), + recent_blockhash=recent_blockhash, + signing_keypairs=[payer], ) - recent_blockhash = (await client.get_latest_blockhash()).value.blockhash - await client.send_transaction(txn, payer, recent_blockhash=recent_blockhash, opts=OPTS) + await client.send_transaction(txn, opts=OPTS) diff --git a/clients/py/tests/conftest.py b/clients/py/tests/conftest.py index df131d2c..a19049ae 100644 --- a/clients/py/tests/conftest.py +++ b/clients/py/tests/conftest.py @@ -11,6 +11,7 @@ from solders.pubkey import Pubkey from solana.rpc.async_api import AsyncClient from solana.rpc.commitment import Confirmed +from solana.exceptions import SolanaRpcException from spl.token.instructions import get_associated_token_address @@ -77,7 +78,12 @@ async def async_client(solana_test_validator) -> AsyncIterator[AsyncClient]: async_client = AsyncClient(commitment=Confirmed) total_attempts = 20 current_attempt = 0 - while not await async_client.is_connected(): + while True: + try: + if await async_client.is_connected(): + break + except SolanaRpcException: + pass if current_attempt == total_attempts: raise Exception("Could not connect to test validator") else: diff --git a/clients/py/vote/actions.py b/clients/py/vote/actions.py index 305d79a4..6f4a831b 100644 --- a/clients/py/vote/actions.py +++ b/clients/py/vote/actions.py @@ -4,7 +4,7 @@ from solana.rpc.commitment import Confirmed from solana.rpc.types import TxOpts from solders.sysvar import CLOCK, RENT -from solana.transaction import Transaction +from solders.transaction import Transaction import solders.system_program as sys from vote.constants import VOTE_PROGRAM_ID, VOTE_STATE_LEN @@ -16,32 +16,34 @@ async def create_vote( voter: Pubkey, withdrawer: Pubkey, commission: int): print(f"Creating vote account {vote.pubkey()}") resp = await client.get_minimum_balance_for_rent_exemption(VOTE_STATE_LEN) - txn = Transaction(fee_payer=payer.pubkey()) - txn.add( - sys.create_account( - sys.CreateAccountParams( - from_pubkey=payer.pubkey(), - to_pubkey=vote.pubkey(), - lamports=resp.value, - space=VOTE_STATE_LEN, - owner=VOTE_PROGRAM_ID, - ) - ) - ) - txn.add( - initialize( - InitializeParams( - vote=vote.pubkey(), - rent_sysvar=RENT, - clock_sysvar=CLOCK, - node=node.pubkey(), - authorized_voter=voter, - authorized_withdrawer=withdrawer, - commission=commission, + recent_blockhash = (await client.get_latest_blockhash()).value.blockhash + txn = Transaction.new_signed_with_payer( + [ + sys.create_account( + sys.CreateAccountParams( + from_pubkey=payer.pubkey(), + to_pubkey=vote.pubkey(), + lamports=resp.value, + space=VOTE_STATE_LEN, + owner=VOTE_PROGRAM_ID, + ) + ), + initialize( + InitializeParams( + vote=vote.pubkey(), + rent_sysvar=RENT, + clock_sysvar=CLOCK, + node=node.pubkey(), + authorized_voter=voter, + authorized_withdrawer=withdrawer, + commission=commission, + ) ) - ) + ], + payer=payer.pubkey(), + signing_keypairs=[payer, vote, node], + recent_blockhash=recent_blockhash, ) - recent_blockhash = (await client.get_latest_blockhash()).value.blockhash await client.send_transaction( - txn, payer, vote, node, recent_blockhash=recent_blockhash, + txn, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed))