@pear-protocol/exchanges-sdk 0.11.0 → 0.12.0

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.d.ts CHANGED
@@ -1526,98 +1526,6 @@ declare const AccountBalanceCore: z.ZodObject<{
1526
1526
  /** Human-readable name for each mode, as the venue's own account page labels it. */
1527
1527
  declare const ACCOUNT_MODE_LABELS: Record<AccountMode, string>;
1528
1528
 
1529
- /**
1530
- * Mirrors the shipped basket model (`BasketItem` in the frontend): unsigned `weight`
1531
- * with `side` alongside, weights summing to 100. Sizing ignores `side` — margin
1532
- * requirement does not depend on direction — and normalises by Σweight.
1533
- */
1534
- declare const BasketLeg: z.ZodObject<{
1535
- asset: z.ZodString;
1536
- marginMode: z.ZodEnum<{
1537
- isolated: "isolated";
1538
- cross: "cross";
1539
- }>;
1540
- leverage: z.ZodString;
1541
- side: z.ZodEnum<{
1542
- BUY: "BUY";
1543
- SELL: "SELL";
1544
- }>;
1545
- weight: z.ZodNumber;
1546
- }, z.core.$strip>;
1547
- type BasketLeg = z.infer<typeof BasketLeg>;
1548
- declare const MaxBasketSizeInput: z.ZodObject<{
1549
- legs: z.ZodArray<z.ZodObject<{
1550
- asset: z.ZodString;
1551
- marginMode: z.ZodEnum<{
1552
- isolated: "isolated";
1553
- cross: "cross";
1554
- }>;
1555
- leverage: z.ZodString;
1556
- side: z.ZodEnum<{
1557
- BUY: "BUY";
1558
- SELL: "SELL";
1559
- }>;
1560
- weight: z.ZodNumber;
1561
- }, z.core.$strip>>;
1562
- }, z.core.$strip>;
1563
- type MaxBasketSizeInput = z.infer<typeof MaxBasketSizeInput>;
1564
- declare const MaxBasketSizeResult: z.ZodObject<{
1565
- maxNotional: z.ZodNullable<z.ZodString>;
1566
- legs: z.ZodArray<z.ZodObject<{
1567
- asset: z.ZodString;
1568
- notional: z.ZodString;
1569
- marginRequired: z.ZodString;
1570
- }, z.core.$strip>>;
1571
- bindingConstraint: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
1572
- kind: z.ZodLiteral<"cross-pool">;
1573
- pool: z.ZodString;
1574
- }, z.core.$strip>, z.ZodObject<{
1575
- kind: z.ZodLiteral<"isolated-leg">;
1576
- asset: z.ZodString;
1577
- }, z.core.$strip>], "kind">>;
1578
- }, z.core.$strip>;
1579
- type MaxBasketSizeResult = z.infer<typeof MaxBasketSizeResult>;
1580
- /**
1581
- * One basket leg with its leverage already capped by the venue adapter.
1582
- *
1583
- * `marginMode` does not enter the maths: an isolated leg gets dedicated margin, but that margin is
1584
- * still transferred out of the same free balance, so it draws on the same budget as a cross leg.
1585
- * It is carried so the caller passes its basket through unchanged.
1586
- */
1587
- type CappedBasketLeg = {
1588
- asset: string;
1589
- /**
1590
- * The collateral pool this leg's margin comes out of, as the venue adapter resolves it — a CEX
1591
- * from the symbol's settlement currency, Hyperliquid from the dex's collateral token. Legs in
1592
- * different pools cannot fund each other.
1593
- */
1594
- pool: string;
1595
- /** Unsigned, in the caller's own scale — `computeMaxBasketSize` normalises by Σweight. */
1596
- weight: number;
1597
- effectiveLeverage: string;
1598
- marginMode: MarginMode;
1599
- /** This leg's own venue ceiling in USD notional; `null` when the venue names no cap. */
1600
- maxNotional: string | null;
1601
- };
1602
- /** The margin budget behind each collateral pool, plus the legs those pools must fund at once. */
1603
- type MaxBasketSizeCalculation = {
1604
- /**
1605
- * Pool id to that pool's USD-equivalent budget. A pool whose collateral is not ~1 USD supplies no
1606
- * entry until someone adds a price source, and a leg drawing on a missing entry voids the answer.
1607
- */
1608
- budgets: Record<string, string>;
1609
- legs: CappedBasketLeg[];
1610
- };
1611
- /**
1612
- * The largest gross notional this basket can reach while every leg stays funded at its weight.
1613
- *
1614
- * Returns a null size when a pool behind the basket cannot be valued — never a zero, which a
1615
- * consumer would read as "no collateral" rather than "not known". A basket whose own figures cannot
1616
- * be sized (see `isSizeableInput`) gets the same null, so this call never throws and never returns a
1617
- * result that fails `MaxBasketSizeResult`.
1618
- */
1619
- declare function computeMaxBasketSize(input: MaxBasketSizeCalculation): MaxBasketSizeResult;
1620
-
1621
1529
  interface AccountPosition {
1622
1530
  symbol: string;
1623
1531
  side: 'long' | 'short' | 'both';
@@ -1674,16 +1582,12 @@ interface AccountTracker {
1674
1582
  disconnect(): Promise<void>;
1675
1583
  snapshot(): Promise<AccountSnapshot>;
1676
1584
  snapshotAssets(coins: string[]): Promise<AssetSnapshotMap>;
1677
- /** Sizes a basket over REST alone, so it stays usable without a running socket. */
1678
- snapshotMaxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1679
1585
  readonly isConnected: boolean;
1680
1586
  readonly isInitialized: boolean;
1681
1587
  readonly hasListeners: boolean;
1682
1588
  trackBalance(cb: BalanceCallback): () => void;
1683
1589
  trackPosition(cb: PositionsCallback): () => void;
1684
1590
  trackAsset(asset: string, cb: TrackedAssetCallback): () => void;
1685
- /** Async: a basket may name assets this tracker has not subscribed to yet. */
1686
- maxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1687
1591
  getBalance(): AccountBalance | null;
1688
1592
  getPositions(): AccountPosition[];
1689
1593
  getTrackedAsset(coin: string): TrackedAssetInfo | null;
@@ -1724,9 +1628,6 @@ declare abstract class BaseAccountTracker implements AccountTracker {
1724
1628
  private broadcast;
1725
1629
  abstract start(): Promise<void>;
1726
1630
  abstract snapshot(): Promise<AccountSnapshot>;
1727
- /** Every venue implements both sizing paths — the live one and the REST one. */
1728
- abstract maxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1729
- abstract snapshotMaxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1730
1631
  protected abstract fetchAssetSnapshots(coins: string[]): Promise<AssetSnapshotMap>;
1731
1632
  abstract get isConnected(): boolean;
1732
1633
  protected abstract ensureAssetTracked(asset: string): void;
@@ -1799,15 +1700,6 @@ declare class BinanceAccountTracker extends BaseAccountTracker {
1799
1700
  private trackedAssetInfos;
1800
1701
  constructor(config: BinanceAccountTrackerConfig);
1801
1702
  snapshot(): Promise<AccountSnapshot>;
1802
- /**
1803
- * Binance sizes no basket in v1: the SDK reads no per-asset max leverage from it, and sizing off
1804
- * `availableMargin` alone would ship a number no venue field backs. The missing input is
1805
- * `/fapi/v2/positionRisk` → `maxNotionalValue` (the account's own per-symbol ceiling), with
1806
- * `/fapi/v1/leverageBracket` behind it for the tier a larger size would fall into.
1807
- */
1808
- maxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1809
- /** The REST path answers the same way — there is no size either way, not a slower one. */
1810
- snapshotMaxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1811
1703
  /**
1812
1704
  * Stateless one-shot per-asset settings read: `positionRisk` with no symbol returns leverage +
1813
1705
  * margin type for every symbol (positioned or not), so any number of assets costs one call.
@@ -1906,15 +1798,6 @@ declare class BybitAccountTracker extends BaseAccountTracker {
1906
1798
  private trackedAssetInfos;
1907
1799
  constructor(config: BybitAccountTrackerConfig);
1908
1800
  snapshot(): Promise<AccountSnapshot>;
1909
- /**
1910
- * Bybit sizes no basket in v1: the SDK reads no per-asset max leverage from it, and sizing off
1911
- * `availableMargin` alone would ship a number no venue field backs. The missing input is
1912
- * `/v5/position/list` → `leverage` (the account's own per-symbol setting), with
1913
- * `/v5/market/risk-limit` → `maxLeverage` behind it for the tier a larger size would fall into.
1914
- */
1915
- maxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1916
- /** The REST path answers the same way — there is no size either way, not a slower one. */
1917
- snapshotMaxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1918
1801
  /**
1919
1802
  * Stateless one-shot per-asset settings read. Bybit has no batch leverage endpoint, but
1920
1803
  * `position/list` by settleCoin returns every open position (with leverage) in one call, so
@@ -2187,13 +2070,6 @@ declare class HyperliquidAccountTracker extends BaseAccountTracker {
2187
2070
  * per-asset headroom without opening a socket.
2188
2071
  */
2189
2072
  snapshot(): Promise<AccountSnapshot>;
2190
- /** Sizes a basket over REST alone, so the call stays usable without a running socket. */
2191
- snapshotMaxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
2192
- /**
2193
- * Sizes a basket against live state, fetching per-asset data for any leg the socket has not
2194
- * subscribed to — which is exactly why the call is asynchronous on both paths.
2195
- */
2196
- maxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
2197
2073
  /**
2198
2074
  * Stateless one-shot per-asset settings read via the `activeAssetData` info request (the REST
2199
2075
  * twin of the live WS subscription), one request per coin fired in parallel — the info endpoint
@@ -2217,10 +2093,6 @@ declare class HyperliquidAccountTracker extends BaseAccountTracker {
2217
2093
  private routeRaw;
2218
2094
  private handle;
2219
2095
  private loadPerpMetas;
2220
- /** Loads the dex metadata a sizing call needs, reusing whatever `start()` already cached. */
2221
- private loadPerpMetasOnce;
2222
- /** Loads the token names a pool id is spelled with, reusing whatever `start()` already cached. */
2223
- private loadCollateralTokenNamesOnce;
2224
2096
  /** Reads `activeAssetData` for each coin in parallel, dropping the coins the venue refuses. */
2225
2097
  private fetchActiveAssetEvents;
2226
2098
  /** The asset set `availableMargin` is the floor over: the locked coins plus every tracked one. */
@@ -2369,10 +2241,6 @@ declare class LighterAccountTracker extends BaseAccountTracker {
2369
2241
  * supplies the exchange default for markets absent from the account payload.
2370
2242
  */
2371
2243
  protected fetchAssetSnapshots(marketIds: string[]): Promise<AssetSnapshotMap>;
2372
- /** Sizes a basket against the live account state, falling back to REST before the socket is up. */
2373
- maxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
2374
- /** Sizes a basket over REST alone, so the answer needs no running socket. */
2375
- snapshotMaxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
2376
2244
  start(): Promise<void>;
2377
2245
  /** Creates one tracker lifecycle while repeated callers share the same pending start. */
2378
2246
  private performStart;
@@ -2417,8 +2285,6 @@ declare class LighterAccountTracker extends BaseAccountTracker {
2417
2285
  private buildBalance;
2418
2286
  /** The market data both read paths join account state against, as the latest read left it. */
2419
2287
  private marketContext;
2420
- /** The account's current per-market settings as the base tracker already holds them. */
2421
- private liveAccountSettings;
2422
2288
  /** Reads the account with credentials when present, or explicitly uses the read-only verifier path. */
2423
2289
  private fetchPrimaryAccount;
2424
2290
  /** Reads market context under the same account identity as the snapshot that consumes it. */
@@ -2578,16 +2444,6 @@ declare class OkxAccountTracker extends BaseAccountTracker {
2578
2444
  private trackedAssetInfos;
2579
2445
  constructor(config: OkxAccountTrackerConfig);
2580
2446
  snapshot(): Promise<AccountSnapshot>;
2581
- /**
2582
- * OKX sizes no basket in v1: the SDK reads no per-asset max leverage from it, and sizing off
2583
- * `availableMargin` alone would ship a number no venue field backs. The missing input is
2584
- * `GET /api/v5/public/position-tiers` → `maxLever`/`imr` per tier, which the client does not
2585
- * call — and it is NOT `GET /api/v5/account/position-tiers`, a different endpoint carrying no
2586
- * margin or leverage data at all.
2587
- */
2588
- maxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
2589
- /** The REST path answers the same way — there is no size either way, not a slower one. */
2590
- snapshotMaxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
2591
2447
  /**
2592
2448
  * Stateless one-shot per-asset leverage read via `leverage-info`, which accepts up to 20 instIds
2593
2449
  * per request (chunked in the client), so N assets cost ceil(N/20) calls. Cross margin only,
@@ -2685,11 +2541,6 @@ declare class ExchangesSDK {
2685
2541
  status(connection: ExchangeConnection, options?: ConnectOptions): Promise<AccountStatus>;
2686
2542
  createTracker(connection: ExchangeConnection): AccountTracker;
2687
2543
  snapshot(tradeAccountId: string): Promise<AccountSnapshot>;
2688
- /**
2689
- * Sizes a basket in one shot. Routed to the tracker's REST path on purpose: this entry point
2690
- * builds a throwaway tracker per call, so it must open no socket.
2691
- */
2692
- maxBasketSize(tradeAccountId: string, input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
2693
2544
  snapshotAssets(tradeAccountId: string, coins: string[]): Promise<AssetSnapshotMap>;
2694
2545
  createHelper<E extends ExchangeHelperExchange>(exchange: E): ExchangeHelperMap[E];
2695
2546
  createSyncer(connection: ExchangeConnection): AccountSyncer;
@@ -2697,4 +2548,4 @@ declare class ExchangesSDK {
2697
2548
  private fetchCredentials;
2698
2549
  }
2699
2550
 
2700
- export { ACCOUNT_MODE_LABELS, ASSET_DECIMALS, AccountBalance, AccountBalanceCore, type AccountHealthStatus, AccountMode, type AccountPosition, type AccountSnapshot, type AccountStatus, type AccountSyncer, type AccountSyncerConfig, type AccountTierCallback, type AccountTracker, type AccountTrackerConfig, type AccountWarningReason, type ApiKey, type ApproveIntegratorParams, type ApproveIntegratorResult, AssetId, type AssetSnapshotMap, type BalanceCallback, BaseAccountSyncer, BaseAccountTracker, BaseWs, BasketLeg, BinanceAccountSyncer, BinanceAccountTracker, type BinanceAccountTrackerConfig, BinanceExchangeWs, BinanceMultiAssetBalance, BinanceSingleAssetBalance, BinanceUserDataWs, type BinanceUserDataWsConfig, BinanceWsApi, type BinanceWsApiConfig, BybitAccountSyncer, BybitAccountTracker, type BybitAccountTrackerConfig, BybitExchangeWs, BybitIsolatedMarginBalance, BybitPortfolioMarginBalance, BybitRegularMarginBalance, BybitWs, type BybitWsConfig, type CappedBasketLeg, type CctpDepositAddressParams, type CctpDepositAddressResult, type CctpDepositHistorySettlement, type CctpDepositParams, type CctpDepositRegistrationSettlement, type CctpDepositResult, type CctpDepositSettlement, type ChangeAccountTierParams, type ChangeAccountTierResult, type CheckApiWalletParams, CollateralBalance, type ConnectOptions, type ConnectWalletParams, type ConnectWalletResult, type CreateAccountTrackerConfig, type CreateExchangeWsConfig, DecimalString, type EthereumDepositParams, type EthereumDepositResult, type ExchangeConnection, type ExchangeHelperExchange, type ExchangeHelperMap, type ExchangeState, ExchangeWs, type ExchangeWsByConnector, ExchangesSDK, type ExchangesSDKConfig, FUNXYZ_DEPOSIT_MINIMUMS_USD, FUNXYZ_ETHEREUM_MAINNET_CHAIN_ID, FUNXYZ_EVM_CHAIN_NAMES, type FastWithdrawParams, type FastWithdrawResult, type FillSyncOutcome, type FundingSyncOutcome, type FunxyzAccountState, type FunxyzAsset, type FunxyzDepositAddressParams, type FunxyzDepositAddressResult, type FunxyzDepositCredit, type FunxyzDepositParams, type FunxyzDepositResult, type FunxyzDepositSettlement, type FunxyzDepositSource, type FunxyzMarket, HyperliquidAccountSyncer, HyperliquidAccountTracker, type HyperliquidAccountTrackerConfig, HyperliquidDexState, HyperliquidExchangeWs, type HyperliquidHelper, HyperliquidPortfolioMarginBalance, HyperliquidPortfolioMarginCollateral, HyperliquidStandardBalance, HyperliquidUnifiedBalance, HyperliquidWs, type IntegratorApprovalRequirements, L2_ASSET_DECIMALS, LIGHTER_NATIVE_USDC_ADDRESSES, LIGHTER_USDC_DECIMALS, LighterAccountSyncer, type LighterAccountTier, LighterAccountTracker, type LighterAccountTrackerConfig, type LighterApplyReferralCodeParams, type LighterAuthCredentials, LighterClassicBalance, type LighterDeposit, type LighterDepositAddressParams, type LighterDepositAddressResult, type LighterDepositCredit, type LighterDepositHistoryParams, type LighterDepositNetwork, type LighterDepositPage, type LighterDepositParams, type LighterDepositProgress, type LighterDepositResult, type LighterDepositStatus, type LighterDepositWalletAdapter, LighterExchangeWs, type LighterHelper, type LighterLookupResult, type LighterOnboardingStatus, type LighterReferral, type LighterReferralTotals, type LighterReferralTradeStats, LighterUnifiedBalance, type LighterUserReferrals, type LighterUserReferralsParams, type LighterWithdraw, type LighterWithdrawHistoryParams, type LighterWithdrawPage, type LighterWithdrawStatus, type LighterWithdrawType, LighterWs, type ListExternalFillsParams, type ListExternalFundingParams, type ListExternalPositionsParams, MAX_API_KEY_INDEX, MIN_LIGHTER_CCTP_DEPOSIT_USDC, MIN_LIGHTER_FAST_WITHDRAW_USDC, MIN_USER_API_KEY_INDEX, MarginMode, type MaxBasketSizeCalculation, MaxBasketSizeInput, MaxBasketSizeResult, type MessageListener, OkxAccountSyncer, OkxAccountTracker, type OkxAccountTrackerConfig, OkxExchangeWs, OkxFuturesBalance, OkxMultiCurrencyMarginBalance, OkxPortfolioMarginBalance, OkxSpotBalance, OkxWs, type OkxWsConfig, type OpenListener, type PositionsCallback, RouteType, Side, SignedDecimalString, type StateUpdate, type SupportedCredentials, type TrackedAssetCallback, type TrackedAssetInfo, type WalletClientWithAccount, type WithdrawParams, type WithdrawResult, type WsMessage, computeMaxBasketSize, createAccountSyncer, createAccountTracker, createExchangeWs, createHyperliquidHelper, createLighterHelper, findAvailableApiKeyIndex, getAssetDecimals, getLighterNativeUsdcAddress, listFunxyzTransferableChains, readFunxyzChainSource, readFunxyzMinimumUsd, retrieveLighterAuthToken, usdcAbi };
2551
+ export { ACCOUNT_MODE_LABELS, ASSET_DECIMALS, AccountBalance, AccountBalanceCore, type AccountHealthStatus, AccountMode, type AccountPosition, type AccountSnapshot, type AccountStatus, type AccountSyncer, type AccountSyncerConfig, type AccountTierCallback, type AccountTracker, type AccountTrackerConfig, type AccountWarningReason, type ApiKey, type ApproveIntegratorParams, type ApproveIntegratorResult, AssetId, type AssetSnapshotMap, type BalanceCallback, BaseAccountSyncer, BaseAccountTracker, BaseWs, BinanceAccountSyncer, BinanceAccountTracker, type BinanceAccountTrackerConfig, BinanceExchangeWs, BinanceMultiAssetBalance, BinanceSingleAssetBalance, BinanceUserDataWs, type BinanceUserDataWsConfig, BinanceWsApi, type BinanceWsApiConfig, BybitAccountSyncer, BybitAccountTracker, type BybitAccountTrackerConfig, BybitExchangeWs, BybitIsolatedMarginBalance, BybitPortfolioMarginBalance, BybitRegularMarginBalance, BybitWs, type BybitWsConfig, type CctpDepositAddressParams, type CctpDepositAddressResult, type CctpDepositHistorySettlement, type CctpDepositParams, type CctpDepositRegistrationSettlement, type CctpDepositResult, type CctpDepositSettlement, type ChangeAccountTierParams, type ChangeAccountTierResult, type CheckApiWalletParams, CollateralBalance, type ConnectOptions, type ConnectWalletParams, type ConnectWalletResult, type CreateAccountTrackerConfig, type CreateExchangeWsConfig, DecimalString, type EthereumDepositParams, type EthereumDepositResult, type ExchangeConnection, type ExchangeHelperExchange, type ExchangeHelperMap, type ExchangeState, ExchangeWs, type ExchangeWsByConnector, ExchangesSDK, type ExchangesSDKConfig, FUNXYZ_DEPOSIT_MINIMUMS_USD, FUNXYZ_ETHEREUM_MAINNET_CHAIN_ID, FUNXYZ_EVM_CHAIN_NAMES, type FastWithdrawParams, type FastWithdrawResult, type FillSyncOutcome, type FundingSyncOutcome, type FunxyzAccountState, type FunxyzAsset, type FunxyzDepositAddressParams, type FunxyzDepositAddressResult, type FunxyzDepositCredit, type FunxyzDepositParams, type FunxyzDepositResult, type FunxyzDepositSettlement, type FunxyzDepositSource, type FunxyzMarket, HyperliquidAccountSyncer, HyperliquidAccountTracker, type HyperliquidAccountTrackerConfig, HyperliquidDexState, HyperliquidExchangeWs, type HyperliquidHelper, HyperliquidPortfolioMarginBalance, HyperliquidPortfolioMarginCollateral, HyperliquidStandardBalance, HyperliquidUnifiedBalance, HyperliquidWs, type IntegratorApprovalRequirements, L2_ASSET_DECIMALS, LIGHTER_NATIVE_USDC_ADDRESSES, LIGHTER_USDC_DECIMALS, LighterAccountSyncer, type LighterAccountTier, LighterAccountTracker, type LighterAccountTrackerConfig, type LighterApplyReferralCodeParams, type LighterAuthCredentials, LighterClassicBalance, type LighterDeposit, type LighterDepositAddressParams, type LighterDepositAddressResult, type LighterDepositCredit, type LighterDepositHistoryParams, type LighterDepositNetwork, type LighterDepositPage, type LighterDepositParams, type LighterDepositProgress, type LighterDepositResult, type LighterDepositStatus, type LighterDepositWalletAdapter, LighterExchangeWs, type LighterHelper, type LighterLookupResult, type LighterOnboardingStatus, type LighterReferral, type LighterReferralTotals, type LighterReferralTradeStats, LighterUnifiedBalance, type LighterUserReferrals, type LighterUserReferralsParams, type LighterWithdraw, type LighterWithdrawHistoryParams, type LighterWithdrawPage, type LighterWithdrawStatus, type LighterWithdrawType, LighterWs, type ListExternalFillsParams, type ListExternalFundingParams, type ListExternalPositionsParams, MAX_API_KEY_INDEX, MIN_LIGHTER_CCTP_DEPOSIT_USDC, MIN_LIGHTER_FAST_WITHDRAW_USDC, MIN_USER_API_KEY_INDEX, MarginMode, type MessageListener, OkxAccountSyncer, OkxAccountTracker, type OkxAccountTrackerConfig, OkxExchangeWs, OkxFuturesBalance, OkxMultiCurrencyMarginBalance, OkxPortfolioMarginBalance, OkxSpotBalance, OkxWs, type OkxWsConfig, type OpenListener, type PositionsCallback, RouteType, Side, SignedDecimalString, type StateUpdate, type SupportedCredentials, type TrackedAssetCallback, type TrackedAssetInfo, type WalletClientWithAccount, type WithdrawParams, type WithdrawResult, type WsMessage, createAccountSyncer, createAccountTracker, createExchangeWs, createHyperliquidHelper, createLighterHelper, findAvailableApiKeyIndex, getAssetDecimals, getLighterNativeUsdcAddress, listFunxyzTransferableChains, readFunxyzChainSource, readFunxyzMinimumUsd, retrieveLighterAuthToken, usdcAbi };
package/dist/sdk.js CHANGED
@@ -42,14 +42,6 @@ class ExchangesSDK {
42
42
  const connection = await this.fetchCredentials(tradeAccountId);
43
43
  return this.buildTracker(connection).snapshot();
44
44
  }
45
- /**
46
- * Sizes a basket in one shot. Routed to the tracker's REST path on purpose: this entry point
47
- * builds a throwaway tracker per call, so it must open no socket.
48
- */
49
- async maxBasketSize(tradeAccountId, input) {
50
- const connection = await this.fetchCredentials(tradeAccountId);
51
- return this.buildTracker(connection).snapshotMaxBasketSize(input);
52
- }
53
45
  async snapshotAssets(tradeAccountId, coins) {
54
46
  const connection = await this.fetchCredentials(tradeAccountId);
55
47
  return this.buildTracker(connection).snapshotAssets(coins);
@@ -38,19 +38,6 @@ class BinanceAccountTracker extends BaseAccountTracker {
38
38
  };
39
39
  }
40
40
  /**
41
- * Binance sizes no basket in v1: the SDK reads no per-asset max leverage from it, and sizing off
42
- * `availableMargin` alone would ship a number no venue field backs. The missing input is
43
- * `/fapi/v2/positionRisk` → `maxNotionalValue` (the account's own per-symbol ceiling), with
44
- * `/fapi/v1/leverageBracket` behind it for the tier a larger size would fall into.
45
- */
46
- async maxBasketSize(_input) {
47
- return unsizedBasket();
48
- }
49
- /** The REST path answers the same way — there is no size either way, not a slower one. */
50
- async snapshotMaxBasketSize(_input) {
51
- return unsizedBasket();
52
- }
53
- /**
54
41
  * Stateless one-shot per-asset settings read: `positionRisk` with no symbol returns leverage +
55
42
  * margin type for every symbol (positioned or not), so any number of assets costs one call.
56
43
  */
@@ -254,13 +241,5 @@ function toTrackedAssetInfo(coin, risk) {
254
241
  };
255
242
  }
256
243
  __name(toTrackedAssetInfo, "toTrackedAssetInfo");
257
- function unsizedBasket() {
258
- return {
259
- maxNotional: null,
260
- legs: [],
261
- bindingConstraint: null
262
- };
263
- }
264
- __name(unsizedBasket, "unsizedBasket");
265
244
 
266
245
  export { BinanceAccountTracker };
@@ -37,19 +37,6 @@ class BybitAccountTracker extends BaseAccountTracker {
37
37
  };
38
38
  }
39
39
  /**
40
- * Bybit sizes no basket in v1: the SDK reads no per-asset max leverage from it, and sizing off
41
- * `availableMargin` alone would ship a number no venue field backs. The missing input is
42
- * `/v5/position/list` → `leverage` (the account's own per-symbol setting), with
43
- * `/v5/market/risk-limit` → `maxLeverage` behind it for the tier a larger size would fall into.
44
- */
45
- async maxBasketSize(_input) {
46
- return unsizedBasket();
47
- }
48
- /** The REST path answers the same way — there is no size either way, not a slower one. */
49
- async snapshotMaxBasketSize(_input) {
50
- return unsizedBasket();
51
- }
52
- /**
53
40
  * Stateless one-shot per-asset settings read. Bybit has no batch leverage endpoint, but
54
41
  * `position/list` by settleCoin returns every open position (with leverage) in one call, so
55
42
  * only requested symbols without an open position need a per-symbol fill-in read (`?symbol=`
@@ -426,14 +413,6 @@ function sameWithdrawable(left, right) {
426
413
  return true;
427
414
  }
428
415
  __name(sameWithdrawable, "sameWithdrawable");
429
- function unsizedBasket() {
430
- return {
431
- maxNotional: null,
432
- legs: [],
433
- bindingConstraint: null
434
- };
435
- }
436
- __name(unsizedBasket, "unsizedBasket");
437
416
  function toTrackedAssetInfo(coin, pos) {
438
417
  return {
439
418
  coin,
@@ -1,5 +1,5 @@
1
- import { minimumAvailableToTrade } from './basket-size';
2
1
  import { splitDexCoin } from './coin-name';
2
+ import { toDecimal } from './decimal';
3
3
 
4
4
  var __defProp = Object.defineProperty;
5
5
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
@@ -44,5 +44,18 @@ function collateralTokenByDex(perDexState) {
44
44
  return tokenByDex;
45
45
  }
46
46
  __name(collateralTokenByDex, "collateralTokenByDex");
47
+ function minimumAvailableToTrade(assetData) {
48
+ let floor = null;
49
+ for (const data of assetData) {
50
+ for (const available of data.availableToTrade ?? []) {
51
+ const value = toDecimal(available);
52
+ if (floor === null || value.isLessThan(floor)) {
53
+ floor = value;
54
+ }
55
+ }
56
+ }
57
+ return floor === null ? null : floor.toFixed();
58
+ }
59
+ __name(minimumAvailableToTrade, "minimumAvailableToTrade");
47
60
 
48
- export { buildAvailableMarginByToken, buildCollateralTokenNames };
61
+ export { buildAvailableMarginByToken, buildCollateralTokenNames, minimumAvailableToTrade };
@@ -1,10 +1,8 @@
1
1
  import { createExchangeWs } from '../../client';
2
2
  import { fetchPerpDexs, fetchInfo, fetchAllMids, fetchUserAbstraction, fetchSpotClearinghouseState, fetchDelegatorSummary, fetchUserVaultEquities, fetchClearinghouseState, fetchActiveAssetData } from '../../client/hyperliquid/rest';
3
3
  import { BaseAccountTracker } from '../base';
4
- import { computeMaxBasketSize } from '../basket-size';
5
4
  import { resolveHyperliquidAccountType } from './account-mode';
6
- import { minimumAvailableToTrade, findLegMarket, buildPoolBudgets, buildCappedLegs } from './basket-size';
7
- import { buildAvailableMarginByToken, buildCollateralTokenNames } from './collateral';
5
+ import { buildAvailableMarginByToken, buildCollateralTokenNames, minimumAvailableToTrade } from './collateral';
8
6
  import { LOCKED_TRACKED_COINS } from './const';
9
7
  import { toDecimal, ZERO } from './decimal';
10
8
  import { emptyClearinghouseSummary, aggregateClearinghouseStates, mapBalance, mapPositions } from './mapper';
@@ -96,35 +94,6 @@ class HyperliquidAccountTracker extends BaseAccountTracker {
96
94
  positions
97
95
  };
98
96
  }
99
- /** Sizes a basket over REST alone, so the call stays usable without a running socket. */
100
- async snapshotMaxBasketSize(input) {
101
- const [dexToMeta, tokenNames] = await Promise.all([
102
- this.loadPerpMetasOnce(),
103
- this.loadCollateralTokenNamesOnce()
104
- ]);
105
- const assetData = await this.fetchActiveAssetEvents(input.legs.map((leg) => leg.asset));
106
- return sizeBasket(input, dexToMeta, tokenNames, assetData);
107
- }
108
- /**
109
- * Sizes a basket against live state, fetching per-asset data for any leg the socket has not
110
- * subscribed to — which is exactly why the call is asynchronous on both paths.
111
- */
112
- async maxBasketSize(input) {
113
- const [dexToMeta, tokenNames] = await Promise.all([
114
- this.loadPerpMetasOnce(),
115
- this.loadCollateralTokenNamesOnce()
116
- ]);
117
- const missingCoins = input.legs.map((leg) => leg.asset).filter((asset) => !this.trackedAssetData.has(asset));
118
- const fetched = await this.fetchActiveAssetEvents(missingCoins);
119
- const assetData = new Map(fetched);
120
- for (const leg of input.legs) {
121
- const cached = this.trackedAssetData.get(leg.asset);
122
- if (cached) {
123
- assetData.set(leg.asset, cached);
124
- }
125
- }
126
- return sizeBasket(input, dexToMeta, tokenNames, assetData);
127
- }
128
97
  /**
129
98
  * Stateless one-shot per-asset settings read via the `activeAssetData` info request (the REST
130
99
  * twin of the live WS subscription), one request per coin fired in parallel — the info endpoint
@@ -363,31 +332,6 @@ class HyperliquidAccountTracker extends BaseAccountTracker {
363
332
  this.dexToMeta.set(dex, dexMeta);
364
333
  });
365
334
  }
366
- /** Loads the dex metadata a sizing call needs, reusing whatever `start()` already cached. */
367
- async loadPerpMetasOnce() {
368
- if (this.dexToMeta.size > 0) {
369
- return this.dexToMeta;
370
- }
371
- const [allMetas, perpDexs] = await Promise.all([
372
- fetchInfo({
373
- type: "allPerpMetas"
374
- }, this.demo),
375
- fetchPerpDexs(this.demo)
376
- ]);
377
- this.loadPerpMetas(allMetas, perpDexs);
378
- return this.dexToMeta;
379
- }
380
- /** Loads the token names a pool id is spelled with, reusing whatever `start()` already cached. */
381
- async loadCollateralTokenNamesOnce() {
382
- if (this.collateralTokenNames.size > 0) {
383
- return this.collateralTokenNames;
384
- }
385
- const spotMeta = await fetchInfo({
386
- type: "spotMeta"
387
- }, this.demo);
388
- this.collateralTokenNames = buildCollateralTokenNames(spotMeta);
389
- return this.collateralTokenNames;
390
- }
391
335
  /** Reads `activeAssetData` for each coin in parallel, dropping the coins the venue refuses. */
392
336
  async fetchActiveAssetEvents(coins) {
393
337
  const unique = [
@@ -558,18 +502,6 @@ class HyperliquidAccountTracker extends BaseAccountTracker {
558
502
  return result;
559
503
  }
560
504
  }
561
- function sizeBasket(input, dexToMeta, tokenNames, assetData) {
562
- const markets = new Map(input.legs.map((leg) => [
563
- leg.asset,
564
- findLegMarket(dexToMeta, tokenNames, leg.asset, assetData.get(leg.asset)?.leverage.value ?? null)
565
- ]));
566
- const budgets = buildPoolBudgets(input.legs, markets, assetData);
567
- return computeMaxBasketSize({
568
- budgets,
569
- legs: buildCappedLegs(input.legs, markets)
570
- });
571
- }
572
- __name(sizeBasket, "sizeBasket");
573
505
  function buildTrackedAssetInfo(data) {
574
506
  return {
575
507
  coin: data.coin,
@@ -11,7 +11,6 @@ export { OkxAccountTracker } from './okx/tracker';
11
11
  export { AccountBalance } from './balance';
12
12
  export { ACCOUNT_MODE_LABELS, AccountBalanceCore, AccountMode, CollateralBalance, DecimalString, MarginMode, Side, SignedDecimalString } from './balance-core';
13
13
  export { BaseAccountTracker } from './base';
14
- export { BasketLeg, MaxBasketSizeInput, MaxBasketSizeResult, computeMaxBasketSize } from './basket-size';
15
14
  export { BinanceMultiAssetBalance, BinanceSingleAssetBalance } from './binance/balance';
16
15
  export { BybitIsolatedMarginBalance, BybitPortfolioMarginBalance, BybitRegularMarginBalance } from './bybit/balance';
17
16
  export { HyperliquidDexState, HyperliquidPortfolioMarginBalance, HyperliquidPortfolioMarginCollateral, HyperliquidStandardBalance, HyperliquidUnifiedBalance } from './hyperliquid/balance';
@@ -3,8 +3,6 @@ import { createExchangeWs } from '../../client';
3
3
  import { fetchAccount, fetchPublicAccount, fetchOrderBookDetails, fetchPublicOrderBookDetails, fetchAccountLimits } from '../../client/lighter/rest';
4
4
  import { retrieveLighterAuthToken } from '../../helper/lighter/auth-token.helper';
5
5
  import { BaseAccountTracker } from '../base';
6
- import { computeMaxBasketSize } from '../basket-size';
7
- import { toLighterBasketCalculation } from './basket-size';
8
6
  import { buildSpotPriceIndex, mapPositions, mapRestBalance, mapMarketDefaultAssetInfo, toLighterAccountType, mapLiveBalance, toLighterAccountTier } from './mapper';
9
7
 
10
8
  var __defProp = Object.defineProperty;
@@ -141,36 +139,6 @@ class LighterAccountTracker extends BaseAccountTracker {
141
139
  }
142
140
  return result;
143
141
  }
144
- /** Sizes a basket against the live account state, falling back to REST before the socket is up. */
145
- async maxBasketSize(input) {
146
- if (!this.stats || this.marketsBySymbol.size === 0) {
147
- return this.snapshotMaxBasketSize(input);
148
- }
149
- return computeMaxBasketSize(toLighterBasketCalculation(input.legs, {
150
- availableBalance: this.stats.total.available_balance,
151
- perpBySymbol: this.marketsBySymbol,
152
- settingsByMarketId: this.liveAccountSettings()
153
- }));
154
- }
155
- /** Sizes a basket over REST alone, so the answer needs no running socket. */
156
- async snapshotMaxBasketSize(input) {
157
- const [account, markets] = await Promise.all([
158
- this.fetchPrimaryAccount(),
159
- this.fetchMarkets()
160
- ]);
161
- if (!account) {
162
- return computeMaxBasketSize({
163
- budgets: {},
164
- legs: []
165
- });
166
- }
167
- const context = {
168
- availableBalance: account.available_balance,
169
- perpBySymbol: toMarketsBySymbol(markets.perp),
170
- settingsByMarketId: toAccountSettings(markets.perp, account.positions ?? [])
171
- };
172
- return computeMaxBasketSize(toLighterBasketCalculation(input.legs, context));
173
- }
174
142
  start() {
175
143
  if (this.startInFlight) {
176
144
  return this.startInFlight;
@@ -414,17 +382,6 @@ class LighterAccountTracker extends BaseAccountTracker {
414
382
  spotPriceBySymbol: this.spotPriceBySymbol
415
383
  };
416
384
  }
417
- /** The account's current per-market settings as the base tracker already holds them. */
418
- liveAccountSettings() {
419
- const settings = /* @__PURE__ */ new Map();
420
- for (const marketId of this.marketsByMarketId.keys()) {
421
- const info = this.getTrackedAsset(String(marketId));
422
- if (info) {
423
- settings.set(String(marketId), info);
424
- }
425
- }
426
- return settings;
427
- }
428
385
  /** Reads the account with credentials when present, or explicitly uses the read-only verifier path. */
429
386
  async fetchPrimaryAccount() {
430
387
  const authToken = await this.retrieveAuthToken();
@@ -604,13 +561,6 @@ function toMarketContext(perpMarkets, spotMarkets) {
604
561
  };
605
562
  }
606
563
  __name(toMarketContext, "toMarketContext");
607
- function toMarketsBySymbol(perpMarkets) {
608
- return new Map(perpMarkets.map((market) => [
609
- market.symbol,
610
- market
611
- ]));
612
- }
613
- __name(toMarketsBySymbol, "toMarketsBySymbol");
614
564
  function toAccountSettings(perpMarkets, positions) {
615
565
  const settings = /* @__PURE__ */ new Map();
616
566
  for (const market of perpMarkets) {
@@ -36,20 +36,6 @@ class OkxAccountTracker extends BaseAccountTracker {
36
36
  };
37
37
  }
38
38
  /**
39
- * OKX sizes no basket in v1: the SDK reads no per-asset max leverage from it, and sizing off
40
- * `availableMargin` alone would ship a number no venue field backs. The missing input is
41
- * `GET /api/v5/public/position-tiers` → `maxLever`/`imr` per tier, which the client does not
42
- * call — and it is NOT `GET /api/v5/account/position-tiers`, a different endpoint carrying no
43
- * margin or leverage data at all.
44
- */
45
- async maxBasketSize(_input) {
46
- return unsizedBasket();
47
- }
48
- /** The REST path answers the same way — there is no size either way, not a slower one. */
49
- async snapshotMaxBasketSize(_input) {
50
- return unsizedBasket();
51
- }
52
- /**
53
39
  * Stateless one-shot per-asset leverage read via `leverage-info`, which accepts up to 20 instIds
54
40
  * per request (chunked in the client), so N assets cost ceil(N/20) calls. Cross margin only,
55
41
  * matching the account-level assumption used everywhere else in this connector.
@@ -406,13 +392,5 @@ function sameWithdrawable(left, right) {
406
392
  return true;
407
393
  }
408
394
  __name(sameWithdrawable, "sameWithdrawable");
409
- function unsizedBasket() {
410
- return {
411
- maxNotional: null,
412
- legs: [],
413
- bindingConstraint: null
414
- };
415
- }
416
- __name(unsizedBasket, "unsizedBasket");
417
395
 
418
396
  export { OkxAccountTracker };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pear-protocol/exchanges-sdk",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "Pear Protocol Exchanges SDK",
5
5
  "private": false,
6
6
  "type": "module",
@@ -27,9 +27,9 @@
27
27
  "test:watch": "vitest"
28
28
  },
29
29
  "dependencies": {
30
- "@pear-protocol/core-sdk": "^1.19.0",
30
+ "@pear-protocol/core-sdk": "^1.19.1",
31
31
  "@pear-protocol/types": "^1.30.1",
32
- "@pear-protocol/utils": "^0.5.3",
32
+ "@pear-protocol/utils": "^0.6.0",
33
33
  "bignumber.js": "^11.1.1",
34
34
  "partysocket": "^1.0.3",
35
35
  "viem": "^2.48.8",
@@ -1,194 +0,0 @@
1
- import BigNumber from 'bignumber.js';
2
- import { z } from 'zod';
3
- import { Side, DecimalString, MarginMode } from './balance-core';
4
-
5
- var __defProp = Object.defineProperty;
6
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
- const BasketLeg = z.object({
8
- asset: z.string(),
9
- marginMode: MarginMode,
10
- leverage: DecimalString,
11
- side: Side,
12
- /** Unsigned percentage. The set sums to 100. */
13
- weight: z.number().positive()
14
- });
15
- const MaxBasketSizeInput = z.object({
16
- legs: z.array(BasketLeg).min(1)
17
- });
18
- const MaxBasketSizeResult = z.object({
19
- /**
20
- * The whole basket's max GROSS notional in USD — Σ leg notional, not per-side and not per-asset.
21
- * The basket is atomic, so this is one ceiling for the entire structure.
22
- * Null when the venue cannot supply a per-asset max leverage (all three CEXs in v1), and null
23
- * when any leg draws on a pool the caller could not value.
24
- */
25
- maxNotional: DecimalString.nullable(),
26
- /** Derived from maxNotional — each leg's notional at that basket size. NOT a per-leg maximum. */
27
- legs: z.array(z.object({
28
- asset: z.string(),
29
- notional: DecimalString,
30
- marginRequired: DecimalString
31
- })),
32
- /** Which pool or leg ran out first. */
33
- bindingConstraint: z.discriminatedUnion("kind", [
34
- z.object({
35
- kind: z.literal("cross-pool"),
36
- pool: z.string()
37
- }),
38
- z.object({
39
- kind: z.literal("isolated-leg"),
40
- asset: z.string()
41
- })
42
- ]).nullable()
43
- });
44
- function computeMaxBasketSize(input) {
45
- if (!isSizeableInput(input)) {
46
- return unsizedResult();
47
- }
48
- const budgets = new Map(Object.entries(input.budgets));
49
- const weightSum = sumWeights(input.legs);
50
- if (weightSum.isZero()) {
51
- return unsizedResult();
52
- }
53
- const shares = input.legs.map((leg) => toLegShare(leg, weightSum));
54
- const demandByPool = marginPerUnitNotionalByPool(shares);
55
- const tightestPool = tightestPoolCeiling(demandByPool, budgets);
56
- if (tightestPool === null) {
57
- return unsizedResult();
58
- }
59
- const tightestCap = tightestLegCap(shares);
60
- if (tightestCap === null || tightestPool.size.isLessThanOrEqualTo(tightestCap.size)) {
61
- return buildResult(tightestPool.size, shares, {
62
- kind: "cross-pool",
63
- pool: tightestPool.pool
64
- });
65
- }
66
- return buildResult(tightestCap.size, shares, {
67
- kind: "isolated-leg",
68
- asset: tightestCap.asset
69
- });
70
- }
71
- __name(computeMaxBasketSize, "computeMaxBasketSize");
72
- function isSizeableInput(input) {
73
- for (const budget of Object.values(input.budgets)) {
74
- if (!isUnsignedDecimal(budget)) {
75
- return false;
76
- }
77
- }
78
- for (const leg of input.legs) {
79
- if (!isPositiveFinite(leg.weight)) {
80
- return false;
81
- }
82
- if (!isUsableLeverage(leg.effectiveLeverage)) {
83
- return false;
84
- }
85
- if (leg.maxNotional !== null && !isUnsignedDecimal(leg.maxNotional)) {
86
- return false;
87
- }
88
- }
89
- return true;
90
- }
91
- __name(isSizeableInput, "isSizeableInput");
92
- function isUnsignedDecimal(value) {
93
- return DecimalString.safeParse(value).success;
94
- }
95
- __name(isUnsignedDecimal, "isUnsignedDecimal");
96
- function isPositiveFinite(weight) {
97
- return Number.isFinite(weight) && weight > 0;
98
- }
99
- __name(isPositiveFinite, "isPositiveFinite");
100
- function isUsableLeverage(effectiveLeverage) {
101
- if (!isUnsignedDecimal(effectiveLeverage)) {
102
- return false;
103
- }
104
- return !new BigNumber(effectiveLeverage).isZero();
105
- }
106
- __name(isUsableLeverage, "isUsableLeverage");
107
- function sumWeights(legs) {
108
- let total = new BigNumber(0);
109
- for (const leg of legs) {
110
- total = total.plus(String(leg.weight));
111
- }
112
- return total;
113
- }
114
- __name(sumWeights, "sumWeights");
115
- function unsizedResult() {
116
- return {
117
- maxNotional: null,
118
- legs: [],
119
- bindingConstraint: null
120
- };
121
- }
122
- __name(unsizedResult, "unsizedResult");
123
- function toLegShare(leg, weightSum) {
124
- return {
125
- asset: leg.asset,
126
- pool: leg.pool,
127
- share: new BigNumber(String(leg.weight)).div(weightSum),
128
- imr: new BigNumber(1).div(leg.effectiveLeverage),
129
- maxNotional: leg.maxNotional === null ? null : new BigNumber(leg.maxNotional)
130
- };
131
- }
132
- __name(toLegShare, "toLegShare");
133
- function marginPerUnitNotionalByPool(shares) {
134
- const demandByPool = /* @__PURE__ */ new Map();
135
- for (const leg of shares) {
136
- const running = demandByPool.get(leg.pool) ?? new BigNumber(0);
137
- demandByPool.set(leg.pool, running.plus(leg.share.times(leg.imr)));
138
- }
139
- return demandByPool;
140
- }
141
- __name(marginPerUnitNotionalByPool, "marginPerUnitNotionalByPool");
142
- function tightestPoolCeiling(demandByPool, budgets) {
143
- let tightest = null;
144
- for (const [pool, marginPerUnitNotional] of demandByPool) {
145
- const budget = budgets.get(pool);
146
- if (budget === void 0) {
147
- return null;
148
- }
149
- const size = new BigNumber(budget).div(marginPerUnitNotional);
150
- if (tightest === null || size.isLessThan(tightest.size)) {
151
- tightest = {
152
- pool,
153
- size
154
- };
155
- }
156
- }
157
- return tightest;
158
- }
159
- __name(tightestPoolCeiling, "tightestPoolCeiling");
160
- function tightestLegCap(shares) {
161
- let tightest = null;
162
- for (const leg of shares) {
163
- if (leg.maxNotional === null) {
164
- continue;
165
- }
166
- const size = leg.maxNotional.div(leg.share);
167
- if (tightest === null || size.isLessThan(tightest.size)) {
168
- tightest = {
169
- asset: leg.asset,
170
- size
171
- };
172
- }
173
- }
174
- return tightest;
175
- }
176
- __name(tightestLegCap, "tightestLegCap");
177
- function buildResult(size, shares, bindingConstraint) {
178
- const legs = shares.map((leg) => {
179
- const notional = size.times(leg.share);
180
- return {
181
- asset: leg.asset,
182
- notional: notional.toFixed(),
183
- marginRequired: notional.times(leg.imr).toFixed()
184
- };
185
- });
186
- return {
187
- maxNotional: size.toFixed(),
188
- legs,
189
- bindingConstraint
190
- };
191
- }
192
- __name(buildResult, "buildResult");
193
-
194
- export { BasketLeg, MaxBasketSizeInput, MaxBasketSizeResult, computeMaxBasketSize };
@@ -1,93 +0,0 @@
1
- import BigNumber from 'bignumber.js';
2
- import { splitDexCoin } from './coin-name';
3
- import { toDecimal } from './decimal';
4
-
5
- var __defProp = Object.defineProperty;
6
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
- const UNRESOLVED_POOL = "";
8
- function buildCappedLegs(legs, markets) {
9
- return legs.map((leg) => {
10
- const market = markets.get(leg.asset) ?? null;
11
- const leverage = effectiveLeverage(leg.leverage, market);
12
- return {
13
- asset: leg.asset,
14
- pool: market?.pool ?? UNRESOLVED_POOL,
15
- weight: leg.weight,
16
- effectiveLeverage: leverage,
17
- marginMode: leg.marginMode,
18
- maxNotional: tierBoundaryNotional(market?.marginTiers ?? null, leverage)
19
- };
20
- });
21
- }
22
- __name(buildCappedLegs, "buildCappedLegs");
23
- function buildPoolBudgets(legs, markets, assetData) {
24
- const dataByPool = /* @__PURE__ */ new Map();
25
- for (const leg of legs) {
26
- const pool = markets.get(leg.asset)?.pool ?? null;
27
- const data = assetData.get(leg.asset);
28
- if (pool === null || data === void 0) {
29
- continue;
30
- }
31
- const bucket = dataByPool.get(pool) ?? [];
32
- bucket.push(data);
33
- dataByPool.set(pool, bucket);
34
- }
35
- const budgets = {};
36
- for (const [pool, data] of dataByPool) {
37
- const floor = minimumAvailableToTrade(data);
38
- if (floor !== null) {
39
- budgets[pool] = floor;
40
- }
41
- }
42
- return budgets;
43
- }
44
- __name(buildPoolBudgets, "buildPoolBudgets");
45
- function effectiveLeverage(requestedLeverage, market) {
46
- let leverage = toDecimal(requestedLeverage);
47
- if (market?.venueMaxLeverage !== null && market?.venueMaxLeverage !== void 0) {
48
- leverage = BigNumber.min(leverage, market.venueMaxLeverage);
49
- }
50
- if (market?.accountLeverage !== null && market?.accountLeverage !== void 0) {
51
- leverage = BigNumber.min(leverage, market.accountLeverage);
52
- }
53
- return BigNumber.max(leverage, 1).toFixed();
54
- }
55
- __name(effectiveLeverage, "effectiveLeverage");
56
- function tierBoundaryNotional(marginTiers, effectiveLeverage2) {
57
- if (!marginTiers) {
58
- return null;
59
- }
60
- const leverage = toDecimal(effectiveLeverage2);
61
- const boundary = marginTiers.find((tier) => leverage.isGreaterThan(tier.maxLeverage));
62
- return boundary ? boundary.lowerBound : null;
63
- }
64
- __name(tierBoundaryNotional, "tierBoundaryNotional");
65
- function minimumAvailableToTrade(assetData) {
66
- let floor = null;
67
- for (const data of assetData) {
68
- for (const available of data.availableToTrade ?? []) {
69
- const value = toDecimal(available);
70
- if (floor === null || value.isLessThan(floor)) {
71
- floor = value;
72
- }
73
- }
74
- }
75
- return floor === null ? null : floor.toFixed();
76
- }
77
- __name(minimumAvailableToTrade, "minimumAvailableToTrade");
78
- function findLegMarket(dexToMeta, tokenNames, coin, accountLeverage) {
79
- const { dex, bareCoin } = splitDexCoin(coin);
80
- const meta = dexToMeta.get(dex);
81
- const asset = meta?.universe.find((candidate) => candidate.name === coin || candidate.name === bareCoin);
82
- const marginTiers = meta?.marginTables.find(([id]) => id === asset?.marginTableId)?.[1].marginTiers;
83
- const collateralToken = meta?.collateralToken;
84
- return {
85
- pool: collateralToken === void 0 ? null : tokenNames.get(collateralToken) ?? null,
86
- venueMaxLeverage: asset?.maxLeverage ?? null,
87
- accountLeverage,
88
- marginTiers: marginTiers?.length ? marginTiers : null
89
- };
90
- }
91
- __name(findLegMarket, "findLegMarket");
92
-
93
- export { buildCappedLegs, buildPoolBudgets, effectiveLeverage, findLegMarket, minimumAvailableToTrade, tierBoundaryNotional };
@@ -1,74 +0,0 @@
1
- import BigNumber from 'bignumber.js';
2
- import { QUOTE_ASSET } from './const';
3
-
4
- var __defProp = Object.defineProperty;
5
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
- const MARGIN_FRACTION_SCALE = 1e4;
7
- const CROSS_POOL = QUOTE_ASSET;
8
- const DECIMAL_PATTERN = /^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/;
9
- function toLighterBasketCalculation(legs, context) {
10
- const capped = [];
11
- for (const leg of legs) {
12
- const market = context.perpBySymbol.get(leg.asset);
13
- if (!market) {
14
- return {
15
- budgets: {},
16
- legs: []
17
- };
18
- }
19
- capped.push(toCappedLeg(leg, market, context.settingsByMarketId.get(String(market.market_id))));
20
- }
21
- return {
22
- // Every leg draws on the same pool, so one entry carries the whole basket's budget.
23
- budgets: {
24
- [CROSS_POOL]: context.availableBalance
25
- },
26
- legs: capped
27
- };
28
- }
29
- __name(toLighterBasketCalculation, "toLighterBasketCalculation");
30
- function toCappedLeg(leg, market, currentSetting) {
31
- return {
32
- asset: leg.asset,
33
- pool: CROSS_POOL,
34
- weight: leg.weight,
35
- effectiveLeverage: effectiveLeverage(leg.leverage, market, currentSetting),
36
- marginMode: leg.marginMode,
37
- maxNotional: null
38
- };
39
- }
40
- __name(toCappedLeg, "toCappedLeg");
41
- function effectiveLeverage(requested, market, currentSetting) {
42
- const accountLeverage = currentSetting === void 0 ? defaultAccountLeverage(market) : toDecimal(currentSetting.leverage);
43
- const granted = BigNumber.min(toDecimal(requested), venueMaxLeverage(market), accountLeverage);
44
- return granted.isFinite() && granted.isGreaterThan(0) ? granted.toFixed() : "1";
45
- }
46
- __name(effectiveLeverage, "effectiveLeverage");
47
- function venueMaxLeverage(market) {
48
- return leverageFromMarginFraction(market.min_initial_margin_fraction);
49
- }
50
- __name(venueMaxLeverage, "venueMaxLeverage");
51
- function defaultAccountLeverage(market) {
52
- return leverageFromMarginFraction(market.default_initial_margin_fraction).integerValue(BigNumber.ROUND_FLOOR);
53
- }
54
- __name(defaultAccountLeverage, "defaultAccountLeverage");
55
- function leverageFromMarginFraction(marginFraction) {
56
- const fraction = toDecimal(marginFraction);
57
- if (!fraction.isGreaterThan(0)) {
58
- return new BigNumber(1);
59
- }
60
- return new BigNumber(MARGIN_FRACTION_SCALE).div(fraction);
61
- }
62
- __name(leverageFromMarginFraction, "leverageFromMarginFraction");
63
- function toDecimal(value) {
64
- if (typeof value === "number") {
65
- return Number.isFinite(value) ? new BigNumber(value) : new BigNumber(0);
66
- }
67
- if (typeof value !== "string" || !DECIMAL_PATTERN.test(value)) {
68
- return new BigNumber(0);
69
- }
70
- return new BigNumber(value);
71
- }
72
- __name(toDecimal, "toDecimal");
73
-
74
- export { toLighterBasketCalculation, venueMaxLeverage };