@lifi/perps-sdk-provider-ondo 19.0.0 → 20.0.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.
Files changed (44) hide show
  1. package/README.md +14 -0
  2. package/dist/cjs/OndoProvider.d.ts.map +1 -1
  3. package/dist/cjs/OndoProvider.js +59 -0
  4. package/dist/cjs/OndoProvider.js.map +1 -1
  5. package/dist/cjs/types/wire.d.ts +26 -0
  6. package/dist/cjs/types/wire.d.ts.map +1 -1
  7. package/dist/cjs/utils/availableToTrade.d.ts +4 -0
  8. package/dist/cjs/utils/availableToTrade.d.ts.map +1 -0
  9. package/dist/cjs/utils/availableToTrade.js +46 -0
  10. package/dist/cjs/utils/availableToTrade.js.map +1 -0
  11. package/dist/cjs/utils/index.d.ts +1 -0
  12. package/dist/cjs/utils/index.d.ts.map +1 -1
  13. package/dist/cjs/utils/index.js +3 -1
  14. package/dist/cjs/utils/index.js.map +1 -1
  15. package/dist/cjs/websocket/OndoWsProvider.js +1 -1
  16. package/dist/cjs/websocket/OndoWsProvider.js.map +1 -1
  17. package/dist/esm/OndoProvider.d.ts.map +1 -1
  18. package/dist/esm/OndoProvider.js +62 -2
  19. package/dist/esm/OndoProvider.js.map +1 -1
  20. package/dist/esm/types/wire.d.ts +33 -0
  21. package/dist/esm/types/wire.d.ts.map +1 -1
  22. package/dist/esm/utils/availableToTrade.d.ts +14 -0
  23. package/dist/esm/utils/availableToTrade.d.ts.map +1 -0
  24. package/dist/esm/utils/availableToTrade.js +50 -0
  25. package/dist/esm/utils/availableToTrade.js.map +1 -0
  26. package/dist/esm/utils/index.d.ts +1 -0
  27. package/dist/esm/utils/index.d.ts.map +1 -1
  28. package/dist/esm/utils/index.js +1 -0
  29. package/dist/esm/utils/index.js.map +1 -1
  30. package/dist/esm/websocket/OndoWsProvider.js +1 -1
  31. package/dist/esm/websocket/OndoWsProvider.js.map +1 -1
  32. package/dist/types/OndoProvider.d.ts.map +1 -1
  33. package/dist/types/types/wire.d.ts +33 -0
  34. package/dist/types/types/wire.d.ts.map +1 -1
  35. package/dist/types/utils/availableToTrade.d.ts +14 -0
  36. package/dist/types/utils/availableToTrade.d.ts.map +1 -0
  37. package/dist/types/utils/index.d.ts +1 -0
  38. package/dist/types/utils/index.d.ts.map +1 -1
  39. package/package.json +2 -2
  40. package/src/OndoProvider.ts +89 -0
  41. package/src/types/wire.ts +34 -0
  42. package/src/utils/availableToTrade.ts +68 -0
  43. package/src/utils/index.ts +1 -0
  44. package/src/websocket/OndoWsProvider.ts +1 -1
