@limitless-exchange/sdk 0.0.1 → 0.0.3
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 +71 -6
- package/dist/index.d.mts +835 -200
- package/dist/index.d.ts +835 -200
- package/dist/index.js +301 -210
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +301 -209
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -41,7 +41,6 @@ __export(index_exports, {
|
|
|
41
41
|
DEFAULT_WS_URL: () => DEFAULT_WS_URL,
|
|
42
42
|
HttpClient: () => HttpClient,
|
|
43
43
|
MarketFetcher: () => MarketFetcher,
|
|
44
|
-
MarketType: () => MarketType,
|
|
45
44
|
MessageSigner: () => MessageSigner,
|
|
46
45
|
NoOpLogger: () => NoOpLogger,
|
|
47
46
|
OrderBuilder: () => OrderBuilder,
|
|
@@ -115,16 +114,11 @@ var Side = /* @__PURE__ */ ((Side2) => {
|
|
|
115
114
|
Side2[Side2["SELL"] = 1] = "SELL";
|
|
116
115
|
return Side2;
|
|
117
116
|
})(Side || {});
|
|
118
|
-
var OrderType = /* @__PURE__ */ ((
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return
|
|
117
|
+
var OrderType = /* @__PURE__ */ ((OrderType2) => {
|
|
118
|
+
OrderType2["FOK"] = "FOK";
|
|
119
|
+
OrderType2["GTC"] = "GTC";
|
|
120
|
+
return OrderType2;
|
|
122
121
|
})(OrderType || {});
|
|
123
|
-
var MarketType = /* @__PURE__ */ ((MarketType3) => {
|
|
124
|
-
MarketType3["CLOB"] = "CLOB";
|
|
125
|
-
MarketType3["NEGRISK"] = "NEGRISK";
|
|
126
|
-
return MarketType3;
|
|
127
|
-
})(MarketType || {});
|
|
128
122
|
var SignatureType = /* @__PURE__ */ ((SignatureType2) => {
|
|
129
123
|
SignatureType2[SignatureType2["EOA"] = 0] = "EOA";
|
|
130
124
|
SignatureType2[SignatureType2["POLY_PROXY"] = 1] = "POLY_PROXY";
|
|
@@ -504,6 +498,8 @@ var AuthenticatedClient = class {
|
|
|
504
498
|
|
|
505
499
|
// src/api/http.ts
|
|
506
500
|
var import_axios = __toESM(require("axios"));
|
|
501
|
+
var import_http = __toESM(require("http"));
|
|
502
|
+
var import_https = __toESM(require("https"));
|
|
507
503
|
|
|
508
504
|
// src/utils/constants.ts
|
|
509
505
|
var DEFAULT_API_URL = "https://api.limitless.exchange";
|
|
@@ -515,24 +511,31 @@ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
|
515
511
|
var CONTRACT_ADDRESSES = {
|
|
516
512
|
// Base mainnet (chainId: 8453)
|
|
517
513
|
8453: {
|
|
518
|
-
|
|
519
|
-
|
|
514
|
+
USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
515
|
+
// Native USDC on Base
|
|
516
|
+
CTF: "0xC9c98965297Bc527861c898329Ee280632B76e18"
|
|
517
|
+
// Conditional Token Framework
|
|
520
518
|
},
|
|
521
519
|
// Base Sepolia testnet (chainId: 84532)
|
|
522
520
|
84532: {
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
NEGRISK: "0x..."
|
|
521
|
+
USDC: "0x...",
|
|
522
|
+
CTF: "0x..."
|
|
526
523
|
}
|
|
527
524
|
};
|
|
528
|
-
function getContractAddress(
|
|
525
|
+
function getContractAddress(contractType, chainId = DEFAULT_CHAIN_ID) {
|
|
529
526
|
const addresses = CONTRACT_ADDRESSES[chainId];
|
|
530
527
|
if (!addresses) {
|
|
531
528
|
throw new Error(
|
|
532
529
|
`No contract addresses configured for chainId ${chainId}. Supported chains: ${Object.keys(CONTRACT_ADDRESSES).join(", ")}`
|
|
533
530
|
);
|
|
534
531
|
}
|
|
535
|
-
|
|
532
|
+
const address = addresses[contractType];
|
|
533
|
+
if (!address || address === "0x...") {
|
|
534
|
+
throw new Error(
|
|
535
|
+
`Contract address for ${contractType} not available on chainId ${chainId}. Please configure the address in constants.ts or use environment variables.`
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
return address;
|
|
536
539
|
}
|
|
537
540
|
|
|
538
541
|
// src/api/http.ts
|
|
@@ -545,14 +548,39 @@ var HttpClient = class {
|
|
|
545
548
|
constructor(config = {}) {
|
|
546
549
|
this.sessionCookie = config.sessionCookie;
|
|
547
550
|
this.logger = config.logger || new NoOpLogger();
|
|
551
|
+
const keepAlive = config.keepAlive !== false;
|
|
552
|
+
const maxSockets = config.maxSockets || 50;
|
|
553
|
+
const maxFreeSockets = config.maxFreeSockets || 10;
|
|
554
|
+
const socketTimeout = config.socketTimeout || 6e4;
|
|
555
|
+
const httpAgent = new import_http.default.Agent({
|
|
556
|
+
keepAlive,
|
|
557
|
+
maxSockets,
|
|
558
|
+
maxFreeSockets,
|
|
559
|
+
timeout: socketTimeout
|
|
560
|
+
});
|
|
561
|
+
const httpsAgent = new import_https.default.Agent({
|
|
562
|
+
keepAlive,
|
|
563
|
+
maxSockets,
|
|
564
|
+
maxFreeSockets,
|
|
565
|
+
timeout: socketTimeout
|
|
566
|
+
});
|
|
548
567
|
this.client = import_axios.default.create({
|
|
549
568
|
baseURL: config.baseURL || DEFAULT_API_URL,
|
|
550
569
|
timeout: config.timeout || 3e4,
|
|
570
|
+
httpAgent,
|
|
571
|
+
httpsAgent,
|
|
551
572
|
headers: {
|
|
552
573
|
"Content-Type": "application/json",
|
|
553
|
-
Accept: "application/json"
|
|
574
|
+
Accept: "application/json",
|
|
575
|
+
...config.additionalHeaders
|
|
554
576
|
}
|
|
555
577
|
});
|
|
578
|
+
this.logger.debug("HTTP client initialized", {
|
|
579
|
+
baseURL: config.baseURL || DEFAULT_API_URL,
|
|
580
|
+
keepAlive,
|
|
581
|
+
maxSockets,
|
|
582
|
+
maxFreeSockets
|
|
583
|
+
});
|
|
556
584
|
this.setupInterceptors();
|
|
557
585
|
}
|
|
558
586
|
/**
|
|
@@ -933,8 +961,7 @@ var OrderBuilder = class {
|
|
|
933
961
|
* const fokOrder = builder.buildOrder({
|
|
934
962
|
* tokenId: '123456',
|
|
935
963
|
* makerAmount: 50, // 50 USDC to spend
|
|
936
|
-
* side: Side.BUY
|
|
937
|
-
* marketType: MarketType.CLOB
|
|
964
|
+
* side: Side.BUY
|
|
938
965
|
* });
|
|
939
966
|
*
|
|
940
967
|
* // GTC order (price + size)
|
|
@@ -942,8 +969,7 @@ var OrderBuilder = class {
|
|
|
942
969
|
* tokenId: '123456',
|
|
943
970
|
* price: 0.38,
|
|
944
971
|
* size: 22.123, // Will be rounded to tick-aligned: 22.123 shares
|
|
945
|
-
* side: Side.BUY
|
|
946
|
-
* marketType: MarketType.CLOB
|
|
972
|
+
* side: Side.BUY
|
|
947
973
|
* });
|
|
948
974
|
* ```
|
|
949
975
|
*/
|
|
@@ -1218,8 +1244,7 @@ var OrderSigner = class {
|
|
|
1218
1244
|
* ```typescript
|
|
1219
1245
|
* const signature = await signer.signOrder(unsignedOrder, {
|
|
1220
1246
|
* chainId: 8453,
|
|
1221
|
-
* contractAddress: '0x...'
|
|
1222
|
-
* marketType: MarketType.CLOB
|
|
1247
|
+
* contractAddress: '0x...'
|
|
1223
1248
|
* });
|
|
1224
1249
|
* ```
|
|
1225
1250
|
*/
|
|
@@ -1227,7 +1252,7 @@ var OrderSigner = class {
|
|
|
1227
1252
|
this.logger.debug("Signing order with EIP-712", {
|
|
1228
1253
|
tokenId: order.tokenId,
|
|
1229
1254
|
side: order.side,
|
|
1230
|
-
|
|
1255
|
+
verifyingContract: config.contractAddress
|
|
1231
1256
|
});
|
|
1232
1257
|
const walletAddress = await this.wallet.getAddress();
|
|
1233
1258
|
if (walletAddress.toLowerCase() !== order.signer.toLowerCase()) {
|
|
@@ -1452,14 +1477,221 @@ function validateSignedOrder(order) {
|
|
|
1452
1477
|
}
|
|
1453
1478
|
}
|
|
1454
1479
|
|
|
1480
|
+
// src/markets/fetcher.ts
|
|
1481
|
+
var MarketFetcher = class {
|
|
1482
|
+
/**
|
|
1483
|
+
* Creates a new market fetcher instance.
|
|
1484
|
+
*
|
|
1485
|
+
* @param httpClient - HTTP client for API requests
|
|
1486
|
+
* @param logger - Optional logger for debugging (default: no logging)
|
|
1487
|
+
*
|
|
1488
|
+
* @example
|
|
1489
|
+
* ```typescript
|
|
1490
|
+
* const fetcher = new MarketFetcher(httpClient);
|
|
1491
|
+
* ```
|
|
1492
|
+
*/
|
|
1493
|
+
constructor(httpClient, logger) {
|
|
1494
|
+
this.httpClient = httpClient;
|
|
1495
|
+
this.logger = logger || new NoOpLogger();
|
|
1496
|
+
this.venueCache = /* @__PURE__ */ new Map();
|
|
1497
|
+
}
|
|
1498
|
+
/**
|
|
1499
|
+
* Gets active markets with query parameters and pagination support.
|
|
1500
|
+
*
|
|
1501
|
+
* @param params - Query parameters for filtering and pagination
|
|
1502
|
+
* @returns Promise resolving to active markets response
|
|
1503
|
+
* @throws Error if API request fails
|
|
1504
|
+
*
|
|
1505
|
+
* @example
|
|
1506
|
+
* ```typescript
|
|
1507
|
+
* // Get 8 markets sorted by LP rewards
|
|
1508
|
+
* const response = await fetcher.getActiveMarkets({
|
|
1509
|
+
* limit: 8,
|
|
1510
|
+
* sortBy: 'lp_rewards'
|
|
1511
|
+
* });
|
|
1512
|
+
* console.log(`Found ${response.data.length} of ${response.totalMarketsCount} markets`);
|
|
1513
|
+
*
|
|
1514
|
+
* // Get page 2
|
|
1515
|
+
* const page2 = await fetcher.getActiveMarkets({
|
|
1516
|
+
* limit: 8,
|
|
1517
|
+
* page: 2,
|
|
1518
|
+
* sortBy: 'ending_soon'
|
|
1519
|
+
* });
|
|
1520
|
+
* ```
|
|
1521
|
+
*/
|
|
1522
|
+
async getActiveMarkets(params) {
|
|
1523
|
+
const queryParams = new URLSearchParams();
|
|
1524
|
+
if (params?.limit !== void 0) {
|
|
1525
|
+
queryParams.append("limit", params.limit.toString());
|
|
1526
|
+
}
|
|
1527
|
+
if (params?.page !== void 0) {
|
|
1528
|
+
queryParams.append("page", params.page.toString());
|
|
1529
|
+
}
|
|
1530
|
+
if (params?.sortBy) {
|
|
1531
|
+
queryParams.append("sortBy", params.sortBy);
|
|
1532
|
+
}
|
|
1533
|
+
const queryString = queryParams.toString();
|
|
1534
|
+
const endpoint = `/markets/active${queryString ? `?${queryString}` : ""}`;
|
|
1535
|
+
this.logger.debug("Fetching active markets", { params });
|
|
1536
|
+
try {
|
|
1537
|
+
const response = await this.httpClient.get(endpoint);
|
|
1538
|
+
this.logger.info("Active markets fetched successfully", {
|
|
1539
|
+
count: response.data.length,
|
|
1540
|
+
total: response.totalMarketsCount,
|
|
1541
|
+
sortBy: params?.sortBy,
|
|
1542
|
+
page: params?.page
|
|
1543
|
+
});
|
|
1544
|
+
return response;
|
|
1545
|
+
} catch (error) {
|
|
1546
|
+
this.logger.error("Failed to fetch active markets", error, { params });
|
|
1547
|
+
throw error;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
/**
|
|
1551
|
+
* Gets a single market by slug.
|
|
1552
|
+
*
|
|
1553
|
+
* @remarks
|
|
1554
|
+
* Automatically caches venue information for efficient order signing.
|
|
1555
|
+
* Always call this method before creating orders to ensure venue data
|
|
1556
|
+
* is available and avoid additional API requests.
|
|
1557
|
+
*
|
|
1558
|
+
* @param slug - Market slug identifier
|
|
1559
|
+
* @returns Promise resolving to market details
|
|
1560
|
+
* @throws Error if API request fails or market not found
|
|
1561
|
+
*
|
|
1562
|
+
* @example
|
|
1563
|
+
* ```typescript
|
|
1564
|
+
* const market = await fetcher.getMarket('bitcoin-price-2024');
|
|
1565
|
+
* console.log(`Market: ${market.title}`);
|
|
1566
|
+
*
|
|
1567
|
+
* // Venue is now cached for order signing
|
|
1568
|
+
* await orderClient.createOrder({
|
|
1569
|
+
* marketSlug: 'bitcoin-price-2024',
|
|
1570
|
+
* ...
|
|
1571
|
+
* });
|
|
1572
|
+
* ```
|
|
1573
|
+
*/
|
|
1574
|
+
async getMarket(slug) {
|
|
1575
|
+
this.logger.debug("Fetching market", { slug });
|
|
1576
|
+
try {
|
|
1577
|
+
const market = await this.httpClient.get(`/markets/${slug}`);
|
|
1578
|
+
if (market.venue) {
|
|
1579
|
+
this.venueCache.set(slug, market.venue);
|
|
1580
|
+
this.logger.debug("Venue cached for order signing", {
|
|
1581
|
+
slug,
|
|
1582
|
+
exchange: market.venue.exchange,
|
|
1583
|
+
adapter: market.venue.adapter,
|
|
1584
|
+
cacheSize: this.venueCache.size
|
|
1585
|
+
});
|
|
1586
|
+
} else {
|
|
1587
|
+
this.logger.warn("Market has no venue data", { slug });
|
|
1588
|
+
}
|
|
1589
|
+
this.logger.info("Market fetched successfully", {
|
|
1590
|
+
slug,
|
|
1591
|
+
title: market.title
|
|
1592
|
+
});
|
|
1593
|
+
return market;
|
|
1594
|
+
} catch (error) {
|
|
1595
|
+
this.logger.error("Failed to fetch market", error, { slug });
|
|
1596
|
+
throw error;
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
/**
|
|
1600
|
+
* Gets cached venue information for a market.
|
|
1601
|
+
*
|
|
1602
|
+
* @remarks
|
|
1603
|
+
* Returns venue data previously cached by getMarket() call.
|
|
1604
|
+
* Used internally by OrderClient for efficient order signing.
|
|
1605
|
+
*
|
|
1606
|
+
* @param slug - Market slug identifier
|
|
1607
|
+
* @returns Cached venue information, or undefined if not in cache
|
|
1608
|
+
*
|
|
1609
|
+
* @example
|
|
1610
|
+
* ```typescript
|
|
1611
|
+
* const venue = fetcher.getVenue('bitcoin-price-2024');
|
|
1612
|
+
* if (venue) {
|
|
1613
|
+
* console.log(`Exchange: ${venue.exchange}`);
|
|
1614
|
+
* }
|
|
1615
|
+
* ```
|
|
1616
|
+
*/
|
|
1617
|
+
getVenue(slug) {
|
|
1618
|
+
const venue = this.venueCache.get(slug);
|
|
1619
|
+
if (venue) {
|
|
1620
|
+
this.logger.debug("Venue cache hit", {
|
|
1621
|
+
slug,
|
|
1622
|
+
exchange: venue.exchange
|
|
1623
|
+
});
|
|
1624
|
+
} else {
|
|
1625
|
+
this.logger.debug("Venue cache miss", { slug });
|
|
1626
|
+
}
|
|
1627
|
+
return venue;
|
|
1628
|
+
}
|
|
1629
|
+
/**
|
|
1630
|
+
* Gets the orderbook for a CLOB market.
|
|
1631
|
+
*
|
|
1632
|
+
* @param slug - Market slug identifier
|
|
1633
|
+
* @returns Promise resolving to orderbook data
|
|
1634
|
+
* @throws Error if API request fails
|
|
1635
|
+
*
|
|
1636
|
+
* @example
|
|
1637
|
+
* ```typescript
|
|
1638
|
+
* const orderbook = await fetcher.getOrderBook('bitcoin-price-2024');
|
|
1639
|
+
* console.log(`Bids: ${orderbook.bids.length}, Asks: ${orderbook.asks.length}`);
|
|
1640
|
+
* ```
|
|
1641
|
+
*/
|
|
1642
|
+
async getOrderBook(slug) {
|
|
1643
|
+
this.logger.debug("Fetching orderbook", { slug });
|
|
1644
|
+
try {
|
|
1645
|
+
const orderbook = await this.httpClient.get(
|
|
1646
|
+
`/markets/${slug}/orderbook`
|
|
1647
|
+
);
|
|
1648
|
+
this.logger.info("Orderbook fetched successfully", {
|
|
1649
|
+
slug,
|
|
1650
|
+
bids: orderbook.bids.length,
|
|
1651
|
+
asks: orderbook.asks.length,
|
|
1652
|
+
tokenId: orderbook.tokenId
|
|
1653
|
+
});
|
|
1654
|
+
return orderbook;
|
|
1655
|
+
} catch (error) {
|
|
1656
|
+
this.logger.error("Failed to fetch orderbook", error, { slug });
|
|
1657
|
+
throw error;
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
/**
|
|
1661
|
+
* Gets the current price for a token.
|
|
1662
|
+
*
|
|
1663
|
+
* @param tokenId - Token ID
|
|
1664
|
+
* @returns Promise resolving to price information
|
|
1665
|
+
* @throws Error if API request fails
|
|
1666
|
+
*
|
|
1667
|
+
* @example
|
|
1668
|
+
* ```typescript
|
|
1669
|
+
* const price = await fetcher.getPrice('123456');
|
|
1670
|
+
* console.log(`Current price: ${price.price}`);
|
|
1671
|
+
* ```
|
|
1672
|
+
*/
|
|
1673
|
+
async getPrice(tokenId) {
|
|
1674
|
+
this.logger.debug("Fetching price", { tokenId });
|
|
1675
|
+
try {
|
|
1676
|
+
const price = await this.httpClient.get(`/prices/${tokenId}`);
|
|
1677
|
+
this.logger.info("Price fetched successfully", {
|
|
1678
|
+
tokenId,
|
|
1679
|
+
price: price.price
|
|
1680
|
+
});
|
|
1681
|
+
return price;
|
|
1682
|
+
} catch (error) {
|
|
1683
|
+
this.logger.error("Failed to fetch price", error, { tokenId });
|
|
1684
|
+
throw error;
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
};
|
|
1688
|
+
|
|
1455
1689
|
// src/orders/client.ts
|
|
1456
1690
|
var OrderClient = class {
|
|
1457
1691
|
/**
|
|
1458
1692
|
* Creates a new order client instance.
|
|
1459
1693
|
*
|
|
1460
1694
|
* @param config - Order client configuration
|
|
1461
|
-
*
|
|
1462
|
-
* @throws Error if neither marketType nor signingConfig is provided
|
|
1463
1695
|
*/
|
|
1464
1696
|
constructor(config) {
|
|
1465
1697
|
this.httpClient = config.httpClient;
|
|
@@ -1468,32 +1700,18 @@ var OrderClient = class {
|
|
|
1468
1700
|
const feeRateBps = config.userData.feeRateBps;
|
|
1469
1701
|
this.orderBuilder = new OrderBuilder(config.wallet.address, feeRateBps, 1e-3);
|
|
1470
1702
|
this.orderSigner = new OrderSigner(config.wallet, this.logger);
|
|
1703
|
+
this.marketFetcher = config.marketFetcher || new MarketFetcher(config.httpClient, this.logger);
|
|
1471
1704
|
if (config.signingConfig) {
|
|
1472
1705
|
this.signingConfig = config.signingConfig;
|
|
1473
|
-
} else if (config.marketType) {
|
|
1474
|
-
const chainId = parseInt(process.env.CHAIN_ID || "8453");
|
|
1475
|
-
const contractAddress = config.marketType === "NEGRISK" /* NEGRISK */ ? process.env.NEGRISK_CONTRACT_ADDRESS || getContractAddress("NEGRISK", chainId) : process.env.CLOB_CONTRACT_ADDRESS || getContractAddress("CLOB", chainId);
|
|
1476
|
-
this.signingConfig = {
|
|
1477
|
-
chainId,
|
|
1478
|
-
contractAddress,
|
|
1479
|
-
marketType: config.marketType
|
|
1480
|
-
};
|
|
1481
|
-
this.logger.info("Auto-configured signing", {
|
|
1482
|
-
chainId,
|
|
1483
|
-
contractAddress,
|
|
1484
|
-
marketType: config.marketType
|
|
1485
|
-
});
|
|
1486
1706
|
} else {
|
|
1487
1707
|
const chainId = parseInt(process.env.CHAIN_ID || "8453");
|
|
1488
|
-
const contractAddress =
|
|
1708
|
+
const contractAddress = ZERO_ADDRESS;
|
|
1489
1709
|
this.signingConfig = {
|
|
1490
|
-
chainId,
|
|
1491
|
-
contractAddress,
|
|
1492
|
-
marketType: "CLOB" /* CLOB */
|
|
1493
|
-
};
|
|
1494
|
-
this.logger.debug("Using default CLOB configuration", {
|
|
1495
1710
|
chainId,
|
|
1496
1711
|
contractAddress
|
|
1712
|
+
};
|
|
1713
|
+
this.logger.info("Auto-configured signing (contract address from venue)", {
|
|
1714
|
+
chainId
|
|
1497
1715
|
});
|
|
1498
1716
|
}
|
|
1499
1717
|
}
|
|
@@ -1502,24 +1720,31 @@ var OrderClient = class {
|
|
|
1502
1720
|
*
|
|
1503
1721
|
* @remarks
|
|
1504
1722
|
* This method handles the complete order creation flow:
|
|
1505
|
-
* 1.
|
|
1506
|
-
* 2.
|
|
1507
|
-
* 3.
|
|
1723
|
+
* 1. Resolve venue address (from cache or API)
|
|
1724
|
+
* 2. Build unsigned order
|
|
1725
|
+
* 3. Sign with EIP-712 using venue.exchange as verifyingContract
|
|
1726
|
+
* 4. Submit to API
|
|
1727
|
+
*
|
|
1728
|
+
* Performance best practice: Always call marketFetcher.getMarket(marketSlug)
|
|
1729
|
+
* before createOrder() to cache venue data and avoid additional API requests.
|
|
1508
1730
|
*
|
|
1509
1731
|
* @param params - Order parameters
|
|
1510
1732
|
* @returns Promise resolving to order response
|
|
1511
1733
|
*
|
|
1512
|
-
* @throws Error if order creation fails
|
|
1734
|
+
* @throws Error if order creation fails or venue not found
|
|
1513
1735
|
*
|
|
1514
1736
|
* @example
|
|
1515
1737
|
* ```typescript
|
|
1738
|
+
* // Best practice: fetch market first to cache venue
|
|
1739
|
+
* const market = await marketFetcher.getMarket('bitcoin-2024');
|
|
1740
|
+
*
|
|
1516
1741
|
* const order = await orderClient.createOrder({
|
|
1517
|
-
* tokenId:
|
|
1742
|
+
* tokenId: market.tokens.yes,
|
|
1518
1743
|
* price: 0.65,
|
|
1519
1744
|
* size: 100,
|
|
1520
1745
|
* side: Side.BUY,
|
|
1521
1746
|
* orderType: OrderType.GTC,
|
|
1522
|
-
* marketSlug: '
|
|
1747
|
+
* marketSlug: 'bitcoin-2024'
|
|
1523
1748
|
* });
|
|
1524
1749
|
*
|
|
1525
1750
|
* console.log(`Order created: ${order.order.id}`);
|
|
@@ -1531,6 +1756,29 @@ var OrderClient = class {
|
|
|
1531
1756
|
orderType: params.orderType,
|
|
1532
1757
|
marketSlug: params.marketSlug
|
|
1533
1758
|
});
|
|
1759
|
+
let venue = this.marketFetcher.getVenue(params.marketSlug);
|
|
1760
|
+
if (!venue) {
|
|
1761
|
+
this.logger.warn(
|
|
1762
|
+
"Venue not cached, fetching market details. For better performance, call marketFetcher.getMarket() before createOrder().",
|
|
1763
|
+
{ marketSlug: params.marketSlug }
|
|
1764
|
+
);
|
|
1765
|
+
const market = await this.marketFetcher.getMarket(params.marketSlug);
|
|
1766
|
+
if (!market.venue) {
|
|
1767
|
+
throw new Error(
|
|
1768
|
+
`Market ${params.marketSlug} does not have venue information. Venue data is required for order signing.`
|
|
1769
|
+
);
|
|
1770
|
+
}
|
|
1771
|
+
venue = market.venue;
|
|
1772
|
+
}
|
|
1773
|
+
const dynamicSigningConfig = {
|
|
1774
|
+
...this.signingConfig,
|
|
1775
|
+
contractAddress: venue.exchange
|
|
1776
|
+
};
|
|
1777
|
+
this.logger.debug("Using venue for order signing", {
|
|
1778
|
+
marketSlug: params.marketSlug,
|
|
1779
|
+
exchange: venue.exchange,
|
|
1780
|
+
adapter: venue.adapter
|
|
1781
|
+
});
|
|
1534
1782
|
const unsignedOrder = this.orderBuilder.buildOrder(params);
|
|
1535
1783
|
this.logger.debug("Built unsigned order", {
|
|
1536
1784
|
salt: unsignedOrder.salt,
|
|
@@ -1539,7 +1787,7 @@ var OrderClient = class {
|
|
|
1539
1787
|
});
|
|
1540
1788
|
const signature = await this.orderSigner.signOrder(
|
|
1541
1789
|
unsignedOrder,
|
|
1542
|
-
|
|
1790
|
+
dynamicSigningConfig
|
|
1543
1791
|
);
|
|
1544
1792
|
const payload = {
|
|
1545
1793
|
order: {
|
|
@@ -1722,162 +1970,6 @@ var OrderClient = class {
|
|
|
1722
1970
|
}
|
|
1723
1971
|
};
|
|
1724
1972
|
|
|
1725
|
-
// src/markets/fetcher.ts
|
|
1726
|
-
var MarketFetcher = class {
|
|
1727
|
-
/**
|
|
1728
|
-
* Creates a new market fetcher instance.
|
|
1729
|
-
*
|
|
1730
|
-
* @param httpClient - HTTP client for API requests
|
|
1731
|
-
* @param logger - Optional logger for debugging (default: no logging)
|
|
1732
|
-
*
|
|
1733
|
-
* @example
|
|
1734
|
-
* ```typescript
|
|
1735
|
-
* const fetcher = new MarketFetcher(httpClient);
|
|
1736
|
-
* ```
|
|
1737
|
-
*/
|
|
1738
|
-
constructor(httpClient, logger) {
|
|
1739
|
-
this.httpClient = httpClient;
|
|
1740
|
-
this.logger = logger || new NoOpLogger();
|
|
1741
|
-
}
|
|
1742
|
-
/**
|
|
1743
|
-
* Gets active markets with query parameters and pagination support.
|
|
1744
|
-
*
|
|
1745
|
-
* @param params - Query parameters for filtering and pagination
|
|
1746
|
-
* @returns Promise resolving to active markets response
|
|
1747
|
-
* @throws Error if API request fails
|
|
1748
|
-
*
|
|
1749
|
-
* @example
|
|
1750
|
-
* ```typescript
|
|
1751
|
-
* // Get 8 markets sorted by LP rewards
|
|
1752
|
-
* const response = await fetcher.getActiveMarkets({
|
|
1753
|
-
* limit: 8,
|
|
1754
|
-
* sortBy: 'lp_rewards'
|
|
1755
|
-
* });
|
|
1756
|
-
* console.log(`Found ${response.data.length} of ${response.totalMarketsCount} markets`);
|
|
1757
|
-
*
|
|
1758
|
-
* // Get page 2
|
|
1759
|
-
* const page2 = await fetcher.getActiveMarkets({
|
|
1760
|
-
* limit: 8,
|
|
1761
|
-
* page: 2,
|
|
1762
|
-
* sortBy: 'ending_soon'
|
|
1763
|
-
* });
|
|
1764
|
-
* ```
|
|
1765
|
-
*/
|
|
1766
|
-
async getActiveMarkets(params) {
|
|
1767
|
-
const queryParams = new URLSearchParams();
|
|
1768
|
-
if (params?.limit !== void 0) {
|
|
1769
|
-
queryParams.append("limit", params.limit.toString());
|
|
1770
|
-
}
|
|
1771
|
-
if (params?.page !== void 0) {
|
|
1772
|
-
queryParams.append("page", params.page.toString());
|
|
1773
|
-
}
|
|
1774
|
-
if (params?.sortBy) {
|
|
1775
|
-
queryParams.append("sortBy", params.sortBy);
|
|
1776
|
-
}
|
|
1777
|
-
const queryString = queryParams.toString();
|
|
1778
|
-
const endpoint = `/markets/active${queryString ? `?${queryString}` : ""}`;
|
|
1779
|
-
this.logger.debug("Fetching active markets", { params });
|
|
1780
|
-
try {
|
|
1781
|
-
const response = await this.httpClient.get(endpoint);
|
|
1782
|
-
this.logger.info("Active markets fetched successfully", {
|
|
1783
|
-
count: response.data.length,
|
|
1784
|
-
total: response.totalMarketsCount,
|
|
1785
|
-
sortBy: params?.sortBy,
|
|
1786
|
-
page: params?.page
|
|
1787
|
-
});
|
|
1788
|
-
return response;
|
|
1789
|
-
} catch (error) {
|
|
1790
|
-
this.logger.error("Failed to fetch active markets", error, { params });
|
|
1791
|
-
throw error;
|
|
1792
|
-
}
|
|
1793
|
-
}
|
|
1794
|
-
/**
|
|
1795
|
-
* Gets a single market by slug.
|
|
1796
|
-
*
|
|
1797
|
-
* @param slug - Market slug identifier
|
|
1798
|
-
* @returns Promise resolving to market details
|
|
1799
|
-
* @throws Error if API request fails or market not found
|
|
1800
|
-
*
|
|
1801
|
-
* @example
|
|
1802
|
-
* ```typescript
|
|
1803
|
-
* const market = await fetcher.getMarket('bitcoin-price-2024');
|
|
1804
|
-
* console.log(`Market: ${market.title}`);
|
|
1805
|
-
* ```
|
|
1806
|
-
*/
|
|
1807
|
-
async getMarket(slug) {
|
|
1808
|
-
this.logger.debug("Fetching market", { slug });
|
|
1809
|
-
try {
|
|
1810
|
-
const market = await this.httpClient.get(`/markets/${slug}`);
|
|
1811
|
-
this.logger.info("Market fetched successfully", {
|
|
1812
|
-
slug,
|
|
1813
|
-
title: market.title
|
|
1814
|
-
});
|
|
1815
|
-
return market;
|
|
1816
|
-
} catch (error) {
|
|
1817
|
-
this.logger.error("Failed to fetch market", error, { slug });
|
|
1818
|
-
throw error;
|
|
1819
|
-
}
|
|
1820
|
-
}
|
|
1821
|
-
/**
|
|
1822
|
-
* Gets the orderbook for a CLOB market.
|
|
1823
|
-
*
|
|
1824
|
-
* @param slug - Market slug identifier
|
|
1825
|
-
* @returns Promise resolving to orderbook data
|
|
1826
|
-
* @throws Error if API request fails
|
|
1827
|
-
*
|
|
1828
|
-
* @example
|
|
1829
|
-
* ```typescript
|
|
1830
|
-
* const orderbook = await fetcher.getOrderBook('bitcoin-price-2024');
|
|
1831
|
-
* console.log(`Bids: ${orderbook.bids.length}, Asks: ${orderbook.asks.length}`);
|
|
1832
|
-
* ```
|
|
1833
|
-
*/
|
|
1834
|
-
async getOrderBook(slug) {
|
|
1835
|
-
this.logger.debug("Fetching orderbook", { slug });
|
|
1836
|
-
try {
|
|
1837
|
-
const orderbook = await this.httpClient.get(
|
|
1838
|
-
`/markets/${slug}/orderbook`
|
|
1839
|
-
);
|
|
1840
|
-
this.logger.info("Orderbook fetched successfully", {
|
|
1841
|
-
slug,
|
|
1842
|
-
bids: orderbook.bids.length,
|
|
1843
|
-
asks: orderbook.asks.length,
|
|
1844
|
-
tokenId: orderbook.tokenId
|
|
1845
|
-
});
|
|
1846
|
-
return orderbook;
|
|
1847
|
-
} catch (error) {
|
|
1848
|
-
this.logger.error("Failed to fetch orderbook", error, { slug });
|
|
1849
|
-
throw error;
|
|
1850
|
-
}
|
|
1851
|
-
}
|
|
1852
|
-
/**
|
|
1853
|
-
* Gets the current price for a token.
|
|
1854
|
-
*
|
|
1855
|
-
* @param tokenId - Token ID
|
|
1856
|
-
* @returns Promise resolving to price information
|
|
1857
|
-
* @throws Error if API request fails
|
|
1858
|
-
*
|
|
1859
|
-
* @example
|
|
1860
|
-
* ```typescript
|
|
1861
|
-
* const price = await fetcher.getPrice('123456');
|
|
1862
|
-
* console.log(`Current price: ${price.price}`);
|
|
1863
|
-
* ```
|
|
1864
|
-
*/
|
|
1865
|
-
async getPrice(tokenId) {
|
|
1866
|
-
this.logger.debug("Fetching price", { tokenId });
|
|
1867
|
-
try {
|
|
1868
|
-
const price = await this.httpClient.get(`/prices/${tokenId}`);
|
|
1869
|
-
this.logger.info("Price fetched successfully", {
|
|
1870
|
-
tokenId,
|
|
1871
|
-
price: price.price
|
|
1872
|
-
});
|
|
1873
|
-
return price;
|
|
1874
|
-
} catch (error) {
|
|
1875
|
-
this.logger.error("Failed to fetch price", error, { tokenId });
|
|
1876
|
-
throw error;
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1879
|
-
};
|
|
1880
|
-
|
|
1881
1973
|
// src/portfolio/fetcher.ts
|
|
1882
1974
|
var PortfolioFetcher = class {
|
|
1883
1975
|
/**
|
|
@@ -2528,7 +2620,6 @@ var WebSocketClient = class {
|
|
|
2528
2620
|
DEFAULT_WS_URL,
|
|
2529
2621
|
HttpClient,
|
|
2530
2622
|
MarketFetcher,
|
|
2531
|
-
MarketType,
|
|
2532
2623
|
MessageSigner,
|
|
2533
2624
|
NoOpLogger,
|
|
2534
2625
|
OrderBuilder,
|