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 create_vote(client: AsyncClient, payer: Keypair, vote: Keypair, node: Keypair, voter: PublicKey, withdrawer: PublicKey, commission: int): print(f"Creating vote account {vote.public_key}") resp = await client.get_minimum_balance_for_rent_exemption(VOTE_STATE_LEN) txn = Transaction() txn.add( sys.create_account( sys.CreateAccountParams( from_pubkey=payer.public_key, new_account_pubkey=vote.public_key, lamports=resp['result'], space=VOTE_STATE_LEN, program_id=VOTE_PROGRAM_ID, ))) txn.add( initialize( InitializeParams( vote=vote.public_key, rent_sysvar=SYSVAR_RENT_PUBKEY, clock_sysvar=SYSVAR_CLOCK_PUBKEY, node=node.public_key, authorized_voter=voter, authorized_withdrawer=withdrawer, commission=commission, ))) await client.send_transaction(txn, payer, vote, node, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed))
async def create_mint(client: AsyncClient, payer: Keypair, mint: Keypair, mint_authority: PublicKey): mint_balance = await AsyncToken.get_min_balance_rent_for_exempt_for_mint( client) print(f"Creating pool token mint {mint.public_key}") txn = Transaction() txn.add( sys.create_account( sys.CreateAccountParams( from_pubkey=payer.public_key, new_account_pubkey=mint.public_key, lamports=mint_balance, space=MINT_LAYOUT.sizeof(), program_id=TOKEN_PROGRAM_ID, ))) txn.add( spl_token.initialize_mint( spl_token.InitializeMintParams( program_id=TOKEN_PROGRAM_ID, mint=mint.public_key, decimals=9, mint_authority=mint_authority, freeze_authority=None, ))) await client.send_transaction(txn, payer, mint, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed))
def _create_account_args( self, owner: PublicKey, skip_confirmation: bool, balance_needed: int, ) -> Tuple[PublicKey, Transaction, Account, Account, TxOpts]: new_account = Account() # 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_account.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_account.public_key(), mint=self.pubkey, owner=owner, program_id=self.program_id))) return ( new_account.public_key(), txn, self.payer, new_account, TxOpts(skip_preflight=True, skip_confirmation=skip_confirmation), )
async def create_stake(client: AsyncClient, payer: Keypair, stake: Keypair, authority: PublicKey, lamports: int): print(f"Creating stake {stake.public_key}") resp = await client.get_minimum_balance_for_rent_exemption(STAKE_LEN) txn = Transaction() txn.add( sys.create_account( sys.CreateAccountParams( from_pubkey=payer.public_key, new_account_pubkey=stake.public_key, lamports=resp['result'] + lamports, space=STAKE_LEN, program_id=STAKE_PROGRAM_ID, ))) txn.add( st.initialize( st.InitializeParams(stake=stake.public_key, authorized=Authorized( staker=authority, withdrawer=authority, ), lockup=Lockup( unix_timestamp=0, epoch=0, custodian=sys.SYS_PROGRAM_ID, )))) await client.send_transaction(txn, payer, stake, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed))
def create_mint( conn: Client, payer: Account, mint_authority: PublicKey, decimals: int, program_id: PublicKey, freeze_authority: Optional[PublicKey] = None, skip_confirmation: bool = False, ) -> Token: """Create and initialize a token. :param conn: RPC connection to a solana cluster. :param payer: Fee payer for transaction. :param mint_authority: Account or multisig that will control minting. :param decimals: Location of the decimal place. :param program_id: SPL Token program account. :param freeze_authority: (optional) Account or multisig that can freeze token accounts. :param skip_confirmation: (optional) Option to skip transaction confirmation. :return: Token object for the newly minted token. If skip confirmation is set to `False`, this method will block for at most 30 seconds or until the transaction is confirmed. """ mint_account = Account() token = Token(conn, mint_account.public_key(), program_id, payer) # Allocate memory for the account balance_needed = Token.get_min_balance_rent_for_exempt_for_mint(conn) # Construct transaction txn = Transaction() txn.add( sp.create_account( sp.CreateAccountParams( from_pubkey=payer.public_key(), new_account_pubkey=mint_account.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_account.public_key(), decimals=decimals, mint_authority=mint_authority, freeze_authority=freeze_authority, ) ) ) # Send the two instructions conn.send_transaction( txn, payer, mint_account, opts=TxOpts(skip_confirmation=skip_confirmation, skip_preflight=True) ) return token
def test_create_account(): """Test creating a transaction for creat account.""" params = sp.CreateAccountParams( from_pubkey=Account().public_key(), new_account_pubkey=Account().public_key(), lamports=123, space=1, program_id=PublicKey(1), ) assert sp.decode_create_account(sp.create_account(params)) == params
def make_create_account_instruction( owner_address: PublicKey, new_account_address: PublicKey, lamports: int, program_id: PublicKey = DEFAULT_DEX_PROGRAM_ID, ) -> TransactionInstruction: return create_account( CreateAccountParams( from_pubkey=owner_address, new_account_pubkey=new_account_address, lamports=lamports, space=OPEN_ORDERS_LAYOUT.sizeof(), program_id=program_id, ))
def create_account( self, owner: PublicKey, skip_confirmation: bool = False, ) -> PublicKey: """Create and initialize a new account. This account may then be used as a `transfer()` or `approve()` destination. :param owner: User account that will own the new account. :param skip_confirmation: (optional) Option to skip transaction confirmation. :return: Public key of the new empty account. If skip confirmation is set to `False`, this method will block for at most 30 seconds or until the transaction is confirmed. """ new_account = Account() # Allocate memory for the account balance_needed = Token.get_min_balance_rent_for_exempt_for_account( self._conn) # Construct transaction txn = Transaction() txn.add( sp.create_account( sp.CreateAccountParams( from_pubkey=self.payer.public_key(), new_account_pubkey=new_account.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_account.public_key(), mint=self.pubkey, owner=owner, program_id=self.program_id))) # Send the two instructions self._conn.send_transaction(txn, self.payer, new_account, opts=TxOpts( skip_preflight=True, skip_confirmation=skip_confirmation)) return new_account.public_key()
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)
async def withdraw_stake( client: AsyncClient, payer: Keypair, source_transfer_authority: Keypair, destination_stake: Keypair, stake_pool_address: PublicKey, validator_vote: PublicKey, destination_stake_authority: PublicKey, source_pool_account: PublicKey, amount: int, ): resp = await client.get_account_info(stake_pool_address, commitment=Confirmed) data = resp['result']['value']['data'] stake_pool = StakePool.decode(data[0], data[1]) (withdraw_authority, _) = find_withdraw_authority_program_address(STAKE_POOL_PROGRAM_ID, stake_pool_address) (validator_stake, _) = find_stake_program_address( STAKE_POOL_PROGRAM_ID, validator_vote, stake_pool_address, ) resp = await client.get_minimum_balance_for_rent_exemption(STAKE_LEN) stake_rent_exemption = resp['result'] txn = Transaction() txn.add( sys.create_account( sys.CreateAccountParams( from_pubkey=payer.public_key, new_account_pubkey=destination_stake.public_key, lamports=stake_rent_exemption, space=STAKE_LEN, program_id=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.public_key, destination_stake_authority=destination_stake_authority, source_transfer_authority=source_transfer_authority.public_key, source_pool_account=source_pool_account, manager_fee_account=stake_pool.manager_fee_account, pool_mint=stake_pool.pool_mint, clock_sysvar=SYSVAR_CLOCK_PUBKEY, 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] await client.send_transaction( txn, *signers, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed))
async def create(client: AsyncClient, manager: Keypair, stake_pool: Keypair, validator_list: Keypair, pool_mint: PublicKey, reserve_stake: PublicKey, manager_fee_account: PublicKey, fee: Fee, referral_fee: int): resp = await client.get_minimum_balance_for_rent_exemption(STAKE_POOL_LAYOUT.sizeof()) pool_balance = resp['result'] txn = Transaction() txn.add( sys.create_account( sys.CreateAccountParams( from_pubkey=manager.public_key, new_account_pubkey=stake_pool.public_key, lamports=pool_balance, space=STAKE_POOL_LAYOUT.sizeof(), program_id=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['result'] txn.add( sys.create_account( sys.CreateAccountParams( from_pubkey=manager.public_key, new_account_pubkey=validator_list.public_key, lamports=validator_list_balance, space=validator_list_size, program_id=STAKE_POOL_PROGRAM_ID, ) ) ) await client.send_transaction( txn, manager, stake_pool, validator_list, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed)) (withdraw_authority, seed) = find_withdraw_authority_program_address( STAKE_POOL_PROGRAM_ID, stake_pool.public_key) txn = Transaction() txn.add( sp.initialize( sp.InitializeParams( program_id=STAKE_POOL_PROGRAM_ID, stake_pool=stake_pool.public_key, manager=manager.public_key, staker=manager.public_key, withdraw_authority=withdraw_authority, validator_list=validator_list.public_key, 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, ) ) ) await client.send_transaction( txn, manager, validator_list, opts=TxOpts(skip_confirmation=False, preflight_commitment=Confirmed))
def place_order( # pylint: disable=too-many-arguments,too-many-locals self, payer: PublicKey, owner: Account, order_type: OrderType, side: Side, limit_price: int, max_quantity: int, client_id: int = 0, opts: TxOpts = TxOpts(), ) -> RPCResponse: # TODO: Add open_orders_address_key param and fee_discount_pubkey transaction = Transaction() signers: List[Account] = [owner] open_order_accounts = self.find_open_orders_accounts_for_owner( owner.public_key()) if not open_order_accounts: new_open_orders_account = Account() mbfre_resp = self._conn.get_minimum_balance_for_rent_exemption( OPEN_ORDERS_LAYOUT.sizeof()) balanced_needed = mbfre_resp["result"] transaction.add( make_create_account_instruction( owner.public_key(), new_open_orders_account.public_key(), balanced_needed, self.state.program_id(), )) signers.append(new_open_orders_account) # TODO: Cache new_open_orders_account # TODO: Handle open_orders_address_key # TODO: Handle fee_discount_pubkey if payer == owner.public_key(): raise ValueError("Invalid payer account") # TODO: add integration test for SOL wrapping. should_wrap_sol = (side == side.Buy and self.state.quote_mint() == WRAPPED_SOL_MINT) or (side == side.Sell and self.state.base_mint == WRAPPED_SOL_MINT) wrapped_sol_account = Account() if should_wrap_sol: transaction.add( create_account( CreateAccountParams( from_pubkey=owner.public_key(), new_account_pubkey=wrapped_sol_account.public_key(), lamports=Market._get_lamport_need_for_sol_wrapping( limit_price, max_quantity, side, open_order_accounts), space=ACCOUNT_LEN, program_id=TOKEN_PROGRAM_ID, ))) transaction.add( initialize_account( InitializeAccountParams( account=wrapped_sol_account.public_key(), mint=WRAPPED_SOL_MINT, owner=owner.public_key(), program_id=SYSVAR_RENT_PUBKEY, ))) transaction.add( self.make_place_order_instruction( wrapped_sol_account.public_key() if should_wrap_sol else payer, owner, order_type, side, limit_price, max_quantity, client_id, open_order_accounts[0].address if open_order_accounts else new_open_orders_account.public_key(), )) if should_wrap_sol: transaction.add( close_account( CloseAccountParams( account=wrapped_sol_account.public_key(), owner=owner.public_key(), dest=owner.public_key(), ))) # TODO: extract `make_place_order_transaction`. return self._conn.send_transaction(transaction, *signers, opts=opts)