@@ -13,6 +13,7 @@ import {
13
13
  type ProviderAccountExistsParams,
14
14
  type ProviderGetAccountParams,
15
15
  type ProviderGetActivityParams,
16
+ type ProviderGetAvailableToTradeParams,
16
17
  type ProviderGetDepositFlowParams,
17
18
  type ProviderGetFillsParams,
18
19
  type ProviderGetOrderParams,
@@ -28,6 +29,7 @@ import {
28
29
  type SDKRequestOptions,
29
30
  type SignActionsContext,
30
31
  type StorageAdapter,
32
+ toAssetDisplay,
31
33
  toMarketDisplay,
32
34
  toPerpsMarketDisplay,
33
35
  } from '@lifi/perps-sdk'
@@ -40,6 +42,7 @@ import type {
40
42
  ActionStep,
41
43
  ActivitiesResponse,
42
44
  ActivityItem,
45
+ AvailableToTrade,
43
46
  Fill,
44
47
  FillsResponse,
45
48
  FundingActivity,
@@ -80,11 +83,14 @@ import type {
80
83
  OndoBalanceSummary,
81
84
  OndoFill,
82
85
  OndoFundingFeeTransfer,
86
+ OndoLeverage,
83
87
  OndoLiquidationEvent,
88
+ OndoMaxOrderSizesRes,
84
89
  OndoOrder,
85
90
  OndoPortfolioGraphPoint,
86
91
  OndoPortfolioSummary,
87
92
  OndoPosition,
93
+ OndoRestMarkPrice,
88
94
  OndoTwapOrder,
89
95
  OndoWalletDeposit,
90
96
  OndoWalletWithdrawal,
@@ -113,6 +119,7 @@ import {
113
119
  mapOpenPositions,
114
120
  mapOrder,
115
121
  mapWithdrawalActivity,
122
+ ondoAvailableToTrade,
116
123
  ondoWithdrawableBalances,
117
124
  positionRemovableMargin,
118
125
  requireOndoCollateralAsset,
@@ -406,6 +413,88 @@ export const ondoProvider = (
406
413
  )
407
414
  },
408
415
 
416
+ async getAvailableToTrade(
417
+ params: ProviderGetAvailableToTradeParams,
418
+ opts?: SDKRequestOptions
419
+ ): Promise<AvailableToTrade | undefined> {
420
+ return withSession(
421
+ params.address,
422
+ () => undefined,
423
+ async (token) => {
424
+ const registry = marketRegistry()
425
+ await registry.sync()
426
+ const market = registry.require(params.marketId)
427
+ const client = apiClient(opts)
428
+ const [maxOrderSizes, leveragesRead, markPricesRead] =
429
+ await Promise.allSettled([
430
+ client
431
+ .get<OndoMaxOrderSizesRes>('/v1/perps/max_order_size', {
432
+ params: { market: market.id, buffer: '1' },
433
+ authToken: token.token,
434
+ })
435
+ .catch((error: unknown) => {
436
+ if (
437
+ error instanceof OndoApiError &&
438
+ error.errorCode === 'insufficient_margin'
439
+ ) {
440
+ return null
441
+ }
442
+ throw error
443
+ }),
444
+ client.get<OndoLeverage[]>('/v1/perps/leverage', {
445
+ params: { market: market.id },
446
+ authToken: token.token,
447
+ }),
448
+ client.get<Record<string, OndoRestMarkPrice>>(
449
+ '/v1/perps/mark_prices'
450
+ ),
451
+ ])
452
+ if (maxOrderSizes.status === 'rejected') {
453
+ throw maxOrderSizes.reason
454
+ }
455
+ const asset = toAssetDisplay(market.quoteAsset)
456
+ // The zero result reads neither companion, so their failures do not apply.
457
+ if (maxOrderSizes.value === null) {
458
+ return {
459
+ providerId: market.providerId,
460
+ marketId: market.id,
461
+ asset,
462
+ buy: '0',
463
+ sell: '0',
464
+ }
465
+ }
466
+ if (leveragesRead.status === 'rejected') {
467
+ throw leveragesRead.reason
468
+ }
469
+ if (markPricesRead.status === 'rejected') {
470
+ throw markPricesRead.reason
471
+ }
472
+ const leverage = leveragesRead.value.find(
473
+ (row) => row.market === market.id
474
+ )
475
+ const markPrice = markPricesRead.value[market.id]
476
+ if (leverage === undefined || markPrice === undefined) {
477
+ const error = new PerpsError(
478
+ PerpsErrorCode.SDKError,
479
+ `Ondo returned no ${leverage === undefined ? 'leverage' : 'mark price'} for market '${market.id}'`
480
+ )
481
+ error.tool = ONDO_PROVIDER_KEY
482
+ throw error
483
+ }
484
+ return {
485
+ providerId: market.providerId,
486
+ marketId: market.id,
487
+ asset,
488
+ ...ondoAvailableToTrade(
489
+ maxOrderSizes.value.percent100,
490
+ leverage.leverage,
491
+ markPrice.markPrice
492
+ ),
493
+ }
494
+ }
495
+ )
496
+ },
497
+
409
498
  async accountExists(
410
499
  params: ProviderAccountExistsParams,
411
500
  opts?: SDKRequestOptions
package/src/types/wire.ts CHANGED
@@ -378,3 +378,37 @@ export interface OndoPortfolioSummary {
378
378
  volume30d: string
379
379
  volumeAllTime: string
380
380
  }
381
+
382
+ /** Mirrors Ondo's `OrderSizes`: one `MaxOrderSizesRes` tier, in base-asset units. @public */
383
+ export interface OndoOrderSizes {
384
+ maxBidBaseSize: string
385
+ maxAskBaseSize: string
386
+ }
387
+
388
+ /**
389
+ * Mirrors Ondo's `MaxOrderSizesRes` (the `/v1/perps/max_order_size` result).
390
+ * The request `buffer` scales every tier. @public
391
+ */
392
+ export interface OndoMaxOrderSizesRes {
393
+ percent100: OndoOrderSizes
394
+ percent75: OndoOrderSizes
395
+ percent50: OndoOrderSizes
396
+ percent25: OndoOrderSizes
397
+ }
398
+
399
+ /** Mirrors Ondo's `ApiLeverage` (a `/v1/perps/leverage` result row). @public */
400
+ export interface OndoLeverage {
401
+ market: string
402
+ leverage: string
403
+ }
404
+
405
+ /** Mirrors Ondo's `MarkPrice` (a `/v1/perps/mark_prices` result value). @public */
406
+ export interface OndoRestMarkPrice {
407
+ market: string
408
+ pair: { base: string; quote: string }
409
+ price: string
410
+ markPrice: string
411
+ oraclePrice: string
412
+ lastExternalPrice: string
413
+ lastUpdatedTime: string
414
+ }
@@ -0,0 +1,68 @@
1
+ import { PerpsError } from '@lifi/perps-sdk'
2
+ import type { AvailableToTrade } from '@lifi/perps-types'
3
+ import { PerpsErrorCode } from '@lifi/perps-types'
4
+ import Big from 'big.js'
5
+ import { ONDO_PROVIDER_KEY } from '../constants.js'
6
+ import type { OndoOrderSizes } from '../types/wire.js'
7
+ import { toWireBig } from './decimal.js'
8
+
9
+ // A max amount must never exceed the exact cap, so the division truncates.
10
+ const TruncatingBig = Big()
11
+ TruncatingBig.RM = Big.roundDown
12
+
13
+ const outOfRange = (
14
+ field: string,
15
+ value: string,
16
+ bound: string
17
+ ): PerpsError => {
18
+ const error = new PerpsError(
19
+ PerpsErrorCode.SDKError,
20
+ `Ondo field \`${field}\` must be ${bound}: '${value}'`
21
+ )
22
+ error.tool = ONDO_PROVIDER_KEY
23
+ return error
24
+ }
25
+
26
+ const toPositiveBig = (value: string, field: string): Big => {
27
+ const parsed = toWireBig(value, field)
28
+ if (parsed.lte(0)) {
29
+ throw outOfRange(field, value, 'positive')
30
+ }
31
+ return parsed
32
+ }
33
+
34
+ const toNonNegativeBig = (value: string, field: string): Big => {
35
+ const parsed = toWireBig(value, field)
36
+ if (parsed.lt(0)) {
37
+ throw outOfRange(field, value, 'non-negative')
38
+ }
39
+ return parsed
40
+ }
41
+
42
+ /**
43
+ * Convert one Ondo max-order-size tier from base-asset units into the margin
44
+ * the order would lock: `baseSize × markPrice ÷ leverage`, truncated toward
45
+ * zero at 20 decimal places. The bid side maps to `buy` and the ask side to
46
+ * `sell`.
47
+ *
48
+ * @throws {PerpsError} `SDKError` when a venue field is not a decimal, a size
49
+ * is negative, or the leverage or mark price is not positive.
50
+ * @public
51
+ */
52
+ export const ondoAvailableToTrade = (
53
+ sizes: OndoOrderSizes,
54
+ leverage: string,
55
+ markPrice: string
56
+ ): Pick<AvailableToTrade, 'buy' | 'sell'> => {
57
+ const lev = toPositiveBig(leverage, 'leverage.leverage')
58
+ const mark = toPositiveBig(markPrice, 'markPrice.markPrice')
59
+ const toMargin = (baseSize: string, field: string): string =>
60
+ new TruncatingBig(toNonNegativeBig(baseSize, field))
61
+ .times(mark)
62
+ .div(lev)
63
+ .toFixed()
64
+ return {
65
+ buy: toMargin(sizes.maxBidBaseSize, 'maxOrderSize.maxBidBaseSize'),
66
+ sell: toMargin(sizes.maxAskBaseSize, 'maxOrderSize.maxAskBaseSize'),
67
+ }
68
+ }
@@ -16,6 +16,7 @@ export {
16
16
  type OndoRequestOptions,
17
17
  OndoSessionExpiredError,
18
18
  } from './apiClient.js'
19
+ export { ondoAvailableToTrade } from './availableToTrade.js'
19
20
  export { requireOndoCollateralAsset } from './collateralAsset.js'
20
21
  export {
21
22
  buildOndoProvisionPayload,
@@ -853,5 +853,5 @@ export const ondoWsProvider = (
853
853
  Object.assign(
854
854
  ({ provider, wsUrl, client }: WsProviderFactoryParams) =>
855
855
  new OndoWsProvider(wsUrl, provider, options, client),
856
- { streamsCandles: true }
856
+ { streamsCandles: true, streamsAvailableToTrade: false }
857
857
  )