fix(examples): add bonding_curve_v2 to learning examples (#160)

* fix(examples): add bonding_curve_v2 remaining account to learning examples

Add the required bonding_curve_v2 PDA as a remaining account to buy/sell
instructions in manual_buy, manual_sell, mint_and_buy, and mint_and_buy_v2
learning examples, matching the pump.fun program upgrade.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(examples): add bonding_curve_v2 to manual_buy_geyser and manual_buy_cu_optimized

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Anton Sauchyk
2026-02-27 23:54:18 +01:00
committed by GitHub
parent 4a48f545c1
commit 546b94af6f
6 changed files with 136 additions and 22 deletions
+34 -8
View File
@@ -159,6 +159,14 @@ def _find_fee_config() -> Pubkey:
return derived_address
def _find_bonding_curve_v2(mint: Pubkey) -> Pubkey:
derived_address, _ = Pubkey.find_program_address(
[b"bonding-curve-v2", bytes(mint)],
PUMP_PROGRAM,
)
return derived_address
async def get_fee_recipient(
client: AsyncClient, curve_state: BondingCurveState
) -> Pubkey:
@@ -253,9 +261,7 @@ async def buy_token(
),
AccountMeta(pubkey=payer.pubkey(), is_signer=True, is_writable=True),
AccountMeta(pubkey=SYSTEM_PROGRAM, is_signer=False, is_writable=False),
AccountMeta(
pubkey=token_program, is_signer=False, is_writable=False
),
AccountMeta(pubkey=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
@@ -283,6 +289,12 @@ async def buy_token(
is_signer=False,
is_writable=False,
),
# Remaining account: bonding_curve_v2 (readonly, required for all coins)
AccountMeta(
pubkey=_find_bonding_curve_v2(mint),
is_signer=False,
is_writable=False,
),
]
discriminator = struct.pack("<Q", 16927863322537952870)
@@ -433,7 +445,9 @@ async def listen_for_create_transaction():
if discriminator == create_discriminator:
instruction_name = "create"
token_program = SYSTEM_TOKEN_PROGRAM
elif discriminator == create_v2_discriminator:
elif (
discriminator == create_v2_discriminator
):
instruction_name = "create_v2"
token_program = TOKEN_2022_PROGRAM
@@ -457,8 +471,12 @@ async def listen_for_create_transaction():
)
)
# Add token program info to decoded args
decoded_args["token_program"] = str(token_program)
decoded_args["is_token_2022"] = (token_program == TOKEN_2022_PROGRAM)
decoded_args["token_program"] = str(
token_program
)
decoded_args["is_token_2022"] = (
token_program == TOKEN_2022_PROGRAM
)
return decoded_args
@@ -488,13 +506,21 @@ async def main():
slippage = 0.3 # 30% slippage tolerance
print(f"Bonding curve address: {bonding_curve}")
print(f"Token Program: {token_program} ({'Token2022' if token_data['is_token_2022'] else 'Standard Token'})")
print(
f"Token Program: {token_program} ({'Token2022' if token_data['is_token_2022'] else 'Standard Token'})"
)
print(f"Token price: {token_price_sol:.10f} SOL")
print(
f"Buying {amount:.6f} SOL worth of the new token with {slippage * 100:.1f}% slippage tolerance..."
)
await buy_token(
mint, bonding_curve, associated_bonding_curve, creator_vault, token_program, amount, slippage
mint,
bonding_curve,
associated_bonding_curve,
creator_vault,
token_program,
amount,
slippage,
)
+34 -8
View File
@@ -180,6 +180,14 @@ def _find_fee_config() -> Pubkey:
return derived_address
def _find_bonding_curve_v2(mint: Pubkey) -> Pubkey:
derived_address, _ = Pubkey.find_program_address(
[b"bonding-curve-v2", bytes(mint)],
PUMP_PROGRAM,
)
return derived_address
async def get_fee_recipient(
client: AsyncClient, curve_state: BondingCurveState
) -> Pubkey:
@@ -291,9 +299,7 @@ async def buy_token(
),
AccountMeta(pubkey=payer.pubkey(), is_signer=True, is_writable=True),
AccountMeta(pubkey=SYSTEM_PROGRAM, is_signer=False, is_writable=False),
AccountMeta(
pubkey=token_program, is_signer=False, is_writable=False
),
AccountMeta(pubkey=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
@@ -321,6 +327,12 @@ async def buy_token(
is_signer=False,
is_writable=False,
),
# Remaining account: bonding_curve_v2 (readonly, required for all coins)
AccountMeta(
pubkey=_find_bonding_curve_v2(mint),
is_signer=False,
is_writable=False,
),
]
discriminator = struct.pack("<Q", 16927863322537952870)
@@ -475,7 +487,9 @@ async def listen_for_create_transaction():
if discriminator == create_discriminator:
instruction_name = "create"
token_program = SYSTEM_TOKEN_PROGRAM
elif discriminator == create_v2_discriminator:
elif (
discriminator == create_v2_discriminator
):
instruction_name = "create_v2"
token_program = TOKEN_2022_PROGRAM
@@ -499,8 +513,12 @@ async def listen_for_create_transaction():
)
)
# Add token program info to decoded args
decoded_args["token_program"] = str(token_program)
decoded_args["is_token_2022"] = (token_program == TOKEN_2022_PROGRAM)
decoded_args["token_program"] = str(
token_program
)
decoded_args["is_token_2022"] = (
token_program == TOKEN_2022_PROGRAM
)
return decoded_args
@@ -529,14 +547,22 @@ async def main():
slippage = 0.3 # 30% slippage tolerance
print(f"Bonding curve address: {bonding_curve}")
print(f"Token Program: {token_program} ({'Token2022' if token_data['is_token_2022'] else 'Standard Token'})")
print(
f"Token Program: {token_program} ({'Token2022' if token_data['is_token_2022'] else 'Standard Token'})"
)
print(f"Token price: {token_price_sol:.10f} SOL")
print(
f"Buying {amount:.6f} SOL worth of the new token with {slippage * 100:.1f}% slippage tolerance..."
)
print("CU Optimization: Enabled (512KB account data limit)")
await buy_token(
mint, bonding_curve, associated_bonding_curve, creator_vault, token_program, amount, slippage
mint,
bonding_curve,
associated_bonding_curve,
creator_vault,
token_program,
amount,
slippage,
)
+26 -6
View File
@@ -172,6 +172,14 @@ def _find_fee_config() -> Pubkey:
return derived_address
def _find_bonding_curve_v2(mint: Pubkey) -> Pubkey:
derived_address, _ = Pubkey.find_program_address(
[b"bonding-curve-v2", bytes(mint)],
PUMP_PROGRAM,
)
return derived_address
async def get_fee_recipient(
client: AsyncClient, curve_state: BondingCurveState
) -> Pubkey:
@@ -328,7 +336,7 @@ async def listen_for_create_transaction_geyser():
# Add token program info to decoded args
token_data["token_program"] = str(token_program)
token_data["is_token_2022"] = (token_program == SYSTEM_TOKEN_2022_PROGRAM)
token_data["is_token_2022"] = token_program == SYSTEM_TOKEN_2022_PROGRAM
signature = base58.b58encode(
bytes(update.transaction.transaction.signature)
@@ -391,9 +399,7 @@ async def buy_token(
),
AccountMeta(pubkey=payer.pubkey(), is_signer=True, is_writable=True),
AccountMeta(pubkey=SYSTEM_PROGRAM, is_signer=False, is_writable=False),
AccountMeta(
pubkey=token_program, is_signer=False, is_writable=False
),
AccountMeta(pubkey=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
@@ -421,6 +427,12 @@ async def buy_token(
is_signer=False,
is_writable=False,
),
# Remaining account: bonding_curve_v2 (readonly, required for all coins)
AccountMeta(
pubkey=_find_bonding_curve_v2(mint),
is_signer=False,
is_writable=False,
),
]
discriminator = struct.pack("<Q", 16927863322537952870)
@@ -508,13 +520,21 @@ async def main():
slippage = 0.3 # 30% slippage tolerance
print(f"Bonding curve address: {bonding_curve}")
print(f"Token Program: {token_program} ({'Token2022' if token_data['is_token_2022'] else 'Standard Token'})")
print(
f"Token Program: {token_program} ({'Token2022' if token_data['is_token_2022'] else 'Standard Token'})"
)
# print(f"Token price: {token_price_sol:.10f} SOL")
print(
f"Buying {amount:.6f} SOL worth of the new token with {slippage * 100:.1f}% slippage tolerance..."
)
await buy_token(
mint, bonding_curve, associated_bonding_curve, creator_vault, token_program, amount, slippage
mint,
bonding_curve,
associated_bonding_curve,
creator_vault,
token_program,
amount,
slippage,
)
+14
View File
@@ -147,6 +147,14 @@ def _find_fee_config() -> Pubkey:
return derived_address
def _find_bonding_curve_v2(mint: Pubkey) -> Pubkey:
derived_address, _ = Pubkey.find_program_address(
[b"bonding-curve-v2", bytes(mint)],
PUMP_PROGRAM,
)
return derived_address
async def get_fee_recipient(
client: AsyncClient, curve_state: BondingCurveState
) -> Pubkey:
@@ -312,6 +320,12 @@ async def sell_token(
is_signer=False,
is_writable=False,
),
# Remaining account: bonding_curve_v2 (readonly, required for all coins)
AccountMeta(
pubkey=_find_bonding_curve_v2(mint),
is_signer=False,
is_writable=False,
),
]
discriminator = struct.pack("<Q", 12502976635542562355)
+14
View File
@@ -143,6 +143,14 @@ def _find_fee_config() -> Pubkey:
return derived_address
def _find_bonding_curve_v2(mint: Pubkey) -> Pubkey:
derived_address, _ = Pubkey.find_program_address(
[b"bonding-curve-v2", bytes(mint)],
PUMP_PROGRAM,
)
return derived_address
def create_pump_create_instruction(
mint: Pubkey,
mint_authority: Pubkey,
@@ -263,6 +271,12 @@ def create_buy_instruction(
is_signer=False,
is_writable=False,
),
# Remaining account: bonding_curve_v2 (readonly, required for all coins)
AccountMeta(
pubkey=_find_bonding_curve_v2(mint),
is_signer=False,
is_writable=False,
),
]
# Encode OptionBool for track_volume
+14
View File
@@ -159,6 +159,14 @@ def _find_fee_config() -> Pubkey:
return derived_address
def _find_bonding_curve_v2(mint: Pubkey) -> Pubkey:
derived_address, _ = Pubkey.find_program_address(
[b"bonding-curve-v2", bytes(mint)],
PUMP_PROGRAM,
)
return derived_address
def create_pump_create_v2_instruction(
mint: Pubkey,
mint_authority: Pubkey,
@@ -307,6 +315,12 @@ def create_buy_instruction(
is_signer=False,
is_writable=False,
),
# Remaining account: bonding_curve_v2 (readonly, required for all coins)
AccountMeta(
pubkey=_find_bonding_curve_v2(mint),
is_signer=False,
is_writable=False,
),
]
# Encode OptionBool for track_volume