@0xarchive/sdk 0.9.0 → 0.9.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/dist/index.mjs CHANGED
@@ -45,6 +45,14 @@ var HttpClient = class {
45
45
  get validationEnabled() {
46
46
  return this.validate;
47
47
  }
48
+ /** Base URL for raw requests (used by web3 subscribe) */
49
+ getBaseUrl() {
50
+ return this.baseUrl;
51
+ }
52
+ /** Timeout in ms for raw requests (used by web3 subscribe) */
53
+ getTimeout() {
54
+ return this.timeout;
55
+ }
48
56
  /**
49
57
  * Make a GET request to the API
50
58
  *
@@ -115,6 +123,66 @@ var HttpClient = class {
115
123
  );
116
124
  }
117
125
  }
126
+ /**
127
+ * Make a POST request to the API
128
+ *
129
+ * @param path - API endpoint path
130
+ * @param body - JSON request body
131
+ * @param schema - Optional Zod schema for validation (used when validation is enabled)
132
+ */
133
+ async post(path, body, schema) {
134
+ const url = `${this.baseUrl}${path}`;
135
+ const controller = new AbortController();
136
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
137
+ try {
138
+ const response = await fetch(url, {
139
+ method: "POST",
140
+ headers: {
141
+ "X-API-Key": this.apiKey,
142
+ "Content-Type": "application/json"
143
+ },
144
+ body: body ? JSON.stringify(body) : void 0,
145
+ signal: controller.signal
146
+ });
147
+ clearTimeout(timeoutId);
148
+ const rawData = await response.json();
149
+ const data = transformKeys(rawData);
150
+ if (!response.ok) {
151
+ const error = data;
152
+ const apiResponse = data;
153
+ throw new OxArchiveError(
154
+ error.error || `Request failed with status ${response.status}`,
155
+ response.status,
156
+ apiResponse.meta?.requestId
157
+ );
158
+ }
159
+ if (this.validate && schema) {
160
+ const result = schema.safeParse(data);
161
+ if (!result.success) {
162
+ const apiResponse = data;
163
+ throw new OxArchiveError(
164
+ `Response validation failed: ${result.error.message}`,
165
+ 422,
166
+ apiResponse.meta?.requestId
167
+ );
168
+ }
169
+ return result.data;
170
+ }
171
+ return data;
172
+ } catch (error) {
173
+ clearTimeout(timeoutId);
174
+ if (error instanceof OxArchiveError) {
175
+ throw error;
176
+ }
177
+ if (error instanceof Error && error.name === "AbortError") {
178
+ throw new OxArchiveError(`Request timeout after ${this.timeout}ms`, 408);
179
+ }
180
+ throw new OxArchiveError(
181
+ error instanceof Error ? error.message : "Unknown error",
182
+ 500
183
+ );
184
+ }
185
+ }
118
186
  };
119
187
 
120
188
  // src/schemas.ts
@@ -1386,6 +1454,147 @@ var DataQualityResource = class {
1386
1454
  }
1387
1455
  };
1388
1456
 
