@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/README.md +137 -4
- package/dist/index.d.mts +214 -3
- package/dist/index.d.ts +214 -3
- package/dist/index.js +310 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +310 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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);
|