@solard/cli 0.2.20 → 0.2.22

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.
@@ -7,13 +7,13 @@ import {
7
7
  type Logs,
8
8
  type ParsedTransactionWithMeta,
9
9
  } from "@solana/web3.js";
10
- import { connectPriceFeed } from "./price-feed-client.ts";
11
- import type { PriceFeedPrice } from "./price-feed-protocol.ts";
12
10
  import {
13
11
  RaydiumService,
14
12
  createTraderSolard,
15
13
  resolveTradeAsset,
16
14
  sol,
15
+ subscribeTrades,
16
+ type TradeEvent,
17
17
  } from "@solard/core";
18
18
 
19
19
  type Flags = Map<string, string>;
@@ -1003,14 +1003,10 @@ export async function runTradeStrategyCommand(args: {
1003
1003
  Math.trunc(numberFlag(args.flags, "heartbeat-ms", 15_000)),
1004
1004
  );
1005
1005
  const rpc = rpcUrl(args.flags);
1006
- const feed =
1007
- flag(args.flags, "feed") ??
1008
- process.env.SOLARD_FEED_URL?.trim() ??
1009
- "ws://127.0.0.1:8788/ws";
1010
1006
  const strategy = await loadStrategy(path);
1011
1007
  if (typeof strategy.onPrice !== "function")
1012
1008
  throw new Error(
1013
- `Live shared-feed strategy ${path} must define onPrice(ctx, price). ` +
1009
+ `Live trade strategy ${path} must define onPrice(ctx, price). ` +
1014
1010
  `Legacy onTrade is retained for historical exact-trade backtests, not per-agent live RPC subscriptions.`,
1015
1011
  );
1016
1012
  const state = await initialState(strategy);
@@ -1021,8 +1017,7 @@ export async function runTradeStrategyCommand(args: {
1021
1017
  let priceCount = 0;
1022
1018
  let lastPrice: StrategyPriceTick | null = null;
1023
1019
  let callbackErrors = 0;
1024
- let feedErrors = 0;
1025
- let feedConnected = false;
1020
+ let marketErrors = 0;
1026
1021
  let callbackQueue: Promise<void> = Promise.resolve();
1027
1022
 
1028
1023
  try {
@@ -1139,18 +1134,20 @@ export async function runTradeStrategyCommand(args: {
1139
1134
  }
1140
1135
  };
1141
1136
 
1142
- const onPrice = async (event: PriceFeedPrice) => {
1143
- if (event.mint !== mint || stopped) return;
1137
+ const onPrice = async (event: TradeEvent) => {
1138
+ if (event.mint !== mint || stopped || event.priceQuote == null) return;
1139
+ const priceSol = event.quoteMint === WSOL_MINT ? event.priceQuote : null;
1140
+ const priceUsd = event.quoteMint === USDC_MINT ? event.priceQuote : null;
1141
+ if (priceSol == null && priceUsd == null) return;
1144
1142
  const price: StrategyPriceTick = {
1145
- signature: event.signature ?? "feed",
1146
- slot: event.slot ?? 0,
1143
+ signature: event.signature,
1144
+ slot: event.slot,
1147
1145
  atMs: event.atMs,
1148
1146
  mint,
1149
- priceSol: event.priceSol,
1150
- priceUsd: event.priceUsd,
1151
- marketCapUsd: event.marketCapUsd,
1147
+ priceSol,
1148
+ priceUsd,
1149
+ marketCapUsd: null,
1152
1150
  };
1153
- if (price.priceSol == null && price.priceUsd == null) return;
1154
1151
  priceCount += 1;
1155
1152
  lastPrice = price;
1156
1153
  if (json) report("price", price as any);
@@ -1162,21 +1159,16 @@ export async function runTradeStrategyCommand(args: {
1162
1159
  };
1163
1160
 
1164
1161
  const controller = new AbortController();
1165
- const feedClient = await connectPriceFeed({
1166
- url: feed,
1167
- subscribe: { op: "subscribe", mints: [mint] },
1162
+ const marketSubscription = await subscribeTrades({
1163
+ connection: slrd.connection(),
1164
+ tokens: [mint],
1168
1165
  signal: controller.signal,
1169
- onStatus(event, data) {
1170
- if (event === "connected") feedConnected = true;
1171
- if (event === "connect-error") {
1172
- feedConnected = false;
1173
- feedErrors += 1;
1174
- }
1175
- report(`feed ${event}`, data ?? {});
1166
+ onTrade(event) {
1167
+ callbackQueue = callbackQueue.then(() => onPrice(event));
1176
1168
  },
1177
- onMessage(message) {
1178
- if (message.type !== "price" || message.mint !== mint) return;
1179
- callbackQueue = callbackQueue.then(() => onPrice(message));
1169
+ onStatus(event, data) {
1170
+ if (event.includes("error")) marketErrors += 1;
1171
+ report(`market ${event}`, data ?? {});
1180
1172
  },
1181
1173
  });
1182
1174
 
@@ -1186,9 +1178,8 @@ export async function runTradeStrategyCommand(args: {
1186
1178
  wallet: walletRef,
1187
1179
  walletAddress,
1188
1180
  live,
1189
- feed,
1190
- event: "shared-price-feed",
1191
- upstreamMarketSubscriptions: 0,
1181
+ event: "direct-trade-subscription",
1182
+ upstreamMarketSubscriptions: marketSubscription.listTokens().length,
1192
1183
  });
1193
1184
 
1194
1185
  if (strategy.onStart) {
@@ -1208,11 +1199,10 @@ export async function runTradeStrategyCommand(args: {
1208
1199
  process.once("SIGTERM", stopSignal);
1209
1200
  const heartbeatTimer = setInterval(() => {
1210
1201
  report("strategy heartbeat", {
1211
- feedConnected,
1212
1202
  prices: priceCount,
1213
1203
  callbackErrors,
1214
- feedErrors,
1215
- upstreamMarketSubscriptions: 0,
1204
+ marketErrors,
1205
+ upstreamMarketSubscriptions: marketSubscription.listTokens().length,
1216
1206
  executionVenue: executor.venue ?? "unresolved",
1217
1207
  });
1218
1208
  }, heartbeatMs);
@@ -1224,7 +1214,7 @@ export async function runTradeStrategyCommand(args: {
1224
1214
  process.removeListener("SIGINT", stopSignal);
1225
1215
  process.removeListener("SIGTERM", stopSignal);
1226
1216
  controller.abort();
1227
- feedClient.close();
1217
+ await marketSubscription.close();
1228
1218
  await callbackQueue.catch(() => undefined);
1229
1219
  if (strategy.onStop) {
1230
1220
  try {
@@ -1238,7 +1228,7 @@ export async function runTradeStrategyCommand(args: {
1238
1228
  reason: stopReason,
1239
1229
  prices: priceCount,
1240
1230
  callbackErrors,
1241
- feedErrors,
1231
+ marketErrors,
1242
1232
  });
1243
1233
  }
1244
1234
  } finally {