@0block.io/sdk 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/fetch.d.ts CHANGED
@@ -19,19 +19,32 @@ export declare function resolveTokenProgram(fetcher: AccountFetcher, mint: Addre
19
19
  export declare function fetchPumpfunGlobalFeeRecipient(fetcher: AccountFetcher, globalAccount: web3.PublicKey): Promise<web3.PublicKey>;
20
20
  /** Non-zero entries of Global.buyback_fee_recipients ([Pubkey; 8]). */
21
21
  export declare function fetchPumpfunBuybackFeeRecipients(fetcher: AccountFetcher, globalAccount: web3.PublicKey): Promise<web3.PublicKey[]>;
22
+ export interface PumpfunBondingCurveInfo {
23
+ /**
24
+ * BondingCurve.creator. For a legacy (never-extended) curve this is
25
+ * `PublicKey.default` — exactly what `extend_account` zero-fills, and the
26
+ * program derives `creator_vault` from `bonding_curve.creator` at execution
27
+ * time, so the default-creator vault is the correct one to pass.
28
+ */
29
+ creator: web3.PublicKey;
30
+ /**
31
+ * True when the curve is the 49-byte pre-creator legacy layout: pump.fun's
32
+ * `extend_account` (its own migration path; permissionless, no rent payer —
33
+ * curves fund their own rent from the SOL reserves they hold) must run
34
+ * before a modern swap can deserialize the account. The transaction builder
35
+ * prepends it when `PumpfunMarketContext.curveNeedsExtension` is set.
36
+ */
37
+ needsExtension: boolean;
38
+ }
22
39
  /**
23
- * BondingCurve.creator (offset: discriminator + 5×u64 + bool), with tradeability
24
- * preflight. Throws a PRECISE error instead of letting an untradeable market
25
- * fail on-chain (where the user would still pay the tx fee + tip):
26
- *
27
- * - `complete == true` → the token GRADUATED off the bonding curve (liquidity
28
- * moved to an AMM — PumpSwap/Raydium); the pump.fun program rejects both
29
- * buys and sells on a complete curve.
30
- * - 49-byte legacy layout (pre-creator-fee, curve untouched since the mid-2025
31
- * pump.fun upgrade) → needs the program's extend_account before any modern
32
- * swap can even deserialize it. In practice these are dead tokens: anything
33
- * actively traded has long been extended.
40
+ * Tradeability preflight + creator, from ONE bonding-curve read. Throws a
41
+ * PRECISE error instead of letting an untradeable market fail on-chain (where
42
+ * the user would still pay the tx fee + tip): `complete == true` means the
43
+ * token GRADUATED off the bonding curve (liquidity moved to an AMM —
44
+ * PumpSwap/Raydium) and the pump.fun program rejects both buys and sells.
34
45
  */
46
+ export declare function fetchPumpfunBondingCurveInfo(fetcher: AccountFetcher, bondingCurve: web3.PublicKey): Promise<PumpfunBondingCurveInfo>;
47
+ /** BondingCurve.creator (see fetchPumpfunBondingCurveInfo for the preflight). */
35
48
  export declare function fetchPumpfunBondingCurveCreator(fetcher: AccountFetcher, bondingCurve: web3.PublicKey): Promise<web3.PublicKey>;
36
49
  /**
37
50
  * Resolve everything a pump.fun swap needs for one mint. Run this server-side
package/dist/fetch.js CHANGED
@@ -56,19 +56,13 @@ export async function fetchPumpfunBuybackFeeRecipients(fetcher, globalAccount) {
56
56
  return recipients;
57
57
  }
58
58
  /**
59
- * BondingCurve.creator (offset: discriminator + 5×u64 + bool), with tradeability
60
- * preflight. Throws a PRECISE error instead of letting an untradeable market
61
- * fail on-chain (where the user would still pay the tx fee + tip):
62
- *
63
- * - `complete == true` → the token GRADUATED off the bonding curve (liquidity
64
- * moved to an AMM — PumpSwap/Raydium); the pump.fun program rejects both
65
- * buys and sells on a complete curve.
66
- * - 49-byte legacy layout (pre-creator-fee, curve untouched since the mid-2025
67
- * pump.fun upgrade) → needs the program's extend_account before any modern
68
- * swap can even deserialize it. In practice these are dead tokens: anything
69
- * actively traded has long been extended.
59
+ * Tradeability preflight + creator, from ONE bonding-curve read. Throws a
60
+ * PRECISE error instead of letting an untradeable market fail on-chain (where
61
+ * the user would still pay the tx fee + tip): `complete == true` means the
62
+ * token GRADUATED off the bonding curve (liquidity moved to an AMM —
63
+ * PumpSwap/Raydium) and the pump.fun program rejects both buys and sells.
70
64
  */
71
- export async function fetchPumpfunBondingCurveCreator(fetcher, bondingCurve) {
65
+ export async function fetchPumpfunBondingCurveInfo(fetcher, bondingCurve) {
72
66
  const info = await fetcher.getAccountInfo(bondingCurve);
73
67
  if (!info) {
74
68
  throw new Error(`pump.fun bonding curve not found: ${bondingCurve.toBase58()}`);
@@ -83,10 +77,16 @@ export async function fetchPumpfunBondingCurveCreator(fetcher, bondingCurve) {
83
77
  "(PumpSwap/Raydium); it cannot be traded on the bonding curve");
84
78
  }
85
79
  if (info.data.length < legacyLen + 32) {
86
- throw new Error("legacy pump.fun bonding curve (pre-creator layout, never extended) — " +
87
- "the account needs pump.fun extend_account before modern swaps can run");
80
+ return { creator: web3.PublicKey.default, needsExtension: true };
88
81
  }
89
- return new web3.PublicKey(info.data.slice(legacyLen, legacyLen + 32));
82
+ return {
83
+ creator: new web3.PublicKey(info.data.slice(legacyLen, legacyLen + 32)),
84
+ needsExtension: false,
85
+ };
86
+ }
87
+ /** BondingCurve.creator (see fetchPumpfunBondingCurveInfo for the preflight). */
88
+ export async function fetchPumpfunBondingCurveCreator(fetcher, bondingCurve) {
89
+ return (await fetchPumpfunBondingCurveInfo(fetcher, bondingCurve)).creator;
90
90
  }
91
91
  /**
92
92
  * Resolve everything a pump.fun swap needs for one mint. Run this server-side
@@ -100,11 +100,11 @@ export async function resolvePumpfunMarketContext(fetcher, params) {
100
100
  const feeProgram = toPk(params.pumpfunFeeProgram ?? PUMPFUN_FEE_PROGRAM_ID);
101
101
  const global = derivePumpfunGlobal(pumpProgram);
102
102
  const bondingCurve = derivePumpfunBondingCurve(pumpProgram, mint);
103
- const [mintTokenProgram, feeRecipient, buybackRecipients, creator] = await Promise.all([
103
+ const [mintTokenProgram, feeRecipient, buybackRecipients, curveInfo] = await Promise.all([
104
104
  resolveTokenProgram(fetcher, mint),
105
105
  fetchPumpfunGlobalFeeRecipient(fetcher, global),
106
106
  fetchPumpfunBuybackFeeRecipients(fetcher, global),
107
- fetchPumpfunBondingCurveCreator(fetcher, bondingCurve),
107
+ fetchPumpfunBondingCurveInfo(fetcher, bondingCurve),
108
108
  ]);
109
109
  return {
110
110
  mint: mint.toBase58(),
@@ -115,11 +115,12 @@ export async function resolvePumpfunMarketContext(fetcher, params) {
115
115
  bondingCurve: bondingCurve.toBase58(),
116
116
  associatedBondingCurve: deriveAta(bondingCurve, mint, mintTokenProgram).toBase58(),
117
117
  bondingCurveV2: derivePumpfunBondingCurveV2(pumpProgram, mint).toBase58(),
118
- creatorVault: derivePumpfunCreatorVault(pumpProgram, creator).toBase58(),
118
+ creatorVault: derivePumpfunCreatorVault(pumpProgram, curveInfo.creator).toBase58(),
119
119
  feeRecipient: feeRecipient.toBase58(),
120
120
  buybackFeeRecipients: buybackRecipients.map((r) => r.toBase58()),
121
121
  eventAuthority: derivePumpfunEventAuthority(pumpProgram).toBase58(),
122
122
  globalVolumeAccumulator: derivePumpfunGlobalVolumeAccumulator(pumpProgram).toBase58(),
123
123
  feeConfig: derivePumpfunFeeConfig(feeProgram, pumpProgram).toBase58(),
124
+ curveNeedsExtension: curveInfo.needsExtension,
124
125
  };
125
126
  }
package/dist/index.d.ts CHANGED
@@ -5,8 +5,8 @@ export { buildSendTransactionRequest, createLandingClient, withLandingTip, type
5
5
  export { fetchRecentBlockhash, type FetchBlockhashOptions, type RecentBlockhash, } from "./blockhash.js";
6
6
  export { zeroblockFetcher, fetchTokenBalanceViaZeroblock, fetchLookupTableViaZeroblock, type ZeroblockReadOptions, type ZeroblockTokenBalance, } from "./zeroblock.js";
7
7
  export { toPk, deriveAta, deriveOrderMarker, deriveWrapperConfig, deriveRouterGlobalConfig, deriveRouterTenantConfig, derivePumpfunGlobal, derivePumpfunBondingCurve, derivePumpfunBondingCurveV2, derivePumpfunEventAuthority, derivePumpfunCreatorVault, derivePumpfunGlobalVolumeAccumulator, derivePumpfunUserVolumeAccumulator, derivePumpfunFeeConfig, } from "./pda.js";
8
- export { type AccountFetcher, connectionFetcher, resolveTokenProgram, resolvePumpfunMarketContext, fetchPumpfunGlobalFeeRecipient, fetchPumpfunBondingCurveCreator, fetchPumpfunBuybackFeeRecipients, } from "./fetch.js";
9
- export { buildPumpfunRemainingAccounts, type PumpfunRemainingAccountsParams, } from "./venues/pumpfun.js";
8
+ export { type AccountFetcher, connectionFetcher, resolveTokenProgram, resolvePumpfunMarketContext, fetchPumpfunGlobalFeeRecipient, fetchPumpfunBondingCurveCreator, fetchPumpfunBondingCurveInfo, type PumpfunBondingCurveInfo, fetchPumpfunBuybackFeeRecipients, } from "./fetch.js";
9
+ export { buildPumpfunRemainingAccounts, buildPumpfunExtendAccountInstruction, type PumpfunRemainingAccountsParams, } from "./venues/pumpfun.js";
10
10
  export { buildPumpfunSwapInstruction, decodeSwapData, randomOrderId, resolveFeeMint, type SwapInstructionResult, } from "./swap.js";
11
11
  export { buildTipInstruction, maskTipAccountInTables } from "./tip.js";
12
12
  export { buildComputeBudgetInstructions } from "./computeBudget.js";
package/dist/index.js CHANGED
@@ -18,8 +18,8 @@ export { buildSendTransactionRequest, createLandingClient, withLandingTip, } fro
18
18
  export { fetchRecentBlockhash, } from "./blockhash.js";
19
19
  export { zeroblockFetcher, fetchTokenBalanceViaZeroblock, fetchLookupTableViaZeroblock, } from "./zeroblock.js";
20
20
  export { toPk, deriveAta, deriveOrderMarker, deriveWrapperConfig, deriveRouterGlobalConfig, deriveRouterTenantConfig, derivePumpfunGlobal, derivePumpfunBondingCurve, derivePumpfunBondingCurveV2, derivePumpfunEventAuthority, derivePumpfunCreatorVault, derivePumpfunGlobalVolumeAccumulator, derivePumpfunUserVolumeAccumulator, derivePumpfunFeeConfig, } from "./pda.js";
21
- export { connectionFetcher, resolveTokenProgram, resolvePumpfunMarketContext, fetchPumpfunGlobalFeeRecipient, fetchPumpfunBondingCurveCreator, fetchPumpfunBuybackFeeRecipients, } from "./fetch.js";
22
- export { buildPumpfunRemainingAccounts, } from "./venues/pumpfun.js";
21
+ export { connectionFetcher, resolveTokenProgram, resolvePumpfunMarketContext, fetchPumpfunGlobalFeeRecipient, fetchPumpfunBondingCurveCreator, fetchPumpfunBondingCurveInfo, fetchPumpfunBuybackFeeRecipients, } from "./fetch.js";
22
+ export { buildPumpfunRemainingAccounts, buildPumpfunExtendAccountInstruction, } from "./venues/pumpfun.js";
23
23
  export { buildPumpfunSwapInstruction, decodeSwapData, randomOrderId, resolveFeeMint, } from "./swap.js";
24
24
  export { buildTipInstruction, maskTipAccountInTables } from "./tip.js";
25
25
  export { buildComputeBudgetInstructions } from "./computeBudget.js";
@@ -4,6 +4,7 @@ import { toPk } from "./pda.js";
4
4
  import { buildComputeBudgetInstructions } from "./computeBudget.js";
5
5
  import { buildPumpfunSwapInstruction } from "./swap.js";
6
6
  import { buildTipInstruction, maskTipAccountInTables } from "./tip.js";
7
+ import { buildPumpfunExtendAccountInstruction } from "./venues/pumpfun.js";
7
8
  import { closeAccountInstruction, createAtaIdempotentInstruction, unwrapWsolInstruction, wrapSolInstructions, } from "./wsol.js";
8
9
  /** Rehydrate a streamed lookup table into web3.js form (compile-time only fields defaulted). */
9
10
  export function toLookupTableAccount(data) {
@@ -45,6 +46,18 @@ export function buildPumpfunSwapTransaction(params) {
45
46
  if (params.computeBudget) {
46
47
  instructions.push(...buildComputeBudgetInstructions(params.computeBudget));
47
48
  }
49
+ // LEGACY CURVE (49-byte pre-creator layout): run pump.fun's own migration —
50
+ // extend_account — before the swap so the program can deserialize the curve.
51
+ // Zero-fills the new fields, so the resolver's default-creator vault in
52
+ // market.creatorVault matches what the program derives at execution time.
53
+ if (params.market.curveNeedsExtension) {
54
+ instructions.push(buildPumpfunExtendAccountInstruction({
55
+ pumpfunProgram: toPk(params.market.pumpfunProgram),
56
+ account: toPk(params.market.bondingCurve),
57
+ user,
58
+ eventAuthority: toPk(params.market.eventAuthority),
59
+ }));
60
+ }
48
61
  // TENANT MODE: the wrapper program manages the entire native-SOL lifecycle
49
62
  // on-chain (ATA creation, wrap sized with exact on-chain fee headroom,
50
63
  // post-swap sweep, proceeds unwrap, emptied-ATA cleanup) — the client adds
package/dist/types.d.ts CHANGED
@@ -27,6 +27,15 @@ export interface PumpfunMarketContext {
27
27
  eventAuthority: string;
28
28
  globalVolumeAccumulator: string;
29
29
  feeConfig: string;
30
+ /**
31
+ * True when the bonding curve is the 49-byte pre-creator legacy layout
32
+ * (untouched since pump.fun's creator upgrade). The transaction builder then
33
+ * prepends pump.fun's `extend_account` instruction — the program's own
34
+ * migration path — so the swap can deserialize the account. The zero-filled
35
+ * creator makes `creatorVault` the default-creator vault (already baked in
36
+ * by the resolver).
37
+ */
38
+ curveNeedsExtension?: boolean;
30
39
  }
31
40
  /** Serializable address-lookup-table contents, streamable over a WS. */
32
41
  export interface LookupTableData {
@@ -30,3 +30,23 @@ export interface PumpfunRemainingAccountsParams {
30
30
  * program id is always index 0 and is hard-checked on-chain.
31
31
  */
32
32
  export declare function buildPumpfunRemainingAccounts(side: SwapSide, p: PumpfunRemainingAccountsParams): web3.AccountMeta[];
33
+ /**
34
+ * pump.fun `extend_account` — the program's own migration path for accounts
35
+ * predating a layout upgrade (e.g. 49-byte pre-creator bonding curves, which
36
+ * modern swaps cannot even deserialize). Permissionless; `user` only signs
37
+ * (no rent payer — a bonding curve funds its own rent from the SOL reserves
38
+ * it holds as lamports). Realloc zero-fills the new fields, so post-extension
39
+ * `creator == PublicKey.default` and the swap's creator_vault must be the
40
+ * default-creator vault (the market resolver bakes that in).
41
+ *
42
+ * Discriminator and account list verified against the on-chain anchor IDL of
43
+ * 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P.
44
+ */
45
+ export declare function buildPumpfunExtendAccountInstruction(params: {
46
+ pumpfunProgram: web3.PublicKey;
47
+ /** The program-owned account to extend (the bonding curve). */
48
+ account: web3.PublicKey;
49
+ /** The transaction's user/payer (signer). */
50
+ user: web3.PublicKey;
51
+ eventAuthority: web3.PublicKey;
52
+ }): web3.TransactionInstruction;
@@ -1,3 +1,4 @@
1
+ import * as web3 from "@solana/web3.js";
1
2
  /**
2
3
  * Remaining accounts for one pump.fun leg, in the exact order the router's
3
4
  * adapter parses them (PumpfunBuyAccounts / PumpfunSellAccounts). The dex
@@ -54,3 +55,29 @@ export function buildPumpfunRemainingAccounts(side, p) {
54
55
  }
55
56
  throw new Error(`Unsupported pump.fun side: ${side}`);
56
57
  }
58
+ /**
59
+ * pump.fun `extend_account` — the program's own migration path for accounts
60
+ * predating a layout upgrade (e.g. 49-byte pre-creator bonding curves, which
61
+ * modern swaps cannot even deserialize). Permissionless; `user` only signs
62
+ * (no rent payer — a bonding curve funds its own rent from the SOL reserves
63
+ * it holds as lamports). Realloc zero-fills the new fields, so post-extension
64
+ * `creator == PublicKey.default` and the swap's creator_vault must be the
65
+ * default-creator vault (the market resolver bakes that in).
66
+ *
67
+ * Discriminator and account list verified against the on-chain anchor IDL of
68
+ * 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P.
69
+ */
70
+ export function buildPumpfunExtendAccountInstruction(params) {
71
+ return new web3.TransactionInstruction({
72
+ programId: params.pumpfunProgram,
73
+ keys: [
74
+ { pubkey: params.account, isSigner: false, isWritable: true },
75
+ { pubkey: params.user, isSigner: true, isWritable: false },
76
+ { pubkey: web3.SystemProgram.programId, isSigner: false, isWritable: false },
77
+ { pubkey: params.eventAuthority, isSigner: false, isWritable: false },
78
+ { pubkey: params.pumpfunProgram, isSigner: false, isWritable: false },
79
+ ],
80
+ // sha256("global:extend_account")[0..8] — from the on-chain IDL.
81
+ data: Buffer.from([234, 102, 194, 203, 150, 72, 62, 229]),
82
+ });
83
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0block.io/sdk",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Client-side transaction builder for the 0Block DEX router. Builds unsigned v0 swap transactions entirely offline \u2014 tenant-wrapped or direct \u2014 with shared address lookup tables, gateway tips, and on-chain fee-event decoding for accounting.",
5
5
  "keywords": [
6
6
  "solana",