@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,83 @@
|
|
|
1
|
+
// Lighter submit/execute-path wire shapes (sendTx, fastwithdraw, changeAccountTier).
|
|
2
|
+
|
|
3
|
+
/** @public */
|
|
4
|
+
export interface LtSendTxRequest {
|
|
5
|
+
tx_type: number
|
|
6
|
+
tx_info: string
|
|
7
|
+
price_protection?: boolean
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** @public */
|
|
11
|
+
export interface LtSendTxResponse {
|
|
12
|
+
code: number
|
|
13
|
+
message: string
|
|
14
|
+
tx_hash: string
|
|
15
|
+
predicted_execution_time_ms?: number
|
|
16
|
+
volume_quota_remaining?: number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** @public */
|
|
20
|
+
export interface LtSendTxBatchRequest {
|
|
21
|
+
tx_types: string // JSON-encoded number[]
|
|
22
|
+
tx_infos: string // JSON-encoded string[]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** @public */
|
|
26
|
+
export interface LtSendTxBatchResponse {
|
|
27
|
+
code: number
|
|
28
|
+
message: string
|
|
29
|
+
tx_hash: string[] // one hash per submitted tx, indexed by submission order
|
|
30
|
+
predicted_execution_time_ms?: number
|
|
31
|
+
volume_quota_remaining?: number
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* `GET /api/v1/fastwithdraw/info` (Lighter `RespGetFastwithdrawalInfo`).
|
|
36
|
+
*
|
|
37
|
+
* Probe response that tells the caller whether the fast-withdraw operator is
|
|
38
|
+
* accepting transfers from `account_index` and, if so, which operator account
|
|
39
|
+
* to send the signed L2 transfer to. `withdraw_limit` and
|
|
40
|
+
* `max_withdrawal_amount` are USDC strings in **L2 6-decimal scale**, matching
|
|
41
|
+
* the `usdc_amount` units the WASM `SignTransfer` consumes. Lighter signals
|
|
42
|
+
* "fast path is not available right now" with a non-success `code` AND/OR a
|
|
43
|
+
* missing `to_account_index` (a `0` is also treated as missing because account
|
|
44
|
+
* index 0 is reserved by the protocol and never an operator).
|
|
45
|
+
*
|
|
46
|
+
* @public
|
|
47
|
+
*/
|
|
48
|
+
export interface LtFastwithdrawInfoResponse {
|
|
49
|
+
code: number
|
|
50
|
+
message?: string
|
|
51
|
+
to_account_index: number
|
|
52
|
+
withdraw_limit: string
|
|
53
|
+
max_withdrawal_amount: string
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* `POST /api/v1/fastwithdraw` (Lighter `ResultCode`).
|
|
58
|
+
*
|
|
59
|
+
* Returns only `{code, message}` — no `tx_hash`, unlike `/sendTx`. The Lighter
|
|
60
|
+
* relayer drains the operator account back to the user's L1 address
|
|
61
|
+
* out-of-band; success here means the signed L2 transfer was accepted, not
|
|
62
|
+
* that L1 settlement is complete.
|
|
63
|
+
*
|
|
64
|
+
* @public
|
|
65
|
+
*/
|
|
66
|
+
export interface LtFastwithdrawResponse {
|
|
67
|
+
code: number
|
|
68
|
+
message?: string
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* `POST /api/v1/changeAccountTier` (Lighter `RespChangeAccountTier`).
|
|
73
|
+
*
|
|
74
|
+
* Code 0 means Lighter accepted the tier change; any other code carries a
|
|
75
|
+
* Lighter-defined business-rule rejection (open positions, pending orders, 24h
|
|
76
|
+
* cooldown, etc.) and `message` is the operator-readable reason.
|
|
77
|
+
*
|
|
78
|
+
* @public
|
|
79
|
+
*/
|
|
80
|
+
export interface LtChangeAccountTierResponse {
|
|
81
|
+
code: number
|
|
82
|
+
message?: string
|
|
83
|
+
}
|
package/src/types/ws.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// The Lighter stream server sends JSON messages of shape:
|
|
2
|
+
// { type: 'subscribed/<channel>' | 'update/<channel>' | 'ping',
|
|
3
|
+
// channel: '<channel>/<id>',
|
|
4
|
+
// ...payload }
|
|
5
|
+
//
|
|
6
|
+
// Channels we subscribe to:
|
|
7
|
+
// - market_stats/all → public prices across all perp markets
|
|
8
|
+
// - spot_market_stats/all → public prices across all spot markets
|
|
9
|
+
// - order_book/{market_id} → bids/asks per market (stateful with deltas)
|
|
10
|
+
|
|
11
|
+
/** @public */
|
|
12
|
+
export type LtWsMessage = {
|
|
13
|
+
channel?: string
|
|
14
|
+
type: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** @public */
|
|
18
|
+
export type LtWsPingMessage = LtWsMessage & { type: 'ping' }
|
|
19
|
+
|
|
20
|
+
/** @public */
|
|
21
|
+
export type LtWsMarketStats = {
|
|
22
|
+
market_id: number
|
|
23
|
+
index_price: string
|
|
24
|
+
mark_price: string
|
|
25
|
+
open_interest: string
|
|
26
|
+
last_trade_price: string
|
|
27
|
+
current_funding_rate: string
|
|
28
|
+
funding_rate: string
|
|
29
|
+
funding_timestamp: number
|
|
30
|
+
daily_base_token_volume: string
|
|
31
|
+
daily_quote_token_volume: string
|
|
32
|
+
daily_price_change: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* `market_stats/all` pushes one record per known market each tick. We
|
|
37
|
+
* aggregate them into a Record<assetId, price> before emitting `prices`.
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
40
|
+
export type LtWsMarketStatsAllMessage = LtWsMessage & {
|
|
41
|
+
type: 'subscribed/market_stats' | 'update/market_stats'
|
|
42
|
+
market_stats?: Record<string, LtWsMarketStats>
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Spot market stats carry no funding/open-interest fields and address
|
|
47
|
+
* markets by their spot `market_id` (2048+).
|
|
48
|
+
* @public
|
|
49
|
+
*/
|
|
50
|
+
export type LtWsSpotMarketStats = {
|
|
51
|
+
market_id: number
|
|
52
|
+
symbol: string
|
|
53
|
+
index_price: string
|
|
54
|
+
mid_price: string
|
|
55
|
+
best_ask_price: string
|
|
56
|
+
best_bid_price: string
|
|
57
|
+
last_trade_price: string
|
|
58
|
+
daily_base_token_volume: number
|
|
59
|
+
daily_quote_token_volume: number
|
|
60
|
+
daily_price_low: number
|
|
61
|
+
daily_price_high: number
|
|
62
|
+
daily_price_change: number
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* `spot_market_stats/all` is the spot-market counterpart to
|
|
67
|
+
* `market_stats/all`; both feed the same aggregated `prices` emit.
|
|
68
|
+
* @public
|
|
69
|
+
*/
|
|
70
|
+
export type LtWsSpotMarketStatsAllMessage = LtWsMessage & {
|
|
71
|
+
type: 'subscribed/spot_market_stats' | 'update/spot_market_stats'
|
|
72
|
+
spot_market_stats?: Record<string, LtWsSpotMarketStats>
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** @public */
|
|
76
|
+
export type LtWsOrderBookLevel = {
|
|
77
|
+
price: string
|
|
78
|
+
size: string
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** @public */
|
|
82
|
+
export type LtWsOrderBook = {
|
|
83
|
+
asks: LtWsOrderBookLevel[]
|
|
84
|
+
bids: LtWsOrderBookLevel[]
|
|
85
|
+
offset?: number
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** @public */
|
|
89
|
+
export type LtWsOrderBookMessage = LtWsMessage & {
|
|
90
|
+
type: 'subscribed/order_book' | 'update/order_book'
|
|
91
|
+
order_book: LtWsOrderBook
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Auth-channel payloads.
|
|
96
|
+
*
|
|
97
|
+
* The response `channel` field uses `:` as separator (e.g.
|
|
98
|
+
* `account_all_orders:42`) while the subscribe payload uses `/`.
|
|
99
|
+
*
|
|
100
|
+
* Per the Lighter WS spec:
|
|
101
|
+
* - orders/trades: object indexed by market index, each value an array
|
|
102
|
+
* (`{ "0": [Order], "1": [Order] }`)
|
|
103
|
+
* - positions: object indexed by market index, each value a single object
|
|
104
|
+
* (`{ "0": Position }`)
|
|
105
|
+
* - initial `account_all_trades` snapshot may send an empty flat array
|
|
106
|
+
*
|
|
107
|
+
* The provider uses `collectAuthChannelItems` to normalise all three shapes
|
|
108
|
+
* into a flat T[].
|
|
109
|
+
* @public
|
|
110
|
+
*/
|
|
111
|
+
export type LtWsAccountAllOrdersMessage = LtWsMessage & {
|
|
112
|
+
type: 'subscribed/account_all_orders' | 'update/account_all_orders'
|
|
113
|
+
orders?: Record<string, unknown[]> | unknown[]
|
|
114
|
+
data?: { orders?: Record<string, unknown[]> | unknown[] }
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** @public */
|
|
118
|
+
export type LtWsAccountAllTradesMessage = LtWsMessage & {
|
|
119
|
+
type: 'subscribed/account_all_trades' | 'update/account_all_trades'
|
|
120
|
+
trades?: Record<string, unknown[]> | unknown[]
|
|
121
|
+
total_volume?: number
|
|
122
|
+
monthly_volume?: number
|
|
123
|
+
weekly_volume?: number
|
|
124
|
+
daily_volume?: number
|
|
125
|
+
data?: { trades?: Record<string, unknown[]> | unknown[] }
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** @public */
|
|
129
|
+
export type LtWsAccountAllPositionsMessage = LtWsMessage & {
|
|
130
|
+
type: 'subscribed/account_all_positions' | 'update/account_all_positions'
|
|
131
|
+
positions?: Record<string, unknown>
|
|
132
|
+
shares?: unknown[]
|
|
133
|
+
last_funding_round?: Record<string, string>
|
|
134
|
+
last_funding_discount?: Record<string, string>
|
|
135
|
+
data?: { positions?: Record<string, unknown> }
|
|
136
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { PerpsError } from '@lifi/perps-sdk'
|
|
2
|
+
import { type ActivityItem, PerpsErrorCode } from '@lifi/perps-types'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Per-endpoint cursor envelope for Lighter activity pagination.
|
|
6
|
+
*
|
|
7
|
+
* Each key holds the upstream `cursor` / `next_cursor` returned by that
|
|
8
|
+
* endpoint on the previous call. When a key is **present** with a non-empty
|
|
9
|
+
* string the corresponding endpoint will be re-fetched at that cursor on the
|
|
10
|
+
* next call; when a key is **absent** the endpoint is treated as exhausted
|
|
11
|
+
* (or never paged because the type filter excluded it) and skipped.
|
|
12
|
+
*
|
|
13
|
+
* The envelope is round-tripped through `cursor` as base64url JSON so callers
|
|
14
|
+
* don't need to know the per-endpoint shape. The encoding mirrors the LI.FI
|
|
15
|
+
* backend's wire format so cursors created by the backend remain usable.
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export interface LighterActivityCursor {
|
|
19
|
+
deposits?: string
|
|
20
|
+
withdraws?: string
|
|
21
|
+
fundings?: string
|
|
22
|
+
liquidations?: string
|
|
23
|
+
transfers?: string
|
|
24
|
+
/**
|
|
25
|
+
* Already-fetched, merged-and-sorted rows that did not fit under the page
|
|
26
|
+
* `limit`. The upstream cursors above have advanced past these rows, so they
|
|
27
|
+
* are replayed (prepended) on the next page before any fresh fetch — without
|
|
28
|
+
* them the tail would be lost forever.
|
|
29
|
+
*/
|
|
30
|
+
overflow?: ActivityItem[]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const CURSOR_KEYS = [
|
|
34
|
+
'deposits',
|
|
35
|
+
'withdraws',
|
|
36
|
+
'fundings',
|
|
37
|
+
'liquidations',
|
|
38
|
+
'transfers',
|
|
39
|
+
] as const
|
|
40
|
+
|
|
41
|
+
const isNonEmpty = (v: string | undefined): v is string =>
|
|
42
|
+
typeof v === 'string' && v.length > 0
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Encode a `LighterActivityCursor` as the base64url-of-JSON cursor string
|
|
46
|
+
* Lighter widgets persist between activity pages. Returns `undefined` when
|
|
47
|
+
* every per-endpoint key is empty and no `overflow` rows remain — the caller
|
|
48
|
+
* should report `hasMore: false` and omit `cursor` from `Pagination` then.
|
|
49
|
+
*
|
|
50
|
+
* Browser-direct: `Buffer` is Node-only. We use `btoa` over a Latin-1
|
|
51
|
+
* encoding of the UTF-8 bytes and then rewrite `+/=` to base64url. This is
|
|
52
|
+
* the same byte sequence Node's `Buffer.from(json, 'utf8').toString('base64url')`
|
|
53
|
+
* produces, so cursors round-trip across environments.
|
|
54
|
+
* @public
|
|
55
|
+
*/
|
|
56
|
+
export const encodeActivityCursor = (
|
|
57
|
+
env: LighterActivityCursor
|
|
58
|
+
): string | undefined => {
|
|
59
|
+
const compact: LighterActivityCursor = {}
|
|
60
|
+
for (const key of CURSOR_KEYS) {
|
|
61
|
+
if (isNonEmpty(env[key])) {
|
|
62
|
+
compact[key] = env[key]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (env.overflow !== undefined && env.overflow.length > 0) {
|
|
66
|
+
compact.overflow = env.overflow
|
|
67
|
+
}
|
|
68
|
+
if (Object.keys(compact).length === 0) {
|
|
69
|
+
return undefined
|
|
70
|
+
}
|
|
71
|
+
return toBase64Url(JSON.stringify(compact))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Decode a previously-encoded activity cursor. Returns `undefined` for an
|
|
76
|
+
* absent cursor (first page) and throws {@link PerpsError} with
|
|
77
|
+
* `ValidationError` if the string is malformed — we'd rather fail loudly than
|
|
78
|
+
* silently re-page from page 1 and re-deliver already-paginated rows.
|
|
79
|
+
* @public
|
|
80
|
+
*/
|
|
81
|
+
export const decodeActivityCursor = (
|
|
82
|
+
cursor: string | undefined
|
|
83
|
+
): LighterActivityCursor | undefined => {
|
|
84
|
+
if (cursor === undefined) {
|
|
85
|
+
return undefined
|
|
86
|
+
}
|
|
87
|
+
let parsed: unknown
|
|
88
|
+
try {
|
|
89
|
+
parsed = JSON.parse(fromBase64Url(cursor))
|
|
90
|
+
} catch {
|
|
91
|
+
throw new PerpsError(
|
|
92
|
+
PerpsErrorCode.ValidationError,
|
|
93
|
+
'Invalid Lighter activity cursor: not base64url-encoded JSON'
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
if (parsed === null || typeof parsed !== 'object') {
|
|
97
|
+
throw new PerpsError(
|
|
98
|
+
PerpsErrorCode.ValidationError,
|
|
99
|
+
'Invalid Lighter activity cursor: expected JSON object'
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
const cursorRecord = parsed as Record<string, unknown>
|
|
103
|
+
const env: LighterActivityCursor = {}
|
|
104
|
+
for (const key of CURSOR_KEYS) {
|
|
105
|
+
const v = cursorRecord[key]
|
|
106
|
+
if (v === undefined) {
|
|
107
|
+
continue
|
|
108
|
+
}
|
|
109
|
+
if (typeof v !== 'string') {
|
|
110
|
+
throw new PerpsError(
|
|
111
|
+
PerpsErrorCode.ValidationError,
|
|
112
|
+
`Invalid Lighter activity cursor: ${key} must be a string`
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
env[key] = v
|
|
116
|
+
}
|
|
117
|
+
const overflow = cursorRecord.overflow
|
|
118
|
+
if (overflow !== undefined) {
|
|
119
|
+
if (!Array.isArray(overflow)) {
|
|
120
|
+
throw new PerpsError(
|
|
121
|
+
PerpsErrorCode.ValidationError,
|
|
122
|
+
'Invalid Lighter activity cursor: overflow must be an array'
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
env.overflow = overflow as ActivityItem[]
|
|
126
|
+
}
|
|
127
|
+
return env
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const toBase64Url = (s: string): string => {
|
|
131
|
+
if (typeof Buffer !== 'undefined') {
|
|
132
|
+
return Buffer.from(s, 'utf8').toString('base64url')
|
|
133
|
+
}
|
|
134
|
+
const utf8 = unescape(encodeURIComponent(s))
|
|
135
|
+
return btoa(utf8).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const fromBase64Url = (s: string): string => {
|
|
139
|
+
if (typeof Buffer !== 'undefined') {
|
|
140
|
+
return Buffer.from(s, 'base64url').toString('utf8')
|
|
141
|
+
}
|
|
142
|
+
const padded = s.replace(/-/g, '+').replace(/_/g, '/') + padFor(s)
|
|
143
|
+
const decoded = atob(padded)
|
|
144
|
+
return decodeURIComponent(escape(decoded))
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const padFor = (s: string): string => {
|
|
148
|
+
const rem = s.length % 4
|
|
149
|
+
return rem === 0 ? '' : '='.repeat(4 - rem)
|
|
150
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import {
|
|
2
|
+
fetchWithRetry,
|
|
3
|
+
PerpsError,
|
|
4
|
+
type ResolvedRetryPolicy,
|
|
5
|
+
} from '@lifi/perps-sdk'
|
|
6
|
+
import { PerpsErrorCode } from '@lifi/perps-types'
|
|
7
|
+
import {
|
|
8
|
+
LIGHTER_INVALID_AUTH_CODE,
|
|
9
|
+
LIGHTER_SUCCESS_CODES,
|
|
10
|
+
} from '../constants.js'
|
|
11
|
+
|
|
12
|
+
/** @internal */
|
|
13
|
+
export type ApiParams = Record<string, string | number | boolean>
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Lighter signals errors on two channels: a non-2xx HTTP status, or an HTTP 200
|
|
17
|
+
* carrying an error `code` in the JSON body. Returns the body error `code` when
|
|
18
|
+
* the body advertises one that is not a success code, else `undefined`.
|
|
19
|
+
*/
|
|
20
|
+
const lighterBodyErrorCode = (data: unknown): number | undefined => {
|
|
21
|
+
const code = (data as { code?: number } | undefined)?.code
|
|
22
|
+
if (code === undefined || LIGHTER_SUCCESS_CODES.has(code)) {
|
|
23
|
+
return undefined
|
|
24
|
+
}
|
|
25
|
+
return code
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Auth-gated read whose token Lighter rejected. Distinct from a generic
|
|
30
|
+
* {@link PerpsError} so callers can evict the stored read-only token and retry
|
|
31
|
+
* with a freshly-created one. Lighter signals this on either channel: an HTTP
|
|
32
|
+
* 401/403, or an HTTP 200 carrying an error `code` in the body.
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export class LighterAuthRejectedError extends PerpsError {}
|
|
36
|
+
|
|
37
|
+
const isLighterAuthRejection = (status: number, data: unknown): boolean =>
|
|
38
|
+
status === 401 ||
|
|
39
|
+
status === 403 ||
|
|
40
|
+
lighterBodyErrorCode(data) === LIGHTER_INVALID_AUTH_CODE
|
|
41
|
+
|
|
42
|
+
/** @internal */
|
|
43
|
+
export const LIGHTER_RETRY_DEFAULTS: ResolvedRetryPolicy = {
|
|
44
|
+
enabled: true,
|
|
45
|
+
maxAttempts: 2,
|
|
46
|
+
baseDelayMs: 10_000,
|
|
47
|
+
maxDelayMs: 60_000,
|
|
48
|
+
respectRetryAfter: true,
|
|
49
|
+
classify: ({ response }) => {
|
|
50
|
+
if (response.status === 429 || response.status === 405) {
|
|
51
|
+
return 'retry-rate-limit'
|
|
52
|
+
}
|
|
53
|
+
if (
|
|
54
|
+
response.status === 502 ||
|
|
55
|
+
response.status === 503 ||
|
|
56
|
+
response.status === 504
|
|
57
|
+
) {
|
|
58
|
+
return 'retry-server'
|
|
59
|
+
}
|
|
60
|
+
return 'fail'
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** @internal */
|
|
65
|
+
export interface LighterApiClientOptions {
|
|
66
|
+
signal?: AbortSignal
|
|
67
|
+
policy?: ResolvedRetryPolicy
|
|
68
|
+
fetchImpl?: typeof fetch
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* HTTP boundary against Lighter's REST API.
|
|
73
|
+
*
|
|
74
|
+
* Browser-direct by design: no LI.FI backend hop, no caching shim — caller
|
|
75
|
+
* supplies the REST base URL, the path, and any query params, and we return
|
|
76
|
+
* the parsed JSON body. Lighter advertises CORS headers on every public
|
|
77
|
+
* endpoint so a vanilla `fetch` from the widget works.
|
|
78
|
+
*
|
|
79
|
+
* Auth-gated endpoints (accountLimits, accountActiveOrders, deposit/history,
|
|
80
|
+
* withdraw/history, positionFunding, liquidations, transfer/history) take the
|
|
81
|
+
* Lighter read-only token as the `auth` query parameter — NOT as an
|
|
82
|
+
* `Authorization` header. This matches Lighter's OpenAPI spec and lets the
|
|
83
|
+
* same call work browser-direct and from server-side proxies.
|
|
84
|
+
*
|
|
85
|
+
* Lighter signals rate limiting via 429 OR 405 (documented behaviour) with a
|
|
86
|
+
* documented 60s firewall cooldown. The default {@link ResolvedRetryPolicy}
|
|
87
|
+
* waits long enough to avoid hammering through the cooldown.
|
|
88
|
+
* @public
|
|
89
|
+
*/
|
|
90
|
+
export class LighterApiClient {
|
|
91
|
+
private readonly baseUrl: string
|
|
92
|
+
private readonly signal: AbortSignal | undefined
|
|
93
|
+
private readonly policy: ResolvedRetryPolicy
|
|
94
|
+
private readonly fetchImpl: typeof fetch | undefined
|
|
95
|
+
|
|
96
|
+
constructor(baseUrl: string, options?: LighterApiClientOptions) {
|
|
97
|
+
this.baseUrl = baseUrl.replace(/\/$/, '')
|
|
98
|
+
this.signal = options?.signal
|
|
99
|
+
this.policy = options?.policy ?? LIGHTER_RETRY_DEFAULTS
|
|
100
|
+
this.fetchImpl = options?.fetchImpl
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private buildUrl(path: string, params?: ApiParams): string {
|
|
104
|
+
const url = `${this.baseUrl}${path}`
|
|
105
|
+
if (!params || Object.keys(params).length === 0) {
|
|
106
|
+
return url
|
|
107
|
+
}
|
|
108
|
+
const qs = Object.entries(params)
|
|
109
|
+
.map(
|
|
110
|
+
([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`
|
|
111
|
+
)
|
|
112
|
+
.join('&')
|
|
113
|
+
return `${url}?${qs}`
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async get<T>(path: string, params?: ApiParams): Promise<T> {
|
|
117
|
+
return this.getChecked<T>(path, params)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Auth-gated GET. The token is appended as the `auth` query parameter (per
|
|
122
|
+
* Lighter's OpenAPI spec); the `Authorization` header is intentionally NOT
|
|
123
|
+
* used — Lighter rejects it.
|
|
124
|
+
*/
|
|
125
|
+
async getAuthed<T>(
|
|
126
|
+
path: string,
|
|
127
|
+
authToken: string,
|
|
128
|
+
params: ApiParams = {}
|
|
129
|
+
): Promise<T> {
|
|
130
|
+
const { status, data } = await this.getWithStatus<unknown>(path, {
|
|
131
|
+
...params,
|
|
132
|
+
auth: authToken,
|
|
133
|
+
})
|
|
134
|
+
if (isLighterAuthRejection(status, data)) {
|
|
135
|
+
throw new LighterAuthRejectedError(
|
|
136
|
+
PerpsErrorCode.ThirdPartyError,
|
|
137
|
+
`Lighter rejected the auth token for ${path}`
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
if (status < 200 || status >= 300) {
|
|
141
|
+
throw new PerpsError(
|
|
142
|
+
PerpsErrorCode.ThirdPartyError,
|
|
143
|
+
`Lighter API request failed: ${status} — ${JSON.stringify(data).slice(0, 200)}`
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
return data as T
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* GET that surfaces the raw `{status, body}` pair without throwing on
|
|
151
|
+
* non-2xx — used for endpoints (account lookup by L1 address) where the
|
|
152
|
+
* caller distinguishes specific Lighter error codes from generic failures.
|
|
153
|
+
*/
|
|
154
|
+
async getWithStatus<T>(
|
|
155
|
+
path: string,
|
|
156
|
+
params?: ApiParams
|
|
157
|
+
): Promise<{ status: number; data: T }> {
|
|
158
|
+
const url = this.buildUrl(path, params)
|
|
159
|
+
const response = await fetchWithRetry(
|
|
160
|
+
url,
|
|
161
|
+
{},
|
|
162
|
+
{ policy: this.policy, fetchImpl: this.fetchImpl, signal: this.signal }
|
|
163
|
+
)
|
|
164
|
+
const data = (await response.json().catch(() => undefined)) as T
|
|
165
|
+
return { status: response.status, data }
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
private async getChecked<T>(path: string, params?: ApiParams): Promise<T> {
|
|
169
|
+
const { status, data } = await this.getWithStatus<unknown>(path, params)
|
|
170
|
+
if (status < 200 || status >= 300) {
|
|
171
|
+
throw new PerpsError(
|
|
172
|
+
PerpsErrorCode.ThirdPartyError,
|
|
173
|
+
`Lighter API request failed: ${status} — ${JSON.stringify(data).slice(0, 200)}`
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
const errorCode = lighterBodyErrorCode(data)
|
|
177
|
+
if (errorCode !== undefined) {
|
|
178
|
+
throw new PerpsError(
|
|
179
|
+
PerpsErrorCode.ThirdPartyError,
|
|
180
|
+
`Lighter API error for ${path}: code ${errorCode} — ${JSON.stringify(data).slice(0, 200)}`
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
return data as T
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { PerpsError } from '@lifi/perps-sdk'
|
|
2
|
+
import { PerpsErrorCode } from '@lifi/perps-types'
|
|
3
|
+
import type { Address } from 'viem'
|
|
4
|
+
import { LIGHTER_CODE_ACCOUNT_NOT_FOUND } from '../constants.js'
|
|
5
|
+
import type { LtDetailedAccount } from '../types/index.js'
|
|
6
|
+
import type { LighterApiClient } from './apiClient.js'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Look up the Lighter account for an L1 address via `/api/v1/account`,
|
|
10
|
+
* discriminating Lighter's account-not-found body code from generic failures.
|
|
11
|
+
*
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
export const fetchDetailedAccount = async (
|
|
15
|
+
client: LighterApiClient,
|
|
16
|
+
address: Address
|
|
17
|
+
): Promise<LtDetailedAccount> => {
|
|
18
|
+
const { status, data } = await client.getWithStatus<{
|
|
19
|
+
code: number
|
|
20
|
+
accounts?: LtDetailedAccount[]
|
|
21
|
+
message?: string
|
|
22
|
+
}>('/api/v1/account', { by: 'l1_address', value: address })
|
|
23
|
+
|
|
24
|
+
if (status === 400 && data?.code === LIGHTER_CODE_ACCOUNT_NOT_FOUND) {
|
|
25
|
+
throw new PerpsError(
|
|
26
|
+
PerpsErrorCode.AccountNotFound,
|
|
27
|
+
`No Lighter account found for address: ${address}`
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (status < 200 || status >= 300) {
|
|
32
|
+
throw new PerpsError(
|
|
33
|
+
PerpsErrorCode.ThirdPartyError,
|
|
34
|
+
`Lighter account request failed: ${status} — ${JSON.stringify(data).slice(0, 200)}`
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const accounts = data?.accounts
|
|
39
|
+
if (accounts === undefined || accounts.length === 0) {
|
|
40
|
+
throw new PerpsError(
|
|
41
|
+
PerpsErrorCode.AccountNotFound,
|
|
42
|
+
`No Lighter account found for address: ${address}`
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
return accounts[0]
|
|
46
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// biome-ignore-all lint/performance/noBarrelFile: single re-export entry point
|
|
2
|
+
// for the package's utility surface. Internal modules import per-file paths
|
|
3
|
+
// (e.g. `./apiClient.js`, `./mapFill.js`) directly.
|
|
4
|
+
|
|
5
|
+
export type { LighterActivityCursor } from './activityCursor.js'
|
|
6
|
+
export {
|
|
7
|
+
decodeActivityCursor,
|
|
8
|
+
encodeActivityCursor,
|
|
9
|
+
} from './activityCursor.js'
|
|
10
|
+
export { LighterApiClient } from './apiClient.js'
|
|
11
|
+
export { fetchDetailedAccount } from './fetchDetailedAccount.js'
|
|
12
|
+
export { lighterAsset } from './lighterAsset.js'
|
|
13
|
+
export { estimateLiquidationPrice } from './liquidation.js'
|
|
14
|
+
export { mapFill } from './mapFill.js'
|
|
15
|
+
export { mapOpenPositions } from './mapOpenPositions.js'
|
|
16
|
+
export {
|
|
17
|
+
classifyAndMapOrders,
|
|
18
|
+
isTriggerOrder,
|
|
19
|
+
isTriggerType,
|
|
20
|
+
mapOrder,
|
|
21
|
+
mapOrderDetail,
|
|
22
|
+
mapStatusReason,
|
|
23
|
+
mapTriggerOrder,
|
|
24
|
+
} from './mapOrder.js'
|
|
25
|
+
export { mapPosition } from './mapPosition.js'
|
|
26
|
+
export { mapInterval } from './ohlcvInterval.js'
|
|
27
|
+
export { formatOrderPrice, formatOrderSize } from './orderFormatting.js'
|
|
28
|
+
export { toIsoFromMs, toIsoFromSeconds } from './time.js'
|
|
29
|
+
export type { ScaleToIntegerPolicy } from './wireEncoding.js'
|
|
30
|
+
export {
|
|
31
|
+
leverageToFraction,
|
|
32
|
+
mapOrderTypeToInt,
|
|
33
|
+
mapTimeInForceToInt,
|
|
34
|
+
marginFractionToMaxLeverage,
|
|
35
|
+
orderExpiryForTif,
|
|
36
|
+
resolveTimeInForce,
|
|
37
|
+
scaleToInteger,
|
|
38
|
+
} from './wireEncoding.js'
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Asset } from '@lifi/perps-types'
|
|
2
|
+
import { LIGHTER_PROVIDER_KEY } from '../constants.js'
|
|
3
|
+
|
|
4
|
+
/** @public */
|
|
5
|
+
export const lighterAsset = (id: string, displaySymbol: string): Asset => ({
|
|
6
|
+
providerId: LIGHTER_PROVIDER_KEY,
|
|
7
|
+
id,
|
|
8
|
+
displaySymbol,
|
|
9
|
+
logoURI: '',
|
|
10
|
+
})
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lighter liquidation price estimation.
|
|
3
|
+
*
|
|
4
|
+
* Lighter publishes a flat per-market `maintenance_margin_fraction` on its
|
|
5
|
+
* order books, surfaced on the generic {@link PerpsMarket} as
|
|
6
|
+
* `maintenanceMarginRate`. The estimate is the standard isolated-margin
|
|
7
|
+
* model parameterised by that rate.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
estimateIsolatedLiquidationPrice,
|
|
12
|
+
type LiquidationEstimateParams,
|
|
13
|
+
} from '@lifi/perps-sdk'
|
|
14
|
+
import type { PerpsMarket } from '@lifi/perps-types'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Estimate the liquidation price of a new isolated position on a Lighter
|
|
18
|
+
* market.
|
|
19
|
+
*
|
|
20
|
+
* @returns The estimated liquidation price, or `undefined` when
|
|
21
|
+
* `market.maintenanceMarginRate` is absent (the model cannot be evaluated
|
|
22
|
+
* without the venue's maintenance margin rate) or the inputs are
|
|
23
|
+
* degenerate.
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
export function estimateLiquidationPrice(
|
|
27
|
+
market: PerpsMarket,
|
|
28
|
+
params: LiquidationEstimateParams
|
|
29
|
+
): number | undefined {
|
|
30
|
+
if (market.maintenanceMarginRate === undefined) {
|
|
31
|
+
return undefined
|
|
32
|
+
}
|
|
33
|
+
return estimateIsolatedLiquidationPrice({
|
|
34
|
+
entryPrice: params.entryPrice,
|
|
35
|
+
leverage: params.leverage,
|
|
36
|
+
isLong: params.isLong,
|
|
37
|
+
maintenanceMarginRate: market.maintenanceMarginRate,
|
|
38
|
+
})
|
|
39
|
+
}
|