@lifi/perps-sdk-provider-lighter 8.2.1 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/README.md +14 -10
  2. package/dist/cjs/LighterProvider.d.ts +5 -10
  3. package/dist/cjs/LighterProvider.d.ts.map +1 -1
  4. package/dist/cjs/LighterProvider.js +31 -26
  5. package/dist/cjs/LighterProvider.js.map +1 -1
  6. package/dist/cjs/constants.d.ts +5 -8
  7. package/dist/cjs/constants.d.ts.map +1 -1
  8. package/dist/cjs/constants.js +15 -12
  9. package/dist/cjs/constants.js.map +1 -1
  10. package/dist/cjs/index.d.ts +3 -4
  11. package/dist/cjs/index.d.ts.map +1 -1
  12. package/dist/cjs/index.js +6 -5
  13. package/dist/cjs/index.js.map +1 -1
  14. package/dist/cjs/signers/LighterSigner.d.ts +5 -7
  15. package/dist/cjs/signers/LighterSigner.d.ts.map +1 -1
  16. package/dist/cjs/signers/LighterSigner.js +30 -17
  17. package/dist/cjs/signers/LighterSigner.js.map +1 -1
  18. package/dist/cjs/signers/generated/wasmExecRuntime.d.ts +2 -0
  19. package/dist/cjs/signers/generated/wasmExecRuntime.d.ts.map +1 -0
  20. package/dist/cjs/signers/generated/wasmExecRuntime.js +569 -0
  21. package/dist/cjs/signers/generated/wasmExecRuntime.js.map +1 -0
  22. package/dist/cjs/signers/signActions.d.ts +2 -2
  23. package/dist/cjs/signers/signActions.d.ts.map +1 -1
  24. package/dist/cjs/signers/signActions.js +4 -10
  25. package/dist/cjs/signers/signActions.js.map +1 -1
  26. package/dist/cjs/signers/wasmBinaryUrl.js +11 -0
  27. package/dist/cjs/signers/wasmLoader.d.ts +1 -6
  28. package/dist/cjs/signers/wasmLoader.d.ts.map +1 -1
  29. package/dist/cjs/signers/wasmLoader.js +15 -69
  30. package/dist/cjs/signers/wasmLoader.js.map +1 -1
  31. package/dist/cjs/types/account.d.ts +4 -1
  32. package/dist/cjs/types/account.d.ts.map +1 -1
  33. package/dist/cjs/types/action.d.ts +4 -1
  34. package/dist/cjs/types/action.d.ts.map +1 -1
  35. package/dist/cjs/types/action.js.map +1 -1
  36. package/dist/cjs/utils/assetCollateral.d.ts +2 -1
  37. package/dist/cjs/utils/assetCollateral.d.ts.map +1 -1
  38. package/dist/cjs/utils/assetCollateral.js +1 -1
  39. package/dist/cjs/utils/assetCollateral.js.map +1 -1
  40. package/dist/cjs/utils/index.d.ts +1 -0
  41. package/dist/cjs/utils/index.d.ts.map +1 -1
  42. package/dist/cjs/utils/index.js +3 -1
  43. package/dist/cjs/utils/index.js.map +1 -1
  44. package/dist/cjs/utils/withdrawableBalances.d.ts +4 -0
  45. package/dist/cjs/utils/withdrawableBalances.d.ts.map +1 -0
  46. package/dist/cjs/utils/withdrawableBalances.js +21 -0
  47. package/dist/cjs/utils/withdrawableBalances.js.map +1 -0
  48. package/dist/esm/LighterProvider.d.ts +53 -56
  49. package/dist/esm/LighterProvider.d.ts.map +1 -1
  50. package/dist/esm/LighterProvider.js +74 -49
  51. package/dist/esm/LighterProvider.js.map +1 -1
  52. package/dist/esm/constants.d.ts +25 -36
  53. package/dist/esm/constants.d.ts.map +1 -1
  54. package/dist/esm/constants.js +31 -18
  55. package/dist/esm/constants.js.map +1 -1
  56. package/dist/esm/index.d.ts +6 -7
  57. package/dist/esm/index.d.ts.map +1 -1
  58. package/dist/esm/index.js +5 -6
  59. package/dist/esm/index.js.map +1 -1
  60. package/dist/esm/signers/LighterSigner.d.ts +10 -18
  61. package/dist/esm/signers/LighterSigner.d.ts.map +1 -1
  62. package/dist/esm/signers/LighterSigner.js +32 -25
  63. package/dist/esm/signers/LighterSigner.js.map +1 -1
  64. package/dist/esm/signers/generated/wasmExecRuntime.d.ts +8 -0
  65. package/dist/esm/signers/generated/wasmExecRuntime.d.ts.map +1 -0
  66. package/dist/esm/signers/generated/wasmExecRuntime.js +574 -0
  67. package/dist/esm/signers/generated/wasmExecRuntime.js.map +1 -0
  68. package/dist/esm/signers/signActions.d.ts +3 -5
  69. package/dist/esm/signers/signActions.d.ts.map +1 -1
  70. package/dist/esm/signers/signActions.js +4 -10
  71. package/dist/esm/signers/signActions.js.map +1 -1
  72. package/dist/esm/signers/wasmBinaryUrl.js +10 -0
  73. package/dist/esm/signers/wasmLoader.d.ts +7 -31
  74. package/dist/esm/signers/wasmLoader.d.ts.map +1 -1
  75. package/dist/esm/signers/wasmLoader.js +32 -108
  76. package/dist/esm/signers/wasmLoader.js.map +1 -1
  77. package/dist/esm/types/account.d.ts +17 -6
  78. package/dist/esm/types/account.d.ts.map +1 -1
  79. package/dist/esm/types/action.d.ts +14 -2
  80. package/dist/esm/types/action.d.ts.map +1 -1
  81. package/dist/esm/types/action.js.map +1 -1
  82. package/dist/esm/utils/assetCollateral.d.ts +3 -2
  83. package/dist/esm/utils/assetCollateral.d.ts.map +1 -1
  84. package/dist/esm/utils/assetCollateral.js +5 -5
  85. package/dist/esm/utils/assetCollateral.js.map +1 -1
  86. package/dist/esm/utils/index.d.ts +1 -0
  87. package/dist/esm/utils/index.d.ts.map +1 -1
  88. package/dist/esm/utils/index.js +1 -0
  89. package/dist/esm/utils/index.js.map +1 -1
  90. package/dist/esm/utils/withdrawableBalances.d.ts +12 -0
  91. package/dist/esm/utils/withdrawableBalances.d.ts.map +1 -0
  92. package/dist/esm/utils/withdrawableBalances.js +25 -0
  93. package/dist/esm/utils/withdrawableBalances.js.map +1 -0
  94. package/dist/types/LighterProvider.d.ts +53 -56
  95. package/dist/types/LighterProvider.d.ts.map +1 -1
  96. package/dist/types/constants.d.ts +25 -36
  97. package/dist/types/constants.d.ts.map +1 -1
  98. package/dist/types/index.d.ts +6 -7
  99. package/dist/types/index.d.ts.map +1 -1
  100. package/dist/types/signers/LighterSigner.d.ts +10 -18
  101. package/dist/types/signers/LighterSigner.d.ts.map +1 -1
  102. package/dist/types/signers/generated/wasmExecRuntime.d.ts +8 -0
  103. package/dist/types/signers/generated/wasmExecRuntime.d.ts.map +1 -0
  104. package/dist/types/signers/signActions.d.ts +3 -5
  105. package/dist/types/signers/signActions.d.ts.map +1 -1
  106. package/dist/types/signers/wasmLoader.d.ts +7 -31
  107. package/dist/types/signers/wasmLoader.d.ts.map +1 -1
  108. package/dist/types/types/account.d.ts +17 -6
  109. package/dist/types/types/account.d.ts.map +1 -1
  110. package/dist/types/types/action.d.ts +14 -2
  111. package/dist/types/types/action.d.ts.map +1 -1
  112. package/dist/types/utils/assetCollateral.d.ts +3 -2
  113. package/dist/types/utils/assetCollateral.d.ts.map +1 -1
  114. package/dist/types/utils/index.d.ts +1 -0
  115. package/dist/types/utils/index.d.ts.map +1 -1
  116. package/dist/types/utils/withdrawableBalances.d.ts +12 -0
  117. package/dist/types/utils/withdrawableBalances.d.ts.map +1 -0
  118. package/package.json +3 -6
  119. package/src/LighterProvider.ts +112 -101
  120. package/src/constants.ts +35 -45
  121. package/src/index.ts +13 -10
  122. package/src/signers/LighterSigner.ts +47 -51
  123. package/src/signers/generated/wasmExecRuntime.ts +575 -0
  124. package/src/signers/signActions.ts +12 -30
  125. package/src/signers/wasmBinaryUrl.d.ts +7 -0
  126. package/src/signers/wasmLoader.ts +33 -152
  127. package/src/types/account.ts +18 -6
  128. package/src/types/action.ts +14 -2
  129. package/src/utils/assetCollateral.ts +8 -6
  130. package/src/utils/index.ts +1 -0
  131. package/src/utils/withdrawableBalances.ts +31 -0
  132. package/dist/cjs/signers/index.d.ts +0 -11
  133. package/dist/cjs/signers/index.d.ts.map +0 -1
  134. package/dist/cjs/signers/index.js +0 -18
  135. package/dist/cjs/signers/index.js.map +0 -1
  136. package/dist/esm/signers/index.d.ts +0 -11
  137. package/dist/esm/signers/index.d.ts.map +0 -1
  138. package/dist/esm/signers/index.js +0 -7
  139. package/dist/esm/signers/index.js.map +0 -1
  140. package/dist/types/signers/index.d.ts +0 -11
  141. package/dist/types/signers/index.d.ts.map +0 -1
  142. package/dist/wasm/wasm_exec.js +0 -561
  143. package/src/signers/index.ts +0 -35
  144. package/wasm/lighter-signer.wasm +0 -0
  145. package/wasm/wasm_exec.js +0 -561
