@hyperix/hooks 0.1.23 → 0.1.24
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.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/use-spot-markets.d.ts +29 -0
- package/dist/use-spot-markets.js +61 -0
- package/dist/use-spot-meta-and-asset-ctxs.d.ts +5 -0
- package/dist/use-spot-meta-and-asset-ctxs.js +9 -0
- package/dist/use-spot-state.d.ts +13 -0
- package/dist/use-spot-state.js +27 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -17,7 +17,10 @@ export * from "./use-perp-meta.js";
|
|
|
17
17
|
export * from "./use-portfolio.js";
|
|
18
18
|
export * from "./use-positions.js";
|
|
19
19
|
export * from "./use-spot-asset-ctxs.js";
|
|
20
|
+
export * from "./use-spot-markets.js";
|
|
21
|
+
export * from "./use-spot-meta-and-asset-ctxs.js";
|
|
20
22
|
export * from "./use-spot-meta.js";
|
|
23
|
+
export * from "./use-spot-state.js";
|
|
21
24
|
export * from "./use-symbol-converter.js";
|
|
22
25
|
export * from "./use-twap-states.js";
|
|
23
26
|
export * from "./use-user-fundings.js";
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,10 @@ export * from "./use-perp-meta.js";
|
|
|
17
17
|
export * from "./use-portfolio.js";
|
|
18
18
|
export * from "./use-positions.js";
|
|
19
19
|
export * from "./use-spot-asset-ctxs.js";
|
|
20
|
+
export * from "./use-spot-markets.js";
|
|
21
|
+
export * from "./use-spot-meta-and-asset-ctxs.js";
|
|
20
22
|
export * from "./use-spot-meta.js";
|
|
23
|
+
export * from "./use-spot-state.js";
|
|
21
24
|
export * from "./use-symbol-converter.js";
|
|
22
25
|
export * from "./use-twap-states.js";
|
|
23
26
|
export * from "./use-user-fundings.js";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type SpotMarket = {
|
|
2
|
+
symbol: string;
|
|
3
|
+
pairId: string;
|
|
4
|
+
baseToken: string;
|
|
5
|
+
quoteToken: string;
|
|
6
|
+
baseTokenFullName: string | null;
|
|
7
|
+
quoteTokenFullName: string | null;
|
|
8
|
+
universeIndex: number;
|
|
9
|
+
szDecimals: number;
|
|
10
|
+
weiDecimals: number;
|
|
11
|
+
tokenId: string;
|
|
12
|
+
isCanonical: boolean;
|
|
13
|
+
markPrice: number;
|
|
14
|
+
midPrice: number | null;
|
|
15
|
+
prevDayPrice: number;
|
|
16
|
+
volume24h: number;
|
|
17
|
+
baseVolume24h: number;
|
|
18
|
+
circulatingSupply: number;
|
|
19
|
+
totalSupply: number;
|
|
20
|
+
};
|
|
21
|
+
export type UseSpotMarketsOptions = {
|
|
22
|
+
enabled?: boolean;
|
|
23
|
+
};
|
|
24
|
+
export declare function useSpotMarkets(options?: UseSpotMarketsOptions): {
|
|
25
|
+
data: SpotMarket[];
|
|
26
|
+
loading: boolean;
|
|
27
|
+
ready: boolean;
|
|
28
|
+
error: string | undefined;
|
|
29
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { useSpotAssetCtxs } from "./use-spot-asset-ctxs.js";
|
|
3
|
+
import { useSpotMeta } from "./use-spot-meta.js";
|
|
4
|
+
function toNumber(value) {
|
|
5
|
+
const numericValue = Number(value);
|
|
6
|
+
return Number.isFinite(numericValue) ? numericValue : 0;
|
|
7
|
+
}
|
|
8
|
+
function toOptionalNumber(value) {
|
|
9
|
+
if (value === null || value === undefined) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
const numericValue = Number(value);
|
|
13
|
+
return Number.isFinite(numericValue) ? numericValue : null;
|
|
14
|
+
}
|
|
15
|
+
function buildCtxMap(data) {
|
|
16
|
+
return new Map((data ?? []).map((ctx) => [ctx.coin, ctx]));
|
|
17
|
+
}
|
|
18
|
+
export function useSpotMarkets(options = {}) {
|
|
19
|
+
const { enabled = true } = options;
|
|
20
|
+
const spotMetaState = useSpotMeta({ enabled });
|
|
21
|
+
const assetCtxsState = useSpotAssetCtxs({ enabled });
|
|
22
|
+
const markets = useMemo(() => {
|
|
23
|
+
const spotMeta = spotMetaState.data;
|
|
24
|
+
const assetCtxsByPairId = buildCtxMap(assetCtxsState.data);
|
|
25
|
+
if (!spotMeta) {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
const tokenByIndex = new Map(spotMeta.tokens.map((token) => [token.index, token]));
|
|
29
|
+
return spotMeta.universe.map((market) => {
|
|
30
|
+
const baseToken = tokenByIndex.get(market.tokens[0]);
|
|
31
|
+
const quoteToken = tokenByIndex.get(market.tokens[1]);
|
|
32
|
+
const ctx = assetCtxsByPairId.get(market.name);
|
|
33
|
+
return {
|
|
34
|
+
symbol: baseToken && quoteToken ? `${baseToken.name}/${quoteToken.name}` : market.name,
|
|
35
|
+
pairId: market.name,
|
|
36
|
+
baseToken: baseToken?.name ?? "",
|
|
37
|
+
quoteToken: quoteToken?.name ?? "",
|
|
38
|
+
baseTokenFullName: baseToken?.fullName ?? null,
|
|
39
|
+
quoteTokenFullName: quoteToken?.fullName ?? null,
|
|
40
|
+
universeIndex: market.index,
|
|
41
|
+
szDecimals: baseToken?.szDecimals ?? 0,
|
|
42
|
+
weiDecimals: baseToken?.weiDecimals ?? 0,
|
|
43
|
+
tokenId: baseToken?.tokenId ?? "",
|
|
44
|
+
isCanonical: market.isCanonical ?? false,
|
|
45
|
+
markPrice: toNumber(ctx?.markPx),
|
|
46
|
+
midPrice: toOptionalNumber(ctx?.midPx),
|
|
47
|
+
prevDayPrice: toNumber(ctx?.prevDayPx),
|
|
48
|
+
volume24h: toNumber(ctx?.dayNtlVlm),
|
|
49
|
+
baseVolume24h: toNumber(ctx?.dayBaseVlm),
|
|
50
|
+
circulatingSupply: toNumber(ctx?.circulatingSupply),
|
|
51
|
+
totalSupply: toNumber(ctx?.totalSupply),
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
}, [assetCtxsState.data, spotMetaState.data]);
|
|
55
|
+
return {
|
|
56
|
+
data: markets,
|
|
57
|
+
loading: spotMetaState.isLoading || assetCtxsState.loading,
|
|
58
|
+
ready: spotMetaState.isSuccess && assetCtxsState.ready,
|
|
59
|
+
error: spotMetaState.error?.message ?? assetCtxsState.error,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type UseQueryOptions, type UseQueryResult } from "@tanstack/react-query";
|
|
2
|
+
import type { SpotMetaAndAssetCtxsResponse } from "@nktkas/hyperliquid/api/info";
|
|
3
|
+
export type SpotMetaAndAssetCtxsData = SpotMetaAndAssetCtxsResponse;
|
|
4
|
+
export type UseSpotMetaAndAssetCtxsOptions = Omit<UseQueryOptions<SpotMetaAndAssetCtxsData, Error, SpotMetaAndAssetCtxsData, ["spot-meta-and-asset-ctxs"]>, "queryKey" | "queryFn">;
|
|
5
|
+
export declare function useSpotMetaAndAssetCtxs(options?: UseSpotMetaAndAssetCtxsOptions): UseQueryResult<SpotMetaAndAssetCtxsData, Error>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { useQuery } from "@tanstack/react-query";
|
|
2
|
+
import { infoClient } from "./config/hl.js";
|
|
3
|
+
export function useSpotMetaAndAssetCtxs(options = {}) {
|
|
4
|
+
return useQuery({
|
|
5
|
+
queryKey: ["spot-meta-and-asset-ctxs"],
|
|
6
|
+
queryFn: () => infoClient.spotMetaAndAssetCtxs(),
|
|
7
|
+
...options,
|
|
8
|
+
});
|
|
9
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type UseSubscribeState } from "@outofgas/react-stream";
|
|
2
|
+
import type { SpotStateEvent } from "@nktkas/hyperliquid/api/subscription";
|
|
3
|
+
export type SpotBalance = SpotStateEvent["spotState"]["balances"][number];
|
|
4
|
+
export type SpotEscrow = NonNullable<SpotStateEvent["spotState"]["evmEscrows"]>[number];
|
|
5
|
+
export type SpotStateData = SpotStateEvent["spotState"] & {
|
|
6
|
+
user: `0x${string}`;
|
|
7
|
+
};
|
|
8
|
+
export type UseSpotStateOptions = {
|
|
9
|
+
enabled?: boolean;
|
|
10
|
+
ignorePortfolioMargin?: boolean;
|
|
11
|
+
onUpdate?: (event: SpotStateEvent) => void;
|
|
12
|
+
};
|
|
13
|
+
export declare function useSpotState(user: `0x${string}`, options?: UseSpotStateOptions): UseSubscribeState<SpotStateData>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useSubscribe } from "@outofgas/react-stream";
|
|
2
|
+
import { wsClient } from "./config/hl.js";
|
|
3
|
+
export function useSpotState(user, options = {}) {
|
|
4
|
+
const { enabled: enabledOverride, ignorePortfolioMargin, onUpdate } = options;
|
|
5
|
+
const enabled = enabledOverride ?? Boolean(user);
|
|
6
|
+
return useSubscribe({
|
|
7
|
+
key: ["spot-state", user, ignorePortfolioMargin ? "ignore-pm" : "default"],
|
|
8
|
+
enabled,
|
|
9
|
+
subscribe: async ({ onData, onError }) => {
|
|
10
|
+
const subscription = await wsClient.spotState({ user, ignorePortfolioMargin }, (event) => {
|
|
11
|
+
try {
|
|
12
|
+
onUpdate?.(event);
|
|
13
|
+
onData({
|
|
14
|
+
user: event.user,
|
|
15
|
+
...event.spotState,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
onError(error instanceof Error ? error : new Error("Failed to process spot state event"));
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
return {
|
|
23
|
+
unsubscribe: () => subscription.unsubscribe(),
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|