@lifi/perps-sdk-provider-lighter 17.0.1 → 17.2.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 (73) hide show
  1. package/dist/cjs/LighterProvider.d.ts.map +1 -1
  2. package/dist/cjs/LighterProvider.js +1 -0
  3. package/dist/cjs/LighterProvider.js.map +1 -1
  4. package/dist/cjs/accountConfig.d.ts.map +1 -1
  5. package/dist/cjs/accountConfig.js +12 -4
  6. package/dist/cjs/accountConfig.js.map +1 -1
  7. package/dist/cjs/constants.d.ts +1 -0
  8. package/dist/cjs/constants.d.ts.map +1 -1
  9. package/dist/cjs/constants.js +2 -1
  10. package/dist/cjs/constants.js.map +1 -1
  11. package/dist/cjs/signers/LighterKeyStore.d.ts +2 -1
  12. package/dist/cjs/signers/LighterKeyStore.d.ts.map +1 -1
  13. package/dist/cjs/signers/LighterKeyStore.js +8 -6
  14. package/dist/cjs/signers/LighterKeyStore.js.map +1 -1
  15. package/dist/cjs/signers/LighterReadOnlyTokenManager.d.ts +42 -0
  16. package/dist/cjs/signers/LighterReadOnlyTokenManager.d.ts.map +1 -1
  17. package/dist/cjs/signers/LighterReadOnlyTokenManager.js +87 -6
  18. package/dist/cjs/signers/LighterReadOnlyTokenManager.js.map +1 -1
  19. package/dist/cjs/signers/signActions.d.ts.map +1 -1
  20. package/dist/cjs/signers/signActions.js +9 -5
  21. package/dist/cjs/signers/signActions.js.map +1 -1
  22. package/dist/cjs/types/fill.d.ts +2 -0
  23. package/dist/cjs/types/fill.d.ts.map +1 -1
  24. package/dist/cjs/utils/mapFill.d.ts.map +1 -1
  25. package/dist/cjs/utils/mapFill.js +8 -0
  26. package/dist/cjs/utils/mapFill.js.map +1 -1
  27. package/dist/esm/LighterProvider.d.ts.map +1 -1
  28. package/dist/esm/LighterProvider.js +1 -0
  29. package/dist/esm/LighterProvider.js.map +1 -1
  30. package/dist/esm/accountConfig.d.ts.map +1 -1
  31. package/dist/esm/accountConfig.js +29 -16
  32. package/dist/esm/accountConfig.js.map +1 -1
  33. package/dist/esm/constants.d.ts +9 -0
  34. package/dist/esm/constants.d.ts.map +1 -1
  35. package/dist/esm/constants.js +9 -0
  36. package/dist/esm/constants.js.map +1 -1
  37. package/dist/esm/signers/LighterKeyStore.d.ts +12 -4
  38. package/dist/esm/signers/LighterKeyStore.d.ts.map +1 -1
  39. package/dist/esm/signers/LighterKeyStore.js +16 -15
  40. package/dist/esm/signers/LighterKeyStore.js.map +1 -1
  41. package/dist/esm/signers/LighterReadOnlyTokenManager.d.ts +112 -12
  42. package/dist/esm/signers/LighterReadOnlyTokenManager.d.ts.map +1 -1
  43. package/dist/esm/signers/LighterReadOnlyTokenManager.js +119 -8
  44. package/dist/esm/signers/LighterReadOnlyTokenManager.js.map +1 -1
  45. package/dist/esm/signers/signActions.d.ts.map +1 -1
  46. package/dist/esm/signers/signActions.js +15 -9
  47. package/dist/esm/signers/signActions.js.map +1 -1
  48. package/dist/esm/types/fill.d.ts +2 -0
  49. package/dist/esm/types/fill.d.ts.map +1 -1
  50. package/dist/esm/utils/mapFill.d.ts.map +1 -1
  51. package/dist/esm/utils/mapFill.js +16 -1
  52. package/dist/esm/utils/mapFill.js.map +1 -1
  53. package/dist/types/LighterProvider.d.ts.map +1 -1
  54. package/dist/types/accountConfig.d.ts.map +1 -1
  55. package/dist/types/constants.d.ts +9 -0
  56. package/dist/types/constants.d.ts.map +1 -1
  57. package/dist/types/signers/LighterKeyStore.d.ts +12 -4
  58. package/dist/types/signers/LighterKeyStore.d.ts.map +1 -1
  59. package/dist/types/signers/LighterReadOnlyTokenManager.d.ts +112 -12
  60. package/dist/types/signers/LighterReadOnlyTokenManager.d.ts.map +1 -1
  61. package/dist/types/signers/signActions.d.ts.map +1 -1
  62. package/dist/types/types/fill.d.ts +2 -0
  63. package/dist/types/types/fill.d.ts.map +1 -1
  64. package/dist/types/utils/mapFill.d.ts.map +1 -1
  65. package/package.json +3 -3
  66. package/src/LighterProvider.ts +1 -0
  67. package/src/accountConfig.ts +33 -16
  68. package/src/constants.ts +10 -0
  69. package/src/signers/LighterKeyStore.ts +50 -29
  70. package/src/signers/LighterReadOnlyTokenManager.ts +245 -18
  71. package/src/signers/signActions.ts +18 -11
  72. package/src/types/fill.ts +6 -0
  73. package/src/utils/mapFill.ts +21 -1