@@ -1 +1 @@
1
- {"version":3,"file":"assetCollateral.d.ts","sourceRoot":"","sources":["../../../src/utils/assetCollateral.ts"],"names":[],"mappings":"AAOA,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAE3D;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAEhE"}
1
+ {"version":3,"file":"assetCollateral.d.ts","sourceRoot":"","sources":["../../../src/utils/assetCollateral.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAS5D,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAE3D;AAED,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAE3E"}
@@ -16,4 +16,5 @@ export { formatOrderPrice, formatOrderSize } from './orderFormatting.js';
16
16
  export { toIsoFromMs, toIsoFromSeconds } from './time.js';
17
17
  export { positionMarginConstraints } from './transferMargin.js';
18
18
  export { leverageToFraction, mapOrderTypeToInt, mapTimeInForceToInt, marginFractionToMaxLeverage, orderExpiryForTif, resolveTimeInForce, } from './wireEncoding.js';
19
+ export { lighterWithdrawableBalances } from './withdrawableBalances.js';
19
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAIA,YAAY,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAC/E,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,aAAa,EACb,QAAQ,EACR,cAAc,EACd,eAAe,EACf,eAAe,GAChB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACxE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,2BAA2B,EAC3B,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,mBAAmB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAIA,YAAY,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAC/E,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,aAAa,EACb,QAAQ,EACR,cAAc,EACd,eAAe,EACf,eAAe,GAChB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACxE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,2BAA2B,EAC3B,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAA"}
@@ -0,0 +1,12 @@
1
+ import type { ProviderWithdrawableBalance } from '@lifi/perps-sdk';
2
+ import type { LtAccountAsset } from '../types/account.js';
3
+ /**
4
+ * Split each held asset into the two routes a Lighter withdrawal can name:
5
+ * spot draws on `balance` net of `locked_balance`, perps draws on
6
+ * `margin_balance`. Routes with nothing left to draw are dropped; the
7
+ * per-asset venue minimum is applied by the caller holding the asset registry.
8
+ *
9
+ * @public
10
+ */
11
+ export declare const lighterWithdrawableBalances: (assets: LtAccountAsset[]) => ProviderWithdrawableBalance[];
12
+ //# sourceMappingURL=withdrawableBalances.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"withdrawableBalances.d.ts","sourceRoot":"","sources":["../../../src/utils/withdrawableBalances.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAGzD;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,GACtC,QAAQ,cAAc,EAAE,KACvB,2BAA2B,EAgB7B,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifi/perps-sdk-provider-lighter",
3
- "version": "8.2.1",
3
+ "version": "10.0.0",
4
4
  "description": "Lighter provider plugin for @lifi/perps-sdk",
5
5
  "homepage": "https://github.com/lifinance/perps-sdk",
6
6
  "bugs": {
@@ -24,15 +24,12 @@
24
24
  "import": "./dist/esm/index.js",
25
25
  "default": "./dist/cjs/index.js"
26
26
  },
27
- "./wasm/*": "./wasm/*",
28
27
  "./package.json": "./package.json"
29
28
  },
