@lifi/perps-sdk-provider-ondo 17.0.0 → 18.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/dist/cjs/OndoProvider.d.ts.map +1 -1
- package/dist/cjs/OndoProvider.js +22 -10
- package/dist/cjs/OndoProvider.js.map +1 -1
- package/dist/cjs/accountSummary.d.ts +2 -2
- package/dist/cjs/accountSummary.d.ts.map +1 -1
- package/dist/cjs/accountSummary.js +24 -2
- package/dist/cjs/accountSummary.js.map +1 -1
- package/dist/cjs/utils/collateralAsset.d.ts +3 -0
- package/dist/cjs/utils/collateralAsset.d.ts.map +1 -0
- package/dist/cjs/utils/collateralAsset.js +19 -0
- package/dist/cjs/utils/collateralAsset.js.map +1 -0
- package/dist/cjs/utils/decimal.d.ts +3 -0
- package/dist/cjs/utils/decimal.d.ts.map +1 -0
- package/dist/cjs/utils/decimal.js +22 -0
- package/dist/cjs/utils/decimal.js.map +1 -0
- package/dist/cjs/utils/index.d.ts +2 -0
- package/dist/cjs/utils/index.d.ts.map +1 -1
- package/dist/cjs/utils/index.js +5 -1
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/withdrawableBalances.d.ts +4 -0
- package/dist/cjs/utils/withdrawableBalances.d.ts.map +1 -0
- package/dist/cjs/utils/withdrawableBalances.js +12 -0
- package/dist/cjs/utils/withdrawableBalances.js.map +1 -0
- package/dist/cjs/websocket/OndoWsProvider.d.ts +3 -1
- package/dist/cjs/websocket/OndoWsProvider.d.ts.map +1 -1
- package/dist/cjs/websocket/OndoWsProvider.js +28 -27
- package/dist/cjs/websocket/OndoWsProvider.js.map +1 -1
- package/dist/esm/OndoProvider.d.ts.map +1 -1
- package/dist/esm/OndoProvider.js +24 -12
- package/dist/esm/OndoProvider.js.map +1 -1
- package/dist/esm/accountSummary.d.ts +6 -7
- package/dist/esm/accountSummary.d.ts.map +1 -1
- package/dist/esm/accountSummary.js +29 -8
- package/dist/esm/accountSummary.js.map +1 -1
- package/dist/esm/utils/collateralAsset.d.ts +10 -0
- package/dist/esm/utils/collateralAsset.d.ts.map +1 -0
- package/dist/esm/utils/collateralAsset.js +22 -0
- package/dist/esm/utils/collateralAsset.js.map +1 -0
- package/dist/esm/utils/decimal.d.ts +10 -0
- package/dist/esm/utils/decimal.d.ts.map +1 -0
- package/dist/esm/utils/decimal.js +22 -0
- package/dist/esm/utils/decimal.js.map +1 -0
- package/dist/esm/utils/index.d.ts +2 -0
- package/dist/esm/utils/index.d.ts.map +1 -1
- package/dist/esm/utils/index.js +2 -0
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/esm/utils/withdrawableBalances.d.ts +13 -0
- package/dist/esm/utils/withdrawableBalances.d.ts.map +1 -0
- package/dist/esm/utils/withdrawableBalances.js +17 -0
- package/dist/esm/utils/withdrawableBalances.js.map +1 -0
- package/dist/esm/websocket/OndoWsProvider.d.ts +15 -12
- package/dist/esm/websocket/OndoWsProvider.d.ts.map +1 -1
- package/dist/esm/websocket/OndoWsProvider.js +41 -39
- package/dist/esm/websocket/OndoWsProvider.js.map +1 -1
- package/dist/types/OndoProvider.d.ts.map +1 -1
- package/dist/types/accountSummary.d.ts +6 -7
- package/dist/types/accountSummary.d.ts.map +1 -1
- package/dist/types/utils/collateralAsset.d.ts +10 -0
- package/dist/types/utils/collateralAsset.d.ts.map +1 -0
- package/dist/types/utils/decimal.d.ts +10 -0
- package/dist/types/utils/decimal.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +2 -0
- package/dist/types/utils/index.d.ts.map +1 -1
- package/dist/types/utils/withdrawableBalances.d.ts +13 -0
- package/dist/types/utils/withdrawableBalances.d.ts.map +1 -0
- package/dist/types/websocket/OndoWsProvider.d.ts +15 -12
- package/dist/types/websocket/OndoWsProvider.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/OndoProvider.ts +38 -19
- package/src/accountSummary.ts +37 -12
- package/src/utils/collateralAsset.ts +30 -0
- package/src/utils/decimal.ts +24 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/withdrawableBalances.ts +25 -0
- package/src/websocket/OndoWsProvider.ts +53 -48
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { PerpsError } from '@lifi/perps-sdk'
|
|
2
|
+
import { PerpsErrorCode } from '@lifi/perps-types'
|
|
3
|
+
import Big from 'big.js'
|
|
4
|
+
import { ONDO_PROVIDER_KEY } from '../constants.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Exact-decimal parse of an Ondo wire decimal string. `field` names the
|
|
8
|
+
* offending field on failure, so a venue contract breach surfaces as a
|
|
9
|
+
* `PerpsError` instead of an anonymous big.js throw.
|
|
10
|
+
*
|
|
11
|
+
* @throws {PerpsError} `SDKError` when `value` is not a decimal numeric string.
|
|
12
|
+
*/
|
|
13
|
+
export const toWireBig = (value: string, field: string): Big => {
|
|
14
|
+
try {
|
|
15
|
+
return new Big(value)
|
|
16
|
+
} catch {
|
|
17
|
+
const error = new PerpsError(
|
|
18
|
+
PerpsErrorCode.SDKError,
|
|
19
|
+
`Ondo field \`${field}\` is not a valid decimal: '${value}'`
|
|
20
|
+
)
|
|
21
|
+
error.tool = ONDO_PROVIDER_KEY
|
|
22
|
+
throw error
|
|
23
|
+
}
|
|
24
|
+
}
|
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 { requireOndoCollateralAsset } from './collateralAsset.js'
|
|
19
20
|
export {
|
|
20
21
|
buildOndoProvisionPayload,
|
|
21
22
|
listOndoDepositAddress,
|
|
@@ -38,3 +39,4 @@ export { intervalFromBarSpan, mapInterval } from './ohlcvInterval.js'
|
|
|
38
39
|
export { ondoAsset } from './ondoAsset.js'
|
|
39
40
|
export { formatOrderPrice, formatOrderSize } from './orderFormatting.js'
|
|
40
41
|
export { positionMarginConstraints } from './transferMargin.js'
|
|
42
|
+
export { ondoWithdrawableBalances } from './withdrawableBalances.js'
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ProviderWithdrawableBalance } from '@lifi/perps-sdk'
|
|
2
|
+
import type { OndoBalanceSummary } from '../types/wire.js'
|
|
3
|
+
import { toWireBig } from './decimal.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The single route an Ondo withdrawal draws on: `withdrawableMargin`, the
|
|
7
|
+
* venue's own figure for the margin the account can take out. A route with
|
|
8
|
+
* nothing left to draw carries no row, and the caller applies the per-asset
|
|
9
|
+
* venue minimum.
|
|
10
|
+
*
|
|
11
|
+
* @param assetId - `Asset.id` the row is keyed by.
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
export const ondoWithdrawableBalances = (
|
|
15
|
+
assetId: string,
|
|
16
|
+
balance: OndoBalanceSummary
|
|
17
|
+
): ProviderWithdrawableBalance[] => {
|
|
18
|
+
const available = toWireBig(
|
|
19
|
+
balance.withdrawableMargin,
|
|
20
|
+
'balance.withdrawableMargin'
|
|
21
|
+
)
|
|
22
|
+
return available.gt(0)
|
|
23
|
+
? [{ assetId, route: 'perps', available: available.toFixed() }]
|
|
24
|
+
: []
|
|
25
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
DecodeChain,
|
|
2
3
|
getMarketRegistry,
|
|
3
4
|
localStorageAdapter,
|
|
4
5
|
type MarketRegistry,
|
|
@@ -18,6 +19,7 @@ import {
|
|
|
18
19
|
import type {
|
|
19
20
|
MarketContext,
|
|
20
21
|
MarketDisplay,
|
|
22
|
+
OndoAccountBalance,
|
|
21
23
|
PerpsMarketDisplay,
|
|
22
24
|
Subscription,
|
|
23
25
|
} from '@lifi/perps-types'
|
|
@@ -131,13 +133,20 @@ export class OndoWsProvider extends WsProviderBase<SubState> {
|
|
|
131
133
|
private readonly authWireRefs = new Map<string, number>()
|
|
132
134
|
|
|
133
135
|
/**
|
|
134
|
-
*
|
|
135
|
-
* (`undefined` otherwise).
|
|
136
|
-
*
|
|
136
|
+
* Latest venue balance figures while `accountSummary` is subscribed
|
|
137
|
+
* (`undefined` otherwise). REST-seeded, then re-read on every fills and
|
|
138
|
+
* positions frame, which is what moves them.
|
|
137
139
|
*/
|
|
138
|
-
private accountSummary:
|
|
139
|
-
|
|
140
|
-
|
|
140
|
+
private accountSummary: OndoAccountBalance | undefined
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Serializes the balance re-read: a single trade event emits a fills frame
|
|
144
|
+
* and a positions frame together, and two concurrent REST reads can resolve
|
|
145
|
+
* out of order. `'latest'` coalesces the backlog to one trailing refresh.
|
|
146
|
+
*/
|
|
147
|
+
private readonly accountSummaryChain = new DecodeChain('latest', (err) =>
|
|
148
|
+
wsLog.handlerFailure(this.providerKey, err)
|
|
149
|
+
)
|
|
141
150
|
|
|
142
151
|
/** Complete (mark-price-bearing) contexts, keyed by venue market symbol. */
|
|
143
152
|
private contexts: Record<string, MarketContext> = {}
|
|
@@ -215,6 +224,8 @@ export class OndoWsProvider extends WsProviderBase<SubState> {
|
|
|
215
224
|
case 'accountSummary':
|
|
216
225
|
case 'spotBalances':
|
|
217
226
|
return `${sub.channel}:${sub.address.toLowerCase()}`
|
|
227
|
+
case 'availableToTrade':
|
|
228
|
+
throw new Error(`Ondo WS does not support channel: ${sub.channel}.`)
|
|
218
229
|
}
|
|
219
230
|
}
|
|
220
231
|
|
|
@@ -269,6 +280,7 @@ export class OndoWsProvider extends WsProviderBase<SubState> {
|
|
|
269
280
|
return () => {
|
|
270
281
|
if (sub.channel === 'accountSummary') {
|
|
271
282
|
this.accountSummary = undefined
|
|
283
|
+
this.accountSummaryChain.reset()
|
|
272
284
|
}
|
|
273
285
|
for (const [key, state] of wireSubs) {
|
|
274
286
|
this.releaseWire(key, state, needsLogin)
|
|
@@ -484,6 +496,7 @@ export class OndoWsProvider extends WsProviderBase<SubState> {
|
|
|
484
496
|
],
|
|
485
497
|
]
|
|
486
498
|
case 'spotBalances':
|
|
499
|
+
case 'availableToTrade':
|
|
487
500
|
return []
|
|
488
501
|
}
|
|
489
502
|
}
|
|
@@ -530,62 +543,60 @@ export class OndoWsProvider extends WsProviderBase<SubState> {
|
|
|
530
543
|
}
|
|
531
544
|
|
|
532
545
|
/**
|
|
533
|
-
* Seed the account-summary
|
|
534
|
-
* complete before any positions frame lands. Throws {@link
|
|
546
|
+
* Seed the account-summary figures from the REST balance so the first emit
|
|
547
|
+
* is complete before any positions frame lands. Throws {@link
|
|
535
548
|
* OndoSessionExpiredError} when the SIWE session is missing, matching the
|
|
536
549
|
* other authenticated channels.
|
|
537
550
|
*/
|
|
538
551
|
private async seedAccountSummary(address: Address): Promise<void> {
|
|
539
552
|
const token = await this.requireSession(address)
|
|
540
|
-
|
|
541
|
-
'/v1/perps/balance',
|
|
542
|
-
{ authToken: token.token }
|
|
543
|
-
)
|
|
544
|
-
this.accountSummary = {
|
|
545
|
-
walletBalance: Number.parseFloat(balance.walletBalance) || 0,
|
|
546
|
-
marginUsed: Number.parseFloat(balance.usedMargin) || 0,
|
|
547
|
-
unrealizedPnl: Number.parseFloat(balance.unrealizedPnl) || 0,
|
|
548
|
-
}
|
|
553
|
+
this.accountSummary = await this.readBalance(token.token)
|
|
549
554
|
this.emitAccountSummary()
|
|
550
555
|
}
|
|
551
556
|
|
|
552
|
-
/** Re-
|
|
553
|
-
private async
|
|
557
|
+
/** Re-read the venue balance moved by the frame and re-emit the summary. */
|
|
558
|
+
private async refreshAccountSummary(address: Address): Promise<void> {
|
|
554
559
|
const token = await this.tokenStore.get(address)
|
|
555
560
|
if (token === null || this.accountSummary === undefined) {
|
|
556
561
|
return
|
|
557
562
|
}
|
|
558
|
-
const balance = await this.
|
|
559
|
-
'/v1/perps/balance',
|
|
560
|
-
{ authToken: token.token }
|
|
561
|
-
)
|
|
563
|
+
const balance = await this.readBalance(token.token)
|
|
562
564
|
if (this.accountSummary === undefined) {
|
|
563
565
|
return
|
|
564
566
|
}
|
|
565
|
-
this.accountSummary
|
|
566
|
-
Number.parseFloat(balance.walletBalance) || 0
|
|
567
|
+
this.accountSummary = balance
|
|
567
568
|
this.emitAccountSummary()
|
|
568
569
|
}
|
|
569
570
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
571
|
+
private async readBalance(authToken: string): Promise<OndoAccountBalance> {
|
|
572
|
+
const balance = await this.restClient().get<OndoBalanceSummary>(
|
|
573
|
+
'/v1/perps/balance',
|
|
574
|
+
{ authToken }
|
|
575
|
+
)
|
|
576
|
+
return {
|
|
577
|
+
walletBalance: balance.walletBalance,
|
|
578
|
+
unrealizedPnl: balance.unrealizedPnl,
|
|
579
|
+
marginBalance: balance.marginBalance,
|
|
580
|
+
usedMargin: balance.usedMargin,
|
|
581
|
+
availableMargin: balance.availableMargin,
|
|
582
|
+
withdrawableMargin: balance.withdrawableMargin,
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/** Emit the current account summary from the venue balance figures. */
|
|
575
587
|
private emitAccountSummary(): void {
|
|
576
|
-
const
|
|
588
|
+
const balance = this.accountSummary
|
|
577
589
|
const address = this.accountAddress
|
|
578
|
-
if (
|
|
590
|
+
if (balance === undefined || address === undefined) {
|
|
579
591
|
return
|
|
580
592
|
}
|
|
581
|
-
const portfolioValue = summary.walletBalance + summary.unrealizedPnl
|
|
582
593
|
this.emit(`accountSummary:${address}`, {
|
|
583
594
|
channel: 'accountSummary',
|
|
584
595
|
data: {
|
|
585
|
-
portfolioValue:
|
|
586
|
-
availableMargin:
|
|
587
|
-
marginUsed:
|
|
588
|
-
unrealizedPnl:
|
|
596
|
+
portfolioValue: balance.marginBalance,
|
|
597
|
+
availableMargin: balance.availableMargin,
|
|
598
|
+
marginUsed: balance.usedMargin,
|
|
599
|
+
unrealizedPnl: balance.unrealizedPnl,
|
|
589
600
|
},
|
|
590
601
|
})
|
|
591
602
|
}
|
|
@@ -792,8 +803,8 @@ export class OndoWsProvider extends WsProviderBase<SubState> {
|
|
|
792
803
|
}
|
|
793
804
|
this.emit(`fills:${address}`, { channel: 'fills', data: mapped })
|
|
794
805
|
if (this.accountSummary !== undefined) {
|
|
795
|
-
this.
|
|
796
|
-
|
|
806
|
+
this.accountSummaryChain.push(() =>
|
|
807
|
+
this.refreshAccountSummary(address as Address)
|
|
797
808
|
)
|
|
798
809
|
}
|
|
799
810
|
}
|
|
@@ -818,15 +829,9 @@ export class OndoWsProvider extends WsProviderBase<SubState> {
|
|
|
818
829
|
data: mapped,
|
|
819
830
|
})
|
|
820
831
|
if (this.accountSummary !== undefined) {
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
marginUsed += Number.parseFloat(position.usedMargin) || 0
|
|
825
|
-
unrealizedPnl += Number.parseFloat(position.unrealizedPnl) || 0
|
|
826
|
-
}
|
|
827
|
-
this.accountSummary.marginUsed = marginUsed
|
|
828
|
-
this.accountSummary.unrealizedPnl = unrealizedPnl
|
|
829
|
-
this.emitAccountSummary()
|
|
832
|
+
this.accountSummaryChain.push(() =>
|
|
833
|
+
this.refreshAccountSummary(address as Address)
|
|
834
|
+
)
|
|
830
835
|
}
|
|
831
836
|
}
|
|
832
837
|
}
|