1457
+ // src/resources/web3.ts
1458
+ var Web3Resource = class {
1459
+ constructor(http) {
1460
+ this.http = http;
1461
+ }
1462
+ /**
1463
+ * Get a SIWE challenge message to sign.
1464
+ *
1465
+ * @param address - Ethereum wallet address
1466
+ * @returns SIWE message and nonce. Sign the message with personal_sign (EIP-191).
1467
+ */
1468
+ async challenge(address) {
1469
+ return this.http.post("/v1/auth/web3/challenge", { address });
1470
+ }
1471
+ /**
1472
+ * Create a free-tier account and get an API key.
1473
+ *
1474
+ * @param message - The SIWE message from {@link challenge}
1475
+ * @param signature - Hex-encoded signature from personal_sign
1476
+ * @returns API key, tier, and wallet address
1477
+ */
1478
+ async signup(message, signature) {
1479
+ return this.http.post("/v1/web3/signup", { message, signature });
1480
+ }
1481
+ /**
1482
+ * List all API keys for the authenticated wallet.
1483
+ *
1484
+ * @param message - The SIWE message from {@link challenge}
1485
+ * @param signature - Hex-encoded signature from personal_sign
1486
+ * @returns List of API keys and wallet address
1487
+ */
1488
+ async listKeys(message, signature) {
1489
+ return this.http.post("/v1/web3/keys", { message, signature });
1490
+ }
1491
+ /**
1492
+ * Revoke a specific API key.
1493
+ *
1494
+ * @param message - The SIWE message from {@link challenge}
1495
+ * @param signature - Hex-encoded signature from personal_sign
1496
+ * @param keyId - UUID of the key to revoke
1497
+ * @returns Confirmation message and wallet address
1498
+ */
1499
+ async revokeKey(message, signature, keyId) {
1500
+ return this.http.post("/v1/web3/keys/revoke", {
1501
+ message,
1502
+ signature,
1503
+ key_id: keyId
1504
+ });
1505
+ }
1506
+ /**
1507
+ * Get pricing info for a paid subscription (x402 flow, step 1).
1508
+ *
1509
+ * Returns the payment details needed to sign a USDC transfer on Base.
1510
+ * After signing, pass the payment signature to {@link subscribe}.
1511
+ *
1512
+ * @param tier - Subscription tier: 'build' ($49/mo) or 'pro' ($199/mo)
1513
+ * @returns Payment details (amount, asset, network, pay-to address)
1514
+ */
1515
+ async subscribeQuote(tier) {
1516
+ const url = `${this.http.getBaseUrl()}/v1/web3/subscribe`;
1517
+ const timeout = this.http.getTimeout();
1518
+ const controller = new AbortController();
1519
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
1520
+ try {
1521
+ const response = await fetch(url, {
1522
+ method: "POST",
1523
+ headers: { "Content-Type": "application/json" },
1524
+ body: JSON.stringify({ tier }),
1525
+ signal: controller.signal
1526
+ });
1527
+ clearTimeout(timeoutId);
1528
+ const rawData = await response.json();
1529
+ const data = transformKeys(rawData);
1530
+ if (response.status === 402) {
1531
+ return data.payment;
1532
+ }
1533
+ throw new OxArchiveError(
1534
+ data.error || `Unexpected status ${response.status}`,
1535
+ response.status
1536
+ );
1537
+ } catch (error) {
1538
+ clearTimeout(timeoutId);
1539
+ if (error instanceof OxArchiveError) throw error;
1540
+ if (error instanceof Error && error.name === "AbortError") {
1541
+ throw new OxArchiveError(`Request timeout after ${timeout}ms`, 408);
1542
+ }
1543
+ throw new OxArchiveError(
1544
+ error instanceof Error ? error.message : "Unknown error",
1545
+ 500
1546
+ );
1547
+ }
1548
+ }
1549
+ /**
1550
+ * Complete a paid subscription with a signed x402 payment (step 2).
1551
+ *
1552
+ * Requires a payment signature from signing a USDC transfer (EIP-3009)
1553
+ * for the amount returned by {@link subscribeQuote}.
1554
+ *
1555
+ * @param tier - Subscription tier: 'build' or 'pro'
1556
+ * @param paymentSignature - Signed x402 payment (from EIP-3009 USDC transfer on Base)
1557
+ * @returns API key, tier, expiration, and wallet address
1558
+ */
1559
+ async subscribe(tier, paymentSignature) {
1560
+ const url = `${this.http.getBaseUrl()}/v1/web3/subscribe`;
1561
+ const timeout = this.http.getTimeout();
1562
+ const controller = new AbortController();
1563
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
1564
+ try {
1565
+ const response = await fetch(url, {
1566
+ method: "POST",
1567
+ headers: {
1568
+ "Content-Type": "application/json",
1569
+ "payment-signature": paymentSignature
1570
+ },
1571
+ body: JSON.stringify({ tier }),
1572
+ signal: controller.signal
1573
+ });
1574
+ clearTimeout(timeoutId);
1575
+ const rawData = await response.json();
1576
+ const data = transformKeys(rawData);
1577
+ if (!response.ok) {
1578
+ throw new OxArchiveError(
1579
+ data.error || "Subscribe failed",
1580
+ response.status
1581
+ );
1582
+ }
1583
+ return data;
1584
+ } catch (error) {
1585
+ clearTimeout(timeoutId);
1586
+ if (error instanceof OxArchiveError) throw error;
1587
+ if (error instanceof Error && error.name === "AbortError") {
1588
+ throw new OxArchiveError(`Request timeout after ${timeout}ms`, 408);
1589
+ }
1590
+ throw new OxArchiveError(
1591
+ error instanceof Error ? error.message : "Unknown error",
1592
+ 500
1593
+ );
1594
+ }
1595
+ }
1596
+ };
1597
+
1389
1598
  // src/exchanges.ts
