@basedone/core 0.1.8 → 0.2.0

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.
Files changed (59) hide show
  1. package/dist/chunk-4GAKANLT.mjs +1987 -0
  2. package/dist/chunk-4UEJOM6W.mjs +1 -3
  3. package/dist/chunk-VBC6EQ7Q.mjs +235 -0
  4. package/dist/client-CgmiTuEX.d.mts +179 -0
  5. package/dist/client-CgmiTuEX.d.ts +179 -0
  6. package/dist/ecommerce.d.mts +3732 -0
  7. package/dist/ecommerce.d.ts +3732 -0
  8. package/dist/ecommerce.js +2031 -0
  9. package/dist/ecommerce.mjs +2 -0
  10. package/dist/index.d.mts +79 -4
  11. package/dist/index.d.ts +79 -4
  12. package/dist/index.js +3674 -331
  13. package/dist/index.mjs +107 -104
  14. package/dist/{meta-57AY44US.mjs → meta-JB5ITE27.mjs} +6 -14
  15. package/dist/{meta-RSZFFH63.mjs → meta-UOGUG3OW.mjs} +5 -11
  16. package/dist/{perpDexs-PBKWKKQU.mjs → perpDexs-3LRJ5ZHM.mjs} +100 -13
  17. package/dist/{perpDexs-XSB4Y2BP.mjs → perpDexs-4ISLD7NX.mjs} +798 -121
  18. package/dist/react.d.mts +39 -0
  19. package/dist/react.d.ts +39 -0
  20. package/dist/react.js +268 -0
  21. package/dist/react.mjs +31 -0
  22. package/dist/{spotMeta-WQ4PXRNY.mjs → spotMeta-GHXX7C5M.mjs} +85 -14
  23. package/dist/{spotMeta-Y7G2GI7B.mjs → spotMeta-IBBUP2SG.mjs} +249 -12
  24. package/dist/staticMeta-GM7T3OYL.mjs +3 -6
  25. package/dist/staticMeta-QV2KMX57.mjs +3 -6
  26. package/ecommerce.ts +15 -0
  27. package/index.ts +7 -0
  28. package/lib/cloid/cloid.ts +2 -0
  29. package/lib/ecommerce/QUICK_REFERENCE.md +211 -0
  30. package/lib/ecommerce/README.md +385 -0
  31. package/lib/ecommerce/USAGE_EXAMPLES.md +704 -0
  32. package/lib/ecommerce/client/base.ts +272 -0
  33. package/lib/ecommerce/client/customer.ts +522 -0
  34. package/lib/ecommerce/client/merchant.ts +1341 -0
  35. package/lib/ecommerce/index.ts +51 -0
  36. package/lib/ecommerce/types/entities.ts +722 -0
  37. package/lib/ecommerce/types/enums.ts +270 -0
  38. package/lib/ecommerce/types/index.ts +18 -0
  39. package/lib/ecommerce/types/requests.ts +525 -0
  40. package/lib/ecommerce/types/responses.ts +805 -0
  41. package/lib/ecommerce/utils/errors.ts +113 -0
  42. package/lib/ecommerce/utils/helpers.ts +131 -0
  43. package/lib/fee.ts +10 -10
  44. package/lib/hip3/market-info.ts +36 -8
  45. package/lib/hip3/utils.ts +15 -2
  46. package/lib/instrument/client.ts +351 -0
  47. package/lib/meta/data/mainnet/meta.json +2 -4
  48. package/lib/meta/data/mainnet/perpDexs.json +97 -9
  49. package/lib/meta/data/mainnet/spotMeta.json +82 -8
  50. package/lib/meta/data/testnet/meta.json +3 -7
  51. package/lib/meta/data/testnet/perpDexs.json +795 -117
  52. package/lib/meta/data/testnet/spotMeta.json +246 -6
  53. package/lib/meta/metadata.ts +8 -1
  54. package/lib/meta/types.ts +36 -0
  55. package/lib/react/InstrumentProvider.tsx +69 -0
  56. package/lib/utils/flooredDateTime.ts +55 -0
  57. package/lib/utils/time.ts +51 -0
  58. package/package.json +37 -11
  59. package/react.ts +1 -0
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Ecommerce API Error Utilities
3
+ *
4
+ * This module contains error handling utilities for the ecommerce API.
5
+ */
6
+
7
+ /**
8
+ * Ecommerce API error class
9
+ */
10
+ export class EcommerceApiError extends Error {
11
+ /** HTTP status code */
12
+ public statusCode?: number;
13
+
14
+ /** Response data */
15
+ public data?: any;
16
+
17
+ /** Is network error */
18
+ public isNetworkError: boolean;
19
+
20
+ /** Is timeout error */
21
+ public isTimeoutError: boolean;
22
+
23
+ /** Is authentication error */
24
+ public isAuthError: boolean;
25
+
26
+ constructor(
27
+ message: string,
28
+ statusCode?: number,
29
+ data?: any,
30
+ isNetworkError = false,
31
+ isTimeoutError = false
32
+ ) {
33
+ super(message);
34
+ this.name = "EcommerceApiError";
35
+ this.statusCode = statusCode;
36
+ this.data = data;
37
+ this.isNetworkError = isNetworkError;
38
+ this.isTimeoutError = isTimeoutError;
39
+ this.isAuthError = statusCode === 401 || statusCode === 403;
40
+
41
+ // Maintains proper stack trace for where our error was thrown (only available on V8)
42
+ if (Error.captureStackTrace) {
43
+ Error.captureStackTrace(this, EcommerceApiError);
44
+ }
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Parse error from axios error or API response
50
+ */
51
+ export function parseError(error: any): EcommerceApiError {
52
+ // Network error
53
+ if (error.code === "ECONNABORTED" || error.code === "ETIMEDOUT") {
54
+ return new EcommerceApiError(
55
+ "Request timeout",
56
+ undefined,
57
+ undefined,
58
+ false,
59
+ true
60
+ );
61
+ }
62
+
63
+ if (error.code === "ERR_NETWORK" || !error.response) {
64
+ return new EcommerceApiError(
65
+ error.message || "Network error",
66
+ undefined,
67
+ undefined,
68
+ true,
69
+ false
70
+ );
71
+ }
72
+
73
+ // API error
74
+ const response = error.response;
75
+ const statusCode = response?.status;
76
+ const data = response?.data;
77
+
78
+ const message =
79
+ data?.error ||
80
+ data?.message ||
81
+ error.message ||
82
+ `API error (${statusCode})`;
83
+
84
+ return new EcommerceApiError(message, statusCode, data);
85
+ }
86
+
87
+ /**
88
+ * Check if error is retryable
89
+ */
90
+ export function isRetryableError(error: EcommerceApiError): boolean {
91
+ // Retry on network errors
92
+ if (error.isNetworkError) {
93
+ return true;
94
+ }
95
+
96
+ // Retry on timeout
97
+ if (error.isTimeoutError) {
98
+ return true;
99
+ }
100
+
101
+ // Retry on 5xx errors
102
+ if (error.statusCode && error.statusCode >= 500) {
103
+ return true;
104
+ }
105
+
106
+ // Retry on 429 (rate limit)
107
+ if (error.statusCode === 429) {
108
+ return true;
109
+ }
110
+
111
+ return false;
112
+ }
113
+
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Ecommerce API Helper Utilities
3
+ *
4
+ * This module contains helper functions for the ecommerce API.
5
+ */
6
+
7
+ /**
8
+ * Build query string from params object
9
+ */
10
+ export function buildQueryString(params: Record<string, any>): string {
11
+ const searchParams = new URLSearchParams();
12
+
13
+ Object.entries(params).forEach(([key, value]) => {
14
+ if (value !== undefined && value !== null) {
15
+ if (Array.isArray(value)) {
16
+ // Handle arrays (e.g., ids, tags)
17
+ searchParams.append(key, value.join(","));
18
+ } else {
19
+ searchParams.append(key, String(value));
20
+ }
21
+ }
22
+ });
23
+
24
+ const queryString = searchParams.toString();
25
+ return queryString ? `?${queryString}` : "";
26
+ }
27
+
28
+ /**
29
+ * Sleep for specified milliseconds
30
+ */
31
+ export function sleep(ms: number): Promise<void> {
32
+ return new Promise((resolve) => setTimeout(resolve, ms));
33
+ }
34
+
35
+ /**
36
+ * Calculate exponential backoff delay
37
+ */
38
+ export function getBackoffDelay(attempt: number, baseDelay = 1000): number {
39
+ return Math.min(baseDelay * Math.pow(2, attempt), 30000);
40
+ }
41
+
42
+ /**
43
+ * Retry function with exponential backoff
44
+ */
45
+ export async function retryWithBackoff<T>(
46
+ fn: () => Promise<T>,
47
+ maxRetries = 3,
48
+ baseDelay = 1000,
49
+ shouldRetry?: (error: any) => boolean
50
+ ): Promise<T> {
51
+ let lastError: any;
52
+
53
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
54
+ try {
55
+ return await fn();
56
+ } catch (error) {
57
+ lastError = error;
58
+
59
+ // Check if we should retry
60
+ if (attempt < maxRetries && (!shouldRetry || shouldRetry(error))) {
61
+ const delay = getBackoffDelay(attempt, baseDelay);
62
+ await sleep(delay);
63
+ continue;
64
+ }
65
+
66
+ throw error;
67
+ }
68
+ }
69
+
70
+ throw lastError;
71
+ }
72
+
73
+ /**
74
+ * Format price for display
75
+ */
76
+ export function formatPrice(price: string | number, decimals = 2): string {
77
+ const num = typeof price === "string" ? parseFloat(price) : price;
78
+ return num.toFixed(decimals);
79
+ }
80
+
81
+ /**
82
+ * Validate email address
83
+ */
84
+ export function isValidEmail(email: string): boolean {
85
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
86
+ return emailRegex.test(email);
87
+ }
88
+
89
+ /**
90
+ * Validate Ethereum address
91
+ */
92
+ export function isValidAddress(address: string): boolean {
93
+ return /^0x[a-fA-F0-9]{40}$/.test(address);
94
+ }
95
+
96
+ /**
97
+ * Truncate address for display
98
+ */
99
+ export function truncateAddress(address: string, start = 6, end = 4): string {
100
+ if (!address || address.length < start + end) {
101
+ return address;
102
+ }
103
+ return `${address.slice(0, start)}...${address.slice(-end)}`;
104
+ }
105
+
106
+ /**
107
+ * Calculate discount amount
108
+ */
109
+ export function calculateDiscountAmount(
110
+ price: number,
111
+ discountType: "PERCENTAGE" | "FIXED_AMOUNT",
112
+ discountValue: number
113
+ ): number {
114
+ if (discountType === "PERCENTAGE") {
115
+ return (price * discountValue) / 100;
116
+ }
117
+ return Math.min(discountValue, price);
118
+ }
119
+
120
+ /**
121
+ * Calculate final price after discount
122
+ */
123
+ export function calculateFinalPrice(
124
+ price: number,
125
+ discountType: "PERCENTAGE" | "FIXED_AMOUNT",
126
+ discountValue: number
127
+ ): number {
128
+ const discountAmount = calculateDiscountAmount(price, discountType, discountValue);
129
+ return Math.max(0, price - discountAmount);
130
+ }
131
+
package/lib/fee.ts CHANGED
@@ -15,8 +15,8 @@ export const TARGET_APPROVED_MAX_BUILDER_FEE_PERCENT = `0.1%`;
15
15
 
16
16
  /**
17
17
  * Get the amount of builder fee to approve for
18
- * @param perpetualTradingFee - Perp fee in percentage
19
- * @param spotTradingFee - Spot fee in percentage
18
+ * @param perpetualTradingFee - Perp fee in percentage (0.025 means 0.025% perp fee)
19
+ * @param spotTradingFee - Spot fee in percentage (0.01 means 0.01% spot fee)
20
20
  * @param feeDiscount - Discount fee in percentage (0.9 means 90% discount)
21
21
  * @returns {
22
22
  * amount: number; - The amount of builder fee to approve in 1/10 of a basis point
@@ -75,19 +75,19 @@ export const getApprovalAmount = ({
75
75
  .mul(discountMultiplier)
76
76
  .toNumber();
77
77
 
78
- // ensure perp fee is either 0 or between 0.01% and 0.1%
79
- if (validatedPerpFeePct > 0 && validatedPerpFeePct < 0.01) {
80
- console.warn("Perp fee is less than 0.01%, setting to 0.01%");
81
- validatedPerpFeePct = 0.01;
82
- }
83
- if (validatedPerpFeePct < 0) {
84
- console.warn("Perp fee is less than 0, setting to 0");
85
- validatedPerpFeePct = 0;
78
+ // ensure perp fee is either 0 or between 0.001%
79
+ if (validatedPerpFeePct > 0 && validatedPerpFeePct < 0.001) {
80
+ console.warn("Perp fee is less than 0.001%, setting to 0.001%");
81
+ validatedPerpFeePct = 0.001;
86
82
  }
87
83
  if (validatedPerpFeePct > 0.1) {
88
84
  console.warn("Perp fee is greater than 0.1%, setting to 0.1%");
89
85
  validatedPerpFeePct = 0.1;
90
86
  }
87
+ if (validatedPerpFeePct < 0) {
88
+ console.warn("Perp fee is less than 0, setting to 0");
89
+ validatedPerpFeePct = 0;
90
+ }
91
91
 
92
92
  let validatedSpotFeePct = spotTradingFee;
93
93
 
@@ -1,17 +1,45 @@
1
- import { PerpsMeta, InfoClient } from "@nktkas/hyperliquid";
1
+ import { InfoClient, PerpsAssetCtx, MarginTables } from "@nktkas/hyperliquid";
2
2
 
3
- export type PerpsMetaWithCollateralToken = PerpsMeta & {
4
- collateralToken?: number; // spot token index
5
- };
3
+ export interface PerpsMeta {
4
+ collateralToken: number;
5
+ /** Trading universes available for perpetual trading. */
6
+ universe: PerpsUniverse[];
7
+ /** Margin requirement tables for different leverage tiers. */
8
+ marginTables: MarginTables;
9
+ }
10
+ /** Metadata and context for perpetual assets. */
11
+ export type PerpsMetaAndAssetCtxs = [
12
+ /** Metadata for assets. */
13
+ PerpsMeta,
14
+ /** Context for each perpetual asset. */
15
+ PerpsAssetCtx[],
16
+ ];
17
+ /** Trading universe parameters for perpetual assets. */
18
+ export interface PerpsUniverse {
19
+ /** Minimum decimal places for order sizes. */
20
+ szDecimals: number;
21
+ /** Name of the universe. */
22
+ name: string;
23
+ /** Maximum allowed leverage. */
24
+ maxLeverage: number;
25
+ /** Unique identifier for the margin requirements table. */
26
+ marginTableId: number;
27
+ /** Indicates if only isolated margin trading is allowed. */
28
+ onlyIsolated?: true;
29
+ /** Indicates if the universe is delisted. */
30
+ isDelisted?: true;
31
+ /** Indicates if the universe is in growth mode, eligible for discounted fees */
32
+ growthMode?: "enabled";
33
+ /** Margin mode for the universe. */
34
+ marginMode?: "strictIsolated" | "noCross";
35
+ }
6
36
 
