@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.mjs
CHANGED
|
@@ -46,16 +46,11 @@ var Side = /* @__PURE__ */ ((Side2) => {
|
|
|
46
46
|
Side2[Side2["SELL"] = 1] = "SELL";
|
|
47
47
|
return Side2;
|
|
48
48
|
})(Side || {});
|
|
49
|
-
var OrderType = /* @__PURE__ */ ((
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return
|
|
49
|
+
var OrderType = /* @__PURE__ */ ((OrderType2) => {
|
|
50
|
+
OrderType2["FOK"] = "FOK";
|
|
51
|
+
OrderType2["GTC"] = "GTC";
|
|
52
|
+
return OrderType2;
|
|
53
53
|
})(OrderType || {});
|
|
54
|
-
var MarketType = /* @__PURE__ */ ((MarketType3) => {
|
|
55
|
-
MarketType3["CLOB"] = "CLOB";
|
|
56
|
-
MarketType3["NEGRISK"] = "NEGRISK";
|
|
57
|
-
return MarketType3;
|
|
58
|
-
})(MarketType || {});
|
|
59
54
|
var SignatureType = /* @__PURE__ */ ((SignatureType2) => {
|
|
60
55
|
SignatureType2[SignatureType2["EOA"] = 0] = "EOA";
|
|
61
56
|
SignatureType2[SignatureType2["POLY_PROXY"] = 1] = "POLY_PROXY";
|
|
@@ -435,6 +430,8 @@ var AuthenticatedClient = class {
|
|
|
435
430
|
|
|
436
431
|
// src/api/http.ts
|
|
437
432
|
import axios from "axios";
|
|
433
|
+
import http from "http";
|
|
434
|
+
import https from "https";
|
|
438
435
|
|
|
439
436
|
// src/utils/constants.ts
|
|
440
437
|
var DEFAULT_API_URL = "https://api.limitless.exchange";
|
|
@@ -446,24 +443,31 @@ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
|
446
443
|
var CONTRACT_ADDRESSES = {
|
|
447
444
|
// Base mainnet (chainId: 8453)
|
|
448
445
|
8453: {
|
|
449
|
-
|
|
450
|
-
|
|
446
|
+
USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
447
|
+
// Native USDC on Base
|
|
448
|
+
CTF: "0xC9c98965297Bc527861c898329Ee280632B76e18"
|
|
449
|
+
// Conditional Token Framework
|
|
451
450
|
},
|
|
452
451
|
// Base Sepolia testnet (chainId: 84532)
|
|
453
452
|
84532: {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
NEGRISK: "0x..."
|
|
453
|
+
USDC: "0x...",
|
|
454
|
+
CTF: "0x..."
|
|
457
455
|
}
|
|
458
456
|
};
|
|
459
|
-
function getContractAddress(
|
|
457
|
+
function getContractAddress(contractType, chainId = DEFAULT_CHAIN_ID) {
|
|
460
458
|
const addresses = CONTRACT_ADDRESSES[chainId];
|
|
461
459
|
if (!addresses) {
|
|
462
460
|
throw new Error(
|
|
463
461
|
`No contract addresses configured for chainId ${chainId}. Supported chains: ${Object.keys(CONTRACT_ADDRESSES).join(", ")}`
|
|
464
462
|
);
|
|
465
463
|
}
|
|
466
|
-
|
|
464
|
+
const address = addresses[contractType];
|
|
465
|
+
if (!address || address === "0x...") {
|
|
466
|
+
throw new Error(
|
|
467
|
+
`Contract address for ${contractType} not available on chainId ${chainId}. Please configure the address in constants.ts or use environment variables.`
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
return address;
|
|
467
471
|
}
|
|
468
472
|
|
|
469
473
|
// src/api/http.ts
|
|
@@ -476,14 +480,39 @@ var HttpClient = class {
|
|
|
476
480
|
constructor(config = {}) {
|
|
477
481
|
this.sessionCookie = config.sessionCookie;
|
|
478
482
|
this.logger = config.logger || new NoOpLogger();
|
|
483
|
+
const keepAlive = config.keepAlive !== false;
|
|
484
|
+
const maxSockets = config.maxSockets || 50;
|
|
485
|
+
const maxFreeSockets = config.maxFreeSockets || 10;
|
|
486
|
+
const socketTimeout = config.socketTimeout || 6e4;
|
|
487
|
+
const httpAgent = new http.Agent({
|
|
488
|
+
keepAlive,
|
|
489
|
+
maxSockets,
|
|
490
|
+
maxFreeSockets,
|
|
491
|
+
timeout: socketTimeout
|
|
492
|
+
});
|
|
493
|
+
const httpsAgent = new https.Agent({
|
|
494
|
+
keepAlive,
|
|
495
|
+
maxSockets,
|
|
496
|
+
maxFreeSockets,
|
|
497
|
+
timeout: socketTimeout
|
|
498
|
+
});
|
|
479
499
|
this.client = axios.create({
|
|
480
500
|
baseURL: config.baseURL || DEFAULT_API_URL,
|
|
481
501
|
timeout: config.timeout || 3e4,
|
|
502
|
+
httpAgent,
|
|
503
|
+
httpsAgent,
|
|
482
504
|
headers: {
|
|
483
505
|
"Content-Type": "application/json",
|
|
484
|
-
Accept: "application/json"
|
|
506
|
+
Accept: "application/json",
|
|
507
|
+
...config.additionalHeaders
|
|
485
508
|
}
|
|
486
509
|
});
|
|
510
|
+
this.logger.debug("HTTP client initialized", {
|
|
511
|
+
baseURL: config.baseURL || DEFAULT_API_URL,
|
|
512
|
+
keepAlive,
|
|
513
|
+
maxSockets,
|
|
514
|
+
maxFreeSockets
|
|
515
|
+
});
|
|
487
516
|
this.setupInterceptors();
|
|
488
517
|
}
|
|
489
518
|
/**
|
|
@@ -864,8 +893,7 @@ var OrderBuilder = class {
|
|
|
864
893
|
* const fokOrder = builder.buildOrder({
|
|
865
894
|
* tokenId: '123456',
|
|
866
895
|
* makerAmount: 50, // 50 USDC to spend
|
|
867
|
-
* side: Side.BUY
|
|
868
|
-
* marketType: MarketType.CLOB
|
|
896
|
+
* side: Side.BUY
|
|
869
897
|
* });
|
|
870
898
|
*
|
|
871
899
|
* // GTC order (price + size)
|
|
@@ -873,8 +901,7 @@ var OrderBuilder = class {
|
|
|
873
901
|
* tokenId: '123456',
|
|
874
902
|
* price: 0.38,
|
|
875
903
|
* size: 22.123, // Will be rounded to tick-aligned: 22.123 shares
|
|
876
|
-
* side: Side.BUY
|
|
877
|
-
* marketType: MarketType.CLOB
|
|
904
|
+
* side: Side.BUY
|
|
878
905
|
* });
|
|
879
906
|
* ```
|
|
880
907
|
*/
|
|
@@ -1149,8 +1176,7 @@ var OrderSigner = class {
|
|
|
1149
1176
|
* ```typescript
|
|
1150
1177
|
* const signature = await signer.signOrder(unsignedOrder, {
|
|
1151
1178
|
* chainId: 8453,
|
|
1152
|
-
* contractAddress: '0x...'
|
|
1153
|
-
* marketType: MarketType.CLOB
|
|
1179
|
+
* contractAddress: '0x...'
|
|
1154
1180
|
* });
|
|
1155
1181
|
* ```
|
|
1156
1182
|
*/
|
|
@@ -1158,7 +1184,7 @@ var OrderSigner = class {
|
|
|
1158
1184
|
this.logger.debug("Signing order with EIP-712", {
|
|
1159
1185
|
tokenId: order.tokenId,
|
|
1160
1186
|
side: order.side,
|
|
1161
|
-
|
|
1187
|
+
verifyingContract: config.contractAddress
|
|
1162
1188
|
});
|
|
1163
1189
|
const walletAddress = await this.wallet.getAddress();
|
|
1164
1190
|
if (walletAddress.toLowerCase() !== order.signer.toLowerCase()) {
|
|
@@ -1383,14 +1409,221 @@ function validateSignedOrder(order) {
|
|
|
1383
1409
|
}
|
|
1384
1410
|
}
|
|
1385
1411
|
|
|
1412
|
+
// src/markets/fetcher.ts
|
|
1413
|
+
var MarketFetcher = class {
|
|
1414
|
+
/**
|
|
1415
|
+
* Creates a new market fetcher instance.
|
|
1416
|
+
*
|
|
1417
|
+
* @param httpClient - HTTP client for API requests
|
|
1418
|
+
* @param logger - Optional logger for debugging (default: no logging)
|
|
1419
|
+
*
|
|
1420
|
+
* @example
|
|
1421
|
+
* ```typescript
|
|
1422
|
+
* const fetcher = new MarketFetcher(httpClient);
|
|
1423
|
+
* ```
|
|
1424
|
+
*/
|
|
1425
|
+
constructor(httpClient, logger) {
|
|
1426
|
+
this.httpClient = httpClient;
|
|
1427
|
+
this.logger = logger || new NoOpLogger();
|
|
1428
|
+
this.venueCache = /* @__PURE__ */ new Map();
|
|
1429
|
+
}
|
|
1430
|
+
/**
|
|
1431
|
+
* Gets active markets with query parameters and pagination support.
|
|
1432
|
+
*
|
|
1433
|
+
* @param params - Query parameters for filtering and pagination
|
|
1434
|
+
* @returns Promise resolving to active markets response
|
|
1435
|
+
* @throws Error if API request fails
|
|
1436
|
+
*
|
|
1437
|
+
* @example
|
|
1438
|
+
* ```typescript
|
|
1439
|
+
* // Get 8 markets sorted by LP rewards
|
|
1440
|
+
* const response = await fetcher.getActiveMarkets({
|
|
1441
|
+
* limit: 8,
|
|
1442
|
+
* sortBy: 'lp_rewards'
|
|
1443
|
+
* });
|
|
1444
|
+
* console.log(`Found ${response.data.length} of ${response.totalMarketsCount} markets`);
|
|
1445
|
+
*
|
|
1446
|
+
* // Get page 2
|
|
1447
|
+
* const page2 = await fetcher.getActiveMarkets({
|
|
1448
|
+
* limit: 8,
|
|
1449
|
+
* page: 2,
|
|
1450
|
+
* sortBy: 'ending_soon'
|
|
1451
|
+
* });
|
|
1452
|
+
* ```
|
|
1453
|
+
*/
|
|
1454
|
+
async getActiveMarkets(params) {
|
|
1455
|
+
const queryParams = new URLSearchParams();
|
|
1456
|
+
if (params?.limit !== void 0) {
|
|
1457
|
+
queryParams.append("limit", params.limit.toString());
|
|
1458
|
+
}
|
|
1459
|
+
if (params?.page !== void 0) {
|
|
1460
|
+
queryParams.append("page", params.page.toString());
|
|
1461
|
+
}
|
|
1462
|
+
if (params?.sortBy) {
|
|
1463
|
+
queryParams.append("sortBy", params.sortBy);
|
|
1464
|
+
}
|
|
1465
|
+
const queryString = queryParams.toString();
|
|
1466
|
+
const endpoint = `/markets/active${queryString ? `?${queryString}` : ""}`;
|
|
1467
|
+
this.logger.debug("Fetching active markets", { params });
|
|
1468
|
+
try {
|
|
1469
|
+
const response = await this.httpClient.get(endpoint);
|
|
1470
|
+
this.logger.info("Active markets fetched successfully", {
|
|
1471
|
+
count: response.data.length,
|
|
1472
|
+
total: response.totalMarketsCount,
|
|
1473
|
+
sortBy: params?.sortBy,
|
|
1474
|
+
page: params?.page
|
|
1475
|
+
});
|
|
1476
|
+
return response;
|
|
1477
|
+
} catch (error) {
|
|
1478
|
+
this.logger.error("Failed to fetch active markets", error, { params });
|
|
1479
|
+
throw error;
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
/**
|
|
1483
|
+
* Gets a single market by slug.
|
|
1484
|
+
*
|
|
1485
|
+
* @remarks
|
|
1486
|
+
* Automatically caches venue information for efficient order signing.
|
|
1487
|
+
* Always call this method before creating orders to ensure venue data
|
|
1488
|
+
* is available and avoid additional API requests.
|
|
1489
|
+
*
|
|
1490
|
+
* @param slug - Market slug identifier
|
|
1491
|
+
* @returns Promise resolving to market details
|
|
1492
|
+
* @throws Error if API request fails or market not found
|
|
1493
|
+
*
|
|
1494
|
+
* @example
|
|
1495
|
+
* ```typescript
|
|
1496
|
+
* const market = await fetcher.getMarket('bitcoin-price-2024');
|
|
1497
|
+
* console.log(`Market: ${market.title}`);
|
|
1498
|
+
*
|
|
1499
|
+
* // Venue is now cached for order signing
|
|
1500
|
+
* await orderClient.createOrder({
|
|
1501
|
+
* marketSlug: 'bitcoin-price-2024',
|
|
1502
|
+
* ...
|
|
1503
|
+
* });
|
|
1504
|
+
* ```
|
|
1505
|
+
*/
|
|
1506
|
+
async getMarket(slug) {
|
|
1507
|
+
this.logger.debug("Fetching market", { slug });
|
|
1508
|
+
try {
|
|
1509
|
+
const market = await this.httpClient.get(`/markets/${slug}`);
|
|
1510
|
+
if (market.venue) {
|
|
1511
|
+
this.venueCache.set(slug, market.venue);
|
|
1512
|
+
this.logger.debug("Venue cached for order signing", {
|
|
1513
|
+
slug,
|
|
1514
|
+
exchange: market.venue.exchange,
|
|
1515
|
+
adapter: market.venue.adapter,
|
|
1516
|
+
cacheSize: this.venueCache.size
|
|
1517
|
+
});
|
|
1518
|
+
} else {
|
|
1519
|
+
this.logger.warn("Market has no venue data", { slug });
|
|
1520
|
+
}
|
|
1521
|
+
this.logger.info("Market fetched successfully", {
|
|
1522
|
+
slug,
|
|
1523
|
+
title: market.title
|
|
1524
|
+
});
|
|
1525
|
+
return market;
|
|
1526
|
+
} catch (error) {
|
|
1527
|
+
this.logger.error("Failed to fetch market", error, { slug });
|
|
1528
|
+
throw error;
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
/**
|
|
1532
|
+
* Gets cached venue information for a market.
|
|
1533
|
+
*
|
|
1534
|
+
* @remarks
|
|
1535
|
+
* Returns venue data previously cached by getMarket() call.
|
|
1536
|
+
* Used internally by OrderClient for efficient order signing.
|
|
1537
|
+
*
|
|
1538
|
+
* @param slug - Market slug identifier
|
|
1539
|
+
* @returns Cached venue information, or undefined if not in cache
|
|
1540
|
+
*
|
|
1541
|
+
* @example
|
|
1542
|
+
* ```typescript
|
|
1543
|
+
* const venue = fetcher.getVenue('bitcoin-price-2024');
|
|
1544
|
+
* if (venue) {
|
|
1545
|
+
* console.log(`Exchange: ${venue.exchange}`);
|
|
1546
|
+
* }
|
|
1547
|
+
* ```
|
|
1548
|
+
*/
|
|
1549
|
+
getVenue(slug) {
|
|
1550
|
+
const venue = this.venueCache.get(slug);
|
|
1551
|
+
if (venue) {
|
|
1552
|
+
this.logger.debug("Venue cache hit", {
|
|
1553
|
+
slug,
|
|
1554
|
+
exchange: venue.exchange
|
|
1555
|
+
});
|
|
1556
|
+
} else {
|
|
1557
|
+
this.logger.debug("Venue cache miss", { slug });
|
|
1558
|
+
}
|
|
1559
|
+
return venue;
|
|
1560
|
+
}
|
|
1561
|
+
/**
|
|
1562
|
+
* Gets the orderbook for a CLOB market.
|
|
1563
|
+
*
|
|
1564
|
+
* @param slug - Market slug identifier
|
|
1565
|
+
* @returns Promise resolving to orderbook data
|
|
1566
|
+
* @throws Error if API request fails
|
|
1567
|
+
*
|
|
1568
|
+
* @example
|
|
1569
|
+
* ```typescript
|
|
1570
|
+
* const orderbook = await fetcher.getOrderBook('bitcoin-price-2024');
|
|
1571
|
+
* console.log(`Bids: ${orderbook.bids.length}, Asks: ${orderbook.asks.length}`);
|
|
1572
|
+
* ```
|
|
1573
|
+
*/
|
|
1574
|
+
async getOrderBook(slug) {
|
|
1575
|
+
this.logger.debug("Fetching orderbook", { slug });
|
|
1576
|
+
try {
|
|
1577
|
+
const orderbook = await this.httpClient.get(
|
|
1578
|
+
`/markets/${slug}/orderbook`
|
|
1579
|
+
);
|
|
1580
|
+
this.logger.info("Orderbook fetched successfully", {
|
|
1581
|
+
slug,
|
|
1582
|
+
bids: orderbook.bids.length,
|
|
1583
|
+
asks: orderbook.asks.length,
|
|
1584
|
+
tokenId: orderbook.tokenId
|
|
1585
|
+
});
|
|
1586
|
+
return orderbook;
|
|
1587
|
+
} catch (error) {
|
|
1588
|
+
this.logger.error("Failed to fetch orderbook", error, { slug });
|
|
1589
|
+
throw error;
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
/**
|
|
1593
|
+
* Gets the current price for a token.
|
|
1594
|
+
*
|
|
1595
|
+
* @param tokenId - Token ID
|
|
1596
|
+
* @returns Promise resolving to price information
|
|
1597
|
+
* @throws Error if API request fails
|
|
1598
|
+
*
|
|
1599
|
+
* @example
|
|
1600
|
+
* ```typescript
|
|
1601
|
+
* const price = await fetcher.getPrice('123456');
|
|
1602
|
+
* console.log(`Current price: ${price.price}`);
|
|
1603
|
+
* ```
|
|
1604
|
+
*/
|
|
1605
|
+
async getPrice(tokenId) {
|
|
1606
|
+
this.logger.debug("Fetching price", { tokenId });
|
|
1607
|
+
try {
|
|
1608
|
+
const price = await this.httpClient.get(`/prices/${tokenId}`);
|
|
1609
|
+
this.logger.info("Price fetched successfully", {
|
|
1610
|
+
tokenId,
|
|
1611
|
+
price: price.price
|
|
1612
|
+
});
|
|
1613
|
+
return price;
|
|
1614
|
+
} catch (error) {
|
|
1615
|
+
this.logger.error("Failed to fetch price", error, { tokenId });
|
|
1616
|
+
throw error;
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
};
|
|
1620
|
+
|
|
1386
1621
|
// src/orders/client.ts
|
|
1387
1622
|
var OrderClient = class {
|
|
1388
1623
|
/**
|
|
1389
1624
|
* Creates a new order client instance.
|
|
1390
1625
|
*
|
|
1391
1626
|
* @param config - Order client configuration
|
|
1392
|
-
*
|
|
1393
|
-
* @throws Error if neither marketType nor signingConfig is provided
|
|
1394
1627
|
*/
|
|
1395
1628
|
constructor(config) {
|
|
1396
1629
|
this.httpClient = config.httpClient;
|
|
@@ -1399,32 +1632,18 @@ var OrderClient = class {
|
|
|
1399
1632
|
const feeRateBps = config.userData.feeRateBps;
|
|
1400
1633
|
this.orderBuilder = new OrderBuilder(config.wallet.address, feeRateBps, 1e-3);
|
|
1401
1634
|
this.orderSigner = new OrderSigner(config.wallet, this.logger);
|
|
1635
|
+
this.marketFetcher = config.marketFetcher || new MarketFetcher(config.httpClient, this.logger);
|
|
1402
1636
|
if (config.signingConfig) {
|
|
1403
1637
|
this.signingConfig = config.signingConfig;
|
|
1404
|
-
} else if (config.marketType) {
|
|
1405
|
-
const chainId = parseInt(process.env.CHAIN_ID || "8453");
|
|
1406
|
-
const contractAddress = config.marketType === "NEGRISK" /* NEGRISK */ ? process.env.NEGRISK_CONTRACT_ADDRESS || getContractAddress("NEGRISK", chainId) : process.env.CLOB_CONTRACT_ADDRESS || getContractAddress("CLOB", chainId);
|
|
1407
|
-
this.signingConfig = {
|
|
1408
|
-
chainId,
|
|
1409
|
-
contractAddress,
|
|
1410
|
-
marketType: config.marketType
|
|
1411
|
-
};
|
|
1412
|
-
this.logger.info("Auto-configured signing", {
|
|
1413
|
-
chainId,
|
|
1414
|
-
contractAddress,
|
|
1415
|
-
marketType: config.marketType
|
|
1416
|
-
});
|
|
1417
1638
|
} else {
|
|
1418
1639
|
const chainId = parseInt(process.env.CHAIN_ID || "8453");
|
|
1419
|
-
const contractAddress =
|
|
1640
|
+
const contractAddress = ZERO_ADDRESS;
|
|
1420
1641
|
this.signingConfig = {
|
|
1421
|
-
chainId,
|
|
1422
|
-
contractAddress,
|
|
1423
|
-
marketType: "CLOB" /* CLOB */
|
|
1424
|
-
};
|
|
1425
|
-
this.logger.debug("Using default CLOB configuration", {
|
|
1426
1642
|
chainId,
|
|
1427
1643
|
contractAddress
|
|
1644
|
+
};
|
|
1645
|
+
this.logger.info("Auto-configured signing (contract address from venue)", {
|
|
1646
|
+
chainId
|
|
1428
1647
|
});
|
|
1429
1648
|
}
|
|
1430
1649
|
}
|
|
@@ -1433,24 +1652,31 @@ var OrderClient = class {
|
|
|
1433
1652
|
*
|
|
1434
1653
|
* @remarks
|
|
1435
1654
|
* This method handles the complete order creation flow:
|
|
1436
|
-
* 1.
|
|
1437
|
-
* 2.
|
|
1438
|
-
* 3.
|
|
1655
|
+
* 1. Resolve venue address (from cache or API)
|
|
1656
|
+
* 2. Build unsigned order
|
|
1657
|
+
* 3. Sign with EIP-712 using venue.exchange as verifyingContract
|
|
1658
|
+
* 4. Submit to API
|
|
1659
|
+
*
|
|
1660
|
+
* Performance best practice: Always call marketFetcher.getMarket(marketSlug)
|
|
1661
|
+
* before createOrder() to cache venue data and avoid additional API requests.
|
|
1439
1662
|
*
|
|
1440
1663
|
* @param params - Order parameters
|
|
1441
1664
|
* @returns Promise resolving to order response
|
|
1442
1665
|
*
|
|
1443
|
-
* @throws Error if order creation fails
|
|
1666
|
+
* @throws Error if order creation fails or venue not found
|
|
1444
1667
|
*
|
|
1445
1668
|
* @example
|
|
1446
1669
|
* ```typescript
|
|
1670
|
+
* // Best practice: fetch market first to cache venue
|
|
1671
|
+
* const market = await marketFetcher.getMarket('bitcoin-2024');
|
|
1672
|
+
*
|
|
1447
1673
|
* const order = await orderClient.createOrder({
|
|
1448
|
-
* tokenId:
|
|
1674
|
+
* tokenId: market.tokens.yes,
|
|
1449
1675
|
* price: 0.65,
|
|
1450
1676
|
* size: 100,
|
|
1451
1677
|
* side: Side.BUY,
|
|
1452
1678
|
* orderType: OrderType.GTC,
|
|
1453
|
-
* marketSlug: '
|
|
1679
|
+
* marketSlug: 'bitcoin-2024'
|
|
1454
1680
|
* });
|
|
1455
1681
|
*
|
|
1456
1682
|
* console.log(`Order created: ${order.order.id}`);
|
|
@@ -1462,6 +1688,29 @@ var OrderClient = class {
|
|
|
1462
1688
|
orderType: params.orderType,
|
|
1463
1689
|
marketSlug: params.marketSlug
|
|
1464
1690
|
});
|
|
1691
|
+
let venue = this.marketFetcher.getVenue(params.marketSlug);
|
|
1692
|
+
if (!venue) {
|
|
1693
|
+
this.logger.warn(
|
|
1694
|
+
"Venue not cached, fetching market details. For better performance, call marketFetcher.getMarket() before createOrder().",
|
|
1695
|
+
{ marketSlug: params.marketSlug }
|
|
1696
|
+
);
|
|
1697
|
+
const market = await this.marketFetcher.getMarket(params.marketSlug);
|
|
1698
|
+
if (!market.venue) {
|
|
1699
|
+
throw new Error(
|
|
1700
|
+
`Market ${params.marketSlug} does not have venue information. Venue data is required for order signing.`
|
|
1701
|
+
);
|
|
1702
|
+
}
|
|
1703
|
+
venue = market.venue;
|
|
1704
|
+
}
|
|
1705
|
+
const dynamicSigningConfig = {
|
|
1706
|
+
...this.signingConfig,
|
|
1707
|
+
contractAddress: venue.exchange
|
|
1708
|
+
};
|
|
1709
|
+
this.logger.debug("Using venue for order signing", {
|
|
1710
|
+
marketSlug: params.marketSlug,
|
|
1711
|
+
exchange: venue.exchange,
|
|
1712
|
+
adapter: venue.adapter
|
|
1713
|
+
});
|
|
1465
1714
|
const unsignedOrder = this.orderBuilder.buildOrder(params);
|
|
1466
1715
|
this.logger.debug("Built unsigned order", {
|
|
1467
1716
|
salt: unsignedOrder.salt,
|
|
@@ -1470,7 +1719,7 @@ var OrderClient = class {
|
|
|
1470
1719
|
});
|
|
1471
1720
|
const signature = await this.orderSigner.signOrder(
|
|
1472
1721
|
unsignedOrder,
|
|
1473
|
-
|
|
1722
|
+
dynamicSigningConfig
|
|
1474
1723
|
);
|
|
1475
1724
|
const payload = {
|
|
1476
1725
|
order: {
|
|
@@ -1653,162 +1902,6 @@ var OrderClient = class {
|
|
|
1653
1902
|
}
|
|
1654
1903
|
};
|
|
1655
1904
|
|
|
1656
|
-
// src/markets/fetcher.ts
|
|
1657
|
-
var MarketFetcher = class {
|
|
1658
|
-
/**
|
|
1659
|
-
* Creates a new market fetcher instance.
|
|
1660
|
-
*
|
|
1661
|
-
* @param httpClient - HTTP client for API requests
|
|
1662
|
-
* @param logger - Optional logger for debugging (default: no logging)
|
|
1663
|
-
*
|
|
1664
|
-
* @example
|
|
1665
|
-
* ```typescript
|
|
1666
|
-
* const fetcher = new MarketFetcher(httpClient);
|
|
1667
|
-
* ```
|
|
1668
|
-
*/
|
|
1669
|
-
constructor(httpClient, logger) {
|
|
1670
|
-
this.httpClient = httpClient;
|
|
1671
|
-
this.logger = logger || new NoOpLogger();
|
|
1672
|
-
}
|
|
1673
|
-
/**
|
|
1674
|
-
* Gets active markets with query parameters and pagination support.
|
|
1675
|
-
*
|
|
1676
|
-
* @param params - Query parameters for filtering and pagination
|
|
1677
|
-
* @returns Promise resolving to active markets response
|
|
1678
|
-
* @throws Error if API request fails
|
|
1679
|
-
*
|
|
1680
|
-
* @example
|
|
1681
|
-
* ```typescript
|
|
1682
|
-
* // Get 8 markets sorted by LP rewards
|
|
1683
|
-
* const response = await fetcher.getActiveMarkets({
|
|
1684
|
-
* limit: 8,
|
|
1685
|
-
* sortBy: 'lp_rewards'
|
|
1686
|
-
* });
|
|
1687
|
-
* console.log(`Found ${response.data.length} of ${response.totalMarketsCount} markets`);
|
|
1688
|
-
*
|
|
1689
|
-
* // Get page 2
|
|
1690
|
-
* const page2 = await fetcher.getActiveMarkets({
|
|
1691
|
-
* limit: 8,
|
|
1692
|
-
* page: 2,
|
|
1693
|
-
* sortBy: 'ending_soon'
|
|
1694
|
-
* });
|
|
1695
|
-
* ```
|
|
1696
|
-
*/
|
|
1697
|
-
async getActiveMarkets(params) {
|
|
1698
|
-
const queryParams = new URLSearchParams();
|
|
1699
|
-
if (params?.limit !== void 0) {
|
|
1700
|
-
queryParams.append("limit", params.limit.toString());
|
|
1701
|
-
}
|
|
1702
|
-
if (params?.page !== void 0) {
|
|
1703
|
-
queryParams.append("page", params.page.toString());
|
|
1704
|
-
}
|
|
1705
|
-
if (params?.sortBy) {
|
|
1706
|
-
queryParams.append("sortBy", params.sortBy);
|
|
1707
|
-
}
|
|
1708
|
-
const queryString = queryParams.toString();
|
|
1709
|
-
const endpoint = `/markets/active${queryString ? `?${queryString}` : ""}`;
|
|
1710
|
-
this.logger.debug("Fetching active markets", { params });
|
|
1711
|
-
try {
|
|
1712
|
-
const response = await this.httpClient.get(endpoint);
|
|
1713
|
-
this.logger.info("Active markets fetched successfully", {
|
|
1714
|
-
count: response.data.length,
|
|
1715
|
-
total: response.totalMarketsCount,
|
|
1716
|
-
sortBy: params?.sortBy,
|
|
1717
|
-
page: params?.page
|
|
1718
|
-
});
|
|
1719
|
-
return response;
|
|
1720
|
-
} catch (error) {
|
|
1721
|
-
this.logger.error("Failed to fetch active markets", error, { params });
|
|
1722
|
-
throw error;
|
|
1723
|
-
}
|
|
1724
|
-
}
|
|
1725
|
-
/**
|
|
1726
|
-
* Gets a single market by slug.
|
|
1727
|
-
*
|
|
1728
|
-
* @param slug - Market slug identifier
|
|
1729
|
-
* @returns Promise resolving to market details
|
|
1730
|
-
* @throws Error if API request fails or market not found
|
|
1731
|
-
*
|
|
1732
|
-
* @example
|
|
1733
|
-
* ```typescript
|
|
1734
|
-
* const market = await fetcher.getMarket('bitcoin-price-2024');
|
|
1735
|
-
* console.log(`Market: ${market.title}`);
|
|
1736
|
-
* ```
|
|
1737
|
-
*/
|
|
1738
|
-
async getMarket(slug) {
|
|
1739
|
-
this.logger.debug("Fetching market", { slug });
|
|
1740
|
-
try {
|
|
1741
|
-
const market = await this.httpClient.get(`/markets/${slug}`);
|
|
1742
|
-
this.logger.info("Market fetched successfully", {
|
|
1743
|
-
slug,
|
|
1744
|
-
title: market.title
|
|
1745
|
-
});
|
|
1746
|
-
return market;
|
|
1747
|
-
} catch (error) {
|
|
1748
|
-
this.logger.error("Failed to fetch market", error, { slug });
|
|
1749
|
-
throw error;
|
|
1750
|
-
}
|
|
1751
|
-
}
|
|
1752
|
-
/**
|
|
1753
|
-
* Gets the orderbook for a CLOB market.
|
|
1754
|
-
*
|
|
1755
|
-
* @param slug - Market slug identifier
|
|
1756
|
-
* @returns Promise resolving to orderbook data
|
|
1757
|
-
* @throws Error if API request fails
|
|
1758
|
-
*
|
|
1759
|
-
* @example
|
|
1760
|
-
* ```typescript
|
|
1761
|
-
* const orderbook = await fetcher.getOrderBook('bitcoin-price-2024');
|
|
1762
|
-
* console.log(`Bids: ${orderbook.bids.length}, Asks: ${orderbook.asks.length}`);
|
|
1763
|
-
* ```
|
|
1764
|
-
*/
|
|
1765
|
-
async getOrderBook(slug) {
|
|
1766
|
-
this.logger.debug("Fetching orderbook", { slug });
|
|
1767
|
-
try {
|
|
1768
|
-
const orderbook = await this.httpClient.get(
|
|
1769
|
-
`/markets/${slug}/orderbook`
|
|
1770
|
-
);
|
|
1771
|
-
this.logger.info("Orderbook fetched successfully", {
|
|
1772
|
-
slug,
|
|
1773
|
-
bids: orderbook.bids.length,
|
|
1774
|
-
asks: orderbook.asks.length,
|
|
1775
|
-
tokenId: orderbook.tokenId
|
|
1776
|
-
});
|
|
1777
|
-
return orderbook;
|
|
1778
|
-
} catch (error) {
|
|
1779
|
-
this.logger.error("Failed to fetch orderbook", error, { slug });
|
|
1780
|
-
throw error;
|
|
1781
|
-
}
|
|
1782
|
-
}
|
|
1783
|
-
/**
|
|
1784
|
-
* Gets the current price for a token.
|
|
1785
|
-
*
|
|
1786
|
-
* @param tokenId - Token ID
|
|
1787
|
-
* @returns Promise resolving to price information
|
|
1788
|
-
* @throws Error if API request fails
|
|
1789
|
-
*
|
|
1790
|
-
* @example
|
|
1791
|
-
* ```typescript
|
|
1792
|
-
* const price = await fetcher.getPrice('123456');
|
|
1793
|
-
* console.log(`Current price: ${price.price}`);
|
|
1794
|
-
* ```
|
|
1795
|
-
*/
|
|
1796
|
-
async getPrice(tokenId) {
|
|
1797
|
-
this.logger.debug("Fetching price", { tokenId });
|
|
1798
|
-
try {
|
|
1799
|
-
const price = await this.httpClient.get(`/prices/${tokenId}`);
|
|
1800
|
-
this.logger.info("Price fetched successfully", {
|
|
1801
|
-
tokenId,
|
|
1802
|
-
price: price.price
|
|
1803
|
-
});
|
|
1804
|
-
return price;
|
|
1805
|
-
} catch (error) {
|
|
1806
|
-
this.logger.error("Failed to fetch price", error, { tokenId });
|
|
1807
|
-
throw error;
|
|
1808
|
-
}
|
|
1809
|
-
}
|
|
1810
|
-
};
|
|
1811
|
-
|
|
1812
1905
|
// src/portfolio/fetcher.ts
|
|
1813
1906
|
var PortfolioFetcher = class {
|
|
1814
1907
|
/**
|
|
@@ -2458,7 +2551,6 @@ export {
|
|
|
2458
2551
|
DEFAULT_WS_URL,
|
|
2459
2552
|
HttpClient,
|
|
2460
2553
|
MarketFetcher,
|
|
2461
|
-
MarketType,
|
|
2462
2554
|
MessageSigner,
|
|
2463
2555
|
NoOpLogger,
|
|
2464
2556
|
OrderBuilder,
|