sol-parser-sdk 0.5.13 → 0.5.15

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.
@@ -55,10 +55,10 @@ const types_js_1 = require("./types.js");
55
55
  function cancelSubscribeStream(stream) {
56
56
  if (!stream)
57
57
  return;
58
- // grpc-js emits CANCELLED through `error`; guard the short setup window before
58
+ // Stream destruction can emit an error during the short setup window before
59
59
  // the normal lifecycle listeners have been installed.
60
60
  stream.once("error", () => { });
61
- stream.cancel();
61
+ stream.destroy();
62
62
  }
63
63
  function positiveIntegerOption(value, fallback, name) {
64
64
  const normalized = value ?? fallback;
@@ -101,6 +101,7 @@ class YellowstoneGrpc {
101
101
  client;
102
102
  config;
103
103
  connected = false;
104
+ connectPromise;
104
105
  subscribers = new Map();
105
106
  dexSubscribers = new Map();
106
107
  constructor(endpoint, xToken, config = (0, types_js_1.defaultClientConfig)()) {
@@ -117,10 +118,20 @@ class YellowstoneGrpc {
117
118
  }
118
119
  /** 连接到 gRPC 服务器 */
119
120
  async connect() {
120
- if (this.connected) {
121
+ if (this.connected)
121
122
  return;
123
+ if (!this.connectPromise) {
124
+ this.connectPromise = this.client.connect().then(() => {
125
+ this.connected = true;
126
+ });
127
+ }
128
+ try {
129
+ await this.connectPromise;
130
+ }
131
+ catch (error) {
132
+ this.connectPromise = undefined;
133
+ throw error;
122
134
  }
123
- this.connected = true;
124
135
  }
125
136
  /** 断开连接 */
126
137
  async disconnect() {
@@ -133,6 +144,7 @@ class YellowstoneGrpc {
133
144
  }
134
145
  this.dexSubscribers.clear();
135
146
  this.connected = false;
147
+ this.connectPromise = undefined;
136
148
  }
137
149
  /** 检查是否已连接 */
138
150
  isConnected() {
@@ -283,6 +295,10 @@ class YellowstoneGrpc {
283
295
  return Number.NaN;
284
296
  }
285
297
  static timestampToMicros(value) {
298
+ if (value instanceof Date) {
299
+ const milliseconds = value.getTime();
300
+ return Number.isFinite(milliseconds) ? Math.trunc(milliseconds * 1_000) : undefined;
301
+ }
286
302
  if (!value || typeof value !== "object")
287
303
  return undefined;
288
304
  const ts = value;
@@ -351,6 +367,7 @@ class YellowstoneGrpc {
351
367
  }
352
368
  /** 订阅交易 */
353
369
  async subscribeTransactions(filter, callbacks) {
370
+ await this.connect();
354
371
  const id = `sub_${Date.now()}_${Math.random().toString(36).slice(2)}`;
355
372
  let isCancelled = false;
356
373
  const streamHolder = { current: null };
@@ -516,7 +533,7 @@ class YellowstoneGrpc {
516
533
  for (const resolve of ingressIdleWaiters.splice(0))
517
534
  resolve();
518
535
  };
519
- const annotateLocalMetrics = (events, grpcRecvNs, parseStartedNs, parseFinishedNs) => {
536
+ const annotateLocalMetrics = (events, grpcRecvNs, parseStartedNs, parseFinishedNs, sourceToGrpcLatencyUs) => {
520
537
  if (grpcRecvNs === undefined || parseStartedNs === undefined || parseFinishedNs === undefined) {
521
538
  return;
522
539
  }
@@ -530,6 +547,9 @@ class YellowstoneGrpc {
530
547
  metadata.local_queue_latency_us = queueUs;
531
548
  metadata.parse_duration_us = parseUs;
532
549
  metadata.local_processing_latency_us = processingUs;
550
+ if (sourceToGrpcLatencyUs !== undefined) {
551
+ metadata.source_to_grpc_latency_us = sourceToGrpcLatencyUs;
552
+ }
533
553
  }
534
554
  };
535
555
  const rememberParsedUpdate = (identity, slot) => {
@@ -555,7 +575,7 @@ class YellowstoneGrpc {
555
575
  seenHead = 0;
556
576
  }
557
577
  };
558
- const processUpdate = ({ update, grpcRecvUs, grpcRecvNs, blockTimeUs }) => {
578
+ const processUpdate = ({ update, grpcRecvUs, grpcRecvNs, blockTimeUs, sourceToGrpcLatencyUs, }) => {
559
579
  const identity = updateIdentity(update);
560
580
  const slotForReplay = updateSlot(update);
561
581
  if (replayOnReconnect && identity !== undefined && seenUpdates.has(identity)) {
@@ -585,15 +605,16 @@ class YellowstoneGrpc {
585
605
  eventTypeFilter,
586
606
  });
587
607
  const parseFinishedNs = grpcRecvNs === undefined ? undefined : process.hrtime.bigint();
588
- annotateLocalMetrics(txEvents, grpcRecvNs, parseStartedNs, parseFinishedNs);
608
+ annotateLocalMetrics(txEvents, grpcRecvNs, parseStartedNs, parseFinishedNs, sourceToGrpcLatencyUs);
589
609
  order.pushTransactionEvents(txEvents, fallbackSlot, fallbackTxIndex, emitEvent);
590
610
  }
591
611
  if (update.account) {
592
612
  const parseStartedNs = grpcRecvNs === undefined ? undefined : process.hrtime.bigint();
593
613
  const ev = this.parseAccountEventRaw(update.account, grpcRecvUs, eventTypeFilter, blockTimeUs);
594
614
  const parseFinishedNs = grpcRecvNs === undefined ? undefined : process.hrtime.bigint();
595
- if (ev)
596
- annotateLocalMetrics([ev], grpcRecvNs, parseStartedNs, parseFinishedNs);
615
+ if (ev) {
616
+ annotateLocalMetrics([ev], grpcRecvNs, parseStartedNs, parseFinishedNs, sourceToGrpcLatencyUs);
617
+ }
597
618
  if (ev)
598
619
  emitEvent(ev);
599
620
  }
@@ -746,11 +767,13 @@ class YellowstoneGrpc {
746
767
  });
747
768
  return;
748
769
  }
770
+ const createdAtUs = YellowstoneGrpc.timestampToMicros(update.createdAt ?? update.created_at);
749
771
  const accepted = ingress.push({
750
772
  update,
751
773
  grpcRecvUs,
752
774
  grpcRecvNs,
753
- blockTimeUs: YellowstoneGrpc.timestampToMicros(update.createdAt ?? update.created_at),
775
+ blockTimeUs: createdAtUs,
776
+ sourceToGrpcLatencyUs: createdAtUs === undefined ? undefined : Math.max(0, grpcRecvUs - createdAtUs),
754
777
  });
755
778
  if (!accepted) {
756
779
  const now = Date.now();
@@ -878,6 +901,7 @@ class YellowstoneGrpc {
878
901
  }
879
902
  /** 获取最新区块哈希 */
880
903
  async getLatestBlockhash(commitment) {
904
+ await this.connect();
881
905
  const resp = await this.client.getLatestBlockhash(commitment);
882
906
  return {
883
907
  slot: Number(resp.slot),
@@ -887,21 +911,25 @@ class YellowstoneGrpc {
887
911
  }
888
912
  /** 获取区块高度 */
889
913
  async getBlockHeight(commitment) {
914
+ await this.connect();
890
915
  const resp = await this.client.getBlockHeight(commitment);
891
- return Number(resp);
916
+ return Number(resp.blockHeight);
892
917
  }
893
918
  /** 获取当前 Slot */
894
919
  async getSlot(commitment) {
920
+ await this.connect();
895
921
  const resp = await this.client.getSlot(commitment);
896
- return Number(resp);
922
+ return Number(resp.slot);
897
923
  }
898
924
  /** 获取服务器版本 */
899
925
  async getVersion() {
926
+ await this.connect();
900
927
  const resp = await this.client.getVersion();
901
- return String(resp);
928
+ return resp.version;
902
929
  }
903
930
  /** 验证区块哈希是否有效 */
904
931
  async isBlockhashValid(blockhash, commitment) {
932
+ await this.connect();
905
933
  const resp = await this.client.isBlockhashValid(blockhash, commitment);
906
934
  return {
907
935
  slot: Number(resp.slot),
@@ -4,8 +4,7 @@
4
4
  * `@triton-one/yellowstone-grpc` 的 `Client` 通过构造函数第三参传入 `ChannelOptions`;
5
5
  * `connectTimeoutMs` 无与 tonic 完全一一对应的项,仅作文档与默认值对齐(可配合环境网络调优)。
6
6
  */
7
- import type { ChannelOptions } from "@grpc/grpc-js";
8
- import Client from "@triton-one/yellowstone-grpc";
7
+ import Client, { type ChannelOptions } from "@triton-one/yellowstone-grpc";
9
8
  /** 与 Rust `GeyserConnectConfig` 字段对应(毫秒 / 字节) */
10
9
  export interface GeyserConnectConfig {
11
10
  /** 对应 Rust `connect_timeout`(毫秒) */
@@ -6,6 +6,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.defaultGeyserConnectConfig = defaultGeyserConnectConfig;
7
7
  exports.geyserGrpcChannelOptions = geyserGrpcChannelOptions;
8
8
  exports.connectYellowstoneGeyser = connectYellowstoneGeyser;
9
+ /**
10
+ * 与 Rust `sol-parser-sdk/src/grpc/geyser_connect.rs` 对齐:Yellowstone Geyser gRPC 连接选项。
11
+ *
12
+ * `@triton-one/yellowstone-grpc` 的 `Client` 通过构造函数第三参传入 `ChannelOptions`;
13
+ * `connectTimeoutMs` 无与 tonic 完全一一对应的项,仅作文档与默认值对齐(可配合环境网络调优)。
14
+ */
9
15
  const yellowstone_grpc_1 = __importDefault(require("@triton-one/yellowstone-grpc"));
10
16
  /** 公共字段与 Rust `GeyserConnectConfig::default` 一致,并包含 Node gRPC 通道默认值。 */
11
17
  function defaultGeyserConnectConfig() {
@@ -26,15 +32,17 @@ function geyserGrpcChannelOptions(config = defaultGeyserConnectConfig()) {
26
32
  const interval = config.keepAliveIntervalMs ?? 30_000;
27
33
  const timeout = config.keepAliveTimeoutMs ?? 5000;
28
34
  return {
29
- "grpc.max_receive_message_length": max,
30
- "grpc.max_send_message_length": max,
31
- "grpc.keepalive_time_ms": interval,
32
- "grpc.keepalive_timeout_ms": timeout,
33
- /** 无活跃 RPC 时仍发 keepalive,避免长时间仅订阅时被中间设备掐断 */
34
- "grpc.keepalive_permit_without_calls": 1,
35
- "grpc.initial_reconnect_backoff_ms": config.initialReconnectBackoffMs,
36
- "grpc.max_reconnect_backoff_ms": config.maxReconnectBackoffMs,
37
- "grpc-node.flow_control_window": config.flowControlWindowBytes,
35
+ grpcConnectTimeout: config.connectTimeoutMs,
36
+ grpcMaxDecodingMessageSize: max,
37
+ grpcMaxEncodingMessageSize: max,
38
+ grpcHttp2KeepAliveInterval: interval,
39
+ grpcKeepAliveTimeout: timeout,
40
+ grpcTcpKeepalive: interval,
41
+ grpcInitialConnectionWindowSize: config.flowControlWindowBytes,
42
+ grpcInitialStreamWindowSize: config.flowControlWindowBytes,
43
+ grpcHttp2AdaptiveWindow: true,
44
+ grpcKeepAliveWhileIdle: true,
45
+ grpcTcpNodelay: true,
38
46
  };
39
47
  }
40
48
  /**
@@ -42,5 +50,7 @@ function geyserGrpcChannelOptions(config = defaultGeyserConnectConfig()) {
42
50
  * Rust 为 async;此处构造同步完成,返回 `Promise` 以保持 `await connectYellowstoneGeyser(...)` 写法。
43
51
  */
44
52
  async function connectYellowstoneGeyser(endpoint, config = defaultGeyserConnectConfig()) {
45
- return new yellowstone_grpc_1.default(endpoint, config.xToken, geyserGrpcChannelOptions(config));
53
+ const client = new yellowstone_grpc_1.default(endpoint, config.xToken, geyserGrpcChannelOptions(config));
54
+ await client.connect();
55
+ return client;
46
56
  }
@@ -168,6 +168,8 @@ function mergePumpfunTrade(log, ix) {
168
168
  "quote_amount",
169
169
  "virtual_quote_reserves",
170
170
  "real_quote_reserves",
171
+ "holder_rewards_bps",
172
+ "holder_rewards",
171
173
  ]) {
172
174
  fillNonZero(log, key, ix);
173
175
  }
@@ -197,6 +199,7 @@ function mergePumpfunCreate(log, ix) {
197
199
  "real_token_reserves",
198
200
  "token_total_supply",
199
201
  "virtual_quote_reserves",
202
+ "creator_fee_bps",
200
203
  ]) {
201
204
  fillNonZero(log, key, ix);
202
205
  }
@@ -204,6 +207,7 @@ function mergePumpfunCreate(log, ix) {
204
207
  log.is_mayhem_mode = Boolean(log.is_mayhem_mode) || Boolean(ix.is_mayhem_mode);
205
208
  log.is_cashback_enabled =
206
209
  Boolean(log.is_cashback_enabled) || Boolean(ix.is_cashback_enabled);
210
+ log.is_holder_reward = Boolean(log.is_holder_reward) || Boolean(ix.is_holder_reward);
207
211
  }
208
212
  function mergePumpfunCreateV2(log, ix) {
209
213
  mergePumpfunCreate(log, ix);
@@ -224,6 +228,8 @@ function mergePumpfunCreateV2(log, ix) {
224
228
  ]) {
225
229
  fillString(log, key, ix);
226
230
  }
231
+ fillNonZero(log, "creator_fee_bps", ix);
232
+ log.is_holder_reward = Boolean(log.is_holder_reward) || Boolean(ix.is_holder_reward);
227
233
  }
228
234
  function mergePumpfunMigrate(log, ix) {
229
235
  for (const key of ["bonding_curve", "pool", "user"]) {
@@ -1,6 +1,8 @@
1
- import type { Transaction as YTransaction, TransactionStatusMeta } from "@triton-one/yellowstone-grpc/dist/grpc/solana-storage.js";
1
+ import type { SubscribeUpdateTransactionInfo } from "@triton-one/yellowstone-grpc";
2
2
  import { type VersionedTransactionResponse } from "@solana/web3.js";
3
3
  import type { ParseError } from "../core/error.js";
4
+ type YTransaction = NonNullable<SubscribeUpdateTransactionInfo["transaction"]>;
5
+ type TransactionStatusMeta = NonNullable<SubscribeUpdateTransactionInfo["meta"]>;
4
6
  export type ConvertRpcToGrpcOk = {
5
7
  ok: true;
6
8
  meta: TransactionStatusMeta;
@@ -16,3 +18,4 @@ export type ConvertRpcToGrpcErr = {
16
18
  export declare function convertRpcToGrpc(tx: VersionedTransactionResponse): ConvertRpcToGrpcOk | ConvertRpcToGrpcErr;
17
19
  /** Rust 蛇形命名 */
18
20
  export declare const convert_rpc_to_grpc: typeof convertRpcToGrpc;
21
+ export {};
@@ -1,4 +1,7 @@
1
- import type { TokenBalance, Transaction, TransactionStatusMeta } from "@triton-one/yellowstone-grpc/dist/grpc/solana-storage.js";
1
+ import type { SubscribeUpdateTransactionInfo } from "@triton-one/yellowstone-grpc";
2
+ type Transaction = NonNullable<SubscribeUpdateTransactionInfo["transaction"]>;
3
+ type TransactionStatusMeta = NonNullable<SubscribeUpdateTransactionInfo["meta"]>;
4
+ type TokenBalance = TransactionStatusMeta["preTokenBalances"][number];
2
5
  /** 32 字节公钥 → Base58(无效长度返回 `null`) */
3
6
  export declare function pubkeyBytesToBs58(bytes: Uint8Array): string | null;
4
7
  /**
@@ -27,3 +30,4 @@ export declare function splTokenCounterpartyByOwner(meta: TransactionStatusMeta,
27
30
  export declare function collectWatchTransferCounterpartyPairs(tx: Transaction, meta: TransactionStatusMeta, watchedBs58: string[], minNativeOutflowLamports: bigint, splMinWatchDecreaseRaw: bigint): [string, string][] | null;
28
31
  /** Yellowstone 交易签名原始字节(64)→ Base58 签名字符串;长度非 64 返回 `null` */
29
32
  export declare function tryYellowstoneSignature(sig: Uint8Array): string | null;
33
+ export {};
@@ -151,7 +151,7 @@ export declare function accountFilterFromProgramOwners(programIds: string[]): Ac
151
151
  */
152
152
  export declare function accountFilterMemcmp(offset: number, bytes: Uint8Array): SubscribeRequestFilterAccountsFilter;
153
153
  /** 事件类型过滤标签 */
154
- export type EventType = "BlockMeta" | "RaydiumLaunchlabTrade" | "RaydiumLaunchlabPoolCreate" | "RaydiumLaunchlabMigrateAmm" | "PumpFunTrade" | "PumpFunBuy" | "PumpFunSell" | "PumpFunBuyExactSolIn" | "PumpFunCreate" | "PumpFunCreateV2" | "PumpFunComplete" | "PumpFunMigrate" | "PumpFeesCreateFeeSharingConfig" | "PumpFeesInitializeFeeConfig" | "PumpFeesResetFeeSharingConfig" | "PumpFeesRevokeFeeSharingAuthority" | "PumpFeesTransferFeeSharingAuthority" | "PumpFeesUpdateAdmin" | "PumpFeesUpdateFeeConfig" | "PumpFeesUpdateFeeShares" | "PumpFeesUpsertFeeTiers" | "PumpFunMigrateBondingCurveCreator" | "PumpSwapTrade" | "PumpSwapBuy" | "PumpSwapSell" | "PumpSwapCreatePool" | "PumpSwapLiquidityAdded" | "PumpSwapLiquidityRemoved" | "RaydiumCpmmSwap" | "RaydiumCpmmDeposit" | "RaydiumCpmmWithdraw" | "RaydiumCpmmInitialize" | "RaydiumClmmSwap" | "RaydiumClmmCreatePool" | "RaydiumClmmOpenPosition" | "RaydiumClmmClosePosition" | "RaydiumClmmIncreaseLiquidity" | "RaydiumClmmDecreaseLiquidity" | "RaydiumClmmLiquidityChange" | "RaydiumClmmConfigChange" | "RaydiumClmmCreatePersonalPosition" | "RaydiumClmmLiquidityCalculate" | "RaydiumClmmOpenLimitOrder" | "RaydiumClmmIncreaseLimitOrder" | "RaydiumClmmDecreaseLimitOrder" | "RaydiumClmmSettleLimitOrder" | "RaydiumClmmUpdateRewardInfos" | "RaydiumClmmOpenPositionWithTokenExtNft" | "RaydiumClmmCollectFee" | "RaydiumAmmV4Swap" | "RaydiumAmmV4Deposit" | "RaydiumAmmV4Withdraw" | "RaydiumAmmV4Initialize2" | "RaydiumAmmV4WithdrawPnl" | "OrcaWhirlpoolSwap" | "OrcaWhirlpoolLiquidityIncreased" | "OrcaWhirlpoolLiquidityDecreased" | "OrcaWhirlpoolPoolInitialized" | "MeteoraPoolsSwap" | "MeteoraPoolsAddLiquidity" | "MeteoraPoolsRemoveLiquidity" | "MeteoraPoolsBootstrapLiquidity" | "MeteoraPoolsPoolCreated" | "MeteoraPoolsSetPoolFees" | "MeteoraDammV2Swap" | "MeteoraDammV2AddLiquidity" | "MeteoraDammV2RemoveLiquidity" | "MeteoraDammV2InitializePool" | "MeteoraDammV2CreatePosition" | "MeteoraDammV2ClosePosition" | "MeteoraDbcSwap" | "MeteoraDbcInitializePool" | "MeteoraDbcCurveComplete" | "MeteoraDlmmSwap" | "MeteoraDlmmAddLiquidity" | "MeteoraDlmmRemoveLiquidity" | "MeteoraDlmmInitializePool" | "MeteoraDlmmInitializeBinArray" | "MeteoraDlmmCreatePosition" | "MeteoraDlmmClosePosition" | "MeteoraDlmmClaimFee" | "TokenAccount" | "TokenInfo" | "NonceAccount" | "AccountPumpFunGlobal" | "AccountPumpFunBondingCurve" | "AccountPumpFunFeeConfig" | "AccountPumpFunSharingConfig" | "AccountPumpFunGlobalVolumeAccumulator" | "AccountPumpFunUserVolumeAccumulator" | "AccountPumpSwapGlobalConfig" | "AccountPumpSwapPool" | "AccountRaydiumClmmAmmConfig" | "AccountRaydiumClmmPoolState" | "AccountRaydiumClmmTickArrayState" | "AccountRaydiumCpmmAmmConfig" | "AccountRaydiumCpmmPoolState" | "AccountOrcaWhirlpool" | "AccountOrcaPosition" | "AccountOrcaTickArray" | "AccountOrcaFeeTier" | "AccountOrcaWhirlpoolsConfig";
154
+ export type EventType = "BlockMeta" | "RaydiumLaunchlabTrade" | "RaydiumLaunchlabPoolCreate" | "RaydiumLaunchlabMigrateAmm" | "PumpFunTrade" | "PumpFunBuy" | "PumpFunSell" | "PumpFunBuyExactSolIn" | "PumpFunCreate" | "PumpFunCreateV2" | "PumpFunComplete" | "PumpFunMigrate" | "PumpFeesCreateFeeSharingConfig" | "PumpFeesInitializeFeeConfig" | "PumpFeesResetFeeSharingConfig" | "PumpFeesRevokeFeeSharingAuthority" | "PumpFeesTransferFeeSharingAuthority" | "PumpFeesUpdateAdmin" | "PumpFeesUpdateFeeConfig" | "PumpFeesUpdateFeeShares" | "PumpFeesUpsertFeeTiers" | "PumpFunMigrateBondingCurveCreator" | "PumpSwapTrade" | "PumpSwapBuy" | "PumpSwapSell" | "PumpSwapCreatePool" | "PumpSwapLiquidityAdded" | "PumpSwapLiquidityRemoved" | "RaydiumCpmmSwap" | "RaydiumCpmmDeposit" | "RaydiumCpmmWithdraw" | "RaydiumCpmmInitialize" | "RaydiumClmmSwap" | "RaydiumClmmCreatePool" | "RaydiumClmmOpenPosition" | "RaydiumClmmClosePosition" | "RaydiumClmmIncreaseLiquidity" | "RaydiumClmmDecreaseLiquidity" | "RaydiumClmmLiquidityChange" | "RaydiumClmmConfigChange" | "RaydiumClmmCreatePersonalPosition" | "RaydiumClmmLiquidityCalculate" | "RaydiumClmmOpenLimitOrder" | "RaydiumClmmIncreaseLimitOrder" | "RaydiumClmmDecreaseLimitOrder" | "RaydiumClmmSettleLimitOrder" | "RaydiumClmmUpdateRewardInfos" | "RaydiumClmmOpenPositionWithTokenExtNft" | "RaydiumClmmCollectFee" | "RaydiumAmmV4Swap" | "RaydiumAmmV4Deposit" | "RaydiumAmmV4Withdraw" | "RaydiumAmmV4Initialize2" | "RaydiumAmmV4WithdrawPnl" | "OrcaWhirlpoolSwap" | "OrcaWhirlpoolLiquidityIncreased" | "OrcaWhirlpoolLiquidityDecreased" | "OrcaWhirlpoolPoolInitialized" | "MeteoraPoolsSwap" | "MeteoraPoolsAddLiquidity" | "MeteoraPoolsRemoveLiquidity" | "MeteoraPoolsBootstrapLiquidity" | "MeteoraPoolsPoolCreated" | "MeteoraPoolsSetPoolFees" | "MeteoraDammV2Swap" | "MeteoraDammV2AddLiquidity" | "MeteoraDammV2RemoveLiquidity" | "MeteoraDammV2InitializePool" | "MeteoraDammV2CreatePosition" | "MeteoraDammV2ClosePosition" | "MeteoraDammV2UpdateDelegatePermission" | "MeteoraDammV2WithdrawDeadLiquidityReward" | "MeteoraDammV2CreateConfig" | "MeteoraDammV2CreateDynamicConfig" | "MeteoraDbcSwap" | "MeteoraDbcInitializePool" | "MeteoraDbcCurveComplete" | "MeteoraDlmmSwap" | "MeteoraDlmmAddLiquidity" | "MeteoraDlmmRemoveLiquidity" | "MeteoraDlmmInitializePool" | "MeteoraDlmmInitializeBinArray" | "MeteoraDlmmCreatePosition" | "MeteoraDlmmClosePosition" | "MeteoraDlmmClaimFee" | "TokenAccount" | "TokenInfo" | "NonceAccount" | "AccountPumpFunGlobal" | "AccountPumpFunBondingCurve" | "AccountPumpFunFeeConfig" | "AccountPumpFunSharingConfig" | "AccountPumpFunGlobalVolumeAccumulator" | "AccountPumpFunUserVolumeAccumulator" | "AccountPumpSwapGlobalConfig" | "AccountPumpSwapPool" | "AccountRaydiumClmmAmmConfig" | "AccountRaydiumClmmPoolState" | "AccountRaydiumClmmTickArrayState" | "AccountRaydiumCpmmAmmConfig" | "AccountRaydiumCpmmPoolState" | "AccountOrcaWhirlpool" | "AccountOrcaPosition" | "AccountOrcaTickArray" | "AccountOrcaFeeTier" | "AccountOrcaWhirlpoolsConfig";
155
155
  /** 与 Rust `grpc::EventType`(由 `StreamingEventType` 导出)一致 */
156
156
  export type StreamingEventType = EventType;
157
157
  /** 所有事件类型列表 */
@@ -207,6 +207,10 @@ exports.ALL_EVENT_TYPES = [
207
207
  "MeteoraDammV2InitializePool",
208
208
  "MeteoraDammV2CreatePosition",
209
209
  "MeteoraDammV2ClosePosition",
210
+ "MeteoraDammV2UpdateDelegatePermission",
211
+ "MeteoraDammV2WithdrawDeadLiquidityReward",
212
+ "MeteoraDammV2CreateConfig",
213
+ "MeteoraDammV2CreateDynamicConfig",
210
214
  // Meteora DBC
211
215
  "MeteoraDbcSwap",
212
216
  "MeteoraDbcInitializePool",
@@ -289,6 +293,10 @@ const METEORA_DAMM_V2_FILTER_TYPES = [
289
293
  "MeteoraDammV2CreatePosition",
290
294
  "MeteoraDammV2InitializePool",
291
295
  "MeteoraDammV2ClosePosition",
296
+ "MeteoraDammV2UpdateDelegatePermission",
297
+ "MeteoraDammV2WithdrawDeadLiquidityReward",
298
+ "MeteoraDammV2CreateConfig",
299
+ "MeteoraDammV2CreateDynamicConfig",
292
300
  ];
293
301
  const METEORA_DBC_FILTER_TYPES = [
294
302
  "MeteoraDbcSwap",
@@ -1,4 +1,7 @@
1
1
  import { type VersionedTransactionResponse } from "@solana/web3.js";
2
- import type { Transaction as YellowstoneTransaction, TransactionStatusMeta as YellowstoneMeta } from "@triton-one/yellowstone-grpc/dist/grpc/solana-storage.js";
2
+ import type { SubscribeUpdateTransactionInfo } from "@triton-one/yellowstone-grpc";
3
+ type YellowstoneTransaction = NonNullable<SubscribeUpdateTransactionInfo["transaction"]>;
4
+ type YellowstoneMeta = NonNullable<SubscribeUpdateTransactionInfo["meta"]>;
3
5
  /** Convert Yellowstone protobuf objects directly, without a WASM/Base58 serialization round trip. */
4
6
  export declare function yellowstoneTransactionToWeb3(transaction: YellowstoneTransaction, meta: YellowstoneMeta, slot: number, blockTime: number | null): VersionedTransactionResponse;
7
+ export {};
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseMeteoraDammInstruction = parseMeteoraDammInstruction;
4
4
  const dex_event_js_1 = require("../core/dex_event.js");
5
+ const meteora_damm_js_1 = require("../logs/meteora_damm.js");
5
6
  const utils_js_1 = require("./utils.js");
6
7
  const Z = (0, dex_event_js_1.defaultPubkey)();
7
8
  function disc8(a) {
@@ -14,6 +15,11 @@ const CPI = {
14
15
  CLOSE_POSITION_LOG: disc8([20, 145, 144, 68, 143, 142, 214, 178]),
15
16
  ADD_LIQUIDITY_LOG: disc8([175, 242, 8, 157, 30, 247, 185, 169]),
16
17
  REMOVE_LIQUIDITY_LOG: disc8([87, 46, 88, 98, 175, 96, 34, 91]),
18
+ LIQUIDITY_CHANGE_LOG: disc8([197, 171, 78, 127, 224, 211, 87, 13]),
19
+ UPDATE_DELEGATE_PERMISSION_LOG: disc8([66, 188, 75, 151, 150, 232, 87, 93]),
20
+ WITHDRAW_DEAD_LIQUIDITY_REWARD_LOG: disc8([228, 66, 150, 195, 42, 62, 163, 13]),
21
+ CREATE_CONFIG_LOG: disc8([131, 207, 180, 174, 180, 73, 165, 54]),
22
+ CREATE_DYNAMIC_CONFIG_LOG: disc8([231, 197, 13, 164, 248, 213, 133, 152]),
17
23
  };
18
24
  /** 与 cp_amm Anchor IDL `instructions[].discriminator` 一致(用户直接调用的外层指令) */
19
25
  const ANCHOR = {
@@ -107,13 +113,28 @@ function parseOuterSwap2Ix(instructionData, accounts, meta) {
107
113
  const swap_mode = (0, utils_js_1.readU8)(instructionData, 24);
108
114
  if (swap_mode === null)
109
115
  return null;
110
- const [amount_in, minimum_amount_out] = swap_mode === 0 ? [amount_0, amount_1] : [amount_1, amount_0];
116
+ let amount_in;
117
+ let minimum_amount_out;
118
+ if (swap_mode === 0 || swap_mode === 1) {
119
+ amount_in = amount_0;
120
+ minimum_amount_out = amount_1;
121
+ }
122
+ else if (swap_mode === 2) {
123
+ amount_in = amount_1;
124
+ minimum_amount_out = amount_0;
125
+ }
126
+ else {
127
+ return null;
128
+ }
111
129
  const pool = (0, utils_js_1.getAccount)(accounts, 1) ?? Z;
112
130
  const ev = {
113
131
  metadata: meta,
114
132
  pool,
115
133
  trade_direction: 0,
116
134
  has_referral: false,
135
+ amount_0,
136
+ amount_1,
137
+ swap_mode,
117
138
  amount_in,
118
139
  minimum_amount_out,
119
140
  output_amount: 0n,
@@ -335,85 +356,11 @@ function parseSwapCpi(data, accounts, meta) {
335
356
  return { MeteoraDammV2Swap: ev };
336
357
  }
337
358
  function parseSwap2Cpi(data, accounts, meta) {
338
- let o = 0;
339
- const pool = (0, utils_js_1.readPubkeyIx)(data, o);
340
- if (!pool)
341
- return null;
342
- o += 32;
343
- const trade_direction = (0, utils_js_1.readU8)(data, o);
344
- if (trade_direction === null)
345
- return null;
346
- o += 1;
347
- const _cfm = (0, utils_js_1.readU8)(data, o);
348
- if (_cfm === null)
349
- return null;
350
- o += 1;
351
- const has_referral = (0, utils_js_1.readBool)(data, o);
352
- if (has_referral === null)
353
- return null;
354
- o += 1;
355
- const amount_0 = (0, utils_js_1.readU64LE)(data, o);
356
- if (amount_0 === null)
357
- return null;
358
- o += 8;
359
- const amount_1 = (0, utils_js_1.readU64LE)(data, o);
360
- if (amount_1 === null)
361
- return null;
362
- o += 8;
363
- const swap_mode = (0, utils_js_1.readU8)(data, o);
364
- if (swap_mode === null)
365
- return null;
366
- o += 1;
367
- const included_fee_input_amount = (0, utils_js_1.readU64LE)(data, o);
368
- if (included_fee_input_amount === null)
369
- return null;
370
- o += 8;
371
- o += 8;
372
- o += 8;
373
- const output_amount = (0, utils_js_1.readU64LE)(data, o);
374
- if (output_amount === null)
375
- return null;
376
- o += 8;
377
- const next_sqrt_price = (0, utils_js_1.readU128LE)(data, o);
378
- if (next_sqrt_price === null)
379
- return null;
380
- o += 16;
381
- const lp_fee = (0, utils_js_1.readU64LE)(data, o);
382
- if (lp_fee === null)
383
- return null;
384
- o += 8;
385
- const protocol_fee = (0, utils_js_1.readU64LE)(data, o);
386
- if (protocol_fee === null)
387
- return null;
388
- o += 8;
389
- const referral_fee = (0, utils_js_1.readU64LE)(data, o);
390
- if (referral_fee === null)
359
+ const ev = (0, meteora_damm_js_1.parseSwap2FromData)(data, meta);
360
+ if (!ev || !("MeteoraDammV2Swap" in ev))
391
361
  return null;
392
- o += 8;
393
- o += 8;
394
- o += 8;
395
- const current_timestamp = (0, utils_js_1.readU64LE)(data, o);
396
- if (current_timestamp === null)
397
- return null;
398
- const [amount_in, minimum_amount_out] = swap_mode === 0 ? [amount_0, amount_1] : [amount_1, amount_0];
399
- const ev = {
400
- metadata: meta,
401
- pool,
402
- trade_direction,
403
- has_referral,
404
- amount_in,
405
- minimum_amount_out,
406
- output_amount,
407
- next_sqrt_price,
408
- lp_fee,
409
- protocol_fee,
410
- partner_fee: 0n,
411
- referral_fee,
412
- actual_amount_in: included_fee_input_amount,
413
- current_timestamp,
414
- ...meteoraSwapVaultsFromAccounts(accounts),
415
- };
416
- return { MeteoraDammV2Swap: ev };
362
+ Object.assign(ev.MeteoraDammV2Swap, meteoraSwapVaultsFromAccounts(accounts));
363
+ return ev;
417
364
  }
418
365
  function parseMeteoraDammInstruction(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs) {
419
366
  if (instructionData.length < 8)
@@ -597,5 +544,20 @@ function parseMeteoraDammInstruction(instructionData, accounts, signature, slot,
597
544
  },
598
545
  };
599
546
  }
547
+ if (discEq(cpiHead, CPI.LIQUIDITY_CHANGE_LOG)) {
548
+ return (0, meteora_damm_js_1.parseLiquidityChangeFromData)(cpiData, meta);
549
+ }
550
+ if (discEq(cpiHead, CPI.UPDATE_DELEGATE_PERMISSION_LOG)) {
551
+ return (0, meteora_damm_js_1.parseUpdateDelegatePermissionFromData)(cpiData, meta);
552
+ }
553
+ if (discEq(cpiHead, CPI.WITHDRAW_DEAD_LIQUIDITY_REWARD_LOG)) {
554
+ return (0, meteora_damm_js_1.parseWithdrawDeadLiquidityRewardFromData)(cpiData, meta);
555
+ }
556
+ if (discEq(cpiHead, CPI.CREATE_CONFIG_LOG)) {
557
+ return (0, meteora_damm_js_1.parseCreateConfigFromData)(cpiData, meta);
558
+ }
559
+ if (discEq(cpiHead, CPI.CREATE_DYNAMIC_CONFIG_LOG)) {
560
+ return (0, meteora_damm_js_1.parseCreateDynamicConfigFromData)(cpiData, meta);
561
+ }
600
562
  return null;
601
563
  }
@@ -151,6 +151,11 @@ function parseMeteoraDlmmInstruction(instructionData, accounts, signature, slot,
151
151
  return {
152
152
  MeteoraDlmmSwap: {
153
153
  metadata,
154
+ token_x_mint: Z,
155
+ token_y_mint: Z,
156
+ user_token_in: (0, utils_js_1.getAccount)(accounts, 4) ?? Z,
157
+ user_token_out: (0, utils_js_1.getAccount)(accounts, 5) ?? Z,
158
+ min_amount_out: (0, binary_js_1.readU64LE)(data, 8) ?? 0n,
154
159
  pool,
155
160
  from: (0, utils_js_1.getAccount)(accounts, 10) ?? Z,
156
161
  start_bin_id: 0,
@@ -175,6 +180,11 @@ function parseMeteoraDlmmInstruction(instructionData, accounts, signature, slot,
175
180
  return {
176
181
  MeteoraDlmmSwap: {
177
182
  metadata,
183
+ token_x_mint: Z,
184
+ token_y_mint: Z,
185
+ user_token_in: (0, utils_js_1.getAccount)(accounts, 4) ?? Z,
186
+ user_token_out: (0, utils_js_1.getAccount)(accounts, 5) ?? Z,
187
+ min_amount_out: 0n,
178
188
  pool,
179
189
  from: (0, utils_js_1.getAccount)(accounts, 10) ?? Z,
180
190
  start_bin_id: 0,
@@ -39,6 +39,8 @@ function createNumericDefaults() {
39
39
  quote_vault: Z,
40
40
  quote_token_program: Z,
41
41
  virtual_quote_reserves: 0n,
42
+ creator_fee_bps: 0n,
43
+ is_holder_reward: false,
42
44
  ix_name: "",
43
45
  };
44
46
  }
@@ -89,6 +91,8 @@ function parsePumpfunTradeV2Instruction(ixName, data, accounts, metadata) {
89
91
  mayhem_mode: false,
90
92
  cashback_fee_basis_points: 0n,
91
93
  cashback: 0n,
94
+ holder_rewards_bps: 0n,
95
+ holder_rewards: 0n,
92
96
  is_cashback_coin: false,
93
97
  associated_bonding_curve: accounts[11] ?? Z,
94
98
  associated_user: accounts[14] ?? Z,
@@ -175,6 +179,8 @@ function parsePumpfunLegacyBuyInstruction(ixName, data, accounts, metadata) {
175
179
  mayhem_mode: false,
176
180
  cashback_fee_basis_points: 0n,
177
181
  cashback: 0n,
182
+ holder_rewards_bps: 0n,
183
+ holder_rewards: 0n,
178
184
  is_cashback_coin: false,
179
185
  quote_mint: exports.PUMPFUN_SOL_QUOTE_MINT,
180
186
  quote_token_program: Z,
@@ -269,6 +275,8 @@ function parsePumpfunLegacySellInstruction(data, accounts, metadata) {
269
275
  mayhem_mode: false,
270
276
  cashback_fee_basis_points: 0n,
271
277
  cashback: 0n,
278
+ holder_rewards_bps: 0n,
279
+ holder_rewards: 0n,
272
280
  is_cashback_coin: false,
273
281
  ...(legacyBuybackFeeRecipient !== Z ? { account: legacyBuybackFeeRecipient } : {}),
274
282
  };
@@ -307,6 +315,12 @@ function parsePumpfunInstruction(instructionData, accounts, signature, slot, txI
307
315
  return null;
308
316
  o += 1;
309
317
  const isCashbackEnabled = (0, utils_js_1.readBool)(data, o) ?? false;
318
+ if (o < data.length)
319
+ o += 1;
320
+ const creatorFeeBps = (0, utils_js_1.readU64LE)(data, o) ?? 0n;
321
+ if (o + 8 <= data.length)
322
+ o += 8;
323
+ const isHolderReward = (0, utils_js_1.readBool)(data, o) ?? false;
310
324
  const mint = accounts[0];
311
325
  const ev = {
312
326
  metadata: meta,
@@ -338,6 +352,8 @@ function parsePumpfunInstruction(instructionData, accounts, signature, slot, txI
338
352
  ix_name: "create_v2",
339
353
  is_mayhem_mode: isMayhemMode,
340
354
  is_cashback_enabled: isCashbackEnabled,
355
+ creator_fee_bps: creatorFeeBps,
356
+ is_holder_reward: isHolderReward,
341
357
  };
342
358
  return { PumpFunCreateV2: ev };
343
359
  }
@@ -99,6 +99,8 @@ function buyLike(data, accounts, meta, swapOrder) {
99
99
  virtual_quote_reserves: 0n,
100
100
  can_boost: false,
101
101
  base_supply: 0n,
102
+ holder_rewards_bps: 0n,
103
+ holder_rewards: 0n,
102
104
  is_pump_pool: false,
103
105
  base_mint: g(3),
104
106
  quote_mint: g(4),
@@ -167,6 +169,8 @@ function parsePumpswapInstruction(instructionData, accounts, signature, slot, tx
167
169
  virtual_quote_reserves: 0n,
168
170
  can_boost: false,
169
171
  base_supply: 0n,
172
+ holder_rewards_bps: 0n,
173
+ holder_rewards: 0n,
170
174
  is_pump_pool: false,
171
175
  base_mint: g(3),
172
176
  quote_mint: g(4),
@@ -187,15 +191,15 @@ function parsePumpswapInstruction(instructionData, accounts, signature, slot, tx
187
191
  const ev = {
188
192
  metadata: meta,
189
193
  timestamp: 0n,
190
- index: 0,
194
+ index: Number(data.length >= 2 ? data[0] | (data[1] << 8) : 0),
191
195
  pool: g(0),
192
196
  creator: g(2),
193
197
  base_mint: g(3),
194
198
  quote_mint: g(4),
195
199
  base_mint_decimals: 0,
196
200
  quote_mint_decimals: 0,
197
- base_amount_in: 0n,
198
- quote_amount_in: 0n,
201
+ base_amount_in: (0, utils_js_1.readU64LE)(data, 2) ?? 0n,
202
+ quote_amount_in: (0, utils_js_1.readU64LE)(data, 10) ?? 0n,
199
203
  pool_base_amount: 0n,
200
204
  pool_quote_amount: 0n,
201
205
  minimum_liquidity: 0n,
@@ -205,8 +209,12 @@ function parsePumpswapInstruction(instructionData, accounts, signature, slot, tx
205
209
  lp_mint: g(5),
206
210
  user_base_token_account: g(6),
207
211
  user_quote_token_account: g(7),
208
- coin_creator: g(1),
209
- is_mayhem_mode: false,
212
+ coin_creator: (0, utils_js_1.readPubkeyIx)(data, 18) ?? g(1),
213
+ is_mayhem_mode: data[50] === 1,
214
+ is_cashback_coin: data[51] === 1,
215
+ creator_fee_bps: (0, utils_js_1.readU64LE)(data, 52) ?? 0n,
216
+ can_edit_creator_fee: data[60] === 1,
217
+ is_holder_reward: data[61] === 1,
210
218
  };
211
219
  return { PumpSwapCreatePool: ev };
212
220
  }
@@ -1,4 +1,20 @@
1
+ import { type EventMetadata } from "../core/metadata.js";
1
2
  import type { DexEvent } from "../core/dex_event.js";
3
+ /**
4
+ * Mainnet upgrade that replaced `trading_fee/partner_fee` in `EvtSwap2` with
5
+ * `claiming_fee/compounding_fee` without changing discriminator or size.
6
+ */
7
+ export declare const COMPOUNDING_FEE_LAYOUT_ACTIVATION_SLOT = 406048752;
8
+ /** Aligns with Rust `parse_swap2_from_data` (full 180-byte EvtSwap2 layout). */
9
+ export declare function parseSwap2FromData(data: Uint8Array, meta: EventMetadata): DexEvent | null;
10
+ export declare function parseAddLiquidityFromData(data: Uint8Array, meta: EventMetadata): DexEvent | null;
11
+ export declare function parseRemoveLiquidityFromData(data: Uint8Array, meta: EventMetadata): DexEvent | null;
12
+ /** Parse current `EvtLiquidityChange`; `change_type` 0 = add, 1 = remove. */
13
+ export declare function parseLiquidityChangeFromData(data: Uint8Array, meta: EventMetadata): DexEvent | null;
14
+ export declare function parseUpdateDelegatePermissionFromData(data: Uint8Array, meta: EventMetadata): DexEvent | null;
15
+ export declare function parseWithdrawDeadLiquidityRewardFromData(data: Uint8Array, meta: EventMetadata): DexEvent | null;
16
+ export declare function parseCreateConfigFromData(data: Uint8Array, meta: EventMetadata): DexEvent | null;
17
+ export declare function parseCreateDynamicConfigFromData(data: Uint8Array, meta: EventMetadata): DexEvent | null;
2
18
  /**
3
19
  * Meteora DAMM Program data 入口;与 Rust `logs/meteora_damm.rs` 一致。
4
20
  */