@0block.io/sdk 0.5.0 → 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,7 +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
- /** BondingCurve.creator (offset: discriminator + 5×u64 + bool). */
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
+ }
39
+ /**
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.
45
+ */
46
+ export declare function fetchPumpfunBondingCurveInfo(fetcher: AccountFetcher, bondingCurve: web3.PublicKey): Promise<PumpfunBondingCurveInfo>;
47
+ /** BondingCurve.creator (see fetchPumpfunBondingCurveInfo for the preflight). */
23
48
  export declare function fetchPumpfunBondingCurveCreator(fetcher: AccountFetcher, bondingCurve: web3.PublicKey): Promise<web3.PublicKey>;
24
49
  /**
25
50
  * Resolve everything a pump.fun swap needs for one mint. Run this server-side
package/dist/fetch.js CHANGED
@@ -55,17 +55,38 @@ export async function fetchPumpfunBuybackFeeRecipients(fetcher, globalAccount) {
55
55
  }
56
56
  return recipients;
57
57
  }
58
- /** BondingCurve.creator (offset: discriminator + 5×u64 + bool). */
59
- export async function fetchPumpfunBondingCurveCreator(fetcher, bondingCurve) {
58
+ /**
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.
64
+ */
65
+ export async function fetchPumpfunBondingCurveInfo(fetcher, bondingCurve) {
60
66
  const info = await fetcher.getAccountInfo(bondingCurve);
61
67
  if (!info) {
62
68
  throw new Error(`pump.fun bonding curve not found: ${bondingCurve.toBase58()}`);
63
69
  }
64
- const offset = 8 + 5 * 8 + 1;
65
- if (info.data.length < offset + 32) {
70
+ const legacyLen = 8 + 5 * 8 + 1; // ..= complete flag (pre-creator layout)
71
+ if (info.data.length < legacyLen) {
66
72
  throw new Error("pump.fun bonding curve data too short");
67
73
  }
68
- return new web3.PublicKey(info.data.slice(offset, offset + 32));
74
+ const complete = info.data[legacyLen - 1] === 1;
75
+ if (complete) {
76
+ throw new Error("pump.fun bonding curve is complete — the token graduated to an AMM " +
77
+ "(PumpSwap/Raydium); it cannot be traded on the bonding curve");
78
+ }
79
+ if (info.data.length < legacyLen + 32) {
80
+ return { creator: web3.PublicKey.default, needsExtension: true };
81
+ }
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;
69
90
  }
70
91
  /**
71
92
  * Resolve everything a pump.fun swap needs for one mint. Run this server-side
@@ -79,11 +100,11 @@ export async function resolvePumpfunMarketContext(fetcher, params) {
79
100
  const feeProgram = toPk(params.pumpfunFeeProgram ?? PUMPFUN_FEE_PROGRAM_ID);
80
101
  const global = derivePumpfunGlobal(pumpProgram);
81
102
  const bondingCurve = derivePumpfunBondingCurve(pumpProgram, mint);
82
- const [mintTokenProgram, feeRecipient, buybackRecipients, creator] = await Promise.all([
103
+ const [mintTokenProgram, feeRecipient, buybackRecipients, curveInfo] = await Promise.all([
83
104
  resolveTokenProgram(fetcher, mint),
84
105
  fetchPumpfunGlobalFeeRecipient(fetcher, global),
85
106
  fetchPumpfunBuybackFeeRecipients(fetcher, global),
86
- fetchPumpfunBondingCurveCreator(fetcher, bondingCurve),
107
+ fetchPumpfunBondingCurveInfo(fetcher, bondingCurve),
87
108
  ]);
88
109
  return {
89
110
  mint: mint.toBase58(),
@@ -94,11 +115,12 @@ export async function resolvePumpfunMarketContext(fetcher, params) {
94
115
  bondingCurve: bondingCurve.toBase58(),
95
116
  associatedBondingCurve: deriveAta(bondingCurve, mint, mintTokenProgram).toBase58(),
96
117
  bondingCurveV2: derivePumpfunBondingCurveV2(pumpProgram, mint).toBase58(),
97
- creatorVault: derivePumpfunCreatorVault(pumpProgram, creator).toBase58(),
118
+ creatorVault: derivePumpfunCreatorVault(pumpProgram, curveInfo.creator).toBase58(),
98
119
  feeRecipient: feeRecipient.toBase58(),
99
120
  buybackFeeRecipients: buybackRecipients.map((r) => r.toBase58()),
100
121
  eventAuthority: derivePumpfunEventAuthority(pumpProgram).toBase58(),
101
122
  globalVolumeAccumulator: derivePumpfunGlobalVolumeAccumulator(pumpProgram).toBase58(),
102
123
  feeConfig: derivePumpfunFeeConfig(feeProgram, pumpProgram).toBase58(),
124
+ curveNeedsExtension: curveInfo.needsExtension,
103
125
  };
104
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.0",
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",