@pear-protocol/exchanges-sdk 0.10.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.
@@ -300,6 +300,80 @@ async function fetchPositionFundingSince(accountIndex, authToken, since, demo =
300
300
  return Array.from(results.values());
301
301
  }
302
302
  __name(fetchPositionFundingSince, "fetchPositionFundingSince");
303
+ async function submitReferralCode(params, demo = false) {
304
+ const body = new URLSearchParams({
305
+ l1_address: params.l1Address,
306
+ referral_code: params.referralCode
307
+ });
308
+ if (params.discord) {
309
+ body.set("discord", params.discord);
310
+ }
311
+ if (params.telegram) {
312
+ body.set("telegram", params.telegram);
313
+ }
314
+ if (params.x) {
315
+ body.set("x", params.x);
316
+ }
317
+ if (params.signature) {
318
+ body.set("signature", params.signature);
319
+ }
320
+ const response = await authenticatedLighterFetch(`${getLighterBaseUrl(demo)}/api/v1/referral/use`, params.authToken, {
321
+ method: "POST",
322
+ headers: {
323
+ "Content-Type": "application/x-www-form-urlencoded"
324
+ },
325
+ body
326
+ });
327
+ await readLighterResponse(response, "/referral/use");
328
+ }
329
+ __name(submitReferralCode, "submitReferralCode");
330
+ async function fetchUserReferrals(params, demo = false) {
331
+ const query = new URLSearchParams({
332
+ l1_address: params.l1Address
333
+ });
334
+ if (params.cursor) {
335
+ query.set("cursor", params.cursor);
336
+ }
337
+ if (params.statsStartTimestamp !== void 0) {
338
+ query.set("stats_start_timestamp", params.statsStartTimestamp.toString());
339
+ }
340
+ if (params.statsEndTimestamp !== void 0) {
341
+ query.set("stats_end_timestamp", params.statsEndTimestamp.toString());
342
+ }
343
+ if (params.limit !== void 0) {
344
+ query.set("limit", params.limit.toString());
345
+ }
346
+ if (params.eligibleOnly) {
347
+ query.set("is_eligible", "true");
348
+ }
349
+ const response = await authenticatedLighterFetch(`${getLighterBaseUrl(demo)}/api/v1/referral/userReferrals?${query.toString()}`, params.authToken);
350
+ const data = await readLighterResponse(response, "/referral/userReferrals");
351
+ const referrals = [];
352
+ for (const referral of data.referrals ?? []) {
353
+ if (typeof referral !== "object" || referral === null) {
354
+ continue;
355
+ }
356
+ if (typeof referral.l1_address !== "string") {
357
+ continue;
358
+ }
359
+ referrals.push({
360
+ l1Address: referral.l1_address,
361
+ referralCode: typeof referral.referral_code === "string" ? referral.referral_code : "",
362
+ usedAt: readReferralCount(referral.used_at),
363
+ tier: typeof referral.tier === "string" ? referral.tier : "",
364
+ tradeStats: readReferralTradeStats(referral.trade_stats)
365
+ });
366
+ }
367
+ return {
368
+ usedCode: typeof data.used_code === "string" && data.used_code.length > 0 ? data.used_code : null,
369
+ referrals,
370
+ totals: readReferralTotals(data.totals),
371
+ // Reuse the funding-history reading: it treats an unparseable cursor as live, so the worst an
372
+ // encoding mismatch costs here is one extra empty page rather than a dropped one.
373
+ nextCursor: readHistoryCursor(data.cursor)
374
+ };
375
+ }
376
+ __name(fetchUserReferrals, "fetchUserReferrals");
303
377
  async function authenticatedLighterFetch(url, authToken, init) {
304
378
  const headers = new Headers(init?.headers);
305
379
  headers.set("authorization", authToken);
@@ -374,5 +448,49 @@ async function readLighterResponse(response, endpoint, acceptedCodes = [
374
448
  return data;
375
449
  }
376
450
  __name(readLighterResponse, "readLighterResponse");
451
+ function readReferralTradeStats(stats) {
452
+ const raw = typeof stats === "object" && stats !== null ? stats : {};
453
+ return {
454
+ count: readReferralCount(raw.count),
455
+ volume: readReferralAmount(raw.volume),
456
+ webCount: readReferralCount(raw.web_count),
457
+ webVolume: readReferralAmount(raw.web_volume),
458
+ mobileAppCount: readReferralCount(raw.mobile_app_count),
459
+ mobileAppVolume: readReferralAmount(raw.mobile_app_volume),
460
+ mobileBrowserCount: readReferralCount(raw.mobile_browser_count),
461
+ mobileBrowserVolume: readReferralAmount(raw.mobile_browser_volume),
462
+ freeMakerVolume: readReferralAmount(raw.free_maker_volume),
463
+ freeTakerVolume: readReferralAmount(raw.free_taker_volume),
464
+ nonFreeMakerVolume: readReferralAmount(raw.non_free_maker_volume),
465
+ nonFreeTakerVolume: readReferralAmount(raw.non_free_taker_volume),
466
+ makerFeesPaid: readReferralAmount(raw.maker_fees_paid),
467
+ takerFeesPaid: readReferralAmount(raw.taker_fees_paid)
468
+ };
469
+ }
470
+ __name(readReferralTradeStats, "readReferralTradeStats");
471
+ function readReferralTotals(totals) {
472
+ const raw = typeof totals === "object" && totals !== null ? totals : {};
473
+ return {
474
+ count: readReferralCount(raw.count),
475
+ volume: readReferralAmount(raw.volume),
476
+ freeMakerVolume: readReferralAmount(raw.free_maker_volume),
477
+ freeTakerVolume: readReferralAmount(raw.free_taker_volume),
478
+ nonFreeMakerVolume: readReferralAmount(raw.non_free_maker_volume),
479
+ nonFreeTakerVolume: readReferralAmount(raw.non_free_taker_volume),
480
+ makerFeesPaid: readReferralAmount(raw.maker_fees_paid),
481
+ takerFeesPaid: readReferralAmount(raw.taker_fees_paid),
482
+ totalReferrals: readReferralCount(raw.total_referrals),
483
+ totalPremiumReferrals: readReferralCount(raw.total_premium_referrals)
484
+ };
485
+ }
486
+ __name(readReferralTotals, "readReferralTotals");
487
+ function readReferralCount(value) {
488
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
489
+ }
490
+ __name(readReferralCount, "readReferralCount");
491
+ function readReferralAmount(value) {
492
+ return typeof value === "string" && value.length > 0 ? value : "0";
493
+ }
494
+ __name(readReferralAmount, "readReferralAmount");
377
495
 
378
- export { createCctpDepositIntentAddress, fetchAccount, fetchAccountLimits, fetchAccountMetadata, fetchAccountsByL1Address, fetchApiKeys, fetchAssetDetails, fetchDepositHistory, fetchDepositNetworks, fetchOrderBookDetails, fetchPositionFundingSince, fetchPublicAccount, fetchPublicOrderBookDetails, fetchTradesSince, fetchWithdrawHistory };
496
+ export { createCctpDepositIntentAddress, fetchAccount, fetchAccountLimits, fetchAccountMetadata, fetchAccountsByL1Address, fetchApiKeys, fetchAssetDetails, fetchDepositHistory, fetchDepositNetworks, fetchOrderBookDetails, fetchPositionFundingSince, fetchPublicAccount, fetchPublicOrderBookDetails, fetchTradesSince, fetchUserReferrals, fetchWithdrawHistory, submitReferralCode };
@@ -7,6 +7,7 @@ import { createDepositAddressForRoute, depositThroughRoute } from './deposit.hel
7
7
  import { writeWithdraw } from './ethereum';
8
8
  import { readWithdrawHistory, readDepositHistory } from './history.helper';
9
9
  import { LIGHTER_ACCOUNT_NOT_REGISTERED_CODE, readOnboardingStatus } from './onboarding.helper';
10
+ import { readUserReferrals, applyReferralCode } from './referral.helper';
10
11
  import { MIN_LIGHTER_FAST_WITHDRAW_USDC } from './types';
11
12
 
12
13
  var __defProp = Object.defineProperty;
@@ -198,6 +199,18 @@ function createLighterHelper(sdk, demo = false) {
198
199
  /** Reads one page of the account's withdrawal history, newest first. */
199
200
  async getWithdrawHistory(params) {
200
201
  return readWithdrawHistory(sdk, params, demo);
202
+ },
203
+ /** Reads the Fun.xyz bridge deposits Lighter has seen for a wallet. */
204
+ async listUdaDeposits(walletAddress) {
205
+ return sdk.core.misc.lighter.listUdaDeposits(walletAddress);
206
+ },
207
+ /** Applies a referrer's code to the owner. Lighter accepts this at most once per owner. */
208
+ async applyReferralCode(params) {
209
+ return applyReferralCode(sdk, params, demo);
210
+ },
211
+ /** Reads one page of the owner's referral record, including the code that referred them. */
212
+ async getUserReferrals(params) {
213
+ return readUserReferrals(sdk, params, demo);
201
214
  }
202
215
  };
203
216
  return helper;
@@ -0,0 +1,33 @@
1
+ import { submitReferralCode, fetchUserReferrals } from '../../client/lighter/rest';
2
+ import { retrieveLighterAuthToken } from './auth-token.helper';
3
+
4
+ var __defProp = Object.defineProperty;
5
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
+ async function applyReferralCode(sdk, params, demo) {
7
+ const authToken = await retrieveLighterAuthToken(sdk, params.credentials, demo);
8
+ await submitReferralCode({
9
+ l1Address: params.l1Address,
10
+ referralCode: params.referralCode,
11
+ authToken,
12
+ discord: params.discord,
13
+ telegram: params.telegram,
14
+ x: params.x,
15
+ signature: params.signature
16
+ }, demo);
17
+ }
18
+ __name(applyReferralCode, "applyReferralCode");
19
+ async function readUserReferrals(sdk, params, demo) {
20
+ const authToken = await retrieveLighterAuthToken(sdk, params.credentials, demo);
21
+ return fetchUserReferrals({
22
+ l1Address: params.l1Address,
23
+ authToken,
24
+ cursor: params.cursor,
25
+ statsStartTimestamp: params.statsStartTimestamp,
26
+ statsEndTimestamp: params.statsEndTimestamp,
27
+ limit: params.limit,
28
+ eligibleOnly: params.eligibleOnly
29
+ }, demo);
30
+ }
31
+ __name(readUserReferrals, "readUserReferrals");
32
+
33
+ export { applyReferralCode, readUserReferrals };
package/dist/index.d.ts CHANGED
@@ -319,6 +319,62 @@ type LighterWithdrawPage = {
319
319
  /** Null once Lighter holds no older page. */
320
320
  nextCursor: string | null;
321
321
  };
322
+ /** What one referred trader has traded, over whatever window the request asked Lighter for. */
323
+ type LighterReferralTradeStats = {
324
+ count: number;
325
+ volume: string;
326
+ webCount: number;
327
+ webVolume: string;
328
+ mobileAppCount: number;
329
+ mobileAppVolume: string;
330
+ mobileBrowserCount: number;
331
+ mobileBrowserVolume: string;
332
+ freeMakerVolume: string;
333
+ freeTakerVolume: string;
334
+ nonFreeMakerVolume: string;
335
+ nonFreeTakerVolume: string;
336
+ makerFeesPaid: string;
337
+ takerFeesPaid: string;
338
+ };
339
+ /** One trader who signed up under the owner's code. */
340
+ type LighterReferral = {
341
+ l1Address: string;
342
+ /** The code that trader used, which is the owner's own code. */
343
+ referralCode: string;
344
+ /** When the code was used. Lighter states no unit; its funding histories send milliseconds. */
345
+ usedAt: number;
346
+ /** Lighter's tier wording for that trader; a kickback accrues only above `standard`. */
347
+ tier: string;
348
+ tradeStats: LighterReferralTradeStats;
349
+ };
350
+ /** The owner's running referral totals, which count every referral rather than only this page. */
351
+ type LighterReferralTotals = {
352
+ count: number;
353
+ volume: string;
354
+ freeMakerVolume: string;
355
+ freeTakerVolume: string;
356
+ nonFreeMakerVolume: string;
357
+ nonFreeTakerVolume: string;
358
+ makerFeesPaid: string;
359
+ takerFeesPaid: string;
360
+ totalReferrals: number;
361
+ /** How many referrals hold a paid tier, which is the only kind that earns a kickback. */
362
+ totalPremiumReferrals: number;
363
+ };
364
+ /**
365
+ * One page of an owner's referral record.
366
+ *
367
+ * `usedCode` is the only place Lighter reports who referred the owner, and it reports the code
368
+ * rather than the referrer. Lighter publishes no endpoint that resolves a code back to its owner.
369
+ */
370
+ type LighterUserReferrals = {
371
+ /** The code the owner signed up under, or null when nobody referred them. */
372
+ usedCode: string | null;
373
+ referrals: LighterReferral[];
374
+ totals: LighterReferralTotals;
375
+ /** Null once Lighter holds no further page. */
376
+ nextCursor: string | null;
377
+ };
322
378
 
323
379
  /** Shares one live Lighter auth token per account without crossing rotated credentials. */
324
380
 
@@ -752,6 +808,38 @@ type LighterOnboardingStatus = {
752
808
  mainAccountIndex: number;
753
809
  subAccountIndexes: number[];
754
810
  };
811
+ type LighterApplyReferralCodeParams = {
812
+ /** Signs the write; the account it names must belong to the address below. */
813
+ credentials: LighterAuthCredentials;
814
+ /** The owner address the referral binds to; Lighter keys its referral record by address. */
815
+ l1Address: string;
816
+ /** The referrer's code, spelled the way Lighter prints it. */
817
+ referralCode: string;
818
+ /** Lighter accepts a Discord handle beside the code but documents no format for it. */
819
+ discord?: string;
820
+ /** Lighter accepts a Telegram handle beside the code but documents no format for it. */
821
+ telegram?: string;
822
+ /** Lighter accepts an X handle beside the code but documents no format for it. */
823
+ x?: string;
824
+ /** Lighter accepts a signature beside the code but documents neither its payload nor its scheme. */
825
+ signature?: string;
826
+ };
827
+ type LighterUserReferralsParams = {
828
+ /** Signs the read; the account it names must belong to the address below. */
829
+ credentials: LighterAuthCredentials;
830
+ /** The owner address whose referral record comes back. */
831
+ l1Address: string;
832
+ /** The `nextCursor` of the page just read; omit to read the first page. */
833
+ cursor?: string;
834
+ /** Opens the `tradeStats` window. Lighter states no unit for it, so pass what its own client passes. */
835
+ statsStartTimestamp?: number;
836
+ /** Closes the `tradeStats` window. Lighter states no unit for it, so pass what its own client passes. */
837
+ statsEndTimestamp?: number;
838
+ /** Rows per page, between 1 and 300; omit to take Lighter's own page size. */
839
+ limit?: number;
840
+ /** Narrows the page to the referrals Lighter counts toward a kickback tier. */
841
+ eligibleOnly?: boolean;
842
+ };
755
843
  interface LighterHelper {
756
844
  checkOnboarding(l1Address: string): Promise<LighterOnboardingStatus>;
757
845
  lookupAccount(l1Address: string): Promise<LighterLookupResult>;
@@ -774,6 +862,12 @@ interface LighterHelper {
774
862
  getDepositHistory(params: LighterDepositHistoryParams): Promise<LighterDepositPage>;
775
863
  /** Reads one page of the account's withdrawal history, newest first. */
776
864
  getWithdrawHistory(params: LighterWithdrawHistoryParams): Promise<LighterWithdrawPage>;
865
+ /** Reads the Fun.xyz bridge deposits Lighter has seen for a wallet. */
866
+ listUdaDeposits(walletAddress: string): Promise<HttpTypes.ListLighterUdaDepositsResult>;
867
+ /** Applies a referrer's code to the owner. Lighter accepts this at most once per owner. */
868
+ applyReferralCode(params: LighterApplyReferralCodeParams): Promise<void>;
869
+ /** Reads one page of the owner's referral record, including the code that referred them. */
870
+ getUserReferrals(params: LighterUserReferralsParams): Promise<LighterUserReferrals>;
777
871
  }
778
872
  type LighterLookupResult = {
779
873
  mainAccountIndex: number;
@@ -1432,98 +1526,6 @@ declare const AccountBalanceCore: z.ZodObject<{
1432
1526
  /** Human-readable name for each mode, as the venue's own account page labels it. */
1433
1527
  declare const ACCOUNT_MODE_LABELS: Record<AccountMode, string>;
1434
1528
 
1435
- /**
1436
- * Mirrors the shipped basket model (`BasketItem` in the frontend): unsigned `weight`
1437
- * with `side` alongside, weights summing to 100. Sizing ignores `side` — margin
1438
- * requirement does not depend on direction — and normalises by Σweight.
1439
- */
1440
- declare const BasketLeg: z.ZodObject<{
1441
- asset: z.ZodString;
1442
- marginMode: z.ZodEnum<{
1443
- isolated: "isolated";
1444
- cross: "cross";
1445
- }>;
1446
- leverage: z.ZodString;
1447
- side: z.ZodEnum<{
1448
- BUY: "BUY";
1449
- SELL: "SELL";
1450
- }>;
1451
- weight: z.ZodNumber;
1452
- }, z.core.$strip>;
1453
- type BasketLeg = z.infer<typeof BasketLeg>;
1454
- declare const MaxBasketSizeInput: z.ZodObject<{
1455
- legs: z.ZodArray<z.ZodObject<{
1456
- asset: z.ZodString;
1457
- marginMode: z.ZodEnum<{
1458
- isolated: "isolated";
1459
- cross: "cross";
1460
- }>;
1461
- leverage: z.ZodString;
1462
- side: z.ZodEnum<{
1463
- BUY: "BUY";
1464
- SELL: "SELL";
1465
- }>;
1466
- weight: z.ZodNumber;
1467
- }, z.core.$strip>>;
1468
- }, z.core.$strip>;
1469
- type MaxBasketSizeInput = z.infer<typeof MaxBasketSizeInput>;
1470
- declare const MaxBasketSizeResult: z.ZodObject<{
1471
- maxNotional: z.ZodNullable<z.ZodString>;
1472
- legs: z.ZodArray<z.ZodObject<{
1473
- asset: z.ZodString;
1474
- notional: z.ZodString;
1475
- marginRequired: z.ZodString;
1476
- }, z.core.$strip>>;
1477
- bindingConstraint: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
1478
- kind: z.ZodLiteral<"cross-pool">;
1479
- pool: z.ZodString;
1480
- }, z.core.$strip>, z.ZodObject<{
1481
- kind: z.ZodLiteral<"isolated-leg">;
1482
- asset: z.ZodString;
1483
- }, z.core.$strip>], "kind">>;
1484
- }, z.core.$strip>;
1485
- type MaxBasketSizeResult = z.infer<typeof MaxBasketSizeResult>;
1486
- /**
1487
- * One basket leg with its leverage already capped by the venue adapter.
1488
- *
1489
- * `marginMode` does not enter the maths: an isolated leg gets dedicated margin, but that margin is
1490
- * still transferred out of the same free balance, so it draws on the same budget as a cross leg.
1491
- * It is carried so the caller passes its basket through unchanged.
1492
- */
1493
- type CappedBasketLeg = {
1494
- asset: string;
1495
- /**
1496
- * The collateral pool this leg's margin comes out of, as the venue adapter resolves it — a CEX
1497
- * from the symbol's settlement currency, Hyperliquid from the dex's collateral token. Legs in
1498
- * different pools cannot fund each other.
1499
- */
1500
- pool: string;
1501
- /** Unsigned, in the caller's own scale — `computeMaxBasketSize` normalises by Σweight. */
1502
- weight: number;
1503
- effectiveLeverage: string;
1504
- marginMode: MarginMode;
1505
- /** This leg's own venue ceiling in USD notional; `null` when the venue names no cap. */
1506
- maxNotional: string | null;
1507
- };
1508
- /** The margin budget behind each collateral pool, plus the legs those pools must fund at once. */
1509
- type MaxBasketSizeCalculation = {
1510
- /**
1511
- * Pool id to that pool's USD-equivalent budget. A pool whose collateral is not ~1 USD supplies no
1512
- * entry until someone adds a price source, and a leg drawing on a missing entry voids the answer.
1513
- */
1514
- budgets: Record<string, string>;
1515
- legs: CappedBasketLeg[];
1516
- };
1517
- /**
1518
- * The largest gross notional this basket can reach while every leg stays funded at its weight.
1519
- *
1520
- * Returns a null size when a pool behind the basket cannot be valued — never a zero, which a
1521
- * consumer would read as "no collateral" rather than "not known". A basket whose own figures cannot
1522
- * be sized (see `isSizeableInput`) gets the same null, so this call never throws and never returns a
1523
- * result that fails `MaxBasketSizeResult`.
1524
- */
1525
- declare function computeMaxBasketSize(input: MaxBasketSizeCalculation): MaxBasketSizeResult;
1526
-
1527
1529
  interface AccountPosition {
1528
1530
  symbol: string;
1529
1531
  side: 'long' | 'short' | 'both';
@@ -1580,16 +1582,12 @@ interface AccountTracker {
1580
1582
  disconnect(): Promise<void>;
1581
1583
  snapshot(): Promise<AccountSnapshot>;
1582
1584
  snapshotAssets(coins: string[]): Promise<AssetSnapshotMap>;
1583
- /** Sizes a basket over REST alone, so it stays usable without a running socket. */
1584
- snapshotMaxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1585
1585
  readonly isConnected: boolean;
1586
1586
  readonly isInitialized: boolean;
1587
1587
  readonly hasListeners: boolean;
1588
1588
  trackBalance(cb: BalanceCallback): () => void;
1589
1589
  trackPosition(cb: PositionsCallback): () => void;
1590
1590
  trackAsset(asset: string, cb: TrackedAssetCallback): () => void;
1591
- /** Async: a basket may name assets this tracker has not subscribed to yet. */
1592
- maxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1593
1591
  getBalance(): AccountBalance | null;
1594
1592
  getPositions(): AccountPosition[];
1595
1593
  getTrackedAsset(coin: string): TrackedAssetInfo | null;
@@ -1630,9 +1628,6 @@ declare abstract class BaseAccountTracker implements AccountTracker {
1630
1628
  private broadcast;
1631
1629
  abstract start(): Promise<void>;
1632
1630
  abstract snapshot(): Promise<AccountSnapshot>;
1633
- /** Every venue implements both sizing paths — the live one and the REST one. */
1634
- abstract maxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1635
- abstract snapshotMaxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1636
1631
  protected abstract fetchAssetSnapshots(coins: string[]): Promise<AssetSnapshotMap>;
1637
1632
  abstract get isConnected(): boolean;
1638
1633
  protected abstract ensureAssetTracked(asset: string): void;
@@ -1705,15 +1700,6 @@ declare class BinanceAccountTracker extends BaseAccountTracker {
1705
1700
  private trackedAssetInfos;
1706
1701
  constructor(config: BinanceAccountTrackerConfig);
1707
1702
  snapshot(): Promise<AccountSnapshot>;
1708
- /**
1709
- * Binance sizes no basket in v1: the SDK reads no per-asset max leverage from it, and sizing off
1710
- * `availableMargin` alone would ship a number no venue field backs. The missing input is
1711
- * `/fapi/v2/positionRisk` → `maxNotionalValue` (the account's own per-symbol ceiling), with
1712
- * `/fapi/v1/leverageBracket` behind it for the tier a larger size would fall into.
1713
- */
1714
- maxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1715
- /** The REST path answers the same way — there is no size either way, not a slower one. */
1716
- snapshotMaxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1717
1703
  /**
1718
1704
  * Stateless one-shot per-asset settings read: `positionRisk` with no symbol returns leverage +
1719
1705
  * margin type for every symbol (positioned or not), so any number of assets costs one call.
@@ -1812,15 +1798,6 @@ declare class BybitAccountTracker extends BaseAccountTracker {
1812
1798
  private trackedAssetInfos;
1813
1799
  constructor(config: BybitAccountTrackerConfig);
1814
1800
  snapshot(): Promise<AccountSnapshot>;
1815
- /**
1816
- * Bybit sizes no basket in v1: the SDK reads no per-asset max leverage from it, and sizing off
1817
- * `availableMargin` alone would ship a number no venue field backs. The missing input is
1818
- * `/v5/position/list` → `leverage` (the account's own per-symbol setting), with
1819
- * `/v5/market/risk-limit` → `maxLeverage` behind it for the tier a larger size would fall into.
1820
- */
1821
- maxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1822
- /** The REST path answers the same way — there is no size either way, not a slower one. */
1823
- snapshotMaxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
1824
1801
  /**
1825
1802
  * Stateless one-shot per-asset settings read. Bybit has no batch leverage endpoint, but
1826
1803
  * `position/list` by settleCoin returns every open position (with leverage) in one call, so
@@ -2093,13 +2070,6 @@ declare class HyperliquidAccountTracker extends BaseAccountTracker {
2093
2070
  * per-asset headroom without opening a socket.
2094
2071
  */
2095
2072
  snapshot(): Promise<AccountSnapshot>;
2096
- /** Sizes a basket over REST alone, so the call stays usable without a running socket. */
2097
- snapshotMaxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
2098
- /**
2099
- * Sizes a basket against live state, fetching per-asset data for any leg the socket has not
2100
- * subscribed to — which is exactly why the call is asynchronous on both paths.
2101
- */
2102
- maxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
2103
2073
  /**
2104
2074
  * Stateless one-shot per-asset settings read via the `activeAssetData` info request (the REST
2105
2075
  * twin of the live WS subscription), one request per coin fired in parallel — the info endpoint
@@ -2123,10 +2093,6 @@ declare class HyperliquidAccountTracker extends BaseAccountTracker {
2123
2093
  private routeRaw;
2124
2094
  private handle;
2125
2095
  private loadPerpMetas;
2126
- /** Loads the dex metadata a sizing call needs, reusing whatever `start()` already cached. */
2127
- private loadPerpMetasOnce;
2128
- /** Loads the token names a pool id is spelled with, reusing whatever `start()` already cached. */
2129
- private loadCollateralTokenNamesOnce;
2130
2096
  /** Reads `activeAssetData` for each coin in parallel, dropping the coins the venue refuses. */
2131
2097
  private fetchActiveAssetEvents;
2132
2098
  /** The asset set `availableMargin` is the floor over: the locked coins plus every tracked one. */
@@ -2275,10 +2241,6 @@ declare class LighterAccountTracker extends BaseAccountTracker {
2275
2241
  * supplies the exchange default for markets absent from the account payload.
2276
2242
  */
2277
2243
  protected fetchAssetSnapshots(marketIds: string[]): Promise<AssetSnapshotMap>;
2278
- /** Sizes a basket against the live account state, falling back to REST before the socket is up. */
2279
- maxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
2280
- /** Sizes a basket over REST alone, so the answer needs no running socket. */
2281
- snapshotMaxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
2282
2244
  start(): Promise<void>;
2283
2245
  /** Creates one tracker lifecycle while repeated callers share the same pending start. */
2284
2246
  private performStart;
@@ -2323,8 +2285,6 @@ declare class LighterAccountTracker extends BaseAccountTracker {
2323
2285
  private buildBalance;
2324
2286
  /** The market data both read paths join account state against, as the latest read left it. */
2325
2287
  private marketContext;
2326
- /** The account's current per-market settings as the base tracker already holds them. */
2327
- private liveAccountSettings;
2328
2288
  /** Reads the account with credentials when present, or explicitly uses the read-only verifier path. */
2329
2289
  private fetchPrimaryAccount;
2330
2290
  /** Reads market context under the same account identity as the snapshot that consumes it. */
@@ -2484,16 +2444,6 @@ declare class OkxAccountTracker extends BaseAccountTracker {
2484
2444
  private trackedAssetInfos;
2485
2445
  constructor(config: OkxAccountTrackerConfig);
2486
2446
  snapshot(): Promise<AccountSnapshot>;
2487
- /**
2488
- * OKX sizes no basket in v1: the SDK reads no per-asset max leverage from it, and sizing off
2489
- * `availableMargin` alone would ship a number no venue field backs. The missing input is
2490
- * `GET /api/v5/public/position-tiers` → `maxLever`/`imr` per tier, which the client does not
2491
- * call — and it is NOT `GET /api/v5/account/position-tiers`, a different endpoint carrying no
2492
- * margin or leverage data at all.
2493
- */
2494
- maxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
2495
- /** The REST path answers the same way — there is no size either way, not a slower one. */
2496
- snapshotMaxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
2497
2447
  /**
2498
2448
  * Stateless one-shot per-asset leverage read via `leverage-info`, which accepts up to 20 instIds
2499
2449
  * per request (chunked in the client), so N assets cost ceil(N/20) calls. Cross margin only,
@@ -2591,11 +2541,6 @@ declare class ExchangesSDK {
2591
2541
  status(connection: ExchangeConnection, options?: ConnectOptions): Promise<AccountStatus>;
2592
2542
  createTracker(connection: ExchangeConnection): AccountTracker;
2593
2543
  snapshot(tradeAccountId: string): Promise<AccountSnapshot>;
2594
- /**
2595
- * Sizes a basket in one shot. Routed to the tracker's REST path on purpose: this entry point
2596
- * builds a throwaway tracker per call, so it must open no socket.
2597
- */
2598
- maxBasketSize(tradeAccountId: string, input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
2599
2544
  snapshotAssets(tradeAccountId: string, coins: string[]): Promise<AssetSnapshotMap>;
2600
2545
  createHelper<E extends ExchangeHelperExchange>(exchange: E): ExchangeHelperMap[E];
2601
2546
  createSyncer(connection: ExchangeConnection): AccountSyncer;
@@ -2603,4 +2548,4 @@ declare class ExchangesSDK {
2603
2548
  private fetchCredentials;
2604
2549
  }
2605
2550
 
2606
- 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 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, LighterUnifiedBalance, 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.10.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",
31
- "@pear-protocol/types": "^1.30.0",
32
- "@pear-protocol/utils": "^0.5.3",
30
+ "@pear-protocol/core-sdk": "^1.19.1",
31
+ "@pear-protocol/types": "^1.30.1",
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 };