7
- export type AllPerpsMeta = PerpsMetaWithCollateralToken[];
37
+ export type AllPerpsMeta = PerpsMeta[];
8
38
 
9
39
  export async function getAllPerpsMeta(
10
40
  infoClient: InfoClient,
11
41
  ): Promise<AllPerpsMeta> {
12
42
  return infoClient.transport.request<AllPerpsMeta>("info", {
13
- action: {
14
- type: "allPerpMetas",
15
- },
43
+ type: "allPerpMetas",
16
44
  });
17
45
  }
package/lib/hip3/utils.ts CHANGED
@@ -99,7 +99,7 @@ export async function getHip3DexAbstraction(client: InfoClient, user: string) {
99
99
 
100
100
  const dexToCollateralTokenSymbol = {
101
101
  rrrrr: "USDEEE",
102
- hyena: "USDE",
102
+ hyna: "USDE",
103
103
  flx: "USDH",
104
104
  vntl: "USDH",
105
105
  };
@@ -150,7 +150,20 @@ export function getDisplayMarketSymbol(
150
150
  showCollateralTokenSymbol: boolean = true,
151
151
  collateralTokenSymbol?: string,
152
152
  ) {
153
- if (!coin || isSpotSymbol(coin)) return coin;
153
+ if (!coin) return coin;
154
+
155
+ if (isSpotSymbol(coin)) {
156
+ if (coin.includes("/")) {
157
+ const [baseToken, quoteToken] = coin.split("/");
158
+
159
+ if (showCollateralTokenSymbol) {
160
+ return `${baseToken}/${collateralTokenSymbol ?? quoteToken}`;
161
+ } else {
162
+ return baseToken;
163
+ }
164
+ }
165
+ return coin;
166
+ }
154
167
 
155
168
  if (isHip3Symbol(coin)) {
156
169
  const [_, symbol] = coin.split(":");