1390
1599
  var HyperliquidClient = class {
1391
1600
  /**
@@ -1505,7 +1714,9 @@ var Hip3Client = class {
1505
1714
  * OHLCV candle data
1506
1715
  */
1507
1716
  candles;
1717
+ http;
1508
1718
  constructor(http) {
1719
+ this.http = http;
1509
1720
  const basePath = "/v1/hyperliquid/hip3";
1510
1721
  const coinTransform = (c) => c;
1511
1722
  this.instruments = new Hip3InstrumentsResource(http, basePath, coinTransform);
@@ -1515,6 +1726,52 @@ var Hip3Client = class {
1515
1726
  this.openInterest = new OpenInterestResource(http, basePath, coinTransform);
1516
1727
  this.candles = new CandlesResource(http, basePath, coinTransform);
1517
1728
  }
1729
+ /**
1730
+ * Get per-coin data freshness across all data types
1731
+ *
1732
+ * @param coin - The coin symbol (case-sensitive, e.g., 'km:US500')
1733
+ * @returns Per-coin freshness with last_updated and lag_ms for each data type
1734
+ */
1735
+ async freshness(coin) {
1736
+ const response = await this.http.get(
1737
+ `/v1/hyperliquid/hip3/freshness/${coin}`,
1738
+ void 0,
1739
+ this.http.validationEnabled ? CoinFreshnessResponseSchema : void 0
1740
+ );
1741
+ return response.data;
1742
+ }
1743
+ /**
1744
+ * Get combined market summary (price, funding, OI) in one call
1745
+ *
1746
+ * @param coin - The coin symbol (case-sensitive, e.g., 'km:US500')
1747
+ * @returns Combined market summary
1748
+ */
1749
+ async summary(coin) {
1750
+ const response = await this.http.get(
1751
+ `/v1/hyperliquid/hip3/summary/${coin}`,
1752
+ void 0,
1753
+ this.http.validationEnabled ? CoinSummaryResponseSchema : void 0
1754
+ );
1755
+ return response.data;
1756
+ }
1757
+ /**
1758
+ * Get mark/oracle/mid price history (projected from OI data)
1759
+ *
1760
+ * @param coin - The coin symbol (case-sensitive, e.g., 'km:US500')
1761
+ * @param params - Time range, cursor, and interval parameters
1762
+ * @returns CursorResponse with price snapshots
1763
+ */
1764
+ async priceHistory(coin, params) {
1765
+ const response = await this.http.get(
1766
+ `/v1/hyperliquid/hip3/prices/${coin}`,
1767
+ params,
1768
+ this.http.validationEnabled ? PriceSnapshotArrayResponseSchema : void 0
1769
+ );
1770
+ return {
1771
+ data: response.data,
1772
+ nextCursor: response.meta.nextCursor
1773
+ };
1774
+ }
1518
1775
  };
1519
1776
  var LighterClient = class {
1520
1777
  /**
@@ -1541,7 +1798,9 @@ var LighterClient = class {
1541
1798
  * OHLCV candle data
1542
1799
  */
1543
1800
  candles;
1801
+ http;
1544
1802
  constructor(http) {
1803
+ this.http = http;
1545
1804
  const basePath = "/v1/lighter";
1546
1805
  this.orderbook = new OrderBookResource(http, basePath);
1547
1806
  this.trades = new TradesResource(http, basePath);
@@ -1550,6 +1809,52 @@ var LighterClient = class {
1550
1809
  this.openInterest = new OpenInterestResource(http, basePath);
1551
1810
  this.candles = new CandlesResource(http, basePath);
1552
1811
  }
1812
+ /**
1813
+ * Get per-coin data freshness across all data types
1814
+ *
1815
+ * @param coin - The coin symbol (e.g., 'BTC', 'ETH')
1816
+ * @returns Per-coin freshness with last_updated and lag_ms for each data type
1817
+ */
1818
+ async freshness(coin) {
1819
+ const response = await this.http.get(
1820
+ `/v1/lighter/freshness/${coin.toUpperCase()}`,
1821
+ void 0,
1822
+ this.http.validationEnabled ? CoinFreshnessResponseSchema : void 0
1823
+ );
1824
+ return response.data;
1825
+ }
1826
+ /**
1827
+ * Get combined market summary (price, funding, OI) in one call
1828
+ *
1829
+ * @param coin - The coin symbol (e.g., 'BTC', 'ETH')
1830
+ * @returns Combined market summary
1831
+ */
1832
+ async summary(coin) {
1833
+ const response = await this.http.get(
1834
+ `/v1/lighter/summary/${coin.toUpperCase()}`,
1835
+ void 0,
1836
+ this.http.validationEnabled ? CoinSummaryResponseSchema : void 0
1837
+ );
1838
+ return response.data;
1839
+ }
1840
+ /**
1841
+ * Get mark/oracle price history (projected from OI data)
1842
+ *
1843
+ * @param coin - The coin symbol (e.g., 'BTC', 'ETH')
1844
+ * @param params - Time range, cursor, and interval parameters
1845
+ * @returns CursorResponse with price snapshots
1846
+ */
1847
+ async priceHistory(coin, params) {
1848
+ const response = await this.http.get(
1849
+ `/v1/lighter/prices/${coin.toUpperCase()}`,
1850
+ params,
1851
+ this.http.validationEnabled ? PriceSnapshotArrayResponseSchema : void 0
1852
+ );
1853
+ return {
1854
+ data: response.data,
1855
+ nextCursor: response.meta.nextCursor
1856
+ };
1857
+ }
1553
1858
  };
1554
1859
 
1555
1860
  // src/client.ts
@@ -1569,6 +1874,10 @@ var OxArchive = class {
1569
1874
  * Data quality metrics: status, coverage, incidents, latency, SLA
1570
1875
  */
1571
1876
  dataQuality;
1877
+ /**
1878
+ * Wallet-based auth: get API keys via SIWE signature
1879
+ */
1880
+ web3;
1572
1881
  /**
1573
1882
  * @deprecated Use client.hyperliquid.orderbook instead
1574
1883
  */
@@ -1607,6 +1916,7 @@ var OxArchive = class {
1607
1916
  this.hyperliquid = new HyperliquidClient(this.http);
1608
1917
  this.lighter = new LighterClient(this.http);
1609
1918
  this.dataQuality = new DataQualityResource(this.http);
1919
+ this.web3 = new Web3Resource(this.http);
1610
1920
  const legacyBase = "/v1/hyperliquid";
1611
1921
  this.orderbook = new OrderBookResource(this.http, legacyBase);
1612
1922
  this.trades = new TradesResource(this.http, legacyBase);