30
29
  "files": [
31
30
  "dist/**",
32
31
  "!dist/**/*.tsbuildinfo",
33
32
  "src/**/*.ts",
34
- "wasm/lighter-signer.wasm",
35
- "wasm/wasm_exec.js",
36
33
  "!src/**/*.spec.ts",
37
34
  "!src/**/*.test.ts",
38
35
  "!src/**/*.mock.ts",
@@ -47,10 +44,10 @@
47
44
  "dependencies": {
48
45
  "big.js": "^7.0.1",
49
46
  "viem": "^2.48.8",
50
- "@lifi/perps-types": "^5.0.0"
47
+ "@lifi/perps-types": "^5.1.0"
51
48
  },
52
49
  "peerDependencies": {
53
- "@lifi/perps-sdk": "^6.2.1"
50
+ "@lifi/perps-sdk": "^6.3.0"
54
51
  },
55
52
  "publishConfig": {
56
53
  "access": "public"
@@ -4,6 +4,7 @@ import {
4
4
  getAssetRegistry,
5
5
  getMarketRegistry,
6
6
  getProviders,
7
+ localStorageAdapter,
7
8
  PerpsError,
8
9
  type PerpsProviderPlugin,
9
10
  type PerpsSDKClient,
@@ -17,10 +18,13 @@ import {
17
18
  type ProviderGetOrdersParams,
18
19
  type ProviderGetPositionsParams,
19
20
  type ProviderGetQuoteParams,
21
+ type ProviderGetWithdrawableBalancesParams,
22
+ type ProviderWithdrawableBalance,
20
23
  resolveQuote,
21
24
  resolveRetryPolicy,
22
25
  type SDKRequestOptions,
23
26
  type SignActionsContext,
27
+ type StorageAdapter,
24
28
  toPerpsMarketDisplay,
25
29
  } from '@lifi/perps-sdk'
26
30
  import type {
@@ -34,7 +38,6 @@ import type {
34
38
  Balance,
35
39
  FillsResponse,
36
40
  LighterAccountConfig,
37
- LighterProviderKey,
38
41
  MarketSettings,
39
42
  Order,
40
43
  OrdersResponse,
@@ -56,23 +59,21 @@ import { projectLighterConfigSettings } from './accountConfig.js'
56
59
  import { getAccountSummary } from './accountSummary.js'
57
60
  import {
58
61
  DEFAULT_API_KEY_INDEX,
59
- DEFAULT_LIGHTER_EXPLORER_TX_BASE_URL,
60
- DEFAULT_LIGHTER_REST_URL,
61
62
  DEFAULT_TRADES_LIMIT,
62
63
  LIGHTER_ALL_MARKETS_WILDCARD,
63
64
  LIGHTER_BASE_FEE_TIER,
64
- LIGHTER_COLLATERAL_ASSETS,
65
65
  LIGHTER_FEE_TICK_SCALE,
66
66
  LIGHTER_HISTORY_PAGE_SIZE,
67
- LIGHTER_PROVIDER_KEY,
67
+ LIGHTER_MAINNET_DEPLOYMENT,
68
+ LIGHTER_RH_DEPLOYMENT,
68
69
  LIGHTER_SPOT_CATEGORY_ID,
70
+ type LighterDeployment,
69
71
  } from './constants.js'
70
72
  import { lighterDepositFlow } from './depositFlow.js'
71
73
  import { createAuthToken } from './signers/createAuthToken.js'
72
- import type { LighterKeyStore } from './signers/LighterKeyStore.js'
73
- import type { LighterReadOnlyTokenManagerOptions } from './signers/LighterReadOnlyTokenManager.js'
74
+ import { LighterKeyStore } from './signers/LighterKeyStore.js'
74
75
  import { LighterReadOnlyTokenManager } from './signers/LighterReadOnlyTokenManager.js'
75
- import type { LighterSigner } from './signers/LighterSigner.js'
76
+ import { LighterSigner } from './signers/LighterSigner.js'
76
77
  import { lighterSignActions } from './signers/signActions.js'
77
78
  import type {
78
79
  LtAccountLimits,
@@ -106,6 +107,7 @@ import {
106
107
  formatOrderSize,
107
108
  leverageFromImf,
108
109
  lighterAsset,
110
+ lighterWithdrawableBalances,
109
111
  mapFill,
110
112
  mapOpenPositions,
111
113
  mapOrderDetail,
@@ -170,67 +172,42 @@ const normalizeLighterPublicKey = (key: string): string =>
170
172
  key.replace(/^0x/i, '').toLowerCase()
171
173
 
172
174
  /**
173
- * Construction options for the Lighter {@link PerpsProviderPlugin}.
174
- *
175
- * `restUrl` defaults to Lighter mainnet; pass a testnet URL or a self-hosted
176
- * mirror to override.
175
+ * Consumer-level overrides for a ready-made Lighter provider plugin. Every
176
+ * deployment fact — provider key, endpoints, signing chain id, collateral
177
+ * asset, explorer — belongs to the SDK's {@link LighterDeployment} descriptor
178
+ * and is not settable here; the signer, API-key store and read-only token
179
+ * manager are created per plugin instance.
177
180
  *
178
181
  * Auth-token resolution order for the auth-gated reads:
179
182
  * 1. Per-call `options.lighterAuthToken`
180
183
  * 2. Constructor `authToken` (string or async factory)
181
- * 3. Persisted long-lived read-only token (via `readOnlyTokenOptions`'s
182
- * storage), keyed on the resolved Lighter `accountIndex`
183
- * 4. Fresh 1h create via the WASM signer + the user's registered API key
184
- * from `keyStore`
184
+ * 3. Persisted long-lived read-only token, keyed on the resolved Lighter
185
+ * `accountIndex`
186
+ * 4. Fresh 1h create via this instance's WASM signer + the user's registered
187
+ * API key
185
188
  *
186
189
  * When none of these yields a token the auth-gated reads degrade gracefully:
187
190
  * - `getOrders`, `getActivity` return empty results (mirrors backend behaviour)
188
191
  * - `getOrder` throws `Unauthorized`
189
192
  * - `getAccount` returns zero fee tier rather than failing
190
193
  *
191
- * `WASM_BLOB` write actions (`signActions`) require `signer` and `keyStore` to
192
- * be supplied; the `EVM_TX` arm signs with the end-user wallet alone.
193
- *
194
194
  * @public
195
195
  */
196
196
  export interface LighterProviderOptions {
197
197
  /**
198
- * Provider key: the plugin `type`, the `Provider.key` matched against the
199
- * backend `/providers` response, and the namespace for this instance's market
200
- * / asset registries and retry policy. Defaults to `'lighter'` (mainnet).
201
- * Set a distinct key (e.g. `'lighter-rh'`) to register a second Lighter
202
- * instance on the same client.
198
+ * Persistence backend for this instance's Lighter API keypair and read-only
199
+ * token. Defaults to browser `localStorage` (encrypted at rest). Pass a
200
+ * custom adapter for SSR / non-browser hosts or another storage backend.
203
201
  */
204
- providerKey?: LighterProviderKey
205
- /** Lighter REST base URL. Defaults to mainnet. */
206
- restUrl?: string
202
+ storage?: StorageAdapter
207
203
  /**
208
- * Explorer tx base URL for transfer-activity links (`${base}${txHash}`).
209
- * Defaults to the mainnet Lighter explorer for the default provider key, and
210
- * to `undefined` (no transfer links) for any other key unless supplied.
204
+ * Lighter REST base URL. Defaults to the deployment's own endpoint; override
205
+ * to point at a reverse proxy, self-hosted mirror or rate-limit gateway. The
206
+ * instance's signer and read-only token manager follow this URL.
211
207
  */
212
- explorerTxBaseUrl?: string
213
- /** Pre-created Lighter read-only bearer. */
208
+ restUrl?: string
209
+ /** Pre-created Lighter read-only bearer, bypassing SDK token resolution. */
214
210
  authToken?: string | (() => string | Promise<string>)
215
- /**
216
- * WASM signer instance. Required for the `WASM_BLOB` arm of `signActions`
217
- * and for on-demand auth-token creating from the user's API key. The default
218
- * configuration loads the WASM blob shipped with this package.
219
- */
220
- signer?: LighterSigner
221
- /**
222
- * Store for the user's per-address Lighter API keypair. Required for the
223
- * `WASM_BLOB` arm of `signActions` and for on-demand auth-token creating.
224
- */
225
- keyStore?: LighterKeyStore
226
- /**
227
- * Injection overrides (storage, fetcher, clock, host) for the read-only
228
- * token manager, which is always active — Lighter reads create a long-lived
229
- * read-only token on first use and reuse it thereafter. The host defaults to
230
- * `restUrl`. This does not enable or disable the manager; it only overrides
231
- * its dependencies (primarily for tests / non-browser storage).
232
- */
233
- readOnlyTokenOptions?: LighterReadOnlyTokenManagerOptions
234
211
  /** Token lifetime for on-demand standard-token creates (Lighter caps at 8h). Default 1h. */
235
212
  tokenLifetimeSeconds?: number
236
213
  /** Re-create when the cached standard token's remaining life is below this. Default 60s. */
@@ -270,27 +247,14 @@ export interface LighterPerpsProvider extends PerpsProviderPlugin {
270
247
  }
271
248
 
272
249
  /**
273
- * Lighter provider plugin factory. Returns an object implementing
274
- * {@link PerpsProviderPlugin}, mirroring the `EthereumProvider()` / `hyperliquidProvider()`
275
- * shape used by the rest of the LI.FI SDK family.
276
- *
277
- * Read functions call Lighter's REST API directly with no LI.FI backend hop.
278
- * Auth-gated reads resolve their token via the order documented on
279
- * {@link LighterProviderOptions}.
280
- *
281
- * Write actions (`WASM_BLOB` and `EVM_TX` signing) are dispatched via
282
- * `signActions` — `PerpsClient.execute` delegates those arms here.
250
+ * Build a Lighter provider plugin for one deployment. The deployment
251
+ * descriptor is SDK-owned, so this stays package-internal: consumers reach it
252
+ * through {@link lighterProvider} / {@link lighterRhProvider}.
283
253
  *
284
- * @example
285
- * ```ts
286
- * const client = createPerpsClient({
287
- * integrator: 'my-app',
288
- * providers: [lighterProvider()],
289
- * })
290
- * ```
291
- * @public
254
+ * @internal
292
255
  */
293
- export const lighterProvider = (
256
+ export const createLighterProvider = (
257
+ deployment: LighterDeployment,
294
258
  options: LighterProviderOptions = {}
295
259
  ): LighterPerpsProvider => {
296
260
  // Late-bind slot: the factory runs before the client exists, so `bind`
@@ -301,34 +265,34 @@ export const lighterProvider = (
301
265
  if (boundClient === undefined) {
302
266
  throw new PerpsError(
303
267
  PerpsErrorCode.SDKError,
304
- 'lighterProvider used before binding. Register it via ' +
305
- 'createPerpsClient({ providers: [lighterProvider()] }).'
268
+ `${deployment.providerKey} provider used before binding. Register it ` +
269
+ 'via createPerpsClient({ providers: [lighterProvider()] }).'
306
270
  )
307
271
  }
308
272
  return boundClient
309
273
  }
310
274
 
311
- const providerKey = options.providerKey ?? LIGHTER_PROVIDER_KEY
312
- const restUrl = options.restUrl ?? DEFAULT_LIGHTER_REST_URL
313
- const explorerTxBaseUrl =
314
- options.explorerTxBaseUrl ??
315
- (providerKey === LIGHTER_PROVIDER_KEY
316
- ? DEFAULT_LIGHTER_EXPLORER_TX_BASE_URL
317
- : undefined)
318
- const collateral = LIGHTER_COLLATERAL_ASSETS[providerKey]
275
+ const providerKey = deployment.providerKey
276
+ const restUrl = options.restUrl ?? deployment.restUrl
277
+ const explorerTxBaseUrl = deployment.explorerTxBaseUrl
278
+ const collateral = deployment.collateral
319
279
  const authTokenSource: (() => string | Promise<string>) | undefined =
320
280
  typeof options.authToken === 'function'
321
281
  ? options.authToken
322
282
  : options.authToken !== undefined
323
283
  ? () => options.authToken as string
324
284
  : undefined
325
- const signer = options.signer
326
- const keyStore = options.keyStore
327
- keyStore?.bindProviderKey(providerKey)
285
+ const storage = options.storage ?? localStorageAdapter
286
+ const signer = new LighterSigner({
287
+ apiUrl: restUrl,
288
+ signerChainId: deployment.signerChainId,
289
+ collateralAssetIndex: collateral.assetIndex,
290
+ })
291
+ const keyStore = new LighterKeyStore(storage, providerKey)
328
292
  const readOnlyTokenManager = new LighterReadOnlyTokenManager({
293
+ storage,
329
294
  providerKey,
330
295
  lighterApiUrl: restUrl,
331
- ...options.readOnlyTokenOptions,
332
296
  })
333
297
  const tokenLifetimeSeconds = options.tokenLifetimeSeconds ?? 60 * 60
334
298
  const tokenRenewBufferSeconds = options.tokenRenewBufferSeconds ?? 60
@@ -360,12 +324,6 @@ export const lighterProvider = (
360
324
  apiKeyPrivateKey: string,
361
325
  indices: { apiKeyIndex: number; accountIndex: number }
362
326
  ): Promise<string> => {
363
- if (signer === undefined) {
364
- throw new PerpsError(
365
- PerpsErrorCode.SDKError,
366
- 'lighterProvider: getStandardAuthToken called without a configured signer.'
367
- )
368
- }
369
327
  const cacheKey = address.toLowerCase()
370
328
  const nowSec = Math.floor(Date.now() / 1000)
371
329
  const cached = standardTokenByAddress.get(cacheKey)
@@ -414,11 +372,11 @@ export const lighterProvider = (
414
372
  if (authTokenSource !== undefined) {
415
373
  return authTokenSource()
416
374
  }
417
- if (address === undefined || keyStore === undefined) {
375
+ if (address === undefined) {
418
376
  return undefined
419
377
  }
420
378
  const apiKey = await keyStore.get(address)
421
- if (apiKey === null || signer === undefined) {
379
+ if (apiKey === null) {
422
380
  return undefined
423
381
  }
424
382
 
@@ -496,7 +454,7 @@ export const lighterProvider = (
496
454
  // rides reads during the creation-failure fallback and authorises
497
455
  // read-only token creation — so a revocation must re-sign it too.
498
456
  standardTokenByAddress.delete(cacheKey)
499
- const apiKey = keyStore ? await keyStore.get(address) : null
457
+ const apiKey = await keyStore.get(address)
500
458
  if (apiKey !== null) {
501
459
  await readOnlyTokenManager.remove(address, apiKey.accountIndex)
502
460
  }
@@ -748,7 +706,7 @@ export const lighterProvider = (
748
706
  : retryOnRevoked(opts, params.address, token, (t) =>
749
707
  fetchAccountLimits(client, account.index, t)
750
708
  ),
751
- keyStore ? keyStore.get(params.address) : Promise.resolve(null),
709
+ keyStore.get(params.address),
752
710
  readOnlyTokenManager.get(params.address, account.index),
753
711
  // No referral code to compare against, or no token to authenticate the
754
712
  // read → undefined → `referralPresent: false`.
@@ -891,6 +849,17 @@ export const lighterProvider = (
891
849
  )
892
850
  },
893
851
 
852
+ async getWithdrawableBalances(
853
+ params: ProviderGetWithdrawableBalancesParams,
854
+ opts?: SDKRequestOptions
855
+ ): Promise<ProviderWithdrawableBalance[]> {
856
+ const account = await fetchDetailedAccount(
857
+ apiClient(opts),
858
+ params.address
859
+ )
860
+ return lighterWithdrawableBalances(account.assets)
861
+ },
862
+
894
863
  async getPositions(
895
864
  params: ProviderGetPositionsParams,
896
865
  opts?: SDKRequestOptions
@@ -1349,9 +1318,8 @@ export const lighterProvider = (
1349
1318
 
1350
1319
  /**
1351
1320
  * Hand the backend the local pubkey for REGISTER_API_KEY so its
1352
- * idempotency check can compare against the on-chain slot. No keystore
1353
- * configured, or no key stored for this address → omit the field;
1354
- * backend stages a fresh registration.
1321
+ * idempotency check can compare against the on-chain slot. No key stored
1322
+ * for this address → omit the field; backend stages a fresh registration.
1355
1323
  */
1356
1324
  async resolveSetupParams(
1357
1325
  action: ActionType,
@@ -1360,9 +1328,6 @@ export const lighterProvider = (
1360
1328
  if (action !== ActionType.REGISTER_API_KEY) {
1361
1329
  return {}
1362
1330
  }
1363
- if (keyStore === undefined) {
1364
- return {}
1365
- }
1366
1331
  const local = await keyStore.get(address)
1367
1332
  if (local === null) {
1368
1333
  return {}
@@ -1390,7 +1355,7 @@ export const lighterProvider = (
1390
1355
  keyStore,
1391
1356
  apiClient: apiClient(),
1392
1357
  resolveAccountIndex: async (addr) => {
1393
- const apiKey = keyStore ? await keyStore.get(addr) : null
1358
+ const apiKey = await keyStore.get(addr)
1394
1359
  if (apiKey !== null) {
1395
1360
  return apiKey.accountIndex
1396
1361
  }
@@ -1407,6 +1372,52 @@ export const lighterProvider = (
1407
1372
  }
1408
1373
  }
1409
1374
 
1375
+ /**
1376
+ * Lighter mainnet provider plugin. Returns an object implementing
1377
+ * {@link PerpsProviderPlugin}, mirroring the `EthereumProvider()` /
1378
+ * `hyperliquidProvider()` shape used by the rest of the LI.FI SDK family.
1379
+ *
1380
+ * Read functions call Lighter's REST API directly with no LI.FI backend hop;
1381
+ * auth-gated reads resolve their token via the order documented on
1382
+ * {@link LighterProviderOptions}. Write actions (`WASM_BLOB` and `EVM_TX`
1383
+ * signing) are dispatched via `signActions` — `PerpsClient.execute` delegates
1384
+ * those arms here. The instance owns its WASM signer, API-key store and
1385
+ * read-only token manager.
1386
+ *
1387
+ * @example
1388
+ * ```ts
1389
+ * const client = createPerpsClient({
1390
+ * integrator: 'my-app',
1391
+ * providers: [lighterProvider()],
1392
+ * })
1393
+ * ```
1394
+ * @public
1395
+ */
1396
+ export const lighterProvider = (
1397
+ options: LighterProviderOptions = {}
1398
+ ): LighterPerpsProvider =>
1399
+ createLighterProvider(LIGHTER_MAINNET_DEPLOYMENT, options)
1400
+
1401
+ /**
1402
+ * Lighter-on-Robinhood-chain provider plugin. Same contract as
1403
+ * {@link lighterProvider}, bound to the RH deployment: its own endpoints,
1404
+ * zkLighter signing chain id, USDG collateral, and its own signer, API-key
1405
+ * store and read-only token manager. Registering both factories on one client
1406
+ * keeps their credentials and caches separate.
1407
+ *
1408
+ * @example
1409
+ * ```ts
1410
+ * const client = createPerpsClient({
1411
+ * integrator: 'my-app',
1412
+ * providers: [lighterProvider(), lighterRhProvider()],
1413
+ * })
1414
+ * ```
1415
+ * @public
1416
+ */
1417
+ export const lighterRhProvider = (
1418
+ options: LighterProviderOptions = {}
1419
+ ): LighterPerpsProvider => createLighterProvider(LIGHTER_RH_DEPLOYMENT, options)
1420
+
1410
1421
  /**
1411
1422
  * Alias matching `@lifi/sdk`'s capitalised factory naming (`EVM()`, `EthereumProvider()`).
1412
1423
  *
package/src/constants.ts CHANGED
@@ -38,11 +38,12 @@ export const DEFAULT_LIGHTER_REST_URL = 'https://mainnet.zklighter.elliot.ai'
38
38
  export const DEFAULT_LIGHTER_WS_URL = 'wss://mainnet.zklighter.elliot.ai/stream'
39
39
 
40
40
  /**
41
- * zkLighter L2 signing chain id fed to {@link LighterSigner} on mainnet.
41
+ * zkLighter L2 signing chain id for the Lighter mainnet deployment, from
42
+ * `elliottech/lighter-python` v1.1.2 `lighter/endpoint_profiles.py`.
42
43
  *
43
44
  * @public
44
45
  */
45
- export const DEFAULT_LIGHTER_SIGNER_CHAIN_ID = 304
46
+ export const LIGHTER_MAINNET_SIGNER_CHAIN_ID = 304
46
47
 
47
48
  /**
48
49
  * Base URL the mainnet Lighter zkLighter explorer resolves a tx hash against
@@ -78,29 +79,30 @@ export const LIGHTER_COLLATERAL_ASSETS: Record<
78
79
  LighterProviderKey,
79
80
  LighterCollateralAsset
80
81
  > = {
81
- [LIGHTER_PROVIDER_KEY]: {
82
+ [LIGHTER_PROVIDER_KEY]: Object.freeze({
82
83
  assetIndex: LT_ASSET_ID_USDC,
83
84
  displaySymbol: 'USDC',
84
- },
85
- [LIGHTER_RH_PROVIDER_KEY]: { assetIndex: 3, displaySymbol: 'USDG' },
85
+ }),
86
+ [LIGHTER_RH_PROVIDER_KEY]: Object.freeze({
87
+ assetIndex: 3,
88
+ displaySymbol: 'USDG',
89
+ }),
86
90
  }
87
91
 
88
92
  /**
89
- * The venue-specific facts that distinguish one Lighter deployment from
90
- * another. One provider + WS pair is built per instance from these; a client
91
- * may register several so long as their `providerKey`s differ.
93
+ * The immutable venue facts that distinguish one Lighter deployment from
94
+ * another. The SDK owns one descriptor per supported deployment; consumers
95
+ * select a deployment by picking its provider factory, never by assembling
96
+ * these fields.
92
97
  *
93
98
  * @public
94
99
  */
95
- export interface LighterInstanceConfig {
96
- /** Wire-visible `Provider.key` and the plugin `type`; unique per instance. */
100
+ export interface LighterDeployment {
101
+ /** Wire-visible `Provider.key` and the plugin `type`; unique per deployment. */
97
102
  providerKey: LighterProviderKey
98
103
  restUrl: string
99
104
  wsUrl: string
100
- /**
101
- * zkLighter L2 signing chain id to construct this instance's
102
- * {@link LighterSigner} with.
103
- */
105
+ /** zkLighter L2 signing chain id this deployment's transactions are signed against. */
104
106
  signerChainId: number
105
107
  /**
106
108
  * Collateral asset this deployment settles in — signed into its withdrawals
@@ -109,75 +111,63 @@ export interface LighterInstanceConfig {
109
111
  collateral: LighterCollateralAsset
110
112
  /**
111
113
  * Explorer tx base URL for transfer-activity links (`${base}${txHash}`).
112
- * When omitted, transfer links are not emitted for this instance.
114
+ * When omitted, transfer links are not emitted for this deployment.
113
115
  */
114
116
  explorerTxBaseUrl?: string
115
117
  }
116
118
 
117
119
  /**
118
- * The built-in mainnet Lighter instance — the defaults `lighterProvider()` and
119
- * `lighterWsProvider()` apply when constructed with no instance overrides.
120
+ * Lighter mainnet, as served by `lighterProvider()`.
120
121
  *
121
122
  * @public
122
123
  */
123
- export const LIGHTER_MAINNET_INSTANCE: LighterInstanceConfig = {
124
+ export const LIGHTER_MAINNET_DEPLOYMENT: LighterDeployment = Object.freeze({
124
125
  providerKey: LIGHTER_PROVIDER_KEY,
125
126
  restUrl: DEFAULT_LIGHTER_REST_URL,
126
127
  wsUrl: DEFAULT_LIGHTER_WS_URL,
127
- signerChainId: DEFAULT_LIGHTER_SIGNER_CHAIN_ID,
128
+ signerChainId: LIGHTER_MAINNET_SIGNER_CHAIN_ID,
128
129
  collateral: LIGHTER_COLLATERAL_ASSETS[LIGHTER_PROVIDER_KEY],
129
130
  explorerTxBaseUrl: DEFAULT_LIGHTER_EXPLORER_TX_BASE_URL,
130
- }
131
+ })
131
132
 
132
133
  /**
133
- * Default REST base URL for the Lighter Robinhood deployment.
134
+ * REST base URL for the Lighter Robinhood deployment.
134
135
  *
135
136
  * @public
136
137
  */
137
138
  export const LIGHTER_RH_REST_URL = 'https://api.rh.lighter.xyz'
138
139
  /**
139
- * Default WebSocket URL for the Lighter Robinhood deployment.
140
+ * WebSocket URL for the Lighter Robinhood deployment.
140
141
  *
141
142
  * @public
142
143
  */
143
144
  export const LIGHTER_RH_WS_URL = 'wss://api.rh.lighter.xyz/stream'
144
145
 
145
146
  /**
146
- * Deployment-supplied facts the RH instance cannot source from public
147
- * documentation and the caller must confirm.
147
+ * zkLighter L2 signing chain id for the Lighter Robinhood deployment, from
148
+ * `elliottech/lighter-python` v1.1.2 `lighter/endpoint_profiles.py`
149
+ * (`ROBINHOOD.chain_id`) and its `signer_client.py` host fallback. Distinct
150
+ * from mainnet's 304 and from Robinhood's L1 chain id 4663 — signing with
151
+ * either yields a venue-rejected transaction.
148
152
  *
149
153
  * @public
150
154
  */
151
- export interface LighterRhInstanceOverrides {
152
- /**
153
- * zkLighter L2 signing chain id for the RH instance. Unverified from public
154
- * sources — must be the value confirmed against lighter-go / RH support, not
155
- * mainnet's 304 nor the RH L1 chain id 4663.
156
- */
157
- signerChainId: number
158
- /**
159
- * RH zkLighter explorer tx base URL. Omit until confirmed; transfer links are
160
- * then left unset rather than pointed at the mainnet explorer.
161
- */
162
- explorerTxBaseUrl?: string
163
- }
155
+ export const LIGHTER_RH_SIGNER_CHAIN_ID = 466324
164
156
 
165
157
  /**
166
- * Build the `lighter-rh` {@link LighterInstanceConfig}. The signing chain id is
167
- * a required argument because it is not verifiable from public sources — the
168
- * caller must pass the value confirmed against lighter-go / RH support.
158
+ * Lighter on Robinhood chain, as served by `lighterRhProvider()`. No explorer
159
+ * base URL: the RH zkLighter explorer is unpublished, so transfer links are
160
+ * left unset rather than pointed at the mainnet explorer.
169
161
  *
170
162
  * @public
171
163
  */
172
- export const lighterRhInstance = (
173
- overrides: LighterRhInstanceOverrides
174
- ): LighterInstanceConfig => ({
164
+ export const LIGHTER_RH_DEPLOYMENT: LighterDeployment = Object.freeze({
175
165
  providerKey: LIGHTER_RH_PROVIDER_KEY,
176
166
  restUrl: LIGHTER_RH_REST_URL,
177
167
  wsUrl: LIGHTER_RH_WS_URL,
178
- signerChainId: overrides.signerChainId,
168
+ signerChainId: LIGHTER_RH_SIGNER_CHAIN_ID,
179
169
  collateral: LIGHTER_COLLATERAL_ASSETS[LIGHTER_RH_PROVIDER_KEY],
180
- explorerTxBaseUrl: overrides.explorerTxBaseUrl,
170
+ explorerTxBaseUrl: undefined,
181
171
  })
182
172
 
183
173
  /** @internal */
package/src/index.ts CHANGED
@@ -5,9 +5,9 @@
5
5
  * Lighter provider plugin for `@lifi/perps-sdk`. Serves `PerpsProvider` reads
6
6
  * directly from Lighter's REST API (no LI.FI backend hop); auth-gated reads
7
7
  * use the user's Lighter read-only token. Also owns `signActions` (the
8
- * `WASM_BLOB` / `EVM_TX` arms of `PerpsClient.execute`) — `LighterSigner`,
9
- * `LighterKeyStore`, `LighterReadOnlyTokenManager`, and the WASM blob ship
10
- * with this package.
8
+ * `WASM_BLOB` / `EVM_TX` arms of `PerpsClient.execute`): each provider
9
+ * instance creates its own WASM signer, API-key store and read-only token
10
+ * manager, and the Go signer binary ships with this package.
11
11
  *
12
12
  * @packageDocumentation
13
13
  * @public
@@ -17,32 +17,35 @@ export { projectLighterConfigSettings } from './accountConfig.js'
17
17
  export { getAccountSummary } from './accountSummary.js'
18
18
  export type {
19
19
  LighterCollateralAsset,
20
- LighterInstanceConfig,
21
- LighterRhInstanceOverrides,
20
+ LighterDeployment,
22
21
  } from './constants.js'
23
22
  export {
24
23
  DEFAULT_API_KEY_INDEX,
25
24
  DEFAULT_LIGHTER_EXPLORER_TX_BASE_URL,
26
25
  DEFAULT_LIGHTER_REST_URL,
27
- DEFAULT_LIGHTER_SIGNER_CHAIN_ID,
28
26
  DEFAULT_LIGHTER_WS_URL,
29
27
  LIGHTER_COLLATERAL_ASSETS,
30
- LIGHTER_MAINNET_INSTANCE,
28
+ LIGHTER_MAINNET_DEPLOYMENT,
29
+ LIGHTER_MAINNET_SIGNER_CHAIN_ID,
31
30
  LIGHTER_PROVIDER_KEY,
31
+ LIGHTER_RH_DEPLOYMENT,
32
32
  LIGHTER_RH_PROVIDER_KEY,
33
33
  LIGHTER_RH_REST_URL,
34
+ LIGHTER_RH_SIGNER_CHAIN_ID,
34
35
  LIGHTER_RH_WS_URL,
35
36
  LIGHTER_SPOT_CATEGORY_ID,
36
- lighterRhInstance,
37
37
  } from './constants.js'
38
38
  export { lighterDepositFlow } from './depositFlow.js'
39
39
  export type {
40
40
  LighterPerpsProvider,
41
41
  LighterProviderOptions,
42
42
  } from './LighterProvider.js'
43
- export { Lighter, lighterProvider } from './LighterProvider.js'
43
+ export {
44
+ Lighter,
45
+ lighterProvider,
46
+ lighterRhProvider,
47
+ } from './LighterProvider.js'
44
48
 
45
- export * from './signers/index.js'
46
49
  export * from './types/index.js'
47
50
  export * from './utils/index.js'
48
51
  export type { LighterAuthTokenResolver } from './websocket/LighterWsProvider.js'