@neutral-trade/sdk 0.1.1 → 0.1.2

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/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  TypeScript SDK for [Neutral Trade](https://neutral.trade) vaults.
8
8
 
9
- 📚 **[Documentation](https://sdk.neutral.trade)**
9
+ 📚 **[Documentation](https://sdk-neutral-trade.vercel.app/)**
10
10
 
11
11
  ## Installation
12
12
 
package/dist/index.d.mts CHANGED
@@ -5095,8 +5095,8 @@ interface NeutralTradeConfig {
5095
5095
  rpcUrl: string;
5096
5096
  /** Optional registry URL to fetch vault configurations from. If provided, fetched vaults will override built-in vaults. */
5097
5097
  registryUrl?: string;
5098
- /** Optional prices map. If not provided, prices will be fetched from Pyth Network automatically */
5099
- prices?: Partial<Record<SupportedToken, number>>;
5098
+ /** Optional fallback prices map. Prices are fetched from Pyth Network first; fallback is used only if Pyth returns incomplete data */
5099
+ fallbackPrices?: Partial<Record<SupportedToken, number>>;
5100
5100
  }
5101
5101
  declare class NeutralTrade {
5102
5102
  readonly connection: Connection;
package/dist/index.mjs CHANGED
@@ -9186,37 +9186,56 @@ const TOKEN_TO_PYTH_FEED_ID = {
9186
9186
  };
9187
9187
  /**
9188
9188
  * Fetch prices from Pyth Network Hermes API
9189
- * @throws Error if fetch fails or price parsing fails
9189
+ * Returns a partial map - missing prices will not be included (no throw)
9190
9190
  */
9191
9191
  async function fetchPricesFromPyth(tokens$1) {
9192
- const url = `https://hermes.pyth.network/v2/updates/price/latest?${tokens$1.map((token) => TOKEN_TO_PYTH_FEED_ID[token]).map((id) => `ids[]=${encodeURIComponent(id)}`).join("&")}`;
9193
- const response = await fetch(url);
9194
- if (!response.ok) throw new Error(`Failed to fetch prices from Pyth Network: ${response.status} ${response.statusText}`);
9195
- const data = await response.json();
9196
- if (!data.parsed || data.parsed.length === 0) throw new Error("No price data returned from Pyth Network");
9197
9192
  const priceMap = /* @__PURE__ */ new Map();
9198
- for (const token of tokens$1) {
9199
- const feedId = TOKEN_TO_PYTH_FEED_ID[token];
9200
- const feed = data.parsed.find((f) => f.id === feedId);
9201
- if (!feed) throw new Error(`Price feed not found for ${token} (${feedId})`);
9202
- const price = Number.parseFloat(feed.price.price) * 10 ** feed.price.expo;
9203
- priceMap.set(token, price);
9193
+ if (tokens$1.length === 0) return priceMap;
9194
+ try {
9195
+ const url = `https://hermes.pyth.network/v2/updates/price/latest?${tokens$1.map((token) => TOKEN_TO_PYTH_FEED_ID[token]).map((id) => `ids[]=${encodeURIComponent(id)}`).join("&")}`;
9196
+ const response = await fetch(url);
9197
+ if (!response.ok) {
9198
+ console.warn(`Failed to fetch prices from Pyth Network: ${response.status} ${response.statusText}`);
9199
+ return priceMap;
9200
+ }
9201
+ const data = await response.json();
9202
+ if (!data.parsed || data.parsed.length === 0) {
9203
+ console.warn("No price data returned from Pyth Network");
9204
+ return priceMap;
9205
+ }
9206
+ for (const token of tokens$1) {
9207
+ const feedId = TOKEN_TO_PYTH_FEED_ID[token];
9208
+ const feed = data.parsed.find((f) => f.id === feedId);
9209
+ if (!feed) {
9210
+ console.warn(`Price feed not found for ${token} (${feedId})`);
9211
+ continue;
9212
+ }
9213
+ const price = Number.parseFloat(feed.price.price) * 10 ** feed.price.expo;
9214
+ priceMap.set(token, price);
9215
+ }
9216
+ } catch (error) {
9217
+ console.warn("Error fetching prices from Pyth Network:", error);
9204
9218
  }
9205
9219
  return priceMap;
9206
9220
  }
9207
9221
  /**
9208
- * Initialize price map from user-provided prices and fetch missing prices from Pyth Network
9209
- * @throws Error if Pyth fetch fails
9222
+ * Initialize price map by fetching from Pyth Network first, then using fallback prices for any missing
9223
+ * @param vaults - Vault configurations to determine which tokens need prices
9224
+ * @param fallbackPrices - Optional fallback prices to use if Pyth fetch fails or returns incomplete data
9210
9225
  */
9211
- async function initializePrices(vaults$1, userPrices) {
9212
- const priceMap = /* @__PURE__ */ new Map();
9213
- if (userPrices) for (const [token, price] of Object.entries(userPrices)) priceMap.set(token, price);
9226
+ async function initializePrices(vaults$1, fallbackPrices) {
9214
9227
  const allDepositTokens = /* @__PURE__ */ new Set();
9215
9228
  for (const vault of Object.values(vaults$1)) if (vault) allDepositTokens.add(vault.depositToken);
9216
- const missingTokens = Array.from(allDepositTokens).filter((token) => !priceMap.has(token));
9217
- if (missingTokens.length > 0) {
9218
- const pythPrices = await fetchPricesFromPyth(missingTokens);
9219
- for (const [token, price] of pythPrices) priceMap.set(token, price);
9229
+ const tokensNeeded = Array.from(allDepositTokens);
9230
+ const priceMap = await fetchPricesFromPyth(tokensNeeded);
9231
+ if (fallbackPrices) {
9232
+ for (const token of tokensNeeded) if (!priceMap.has(token) && token in fallbackPrices) {
9233
+ const fallbackPrice = fallbackPrices[token];
9234
+ if (fallbackPrice !== void 0) {
9235
+ console.warn(`Using fallback price for ${token}: ${fallbackPrice}`);
9236
+ priceMap.set(token, fallbackPrice);
9237
+ }
9238
+ }
9220
9239
  }
9221
9240
  return priceMap;
9222
9241
  }
@@ -9280,7 +9299,7 @@ var NeutralTrade = class NeutralTrade {
9280
9299
  ...remoteVaults
9281
9300
  };
9282
9301
  }
9283
- const priceMap = await initializePrices(vaults$1, config.prices);
9302
+ const priceMap = await initializePrices(vaults$1, config.fallbackPrices);
9284
9303
  return new NeutralTrade(connection, bundleProgramV1, bundleProgramV2, driftVaultClient, vaults$1, priceMap);
9285
9304
  }
9286
9305
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@neutral-trade/sdk",
3
3
  "type": "module",
4
- "version": "0.1.1",
4
+ "version": "0.1.2",
5
5
  "description": "SDK for Neutral Trade vaults",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/neutral-trade/sdk#readme",