mirror of
https://github.com/chainstacklabs/pumpfun-bonkfun-bot.git
synced 2026-07-31 17:27:43 +00:00
Merge pull request #124 from chainstacklabs/feat/upd-buy-instr
Add global_volume_accumulator and user_volume_accumulator to buy instructions (bonding curve, amm)
This commit is contained in:
+1074
-2
File diff suppressed because it is too large
Load Diff
+1045
-2
File diff suppressed because it is too large
Load Diff
@@ -104,6 +104,27 @@ def _find_creator_vault(creator: Pubkey) -> Pubkey:
|
||||
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
|
||||
|
||||
|
||||
async def buy_token(
|
||||
mint: Pubkey,
|
||||
bonding_curve: Pubkey,
|
||||
@@ -153,6 +174,8 @@ async def buy_token(
|
||||
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(payer.pubkey()), is_signer=False, is_writable=True),
|
||||
]
|
||||
|
||||
discriminator = struct.pack("<Q", 16927863322537952870)
|
||||
|
||||
@@ -101,6 +101,27 @@ def find_creator_vault(creator: Pubkey) -> Pubkey:
|
||||
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,
|
||||
@@ -177,6 +198,8 @@ def create_buy_instruction(
|
||||
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 = (
|
||||
|
||||
@@ -20,16 +20,16 @@ from solana.rpc.commitment import Confirmed
|
||||
from solana.rpc.types import MemcmpOpts, TxOpts
|
||||
from solders.compute_budget import set_compute_unit_limit, set_compute_unit_price
|
||||
from solders.instruction import AccountMeta, Instruction
|
||||
from solders.system_program import TransferParams, transfer
|
||||
from solders.keypair import Keypair
|
||||
from solders.message import Message
|
||||
from solders.pubkey import Pubkey
|
||||
from solders.system_program import TransferParams, transfer
|
||||
from solders.transaction import VersionedTransaction
|
||||
from spl.token.instructions import (
|
||||
SyncNativeParams,
|
||||
create_idempotent_associated_token_account,
|
||||
get_associated_token_address,
|
||||
sync_native,
|
||||
SyncNativeParams
|
||||
)
|
||||
|
||||
load_dotenv()
|
||||
@@ -165,6 +165,44 @@ def find_coin_creator_vault(coin_creator: Pubkey) -> Pubkey:
|
||||
)
|
||||
return derived_address
|
||||
|
||||
def find_global_volume_accumulator() -> Pubkey:
|
||||
"""Derive the Program Derived Address (PDA) for the global volume accumulator.
|
||||
|
||||
Calculates the deterministic PDA that tracks global trading volume
|
||||
across all pools in the PUMP AMM protocol.
|
||||
|
||||
Returns:
|
||||
Pubkey of the derived global volume accumulator account
|
||||
"""
|
||||
derived_address, _ = Pubkey.find_program_address(
|
||||
[
|
||||
b"global_volume_accumulator"
|
||||
],
|
||||
PUMP_AMM_PROGRAM_ID,
|
||||
)
|
||||
return derived_address
|
||||
|
||||
def find_user_volume_accumulator(user: Pubkey) -> Pubkey:
|
||||
"""Derive the Program Derived Address (PDA) for a user's volume accumulator.
|
||||
|
||||
Calculates the deterministic PDA that tracks trading volume
|
||||
for a specific user in the PUMP AMM protocol.
|
||||
|
||||
Args:
|
||||
user: Pubkey of the user account
|
||||
|
||||
Returns:
|
||||
Pubkey of the derived user volume accumulator account
|
||||
"""
|
||||
derived_address, _ = Pubkey.find_program_address(
|
||||
[
|
||||
b"user_volume_accumulator",
|
||||
bytes(user)
|
||||
],
|
||||
PUMP_AMM_PROGRAM_ID,
|
||||
)
|
||||
return derived_address
|
||||
|
||||
async def calculate_token_pool_price(client: AsyncClient, pool_base_token_account: Pubkey, pool_quote_token_account: Pubkey) -> float:
|
||||
"""Calculate the current price of tokens in an AMM pool.
|
||||
|
||||
@@ -229,6 +267,10 @@ async def buy_pump_swap(client: AsyncClient, pump_fun_amm_market: Pubkey, payer:
|
||||
print(f"Buying {base_amount_out / (10**TOKEN_DECIMALS):.10f} tokens")
|
||||
print(f"Maximum SOL input: {max_sol_input / LAMPORTS_PER_SOL:.10f} SOL")
|
||||
|
||||
# Calculate required PDAs for volume tracking
|
||||
global_volume_accumulator = find_global_volume_accumulator()
|
||||
user_volume_accumulator = find_user_volume_accumulator(payer.pubkey())
|
||||
|
||||
# Define all accounts needed for the buy instruction
|
||||
accounts = [
|
||||
AccountMeta(pubkey=pump_fun_amm_market, is_signer=False, is_writable=False),
|
||||
@@ -250,6 +292,8 @@ async def buy_pump_swap(client: AsyncClient, pump_fun_amm_market: Pubkey, payer:
|
||||
AccountMeta(pubkey=PUMP_AMM_PROGRAM_ID, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=coin_creator_vault_ata, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=coin_creator_vault_authority, is_signer=False, is_writable=False),
|
||||
AccountMeta(pubkey=global_volume_accumulator, is_signer=False, is_writable=True),
|
||||
AccountMeta(pubkey=user_volume_accumulator, is_signer=False, is_writable=True),
|
||||
]
|
||||
|
||||
data = BUY_DISCRIMINATOR + struct.pack("<Q", base_amount_out) + struct.pack("<Q", max_sol_input)
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ async def start_bot(config_path: str):
|
||||
"wait_before_new_token", 15
|
||||
),
|
||||
max_token_age=cfg.get("timing", {}).get("max_token_age", 0.001),
|
||||
token_wait_timeout=cfg.get("timing", {}).get("token_wait_timeout", 30),
|
||||
token_wait_timeout=cfg.get("timing", {}).get("token_wait_timeout", 120),
|
||||
# Cleanup settings
|
||||
cleanup_mode=cfg.get("cleanup", {}).get("mode", "disabled"),
|
||||
cleanup_force_close_with_burn=cfg.get("cleanup", {}).get(
|
||||
|
||||
@@ -49,3 +49,34 @@ class PumpAddresses:
|
||||
LIQUIDITY_MIGRATOR: Final[Pubkey] = Pubkey.from_string(
|
||||
"39azUYFWPz3VHgKCf3VChUwbpURdCHRxjWVowf5jUJjg"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def find_global_volume_accumulator() -> Pubkey:
|
||||
"""
|
||||
Derive the Program Derived Address (PDA) for the global volume accumulator.
|
||||
|
||||
Returns:
|
||||
Pubkey of the derived global volume accumulator account
|
||||
"""
|
||||
derived_address, _ = Pubkey.find_program_address(
|
||||
[b"global_volume_accumulator"],
|
||||
PumpAddresses.PROGRAM,
|
||||
)
|
||||
return derived_address
|
||||
|
||||
@staticmethod
|
||||
def find_user_volume_accumulator(user: Pubkey) -> Pubkey:
|
||||
"""
|
||||
Derive the Program Derived Address (PDA) for a user's volume accumulator.
|
||||
|
||||
Args:
|
||||
user: Pubkey of the user account
|
||||
|
||||
Returns:
|
||||
Pubkey of the derived user volume accumulator account
|
||||
"""
|
||||
derived_address, _ = Pubkey.find_program_address(
|
||||
[b"user_volume_accumulator", bytes(user)],
|
||||
PumpAddresses.PROGRAM,
|
||||
)
|
||||
return derived_address
|
||||
|
||||
@@ -195,6 +195,12 @@ class TokenBuyer(Trader):
|
||||
AccountMeta(
|
||||
pubkey=PumpAddresses.PROGRAM, is_signer=False, is_writable=False
|
||||
),
|
||||
AccountMeta(
|
||||
pubkey=PumpAddresses.find_global_volume_accumulator(), is_signer=False, is_writable=True
|
||||
),
|
||||
AccountMeta(
|
||||
pubkey=PumpAddresses.find_user_volume_accumulator(self.wallet.pubkey), is_signer=False, is_writable=True
|
||||
),
|
||||
]
|
||||
|
||||
# Prepare idempotent create ATA instruction: it will not fail if ATA already exists
|
||||
|
||||
Reference in New Issue
Block a user