mirror of
https://github.com/chainstacklabs/pumpfun-bonkfun-bot.git
synced 2026-07-29 08:17:45 +00:00
feat(core): add support for creator fee update
This commit is contained in:
+8
-3
@@ -5,7 +5,7 @@ Bonding curve operations for pump.fun tokens.
|
||||
import struct
|
||||
from typing import Final
|
||||
|
||||
from construct import Flag, Int64ul, Struct
|
||||
from construct import Bytes, Flag, Int64ul, Struct
|
||||
from solders.pubkey import Pubkey
|
||||
|
||||
from core.client import SolanaClient
|
||||
@@ -28,6 +28,7 @@ class BondingCurveState:
|
||||
"real_sol_reserves" / Int64ul,
|
||||
"token_total_supply" / Int64ul,
|
||||
"complete" / Flag,
|
||||
"creator" / Bytes(32), # Added new creator field - 32 bytes for Pubkey
|
||||
)
|
||||
|
||||
def __init__(self, data: bytes) -> None:
|
||||
@@ -44,6 +45,10 @@ class BondingCurveState:
|
||||
|
||||
parsed = self._STRUCT.parse(data[8:])
|
||||
self.__dict__.update(parsed)
|
||||
|
||||
# Convert raw bytes to Pubkey for creator field
|
||||
if hasattr(self, 'creator') and isinstance(self.creator, bytes):
|
||||
self.creator = Pubkey.from_bytes(self.creator)
|
||||
|
||||
def calculate_price(self) -> float:
|
||||
"""Calculate token price in SOL.
|
||||
@@ -103,8 +108,8 @@ class BondingCurveManager:
|
||||
return BondingCurveState(account.data)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to get curve state: {str(e)}")
|
||||
raise ValueError(f"Invalid curve state: {str(e)}")
|
||||
logger.error(f"Failed to get curve state: {e!s}")
|
||||
raise ValueError(f"Invalid curve state: {e!s}")
|
||||
|
||||
async def calculate_price(self, curve_address: Pubkey) -> float:
|
||||
"""Calculate the current price of a token.
|
||||
|
||||
@@ -7,9 +7,11 @@ import json
|
||||
import struct
|
||||
from typing import Any
|
||||
|
||||
import base58
|
||||
from solders.pubkey import Pubkey
|
||||
from solders.transaction import VersionedTransaction
|
||||
|
||||
from core.pubkeys import PumpAddresses
|
||||
from trading.base import TokenInfo
|
||||
from utils.logger import get_logger
|
||||
|
||||
@@ -41,7 +43,7 @@ class PumpEventProcessor:
|
||||
with open("idl/pump_fun_idl.json") as f:
|
||||
return json.load(f)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to load IDL: {str(e)}")
|
||||
logger.error(f"Failed to load IDL: {e!s}")
|
||||
# Create a minimal IDL with just what we need
|
||||
return {
|
||||
"instructions": [
|
||||
@@ -111,6 +113,8 @@ class PumpEventProcessor:
|
||||
decoded_args = self._decode_create_instruction(
|
||||
ix_data, create_ix, account_keys
|
||||
)
|
||||
creator = Pubkey.from_string(decoded_args["creator"])
|
||||
creator_vault = self._find_creator_vault(creator)
|
||||
|
||||
return TokenInfo(
|
||||
name=decoded_args["name"],
|
||||
@@ -122,10 +126,12 @@ class PumpEventProcessor:
|
||||
decoded_args["associatedBondingCurve"]
|
||||
),
|
||||
user=Pubkey.from_string(decoded_args["user"]),
|
||||
creator=creator,
|
||||
creator_vault=creator_vault,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing transaction: {str(e)}")
|
||||
logger.error(f"Error processing transaction: {e!s}")
|
||||
|
||||
return None
|
||||
|
||||
@@ -151,8 +157,8 @@ class PumpEventProcessor:
|
||||
offset += 4
|
||||
value = ix_data[offset : offset + length].decode("utf-8")
|
||||
offset += length
|
||||
elif arg["type"] == "publicKey":
|
||||
value = base64.b64encode(ix_data[offset : offset + 32]).decode("utf-8")
|
||||
elif arg["type"] == "pubkey":
|
||||
value = base58.b58encode(ix_data[offset : offset + 32]).decode("utf-8")
|
||||
offset += 32
|
||||
else:
|
||||
logger.warning(f"Unsupported type: {arg['type']}")
|
||||
@@ -166,3 +172,22 @@ class PumpEventProcessor:
|
||||
args["user"] = str(accounts[7])
|
||||
|
||||
return args
|
||||
|
||||
def _find_creator_vault(self, creator: Pubkey) -> Pubkey:
|
||||
"""
|
||||
Find the creator vault for a creator.
|
||||
|
||||
Args:
|
||||
creator: Creator address
|
||||
|
||||
Returns:
|
||||
Creator vault address
|
||||
"""
|
||||
derived_address, _ = Pubkey.find_program_address(
|
||||
[
|
||||
b"creator-vault",
|
||||
bytes(creator)
|
||||
],
|
||||
PumpAddresses.PROGRAM,
|
||||
)
|
||||
return derived_address
|
||||
|
||||
@@ -5,8 +5,10 @@ Event processing for pump.fun tokens using Geyser data.
|
||||
import struct
|
||||
from typing import Final
|
||||
|
||||
import base58
|
||||
from solders.pubkey import Pubkey
|
||||
|
||||
from core.pubkeys import PumpAddresses
|
||||
from trading.base import TokenInfo
|
||||
from utils.logger import get_logger
|
||||
|
||||
@@ -55,6 +57,12 @@ class GeyserEventProcessor:
|
||||
offset += length
|
||||
return value
|
||||
|
||||
def read_pubkey():
|
||||
nonlocal offset
|
||||
value = base58.b58encode(instruction_data[offset : offset + 32]).decode("utf-8")
|
||||
offset += 32
|
||||
return Pubkey.from_string(value)
|
||||
|
||||
# Helper to get account key
|
||||
def get_account_key(index):
|
||||
if index >= len(accounts):
|
||||
@@ -67,11 +75,14 @@ class GeyserEventProcessor:
|
||||
name = read_string()
|
||||
symbol = read_string()
|
||||
uri = read_string()
|
||||
creator = read_pubkey()
|
||||
|
||||
mint = get_account_key(0)
|
||||
bonding_curve = get_account_key(2)
|
||||
associated_bonding_curve = get_account_key(3)
|
||||
user = get_account_key(7)
|
||||
|
||||
creator_vault = self._find_creator_vault(creator)
|
||||
|
||||
if not all([mint, bonding_curve, associated_bonding_curve, user]):
|
||||
logger.warning("Missing required account keys in token creation")
|
||||
@@ -85,8 +96,29 @@ class GeyserEventProcessor:
|
||||
bonding_curve=bonding_curve,
|
||||
associated_bonding_curve=associated_bonding_curve,
|
||||
user=user,
|
||||
creator=creator,
|
||||
creator_vault=creator_vault,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to process transaction data: {e}")
|
||||
return None
|
||||
|
||||
def _find_creator_vault(self, creator: Pubkey) -> Pubkey:
|
||||
"""
|
||||
Find the creator vault for a creator.
|
||||
|
||||
Args:
|
||||
creator: Creator address
|
||||
|
||||
Returns:
|
||||
Creator vault address
|
||||
"""
|
||||
derived_address, _ = Pubkey.find_program_address(
|
||||
[
|
||||
b"creator-vault",
|
||||
bytes(creator)
|
||||
],
|
||||
PumpAddresses.PROGRAM,
|
||||
)
|
||||
return derived_address
|
||||
@@ -9,7 +9,7 @@ from typing import Final
|
||||
import base58
|
||||
from solders.pubkey import Pubkey
|
||||
|
||||
from core.pubkeys import SystemAddresses
|
||||
from core.pubkeys import PumpAddresses, SystemAddresses
|
||||
from trading.base import TokenInfo
|
||||
from utils.logger import get_logger
|
||||
|
||||
@@ -62,6 +62,8 @@ class LogsEventProcessor:
|
||||
associated_curve = self._find_associated_bonding_curve(
|
||||
mint, bonding_curve
|
||||
)
|
||||
creator = Pubkey.from_string(parsed_data["creator"])
|
||||
creator_vault = self._find_creator_vault(creator)
|
||||
|
||||
return TokenInfo(
|
||||
name=parsed_data["name"],
|
||||
@@ -71,6 +73,8 @@ class LogsEventProcessor:
|
||||
bonding_curve=bonding_curve,
|
||||
associated_bonding_curve=associated_curve,
|
||||
user=Pubkey.from_string(parsed_data["user"]),
|
||||
creator=creator,
|
||||
creator_vault=creator_vault,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to process log data: {e}")
|
||||
@@ -106,6 +110,7 @@ class LogsEventProcessor:
|
||||
("mint", "publicKey"),
|
||||
("bondingCurve", "publicKey"),
|
||||
("user", "publicKey"),
|
||||
("creator", "publicKey"),
|
||||
]
|
||||
|
||||
try:
|
||||
@@ -149,3 +154,22 @@ class LogsEventProcessor:
|
||||
SystemAddresses.ASSOCIATED_TOKEN_PROGRAM,
|
||||
)
|
||||
return derived_address
|
||||
|
||||
def _find_creator_vault(self, creator: Pubkey) -> Pubkey:
|
||||
"""
|
||||
Find the creator vault for a creator.
|
||||
|
||||
Args:
|
||||
creator: Creator address
|
||||
|
||||
Returns:
|
||||
Creator vault address
|
||||
"""
|
||||
derived_address, _ = Pubkey.find_program_address(
|
||||
[
|
||||
b"creator-vault",
|
||||
bytes(creator)
|
||||
],
|
||||
PumpAddresses.PROGRAM,
|
||||
)
|
||||
return derived_address
|
||||
|
||||
@@ -22,6 +22,8 @@ class TokenInfo:
|
||||
bonding_curve: Pubkey
|
||||
associated_bonding_curve: Pubkey
|
||||
user: Pubkey
|
||||
creator: Pubkey
|
||||
creator_vault: Pubkey
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict[str, Any]) -> "TokenInfo":
|
||||
@@ -41,6 +43,8 @@ class TokenInfo:
|
||||
bonding_curve=Pubkey.from_string(data["bondingCurve"]),
|
||||
associated_bonding_curve=Pubkey.from_string(data["associatedBondingCurve"]),
|
||||
user=Pubkey.from_string(data["user"]),
|
||||
creator=Pubkey.from_string(data["creator"]),
|
||||
creator_vault=Pubkey.from_string(data["creator_vault"]),
|
||||
)
|
||||
|
||||
def to_dict(self) -> dict[str, str]:
|
||||
@@ -57,6 +61,8 @@ class TokenInfo:
|
||||
"bondingCurve": str(self.bonding_curve),
|
||||
"associatedBondingCurve": str(self.associated_bonding_curve),
|
||||
"user": str(self.user),
|
||||
"creator": str(self.creator),
|
||||
"creatorVault": str(self.creator_vault),
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ class TokenBuyer(Trader):
|
||||
pubkey=SystemAddresses.TOKEN_PROGRAM, is_signer=False, is_writable=False
|
||||
),
|
||||
AccountMeta(
|
||||
pubkey=SystemAddresses.RENT, is_signer=False, is_writable=False
|
||||
pubkey=token_info.creator_vault, is_signer=False, is_writable=True
|
||||
),
|
||||
AccountMeta(
|
||||
pubkey=PumpAddresses.EVENT_AUTHORITY, is_signer=False, is_writable=False
|
||||
|
||||
@@ -128,7 +128,7 @@ class TokenSeller(Trader):
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Sell operation failed: {str(e)}")
|
||||
logger.error(f"Sell operation failed: {e!s}")
|
||||
return TradeResult(success=False, error_message=str(e))
|
||||
|
||||
async def _send_sell_transaction(
|
||||
@@ -175,9 +175,7 @@ class TokenSeller(Trader):
|
||||
pubkey=SystemAddresses.PROGRAM, is_signer=False, is_writable=False
|
||||
),
|
||||
AccountMeta(
|
||||
pubkey=SystemAddresses.ASSOCIATED_TOKEN_PROGRAM,
|
||||
is_signer=False,
|
||||
is_writable=False,
|
||||
pubkey=token_info.creator_vault, is_signer=False, is_writable=True,
|
||||
),
|
||||
AccountMeta(
|
||||
pubkey=SystemAddresses.TOKEN_PROGRAM, is_signer=False, is_writable=False
|
||||
@@ -209,5 +207,5 @@ class TokenSeller(Trader):
|
||||
),
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Sell transaction failed: {str(e)}")
|
||||
logger.error(f"Sell transaction failed: {e!s}")
|
||||
raise
|
||||
|
||||
Reference in New Issue
Block a user