@limitless-exchange/sdk 0.0.2 → 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/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__ */ ((OrderType3) => {
50
- OrderType3["FOK"] = "FOK";
51
- OrderType3["GTC"] = "GTC";
52
- return OrderType3;
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";
@@ -448,24 +443,31 @@ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
448
443
  var CONTRACT_ADDRESSES = {
449
444
  // Base mainnet (chainId: 8453)
450
445
  8453: {
451
- CLOB: "0xa4409D988CA2218d956BeEFD3874100F444f0DC3",
452
- NEGRISK: "0x5a38afc17F7E97ad8d6C547ddb837E40B4aEDfC6"
446
+ USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
447
+ // Native USDC on Base
448
+ CTF: "0xC9c98965297Bc527861c898329Ee280632B76e18"
449
+ // Conditional Token Framework
453
450
  },
454
451
  // Base Sepolia testnet (chainId: 84532)
455
452
  84532: {
456
- CLOB: "0x...",
457
- // Add testnet addresses when available
458
- NEGRISK: "0x..."
453
+ USDC: "0x...",
454
+ CTF: "0x..."
459
455
  }
460
456
  };
461
- function getContractAddress(marketType, chainId = DEFAULT_CHAIN_ID) {
457
+ function getContractAddress(contractType, chainId = DEFAULT_CHAIN_ID) {
462
458
  const addresses = CONTRACT_ADDRESSES[chainId];
463
459
  if (!addresses) {
464
460
  throw new Error(
465
461
  `No contract addresses configured for chainId ${chainId}. Supported chains: ${Object.keys(CONTRACT_ADDRESSES).join(", ")}`
466
462
  );
467
463
  }
468
- return addresses[marketType];
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;
469
471
  }
470
472
 
471
473
  // src/api/http.ts
@@ -891,8 +893,7 @@ var OrderBuilder = class {
891
893
  * const fokOrder = builder.buildOrder({
892
894
  * tokenId: '123456',
893
895
  * makerAmount: 50, // 50 USDC to spend
894
- * side: Side.BUY,
895
- * marketType: MarketType.CLOB
896
+ * side: Side.BUY
896
897
  * });
897
898
  *
898
899
  * // GTC order (price + size)
@@ -900,8 +901,7 @@ var OrderBuilder = class {
900
901
  * tokenId: '123456',
901
902
  * price: 0.38,
902
903
  * size: 22.123, // Will be rounded to tick-aligned: 22.123 shares
903
- * side: Side.BUY,
904
- * marketType: MarketType.CLOB
904
+ * side: Side.BUY
905
905
  * });
906
906
  * ```
907
907
  */
@@ -1176,8 +1176,7 @@ var OrderSigner = class {
1176
1176
  * ```typescript
1177
1177
  * const signature = await signer.signOrder(unsignedOrder, {
1178
1178
  * chainId: 8453,
1179
- * contractAddress: '0x...',
1180
- * marketType: MarketType.CLOB
1179
+ * contractAddress: '0x...'
1181
1180
  * });
1182
1181
  * ```
1183
1182
  */
@@ -1185,7 +1184,7 @@ var OrderSigner = class {
1185
1184
  this.logger.debug("Signing order with EIP-712", {
1186
1185
  tokenId: order.tokenId,
1187
1186
  side: order.side,
1188
- marketType: config.marketType
1187
+ verifyingContract: config.contractAddress
1189
1188
  });
1190
1189
  const walletAddress = await this.wallet.getAddress();
1191
1190
  if (walletAddress.toLowerCase() !== order.signer.toLowerCase()) {
@@ -1410,14 +1409,221 @@ function validateSignedOrder(order) {
1410
1409
  }
1411
1410
  }
1412
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
+
1413
1621
  // src/orders/client.ts
1414
1622
  var OrderClient = class {
1415
1623
  /**
1416
1624
  * Creates a new order client instance.
1417
1625
  *
1418
1626
  * @param config - Order client configuration
1419
- *
1420
- * @throws Error if neither marketType nor signingConfig is provided
1421
1627
  */
1422
1628
  constructor(config) {
1423
1629
  this.httpClient = config.httpClient;
@@ -1426,32 +1632,18 @@ var OrderClient = class {
1426
1632
  const feeRateBps = config.userData.feeRateBps;
1427
1633
  this.orderBuilder = new OrderBuilder(config.wallet.address, feeRateBps, 1e-3);
1428
1634
  this.orderSigner = new OrderSigner(config.wallet, this.logger);
1635
+ this.marketFetcher = config.marketFetcher || new MarketFetcher(config.httpClient, this.logger);
1429
1636
  if (config.signingConfig) {
1430
1637
  this.signingConfig = config.signingConfig;
1431
- } else if (config.marketType) {
1432
- const chainId = parseInt(process.env.CHAIN_ID || "8453");
1433
- const contractAddress = config.marketType === "NEGRISK" /* NEGRISK */ ? process.env.NEGRISK_CONTRACT_ADDRESS || getContractAddress("NEGRISK", chainId) : process.env.CLOB_CONTRACT_ADDRESS || getContractAddress("CLOB", chainId);
1434
- this.signingConfig = {
1435
- chainId,
1436
- contractAddress,
1437
- marketType: config.marketType
1438
- };
1439
- this.logger.info("Auto-configured signing", {
1440
- chainId,
1441
- contractAddress,
1442
- marketType: config.marketType
1443
- });
1444
1638
  } else {
1445
1639
  const chainId = parseInt(process.env.CHAIN_ID || "8453");
1446
- const contractAddress = process.env.CLOB_CONTRACT_ADDRESS || getContractAddress("CLOB", chainId);
1640
+ const contractAddress = ZERO_ADDRESS;
1447
1641
  this.signingConfig = {
1448
- chainId,
1449
- contractAddress,
1450
- marketType: "CLOB" /* CLOB */
1451
- };
1452
- this.logger.debug("Using default CLOB configuration", {
1453
1642
  chainId,
1454
1643
  contractAddress
1644
+ };
1645
+ this.logger.info("Auto-configured signing (contract address from venue)", {
1646
+ chainId
1455
1647
  });
1456
1648
  }
1457
1649
  }
@@ -1460,24 +1652,31 @@ var OrderClient = class {
1460
1652
  *
1461
1653
  * @remarks
1462
1654
  * This method handles the complete order creation flow:
1463
- * 1. Build unsigned order
1464
- * 2. Sign with EIP-712
1465
- * 3. Submit to API
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.
1466
1662
  *
1467
1663
  * @param params - Order parameters
1468
1664
  * @returns Promise resolving to order response
1469
1665
  *
1470
- * @throws Error if order creation fails
1666
+ * @throws Error if order creation fails or venue not found
1471
1667
  *
1472
1668
  * @example
1473
1669
  * ```typescript
1670
+ * // Best practice: fetch market first to cache venue
1671
+ * const market = await marketFetcher.getMarket('bitcoin-2024');
1672
+ *
1474
1673
  * const order = await orderClient.createOrder({
1475
- * tokenId: '123456',
1674
+ * tokenId: market.tokens.yes,
1476
1675
  * price: 0.65,
1477
1676
  * size: 100,
1478
1677
  * side: Side.BUY,
1479
1678
  * orderType: OrderType.GTC,
1480
- * marketSlug: 'market-slug'
1679
+ * marketSlug: 'bitcoin-2024'
1481
1680
  * });
1482
1681
  *
1483
1682
  * console.log(`Order created: ${order.order.id}`);
@@ -1489,6 +1688,29 @@ var OrderClient = class {
1489
1688
  orderType: params.orderType,
1490
1689
  marketSlug: params.marketSlug
1491
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
+ });
1492
1714
  const unsignedOrder = this.orderBuilder.buildOrder(params);
1493
1715
  this.logger.debug("Built unsigned order", {
1494
1716
  salt: unsignedOrder.salt,
@@ -1497,7 +1719,7 @@ var OrderClient = class {
1497
1719
  });
1498
1720
  const signature = await this.orderSigner.signOrder(
1499
1721
  unsignedOrder,
1500
- this.signingConfig
1722
+ dynamicSigningConfig
1501
1723
  );
1502
1724
  const payload = {
1503
1725
  order: {
@@ -1680,162 +1902,6 @@ var OrderClient = class {
1680
1902
  }
1681
1903
  };
1682
1904
 
1683
- // src/markets/fetcher.ts
1684
- var MarketFetcher = class {
1685
- /**
1686
- * Creates a new market fetcher instance.
1687
- *
1688
- * @param httpClient - HTTP client for API requests
1689
- * @param logger - Optional logger for debugging (default: no logging)
1690
- *
1691
- * @example
1692
- * ```typescript
1693
- * const fetcher = new MarketFetcher(httpClient);
1694
- * ```
1695
- */
1696
- constructor(httpClient, logger) {
1697
- this.httpClient = httpClient;
1698
- this.logger = logger || new NoOpLogger();
1699
- }
1700
- /**
1701
- * Gets active markets with query parameters and pagination support.
1702
- *
1703
- * @param params - Query parameters for filtering and pagination
1704
- * @returns Promise resolving to active markets response
1705
- * @throws Error if API request fails
1706
- *
1707
- * @example
1708
- * ```typescript
1709
- * // Get 8 markets sorted by LP rewards
1710
- * const response = await fetcher.getActiveMarkets({
1711
- * limit: 8,
1712
- * sortBy: 'lp_rewards'
1713
- * });
1714
- * console.log(`Found ${response.data.length} of ${response.totalMarketsCount} markets`);
1715
- *
1716
- * // Get page 2
1717
- * const page2 = await fetcher.getActiveMarkets({
1718
- * limit: 8,
1719
- * page: 2,
1720
- * sortBy: 'ending_soon'
1721
- * });
1722
- * ```
1723
- */
1724
- async getActiveMarkets(params) {
1725
- const queryParams = new URLSearchParams();
1726
- if (params?.limit !== void 0) {
1727
- queryParams.append("limit", params.limit.toString());
1728
- }
1729
- if (params?.page !== void 0) {
1730
- queryParams.append("page", params.page.toString());
1731
- }
1732
- if (params?.sortBy) {
1733
- queryParams.append("sortBy", params.sortBy);
1734
- }
1735
- const queryString = queryParams.toString();
1736
- const endpoint = `/markets/active${queryString ? `?${queryString}` : ""}`;
1737
- this.logger.debug("Fetching active markets", { params });
1738
- try {
1739
- const response = await this.httpClient.get(endpoint);
1740
- this.logger.info("Active markets fetched successfully", {
1741
- count: response.data.length,
1742
- total: response.totalMarketsCount,
1743
- sortBy: params?.sortBy,
1744
- page: params?.page
1745
- });
1746
- return response;
1747
- } catch (error) {
1748
- this.logger.error("Failed to fetch active markets", error, { params });
1749
- throw error;
1750
- }
1751
- }
1752
- /**
1753
- * Gets a single market by slug.
1754
- *
1755
- * @param slug - Market slug identifier
1756
- * @returns Promise resolving to market details
1757
- * @throws Error if API request fails or market not found
1758
- *
1759
- * @example
1760
- * ```typescript
1761
- * const market = await fetcher.getMarket('bitcoin-price-2024');
1762
- * console.log(`Market: ${market.title}`);
1763
- * ```
1764
- */
1765
- async getMarket(slug) {
1766
- this.logger.debug("Fetching market", { slug });
1767
- try {
1768
- const market = await this.httpClient.get(`/markets/${slug}`);
1769
- this.logger.info("Market fetched successfully", {
1770
- slug,
1771
- title: market.title
1772
- });
1773
- return market;
1774
- } catch (error) {
1775
- this.logger.error("Failed to fetch market", error, { slug });
1776
- throw error;
1777
- }
1778
- }
1779
- /**
1780
- * Gets the orderbook for a CLOB market.
1781
- *
1782
- * @param slug - Market slug identifier
1783
- * @returns Promise resolving to orderbook data
1784
- * @throws Error if API request fails
1785
- *
1786
- * @example
1787
- * ```typescript
1788
- * const orderbook = await fetcher.getOrderBook('bitcoin-price-2024');
1789
- * console.log(`Bids: ${orderbook.bids.length}, Asks: ${orderbook.asks.length}`);
1790
- * ```
1791
- */
1792
- async getOrderBook(slug) {
1793
- this.logger.debug("Fetching orderbook", { slug });
1794
- try {
1795
- const orderbook = await this.httpClient.get(
1796
- `/markets/${slug}/orderbook`
1797
- );
1798
- this.logger.info("Orderbook fetched successfully", {
1799
- slug,
1800
- bids: orderbook.bids.length,
1801
- asks: orderbook.asks.length,
1802
- tokenId: orderbook.tokenId
1803
- });
1804
- return orderbook;
1805
- } catch (error) {
1806
- this.logger.error("Failed to fetch orderbook", error, { slug });
1807
- throw error;
1808
- }
1809
- }
1810
- /**
1811
- * Gets the current price for a token.
1812
- *
1813
- * @param tokenId - Token ID
1814
- * @returns Promise resolving to price information
1815
- * @throws Error if API request fails
1816
- *
1817
- * @example
1818
- * ```typescript
1819
- * const price = await fetcher.getPrice('123456');
1820
- * console.log(`Current price: ${price.price}`);
1821
- * ```
1822
- */
1823
- async getPrice(tokenId) {
1824
- this.logger.debug("Fetching price", { tokenId });
1825
- try {
1826
- const price = await this.httpClient.get(`/prices/${tokenId}`);
1827
- this.logger.info("Price fetched successfully", {
1828
- tokenId,
1829
- price: price.price
1830
- });
1831
- return price;
1832
- } catch (error) {
1833
- this.logger.error("Failed to fetch price", error, { tokenId });
1834
- throw error;
1835
- }
1836
- }
1837
- };
1838
-
1839
1905
  // src/portfolio/fetcher.ts
1840
1906
  var PortfolioFetcher = class {
1841
1907
  /**
@@ -2485,7 +2551,6 @@ export {
2485
2551
  DEFAULT_WS_URL,
2486
2552
  HttpClient,
2487
2553
  MarketFetcher,
2488
- MarketType,
2489
2554
  MessageSigner,
2490
2555
  NoOpLogger,
2491
2556
  OrderBuilder,