@lifi/perps-sdk-provider-ondo 16.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/mapActivity.d.ts +1 -1
- package/dist/cjs/utils/mapActivity.d.ts.map +1 -1
- package/dist/cjs/utils/mapActivity.js +29 -17
- package/dist/cjs/utils/mapActivity.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/mapActivity.d.ts +1 -1
- package/dist/esm/utils/mapActivity.d.ts.map +1 -1
- package/dist/esm/utils/mapActivity.js +34 -17
- package/dist/esm/utils/mapActivity.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/mapActivity.d.ts +1 -1
- package/dist/types/utils/mapActivity.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/mapActivity.ts +43 -18
- package/src/utils/withdrawableBalances.ts +25 -0
- package/src/websocket/OndoWsProvider.ts +53 -48
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OndoWsProvider.d.ts","sourceRoot":"","sources":["../../../src/websocket/OndoWsProvider.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"OndoWsProvider.d.ts","sourceRoot":"","sources":["../../../src/websocket/OndoWsProvider.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lifi/perps-sdk-provider-ondo",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "18.0.0",
|
|
4
4
|
"description": "Ondo Perps provider plugin for @lifi/perps-sdk",
|
|
5
5
|
"homepage": "https://github.com/lifinance/perps-sdk",
|
|
6
6
|
"bugs": {
|
|
@@ -44,10 +44,10 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"big.js": "^7.0.1",
|
|
46
46
|
"viem": "^2.55.18",
|
|
47
|
-
"@lifi/perps-types": "^
|
|
47
|
+
"@lifi/perps-types": "^15.0.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@lifi/perps-sdk": "^
|
|
50
|
+
"@lifi/perps-sdk": "^16.0.0"
|
|
51
51
|
},
|
|
52
52
|
"publishConfig": {
|
|
53
53
|
"access": "public"
|
package/src/OndoProvider.ts
CHANGED
|
@@ -20,6 +20,8 @@ import {
|
|
|
20
20
|
type ProviderGetPortfolioHistoryParams,
|
|
21
21
|
type ProviderGetPositionsParams,
|
|
22
22
|
type ProviderGetQuoteParams,
|
|
23
|
+
type ProviderGetWithdrawableBalancesParams,
|
|
24
|
+
type ProviderWithdrawableBalance,
|
|
23
25
|
paginateActivity,
|
|
24
26
|
resolveQuote,
|
|
25
27
|
resolveRetryPolicy,
|
|
@@ -111,7 +113,9 @@ import {
|
|
|
111
113
|
mapOpenPositions,
|
|
112
114
|
mapOrder,
|
|
113
115
|
mapWithdrawalActivity,
|
|
116
|
+
ondoWithdrawableBalances,
|
|
114
117
|
positionMarginConstraints,
|
|
118
|
+
requireOndoCollateralAsset,
|
|
115
119
|
} from './utils/index.js'
|
|
116
120
|
import { mapPortfolioHistory } from './utils/mapPortfolioHistory.js'
|
|
117
121
|
import {
|
|
@@ -323,19 +327,7 @@ export const ondoProvider = (
|
|
|
323
327
|
marketRegistry().sync(),
|
|
324
328
|
])
|
|
325
329
|
|
|
326
|
-
const collateralAsset = providers
|
|
327
|
-
.find((provider) => provider.key === ONDO_PROVIDER_KEY)
|
|
328
|
-
?.categories.find(
|
|
329
|
-
(category) => category.id === ONDO_PROVIDER_KEY
|
|
330
|
-
)?.quoteAsset
|
|
331
|
-
if (collateralAsset === null || collateralAsset === undefined) {
|
|
332
|
-
const error = new PerpsError(
|
|
333
|
-
PerpsErrorCode.SDKError,
|
|
334
|
-
'Ondo provider metadata is missing its collateral asset'
|
|
335
|
-
)
|
|
336
|
-
error.tool = ONDO_PROVIDER_KEY
|
|
337
|
-
throw error
|
|
338
|
-
}
|
|
330
|
+
const collateralAsset = requireOndoCollateralAsset(providers)
|
|
339
331
|
|
|
340
332
|
const positions: Position[] = mapOpenPositions(
|
|
341
333
|
rawPositions ?? [],
|
|
@@ -343,7 +335,7 @@ export const ondoProvider = (
|
|
|
343
335
|
)
|
|
344
336
|
|
|
345
337
|
// The backend owns the collateral identity; the venue supplies its
|
|
346
|
-
//
|
|
338
|
+
// wallet balance (locked margin in, unrealized PnL out).
|
|
347
339
|
return {
|
|
348
340
|
provider: ONDO_PROVIDER_KEY,
|
|
349
341
|
address: params.address,
|
|
@@ -373,12 +365,42 @@ export const ondoProvider = (
|
|
|
373
365
|
apiKeyRegistered,
|
|
374
366
|
referralSet: referral !== null && referral !== undefined,
|
|
375
367
|
depositAddress,
|
|
368
|
+
balance: {
|
|
369
|
+
walletBalance: balance.walletBalance,
|
|
370
|
+
unrealizedPnl: balance.unrealizedPnl,
|
|
371
|
+
marginBalance: balance.marginBalance,
|
|
372
|
+
usedMargin: balance.usedMargin,
|
|
373
|
+
availableMargin: balance.availableMargin,
|
|
374
|
+
withdrawableMargin: balance.withdrawableMargin,
|
|
375
|
+
},
|
|
376
376
|
},
|
|
377
377
|
}
|
|
378
378
|
}
|
|
379
379
|
)
|
|
380
380
|
},
|
|
381
381
|
|
|
382
|
+
async getWithdrawableBalances(
|
|
383
|
+
params: ProviderGetWithdrawableBalancesParams,
|
|
384
|
+
opts?: SDKRequestOptions
|
|
385
|
+
): Promise<ProviderWithdrawableBalance[]> {
|
|
386
|
+
return withSession(
|
|
387
|
+
params.address,
|
|
388
|
+
(): ProviderWithdrawableBalance[] => [],
|
|
389
|
+
async (token) => {
|
|
390
|
+
const [{ providers }, balance] = await Promise.all([
|
|
391
|
+
getProviders(requireClient(), opts),
|
|
392
|
+
apiClient(opts).get<OndoBalanceSummary>('/v1/perps/balance', {
|
|
393
|
+
authToken: token.token,
|
|
394
|
+
}),
|
|
395
|
+
])
|
|
396
|
+
return ondoWithdrawableBalances(
|
|
397
|
+
requireOndoCollateralAsset(providers).id,
|
|
398
|
+
balance
|
|
399
|
+
)
|
|
400
|
+
}
|
|
401
|
+
)
|
|
402
|
+
},
|
|
403
|
+
|
|
382
404
|
async accountExists(
|
|
383
405
|
params: ProviderAccountExistsParams,
|
|
384
406
|
opts?: SDKRequestOptions
|
|
@@ -899,11 +921,8 @@ export const ondoProvider = (
|
|
|
899
921
|
)
|
|
900
922
|
},
|
|
901
923
|
|
|
902
|
-
getAccountSummary(
|
|
903
|
-
account
|
|
904
|
-
positions: Position[]
|
|
905
|
-
): AccountSummary {
|
|
906
|
-
return getAccountSummary(account, positions)
|
|
924
|
+
getAccountSummary(account: AccountResponse): AccountSummary {
|
|
925
|
+
return getAccountSummary(account)
|
|
907
926
|
},
|
|
908
927
|
|
|
909
928
|
formatOrderPrice,
|
package/src/accountSummary.ts
CHANGED
|
@@ -1,22 +1,47 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PerpsError } from '@lifi/perps-sdk'
|
|
2
2
|
import type {
|
|
3
3
|
AccountResponse,
|
|
4
4
|
AccountSummary,
|
|
5
|
-
|
|
5
|
+
OndoAccountBalance,
|
|
6
6
|
} from '@lifi/perps-types'
|
|
7
|
+
import { PerpsErrorCode } from '@lifi/perps-types'
|
|
8
|
+
|
|
9
|
+
const ZERO_SUMMARY: AccountSummary = {
|
|
10
|
+
portfolioValue: '0',
|
|
11
|
+
availableMargin: '0',
|
|
12
|
+
marginUsed: '0',
|
|
13
|
+
unrealizedPnl: '0',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const ondoBalance = (
|
|
17
|
+
account: AccountResponse
|
|
18
|
+
): OndoAccountBalance | undefined => {
|
|
19
|
+
if (account.config.provider !== 'ondo') {
|
|
20
|
+
throw new PerpsError(
|
|
21
|
+
PerpsErrorCode.SDKError,
|
|
22
|
+
`Ondo account summary received a '${account.config.provider}' account config`
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
return account.config.balance
|
|
26
|
+
}
|
|
7
27
|
|
|
8
28
|
/**
|
|
9
|
-
* Roll an Ondo
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* venue counts unrealized PnL toward buying power
|
|
13
|
-
* (`availableMargin = marginBalance − usedMargin`).
|
|
29
|
+
* Roll an Ondo account up into an {@link AccountSummary}, from the venue
|
|
30
|
+
* balance figures the response carries. A logged-out account reads no venue
|
|
31
|
+
* balance and summarizes as zero.
|
|
14
32
|
*
|
|
33
|
+
* @throws {PerpsError} `SDKError` when the account is not an Ondo one.
|
|
15
34
|
* @public
|
|
16
35
|
*/
|
|
17
|
-
export function getAccountSummary(
|
|
18
|
-
account
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
36
|
+
export function getAccountSummary(account: AccountResponse): AccountSummary {
|
|
37
|
+
const balance = ondoBalance(account)
|
|
38
|
+
if (balance === undefined) {
|
|
39
|
+
return ZERO_SUMMARY
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
portfolioValue: balance.marginBalance,
|
|
43
|
+
availableMargin: balance.availableMargin,
|
|
44
|
+
marginUsed: balance.usedMargin,
|
|
45
|
+
unrealizedPnl: balance.unrealizedPnl,
|
|
46
|
+
}
|
|
22
47
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { PerpsError } from '@lifi/perps-sdk'
|
|
2
|
+
import type { Asset, Provider } from '@lifi/perps-types'
|
|
3
|
+
import { PerpsErrorCode } from '@lifi/perps-types'
|
|
4
|
+
import { ONDO_PROVIDER_KEY } from '../constants.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The collateral asset the backend publishes for Ondo's single category. The
|
|
8
|
+
* backend owns the collateral identity, so the venue payload never names it.
|
|
9
|
+
*
|
|
10
|
+
* @throws {PerpsError} `SDKError` when the provider metadata carries none.
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export const requireOndoCollateralAsset = (
|
|
14
|
+
providers: readonly Provider[]
|
|
15
|
+
): Asset => {
|
|
16
|
+
const asset = providers
|
|
17
|
+
.find((provider) => provider.key === ONDO_PROVIDER_KEY)
|
|
18
|
+
?.categories.find(
|
|
19
|
+
(category) => category.id === ONDO_PROVIDER_KEY
|
|
20
|
+
)?.quoteAsset
|
|
21
|
+
if (asset === null || asset === undefined) {
|
|
22
|
+
const error = new PerpsError(
|
|
23
|
+
PerpsErrorCode.SDKError,
|
|
24
|
+
'Ondo provider metadata is missing its collateral asset'
|
|
25
|
+
)
|
|
26
|
+
error.tool = ONDO_PROVIDER_KEY
|
|
27
|
+
throw error
|
|
28
|
+
}
|
|
29
|
+
return asset
|
|
30
|
+
}
|
|
@@ -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'
|
package/src/utils/mapActivity.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
type AssetRegistry,
|
|
3
|
+
ExplorerChainId,
|
|
4
|
+
explorerTxUrl,
|
|
5
|
+
} from '@lifi/perps-sdk'
|
|
2
6
|
import type {
|
|
3
7
|
DepositActivity,
|
|
4
8
|
FundingActivity,
|
|
@@ -91,24 +95,46 @@ const depositId = (deposit: OndoWalletDeposit): string => {
|
|
|
91
95
|
: `deposit:${deposit.txid}:${deposit.logIndex}`
|
|
92
96
|
}
|
|
93
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Explorer chain per Ondo wire `chainId`, whose values Ondo's REST spec
|
|
100
|
+
* enumerates. Ondo also settles on Bitcoin, Solana and testnets, and a row on
|
|
101
|
+
* one of those resolves to no explorer link.
|
|
102
|
+
*/
|
|
103
|
+
const EXPLORER_CHAIN_BY_ONDO_CHAIN_ID: Record<string, ExplorerChainId> = {
|
|
104
|
+
'eth-mainnet': ExplorerChainId.ETHEREUM,
|
|
105
|
+
'avax-c-chain': ExplorerChainId.AVALANCHE_C_CHAIN,
|
|
106
|
+
'bsc-mainnet': ExplorerChainId.BNB_SMART_CHAIN,
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const ondoExplorerLink = (
|
|
110
|
+
chainId: string,
|
|
111
|
+
txid: string
|
|
112
|
+
): string | undefined => {
|
|
113
|
+
const explorerChainId = EXPLORER_CHAIN_BY_ONDO_CHAIN_ID[chainId]
|
|
114
|
+
return explorerChainId === undefined
|
|
115
|
+
? undefined
|
|
116
|
+
: explorerTxUrl(explorerChainId, txid)
|
|
117
|
+
}
|
|
118
|
+
|
|
94
119
|
/** Map a wallet deposit with registry asset identity and its on-chain transaction. @public */
|
|
95
120
|
export const mapDepositActivity = (
|
|
96
121
|
deposit: OndoWalletDeposit,
|
|
97
122
|
assetRegistry: AssetRegistry
|
|
98
|
-
): DepositActivity =>
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
123
|
+
): DepositActivity => {
|
|
124
|
+
const explorerLink = ondoExplorerLink(deposit.chainId, deposit.txid)
|
|
125
|
+
return {
|
|
126
|
+
id: depositId(deposit),
|
|
127
|
+
provider: ONDO_PROVIDER_KEY,
|
|
128
|
+
timestamp: new Date(deposit.time).toISOString(),
|
|
129
|
+
type: ActivityType.DEPOSIT,
|
|
130
|
+
asset: assetRegistry.require(deposit.coin),
|
|
131
|
+
amount: deposit.size,
|
|
132
|
+
...(deposit.fromAddress === ''
|
|
133
|
+
? {}
|
|
134
|
+
: { counterpartyAddress: deposit.fromAddress }),
|
|
135
|
+
...(explorerLink === undefined ? {} : { explorerLink }),
|
|
136
|
+
}
|
|
137
|
+
}
|
|
112
138
|
|
|
113
139
|
const SETTLING_WITHDRAWAL_STATUSES = new Set<string>([
|
|
114
140
|
'complete',
|
|
@@ -133,6 +159,7 @@ export const mapWithdrawalActivity = (
|
|
|
133
159
|
if (!SETTLING_WITHDRAWAL_STATUSES.has(withdrawal.status)) {
|
|
134
160
|
return null
|
|
135
161
|
}
|
|
162
|
+
const explorerLink = ondoExplorerLink(withdrawal.chainId, withdrawal.txid)
|
|
136
163
|
return {
|
|
137
164
|
id: withdrawal.withdrawal_id,
|
|
138
165
|
provider: ONDO_PROVIDER_KEY,
|
|
@@ -149,8 +176,6 @@ export const mapWithdrawalActivity = (
|
|
|
149
176
|
asset: ONDO_WITHDRAWAL_FEE_SYMBOL,
|
|
150
177
|
},
|
|
151
178
|
}),
|
|
152
|
-
...(
|
|
153
|
-
? {}
|
|
154
|
-
: { explorerLink: `https://scan.li.fi/tx/${withdrawal.txid}` }),
|
|
179
|
+
...(explorerLink === undefined ? {} : { explorerLink }),
|
|
155
180
|
}
|
|
156
181
|
}
|
|
@@ -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
|
}
|