@basedone/core 0.0.6 → 0.0.7

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/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
- import { SpotToken, PerpsMeta, PerpsAssetCtx, SpotMeta, PerpDex } from '@nktkas/hyperliquid';
1
+ import { SpotToken, PerpsMeta, PerpsAssetCtx, SpotMeta } from '@nktkas/hyperliquid';
2
+ import { Hex } from '@nktkas/hyperliquid/script/src/types/mod';
2
3
 
3
4
  declare function encodeSlug(slug: string): bigint;
4
5
  declare function decodeSlug(value: bigint): string;
@@ -233,6 +234,18 @@ declare function getNextTierInfo(pupTokenAmount: number, normalizedAirDropAmount
233
234
  declare const USDC_SPOT_TOKEN: SpotToken;
234
235
  declare const TESTNET_USDC_SPOT_TOKEN: SpotToken;
235
236
 
237
+ interface PerpDex {
238
+ /** Short name of the perpetual dex. */
239
+ name: string;
240
+ /** Complete name of the perpetual dex. */
241
+ fullName: string;
242
+ /** Hex address of the dex deployer. */
243
+ deployer: Hex;
244
+ /** Hex address of the oracle updater, or null if not available. */
245
+ oracleUpdater: Hex | null;
246
+ feeRecipient: Hex | null;
247
+ assetToStreamingOiCap: [string, string][];
248
+ }
236
249
  /**
237
250
  * Market information for trading operations
238
251
  */
@@ -242,11 +255,15 @@ interface MarketInfo {
242
255
  szDecimals: number;
243
256
  type: "perps" | "spot" | "hip3";
244
257
  coin: string;
258
+ displayName?: string;
259
+ imageUrl?: string;
245
260
  maxLeverage?: number;
246
261
  baseToken?: SpotToken;
247
262
  quoteToken?: SpotToken;
248
263
  dexName?: string;
249
264
  dexIndex?: number;
265
+ dexDisplayName?: string;
266
+ dexImageUrl?: string;
250
267
  }
251
268
  interface DexInfo {
252
269
  meta: PerpsMeta;
@@ -255,6 +272,8 @@ interface DexInfo {
255
272
  dexName: string;
256
273
  dexIndex: number;
257
274
  collateralTokenSymbol: string;
275
+ displayName?: string;
276
+ imageUrl?: string;
258
277
  }
259
278
  type ExtendedPerpsMeta = PerpsMeta & {
260
279
  collateralToken?: number;
@@ -298,6 +317,7 @@ interface MetadataClientConfig {
298
317
  * - Spot: 10000 + index
299
318
  * - HIP-3: 100000 + perp_dex_index * 10000 + index_in_meta
300
319
  */
320
+ declare const ROOT_DEX = "hyperliquid";
301
321
  declare class MetadataClient {
302
322
  private infoClient;
303
323
  private config;
@@ -305,6 +325,7 @@ declare class MetadataClient {
305
325
  private spotMeta;
306
326
  private perpsMeta;
307
327
  private perpDexs;
328
+ private staticMeta;
308
329
  private hip3DexsMeta;
309
330
  private perpsSymbolToIndex;
310
331
  private spotTokenNameToIndex;
@@ -320,6 +341,11 @@ declare class MetadataClient {
320
341
  * Initialize metadata by fetching from Hyperliquid
321
342
  */
322
343
  initialize(): Promise<void>;
344
+ /**
345
+ * Load staticMeta.json for display overrides
346
+ * This is always loaded regardless of config.useStaticFallback
347
+ */
348
+ private loadStaticMetaOverrides;
323
349
  /**
324
350
  * Load static metadata from bundled JSON files
325
351
  */
@@ -459,4 +485,4 @@ declare const formatSizeForOrder: ({ sz, szDecimals, }: {
459
485
  */
460
486
  declare function getPriceDecimals(price: number, szDecimals: number, isSpot: boolean): number;
461
487
 
462
- export { type AirdropAllocationData, CloidClientCode, type CloidClientCodeId, CloidClientCodeNameById, type CloidData, type DexInfo, type ExtendedPerpsMeta, type MarketInfo, MetadataClient, PUP_TOKEN_ADDRESS, PUP_TOKEN_THRESHOLDS, type PupEligibilityResult, TARGET_APPROVED_MAX_BUILDER_FEE, TARGET_APPROVED_MAX_BUILDER_FEE_PERCENT, TESTNET_USDC_SPOT_TOKEN, type TokenInfo, USDC_SPOT_TOKEN, type UpheavalApiResponse, type UpheavalPosition, type UpheavalSnapshot, type V3LPTokenInfo, WidgetType, WidgetTypeById, type WidgetTypeId, XP_BOOST_PERCENTAGES, buildCloid, calculateBoostPercentage, calculateTotalPupAmount, decodeSlug, encodeSlug, formatPriceAndSize, formatPriceForOrder, formatSizeForOrder, getApprovalAmount, getClientCodeNameById, getCloid, getNextTierInfo, getPriceDecimals, getWidgetTypeById, isBasedCloid, isClientCode, isMiniAppCloid, isMiniAppTriggeredCloid, isTenantCloid, isTrackingIdCloid, isWidgetType, normaliseSlug, normaliseTrackingId, normalizeAirdropAmount, parseCloid };
488
+ export { type AirdropAllocationData, CloidClientCode, type CloidClientCodeId, CloidClientCodeNameById, type CloidData, type DexInfo, type ExtendedPerpsMeta, type MarketInfo, MetadataClient, PUP_TOKEN_ADDRESS, PUP_TOKEN_THRESHOLDS, type PerpDex, type PupEligibilityResult, ROOT_DEX, TARGET_APPROVED_MAX_BUILDER_FEE, TARGET_APPROVED_MAX_BUILDER_FEE_PERCENT, TESTNET_USDC_SPOT_TOKEN, type TokenInfo, USDC_SPOT_TOKEN, type UpheavalApiResponse, type UpheavalPosition, type UpheavalSnapshot, type V3LPTokenInfo, WidgetType, WidgetTypeById, type WidgetTypeId, XP_BOOST_PERCENTAGES, buildCloid, calculateBoostPercentage, calculateTotalPupAmount, decodeSlug, encodeSlug, formatPriceAndSize, formatPriceForOrder, formatSizeForOrder, getApprovalAmount, getClientCodeNameById, getCloid, getNextTierInfo, getPriceDecimals, getWidgetTypeById, isBasedCloid, isClientCode, isMiniAppCloid, isMiniAppTriggeredCloid, isTenantCloid, isTrackingIdCloid, isWidgetType, normaliseSlug, normaliseTrackingId, normalizeAirdropAmount, parseCloid };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { SpotToken, PerpsMeta, PerpsAssetCtx, SpotMeta, PerpDex } from '@nktkas/hyperliquid';
1
+ import { SpotToken, PerpsMeta, PerpsAssetCtx, SpotMeta } from '@nktkas/hyperliquid';
2
+ import { Hex } from '@nktkas/hyperliquid/script/src/types/mod';
2
3
 
3
4
  declare function encodeSlug(slug: string): bigint;
4
5
  declare function decodeSlug(value: bigint): string;
@@ -233,6 +234,18 @@ declare function getNextTierInfo(pupTokenAmount: number, normalizedAirDropAmount
233
234
  declare const USDC_SPOT_TOKEN: SpotToken;
234
235
  declare const TESTNET_USDC_SPOT_TOKEN: SpotToken;
235
236
 
237
+ interface PerpDex {
238
+ /** Short name of the perpetual dex. */
239
+ name: string;
240
+ /** Complete name of the perpetual dex. */
241
+ fullName: string;
242
+ /** Hex address of the dex deployer. */
243
+ deployer: Hex;
244
+ /** Hex address of the oracle updater, or null if not available. */
245
+ oracleUpdater: Hex | null;
246
+ feeRecipient: Hex | null;
247
+ assetToStreamingOiCap: [string, string][];
248
+ }
236
249
  /**
237
250
  * Market information for trading operations
238
251
  */
@@ -242,11 +255,15 @@ interface MarketInfo {
242
255
  szDecimals: number;
243
256
  type: "perps" | "spot" | "hip3";
244
257
  coin: string;
258
+ displayName?: string;
259
+ imageUrl?: string;
245
260
  maxLeverage?: number;
246
261
  baseToken?: SpotToken;
247
262
  quoteToken?: SpotToken;
248
263
  dexName?: string;
249
264
  dexIndex?: number;
265
+ dexDisplayName?: string;
266
+ dexImageUrl?: string;
250
267
  }
251
268
  interface DexInfo {
252
269
  meta: PerpsMeta;
@@ -255,6 +272,8 @@ interface DexInfo {
255
272
  dexName: string;
256
273
  dexIndex: number;
257
274
  collateralTokenSymbol: string;
275
+ displayName?: string;
276
+ imageUrl?: string;
258
277
  }
259
278
  type ExtendedPerpsMeta = PerpsMeta & {
260
279
  collateralToken?: number;
@@ -298,6 +317,7 @@ interface MetadataClientConfig {
298
317
  * - Spot: 10000 + index
299
318
  * - HIP-3: 100000 + perp_dex_index * 10000 + index_in_meta
300
319
  */
320
+ declare const ROOT_DEX = "hyperliquid";
301
321
  declare class MetadataClient {
302
322
  private infoClient;
303
323
  private config;
@@ -305,6 +325,7 @@ declare class MetadataClient {
305
325
  private spotMeta;
306
326
  private perpsMeta;
307
327
  private perpDexs;
328
+ private staticMeta;
308
329
  private hip3DexsMeta;
309
330
  private perpsSymbolToIndex;
310
331
  private spotTokenNameToIndex;
@@ -320,6 +341,11 @@ declare class MetadataClient {
320
341
  * Initialize metadata by fetching from Hyperliquid
321
342
  */
322
343
  initialize(): Promise<void>;
344
+ /**
345
+ * Load staticMeta.json for display overrides
346
+ * This is always loaded regardless of config.useStaticFallback
347
+ */
348
+ private loadStaticMetaOverrides;
323
349
  /**
324
350
  * Load static metadata from bundled JSON files
325
351
  */
@@ -459,4 +485,4 @@ declare const formatSizeForOrder: ({ sz, szDecimals, }: {
459
485
  */
460
486
  declare function getPriceDecimals(price: number, szDecimals: number, isSpot: boolean): number;
461
487
 
462
- export { type AirdropAllocationData, CloidClientCode, type CloidClientCodeId, CloidClientCodeNameById, type CloidData, type DexInfo, type ExtendedPerpsMeta, type MarketInfo, MetadataClient, PUP_TOKEN_ADDRESS, PUP_TOKEN_THRESHOLDS, type PupEligibilityResult, TARGET_APPROVED_MAX_BUILDER_FEE, TARGET_APPROVED_MAX_BUILDER_FEE_PERCENT, TESTNET_USDC_SPOT_TOKEN, type TokenInfo, USDC_SPOT_TOKEN, type UpheavalApiResponse, type UpheavalPosition, type UpheavalSnapshot, type V3LPTokenInfo, WidgetType, WidgetTypeById, type WidgetTypeId, XP_BOOST_PERCENTAGES, buildCloid, calculateBoostPercentage, calculateTotalPupAmount, decodeSlug, encodeSlug, formatPriceAndSize, formatPriceForOrder, formatSizeForOrder, getApprovalAmount, getClientCodeNameById, getCloid, getNextTierInfo, getPriceDecimals, getWidgetTypeById, isBasedCloid, isClientCode, isMiniAppCloid, isMiniAppTriggeredCloid, isTenantCloid, isTrackingIdCloid, isWidgetType, normaliseSlug, normaliseTrackingId, normalizeAirdropAmount, parseCloid };
488
+ export { type AirdropAllocationData, CloidClientCode, type CloidClientCodeId, CloidClientCodeNameById, type CloidData, type DexInfo, type ExtendedPerpsMeta, type MarketInfo, MetadataClient, PUP_TOKEN_ADDRESS, PUP_TOKEN_THRESHOLDS, type PerpDex, type PupEligibilityResult, ROOT_DEX, TARGET_APPROVED_MAX_BUILDER_FEE, TARGET_APPROVED_MAX_BUILDER_FEE_PERCENT, TESTNET_USDC_SPOT_TOKEN, type TokenInfo, USDC_SPOT_TOKEN, type UpheavalApiResponse, type UpheavalPosition, type UpheavalSnapshot, type V3LPTokenInfo, WidgetType, WidgetTypeById, type WidgetTypeId, XP_BOOST_PERCENTAGES, buildCloid, calculateBoostPercentage, calculateTotalPupAmount, decodeSlug, encodeSlug, formatPriceAndSize, formatPriceForOrder, formatSizeForOrder, getApprovalAmount, getClientCodeNameById, getCloid, getNextTierInfo, getPriceDecimals, getWidgetTypeById, isBasedCloid, isClientCode, isMiniAppCloid, isMiniAppTriggeredCloid, isTenantCloid, isTrackingIdCloid, isWidgetType, normaliseSlug, normaliseTrackingId, normalizeAirdropAmount, parseCloid };
package/dist/index.js CHANGED
@@ -35,6 +35,44 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
35
35
  ));
36
36
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
37
 
38
+ // lib/meta/data/mainnet/staticMeta.json
39
+ var require_staticMeta = __commonJS({
40
+ "lib/meta/data/mainnet/staticMeta.json"(exports2, module2) {
41
+ module2.exports = {
42
+ coins: {
43
+ "xyz:XYZ100": {
44
+ imageUrl: "https://app.based.one/hip3/xyz/xyz100.webp",
45
+ displayName: "Nasdaq-100"
46
+ }
47
+ },
48
+ dexs: {
49
+ xyz: {
50
+ imageUrl: "",
51
+ displayName: "Stocks"
52
+ }
53
+ }
54
+ };
55
+ }
56
+ });
57
+
58
+ // lib/meta/data/testnet/staticMeta.json
59
+ var require_staticMeta2 = __commonJS({
60
+ "lib/meta/data/testnet/staticMeta.json"(exports2, module2) {
61
+ module2.exports = {
62
+ coins: {
63
+ "rrrrr:BTC": {
64
+ displayName: "BTCe"
65
+ }
66
+ },
67
+ dexs: {
68
+ rrrrr: {
69
+ displayName: "Hyena"
70
+ }
71
+ }
72
+ };
73
+ }
74
+ });
75
+
38
76
  // lib/meta/data/mainnet/spotMeta.json
39
77
  var require_spotMeta = __commonJS({
40
78
  "lib/meta/data/mainnet/spotMeta.json"(exports2, module2) {
@@ -36407,6 +36445,7 @@ __export(index_exports, {
36407
36445
  MetadataClient: () => MetadataClient,
36408
36446
  PUP_TOKEN_ADDRESS: () => PUP_TOKEN_ADDRESS,
36409
36447
  PUP_TOKEN_THRESHOLDS: () => PUP_TOKEN_THRESHOLDS,
36448
+ ROOT_DEX: () => ROOT_DEX,
36410
36449
  TARGET_APPROVED_MAX_BUILDER_FEE: () => TARGET_APPROVED_MAX_BUILDER_FEE,
36411
36450
  TARGET_APPROVED_MAX_BUILDER_FEE_PERCENT: () => TARGET_APPROVED_MAX_BUILDER_FEE_PERCENT,
36412
36451
  TESTNET_USDC_SPOT_TOKEN: () => TESTNET_USDC_SPOT_TOKEN,
@@ -36979,6 +37018,12 @@ function isHip3Symbol(symbol) {
36979
37018
  return symbol.includes(":");
36980
37019
  }
36981
37020
 
37021
+ // import("./data/**/*/staticMeta.json") in lib/meta/metadata.ts
37022
+ var globImport_data_staticMeta_json = __glob({
37023
+ "./data/mainnet/staticMeta.json": () => Promise.resolve().then(() => __toESM(require_staticMeta())),
37024
+ "./data/testnet/staticMeta.json": () => Promise.resolve().then(() => __toESM(require_staticMeta2()))
37025
+ });
37026
+
36982
37027
  // import("./data/**/*/spotMeta.json") in lib/meta/metadata.ts
36983
37028
  var globImport_data_spotMeta_json = __glob({
36984
37029
  "./data/mainnet/spotMeta.json": () => Promise.resolve().then(() => __toESM(require_spotMeta())),
@@ -36998,12 +37043,14 @@ var globImport_data_perpDexs_json = __glob({
36998
37043
  });
36999
37044
 
37000
37045
  // lib/meta/metadata.ts
37046
+ var ROOT_DEX = "hyperliquid";
37001
37047
  var MetadataClient = class {
37002
37048
  constructor(config = {}) {
37003
37049
  // Core metadata
37004
37050
  this.spotMeta = null;
37005
37051
  this.perpsMeta = null;
37006
37052
  this.perpDexs = [];
37053
+ this.staticMeta = null;
37007
37054
  // HIP-3 metadata cache
37008
37055
  this.hip3DexsMeta = /* @__PURE__ */ new Map();
37009
37056
  // Pre-computed lookup maps (populated on initialize)
@@ -37028,6 +37075,7 @@ var MetadataClient = class {
37028
37075
  this.infoClient = new import_hyperliquid.InfoClient({ transport });
37029
37076
  this.config = {
37030
37077
  ...config,
37078
+ hip3Dexs: config.hip3Dexs?.filter((dex) => dex !== ROOT_DEX),
37031
37079
  useStaticFallback: config.useStaticFallback ?? true
37032
37080
  };
37033
37081
  this.isTestnet = config.isTestnet ?? false;
@@ -37038,6 +37086,7 @@ var MetadataClient = class {
37038
37086
  */
37039
37087
  async initialize() {
37040
37088
  if (this.initialized) return;
37089
+ await this.loadStaticMetaOverrides();
37041
37090
  if (this.config.onlyUseStaticFallback) {
37042
37091
  await this.loadStaticMetadata();
37043
37092
  this.buildLookupMaps();
@@ -37076,20 +37125,41 @@ var MetadataClient = class {
37076
37125
  }
37077
37126
  }
37078
37127
  }
37128
+ /**
37129
+ * Load staticMeta.json for display overrides
37130
+ * This is always loaded regardless of config.useStaticFallback
37131
+ */
37132
+ async loadStaticMetaOverrides() {
37133
+ const network = this.isTestnet ? "testnet" : "mainnet";
37134
+ try {
37135
+ const staticMetaModule = await globImport_data_staticMeta_json(`./data/${network}/staticMeta.json`);
37136
+ this.staticMeta = staticMetaModule.default;
37137
+ } catch (error) {
37138
+ console.warn(`Failed to load staticMeta.json for ${network}:`, error);
37139
+ this.staticMeta = null;
37140
+ }
37141
+ }
37079
37142
  /**
37080
37143
  * Load static metadata from bundled JSON files
37081
37144
  */
37082
37145
  async loadStaticMetadata() {
37083
37146
  const network = this.isTestnet ? "testnet" : "mainnet";
37084
37147
  try {
37085
- const [spotMetaModule, perpsMetaModule, perpDexsModule] = await Promise.all([
37148
+ const [
37149
+ spotMetaModule,
37150
+ perpsMetaModule,
37151
+ perpDexsModule,
37152
+ staticMetaModule
37153
+ ] = await Promise.all([
37086
37154
  globImport_data_spotMeta_json(`./data/${network}/spotMeta.json`),
37087
37155
  globImport_data_meta_json(`./data/${network}/meta.json`),
37088
- globImport_data_perpDexs_json(`./data/${network}/perpDexs.json`)
37156
+ globImport_data_perpDexs_json(`./data/${network}/perpDexs.json`),
37157
+ globImport_data_staticMeta_json(`./data/${network}/staticMeta.json`)
37089
37158
  ]);
37090
37159
  this.spotMeta = spotMetaModule.default;
37091
37160
  this.perpsMeta = perpsMetaModule.default;
37092
37161
  this.perpDexs = perpDexsModule.default;
37162
+ this.staticMeta = staticMetaModule.default;
37093
37163
  console.warn(`Using static ${network} metadata`);
37094
37164
  } catch (error) {
37095
37165
  console.error(`Failed to load static ${network} metadata:`, error);
@@ -37126,6 +37196,15 @@ var MetadataClient = class {
37126
37196
  type: "perps",
37127
37197
  maxLeverage: market.maxLeverage
37128
37198
  };
37199
+ const staticOverrides = this.staticMeta?.coins?.[market.name];
37200
+ if (staticOverrides) {
37201
+ if (staticOverrides.displayName) {
37202
+ marketInfo.displayName = staticOverrides.displayName;
37203
+ }
37204
+ if (staticOverrides.imageUrl) {
37205
+ marketInfo.imageUrl = staticOverrides.imageUrl;
37206
+ }
37207
+ }
37129
37208
  this.perpsSymbolToIndex.set(market.name.toUpperCase(), index);
37130
37209
  this.coinToMarket.set(market.name, marketInfo);
37131
37210
  });
@@ -37150,6 +37229,15 @@ var MetadataClient = class {
37150
37229
  baseToken,
37151
37230
  quoteToken
37152
37231
  };
37232
+ const staticOverrides = this.staticMeta?.coins?.[coin];
37233
+ if (staticOverrides) {
37234
+ if (staticOverrides.displayName) {
37235
+ marketInfo.displayName = staticOverrides.displayName;
37236
+ }
37237
+ if (staticOverrides.imageUrl) {
37238
+ marketInfo.imageUrl = staticOverrides.imageUrl;
37239
+ }
37240
+ }
37153
37241
  const pairKey = `${baseToken.name}/${quoteToken.name}`.toUpperCase();
37154
37242
  this.spotPairToMarket.set(pairKey, marketInfo);
37155
37243
  this.coinToMarket.set(pairKey, marketInfo);
@@ -37189,10 +37277,19 @@ var MetadataClient = class {
37189
37277
  meta,
37190
37278
  assetContext: contexts,
37191
37279
  collateralTokenSymbol,
37192
- dexFullName: dex?.full_name ?? dexName,
37280
+ dexFullName: dex?.fullName ?? dexName,
37193
37281
  dexName: dex?.name ?? dexName,
37194
37282
  dexIndex
37195
37283
  };
37284
+ const staticDexOverrides = this.staticMeta?.dexs?.[dexName];
37285
+ if (staticDexOverrides) {
37286
+ if (staticDexOverrides.displayName) {
37287
+ dexInfo.displayName = staticDexOverrides.displayName;
37288
+ }
37289
+ if (staticDexOverrides.imageUrl) {
37290
+ dexInfo.imageUrl = staticDexOverrides.imageUrl;
37291
+ }
37292
+ }
37196
37293
  this.hip3DexsMeta.set(dexName, dexInfo);
37197
37294
  this.buildHip3MarketsForDex(dexName, dexInfo);
37198
37295
  return dexInfo;
@@ -37215,8 +37312,19 @@ var MetadataClient = class {
37215
37312
  type: "hip3",
37216
37313
  maxLeverage: market.maxLeverage,
37217
37314
  dexName,
37218
- dexIndex: dexInfo.dexIndex
37315
+ dexIndex: dexInfo.dexIndex,
37316
+ dexDisplayName: dexInfo.displayName,
37317
+ dexImageUrl: dexInfo.imageUrl
37219
37318
  };
37319
+ const staticOverrides = this.staticMeta?.coins?.[symbol];
37320
+ if (staticOverrides) {
37321
+ if (staticOverrides.displayName) {
37322
+ marketInfo.displayName = staticOverrides.displayName;
37323
+ }
37324
+ if (staticOverrides.imageUrl) {
37325
+ marketInfo.imageUrl = staticOverrides.imageUrl;
37326
+ }
37327
+ }
37220
37328
  this.coinToMarket.set(symbol, marketInfo);
37221
37329
  this.hip3SymbolToMarket.set(symbol, marketInfo);
37222
37330
  });
@@ -37245,7 +37353,7 @@ var MetadataClient = class {
37245
37353
  }
37246
37354
  let lookupKey = symbol.toUpperCase();
37247
37355
  if (!symbol.includes("/") && !symbol.includes("@")) {
37248
- const perpsMarket = this.coinToMarket.get(lookupKey);
37356
+ const perpsMarket = this.coinToMarket.get(symbol);
37249
37357
  if (perpsMarket?.type === "perps") {
37250
37358
  return perpsMarket;
37251
37359
  }
@@ -37430,6 +37538,7 @@ function getPriceDecimals(price, szDecimals, isSpot) {
37430
37538
  MetadataClient,
37431
37539
  PUP_TOKEN_ADDRESS,
37432
37540
  PUP_TOKEN_THRESHOLDS,
37541
+ ROOT_DEX,
37433
37542
  TARGET_APPROVED_MAX_BUILDER_FEE,
37434
37543
  TARGET_APPROVED_MAX_BUILDER_FEE_PERCENT,
37435
37544
  TESTNET_USDC_SPOT_TOKEN,
package/dist/index.mjs CHANGED
@@ -542,6 +542,12 @@ function isHip3Symbol(symbol) {
542
542
  return symbol.includes(":");
543
543
  }
544
544
 
545
+ // import("./data/**/*/staticMeta.json") in lib/meta/metadata.ts
546
+ var globImport_data_staticMeta_json = __glob({
547
+ "./data/mainnet/staticMeta.json": () => import("./staticMeta-HRXST42O.mjs"),
548
+ "./data/testnet/staticMeta.json": () => import("./staticMeta-QWPQK3MD.mjs")
549
+ });
550
+
545
551
  // import("./data/**/*/spotMeta.json") in lib/meta/metadata.ts
546
552
  var globImport_data_spotMeta_json = __glob({
547
553
  "./data/mainnet/spotMeta.json": () => import("./spotMeta-7IJT3W6H.mjs"),
@@ -561,12 +567,14 @@ var globImport_data_perpDexs_json = __glob({
561
567
  });
562
568
 
563
569
  // lib/meta/metadata.ts
570
+ var ROOT_DEX = "hyperliquid";
564
571
  var MetadataClient = class {
565
572
  constructor(config = {}) {
566
573
  // Core metadata
567
574
  this.spotMeta = null;
568
575
  this.perpsMeta = null;
569
576
  this.perpDexs = [];
577
+ this.staticMeta = null;
570
578
  // HIP-3 metadata cache
571
579
  this.hip3DexsMeta = /* @__PURE__ */ new Map();
572
580
  // Pre-computed lookup maps (populated on initialize)
@@ -591,6 +599,7 @@ var MetadataClient = class {
591
599
  this.infoClient = new InfoClient({ transport });
592
600
  this.config = {
593
601
  ...config,
602
+ hip3Dexs: config.hip3Dexs?.filter((dex) => dex !== ROOT_DEX),
594
603
  useStaticFallback: config.useStaticFallback ?? true
595
604
  };
596
605
  this.isTestnet = config.isTestnet ?? false;
@@ -601,6 +610,7 @@ var MetadataClient = class {
601
610
  */
602
611
  async initialize() {
603
612
  if (this.initialized) return;
613
+ await this.loadStaticMetaOverrides();
604
614
  if (this.config.onlyUseStaticFallback) {
605
615
  await this.loadStaticMetadata();
606
616
  this.buildLookupMaps();
@@ -639,20 +649,41 @@ var MetadataClient = class {
639
649
  }
640
650
  }
641
651
  }
652
+ /**
653
+ * Load staticMeta.json for display overrides
654
+ * This is always loaded regardless of config.useStaticFallback
655
+ */
656
+ async loadStaticMetaOverrides() {
657
+ const network = this.isTestnet ? "testnet" : "mainnet";
658
+ try {
659
+ const staticMetaModule = await globImport_data_staticMeta_json(`./data/${network}/staticMeta.json`);
660
+ this.staticMeta = staticMetaModule.default;
661
+ } catch (error) {
662
+ console.warn(`Failed to load staticMeta.json for ${network}:`, error);
663
+ this.staticMeta = null;
664
+ }
665
+ }
642
666
  /**
643
667
  * Load static metadata from bundled JSON files
644
668
  */
645
669
  async loadStaticMetadata() {
646
670
  const network = this.isTestnet ? "testnet" : "mainnet";
647
671
  try {
648
- const [spotMetaModule, perpsMetaModule, perpDexsModule] = await Promise.all([
672
+ const [
673
+ spotMetaModule,
674
+ perpsMetaModule,
675
+ perpDexsModule,
676
+ staticMetaModule
677
+ ] = await Promise.all([
649
678
  globImport_data_spotMeta_json(`./data/${network}/spotMeta.json`),
650
679
  globImport_data_meta_json(`./data/${network}/meta.json`),
651
- globImport_data_perpDexs_json(`./data/${network}/perpDexs.json`)
680
+ globImport_data_perpDexs_json(`./data/${network}/perpDexs.json`),
681
+ globImport_data_staticMeta_json(`./data/${network}/staticMeta.json`)
652
682
  ]);
653
683
  this.spotMeta = spotMetaModule.default;
654
684
  this.perpsMeta = perpsMetaModule.default;
655
685
  this.perpDexs = perpDexsModule.default;
686
+ this.staticMeta = staticMetaModule.default;
656
687
  console.warn(`Using static ${network} metadata`);
657
688
  } catch (error) {
658
689
  console.error(`Failed to load static ${network} metadata:`, error);
@@ -689,6 +720,15 @@ var MetadataClient = class {
689
720
  type: "perps",
690
721
  maxLeverage: market.maxLeverage
691
722
  };
723
+ const staticOverrides = this.staticMeta?.coins?.[market.name];
724
+ if (staticOverrides) {
725
+ if (staticOverrides.displayName) {
726
+ marketInfo.displayName = staticOverrides.displayName;
727
+ }
728
+ if (staticOverrides.imageUrl) {
729
+ marketInfo.imageUrl = staticOverrides.imageUrl;
730
+ }
731
+ }
692
732
  this.perpsSymbolToIndex.set(market.name.toUpperCase(), index);
693
733
  this.coinToMarket.set(market.name, marketInfo);
694
734
  });
@@ -713,6 +753,15 @@ var MetadataClient = class {
713
753
  baseToken,
714
754
  quoteToken
715
755
  };
756
+ const staticOverrides = this.staticMeta?.coins?.[coin];
757
+ if (staticOverrides) {
758
+ if (staticOverrides.displayName) {
759
+ marketInfo.displayName = staticOverrides.displayName;
760
+ }
761
+ if (staticOverrides.imageUrl) {
762
+ marketInfo.imageUrl = staticOverrides.imageUrl;
763
+ }
764
+ }
716
765
  const pairKey = `${baseToken.name}/${quoteToken.name}`.toUpperCase();
717
766
  this.spotPairToMarket.set(pairKey, marketInfo);
718
767
  this.coinToMarket.set(pairKey, marketInfo);
@@ -752,10 +801,19 @@ var MetadataClient = class {
752
801
  meta,
753
802
  assetContext: contexts,
754
803
  collateralTokenSymbol,
755
- dexFullName: dex?.full_name ?? dexName,
804
+ dexFullName: dex?.fullName ?? dexName,
756
805
  dexName: dex?.name ?? dexName,
757
806
  dexIndex
758
807
  };
808
+ const staticDexOverrides = this.staticMeta?.dexs?.[dexName];
809
+ if (staticDexOverrides) {
810
+ if (staticDexOverrides.displayName) {
811
+ dexInfo.displayName = staticDexOverrides.displayName;
812
+ }
813
+ if (staticDexOverrides.imageUrl) {
814
+ dexInfo.imageUrl = staticDexOverrides.imageUrl;
815
+ }
816
+ }
759
817
  this.hip3DexsMeta.set(dexName, dexInfo);
760
818
  this.buildHip3MarketsForDex(dexName, dexInfo);
761
819
  return dexInfo;
@@ -778,8 +836,19 @@ var MetadataClient = class {
778
836
  type: "hip3",
779
837
  maxLeverage: market.maxLeverage,
780
838
  dexName,
781
- dexIndex: dexInfo.dexIndex
839
+ dexIndex: dexInfo.dexIndex,
840
+ dexDisplayName: dexInfo.displayName,
841
+ dexImageUrl: dexInfo.imageUrl
782
842
  };
843
+ const staticOverrides = this.staticMeta?.coins?.[symbol];
844
+ if (staticOverrides) {
845
+ if (staticOverrides.displayName) {
846
+ marketInfo.displayName = staticOverrides.displayName;
847
+ }
848
+ if (staticOverrides.imageUrl) {
849
+ marketInfo.imageUrl = staticOverrides.imageUrl;
850
+ }
851
+ }
783
852
  this.coinToMarket.set(symbol, marketInfo);
784
853
  this.hip3SymbolToMarket.set(symbol, marketInfo);
785
854
  });
@@ -808,7 +877,7 @@ var MetadataClient = class {
808
877
  }
809
878
  let lookupKey = symbol.toUpperCase();
810
879
  if (!symbol.includes("/") && !symbol.includes("@")) {
811
- const perpsMarket = this.coinToMarket.get(lookupKey);
880
+ const perpsMarket = this.coinToMarket.get(symbol);
812
881
  if (perpsMarket?.type === "perps") {
813
882
  return perpsMarket;
814
883
  }
@@ -992,6 +1061,7 @@ export {
992
1061
  MetadataClient,
993
1062
  PUP_TOKEN_ADDRESS,
994
1063
  PUP_TOKEN_THRESHOLDS,
1064
+ ROOT_DEX,
995
1065
  TARGET_APPROVED_MAX_BUILDER_FEE,
996
1066
  TARGET_APPROVED_MAX_BUILDER_FEE_PERCENT,
997
1067
  TESTNET_USDC_SPOT_TOKEN,
@@ -0,0 +1,24 @@
1
+ import "./chunk-4UEJOM6W.mjs";
2
+
3
+ // lib/meta/data/mainnet/staticMeta.json
4
+ var coins = {
5
+ "xyz:XYZ100": {
6
+ imageUrl: "https://app.based.one/hip3/xyz/xyz100.webp",
7
+ displayName: "Nasdaq-100"
8
+ }
9
+ };
10
+ var dexs = {
11
+ xyz: {
12
+ imageUrl: "",
13
+ displayName: "Stocks"
14
+ }
15
+ };
16
+ var staticMeta_default = {
17
+ coins,
18
+ dexs
19
+ };
20
+ export {
21
+ coins,
22
+ staticMeta_default as default,
23
+ dexs
24
+ };
@@ -0,0 +1,22 @@
1
+ import "./chunk-4UEJOM6W.mjs";
2
+
3
+ // lib/meta/data/testnet/staticMeta.json
4
+ var coins = {
5
+ "rrrrr:BTC": {
6
+ displayName: "BTCe"
7
+ }
8
+ };
9
+ var dexs = {
10
+ rrrrr: {
11
+ displayName: "Hyena"
12
+ }
13
+ };
14
+ var staticMeta_default = {
15
+ coins,
16
+ dexs
17
+ };
18
+ export {
19
+ coins,
20
+ staticMeta_default as default,
21
+ dexs
22
+ };
@@ -0,0 +1,26 @@
1
+ {
2
+ "universe": [
3
+ {
4
+ "szDecimals": 4,
5
+ "name": "xyz:XYZ100",
6
+ "maxLeverage": 20,
7
+ "marginTableId": 20,
8
+ "onlyIsolated": true
9
+ }
10
+ ],
11
+ "marginTables": [
12
+ [
13
+ 50,
14
+ {
15
+ "description": "",
16
+ "marginTiers": [
17
+ {
18
+ "lowerBound": "0.0",
19
+ "maxLeverage": 50
20
+ }
21
+ ]
22
+ }
23
+ ]
24
+ ],
25
+ "collateralToken": 0
26
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "coins": {
3
+ "xyz:XYZ100": {
4
+ "imageUrl": "https://app.based.one/hip3/xyz/xyz100.webp",
5
+ "displayName": "Nasdaq-100"
6
+ }
7
+ },
8
+ "dexs": {
9
+ "xyz": {
10
+ "imageUrl": "",
11
+ "displayName": "Stocks"
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "coins": {
3
+ "rrrrr:BTC": {
4
+ "displayName": "BTCe"
5
+ }
6
+ },
7
+ "dexs": {
8
+ "rrrrr": {
9
+ "displayName": "Hyena"
10
+ }
11
+ }
12
+ }
@@ -1,13 +1,27 @@
1
1
  import {
2
2
  HttpTransport,
3
3
  InfoClient,
4
- PerpDex,
5
4
  PerpsAssetCtx,
6
5
  PerpsMeta,
7
6
  SpotMeta,
8
7
  SpotToken,
9
8
  } from "@nktkas/hyperliquid";
10
9
  import { isHip3Symbol } from "../hip3/utils";
10
+ import { Hex } from "@nktkas/hyperliquid/script/src/types/mod";
11
+
12
+ export interface PerpDex {
13
+ /** Short name of the perpetual dex. */
14
+ name: string;
15
+ /** Complete name of the perpetual dex. */
16
+ fullName: string;
17
+ /** Hex address of the dex deployer. */
18
+ deployer: Hex;
19
+ /** Hex address of the oracle updater, or null if not available. */
20
+ oracleUpdater: Hex | null;
21
+
22
+ feeRecipient: Hex | null;
23
+ assetToStreamingOiCap: [string, string][];
24
+ }
11
25
 
12
26
  /**
13
27
  * Market information for trading operations
@@ -19,6 +33,9 @@ export interface MarketInfo {
19
33
  type: "perps" | "spot" | "hip3";
20
34
  coin: string; // Format used in info endpoint (e.g., "@107") for spot hype, "HYPE" for perps, "dex:coin" for hip3
21
35
 
36
+ displayName?: string; // Display name for the market
37
+ imageUrl?: string; // Image URL for the market
38
+
22
39
  maxLeverage?: number; // For perps only
23
40
 
24
41
  // Spot-specific fields
@@ -28,6 +45,8 @@ export interface MarketInfo {
28
45
  // HIP-3 specific fields
29
46
  dexName?: string; // DEX name for HIP-3 markets
30
47
  dexIndex?: number; // DEX index for asset ID calculation
48
+ dexDisplayName?: string; // Display name override for the DEX
49
+ dexImageUrl?: string; // Image URL override for the DEX
31
50
  }
32
51
 
33
52
  export interface DexInfo {
@@ -37,6 +56,8 @@ export interface DexInfo {
37
56
  dexName: string; // DEX name for HIP-3 markets
38
57
  dexIndex: number; // DEX index for asset ID calculation
39
58
  collateralTokenSymbol: string;
59
+ displayName?: string; // Display name override for the DEX
60
+ imageUrl?: string; // Image URL override for the DEX
40
61
  }
41
62
 
42
63
  export type ExtendedPerpsMeta = PerpsMeta & {
@@ -54,6 +75,24 @@ export interface TokenInfo {
54
75
  tokenId: string;
55
76
  }
56
77
 
78
+ /**
79
+ * Static metadata structure for display overrides
80
+ */
81
+ interface StaticMetadata {
82
+ coins?: {
83
+ [symbol: string]: {
84
+ displayName?: string;
85
+ imageUrl?: string;
86
+ };
87
+ };
88
+ dexs?: {
89
+ [dexName: string]: {
90
+ displayName?: string;
91
+ imageUrl?: string;
92
+ };
93
+ };
94
+ }
95
+
57
96
  /**
58
97
  * Configuration for MetadataClient
59
98
  */
@@ -84,6 +123,8 @@ interface MetadataClientConfig {
84
123
  * - Spot: 10000 + index
85
124
  * - HIP-3: 100000 + perp_dex_index * 10000 + index_in_meta
86
125
  */
126
+ export const ROOT_DEX = "hyperliquid";
127
+
87
128
  export class MetadataClient {
88
129
  private infoClient: InfoClient;
89
130
  private config: MetadataClientConfig;
@@ -93,6 +134,7 @@ export class MetadataClient {
93
134
  private spotMeta: SpotMeta | null = null;
94
135
  private perpsMeta: PerpsMeta | null = null;
95
136
  private perpDexs: (PerpDex | null)[] = [];
137
+ private staticMeta: StaticMetadata | null = null;
96
138
 
97
139
  // HIP-3 metadata cache
98
140
  private hip3DexsMeta: Map<string, DexInfo> = new Map();
@@ -124,6 +166,7 @@ export class MetadataClient {
124
166
  this.infoClient = new InfoClient({ transport });
125
167
  this.config = {
126
168
  ...config,
169
+ hip3Dexs: config.hip3Dexs?.filter((dex) => dex !== ROOT_DEX),
127
170
  useStaticFallback: config.useStaticFallback ?? true,
128
171
  };
129
172
  this.isTestnet = config.isTestnet ?? false;
@@ -136,6 +179,9 @@ export class MetadataClient {
136
179
  async initialize(): Promise<void> {
137
180
  if (this.initialized) return;
138
181
 
182
+ // Always load staticMeta.json regardless of config.useStaticFallback
183
+ await this.loadStaticMetaOverrides();
184
+
139
185
  if (this.config.onlyUseStaticFallback) {
140
186
  await this.loadStaticMetadata();
141
187
  this.buildLookupMaps();
@@ -156,7 +202,7 @@ export class MetadataClient {
156
202
  [this.spotMeta, this.perpsMeta, this.perpDexs] = await Promise.all([
157
203
  this.infoClient.spotMeta(),
158
204
  this.infoClient.meta(),
159
- this.infoClient.perpDexs(),
205
+ this.infoClient.perpDexs() as Promise<PerpDex[] | null[]>,
160
206
  ]);
161
207
 
162
208
  // Build optimized lookup maps
@@ -186,6 +232,24 @@ export class MetadataClient {
186
232
  }
187
233
  }
188
234
 
235
+ /**
236
+ * Load staticMeta.json for display overrides
237
+ * This is always loaded regardless of config.useStaticFallback
238
+ */
239
+ private async loadStaticMetaOverrides(): Promise<void> {
240
+ const network = this.isTestnet ? "testnet" : "mainnet";
241
+
242
+ try {
243
+ const staticMetaModule = await import(
244
+ `./data/${network}/staticMeta.json`
245
+ );
246
+ this.staticMeta = staticMetaModule.default as StaticMetadata;
247
+ } catch (error) {
248
+ console.warn(`Failed to load staticMeta.json for ${network}:`, error);
249
+ this.staticMeta = null;
250
+ }
251
+ }
252
+
189
253
  /**
190
254
  * Load static metadata from bundled JSON files
191
255
  */
@@ -194,16 +258,22 @@ export class MetadataClient {
194
258
 
195
259
  try {
196
260
  // Dynamic imports for static data
197
- const [spotMetaModule, perpsMetaModule, perpDexsModule] =
198
- await Promise.all([
199
- import(`./data/${network}/spotMeta.json`),
200
- import(`./data/${network}/meta.json`),
201
- import(`./data/${network}/perpDexs.json`),
202
- ]);
261
+ const [
262
+ spotMetaModule,
263
+ perpsMetaModule,
264
+ perpDexsModule,
265
+ staticMetaModule,
266
+ ] = await Promise.all([
267
+ import(`./data/${network}/spotMeta.json`),
268
+ import(`./data/${network}/meta.json`),
269
+ import(`./data/${network}/perpDexs.json`),
270
+ import(`./data/${network}/staticMeta.json`),
271
+ ]);
203
272
 
204
273
  this.spotMeta = spotMetaModule.default as SpotMeta;
205
274
  this.perpsMeta = perpsMetaModule.default as PerpsMeta;
206
275
  this.perpDexs = perpDexsModule.default as (PerpDex | null)[];
276
+ this.staticMeta = staticMetaModule.default as StaticMetadata;
207
277
 
208
278
  console.warn(`Using static ${network} metadata`);
209
279
  } catch (error) {
@@ -248,6 +318,17 @@ export class MetadataClient {
248
318
  maxLeverage: market.maxLeverage,
249
319
  };
250
320
 
321
+ // Apply static metadata overrides for perps
322
+ const staticOverrides = this.staticMeta?.coins?.[market.name];
323
+ if (staticOverrides) {
324
+ if (staticOverrides.displayName) {
325
+ marketInfo.displayName = staticOverrides.displayName;
326
+ }
327
+ if (staticOverrides.imageUrl) {
328
+ marketInfo.imageUrl = staticOverrides.imageUrl;
329
+ }
330
+ }
331
+
251
332
  // Case-insensitive lookup
252
333
  this.perpsSymbolToIndex.set(market.name.toUpperCase(), index);
253
334
 
@@ -288,6 +369,17 @@ export class MetadataClient {
288
369
  quoteToken: quoteToken,
289
370
  };
290
371
 
372
+ // Apply static metadata overrides for spot
373
+ const staticOverrides = this.staticMeta?.coins?.[coin];
374
+ if (staticOverrides) {
375
+ if (staticOverrides.displayName) {
376
+ marketInfo.displayName = staticOverrides.displayName;
377
+ }
378
+ if (staticOverrides.imageUrl) {
379
+ marketInfo.imageUrl = staticOverrides.imageUrl;
380
+ }
381
+ }
382
+
291
383
  // Store by full pair (case-insensitive)
292
384
  const pairKey = `${baseToken.name}/${quoteToken.name}`.toUpperCase();
293
385
  this.spotPairToMarket.set(pairKey, marketInfo);
@@ -347,15 +439,26 @@ export class MetadataClient {
347
439
  const collateralTokenSymbol =
348
440
  spotMetaTokens?.[collateralTokenIndex]?.name ?? "USDC";
349
441
 
350
- const dexInfo = {
442
+ const dexInfo: DexInfo = {
351
443
  meta,
352
444
  assetContext: contexts,
353
445
  collateralTokenSymbol,
354
- dexFullName: dex?.full_name ?? dexName,
446
+ dexFullName: dex?.fullName ?? dexName,
355
447
  dexName: dex?.name ?? dexName,
356
448
  dexIndex: dexIndex,
357
449
  };
358
450
 
451
+ // Apply static metadata overrides for DEX
452
+ const staticDexOverrides = this.staticMeta?.dexs?.[dexName];
453
+ if (staticDexOverrides) {
454
+ if (staticDexOverrides.displayName) {
455
+ dexInfo.displayName = staticDexOverrides.displayName;
456
+ }
457
+ if (staticDexOverrides.imageUrl) {
458
+ dexInfo.imageUrl = staticDexOverrides.imageUrl;
459
+ }
460
+ }
461
+
359
462
  this.hip3DexsMeta.set(dexName, dexInfo);
360
463
 
361
464
  // Build HIP-3 market lookups for this DEX
@@ -374,6 +477,7 @@ export class MetadataClient {
374
477
  private buildHip3MarketsForDex(dexName: string, dexInfo: DexInfo): void {
375
478
  dexInfo.meta.universe.forEach((market, index) => {
376
479
  const symbol = market.name;
480
+
377
481
  const marketInfo: MarketInfo = {
378
482
  coin: symbol,
379
483
  symbol,
@@ -383,8 +487,21 @@ export class MetadataClient {
383
487
  maxLeverage: market.maxLeverage,
384
488
  dexName,
385
489
  dexIndex: dexInfo.dexIndex,
490
+ dexDisplayName: dexInfo.displayName,
491
+ dexImageUrl: dexInfo.imageUrl,
386
492
  };
387
493
 
494
+ // Apply static metadata overrides for HIP-3
495
+ const staticOverrides = this.staticMeta?.coins?.[symbol];
496
+ if (staticOverrides) {
497
+ if (staticOverrides.displayName) {
498
+ marketInfo.displayName = staticOverrides.displayName;
499
+ }
500
+ if (staticOverrides.imageUrl) {
501
+ marketInfo.imageUrl = staticOverrides.imageUrl;
502
+ }
503
+ }
504
+
388
505
  this.coinToMarket.set(symbol, marketInfo);
389
506
  this.hip3SymbolToMarket.set(symbol, marketInfo);
390
507
  });
@@ -425,7 +542,7 @@ export class MetadataClient {
425
542
  // If no "/" in symbol, it could be perps or need quote asset
426
543
  if (!symbol.includes("/") && !symbol.includes("@")) {
427
544
  // Try perps lookup first (O(1))
428
- const perpsMarket = this.coinToMarket.get(lookupKey);
545
+ const perpsMarket = this.coinToMarket.get(symbol);
429
546
  if (perpsMarket?.type === "perps") {
430
547
  return perpsMarket;
431
548
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basedone/core",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "Core utilities for Based One",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",