@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.
- package/README.md +14 -0
- package/dist/cjs/OndoProvider.d.ts.map +1 -1
- package/dist/cjs/OndoProvider.js +59 -0
- package/dist/cjs/OndoProvider.js.map +1 -1
- package/dist/cjs/types/wire.d.ts +26 -0
- package/dist/cjs/types/wire.d.ts.map +1 -1
- package/dist/cjs/utils/availableToTrade.d.ts +4 -0
- package/dist/cjs/utils/availableToTrade.d.ts.map +1 -0
- package/dist/cjs/utils/availableToTrade.js +46 -0
- package/dist/cjs/utils/availableToTrade.js.map +1 -0
- package/dist/cjs/utils/index.d.ts +1 -0
- package/dist/cjs/utils/index.d.ts.map +1 -1
- package/dist/cjs/utils/index.js +3 -1
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/websocket/OndoWsProvider.js +1 -1
- package/dist/cjs/websocket/OndoWsProvider.js.map +1 -1
- package/dist/esm/OndoProvider.d.ts.map +1 -1
- package/dist/esm/OndoProvider.js +62 -2
- package/dist/esm/OndoProvider.js.map +1 -1
- package/dist/esm/types/wire.d.ts +33 -0
- package/dist/esm/types/wire.d.ts.map +1 -1
- package/dist/esm/utils/availableToTrade.d.ts +14 -0
- package/dist/esm/utils/availableToTrade.d.ts.map +1 -0
- package/dist/esm/utils/availableToTrade.js +50 -0
- package/dist/esm/utils/availableToTrade.js.map +1 -0
- package/dist/esm/utils/index.d.ts +1 -0
- package/dist/esm/utils/index.d.ts.map +1 -1
- package/dist/esm/utils/index.js +1 -0
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/esm/websocket/OndoWsProvider.js +1 -1
- package/dist/esm/websocket/OndoWsProvider.js.map +1 -1
- package/dist/types/OndoProvider.d.ts.map +1 -1
- package/dist/types/types/wire.d.ts +33 -0
- package/dist/types/types/wire.d.ts.map +1 -1
- package/dist/types/utils/availableToTrade.d.ts +14 -0
- package/dist/types/utils/availableToTrade.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/types/utils/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/OndoProvider.ts +89 -0
- package/src/types/wire.ts +34 -0
- package/src/utils/availableToTrade.ts +68 -0
- package/src/utils/index.ts +1 -0
- package/src/websocket/OndoWsProvider.ts +1 -1
package/src/OndoProvider.ts
CHANGED
|
@@ -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
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -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
|
)
|