diff --git a/learning-examples/manual_buy_cu_optimized.py b/learning-examples/manual_buy_cu_optimized.py new file mode 100644 index 0000000..fe831b2 --- /dev/null +++ b/learning-examples/manual_buy_cu_optimized.py @@ -0,0 +1,480 @@ +import asyncio +import base64 +import hashlib +import json +import os +import struct + +import base58 +import websockets +from construct import Bytes, Flag, Int64ul, Struct +from solana.rpc.async_api import AsyncClient +from solana.rpc.commitment import Confirmed +from solana.rpc.types import TxOpts +from solders.compute_budget import set_compute_unit_price +from solders.instruction import AccountMeta, Instruction +from solders.keypair import Keypair +from solders.message import Message +from solders.pubkey import Pubkey +from solders.transaction import Transaction +from spl.token.instructions import ( + create_idempotent_associated_token_account, + get_associated_token_address, +) + +# Discriminators +EXPECTED_DISCRIMINATOR = struct.pack(" None: + if data[:8] != EXPECTED_DISCRIMINATOR: + raise ValueError("Invalid curve state discriminator") + parsed = self._STRUCT.parse(data[8:]) + self.__dict__.update(parsed) + if hasattr(self, "creator") and isinstance(self.creator, bytes): + self.creator = Pubkey.from_bytes(self.creator) + + +async def get_pump_curve_state( + conn: AsyncClient, curve_address: Pubkey +) -> BondingCurveState: + response = await conn.get_account_info(curve_address, encoding="base64") + if not response.value or not response.value.data: + raise ValueError("Invalid curve state: No data") + data = response.value.data + if data[:8] != EXPECTED_DISCRIMINATOR: + raise ValueError("Invalid curve state discriminator") + return BondingCurveState(data) + + +def calculate_pump_curve_price(curve_state: BondingCurveState) -> float: + if curve_state.virtual_token_reserves <= 0 or curve_state.virtual_sol_reserves <= 0: + raise ValueError("Invalid reserve state") + return (curve_state.virtual_sol_reserves / LAMPORTS_PER_SOL) / ( + curve_state.virtual_token_reserves / 10**TOKEN_DECIMALS + ) + + +def _find_creator_vault(creator: Pubkey) -> Pubkey: + derived_address, _ = Pubkey.find_program_address( + [b"creator-vault", bytes(creator)], PUMP_PROGRAM + ) + return derived_address + + +def _find_global_volume_accumulator() -> Pubkey: + derived_address, _ = Pubkey.find_program_address( + [b"global_volume_accumulator"], PUMP_PROGRAM + ) + return derived_address + + +def _find_user_volume_accumulator(user: Pubkey) -> Pubkey: + derived_address, _ = Pubkey.find_program_address( + [b"user_volume_accumulator", bytes(user)], PUMP_PROGRAM + ) + return derived_address + + +def _find_fee_config() -> Pubkey: + derived_address, _ = Pubkey.find_program_address( + [b"fee_config", bytes(PUMP_PROGRAM)], PUMP_FEE_PROGRAM + ) + return derived_address + + +def set_loaded_accounts_data_size_limit(bytes_limit: int) -> Instruction: + """Create SetLoadedAccountsDataSizeLimit compute budget instruction.""" + data = struct.pack("