@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,311 @@
|
|
|
1
|
+
import { PerpsError, type SignActionsContext } from '@lifi/perps-sdk'
|
|
2
|
+
import type {
|
|
3
|
+
ActionStep,
|
|
4
|
+
EvmTxActionStep,
|
|
5
|
+
EvmTxSignedActionStep,
|
|
6
|
+
SignedActionStep,
|
|
7
|
+
WasmBlobActionStep,
|
|
8
|
+
WasmBlobSignedActionStep,
|
|
9
|
+
} from '@lifi/perps-types'
|
|
10
|
+
import { ActionType, PerpsErrorCode, SigningMethod } from '@lifi/perps-types'
|
|
11
|
+
import type { Address } from 'viem'
|
|
12
|
+
import { parseAbi } from 'viem'
|
|
13
|
+
import { DEFAULT_API_KEY_INDEX } from '../constants.js'
|
|
14
|
+
import type { LighterApiKey, LighterKeyStore } from './LighterKeyStore.js'
|
|
15
|
+
import type { LighterSigner } from './LighterSigner.js'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Per-batch dependencies the Lighter `signActions` implementation needs:
|
|
19
|
+
* a WASM signer (`LighterSigner`), the API-key store keyed on L1 address,
|
|
20
|
+
* and a reference to the host SDK client for descriptor/account fetches
|
|
21
|
+
* within the REGISTER_API_KEY hybrid flow.
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
export interface LighterSignActionsDeps {
|
|
25
|
+
signer: LighterSigner
|
|
26
|
+
keyStore: LighterKeyStore
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the user's Lighter `accountIndex` for an L1 address. Required
|
|
29
|
+
* by REGISTER_API_KEY so the ChangePubKey blob carries the right
|
|
30
|
+
* account. Implementations typically call Lighter's `/api/v1/account`
|
|
31
|
+
* with `by=l1_address`.
|
|
32
|
+
*/
|
|
33
|
+
resolveAccountIndex(address: Address): Promise<number>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Sign a `WASM_BLOB` batch (Lighter). Ensures the user's API keypair is
|
|
38
|
+
* registered first — generating one and running the REGISTER_API_KEY
|
|
39
|
+
* hybrid flow via the L1 signer if not — then feeds each subsequent step
|
|
40
|
+
* through the WASM signer.
|
|
41
|
+
*
|
|
42
|
+
* `ACCOUNT_TYPE` (Lighter `/changeAccountTier`) is a WASM_BLOB envelope
|
|
43
|
+
* authenticated with an auth token rather than a wasm tx signature —
|
|
44
|
+
* created via `LighterSigner.createAuthToken` and parked in `signedTx.txInfo`.
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
export async function signWasmBlobActions(
|
|
48
|
+
deps: LighterSignActionsDeps,
|
|
49
|
+
address: Address,
|
|
50
|
+
steps: WasmBlobActionStep[],
|
|
51
|
+
ctx: SignActionsContext | undefined
|
|
52
|
+
): Promise<WasmBlobSignedActionStep[]> {
|
|
53
|
+
const signed: WasmBlobSignedActionStep[] = []
|
|
54
|
+
for (const step of steps) {
|
|
55
|
+
if (step.action === ActionType.REGISTER_API_KEY) {
|
|
56
|
+
signed.push(await signRegisterApiKey(deps, address, step, ctx))
|
|
57
|
+
} else if (step.action === ActionType.ACCOUNT_TYPE) {
|
|
58
|
+
signed.push(await signAccountTierChange(deps, address, step))
|
|
59
|
+
} else {
|
|
60
|
+
signed.push(await signStandardWasmAction(deps, address, step))
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return signed
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async function signStandardWasmAction(
|
|
67
|
+
deps: LighterSignActionsDeps,
|
|
68
|
+
address: Address,
|
|
69
|
+
step: WasmBlobActionStep
|
|
70
|
+
): Promise<WasmBlobSignedActionStep> {
|
|
71
|
+
const apiKey = await requireApiKey(deps, address)
|
|
72
|
+
const signedTx = await deps.signer.sign(step.action, step.wasmSignParams, {
|
|
73
|
+
apiKeyPrivateKey: apiKey.apiKeyPrivateKey,
|
|
74
|
+
apiKeyIndex: apiKey.apiKeyIndex,
|
|
75
|
+
accountIndex: apiKey.accountIndex,
|
|
76
|
+
})
|
|
77
|
+
return {
|
|
78
|
+
action: step.action,
|
|
79
|
+
wasmSignParams: step.wasmSignParams,
|
|
80
|
+
signedTx,
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* REGISTER_API_KEY flow:
|
|
86
|
+
* 1. Look up the user's Lighter accountIndex (Lighter REST).
|
|
87
|
+
* 2. Generate a fresh Lighter API keypair via the WASM signer.
|
|
88
|
+
* 3. Call SignChangePubKey to produce the WASM blob + EIP-191 message.
|
|
89
|
+
* 4. Have the user's L1 Ethereum wallet sign the message.
|
|
90
|
+
* 5. Inject the L1 signature into the ChangePubKey txInfo JSON.
|
|
91
|
+
* 6. Persist the keypair and return the signed blob.
|
|
92
|
+
*
|
|
93
|
+
* Requires the end-user's wallet in `ctx.userWallet` — the L1 signature is the
|
|
94
|
+
* user's consent to rotate keys.
|
|
95
|
+
*/
|
|
96
|
+
async function signRegisterApiKey(
|
|
97
|
+
deps: LighterSignActionsDeps,
|
|
98
|
+
address: Address,
|
|
99
|
+
step: WasmBlobActionStep,
|
|
100
|
+
ctx: SignActionsContext | undefined
|
|
101
|
+
): Promise<WasmBlobSignedActionStep> {
|
|
102
|
+
const walletSigner = ctx?.userWallet
|
|
103
|
+
if (!walletSigner) {
|
|
104
|
+
throw new PerpsError(
|
|
105
|
+
PerpsErrorCode.SDKError,
|
|
106
|
+
'REGISTER_API_KEY requires the end-user wallet — pass `userWallet` to ' +
|
|
107
|
+
'createPerpsClient or call setUserWallet(walletClient).'
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const params = step.wasmSignParams as {
|
|
112
|
+
api_key_index?: number
|
|
113
|
+
nonce?: number
|
|
114
|
+
skip_nonce?: 0 | 1
|
|
115
|
+
}
|
|
116
|
+
const apiKeyIndex = params.api_key_index ?? DEFAULT_API_KEY_INDEX
|
|
117
|
+
const nonce = params.nonce
|
|
118
|
+
if (typeof nonce !== 'number') {
|
|
119
|
+
throw new PerpsError(
|
|
120
|
+
PerpsErrorCode.SDKError,
|
|
121
|
+
'REGISTER_API_KEY wasmSignParams is missing `nonce`.'
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
const skipNonce = params.skip_nonce === 1 ? 1 : 0
|
|
125
|
+
|
|
126
|
+
const accountIndex = await deps.resolveAccountIndex(address)
|
|
127
|
+
|
|
128
|
+
const keypair = await deps.signer.generateAPIKey()
|
|
129
|
+
const changePubKey = await deps.signer.signChangePubKey(
|
|
130
|
+
keypair.publicKey,
|
|
131
|
+
keypair.privateKey,
|
|
132
|
+
nonce,
|
|
133
|
+
apiKeyIndex,
|
|
134
|
+
accountIndex,
|
|
135
|
+
skipNonce
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
const l1Signature = await walletSigner.signMessage({
|
|
139
|
+
account: walletSigner.account,
|
|
140
|
+
message: changePubKey.messageToSign,
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
const txInfoWithL1Sig = deps.signer.embedL1Signature(
|
|
144
|
+
changePubKey.txInfo,
|
|
145
|
+
l1Signature
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
const apiKey: LighterApiKey = {
|
|
149
|
+
accountIndex,
|
|
150
|
+
apiKeyIndex,
|
|
151
|
+
apiKeyPrivateKey: keypair.privateKey,
|
|
152
|
+
apiKeyPublicKey: keypair.publicKey,
|
|
153
|
+
}
|
|
154
|
+
await deps.keyStore.set(address, apiKey)
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
action: step.action,
|
|
158
|
+
wasmSignParams: {
|
|
159
|
+
...step.wasmSignParams,
|
|
160
|
+
new_public_key: keypair.publicKey,
|
|
161
|
+
},
|
|
162
|
+
signedTx: {
|
|
163
|
+
txType: changePubKey.txType,
|
|
164
|
+
txInfo: txInfoWithL1Sig,
|
|
165
|
+
txHash: changePubKey.txHash,
|
|
166
|
+
},
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Sign an `ACCOUNT_TYPE` step (Lighter `changeAccountTier`).
|
|
172
|
+
*
|
|
173
|
+
* Lighter's `/api/v1/changeAccountTier` is an HTTP-only mutation —
|
|
174
|
+
* Lighter does NOT consume a wasm-signed transaction here; it
|
|
175
|
+
* authenticates the request with the same auth token its read endpoints
|
|
176
|
+
* use, and enforces anti-replay business rules server-side. The backend
|
|
177
|
+
* declares the step as a `WasmBlobActionStep` with
|
|
178
|
+
* `wasmSignParams.kind = 'changeAccountTier'` and expects the SDK to create
|
|
179
|
+
* an auth token in lieu of a transaction signature; the executor reads
|
|
180
|
+
* `signedTx.txInfo` as the `auth` form parameter.
|
|
181
|
+
*
|
|
182
|
+
* The 1h deadline mirrors the previous behaviour — Lighter caps tokens at
|
|
183
|
+
* 8h hard, and the backend's executor runs `verifyPendingAction` then a
|
|
184
|
+
* single POST, which completes well inside an hour.
|
|
185
|
+
*/
|
|
186
|
+
async function signAccountTierChange(
|
|
187
|
+
deps: LighterSignActionsDeps,
|
|
188
|
+
address: Address,
|
|
189
|
+
step: WasmBlobActionStep
|
|
190
|
+
): Promise<WasmBlobSignedActionStep> {
|
|
191
|
+
const apiKey = await requireApiKey(deps, address)
|
|
192
|
+
const deadline = Math.floor(Date.now() / 1000) + 60 * 60
|
|
193
|
+
const authToken = await deps.signer.createAuthToken(deadline, {
|
|
194
|
+
apiKeyPrivateKey: apiKey.apiKeyPrivateKey,
|
|
195
|
+
apiKeyIndex: apiKey.apiKeyIndex,
|
|
196
|
+
accountIndex: apiKey.accountIndex,
|
|
197
|
+
})
|
|
198
|
+
return {
|
|
199
|
+
action: step.action,
|
|
200
|
+
wasmSignParams: step.wasmSignParams,
|
|
201
|
+
signedTx: {
|
|
202
|
+
// `/changeAccountTier` reads only `txInfo` (the auth token); `txType`
|
|
203
|
+
// and `txHash` are placeholders to satisfy the envelope shape.
|
|
204
|
+
txType: 0,
|
|
205
|
+
txInfo: authToken,
|
|
206
|
+
txHash: '',
|
|
207
|
+
},
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async function requireApiKey(
|
|
212
|
+
deps: LighterSignActionsDeps,
|
|
213
|
+
address: Address
|
|
214
|
+
): Promise<LighterApiKey> {
|
|
215
|
+
const apiKey = await deps.keyStore.get(address)
|
|
216
|
+
if (!apiKey) {
|
|
217
|
+
throw new PerpsError(
|
|
218
|
+
PerpsErrorCode.SDKError,
|
|
219
|
+
`No Lighter API key registered for ${address}. ` +
|
|
220
|
+
'Run prepareAccount / REGISTER_API_KEY first.'
|
|
221
|
+
)
|
|
222
|
+
}
|
|
223
|
+
return apiKey
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Sign and broadcast a sequence of `EVM_TX` actions via the user's wallet
|
|
228
|
+
* client. Steps are submitted serially so a later step (e.g. deposit) can
|
|
229
|
+
* rely on an earlier step (e.g. approve) having mined. Each step's
|
|
230
|
+
* `txParams` carries chainId, target, function name, args, and a
|
|
231
|
+
* human-readable abi from the backend.
|
|
232
|
+
* @internal
|
|
233
|
+
*/
|
|
234
|
+
export async function signEvmTxActions(
|
|
235
|
+
steps: EvmTxActionStep[],
|
|
236
|
+
ctx: SignActionsContext | undefined
|
|
237
|
+
): Promise<EvmTxSignedActionStep[]> {
|
|
238
|
+
const walletSigner = ctx?.userWallet
|
|
239
|
+
if (!walletSigner) {
|
|
240
|
+
throw new PerpsError(
|
|
241
|
+
PerpsErrorCode.SDKError,
|
|
242
|
+
'EVM_TX signing requires the end-user wallet. Pass `userWallet` to ' +
|
|
243
|
+
'createPerpsClient or call setUserWallet(walletClient).'
|
|
244
|
+
)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const signed: EvmTxSignedActionStep[] = []
|
|
248
|
+
for (const step of steps) {
|
|
249
|
+
const params = step.txParams as {
|
|
250
|
+
chainId: number
|
|
251
|
+
to: Address
|
|
252
|
+
functionName: string
|
|
253
|
+
args: readonly unknown[]
|
|
254
|
+
abi: readonly string[]
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const txHash = await walletSigner.writeContract({
|
|
258
|
+
address: params.to,
|
|
259
|
+
abi: parseAbi(params.abi),
|
|
260
|
+
functionName: params.functionName,
|
|
261
|
+
args: params.args,
|
|
262
|
+
chain: walletSigner.chain,
|
|
263
|
+
account: walletSigner.account,
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
signed.push({
|
|
267
|
+
action: step.action,
|
|
268
|
+
txParams: step.txParams,
|
|
269
|
+
txHash,
|
|
270
|
+
})
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return signed
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Top-level dispatch: pick the per-method signer based on the descriptor's
|
|
278
|
+
* `signingMethod` and forward. `EIP712` is rejected — Lighter declares no
|
|
279
|
+
* EIP712 actions (its user-consent step uses an EIP-191 `signMessage` inside
|
|
280
|
+
* the `WASM_BLOB` REGISTER_API_KEY flow).
|
|
281
|
+
* @internal
|
|
282
|
+
*/
|
|
283
|
+
export async function lighterSignActions(
|
|
284
|
+
deps: LighterSignActionsDeps,
|
|
285
|
+
method: SigningMethod,
|
|
286
|
+
steps: ActionStep[],
|
|
287
|
+
address: Address,
|
|
288
|
+
ctx?: SignActionsContext
|
|
289
|
+
): Promise<SignedActionStep[]> {
|
|
290
|
+
switch (method) {
|
|
291
|
+
case SigningMethod.WASM_BLOB:
|
|
292
|
+
return signWasmBlobActions(
|
|
293
|
+
deps,
|
|
294
|
+
address,
|
|
295
|
+
steps as WasmBlobActionStep[],
|
|
296
|
+
ctx
|
|
297
|
+
)
|
|
298
|
+
case SigningMethod.EVM_TX:
|
|
299
|
+
return signEvmTxActions(steps as EvmTxActionStep[], ctx)
|
|
300
|
+
case SigningMethod.EIP712:
|
|
301
|
+
throw new PerpsError(
|
|
302
|
+
PerpsErrorCode.SDKError,
|
|
303
|
+
'LighterProvider.signActions: Lighter declares no EIP712 actions.'
|
|
304
|
+
)
|
|
305
|
+
default:
|
|
306
|
+
throw new PerpsError(
|
|
307
|
+
PerpsErrorCode.SDKError,
|
|
308
|
+
`LighterProvider.signActions: unknown SigningMethod '${method as string}'.`
|
|
309
|
+
)
|
|
310
|
+
}
|
|
311
|
+
}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
// The Go runtime installs functions (SignCreateOrder, SignCancelOrder, etc.)
|
|
2
|
+
// onto `globalThis` when `go.run(instance)` starts the main goroutine.
|
|
3
|
+
//
|
|
4
|
+
// The default asset URLs resolve relative to this module's emitted JS file:
|
|
5
|
+
// src/signers/../../wasm/lighter-signer.wasm → package-root wasm/
|
|
6
|
+
// dist/{esm,cjs}/signers/../../wasm/… → dist/wasm/ (shared)
|
|
7
|
+
// The build script copies the wasm assets into both dist subtrees so the same
|
|
8
|
+
// relative path resolves at runtime regardless of which bundle is loaded.
|
|
9
|
+
//
|
|
10
|
+
// To resolve the module's own URL in both ESM (where `__filename` is absent)
|
|
11
|
+
// and CJS (where `import.meta.url` is a syntax error), we parse a stack trace
|
|
12
|
+
// — `currentModuleUrl` always appears as the first frame, and V8 includes the
|
|
13
|
+
// emitting file path regardless of module system. Callers can override both
|
|
14
|
+
// asset URLs via {@link LoadLighterWasmOptions} to bypass this heuristic.
|
|
15
|
+
|
|
16
|
+
function currentModuleUrl(): string {
|
|
17
|
+
const cjsFilename = (globalThis as { __filename?: string }).__filename
|
|
18
|
+
if (typeof cjsFilename === 'string' && cjsFilename.length > 0) {
|
|
19
|
+
return `file://${cjsFilename}`
|
|
20
|
+
}
|
|
21
|
+
const stack = new Error().stack ?? ''
|
|
22
|
+
// Stack frames look like one of:
|
|
23
|
+
// " at currentModuleUrl (file:///abs/path/wasmLoader.js:29:10)"
|
|
24
|
+
// " at currentModuleUrl (/abs/path/wasmLoader.js:29:10)"
|
|
25
|
+
// " at currentModuleUrl (file:///abs/path/wasmLoader.ts:29:10)" (vitest)
|
|
26
|
+
// " at currentModuleUrl (http://localhost:5173/.../wasmLoader.ts?v=…:29:10)" (vite dev)
|
|
27
|
+
const match = stack.match(/\(([^)]+wasmLoader\.[tj]s[^)]*)\)/)
|
|
28
|
+
const frame = match?.[1] ?? ''
|
|
29
|
+
const withoutPos = frame.replace(/:\d+:\d+$/, '')
|
|
30
|
+
if (
|
|
31
|
+
withoutPos.startsWith('file://') ||
|
|
32
|
+
withoutPos.startsWith('http://') ||
|
|
33
|
+
withoutPos.startsWith('https://')
|
|
34
|
+
) {
|
|
35
|
+
return withoutPos
|
|
36
|
+
}
|
|
37
|
+
if (withoutPos.length > 0) {
|
|
38
|
+
// Bare absolute path (Node CJS without `file://` prefix in some runners).
|
|
39
|
+
return `file://${withoutPos}`
|
|
40
|
+
}
|
|
41
|
+
throw new Error(
|
|
42
|
+
'Could not resolve the Lighter WASM loader module URL. Pass an explicit ' +
|
|
43
|
+
'`wasmBinaryUrl` and `wasmExecJsUrl` to loadLighterWasm().'
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function defaultAssetUrl(filename: string): URL {
|
|
48
|
+
return new URL(`../../wasm/${filename}`, currentModuleUrl())
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** @public */
|
|
52
|
+
export interface LoadLighterWasmOptions {
|
|
53
|
+
/** Override URL for the `.wasm` binary (browser: fetch; Node: fs). */
|
|
54
|
+
wasmBinaryUrl?: string | URL
|
|
55
|
+
/** Override URL for Go's `wasm_exec.js` runtime. */
|
|
56
|
+
wasmExecJsUrl?: string | URL
|
|
57
|
+
/**
|
|
58
|
+
* Pre-fetched source of Go's `wasm_exec.js`. Preferred over
|
|
59
|
+
* `wasmExecJsUrl` for bundlers (Vite/webpack) that may transform a `.js`
|
|
60
|
+
* URL on serve, breaking the IIFE that installs `globalThis.Go`. Pass via
|
|
61
|
+
* a `?raw` import (Vite) or equivalent so the original source survives
|
|
62
|
+
* intact.
|
|
63
|
+
*/
|
|
64
|
+
wasmExecJsSource?: string
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** @public */
|
|
68
|
+
export interface LighterWasmExports {
|
|
69
|
+
GenerateAPIKey: (seed?: string) => {
|
|
70
|
+
publicKey?: string
|
|
71
|
+
privateKey?: string
|
|
72
|
+
error?: string
|
|
73
|
+
}
|
|
74
|
+
CreateClient: (
|
|
75
|
+
url: string,
|
|
76
|
+
privateKey: string,
|
|
77
|
+
chainId: number,
|
|
78
|
+
apiKeyIndex: number,
|
|
79
|
+
accountIndex: number
|
|
80
|
+
) => { error?: string }
|
|
81
|
+
CheckClient: (apiKeyIndex: number, accountIndex: number) => { error?: string }
|
|
82
|
+
/**
|
|
83
|
+
* Returns `{authToken}` on success — note the field name is `authToken`,
|
|
84
|
+
* NOT `token`. Reading the wrong field silently fails (Go sets nothing
|
|
85
|
+
* else on the result), which is why early code paths returned undefined
|
|
86
|
+
* tokens with no error.
|
|
87
|
+
*/
|
|
88
|
+
CreateAuthToken: (
|
|
89
|
+
deadline: number,
|
|
90
|
+
apiKeyIndex: number,
|
|
91
|
+
accountIndex: number
|
|
92
|
+
) => { authToken?: string; error?: string }
|
|
93
|
+
/**
|
|
94
|
+
* Signature mirrors lighter-python's `signer.SignChangePubKey(...)` call —
|
|
95
|
+
* 5 positional args including `skipNonce` (use 0 to embed our supplied
|
|
96
|
+
* nonce; 1 to leave it out for server-fill scenarios). Earlier versions
|
|
97
|
+
* here had only 4 args, which silently shifted all arguments by one and
|
|
98
|
+
* produced txInfo with garbage AccountIndex / ApiKeyIndex fields →
|
|
99
|
+
* Lighter rejected with code 20001 "invalid param".
|
|
100
|
+
*/
|
|
101
|
+
SignChangePubKey: (
|
|
102
|
+
pubKeyHex: string,
|
|
103
|
+
skipNonce: number,
|
|
104
|
+
nonce: number,
|
|
105
|
+
apiKeyIndex: number,
|
|
106
|
+
accountIndex: number
|
|
107
|
+
) => SignResult & { messageToSign?: string }
|
|
108
|
+
SignCreateOrder: (...args: unknown[]) => SignResult
|
|
109
|
+
SignCancelOrder: (...args: unknown[]) => SignResult
|
|
110
|
+
SignCancelAllOrders: (...args: unknown[]) => SignResult
|
|
111
|
+
SignTransfer: (...args: unknown[]) => SignResult
|
|
112
|
+
SignWithdraw: (...args: unknown[]) => SignResult
|
|
113
|
+
SignUpdateLeverage: (...args: unknown[]) => SignResult
|
|
114
|
+
SignModifyOrder: (...args: unknown[]) => SignResult
|
|
115
|
+
SignUpdateMargin: (...args: unknown[]) => SignResult
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** @internal */
|
|
119
|
+
export interface SignResult {
|
|
120
|
+
txType?: number
|
|
121
|
+
txInfo?: string
|
|
122
|
+
txHash?: string
|
|
123
|
+
error?: string
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const WASM_FUNCTION_NAMES = [
|
|
127
|
+
'GenerateAPIKey',
|
|
128
|
+
'CreateClient',
|
|
129
|
+
'CheckClient',
|
|
130
|
+
'CreateAuthToken',
|
|
131
|
+
'SignChangePubKey',
|
|
132
|
+
'SignCreateOrder',
|
|
133
|
+
'SignCancelOrder',
|
|
134
|
+
'SignCancelAllOrders',
|
|
135
|
+
'SignTransfer',
|
|
136
|
+
'SignWithdraw',
|
|
137
|
+
'SignUpdateLeverage',
|
|
138
|
+
'SignModifyOrder',
|
|
139
|
+
'SignUpdateMargin',
|
|
140
|
+
] as const
|
|
141
|
+
|
|
142
|
+
type GoClass = new () => {
|
|
143
|
+
importObject: WebAssembly.Imports
|
|
144
|
+
run(instance: WebAssembly.Instance): Promise<void>
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
let cachedExports: Promise<LighterWasmExports> | undefined
|
|
148
|
+
|
|
149
|
+
// `node:fs/promises` and `node:url` are Node-only. Static imports force browser
|
|
150
|
+
// bundlers (Vite/Rollup/esbuild) to resolve them up-front, which fails. Dynamic
|
|
151
|
+
// `import('node:...')` lets bundlers leave the branch unreachable in browsers
|
|
152
|
+
// while Node still resolves it at runtime when asked for a `file://` URL.
|
|
153
|
+
async function readNodeFile(url: URL): Promise<Uint8Array> {
|
|
154
|
+
const [{ readFile }, { fileURLToPath }] = await Promise.all([
|
|
155
|
+
import(/* @vite-ignore */ 'node:fs/promises'),
|
|
156
|
+
import(/* @vite-ignore */ 'node:url'),
|
|
157
|
+
])
|
|
158
|
+
return readFile(fileURLToPath(url))
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Resolve a possibly-relative URL string against the current document/page
|
|
163
|
+
* origin. Bundlers like Vite hand out absolute paths (e.g. `/node_modules/…`)
|
|
164
|
+
* for `?url` imports, which `new URL(string)` rejects without a base.
|
|
165
|
+
*/
|
|
166
|
+
function toResolvedUrl(url: string | URL): URL {
|
|
167
|
+
if (url instanceof URL) {
|
|
168
|
+
return url
|
|
169
|
+
}
|
|
170
|
+
const base =
|
|
171
|
+
typeof globalThis !== 'undefined' &&
|
|
172
|
+
(globalThis as { location?: { href?: string } }).location?.href
|
|
173
|
+
? (globalThis as { location: { href: string } }).location.href
|
|
174
|
+
: undefined
|
|
175
|
+
return new URL(url, base)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async function readUrlBytes(url: string | URL): Promise<ArrayBuffer> {
|
|
179
|
+
const u = toResolvedUrl(url)
|
|
180
|
+
if (u.protocol === 'file:') {
|
|
181
|
+
const buf = await readNodeFile(u)
|
|
182
|
+
// Copy the view into a fresh ArrayBuffer — `Buffer.buffer` is a shared
|
|
183
|
+
// ArrayBuffer in Node and the wasm instantiator expects a plain one.
|
|
184
|
+
return buf.slice().buffer as ArrayBuffer
|
|
185
|
+
}
|
|
186
|
+
const response = await fetch(u)
|
|
187
|
+
if (!response.ok) {
|
|
188
|
+
throw new Error(
|
|
189
|
+
`Failed to fetch ${u.href}: ${response.status} ${response.statusText}`
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
return response.arrayBuffer()
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async function readUrlText(url: string | URL): Promise<string> {
|
|
196
|
+
const u = toResolvedUrl(url)
|
|
197
|
+
if (u.protocol === 'file:') {
|
|
198
|
+
const buf = await readNodeFile(u)
|
|
199
|
+
return new TextDecoder('utf-8').decode(buf)
|
|
200
|
+
}
|
|
201
|
+
const response = await fetch(u)
|
|
202
|
+
if (!response.ok) {
|
|
203
|
+
throw new Error(
|
|
204
|
+
`Failed to fetch ${u.href}: ${response.status} ${response.statusText}`
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
return response.text()
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Load the Lighter WASM signer. Memoized per-process: subsequent calls return
|
|
212
|
+
* the cached exports. The Go runtime keeps a long-running goroutine to service
|
|
213
|
+
* JS calls — we start it once and never stop it.
|
|
214
|
+
* @public
|
|
215
|
+
*/
|
|
216
|
+
export async function loadLighterWasm(
|
|
217
|
+
options?: LoadLighterWasmOptions
|
|
218
|
+
): Promise<LighterWasmExports> {
|
|
219
|
+
if (!cachedExports) {
|
|
220
|
+
cachedExports = loadWasmUncached(options)
|
|
221
|
+
}
|
|
222
|
+
return cachedExports
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
async function loadWasmUncached(
|
|
226
|
+
options?: LoadLighterWasmOptions
|
|
227
|
+
): Promise<LighterWasmExports> {
|
|
228
|
+
const wasmBinaryUrl =
|
|
229
|
+
options?.wasmBinaryUrl ?? defaultAssetUrl('lighter-signer.wasm')
|
|
230
|
+
|
|
231
|
+
// Prefer a pre-fetched source string (bundler `?raw` imports) over a URL —
|
|
232
|
+
// bundlers may transform a `.js` URL on serve, breaking the IIFE that sets
|
|
233
|
+
// `globalThis.Go`.
|
|
234
|
+
const wasmExecSourcePromise: Promise<string> =
|
|
235
|
+
options?.wasmExecJsSource !== undefined
|
|
236
|
+
? Promise.resolve(options.wasmExecJsSource)
|
|
237
|
+
: readUrlText(options?.wasmExecJsUrl ?? defaultAssetUrl('wasm_exec.js'))
|
|
238
|
+
|
|
239
|
+
const [wasmExecSource, wasmBytes] = await Promise.all([
|
|
240
|
+
wasmExecSourcePromise,
|
|
241
|
+
readUrlBytes(wasmBinaryUrl),
|
|
242
|
+
])
|
|
243
|
+
|
|
244
|
+
// wasm_exec.js is an IIFE that installs `globalThis.Go = class { ... }` plus
|
|
245
|
+
// fs/process/crypto polyfills. Evaluate it in a Function scope so the class
|
|
246
|
+
// attaches to globalThis and we read it back from there.
|
|
247
|
+
const installGo = new Function(`${wasmExecSource}; return globalThis.Go`)
|
|
248
|
+
const Go = installGo() as GoClass
|
|
249
|
+
|
|
250
|
+
const go = new Go()
|
|
251
|
+
const { instance } = await WebAssembly.instantiate(wasmBytes, go.importObject)
|
|
252
|
+
// Start the Go goroutine — this never resolves until the Go main() returns,
|
|
253
|
+
// which our signer never does. Intentionally not awaited.
|
|
254
|
+
void go.run(instance)
|
|
255
|
+
|
|
256
|
+
// Wait microtasks to let Go's init() register JS-bound functions.
|
|
257
|
+
await yieldToGoRuntime()
|
|
258
|
+
|
|
259
|
+
const exports: Partial<LighterWasmExports> = {}
|
|
260
|
+
for (const name of WASM_FUNCTION_NAMES) {
|
|
261
|
+
const fn = (globalThis as Record<string, unknown>)[name]
|
|
262
|
+
if (typeof fn !== 'function') {
|
|
263
|
+
throw new Error(
|
|
264
|
+
`Lighter WASM did not export expected function: ${name}. ` +
|
|
265
|
+
'The .wasm binary may be stale or incompatible.'
|
|
266
|
+
)
|
|
267
|
+
}
|
|
268
|
+
;(exports as Record<string, unknown>)[name] = fn
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return exports as LighterWasmExports
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
async function yieldToGoRuntime(): Promise<void> {
|
|
275
|
+
for (let i = 0; i < 2; i++) {
|
|
276
|
+
await new Promise<void>((resolve) => {
|
|
277
|
+
if (typeof setImmediate === 'function') {
|
|
278
|
+
setImmediate(resolve)
|
|
279
|
+
} else {
|
|
280
|
+
setTimeout(resolve, 0)
|
|
281
|
+
}
|
|
282
|
+
})
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Testing helper — drop the cached WASM instance so the next load reinitializes.
|
|
288
|
+
*
|
|
289
|
+
* @public
|
|
290
|
+
*/
|
|
291
|
+
export function resetLighterWasmCache(): void {
|
|
292
|
+
cachedExports = undefined
|
|
293
|
+
}
|