@@ -1,17 +1,15 @@
1
1
  import { readValidatedRecord } from '@lifi/perps-sdk';
2
2
  import { LIGHTER_PROVIDER_KEY } from '../constants.js';
3
3
  // The private key here is a Lighter custom keypair — generated via WASM
4
- // GenerateAPIKey — not an Ethereum private key. The storage key is namespaced
5
- // by the resolved provider instance key so two Lighter instances sharing a
6
- // storage adapter (e.g. `lighter` and `lighter-rh`) never clobber each other's
7
- // API key.
4
+ // GenerateAPIKey — not an Ethereum private key.
8
5
  const STORAGE_PREFIX = 'lifi-perps-lighter-key';
9
- const isLighterApiKey = (value) => {
6
+ const isLighterApiKeyOf = (owner) => (value) => {
10
7
  if (typeof value !== 'object' || value === null) {
11
8
  return false;
12
9
  }
13
- const { accountIndex, apiKeyIndex, apiKeyPrivateKey, apiKeyPublicKey } = value;
14
- return (typeof accountIndex === 'number' &&
10
+ const { providerKey, accountIndex, apiKeyIndex, apiKeyPrivateKey, apiKeyPublicKey, } = value;
11
+ return (providerKey === owner &&
12
+ typeof accountIndex === 'number' &&
15
13
  Number.isFinite(accountIndex) &&
16
14
  typeof apiKeyIndex === 'number' &&
17
15
  Number.isFinite(apiKeyIndex) &&
@@ -22,8 +20,9 @@ const isLighterApiKey = (value) => {
22
20
  };
23
21
  /**
24
22
  * Storage-backed cache for Lighter API keys. Records are namespaced by L1
25
- * address and provider instance so multiple Lighter deployments can share one
26
- * {@link StorageAdapter} without collisions.
23
+ * address and provider instance, and each record names its own instance, so
24
+ * multiple Lighter deployments can share one {@link StorageAdapter} and no
25
+ * instance ever reads another instance's key material.
27
26
  *
28
27
  * @public
29
28
  */
@@ -49,8 +48,8 @@ export class LighterKeyStore {
49
48
  bindProviderKey(providerKey) {
50
49
  this.providerKey = providerKey;
51
50
  }
52
- // The default instance keeps the legacy, un-namespaced key so existing
53
- // `lighter` users are not orphaned; only additional instances get a segment.
51
+ // The default instance keeps the legacy, un-namespaced slot name; only
52
+ // additional instances get a segment.
54
53
  storageKey(address) {
55
54
  const lower = address.toLowerCase();
56
55
  return this.providerKey === LIGHTER_PROVIDER_KEY
@@ -67,7 +66,7 @@ export class LighterKeyStore {
67
66
  if (cached) {
68
67
  return cached;
69
68
  }
70
- const parsed = await readValidatedRecord(this.storage, key, isLighterApiKey);
69
+ const parsed = await readValidatedRecord(this.storage, key, isLighterApiKeyOf(this.providerKey));
71
70
  if (!parsed) {
72
71
  return null;
73
72
  }
@@ -76,12 +75,14 @@ export class LighterKeyStore {
76
75
  }
77
76
  /**
78
77
  * Persist an API key for an L1 address, replacing any existing record under
79
- * that provider namespace.
78
+ * that provider namespace. The store stamps the record with its own instance
79
+ * key, so callers never name the instance themselves.
80
80
  */
81
81
  async set(address, value) {
82
82
  const key = this.storageKey(address);
83
- this.cache.set(key, value);
84
- await this.storage.set(key, JSON.stringify(value));
83
+ const record = { ...value, providerKey: this.providerKey };
84
+ this.cache.set(key, record);
85
+ await this.storage.set(key, JSON.stringify(record));
85
86
  }
86
87
  /**
87
88
  * Remove the persisted API key for an L1 address and clear its in-memory
@@ -1 +1 @@
1
- {"version":3,"file":"LighterKeyStore.js","sourceRoot":"","sources":["../../../src/signers/LighterKeyStore.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LighterKeyStore.js","sourceRoot":"","sources":["../../../src/signers/LighterKeyStore.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ import type { Address } from 'viem';
5
5
  * Default token name persisted alongside Lighter's `tokens/create` row.
6
6
  * Lighter requires a non-empty `name` form field; the literal here is what
7
7
  * surfaces in Lighter's UI listing under `app.lighter.xyz/read-only-tokens`.
8
- * @public
8
+ * @internal
9
9
  */
10
10
  export declare const DEFAULT_READ_ONLY_TOKEN_NAME = "LI.FI Perps";
11
11
  /**
@@ -13,7 +13,7 @@ export declare const DEFAULT_READ_ONLY_TOKEN_NAME = "LI.FI Perps";
13
13
  * Lighter's opaque `ro:{accountIndex}:{scope}:{expiry}:{rand}` bearer; the
14
14
  * SDK never parses it — `expiry`/`scope`/`accountIndex` are create-time inputs
15
15
  * we keep alongside so consumers can render expiry UX without re-fetching.
16
- * @public
16
+ * @internal
17
17
  */
18
18
  export interface LighterReadOnlyToken {
19
19
  /** Opaque bearer string — never parse client-side. */
@@ -24,25 +24,33 @@ export interface LighterReadOnlyToken {
24
24
  scope: 'single' | 'all';
25
25
  /** Lighter L2 account index the token authorises. */
26
26
  accountIndex: number;
27
+ /**
28
+ * Lighter's monotonic registry row id. Optional: a record persisted without
29
+ * it stays valid, and the cleanup pass then identifies its row by the
30
+ * bearer string instead.
31
+ */
32
+ tokenId?: number;
27
33
  }
28
34
  /**
29
- * Lighter `POST /api/v1/tokens/create` response shape (subset). Lighter's
30
- * OpenAPI documents additional fields (`token_id`, `name`, `revoked`, etc.)
31
- * we don't need client-side.
32
- * @public
35
+ * Lighter `POST /api/v1/tokens/create` response shape — the subset of
36
+ * Lighter's `RespPostApiToken` the SDK consumes. Lighter documents further
37
+ * fields (`name`, `revoked`, `sub_account_access`) the SDK does not need.
38
+ * @internal
33
39
  */
34
40
  export interface LighterCreateTokenResponse {
35
41
  api_token: string;
36
42
  account_index: number;
37
43
  expiry: number;
38
44
  scopes: string;
45
+ /** Monotonic registry row id Lighter assigns to the new row. */
46
+ token_id: number;
39
47
  }
40
48
  /**
41
49
  * Function injected for the HTTP boundary against Lighter's `tokens/create`
42
50
  * endpoint. Returning a parsed {@link LighterCreateTokenResponse} keeps the
43
51
  * create code free of fetch/multipart plumbing and lets tests drop a fixture
44
52
  * in without spinning a mock server.
45
- * @public
53
+ * @internal
46
54
  */
47
55
  export type LighterTokenFetcher = (params: {
48
56
  url: string;
@@ -53,12 +61,71 @@ export type LighterTokenFetcher = (params: {
53
61
  subAccountAccess: boolean;
54
62
  scopes: string;
55
63
  }) => Promise<LighterCreateTokenResponse>;
64
+ /**
65
+ * One row of Lighter's read-only token registry, matching Lighter's
66
+ * `ApiToken`. `name` carries the label supplied at create time, which is how
67
+ * the SDK recognises a row it owns.
68
+ * @internal
69
+ */
70
+ export interface LighterApiToken {
71
+ token_id: number;
72
+ api_token: string;
73
+ name: string;
74
+ account_index: number;
75
+ expiry: number;
76
+ sub_account_access: boolean;
77
+ revoked: boolean;
78
+ scopes: string;
79
+ }
80
+ /**
81
+ * Lighter `GET /api/v1/tokens` response shape, matching `RespGetApiTokens`.
82
+ * @internal
83
+ */
84
+ export interface LighterListTokensResponse {
85
+ code: number;
86
+ message?: string;
87
+ api_tokens: LighterApiToken[];
88
+ }
89
+ /**
90
+ * Lighter `POST /api/v1/tokens/revoke` response shape, matching Lighter's
91
+ * `RespRevokeApiToken`.
92
+ * @internal
93
+ */
94
+ export interface LighterRevokeTokenResponse {
95
+ code: number;
96
+ message?: string;
97
+ token_id: number;
98
+ revoked: boolean;
99
+ }
100
+ /**
101
+ * Function injected for the HTTP boundary against Lighter's
102
+ * `GET /api/v1/tokens` endpoint. Injected for the same reason as
103
+ * {@link LighterTokenFetcher}: a unit spec supplies a registry fixture
104
+ * without a mock server.
105
+ * @internal
106
+ */
107
+ export type LighterTokenListFetcher = (params: {
108
+ url: string;
109
+ authorization: string;
110
+ accountIndex: number;
111
+ }) => Promise<LighterListTokensResponse>;
112
+ /**
113
+ * Function injected for the HTTP boundary against Lighter's
114
+ * `POST /api/v1/tokens/revoke` endpoint.
115
+ * @internal
116
+ */
117
+ export type LighterTokenRevokeFetcher = (params: {
118
+ url: string;
119
+ authorization: string;
120
+ tokenId: number;
121
+ accountIndex: number;
122
+ }) => Promise<LighterRevokeTokenResponse>;
56
123
  /**
57
124
  * Dependencies and overrides for {@link LighterReadOnlyTokenManager}.
58
125
  * Storage and token-fetching defaults target the browser's local storage and
59
126
  * Lighter's mainnet REST API.
60
127
  *
61
- * @public
128
+ * @internal
62
129
  */
63
130
  export interface LighterReadOnlyTokenManagerOptions {
64
131
  storage?: StorageAdapter;
@@ -73,6 +140,10 @@ export interface LighterReadOnlyTokenManagerOptions {
73
140
  lighterApiUrl?: string;
74
141
  /** Override the multipart POST. Defaults to a `fetch`-based implementation. */
75
142
  fetcher?: LighterTokenFetcher;
143
+ /** Override the registry list GET. Defaults to a `fetch`-based implementation. */
144
+ listFetcher?: LighterTokenListFetcher;
145
+ /** Override the revoke POST. Defaults to a `fetch`-based implementation. */
146
+ revokeFetcher?: LighterTokenRevokeFetcher;
76
147
  /** Clock injection for testing expiry logic. Defaults to `Date.now`. */
77
148
  now?: () => number;
78
149
  }
@@ -80,7 +151,7 @@ export interface LighterReadOnlyTokenManagerOptions {
80
151
  * Input to the read-only-token approval flow. Extends the shared approval
81
152
  * parameters with the L1 address whose wallet authorizes token creation.
82
153
  *
83
- * @public
154
+ * @internal
84
155
  */
85
156
  export interface ApproveReadOnlyTokenInputs extends ApproveReadOnlyTokenParams {
86
157
  /** L1 wallet address that signs the create message. */
@@ -90,7 +161,7 @@ export interface ApproveReadOnlyTokenInputs extends ApproveReadOnlyTokenParams {
90
161
  * Result of approving or creating a Lighter read-only token. `config` is the
91
162
  * account-state projection callers can persist alongside the token.
92
163
  *
93
- * @public
164
+ * @internal
94
165
  */
95
166
  export interface ApproveReadOnlyTokenResult {
96
167
  token: LighterReadOnlyToken;
@@ -114,18 +185,22 @@ export interface ApproveReadOnlyTokenResult {
114
185
  * a fully compromised page — a same-origin script can still drive this manager
115
186
  * to decrypt. Blast radius is limited to reads: the token cannot sign orders
116
187
  * or move funds.
117
- * @public
188
+ * @internal
118
189
  */
119
190
  export declare class LighterReadOnlyTokenManager {
120
191
  private readonly storage;
121
192
  private readonly providerKey;
122
193
  private readonly lighterApiUrl;
123
194
  private readonly fetcher;
195
+ private readonly listFetcher;
196
+ private readonly revokeFetcher;
124
197
  private readonly now;
125
198
  private readonly cache;
126
199
  constructor(options?: LighterReadOnlyTokenManagerOptions);
127
200
  private storageKey;
128
201
  private isExpired;
202
+ /** Stored record for the pair, whether or not it is past its `expiry`. */
203
+ private readStoredToken;
129
204
  /**
130
205
  * Return the stored token for the `(address, accountIndex)` pair, or
131
206
  * `undefined` if absent or past its `expiry`. Never surfaces an expired
@@ -157,6 +232,9 @@ export declare class LighterReadOnlyTokenManager {
157
232
  * and persists the returned `ro:` bearer alongside its
158
233
  * `expiry`/`scope`/`accountIndex`.
159
234
  *
235
+ * Before the create call, the flow revokes this SDK's own stale registry
236
+ * rows. That pass is best-effort: a failure is logged and the create runs.
237
+ *
160
238
  * `authorization` MUST be a **standard** Lighter auth token — one created by
161
239
  * the account's API key (`createAuthToken` / the WASM signer), NOT an L1
162
240
  * wallet signature. Lighter authenticates the create request with that token
@@ -175,13 +253,35 @@ export declare class LighterReadOnlyTokenManager {
175
253
  * @param inputs Token-create parameters plus the owning `address`.
176
254
  */
177
255
  approve(authorization: string, inputs: ApproveReadOnlyTokenInputs): Promise<ApproveReadOnlyTokenResult>;
256
+ /**
257
+ * Revoke the registry rows this SDK owns and no longer needs. Lighter's
258
+ * `tokens/create` appends a row on every call, so without this pass the
259
+ * user's registry grows on every rotation.
260
+ */
261
+ private revokeStaleOwnTokens;
178
262
  }
179
263
  /**
180
264
  * Default fetcher: posts a multipart/form-data request to Lighter's
181
265
  * `tokens/create` endpoint and returns the parsed response. Throws a
182
266
  * {@link PerpsError} with the Lighter-side body when the response is
183
267
  * non-2xx.
184
- * @public
268
+ * @internal
185
269
  */
186
270
  export declare const defaultLighterTokenFetcher: LighterTokenFetcher;
271
+ /**
272
+ * Default list fetcher: `GET /api/v1/tokens` with `account_index` as a query
273
+ * parameter. Lighter's OpenAPI defines no request body for this route. Throws
274
+ * a {@link PerpsError} with the Lighter-side body when the response is
275
+ * non-2xx.
276
+ * @internal
277
+ */
278
+ export declare const defaultLighterTokenListFetcher: LighterTokenListFetcher;
279
+ /**
280
+ * Default revoke fetcher: posts `application/x-www-form-urlencoded` to
281
+ * Lighter's `tokens/revoke` endpoint, which is the content type Lighter's
282
+ * OpenAPI declares for that route. Throws a {@link PerpsError} with the
283
+ * Lighter-side body when the response is non-2xx.
284
+ * @internal
285
+ */
286
+ export declare const defaultLighterTokenRevokeFetcher: LighterTokenRevokeFetcher;
187
287
  //# sourceMappingURL=LighterReadOnlyTokenManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LighterReadOnlyTokenManager.d.ts","sourceRoot":"","sources":["../../../src/signers/LighterReadOnlyTokenManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LighterReadOnlyTokenManager.d.ts","sourceRoot":"","sources":["../../../src/signers/LighterReadOnlyTokenManager.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ import { DEFAULT_LIGHTER_REST_URL, LIGHTER_PROVIDER_KEY } from '../constants.js'
5
5
  * Default token name persisted alongside Lighter's `tokens/create` row.
6
6
  * Lighter requires a non-empty `name` form field; the literal here is what
7
7
  * surfaces in Lighter's UI listing under `app.lighter.xyz/read-only-tokens`.
8
- * @public
8
+ * @internal
9
9
  */
10
10
  export const DEFAULT_READ_ONLY_TOKEN_NAME = 'LI.FI Perps';
11
11
  const SECONDS_PER_DAY = 86_400;
@@ -13,15 +13,21 @@ const isLighterReadOnlyToken = (value) => {
13
13
  if (typeof value !== 'object' || value === null) {
14
14
  return false;
15
15
  }
16
- const { token, expiry, scope, accountIndex } = value;
16
+ const { token, expiry, scope, accountIndex, tokenId } = value;
17
+ // Accept a record that carries no `tokenId`: rejecting one would discard a
18
+ // usable token and force an unnecessary replacement.
17
19
  return (typeof token === 'string' &&
18
20
  token.length > 0 &&
19
21
  typeof expiry === 'number' &&
20
22
  Number.isFinite(expiry) &&
21
23
  (scope === 'single' || scope === 'all') &&
22
24
  typeof accountIndex === 'number' &&
23
- Number.isFinite(accountIndex));
25
+ Number.isFinite(accountIndex) &&
26
+ (tokenId === undefined ||
27
+ (typeof tokenId === 'number' && Number.isFinite(tokenId))));
24
28
  };
29
+ const isLiveRow = (row, live) => live !== undefined &&
30
+ (row.token_id === live.tokenId || row.api_token === live.token);
25
31
  /**
26
32
  * Manage the per-account Lighter read-only token alongside the existing
27
33
  * `(L1 address, account index)`-scoped storage adapter pattern. Takes an
@@ -39,13 +45,15 @@ const isLighterReadOnlyToken = (value) => {
39
45
  * a fully compromised page — a same-origin script can still drive this manager
40
46
  * to decrypt. Blast radius is limited to reads: the token cannot sign orders
41
47
  * or move funds.
42
- * @public
48
+ * @internal
43
49
  */
44
50
  export class LighterReadOnlyTokenManager {
45
51
  storage;
46
52
  providerKey;
47
53
  lighterApiUrl;
48
54
  fetcher;
55
+ listFetcher;
56
+ revokeFetcher;
49
57
  now;
50
58
  cache = new Map();
51
59
  constructor(options = {}) {
@@ -53,6 +61,9 @@ export class LighterReadOnlyTokenManager {
53
61
  this.providerKey = options.providerKey ?? LIGHTER_PROVIDER_KEY;
54
62
  this.lighterApiUrl = options.lighterApiUrl ?? DEFAULT_LIGHTER_REST_URL;
55
63
  this.fetcher = options.fetcher ?? defaultLighterTokenFetcher;
64
+ this.listFetcher = options.listFetcher ?? defaultLighterTokenListFetcher;
65
+ this.revokeFetcher =
66
+ options.revokeFetcher ?? defaultLighterTokenRevokeFetcher;
56
67
  this.now = options.now ?? (() => Date.now());
57
68
  }
58
69
  storageKey(address, accountIndex) {
@@ -61,6 +72,13 @@ export class LighterReadOnlyTokenManager {
61
72
  isExpired(token) {
62
73
  return token.expiry * 1000 <= this.now();
63
74
  }
75
+ /** Stored record for the pair, whether or not it is past its `expiry`. */
76
+ async readStoredToken(address, accountIndex) {
77
+ const key = this.storageKey(address, accountIndex);
78
+ return (this.cache.get(key) ??
79
+ (await readValidatedRecord(this.storage, key, isLighterReadOnlyToken)) ??
80
+ undefined);
81
+ }
64
82
  /**
65
83
  * Return the stored token for the `(address, accountIndex)` pair, or
66
84
  * `undefined` if absent or past its `expiry`. Never surfaces an expired
@@ -86,9 +104,7 @@ export class LighterReadOnlyTokenManager {
86
104
  * has more than `thresholdDays` of life left.
87
105
  */
88
106
  async isReadOnlyTokenExpiringSoon(address, accountIndex, thresholdDays = 30) {
89
- const key = this.storageKey(address, accountIndex);
90
- const token = this.cache.get(key) ??
91
- (await readValidatedRecord(this.storage, key, isLighterReadOnlyToken));
107
+ const token = await this.readStoredToken(address, accountIndex);
92
108
  if (!token) {
93
109
  return false;
94
110
  }
@@ -124,6 +140,9 @@ export class LighterReadOnlyTokenManager {
124
140
  * and persists the returned `ro:` bearer alongside its
125
141
  * `expiry`/`scope`/`accountIndex`.
126
142
  *
143
+ * Before the create call, the flow revokes this SDK's own stale registry
144
+ * rows. That pass is best-effort: a failure is logged and the create runs.
145
+ *
127
146
  * `authorization` MUST be a **standard** Lighter auth token — one created by
128
147
  * the account's API key (`createAuthToken` / the WASM signer), NOT an L1
129
148
  * wallet signature. Lighter authenticates the create request with that token
@@ -143,6 +162,7 @@ export class LighterReadOnlyTokenManager {
143
162
  */
144
163
  async approve(authorization, inputs) {
145
164
  const { address, accountIndex, expirySeconds, scope } = inputs;
165
+ await this.revokeStaleOwnTokens(authorization, address, accountIndex);
146
166
  const response = await this.fetcher({
147
167
  url: `${this.lighterApiUrl}/api/v1/tokens/create`,
148
168
  authorization,
@@ -160,6 +180,12 @@ export class LighterReadOnlyTokenManager {
160
180
  // `get()` looks up by, else a divergent echo orphans the token and re-creates every read.
161
181
  scope,
162
182
  accountIndex,
183
+ // Lighter declares `token_id` required but the response is unvalidated.
184
+ // A non-numeric id must degrade to the bearer-string match: persisting it
185
+ // would fail record validation and re-create the token on every read.
186
+ tokenId: Number.isFinite(response.token_id)
187
+ ? response.token_id
188
+ : undefined,
163
189
  };
164
190
  await this.set(address, token.accountIndex, token);
165
191
  return {
@@ -173,13 +199,54 @@ export class LighterReadOnlyTokenManager {
173
199
  },
174
200
  };
175
201
  }
202
+ /**
203
+ * Revoke the registry rows this SDK owns and no longer needs. Lighter's
204
+ * `tokens/create` appends a row on every call, so without this pass the
205
+ * user's registry grows on every rotation.
206
+ */
207
+ async revokeStaleOwnTokens(authorization, address, accountIndex) {
208
+ try {
209
+ const live = await this.readStoredToken(address, accountIndex);
210
+ const { api_tokens: rows } = await this.listFetcher({
211
+ url: `${this.lighterApiUrl}/api/v1/tokens`,
212
+ authorization,
213
+ accountIndex,
214
+ });
215
+ const nowSeconds = Math.floor(this.now() / 1000);
216
+ const stale = rows
217
+ // A row is ours only when its name matches the name we create rows
218
+ // under. Any other name belongs to the user and must survive.
219
+ .filter((row) => row.name === DEFAULT_READ_ONLY_TOKEN_NAME)
220
+ .filter((row) => !row.revoked)
221
+ // Keep the row the local store holds; with no stored record every owned
222
+ // row is stale, and a peer client's row self-heals via `retryOnRevoked`.
223
+ .filter((row) => row.expiry <= nowSeconds || !isLiveRow(row, live))
224
+ .sort((a, b) => a.token_id - b.token_id);
225
+ for (const row of stale) {
226
+ try {
227
+ await this.revokeFetcher({
228
+ url: `${this.lighterApiUrl}/api/v1/tokens/revoke`,
229
+ authorization,
230
+ tokenId: row.token_id,
231
+ accountIndex,
232
+ });
233
+ }
234
+ catch (err) {
235
+ console.warn(`[lighter] could not revoke stale read-only token ${row.token_id}; continuing.`, err);
236
+ }
237
+ }
238
+ }
239
+ catch (err) {
240
+ console.warn('[lighter] could not clean up stale read-only tokens; creating the new one anyway.', err);
241
+ }
242
+ }
176
243
  }
177
244
  /**
178
245
  * Default fetcher: posts a multipart/form-data request to Lighter's
179
246
  * `tokens/create` endpoint and returns the parsed response. Throws a
180
247
  * {@link PerpsError} with the Lighter-side body when the response is
181
248
  * non-2xx.
182
- * @public
249
+ * @internal
183
250
  */
184
251
  export const defaultLighterTokenFetcher = async ({ url, authorization, name, accountIndex, expiry, subAccountAccess, scopes, }) => {
185
252
  const form = new FormData();
@@ -199,4 +266,48 @@ export const defaultLighterTokenFetcher = async ({ url, authorization, name, acc
199
266
  }
200
267
  return (await response.json());
201
268
  };
269
+ /**
270
+ * Default list fetcher: `GET /api/v1/tokens` with `account_index` as a query
271
+ * parameter. Lighter's OpenAPI defines no request body for this route. Throws
272
+ * a {@link PerpsError} with the Lighter-side body when the response is
273
+ * non-2xx.
274
+ * @internal
275
+ */
276
+ export const defaultLighterTokenListFetcher = async ({ url, authorization, accountIndex, }) => {
277
+ const query = new URLSearchParams({ account_index: String(accountIndex) });
278
+ const response = await fetch(`${url}?${query.toString()}`, {
279
+ headers: { authorization },
280
+ });
281
+ if (!response.ok) {
282
+ const body = await response.text();
283
+ throw new PerpsError(PerpsErrorCode.ServerError, `Lighter tokens returned ${response.status}: ${body || '<empty>'}`);
284
+ }
285
+ return (await response.json());
286
+ };
287
+ /**
288
+ * Default revoke fetcher: posts `application/x-www-form-urlencoded` to
289
+ * Lighter's `tokens/revoke` endpoint, which is the content type Lighter's
290
+ * OpenAPI declares for that route. Throws a {@link PerpsError} with the
291
+ * Lighter-side body when the response is non-2xx.
292
+ * @internal
293
+ */
294
+ export const defaultLighterTokenRevokeFetcher = async ({ url, authorization, tokenId, accountIndex }) => {
295
+ const form = new URLSearchParams({
296
+ token_id: String(tokenId),
297
+ account_index: String(accountIndex),
298
+ });
299
+ const response = await fetch(url, {
300
+ method: 'POST',
301
+ headers: {
302
+ authorization,
303
+ 'content-type': 'application/x-www-form-urlencoded',
304
+ },
305
+ body: form,
306
+ });
307
+ if (!response.ok) {
308
+ const body = await response.text();
309
+ throw new PerpsError(PerpsErrorCode.ServerError, `Lighter tokens/revoke returned ${response.status}: ${body || '<empty>'}`);
310
+ }
311
+ return (await response.json());
312
+ };
202
313
  //# sourceMappingURL=LighterReadOnlyTokenManager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LighterReadOnlyTokenManager.js","sourceRoot":"","sources":["../../../src/signers/LighterReadOnlyTokenManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LighterReadOnlyTokenManager.js","sourceRoot":"","sources":["../../../src/signers/LighterReadOnlyTokenManager.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"signActions.d.ts","sourceRoot":"","sources":["../../../src/signers/signActions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACrE,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAA8B,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAInC,OAAO,KAAK,EAAa,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAMxE,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC1E,OAAO,KAAK,EAEV,aAAa,EAEd,MAAM,oBAAoB,CAAA;AAE3B;;;;;;;;GAQG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,aAAa,CAAA;IACrB,QAAQ,EAAE,eAAe,CAAA;IACzB;;qCAEiC;IACjC,SAAS,EAAE,gBAAgB,CAAA;IAC3B;;;OAGG;IACH,eAAe,EAAE,sBAAsB,CAAA;IACvC;;;;;OAKG;IACH,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACvD;AAyBD;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,qBAAqB,CACnB,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAAA;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,QAAO,sBAqD/C,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,sBAAsB,EAC5B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,kBAAkB,EAAE,EAC3B,GAAG,EAAE,kBAAkB,GAAG,SAAS,GAClC,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAkCrC;AAsUD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,eAAe,EAAE,EACxB,GAAG,EAAE,kBAAkB,GAAG,SAAS,GAClC,OAAO,CAAC,qBAAqB,EAAE,CAAC,CA6ElC;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,sBAAsB,EAC5B,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,UAAU,EAAE,EACnB,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,kBAAkB,GACvB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAsB7B"}
1
+ {"version":3,"file":"signActions.d.ts","sourceRoot":"","sources":["../../../src/signers/signActions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACrE,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAA8B,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAInC,OAAO,KAAK,EAAa,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAMxE,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC1E,OAAO,KAAK,EAEV,aAAa,EAEd,MAAM,oBAAoB,CAAA;AAE3B;;;;;;;;GAQG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,aAAa,CAAA;IACrB,QAAQ,EAAE,eAAe,CAAA;IACzB;;qCAEiC;IACjC,SAAS,EAAE,gBAAgB,CAAA;IAC3B;;;OAGG;IACH,eAAe,EAAE,sBAAsB,CAAA;IACvC;;;;;OAKG;IACH,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACvD;AAyBD;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,qBAAqB,CACnB,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAAA;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,QAAO,sBA6D/C,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,sBAAsB,EAC5B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,kBAAkB,EAAE,EAC3B,GAAG,EAAE,kBAAkB,GAAG,SAAS,GAClC,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAkCrC;AAqUD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,eAAe,EAAE,EACxB,GAAG,EAAE,kBAAkB,GAAG,SAAS,GAClC,OAAO,CAAC,qBAAqB,EAAE,CAAC,CA6ElC;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,sBAAsB,EAC5B,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,UAAU,EAAE,EACnB,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,kBAAkB,GACvB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAsB7B"}
@@ -12,7 +12,7 @@ import { fetchRegisteredApiKey, normalizeLighterPublicKey, } from '../utils/regi
12
12
  */
13
13
  const TOKEN_AUTH_MUTATION_KINDS = new Set(['changeAccountTier', 'referralUse']);
14
14
  /**
15
- * Lifetime of the per-call auth token minted for a token-authenticated venue
15
+ * Lifetime of the per-call auth token issued for a token-authenticated venue
16
16
  * mutation. Minutes, not the read endpoints' hours: it authenticates one POST
17
17
  * that completes immediately, so it never lingers usable.
18
18
  */
@@ -55,15 +55,22 @@ export const createLighterApiKeyFreshness = () => {
55
55
  checkedAtMs.set(windowKey, Date.now());
56
56
  return;
57
57
  }
58
- // A slot carrying no entry leaves nothing to compare against.
59
- if (registered !== undefined &&
60
- normalizeLighterPublicKey(registered.public_key) !== storedKey) {
58
+ // An answered read that names no entry is a verdict, not a gap: the slot
59
+ // holds no key the stored one can match, so a signature it produces
60
+ // cannot verify.
61
+ if (registered === undefined) {
62
+ throw new PerpsError(PerpsErrorCode.SDKError, `The Lighter API key stored for ${address} is not registered: ` +
63
+ `account ${apiKey.accountIndex} holds no key in API-key slot ` +
64
+ `${apiKey.apiKeyIndex}. Run prepareAccount / REGISTER_API_KEY to ` +
65
+ 'register a fresh key.');
66
+ }
67
+ if (normalizeLighterPublicKey(registered.public_key) !== storedKey) {
61
68
  throw new PerpsError(PerpsErrorCode.SDKError, `The Lighter API key stored for ${address} is no longer registered: ` +
62
69
  `API-key slot ${apiKey.apiKeyIndex} now holds a different key. ` +
63
70
  'Run prepareAccount / REGISTER_API_KEY to register a fresh key.');
64
71
  }
65
72
  // Every read the venue answered counts against the window, so a burst
66
- // costs one read whatever the verdict. A mismatch throws above, so it
73
+ // costs one read whatever the verdict. A rejection throws above, so it
67
74
  // never records and the next batch reads again.
68
75
  checkedAtMs.set(windowKey, Date.now());
69
76
  },
@@ -161,13 +168,12 @@ async function signRegisterApiKey(deps, address, step, ctx) {
161
168
  message: changePubKey.messageToSign,
162
169
  });
163
170
  const txInfoWithL1Sig = deps.signer.embedL1Signature(changePubKey.txInfo, l1Signature);
164
- const apiKey = {
171
+ await deps.keyStore.set(address, {
165
172
  accountIndex,
166
173
  apiKeyIndex,
167
174
  apiKeyPrivateKey: keypair.privateKey,
168
175
  apiKeyPublicKey: keypair.publicKey,
169
- };
170
- await deps.keyStore.set(address, apiKey);
176
+ });
171
177
  return {
172
178
  action: step.action,
173
179
  wasmSignParams: {
@@ -246,7 +252,7 @@ async function signTransfer(deps, address, step, ctx) {
246
252
  *
247
253
  * Neither endpoint consumes a wasm-signed transaction — both authenticate with
248
254
  * a Lighter auth token and enforce their business rules (open positions,
249
- * pending orders, 24h tier cooldown) server-side. We mint a fresh short-lived
255
+ * pending orders, 24h tier cooldown) server-side. We create a fresh short-lived
250
256
  * token per call (never the stored read-only token, never persisted) and POST
251
257
  * the mirror of the backend's form body directly to Lighter, so no auth token
252
258
  * ever transits the LI.FI backend. A non-success verdict surfaces Lighter's