import asyncio import os import struct from typing import Final import base58 from dotenv import load_dotenv 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_limit, 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, ) # Configuration for the token to be created TOKEN_NAME = "Test Token" TOKEN_SYMBOL = "TEST" TOKEN_URI = "https://example.com/token.json" BUY_AMOUNT_SOL = 0.001 # Amount of SOL to spend on buying MAX_SLIPPAGE = 0.3 # 30% slippage PRIORITY_FEE_MICROLAMPORTS = 37_037 # Priority fee in microlamports COMPUTE_UNIT_LIMIT = 250_000 # Compute unit limit for the transaction load_dotenv() # Global constants from existing codebase PUMP_PROGRAM: Final[Pubkey] = Pubkey.from_string( "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P" ) PUMP_GLOBAL: Final[Pubkey] = Pubkey.from_string( "4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf" ) PUMP_EVENT_AUTHORITY: Final[Pubkey] = Pubkey.from_string( "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1" ) PUMP_FEE: Final[Pubkey] = Pubkey.from_string( "CebN5WGQ4jvEPvsVU4EoHEpgzq1VV7AbicfhtW4xC9iM" ) PUMP_MINT_AUTHORITY: Final[Pubkey] = Pubkey.from_string( "TSLvdd1pWpHVjahSpsvCXUbgwsL3JAcvokwaKt1eokM" ) SYSTEM_PROGRAM: Final[Pubkey] = Pubkey.from_string("11111111111111111111111111111111") SYSTEM_TOKEN_PROGRAM: Final[Pubkey] = Pubkey.from_string( "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" ) SYSTEM_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM: Final[Pubkey] = Pubkey.from_string( "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" ) SYSTEM_RENT: Final[Pubkey] = Pubkey.from_string( "SysvarRent111111111111111111111111111111111" ) METAPLEX_TOKEN_METADATA: Final[Pubkey] = Pubkey.from_string( "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" ) LAMPORTS_PER_SOL: Final[int] = 1_000_000_000 TOKEN_DECIMALS: Final[int] = 6 # Discriminators CREATE_DISCRIMINATOR: Final[bytes] = struct.pack(" tuple[Pubkey, int]: """Find the bonding curve PDA for a mint.""" return Pubkey.find_program_address([b"bonding-curve", bytes(mint)], PUMP_PROGRAM) def find_associated_bonding_curve(mint: Pubkey, bonding_curve: Pubkey) -> Pubkey: """Find the associated bonding curve token account.""" derived_address, _ = Pubkey.find_program_address( [ bytes(bonding_curve), bytes(SYSTEM_TOKEN_PROGRAM), bytes(mint), ], SYSTEM_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM, ) return derived_address def find_metadata_address(mint: Pubkey) -> Pubkey: """Find the metadata PDA for a mint.""" derived_address, _ = Pubkey.find_program_address( [ b"metadata", bytes(METAPLEX_TOKEN_METADATA), bytes(mint), ], METAPLEX_TOKEN_METADATA, ) return derived_address def find_creator_vault(creator: Pubkey) -> Pubkey: """Find the creator vault PDA.""" 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 create_pump_create_instruction( mint: Pubkey, mint_authority: Pubkey, bonding_curve: Pubkey, associated_bonding_curve: Pubkey, global_state: Pubkey, metadata: Pubkey, user: Pubkey, creator: Pubkey, name: str, symbol: str, uri: str, ) -> Instruction: """Create the pump.fun create instruction.""" accounts = [ AccountMeta(pubkey=mint, is_signer=True, is_writable=True), AccountMeta(pubkey=mint_authority, is_signer=False, is_writable=False), AccountMeta(pubkey=bonding_curve, is_signer=False, is_writable=True), AccountMeta(pubkey=associated_bonding_curve, is_signer=False, is_writable=True), AccountMeta(pubkey=global_state, is_signer=False, is_writable=False), AccountMeta(pubkey=METAPLEX_TOKEN_METADATA, is_signer=False, is_writable=False), AccountMeta(pubkey=metadata, is_signer=False, is_writable=True), AccountMeta(pubkey=user, is_signer=True, is_writable=True), AccountMeta(pubkey=SYSTEM_PROGRAM, is_signer=False, is_writable=False), AccountMeta(pubkey=SYSTEM_TOKEN_PROGRAM, is_signer=False, is_writable=False), AccountMeta( pubkey=SYSTEM_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM, is_signer=False, is_writable=False, ), AccountMeta(pubkey=SYSTEM_RENT, is_signer=False, is_writable=False), AccountMeta(pubkey=PUMP_EVENT_AUTHORITY, is_signer=False, is_writable=False), AccountMeta(pubkey=PUMP_PROGRAM, is_signer=False, is_writable=False), ] # Encode string as length-prefixed def encode_string(s: str) -> bytes: encoded = s.encode("utf-8") return struct.pack(" bytes: return bytes(pubkey) data = ( CREATE_DISCRIMINATOR + encode_string(name) + encode_string(symbol) + encode_string(uri) + encode_pubkey(creator) ) return Instruction(PUMP_PROGRAM, data, accounts) def create_buy_instruction( global_state: Pubkey, fee_recipient: Pubkey, mint: Pubkey, bonding_curve: Pubkey, associated_bonding_curve: Pubkey, associated_user: Pubkey, user: Pubkey, creator_vault: Pubkey, token_amount: int, max_sol_cost: int, ) -> Instruction: """Create the buy instruction.""" accounts = [ AccountMeta(pubkey=global_state, is_signer=False, is_writable=False), AccountMeta(pubkey=fee_recipient, is_signer=False, is_writable=True), AccountMeta(pubkey=mint, is_signer=False, is_writable=False), AccountMeta(pubkey=bonding_curve, is_signer=False, is_writable=True), AccountMeta(pubkey=associated_bonding_curve, is_signer=False, is_writable=True), AccountMeta(pubkey=associated_user, is_signer=False, is_writable=True), AccountMeta(pubkey=user, is_signer=True, is_writable=True), AccountMeta(pubkey=SYSTEM_PROGRAM, is_signer=False, is_writable=False), AccountMeta(pubkey=SYSTEM_TOKEN_PROGRAM, is_signer=False, is_writable=False), AccountMeta(pubkey=creator_vault, is_signer=False, is_writable=True), AccountMeta(pubkey=PUMP_EVENT_AUTHORITY, is_signer=False, is_writable=False), AccountMeta(pubkey=PUMP_PROGRAM, is_signer=False, is_writable=False), AccountMeta( pubkey=_find_global_volume_accumulator(), is_signer=False, is_writable=True ), AccountMeta( pubkey=_find_user_volume_accumulator(user), is_signer=False, is_writable=True, ), ] data = ( BUY_DISCRIMINATOR + struct.pack("