@lifi/perps-sdk-provider-lighter 0.2.0-alpha.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/LICENSE +201 -0
- package/README.md +176 -0
- package/dist/cjs/LighterProvider.d.ts +20 -0
- package/dist/cjs/LighterProvider.d.ts.map +1 -0
- package/dist/cjs/LighterProvider.js +592 -0
- package/dist/cjs/LighterProvider.js.map +1 -0
- package/dist/cjs/accountConfig.d.ts +3 -0
- package/dist/cjs/accountConfig.d.ts.map +1 -0
- package/dist/cjs/accountConfig.js +69 -0
- package/dist/cjs/accountConfig.js.map +1 -0
- package/dist/cjs/accountSummary.d.ts +3 -0
- package/dist/cjs/accountSummary.d.ts.map +1 -0
- package/dist/cjs/accountSummary.js +8 -0
- package/dist/cjs/accountSummary.js.map +1 -0
- package/dist/cjs/constants.d.ts +14 -0
- package/dist/cjs/constants.d.ts.map +1 -0
- package/dist/cjs/constants.js +18 -0
- package/dist/cjs/constants.js.map +1 -0
- package/dist/cjs/index.d.ts +11 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +35 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/signers/LighterKeyStore.d.ts +18 -0
- package/dist/cjs/signers/LighterKeyStore.d.ts.map +1 -0
- package/dist/cjs/signers/LighterKeyStore.js +54 -0
- package/dist/cjs/signers/LighterKeyStore.js.map +1 -0
- package/dist/cjs/signers/LighterReadOnlyTokenManager.d.ts +56 -0
- package/dist/cjs/signers/LighterReadOnlyTokenManager.d.ts.map +1 -0
- package/dist/cjs/signers/LighterReadOnlyTokenManager.js +127 -0
- package/dist/cjs/signers/LighterReadOnlyTokenManager.js.map +1 -0
- package/dist/cjs/signers/LighterSigner.d.ts +41 -0
- package/dist/cjs/signers/LighterSigner.d.ts.map +1 -0
- package/dist/cjs/signers/LighterSigner.js +175 -0
- package/dist/cjs/signers/LighterSigner.js.map +1 -0
- package/dist/cjs/signers/createAuthToken.d.ts +12 -0
- package/dist/cjs/signers/createAuthToken.d.ts.map +1 -0
- package/dist/cjs/signers/createAuthToken.js +28 -0
- package/dist/cjs/signers/createAuthToken.js.map +1 -0
- package/dist/cjs/signers/index.d.ts +11 -0
- package/dist/cjs/signers/index.d.ts.map +1 -0
- package/dist/cjs/signers/index.js +19 -0
- package/dist/cjs/signers/index.js.map +1 -0
- package/dist/cjs/signers/signActions.d.ts +15 -0
- package/dist/cjs/signers/signActions.d.ts.map +1 -0
- package/dist/cjs/signers/signActions.js +142 -0
- package/dist/cjs/signers/signActions.js.map +1 -0
- package/dist/cjs/signers/wasmLoader.d.ts +42 -0
- package/dist/cjs/signers/wasmLoader.d.ts.map +1 -0
- package/dist/cjs/signers/wasmLoader.js +166 -0
- package/dist/cjs/signers/wasmLoader.js.map +1 -0
- package/dist/cjs/types/account.d.ts +97 -0
- package/dist/cjs/types/account.d.ts.map +1 -0
- package/dist/cjs/types/account.js +3 -0
- package/dist/cjs/types/account.js.map +1 -0
- package/dist/cjs/types/action.d.ts +72 -0
- package/dist/cjs/types/action.d.ts.map +1 -0
- package/dist/cjs/types/action.js +23 -0
- package/dist/cjs/types/action.js.map +1 -0
- package/dist/cjs/types/activity.d.ts +73 -0
- package/dist/cjs/types/activity.d.ts.map +1 -0
- package/dist/cjs/types/activity.js +3 -0
- package/dist/cjs/types/activity.js.map +1 -0
- package/dist/cjs/types/asset.d.ts +122 -0
- package/dist/cjs/types/asset.d.ts.map +1 -0
- package/dist/cjs/types/asset.js +3 -0
- package/dist/cjs/types/asset.js.map +1 -0
- package/dist/cjs/types/fill.d.ts +29 -0
- package/dist/cjs/types/fill.d.ts.map +1 -0
- package/dist/cjs/types/fill.js +3 -0
- package/dist/cjs/types/fill.js.map +1 -0
- package/dist/cjs/types/index.d.ts +9 -0
- package/dist/cjs/types/index.d.ts.map +1 -0
- package/dist/cjs/types/index.js +25 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/cjs/types/order.d.ts +57 -0
- package/dist/cjs/types/order.d.ts.map +1 -0
- package/dist/cjs/types/order.js +3 -0
- package/dist/cjs/types/order.js.map +1 -0
- package/dist/cjs/types/submit.d.ts +39 -0
- package/dist/cjs/types/submit.d.ts.map +1 -0
- package/dist/cjs/types/submit.js +3 -0
- package/dist/cjs/types/submit.js.map +1 -0
- package/dist/cjs/types/ws.d.ts +84 -0
- package/dist/cjs/types/ws.d.ts.map +1 -0
- package/dist/cjs/types/ws.js +3 -0
- package/dist/cjs/types/ws.js.map +1 -0
- package/dist/cjs/utils/activityCursor.d.ts +12 -0
- package/dist/cjs/utils/activityCursor.d.ts.map +1 -0
- package/dist/cjs/utils/activityCursor.js +85 -0
- package/dist/cjs/utils/activityCursor.js.map +1 -0
- package/dist/cjs/utils/apiClient.d.ts +26 -0
- package/dist/cjs/utils/apiClient.d.ts.map +1 -0
- package/dist/cjs/utils/apiClient.js +94 -0
- package/dist/cjs/utils/apiClient.js.map +1 -0
- package/dist/cjs/utils/fetchDetailedAccount.d.ts +5 -0
- package/dist/cjs/utils/fetchDetailedAccount.d.ts.map +1 -0
- package/dist/cjs/utils/fetchDetailedAccount.js +22 -0
- package/dist/cjs/utils/fetchDetailedAccount.js.map +1 -0
- package/dist/cjs/utils/index.d.ts +16 -0
- package/dist/cjs/utils/index.d.ts.map +1 -0
- package/dist/cjs/utils/index.js +45 -0
- package/dist/cjs/utils/index.js.map +1 -0
- package/dist/cjs/utils/lighterAsset.d.ts +3 -0
- package/dist/cjs/utils/lighterAsset.d.ts.map +1 -0
- package/dist/cjs/utils/lighterAsset.js +12 -0
- package/dist/cjs/utils/lighterAsset.js.map +1 -0
- package/dist/cjs/utils/liquidation.d.ts +4 -0
- package/dist/cjs/utils/liquidation.d.ts.map +1 -0
- package/dist/cjs/utils/liquidation.js +16 -0
- package/dist/cjs/utils/liquidation.js.map +1 -0
- package/dist/cjs/utils/mapFill.d.ts +4 -0
- package/dist/cjs/utils/mapFill.d.ts.map +1 -0
- package/dist/cjs/utils/mapFill.js +61 -0
- package/dist/cjs/utils/mapFill.js.map +1 -0
- package/dist/cjs/utils/mapOpenPositions.d.ts +4 -0
- package/dist/cjs/utils/mapOpenPositions.d.ts.map +1 -0
- package/dist/cjs/utils/mapOpenPositions.js +9 -0
- package/dist/cjs/utils/mapOpenPositions.js.map +1 -0
- package/dist/cjs/utils/mapOrder.d.ts +15 -0
- package/dist/cjs/utils/mapOrder.d.ts.map +1 -0
- package/dist/cjs/utils/mapOrder.js +164 -0
- package/dist/cjs/utils/mapOrder.js.map +1 -0
- package/dist/cjs/utils/mapPosition.d.ts +4 -0
- package/dist/cjs/utils/mapPosition.d.ts.map +1 -0
- package/dist/cjs/utils/mapPosition.js +30 -0
- package/dist/cjs/utils/mapPosition.js.map +1 -0
- package/dist/cjs/utils/ohlcvInterval.d.ts +2 -0
- package/dist/cjs/utils/ohlcvInterval.d.ts.map +1 -0
- package/dist/cjs/utils/ohlcvInterval.js +26 -0
- package/dist/cjs/utils/ohlcvInterval.js.map +1 -0
- package/dist/cjs/utils/orderFormatting.d.ts +4 -0
- package/dist/cjs/utils/orderFormatting.d.ts.map +1 -0
- package/dist/cjs/utils/orderFormatting.js +23 -0
- package/dist/cjs/utils/orderFormatting.js.map +1 -0
- package/dist/cjs/utils/time.d.ts +3 -0
- package/dist/cjs/utils/time.d.ts.map +1 -0
- package/dist/cjs/utils/time.js +8 -0
- package/dist/cjs/utils/time.js.map +1 -0
- package/dist/cjs/utils/wireEncoding.d.ts +9 -0
- package/dist/cjs/utils/wireEncoding.d.ts.map +1 -0
- package/dist/cjs/utils/wireEncoding.js +87 -0
- package/dist/cjs/utils/wireEncoding.js.map +1 -0
- package/dist/cjs/websocket/LighterWsProvider.d.ts +45 -0
- package/dist/cjs/websocket/LighterWsProvider.d.ts.map +1 -0
- package/dist/cjs/websocket/LighterWsProvider.js +396 -0
- package/dist/cjs/websocket/LighterWsProvider.js.map +1 -0
- package/dist/esm/LighterProvider.d.ts +105 -0
- package/dist/esm/LighterProvider.d.ts.map +1 -0
- package/dist/esm/LighterProvider.js +684 -0
- package/dist/esm/LighterProvider.js.map +1 -0
- package/dist/esm/accountConfig.d.ts +14 -0
- package/dist/esm/accountConfig.d.ts.map +1 -0
- package/dist/esm/accountConfig.js +135 -0
- package/dist/esm/accountConfig.js.map +1 -0
- package/dist/esm/accountSummary.d.ts +12 -0
- package/dist/esm/accountSummary.d.ts.map +1 -0
- package/dist/esm/accountSummary.js +14 -0
- package/dist/esm/accountSummary.js.map +1 -0
- package/dist/esm/constants.d.ts +74 -0
- package/dist/esm/constants.d.ts.map +1 -0
- package/dist/esm/constants.js +73 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/index.d.ts +22 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +22 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/signers/LighterKeyStore.d.ts +24 -0
- package/dist/esm/signers/LighterKeyStore.d.ts.map +1 -0
- package/dist/esm/signers/LighterKeyStore.js +55 -0
- package/dist/esm/signers/LighterKeyStore.js.map +1 -0
- package/dist/esm/signers/LighterReadOnlyTokenManager.d.ts +157 -0
- package/dist/esm/signers/LighterReadOnlyTokenManager.d.ts.map +1 -0
- package/dist/esm/signers/LighterReadOnlyTokenManager.js +194 -0
- package/dist/esm/signers/LighterReadOnlyTokenManager.js.map +1 -0
- package/dist/esm/signers/LighterSigner.d.ts +94 -0
- package/dist/esm/signers/LighterSigner.d.ts.map +1 -0
- package/dist/esm/signers/LighterSigner.js +228 -0
- package/dist/esm/signers/LighterSigner.js.map +1 -0
- package/dist/esm/signers/createAuthToken.d.ts +36 -0
- package/dist/esm/signers/createAuthToken.d.ts.map +1 -0
- package/dist/esm/signers/createAuthToken.js +42 -0
- package/dist/esm/signers/createAuthToken.js.map +1 -0
- package/dist/esm/signers/index.d.ts +11 -0
- package/dist/esm/signers/index.d.ts.map +1 -0
- package/dist/esm/signers/index.js +7 -0
- package/dist/esm/signers/index.js.map +1 -0
- package/dist/esm/signers/signActions.d.ts +54 -0
- package/dist/esm/signers/signActions.d.ts.map +1 -0
- package/dist/esm/signers/signActions.js +193 -0
- package/dist/esm/signers/signActions.js.map +1 -0
- package/dist/esm/signers/wasmLoader.d.ts +79 -0
- package/dist/esm/signers/wasmLoader.d.ts.map +1 -0
- package/dist/esm/signers/wasmLoader.js +180 -0
- package/dist/esm/signers/wasmLoader.js.map +1 -0
- package/dist/esm/types/account.d.ts +113 -0
- package/dist/esm/types/account.d.ts.map +1 -0
- package/dist/esm/types/account.js +4 -0
- package/dist/esm/types/account.js.map +1 -0
- package/dist/esm/types/action.d.ts +146 -0
- package/dist/esm/types/action.d.ts.map +1 -0
- package/dist/esm/types/action.js +50 -0
- package/dist/esm/types/action.js.map +1 -0
- package/dist/esm/types/activity.d.ts +83 -0
- package/dist/esm/types/activity.d.ts.map +1 -0
- package/dist/esm/types/activity.js +4 -0
- package/dist/esm/types/activity.js.map +1 -0
- package/dist/esm/types/asset.d.ts +134 -0
- package/dist/esm/types/asset.d.ts.map +1 -0
- package/dist/esm/types/asset.js +3 -0
- package/dist/esm/types/asset.js.map +1 -0
- package/dist/esm/types/fill.d.ts +31 -0
- package/dist/esm/types/fill.d.ts.map +1 -0
- package/dist/esm/types/fill.js +3 -0
- package/dist/esm/types/fill.js.map +1 -0
- package/dist/esm/types/index.d.ts +9 -0
- package/dist/esm/types/index.d.ts.map +1 -0
- package/dist/esm/types/index.js +12 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/types/order.d.ts +61 -0
- package/dist/esm/types/order.d.ts.map +1 -0
- package/dist/esm/types/order.js +3 -0
- package/dist/esm/types/order.js.map +1 -0
- package/dist/esm/types/submit.d.ts +76 -0
- package/dist/esm/types/submit.d.ts.map +1 -0
- package/dist/esm/types/submit.js +3 -0
- package/dist/esm/types/submit.js.map +1 -0
- package/dist/esm/types/ws.d.ts +124 -0
- package/dist/esm/types/ws.d.ts.map +1 -0
- package/dist/esm/types/ws.js +11 -0
- package/dist/esm/types/ws.js.map +1 -0
- package/dist/esm/utils/activityCursor.d.ts +51 -0
- package/dist/esm/utils/activityCursor.d.ts.map +1 -0
- package/dist/esm/utils/activityCursor.js +99 -0
- package/dist/esm/utils/activityCursor.js.map +1 -0
- package/dist/esm/utils/apiClient.d.ts +65 -0
- package/dist/esm/utils/apiClient.d.ts.map +1 -0
- package/dist/esm/utils/apiClient.js +131 -0
- package/dist/esm/utils/apiClient.js.map +1 -0
- package/dist/esm/utils/fetchDetailedAccount.d.ts +11 -0
- package/dist/esm/utils/fetchDetailedAccount.d.ts.map +1 -0
- package/dist/esm/utils/fetchDetailedAccount.js +24 -0
- package/dist/esm/utils/fetchDetailedAccount.js.map +1 -0
- package/dist/esm/utils/index.d.ts +16 -0
- package/dist/esm/utils/index.d.ts.map +1 -0
- package/dist/esm/utils/index.js +17 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/lighterAsset.d.ts +4 -0
- package/dist/esm/utils/lighterAsset.d.ts.map +1 -0
- package/dist/esm/utils/lighterAsset.js +9 -0
- package/dist/esm/utils/lighterAsset.js.map +1 -0
- package/dist/esm/utils/liquidation.d.ts +22 -0
- package/dist/esm/utils/liquidation.d.ts.map +1 -0
- package/dist/esm/utils/liquidation.js +31 -0
- package/dist/esm/utils/liquidation.js.map +1 -0
- package/dist/esm/utils/mapFill.d.ts +10 -0
- package/dist/esm/utils/mapFill.d.ts.map +1 -0
- package/dist/esm/utils/mapFill.js +72 -0
- package/dist/esm/utils/mapFill.js.map +1 -0
- package/dist/esm/utils/mapOpenPositions.d.ts +11 -0
- package/dist/esm/utils/mapOpenPositions.d.ts.map +1 -0
- package/dist/esm/utils/mapOpenPositions.js +12 -0
- package/dist/esm/utils/mapOpenPositions.js.map +1 -0
- package/dist/esm/utils/mapOrder.d.ts +72 -0
- package/dist/esm/utils/mapOrder.d.ts.map +1 -0
- package/dist/esm/utils/mapOrder.js +219 -0
- package/dist/esm/utils/mapOrder.js.map +1 -0
- package/dist/esm/utils/mapPosition.d.ts +9 -0
- package/dist/esm/utils/mapPosition.d.ts.map +1 -0
- package/dist/esm/utils/mapPosition.js +34 -0
- package/dist/esm/utils/mapPosition.js.map +1 -0
- package/dist/esm/utils/ohlcvInterval.d.ts +3 -0
- package/dist/esm/utils/ohlcvInterval.d.ts.map +1 -0
- package/dist/esm/utils/ohlcvInterval.js +30 -0
- package/dist/esm/utils/ohlcvInterval.js.map +1 -0
- package/dist/esm/utils/orderFormatting.d.ts +29 -0
- package/dist/esm/utils/orderFormatting.d.ts.map +1 -0
- package/dist/esm/utils/orderFormatting.js +41 -0
- package/dist/esm/utils/orderFormatting.js.map +1 -0
- package/dist/esm/utils/time.d.ts +5 -0
- package/dist/esm/utils/time.d.ts.map +1 -0
- package/dist/esm/utils/time.js +5 -0
- package/dist/esm/utils/time.js.map +1 -0
- package/dist/esm/utils/wireEncoding.d.ts +72 -0
- package/dist/esm/utils/wireEncoding.d.ts.map +1 -0
- package/dist/esm/utils/wireEncoding.js +129 -0
- package/dist/esm/utils/wireEncoding.js.map +1 -0
- package/dist/esm/websocket/LighterWsProvider.d.ts +97 -0
- package/dist/esm/websocket/LighterWsProvider.d.ts.map +1 -0
- package/dist/esm/websocket/LighterWsProvider.js +489 -0
- package/dist/esm/websocket/LighterWsProvider.js.map +1 -0
- package/dist/types/LighterProvider.d.ts +105 -0
- package/dist/types/LighterProvider.d.ts.map +1 -0
- package/dist/types/accountConfig.d.ts +14 -0
- package/dist/types/accountConfig.d.ts.map +1 -0
- package/dist/types/accountSummary.d.ts +12 -0
- package/dist/types/accountSummary.d.ts.map +1 -0
- package/dist/types/constants.d.ts +74 -0
- package/dist/types/constants.d.ts.map +1 -0
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/signers/LighterKeyStore.d.ts +24 -0
- package/dist/types/signers/LighterKeyStore.d.ts.map +1 -0
- package/dist/types/signers/LighterReadOnlyTokenManager.d.ts +157 -0
- package/dist/types/signers/LighterReadOnlyTokenManager.d.ts.map +1 -0
- package/dist/types/signers/LighterSigner.d.ts +94 -0
- package/dist/types/signers/LighterSigner.d.ts.map +1 -0
- package/dist/types/signers/createAuthToken.d.ts +36 -0
- package/dist/types/signers/createAuthToken.d.ts.map +1 -0
- package/dist/types/signers/index.d.ts +11 -0
- package/dist/types/signers/index.d.ts.map +1 -0
- package/dist/types/signers/signActions.d.ts +54 -0
- package/dist/types/signers/signActions.d.ts.map +1 -0
- package/dist/types/signers/wasmLoader.d.ts +79 -0
- package/dist/types/signers/wasmLoader.d.ts.map +1 -0
- package/dist/types/types/account.d.ts +113 -0
- package/dist/types/types/account.d.ts.map +1 -0
- package/dist/types/types/action.d.ts +146 -0
- package/dist/types/types/action.d.ts.map +1 -0
- package/dist/types/types/activity.d.ts +83 -0
- package/dist/types/types/activity.d.ts.map +1 -0
- package/dist/types/types/asset.d.ts +134 -0
- package/dist/types/types/asset.d.ts.map +1 -0
- package/dist/types/types/fill.d.ts +31 -0
- package/dist/types/types/fill.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +9 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/types/order.d.ts +61 -0
- package/dist/types/types/order.d.ts.map +1 -0
- package/dist/types/types/submit.d.ts +76 -0
- package/dist/types/types/submit.d.ts.map +1 -0
- package/dist/types/types/ws.d.ts +124 -0
- package/dist/types/types/ws.d.ts.map +1 -0
- package/dist/types/utils/activityCursor.d.ts +51 -0
- package/dist/types/utils/activityCursor.d.ts.map +1 -0
- package/dist/types/utils/apiClient.d.ts +65 -0
- package/dist/types/utils/apiClient.d.ts.map +1 -0
- package/dist/types/utils/fetchDetailedAccount.d.ts +11 -0
- package/dist/types/utils/fetchDetailedAccount.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +16 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/dist/types/utils/lighterAsset.d.ts +4 -0
- package/dist/types/utils/lighterAsset.d.ts.map +1 -0
- package/dist/types/utils/liquidation.d.ts +22 -0
- package/dist/types/utils/liquidation.d.ts.map +1 -0
- package/dist/types/utils/mapFill.d.ts +10 -0
- package/dist/types/utils/mapFill.d.ts.map +1 -0
- package/dist/types/utils/mapOpenPositions.d.ts +11 -0
- package/dist/types/utils/mapOpenPositions.d.ts.map +1 -0
- package/dist/types/utils/mapOrder.d.ts +72 -0
- package/dist/types/utils/mapOrder.d.ts.map +1 -0
- package/dist/types/utils/mapPosition.d.ts +9 -0
- package/dist/types/utils/mapPosition.d.ts.map +1 -0
- package/dist/types/utils/ohlcvInterval.d.ts +3 -0
- package/dist/types/utils/ohlcvInterval.d.ts.map +1 -0
- package/dist/types/utils/orderFormatting.d.ts +29 -0
- package/dist/types/utils/orderFormatting.d.ts.map +1 -0
- package/dist/types/utils/time.d.ts +5 -0
- package/dist/types/utils/time.d.ts.map +1 -0
- package/dist/types/utils/wireEncoding.d.ts +72 -0
- package/dist/types/utils/wireEncoding.d.ts.map +1 -0
- package/dist/types/websocket/LighterWsProvider.d.ts +97 -0
- package/dist/types/websocket/LighterWsProvider.d.ts.map +1 -0
- package/dist/wasm/lighter-signer.wasm +0 -0
- package/dist/wasm/wasm_exec.js +575 -0
- package/package.json +67 -0
- package/src/LighterProvider.ts +1167 -0
- package/src/accountConfig.ts +162 -0
- package/src/accountSummary.ts +22 -0
- package/src/constants.ts +89 -0
- package/src/index.ts +37 -0
- package/src/signers/LighterKeyStore.ts +79 -0
- package/src/signers/LighterReadOnlyTokenManager.ts +340 -0
- package/src/signers/LighterSigner.ts +400 -0
- package/src/signers/createAuthToken.ts +69 -0
- package/src/signers/index.ts +36 -0
- package/src/signers/signActions.ts +311 -0
- package/src/signers/wasmLoader.ts +293 -0
- package/src/types/account.ts +123 -0
- package/src/types/action.ts +163 -0
- package/src/types/activity.ts +94 -0
- package/src/types/asset.ts +146 -0
- package/src/types/fill.ts +42 -0
- package/src/types/index.ts +12 -0
- package/src/types/order.ts +65 -0
- package/src/types/submit.ts +83 -0
- package/src/types/ws.ts +136 -0
- package/src/utils/activityCursor.ts +150 -0
- package/src/utils/apiClient.ts +185 -0
- package/src/utils/fetchDetailedAccount.ts +46 -0
- package/src/utils/index.ts +38 -0
- package/src/utils/lighterAsset.ts +10 -0
- package/src/utils/liquidation.ts +39 -0
- package/src/utils/mapFill.ts +108 -0
- package/src/utils/mapOpenPositions.ts +18 -0
- package/src/utils/mapOrder.ts +258 -0
- package/src/utils/mapPosition.ts +42 -0
- package/src/utils/ohlcvInterval.ts +34 -0
- package/src/utils/orderFormatting.ts +46 -0
- package/src/utils/time.ts +6 -0
- package/src/utils/wireEncoding.ts +179 -0
- package/src/websocket/LighterWsProvider.ts +725 -0
- package/wasm/lighter-signer.wasm +0 -0
- package/wasm/wasm_exec.js +575 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import {
|
|
2
|
+
classifyFillFromPosition,
|
|
3
|
+
ExplorerChainId,
|
|
4
|
+
explorerTxUrl,
|
|
5
|
+
} from '@lifi/perps-sdk'
|
|
6
|
+
import type { Fill, MarketDisplay } from '@lifi/perps-types'
|
|
7
|
+
import {
|
|
8
|
+
FillStatus,
|
|
9
|
+
LiquidityRole,
|
|
10
|
+
OrderSide,
|
|
11
|
+
OrderType,
|
|
12
|
+
} from '@lifi/perps-types'
|
|
13
|
+
import Big from 'big.js'
|
|
14
|
+
import type { LtTrade } from '../types/index.js'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Realized PnL on a position-reducing fill, derived from the pre-trade entry
|
|
18
|
+
* basis. Returns `undefined` for opens/increases (nothing closes) or when the
|
|
19
|
+
* entry-quote snapshot is absent, and `null` when the closed portion realizes
|
|
20
|
+
* exactly zero — mirroring the Hyperliquid mapper's `null`-for-zero convention.
|
|
21
|
+
*/
|
|
22
|
+
const deriveRealizedPnl = (
|
|
23
|
+
startPosition: string,
|
|
24
|
+
entryQuoteBefore: string | undefined,
|
|
25
|
+
fillSize: string,
|
|
26
|
+
fillPrice: string,
|
|
27
|
+
isBuyer: boolean
|
|
28
|
+
): string | null | undefined => {
|
|
29
|
+
if (entryQuoteBefore === undefined) {
|
|
30
|
+
return undefined
|
|
31
|
+
}
|
|
32
|
+
const start = new Big(startPosition)
|
|
33
|
+
if (start.eq(0)) {
|
|
34
|
+
return undefined
|
|
35
|
+
}
|
|
36
|
+
const isLong = start.gt(0)
|
|
37
|
+
const reducing = isLong ? !isBuyer : isBuyer
|
|
38
|
+
if (!reducing) {
|
|
39
|
+
return undefined
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const absStart = start.abs()
|
|
43
|
+
const fill = new Big(fillSize)
|
|
44
|
+
// A fill larger than the open size flips the position; only the portion that
|
|
45
|
+
// unwinds the existing position realizes PnL.
|
|
46
|
+
const closedSize = fill.gt(absStart) ? absStart : fill
|
|
47
|
+
const avgEntry = new Big(entryQuoteBefore).abs().div(absStart)
|
|
48
|
+
const price = new Big(fillPrice)
|
|
49
|
+
const pnl = isLong
|
|
50
|
+
? price.minus(avgEntry).times(closedSize)
|
|
51
|
+
: avgEntry.minus(price).times(closedSize)
|
|
52
|
+
return pnl.eq(0) ? null : pnl.toString()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Map a raw Lighter trade to the generic Fill type.
|
|
57
|
+
* @param accountIndex - The viewer's Lighter account index (selects buy/sell side and maker/taker role).
|
|
58
|
+
* @param market - Backend-resolved market identity for `trade.market_id`.
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
export const mapFill = (
|
|
62
|
+
trade: LtTrade,
|
|
63
|
+
accountIndex: number,
|
|
64
|
+
market: MarketDisplay
|
|
65
|
+
): Fill => {
|
|
66
|
+
const isBuyer = trade.bid_account_id === accountIndex
|
|
67
|
+
const isMaker =
|
|
68
|
+
(trade.is_maker_ask && !isBuyer) || (!trade.is_maker_ask && isBuyer)
|
|
69
|
+
|
|
70
|
+
// Lighter publishes both counterparties' position-before snapshots on every
|
|
71
|
+
// trade row; reading the wrong one mis-classifies when they differ.
|
|
72
|
+
const startPosition = isMaker
|
|
73
|
+
? trade.maker_position_size_before
|
|
74
|
+
: trade.taker_position_size_before
|
|
75
|
+
const entryQuoteBefore = isMaker
|
|
76
|
+
? trade.maker_entry_quote_before
|
|
77
|
+
: trade.taker_entry_quote_before
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
id: trade.trade_id.toString(),
|
|
81
|
+
orderId: String(isBuyer ? trade.bid_id : trade.ask_id),
|
|
82
|
+
market,
|
|
83
|
+
side: isBuyer ? OrderSide.BUY : OrderSide.SELL,
|
|
84
|
+
type: OrderType.LIMIT,
|
|
85
|
+
size: trade.size,
|
|
86
|
+
price: trade.price,
|
|
87
|
+
status: FillStatus.FILLED,
|
|
88
|
+
liquidity: isMaker ? LiquidityRole.MAKER : LiquidityRole.TAKER,
|
|
89
|
+
fee: isMaker ? trade.maker_fee?.toString() : trade.taker_fee?.toString(),
|
|
90
|
+
realizedPnl: deriveRealizedPnl(
|
|
91
|
+
startPosition,
|
|
92
|
+
entryQuoteBefore,
|
|
93
|
+
trade.size,
|
|
94
|
+
trade.price,
|
|
95
|
+
isBuyer
|
|
96
|
+
),
|
|
97
|
+
startPosition,
|
|
98
|
+
// `classifyFillFromPosition` takes an HL-encoded side: `'B'` for buy,
|
|
99
|
+
// anything else for sell.
|
|
100
|
+
classification: classifyFillFromPosition(
|
|
101
|
+
startPosition,
|
|
102
|
+
isBuyer ? 'B' : 'A',
|
|
103
|
+
trade.size
|
|
104
|
+
),
|
|
105
|
+
createdAt: new Date(trade.timestamp).toISOString(),
|
|
106
|
+
explorerLink: explorerTxUrl(ExplorerChainId.LIGHTER, trade.tx_hash),
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { MarketDisplay, Position } from '@lifi/perps-types'
|
|
2
|
+
import type { LtAccountPosition } from '../types/index.js'
|
|
3
|
+
import { mapPosition } from './mapPosition.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Map raw Lighter account positions to open {@link Position}s, dropping
|
|
7
|
+
* zero-size rows. Only valid for payloads carrying the full position set —
|
|
8
|
+
* dropping zeros from a partial frame would make closes unobservable.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export const mapOpenPositions = (
|
|
13
|
+
positions: LtAccountPosition[],
|
|
14
|
+
resolveMarket: (marketId: number) => MarketDisplay
|
|
15
|
+
): Position[] =>
|
|
16
|
+
positions
|
|
17
|
+
.filter((p) => Number.parseFloat(p.position) !== 0)
|
|
18
|
+
.map((p) => mapPosition(p, resolveMarket(p.market_id)))
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { isActiveOrderStatus } from '@lifi/perps-sdk'
|
|
2
|
+
import type {
|
|
3
|
+
MarketDisplay,
|
|
4
|
+
OpenOrder,
|
|
5
|
+
Order,
|
|
6
|
+
TriggerOrder,
|
|
7
|
+
} from '@lifi/perps-types'
|
|
8
|
+
import {
|
|
9
|
+
OrderSide,
|
|
10
|
+
OrderStatus,
|
|
11
|
+
OrderType,
|
|
12
|
+
TimeInForce,
|
|
13
|
+
} from '@lifi/perps-types'
|
|
14
|
+
import type { LtOrder } from '../types/index.js'
|
|
15
|
+
|
|
16
|
+
// Lighter's `type` enum uses hyphens in the OpenAPI spec but earlier API
|
|
17
|
+
// versions emitted underscores. Tolerate both so we don't silently fall
|
|
18
|
+
// through to LIMIT for stop/take-profit orders.
|
|
19
|
+
const mapOrderType = (ltType: string): OrderType => {
|
|
20
|
+
const normalized = ltType.replace(/-/g, '_')
|
|
21
|
+
const map: Record<string, OrderType> = {
|
|
22
|
+
limit: OrderType.LIMIT,
|
|
23
|
+
market: OrderType.MARKET,
|
|
24
|
+
stop_loss: OrderType.STOP_MARKET,
|
|
25
|
+
stop_loss_limit: OrderType.STOP_LIMIT,
|
|
26
|
+
take_profit: OrderType.TAKE_PROFIT_MARKET,
|
|
27
|
+
take_profit_limit: OrderType.TAKE_PROFIT_LIMIT,
|
|
28
|
+
}
|
|
29
|
+
return map[normalized] ?? OrderType.LIMIT
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const mapTimeInForce = (tif: string): TimeInForce | undefined => {
|
|
33
|
+
switch (tif.replace(/-/g, '_')) {
|
|
34
|
+
case 'good_till_time':
|
|
35
|
+
return TimeInForce.GTT
|
|
36
|
+
case 'immediate_or_cancel':
|
|
37
|
+
return TimeInForce.IOC
|
|
38
|
+
case 'post_only':
|
|
39
|
+
return TimeInForce.POST_ONLY
|
|
40
|
+
default:
|
|
41
|
+
return undefined
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const mapOrderStatus = (status: string): OrderStatus => {
|
|
46
|
+
if (
|
|
47
|
+
status === 'open' ||
|
|
48
|
+
status === 'in-progress' ||
|
|
49
|
+
status === 'in_progress'
|
|
50
|
+
) {
|
|
51
|
+
return OrderStatus.OPEN
|
|
52
|
+
}
|
|
53
|
+
if (status === 'pending') {
|
|
54
|
+
return OrderStatus.PENDING
|
|
55
|
+
}
|
|
56
|
+
if (status === 'filled') {
|
|
57
|
+
return OrderStatus.FILLED
|
|
58
|
+
}
|
|
59
|
+
if (status.startsWith('canceled')) {
|
|
60
|
+
return OrderStatus.CANCELLED
|
|
61
|
+
}
|
|
62
|
+
return OrderStatus.OPEN
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Map a raw Lighter order status to a short English sentence describing
|
|
67
|
+
* *why* the order ended in a terminal non-FILLED state. Non-terminal
|
|
68
|
+
* statuses, plain `filled`, and unknown values return `undefined`.
|
|
69
|
+
* @public
|
|
70
|
+
*/
|
|
71
|
+
export const mapStatusReason = (status: string): string | undefined => {
|
|
72
|
+
switch (status) {
|
|
73
|
+
case 'canceled':
|
|
74
|
+
return 'Order cancelled.'
|
|
75
|
+
case 'canceled-post-only':
|
|
76
|
+
return 'Order cancelled: post-only order would have crossed the book.'
|
|
77
|
+
case 'canceled-reduce-only':
|
|
78
|
+
return 'Order cancelled: would not reduce your position.'
|
|
79
|
+
case 'canceled-position-not-allowed':
|
|
80
|
+
return 'Order cancelled: position not allowed.'
|
|
81
|
+
case 'canceled-margin-not-allowed':
|
|
82
|
+
return 'Order cancelled: insufficient margin.'
|
|
83
|
+
case 'canceled-too-much-slippage':
|
|
84
|
+
return 'Order cancelled: slippage exceeded tolerance.'
|
|
85
|
+
case 'canceled-not-enough-liquidity':
|
|
86
|
+
return 'Order cancelled: not enough liquidity to fill.'
|
|
87
|
+
case 'canceled-self-trade':
|
|
88
|
+
return 'Order cancelled: would self-trade against your own resting order.'
|
|
89
|
+
case 'canceled-expired':
|
|
90
|
+
return 'Order expired.'
|
|
91
|
+
case 'canceled-oco':
|
|
92
|
+
return 'Order cancelled: sibling OCO order filled or cancelled first.'
|
|
93
|
+
case 'canceled-child':
|
|
94
|
+
return 'Order cancelled: parent order was cancelled.'
|
|
95
|
+
case 'canceled-liquidation':
|
|
96
|
+
return 'Order cancelled: account was liquidated.'
|
|
97
|
+
case 'canceled-invalid-balance':
|
|
98
|
+
return 'Order cancelled: invalid balance.'
|
|
99
|
+
default:
|
|
100
|
+
return undefined
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* True for order types Lighter exposes as TP/SL legs. Mirrors the
|
|
106
|
+
* Hyperliquid helper of the same name so the backend can split a raw
|
|
107
|
+
* Lighter order list into the same `openOrders` / `triggerOrders`
|
|
108
|
+
* buckets the SDK declares on `OrdersResponse`.
|
|
109
|
+
* @public
|
|
110
|
+
*/
|
|
111
|
+
export const isTriggerType = (type: OrderType): boolean =>
|
|
112
|
+
type === OrderType.TAKE_PROFIT_MARKET ||
|
|
113
|
+
type === OrderType.TAKE_PROFIT_LIMIT ||
|
|
114
|
+
type === OrderType.STOP_MARKET ||
|
|
115
|
+
type === OrderType.STOP_LIMIT
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Decide whether a raw Lighter order belongs in the cross-provider
|
|
119
|
+
* `triggerOrders` bucket. Single source of truth for both the REST
|
|
120
|
+
* `getOrders` path and the `account_all_orders` WS handler.
|
|
121
|
+
*
|
|
122
|
+
* Authoritative signals, in order:
|
|
123
|
+
* 1. `trigger_status` — Lighter's own enum. `'ready' | 'mark-price' |
|
|
124
|
+
* 'parent-order'` all mean "this order has trigger semantics" (TP/SL
|
|
125
|
+
* waiting on price, or a TP/SL leg of a parent placeOrder). `'twap'`
|
|
126
|
+
* is intentionally excluded — TWAP child orders are scheduled resting
|
|
127
|
+
* limits, not TP/SL triggers. `'na'` is "regular order".
|
|
128
|
+
* 2. `trigger_price > 0` — catches cases where `trigger_status`
|
|
129
|
+
* momentarily lags during state transitions (e.g. right after an OCO
|
|
130
|
+
* sibling cancels).
|
|
131
|
+
* 3. `type` — final fallback via the mapped `OrderType`.
|
|
132
|
+
* @public
|
|
133
|
+
*/
|
|
134
|
+
export const isTriggerOrder = (raw: LtOrder): boolean => {
|
|
135
|
+
if (
|
|
136
|
+
raw.trigger_status === 'ready' ||
|
|
137
|
+
raw.trigger_status === 'mark-price' ||
|
|
138
|
+
raw.trigger_status === 'parent-order'
|
|
139
|
+
) {
|
|
140
|
+
return true
|
|
141
|
+
}
|
|
142
|
+
if (raw.trigger_price !== '' && parseFloat(raw.trigger_price) > 0) {
|
|
143
|
+
return true
|
|
144
|
+
}
|
|
145
|
+
return isTriggerType(mapOrderType(raw.type))
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Map a raw Lighter trigger order (stop/take-profit, market or limit) to
|
|
150
|
+
* the generic `TriggerOrder` shape. For market variants the `limitPrice`
|
|
151
|
+
* field is omitted; for limit variants `order.price` is the limit and
|
|
152
|
+
* `order.trigger_price` is the activation level.
|
|
153
|
+
* @public
|
|
154
|
+
*/
|
|
155
|
+
export const mapTriggerOrder = (
|
|
156
|
+
order: LtOrder,
|
|
157
|
+
market: MarketDisplay
|
|
158
|
+
): TriggerOrder => {
|
|
159
|
+
const type = mapOrderType(order.type)
|
|
160
|
+
const isLimit =
|
|
161
|
+
type === OrderType.TAKE_PROFIT_LIMIT || type === OrderType.STOP_LIMIT
|
|
162
|
+
return {
|
|
163
|
+
// `order_index` is the per-(account, market) numeric id Lighter's L2
|
|
164
|
+
// mutating txs (cancel, modify) require. The matching-engine string
|
|
165
|
+
// label `order_id` is internal to the SDK provider and never crosses
|
|
166
|
+
// this boundary — combined with `market.id` (=market_index), the
|
|
167
|
+
// numeric `order_index` uniquely pins a Lighter order.
|
|
168
|
+
orderId: String(order.order_index),
|
|
169
|
+
market,
|
|
170
|
+
type,
|
|
171
|
+
size: order.initial_base_amount,
|
|
172
|
+
triggerPrice: order.trigger_price,
|
|
173
|
+
...(isLimit ? { limitPrice: order.price } : {}),
|
|
174
|
+
createdAt: new Date(order.created_at * 1000).toISOString(),
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Map a raw Lighter order to the generic OpenOrder type.
|
|
180
|
+
* @param market - Backend-resolved market identity for `order.market_index`.
|
|
181
|
+
* @public
|
|
182
|
+
*/
|
|
183
|
+
export const mapOrder = (order: LtOrder, market: MarketDisplay): OpenOrder => ({
|
|
184
|
+
orderId: String(order.order_index),
|
|
185
|
+
market,
|
|
186
|
+
side: order.is_ask ? OrderSide.SELL : OrderSide.BUY,
|
|
187
|
+
type: mapOrderType(order.type),
|
|
188
|
+
size: order.initial_base_amount,
|
|
189
|
+
price: order.price,
|
|
190
|
+
filledSize: order.filled_base_amount,
|
|
191
|
+
reduceOnly: order.reduce_only,
|
|
192
|
+
createdAt: new Date(order.created_at * 1000).toISOString(),
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Walk a flat list of raw Lighter orders and bucket each into the
|
|
197
|
+
* `OpenOrder` / `TriggerOrder` arrays the cross-provider `OrdersResponse`
|
|
198
|
+
* declares, plus a `terminated` list of orderIds whose status has reached
|
|
199
|
+
* a terminal state (filled / cancelled / rejected / expired) — consumers
|
|
200
|
+
* applying WS deltas evict those from the cached buckets. REST callers
|
|
201
|
+
* see `terminated: []` because `accountActiveOrders` returns active only.
|
|
202
|
+
* An order whose market the resolver does not know is skipped.
|
|
203
|
+
* @public
|
|
204
|
+
*/
|
|
205
|
+
export const classifyAndMapOrders = (
|
|
206
|
+
orders: LtOrder[],
|
|
207
|
+
resolveMarket: (marketIndex: number) => MarketDisplay | undefined
|
|
208
|
+
): {
|
|
209
|
+
openOrders: OpenOrder[]
|
|
210
|
+
triggerOrders: TriggerOrder[]
|
|
211
|
+
terminated: string[]
|
|
212
|
+
} => {
|
|
213
|
+
const openOrders: OpenOrder[] = []
|
|
214
|
+
const triggerOrders: TriggerOrder[] = []
|
|
215
|
+
const terminated: string[] = []
|
|
216
|
+
for (const raw of orders) {
|
|
217
|
+
const orderId = String(raw.order_index)
|
|
218
|
+
if (!isActiveOrderStatus(mapOrderStatus(raw.status))) {
|
|
219
|
+
terminated.push(orderId)
|
|
220
|
+
continue
|
|
221
|
+
}
|
|
222
|
+
const market = resolveMarket(raw.market_index)
|
|
223
|
+
if (market === undefined) {
|
|
224
|
+
continue
|
|
225
|
+
}
|
|
226
|
+
if (isTriggerOrder(raw)) {
|
|
227
|
+
triggerOrders.push(mapTriggerOrder(raw, market))
|
|
228
|
+
} else {
|
|
229
|
+
openOrders.push(mapOrder(raw, market))
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return { openOrders, triggerOrders, terminated }
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Map a raw Lighter order to the rich Order type — adds status, time-in-force
|
|
237
|
+
* and remaining/filled sizes on top of the OpenOrder fields.
|
|
238
|
+
* @public
|
|
239
|
+
*/
|
|
240
|
+
export const mapOrderDetail = (
|
|
241
|
+
order: LtOrder,
|
|
242
|
+
market: MarketDisplay
|
|
243
|
+
): Order => ({
|
|
244
|
+
orderId: String(order.order_index),
|
|
245
|
+
market,
|
|
246
|
+
side: order.is_ask ? OrderSide.SELL : OrderSide.BUY,
|
|
247
|
+
type: mapOrderType(order.type),
|
|
248
|
+
price: order.price,
|
|
249
|
+
originalSize: order.initial_base_amount,
|
|
250
|
+
remainingSize: order.remaining_base_amount,
|
|
251
|
+
filledSize: order.filled_base_amount,
|
|
252
|
+
timeInForce: mapTimeInForce(order.time_in_force),
|
|
253
|
+
reduceOnly: order.reduce_only,
|
|
254
|
+
status: mapOrderStatus(order.status),
|
|
255
|
+
statusReason: mapStatusReason(order.status),
|
|
256
|
+
createdAt: new Date(order.created_at * 1000).toISOString(),
|
|
257
|
+
updatedAt: new Date(order.updated_at * 1000).toISOString(),
|
|
258
|
+
})
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { MarketDisplay, Position } from '@lifi/perps-types'
|
|
2
|
+
import { MarginMode, PositionSide } from '@lifi/perps-types'
|
|
3
|
+
import type { LtAccountPosition } from '../types/index.js'
|
|
4
|
+
import { LT_MARGIN_MODE_ISOLATED } from '../types/index.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Map a raw Lighter account position to the generic Position type.
|
|
8
|
+
* @param market - Backend-resolved market identity for `pos.market_id`.
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export const mapPosition = (
|
|
12
|
+
pos: LtAccountPosition,
|
|
13
|
+
market: MarketDisplay
|
|
14
|
+
): Position => {
|
|
15
|
+
const size = parseFloat(pos.position)
|
|
16
|
+
const isIsolated = pos.margin_mode === LT_MARGIN_MODE_ISOLATED
|
|
17
|
+
|
|
18
|
+
// `allocated_margin` is only populated for isolated positions (always "0"
|
|
19
|
+
// on cross accounts). For cross, derive margin as
|
|
20
|
+
// `position_value × initial_margin_fraction / 100` (IMF is in percent).
|
|
21
|
+
const positionValue = Math.abs(parseFloat(pos.position_value))
|
|
22
|
+
const imf = parseFloat(pos.initial_margin_fraction)
|
|
23
|
+
const marginUsed = isIsolated
|
|
24
|
+
? pos.allocated_margin
|
|
25
|
+
: ((positionValue * imf) / 100).toString()
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
market,
|
|
29
|
+
side: pos.sign >= 0 ? PositionSide.LONG : PositionSide.SHORT,
|
|
30
|
+
size: Math.abs(size).toString(),
|
|
31
|
+
entryPrice: pos.avg_entry_price,
|
|
32
|
+
markPrice:
|
|
33
|
+
pos.position_value === '0' || size === 0
|
|
34
|
+
? '0'
|
|
35
|
+
: (parseFloat(pos.position_value) / Math.abs(size)).toString(),
|
|
36
|
+
liquidationPrice: pos.liquidation_price,
|
|
37
|
+
unrealizedPnl: pos.unrealized_pnl,
|
|
38
|
+
leverage: imf > 0 ? Math.round(100 / imf) : 1,
|
|
39
|
+
marginUsed,
|
|
40
|
+
marginMode: isIsolated ? MarginMode.ISOLATED : MarginMode.CROSS,
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { PerpsError } from '@lifi/perps-sdk'
|
|
2
|
+
import { PerpsErrorCode } from '@lifi/perps-types'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Map our `OhlcvInterval` literal to Lighter's `resolution` enum.
|
|
6
|
+
*
|
|
7
|
+
* Lighter exposes only the timeframes listed below. SDK intervals without a
|
|
8
|
+
* direct match (3m, 2h, 8h, 3d, 1M) raise a validation error rather than
|
|
9
|
+
* silently rounding — the caller picks a supported timeframe.
|
|
10
|
+
*/
|
|
11
|
+
const LIGHTER_SUPPORTED_INTERVALS: Record<string, string> = {
|
|
12
|
+
'1m': '1m',
|
|
13
|
+
'5m': '5m',
|
|
14
|
+
'15m': '15m',
|
|
15
|
+
'30m': '30m',
|
|
16
|
+
'1h': '1h',
|
|
17
|
+
'4h': '4h',
|
|
18
|
+
'12h': '12h',
|
|
19
|
+
'1d': '1d',
|
|
20
|
+
'1w': '1w',
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** @public */
|
|
24
|
+
export const mapInterval = (interval: string): string => {
|
|
25
|
+
const resolution = LIGHTER_SUPPORTED_INTERVALS[interval]
|
|
26
|
+
if (!resolution) {
|
|
27
|
+
throw new PerpsError(
|
|
28
|
+
PerpsErrorCode.ValidationError,
|
|
29
|
+
`Lighter does not support OHLCV interval '${interval}'. ` +
|
|
30
|
+
`Supported: ${Object.keys(LIGHTER_SUPPORTED_INTERVALS).join(', ')}.`
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
return resolution
|
|
34
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lighter order size and price formatting for exchange submission.
|
|
3
|
+
*
|
|
4
|
+
* Lighter publishes a flat per-market decimal budget on its order books
|
|
5
|
+
* (`supported_price_decimals` / `supported_size_decimals`), surfaced on the
|
|
6
|
+
* generic {@link Market} as `priceDecimals` / `szDecimals`. Prices round to
|
|
7
|
+
* the tick grid; sizes truncate to the lot grid.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { PerpsError } from '@lifi/perps-sdk'
|
|
11
|
+
import { type Market, PerpsErrorCode } from '@lifi/perps-types'
|
|
12
|
+
import Big from 'big.js'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Format a price onto a Lighter market's tick grid: rounded to the market's
|
|
16
|
+
* `priceDecimals` (Lighter's `supported_price_decimals`), trailing zeros
|
|
17
|
+
* stripped.
|
|
18
|
+
*
|
|
19
|
+
* @throws {PerpsError} `ValidationError` when `market.priceDecimals` is
|
|
20
|
+
* absent — without the venue's tick grid no correct price can be produced.
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
export function formatOrderPrice(market: Market, price: number): string {
|
|
24
|
+
if (market.priceDecimals === undefined) {
|
|
25
|
+
throw new PerpsError(
|
|
26
|
+
PerpsErrorCode.ValidationError,
|
|
27
|
+
`Market '${market.id}' carries no priceDecimals; Lighter order prices ` +
|
|
28
|
+
`cannot be formatted without the market's tick grid.`
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
const rounded = new Big(price).round(market.priceDecimals, Big.roundHalfUp)
|
|
32
|
+
return rounded.eq(0) ? '0' : rounded.toFixed()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Format a size onto a Lighter market's lot grid: truncated (never rounded
|
|
37
|
+
* up, so the size cannot exceed the user's balance) to the market's
|
|
38
|
+
* `szDecimals` (Lighter's `supported_size_decimals`), trailing zeros stripped.
|
|
39
|
+
*
|
|
40
|
+
* @param size - Size in base-asset units as a non-negative magnitude.
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
export function formatOrderSize(market: Market, size: number): string {
|
|
44
|
+
const truncated = new Big(size).round(market.szDecimals, Big.roundDown)
|
|
45
|
+
return truncated.eq(0) ? '0' : truncated.toFixed()
|
|
46
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Convert seconds since unix epoch to ISO-8601. */
|
|
2
|
+
export const toIsoFromSeconds = (seconds: number): string =>
|
|
3
|
+
new Date(seconds * 1000).toISOString()
|
|
4
|
+
|
|
5
|
+
/** Convert milliseconds since unix epoch to ISO-8601. */
|
|
6
|
+
export const toIsoFromMs = (ms: number): string => new Date(ms).toISOString()
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lighter wire encoding for the WASM signer: scaled-integer decimal values,
|
|
3
|
+
* basis-point margin fractions, and order-type/TIF/expiry resolution
|
|
4
|
+
* mirroring the lighter-go signer's rules.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { PerpsError } from '@lifi/perps-sdk'
|
|
8
|
+
import { PerpsErrorCode } from '@lifi/perps-types'
|
|
9
|
+
import Big from 'big.js'
|
|
10
|
+
import {
|
|
11
|
+
LT_DEFAULT_ORDER_EXPIRY,
|
|
12
|
+
LT_ORDER_TYPE_LIMIT,
|
|
13
|
+
LT_ORDER_TYPE_MARKET,
|
|
14
|
+
LT_ORDER_TYPE_STOP_LOSS,
|
|
15
|
+
LT_ORDER_TYPE_STOP_LOSS_LIMIT,
|
|
16
|
+
LT_ORDER_TYPE_TAKE_PROFIT,
|
|
17
|
+
LT_ORDER_TYPE_TAKE_PROFIT_LIMIT,
|
|
18
|
+
LT_TIME_IN_FORCE_GTC,
|
|
19
|
+
LT_TIME_IN_FORCE_IOC,
|
|
20
|
+
LT_TIME_IN_FORCE_POST_ONLY,
|
|
21
|
+
} from '../types/action.js'
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Lighter uses basis-points (1/10000) for margin fractions.
|
|
25
|
+
* Convert to a decimal multiplier: 1000 → 0.1 (10x leverage).
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export const marginFractionToMaxLeverage = (fraction: number): number => {
|
|
29
|
+
if (!Number.isFinite(fraction) || fraction <= 0) {
|
|
30
|
+
return 1
|
|
31
|
+
}
|
|
32
|
+
return Math.floor(10_000 / fraction)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Convert leverage to margin fraction in basis points for WASM signer.
|
|
37
|
+
* @public
|
|
38
|
+
*/
|
|
39
|
+
export const leverageToFraction = (leverage: number): number => {
|
|
40
|
+
if (leverage <= 0) {
|
|
41
|
+
throw new PerpsError(
|
|
42
|
+
PerpsErrorCode.ValidationError,
|
|
43
|
+
`Invalid leverage: ${leverage}`
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
return Math.round(10_000 / leverage)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Off-grid resolution for {@link scaleToInteger}:
|
|
51
|
+
* - `truncate` — toward zero, for sizes and collateral amounts. The wire
|
|
52
|
+
* value never exceeds the caller's intent.
|
|
53
|
+
* - `round` — half away from zero, for prices, which snap to the nearest
|
|
54
|
+
* tick.
|
|
55
|
+
* @public
|
|
56
|
+
*/
|
|
57
|
+
export type ScaleToIntegerPolicy = 'truncate' | 'round'
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Scale a human-readable decimal string to a scaled integer for the WASM
|
|
61
|
+
* signer, in exact decimal arithmetic — an on-grid input maps to its exact
|
|
62
|
+
* scaled integer with no binary float artifacts (`'0.29'` at 2 decimals is
|
|
63
|
+
* 29, never 28). Off-grid input resolves per `policy`; there is no silent
|
|
64
|
+
* default.
|
|
65
|
+
*
|
|
66
|
+
* @throws {PerpsError} `ValidationError` when `value` is not a decimal
|
|
67
|
+
* numeric string, `decimals` is not a non-negative integer, or the scaled
|
|
68
|
+
* result's magnitude exceeds `Number.MAX_SAFE_INTEGER`.
|
|
69
|
+
* @public
|
|
70
|
+
*/
|
|
71
|
+
export const scaleToInteger = (
|
|
72
|
+
value: string,
|
|
73
|
+
decimals: number,
|
|
74
|
+
policy: ScaleToIntegerPolicy
|
|
75
|
+
): number => {
|
|
76
|
+
if (!Number.isInteger(decimals) || decimals < 0) {
|
|
77
|
+
throw new PerpsError(
|
|
78
|
+
PerpsErrorCode.ValidationError,
|
|
79
|
+
`Invalid decimals for Lighter integer scaling: ${decimals}`
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
let parsed: Big
|
|
83
|
+
try {
|
|
84
|
+
parsed = new Big(value)
|
|
85
|
+
} catch {
|
|
86
|
+
throw new PerpsError(
|
|
87
|
+
PerpsErrorCode.ValidationError,
|
|
88
|
+
`Invalid decimal string for Lighter integer scaling: '${value}'`
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
const scaled = parsed
|
|
92
|
+
.times(new Big(10).pow(decimals))
|
|
93
|
+
.round(0, policy === 'truncate' ? Big.roundDown : Big.roundHalfUp)
|
|
94
|
+
if (scaled.abs().gt(Number.MAX_SAFE_INTEGER)) {
|
|
95
|
+
throw new PerpsError(
|
|
96
|
+
PerpsErrorCode.ValidationError,
|
|
97
|
+
`Scaled value ${scaled.toFixed()} exceeds Number.MAX_SAFE_INTEGER and cannot be encoded exactly.`
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
return scaled.toNumber()
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Map our OrderType enum to Lighter's integer order type.
|
|
105
|
+
* @public
|
|
106
|
+
*/
|
|
107
|
+
export const mapOrderTypeToInt = (type?: string): number => {
|
|
108
|
+
const map: Record<string, number> = {
|
|
109
|
+
LIMIT: LT_ORDER_TYPE_LIMIT,
|
|
110
|
+
MARKET: LT_ORDER_TYPE_MARKET,
|
|
111
|
+
STOP_MARKET: LT_ORDER_TYPE_STOP_LOSS,
|
|
112
|
+
STOP_LIMIT: LT_ORDER_TYPE_STOP_LOSS_LIMIT,
|
|
113
|
+
TAKE_PROFIT_MARKET: LT_ORDER_TYPE_TAKE_PROFIT,
|
|
114
|
+
TAKE_PROFIT_LIMIT: LT_ORDER_TYPE_TAKE_PROFIT_LIMIT,
|
|
115
|
+
}
|
|
116
|
+
return map[type ?? 'LIMIT'] ?? LT_ORDER_TYPE_LIMIT
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Lighter pairs each `order_type` with a permitted set of `time_in_force`
|
|
121
|
+
* values: market-style orders (MARKET, STOP_MARKET, TAKE_PROFIT_MARKET) are
|
|
122
|
+
* IOC by definition; limit-style orders may carry any TIF. The Go WASM
|
|
123
|
+
* signer rejects mismatches with `OrderTimeInForce is not valid`. Resolve
|
|
124
|
+
* the caller's optional `timeInForce` against the order type so unspecified
|
|
125
|
+
* values land on the correct default and explicit values are validated up
|
|
126
|
+
* front.
|
|
127
|
+
* @public
|
|
128
|
+
*/
|
|
129
|
+
export const resolveTimeInForce = (
|
|
130
|
+
orderTypeInt: number,
|
|
131
|
+
tif?: string
|
|
132
|
+
): number => {
|
|
133
|
+
const requested = tif === undefined ? undefined : mapTimeInForceToInt(tif)
|
|
134
|
+
const isMarketStyle =
|
|
135
|
+
orderTypeInt === LT_ORDER_TYPE_MARKET ||
|
|
136
|
+
orderTypeInt === LT_ORDER_TYPE_STOP_LOSS ||
|
|
137
|
+
orderTypeInt === LT_ORDER_TYPE_TAKE_PROFIT
|
|
138
|
+
if (isMarketStyle) {
|
|
139
|
+
if (requested !== undefined && requested !== LT_TIME_IN_FORCE_IOC) {
|
|
140
|
+
throw new PerpsError(
|
|
141
|
+
PerpsErrorCode.ValidationError,
|
|
142
|
+
`Lighter market-style orders only accept IOC (got tif=${tif}).`
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
return LT_TIME_IN_FORCE_IOC
|
|
146
|
+
}
|
|
147
|
+
return requested ?? LT_TIME_IN_FORCE_GTC
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Map our TimeInForce enum to Lighter's integer time-in-force.
|
|
152
|
+
* @public
|
|
153
|
+
*/
|
|
154
|
+
export const mapTimeInForceToInt = (tif?: string): number => {
|
|
155
|
+
const map: Record<string, number> = {
|
|
156
|
+
IOC: LT_TIME_IN_FORCE_IOC,
|
|
157
|
+
GTC: LT_TIME_IN_FORCE_GTC,
|
|
158
|
+
POST_ONLY: LT_TIME_IN_FORCE_POST_ONLY,
|
|
159
|
+
}
|
|
160
|
+
return map[tif ?? 'GTC'] ?? LT_TIME_IN_FORCE_GTC
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Pick the `order_expiry` value Lighter expects for a given TIF on a
|
|
165
|
+
* regular limit order. `lighter-go/types/txtypes/create_order.go:121-128`
|
|
166
|
+
* enforces:
|
|
167
|
+
* - IOC limit orders → `OrderExpiry == NilOrderExpiry (0)`
|
|
168
|
+
* - non-IOC limit orders → `OrderExpiry != NilOrderExpiry`
|
|
169
|
+
* For non-IOC we pass the `-1` sentinel, which the WASM signer rewrites
|
|
170
|
+
* to `now + 28d` (absolute ms). Trigger orders take a different rule —
|
|
171
|
+
* see {@link LT_DEFAULT_ORDER_EXPIRY} call sites.
|
|
172
|
+
* @public
|
|
173
|
+
*/
|
|
174
|
+
export const orderExpiryForTif = (tifInt: number): number => {
|
|
175
|
+
if (tifInt === LT_TIME_IN_FORCE_IOC) {
|
|
176
|
+
return 0
|
|
177
|
+
}
|
|
178
|
+
return LT_DEFAULT_ORDER_EXPIRY
|
|
179
|
+
}
|