@luxexchange/sessions 1.0.2 → 1.0.3

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 (54) hide show
  1. package/.depcheckrc +20 -0
  2. package/.eslintrc.js +21 -0
  3. package/README.md +1 -0
  4. package/env.d.ts +12 -0
  5. package/package.json +3 -4
  6. package/project.json +1 -7
  7. package/src/challenge-solvers/createChallengeSolverService.ts +2 -2
  8. package/src/challenge-solvers/createHashcashMockSolver.ts +2 -2
  9. package/src/challenge-solvers/createHashcashSolver.test.ts +6 -6
  10. package/src/challenge-solvers/createHashcashSolver.ts +18 -3
  11. package/src/challenge-solvers/createNoneMockSolver.ts +1 -1
  12. package/src/challenge-solvers/createTurnstileMockSolver.ts +2 -2
  13. package/src/challenge-solvers/createTurnstileSolver.ts +9 -5
  14. package/src/challenge-solvers/hashcash/core.native.ts +1 -1
  15. package/src/challenge-solvers/hashcash/core.test.ts +10 -10
  16. package/src/challenge-solvers/hashcash/core.ts +1 -1
  17. package/src/challenge-solvers/hashcash/createWorkerHashcashSolver.test.ts +4 -4
  18. package/src/challenge-solvers/hashcash/worker/createHashcashMultiWorkerChannel.native.ts +1 -1
  19. package/src/challenge-solvers/hashcash/worker/createHashcashMultiWorkerChannel.ts +1 -1
  20. package/src/challenge-solvers/hashcash/worker/createHashcashWorkerChannel.native.ts +1 -1
  21. package/src/challenge-solvers/hashcash/worker/createHashcashWorkerChannel.ts +1 -1
  22. package/src/challenge-solvers/hashcash/worker/hashcash.worker.ts +3 -3
  23. package/src/challenge-solvers/turnstileSolver.integration.test.ts +1 -1
  24. package/src/challengeFlow.integration.test.ts +41 -41
  25. package/src/device-id/createDeviceIdService.ts +1 -1
  26. package/src/index.ts +8 -6
  27. package/src/oauth-service/types.ts +1 -1
  28. package/src/session-initialization/createSessionInitializationService.ts +29 -38
  29. package/src/session-repository/createSessionClient.ts +1 -1
  30. package/src/session-repository/createSessionRepository.test.ts +2 -2
  31. package/src/session-repository/createSessionRepository.ts +11 -11
  32. package/src/session-repository/types.ts +1 -1
  33. package/src/session-service/createNoopSessionService.ts +2 -2
  34. package/src/session-service/createSessionService.test.ts +29 -29
  35. package/src/session-service/createSessionService.ts +4 -4
  36. package/src/session-service/types.ts +1 -1
  37. package/src/session-storage/createSessionStorage.ts +1 -1
  38. package/src/session.integration.test.ts +116 -80
  39. package/src/sessionLifecycle.integration.test.ts +22 -22
  40. package/src/test-utils/createLocalCookieTransport.ts +1 -1
  41. package/src/test-utils/createLocalHeaderTransport.ts +1 -1
  42. package/src/test-utils/mocks.ts +3 -3
  43. package/src/test-utils.ts +24 -24
  44. package/src/uniswap-identifier/createUniswapIdentifierService.ts +19 -0
  45. package/src/uniswap-identifier/types.ts +11 -0
  46. package/src/uniswap-identifier/uniswapIdentifierQuery.ts +20 -0
  47. package/tsconfig.json +10 -3
  48. package/tsconfig.lint.json +8 -0
  49. package/tsconfig.spec.json +8 -0
  50. package/vitest.config.ts +20 -0
  51. package/vitest.integration.config.ts +14 -0
  52. package/src/lux-identifier/createLuxIdentifierService.ts +0 -19
  53. package/src/lux-identifier/luxIdentifierQuery.ts +0 -20
  54. package/src/lux-identifier/types.ts +0 -11
@@ -1,16 +1,16 @@
1
- import type { DeviceIdService } from '@luxfi/sessions/src/device-id/types'
2
- import type { SessionRepository } from '@luxfi/sessions/src/session-repository/types'
3
- import { createSessionService } from '@luxfi/sessions/src/session-service/createSessionService'
4
- import type { SessionService } from '@luxfi/sessions/src/session-service/types'
5
- import type { SessionStorage } from '@luxfi/sessions/src/session-storage/types'
6
- import type { LuxIdentifierService } from '@luxfi/sessions/src/lux-identifier/types'
1
+ import type { DeviceIdService } from '@luxexchange/sessions/src/device-id/types'
2
+ import type { SessionRepository } from '@luxexchange/sessions/src/session-repository/types'
3
+ import { createSessionService } from '@luxexchange/sessions/src/session-service/createSessionService'
4
+ import type { SessionService } from '@luxexchange/sessions/src/session-service/types'
5
+ import type { SessionStorage } from '@luxexchange/sessions/src/session-storage/types'
6
+ import type { LxIdentifierService } from '@luxexchange/sessions/src/uniswap-identifier/types'
7
7
  import { beforeEach, describe, expect, it, vi } from 'vitest'
8
8
 
9
9
  describe('createSessionService', () => {
10
10
  let storage: SessionStorage
11
11
  let repository: SessionRepository
12
12
  let deviceIdService: DeviceIdService
13
- let luxIdentifierService: LuxIdentifierService
13
+ let lxIdentifierService: LxIdentifierService
14
14
  let service: SessionService
15
15
 
16
16
  beforeEach(() => {
@@ -37,14 +37,14 @@ describe('createSessionService', () => {
37
37
  },
38
38
  }
39
39
 
40
- let luxIdentifierData: string | null = null
41
- luxIdentifierService = {
42
- getLuxIdentifier: async (): Promise<string | null> => luxIdentifierData,
43
- setLuxIdentifier: async (identifier: string): Promise<void> => {
44
- luxIdentifierData = identifier
40
+ let lxIdentifierData: string | null = null
41
+ lxIdentifierService = {
42
+ getLxIdentifier: async (): Promise<string | null> => lxIdentifierData,
43
+ setLxIdentifier: async (identifier: string): Promise<void> => {
44
+ lxIdentifierData = identifier
45
45
  },
46
- removeLuxIdentifier: async (): Promise<void> => {
47
- luxIdentifierData = null
46
+ removeLxIdentifier: async (): Promise<void> => {
47
+ lxIdentifierData = null
48
48
  },
49
49
  }
50
50
 
@@ -68,7 +68,7 @@ describe('createSessionService', () => {
68
68
  sessionStorage: storage,
69
69
  sessionRepository: repository,
70
70
  deviceIdService,
71
- luxIdentifierService,
71
+ lxIdentifierService,
72
72
  })
73
73
  })
74
74
 
@@ -103,7 +103,7 @@ describe('createSessionService', () => {
103
103
  sessionStorage: storage,
104
104
  sessionRepository: repository,
105
105
  deviceIdService,
106
- luxIdentifierService,
106
+ lxIdentifierService,
107
107
  })
108
108
 
109
109
  await service.initSession()
@@ -178,7 +178,7 @@ describe('createSessionService', () => {
178
178
  sessionStorage: storage,
179
179
  sessionRepository: repository,
180
180
  deviceIdService,
181
- luxIdentifierService,
181
+ lxIdentifierService,
182
182
  })
183
183
 
184
184
  expect(await service2.getSessionState()).toEqual({ sessionId: 'test-session-123' })
@@ -201,7 +201,7 @@ describe('createSessionService', () => {
201
201
  sessionStorage: storage2,
202
202
  sessionRepository: repository,
203
203
  deviceIdService,
204
- luxIdentifierService,
204
+ lxIdentifierService,
205
205
  })
206
206
 
207
207
  await service.initSession()
@@ -326,8 +326,8 @@ describe('createSessionService', () => {
326
326
  })
327
327
  })
328
328
 
329
- describe('lux identifier handling', () => {
330
- it('persists luxIdentifier when provided in extra', async () => {
329
+ describe('uniswap identifier handling', () => {
330
+ it('persists lxIdentifier when provided in extra', async () => {
331
331
  repository.initSession = async (): Promise<{
332
332
  sessionId?: string
333
333
  needChallenge: boolean
@@ -335,14 +335,14 @@ describe('createSessionService', () => {
335
335
  }> => ({
336
336
  sessionId: 'test-session-123',
337
337
  needChallenge: false,
338
- extra: { luxIdentifier: '71cef16f-4d99-4082-987c-a6f810f9ca7f' },
338
+ extra: { lxIdentifier: '71cef16f-4d99-4082-987c-a6f810f9ca7f' },
339
339
  })
340
340
 
341
341
  await service.initSession()
342
- expect(await luxIdentifierService.getLuxIdentifier()).toBe('71cef16f-4d99-4082-987c-a6f810f9ca7f')
342
+ expect(await lxIdentifierService.getLxIdentifier()).toBe('71cef16f-4d99-4082-987c-a6f810f9ca7f')
343
343
  })
344
344
 
345
- it('does not persist luxIdentifier when not provided', async () => {
345
+ it('does not persist lxIdentifier when not provided', async () => {
346
346
  repository.initSession = async (): Promise<{
347
347
  sessionId?: string
348
348
  needChallenge: boolean
@@ -354,10 +354,10 @@ describe('createSessionService', () => {
354
354
  })
355
355
 
356
356
  await service.initSession()
357
- expect(await luxIdentifierService.getLuxIdentifier()).toBeNull()
357
+ expect(await lxIdentifierService.getLxIdentifier()).toBeNull()
358
358
  })
359
359
 
360
- it('updates luxIdentifier on subsequent initSession calls', async () => {
360
+ it('updates lxIdentifier on subsequent initSession calls', async () => {
361
361
  repository.initSession = async (): Promise<{
362
362
  sessionId?: string
363
363
  needChallenge: boolean
@@ -365,11 +365,11 @@ describe('createSessionService', () => {
365
365
  }> => ({
366
366
  sessionId: 'test-session-123',
367
367
  needChallenge: false,
368
- extra: { luxIdentifier: 'first-identifier' },
368
+ extra: { lxIdentifier: 'first-identifier' },
369
369
  })
370
370
 
371
371
  await service.initSession()
372
- expect(await luxIdentifierService.getLuxIdentifier()).toBe('first-identifier')
372
+ expect(await lxIdentifierService.getLxIdentifier()).toBe('first-identifier')
373
373
 
374
374
  repository.initSession = async (): Promise<{
375
375
  sessionId?: string
@@ -378,11 +378,11 @@ describe('createSessionService', () => {
378
378
  }> => ({
379
379
  sessionId: 'test-session-456',
380
380
  needChallenge: false,
381
- extra: { luxIdentifier: 'second-identifier' },
381
+ extra: { lxIdentifier: 'second-identifier' },
382
382
  })
383
383
 
384
384
  await service.initSession()
385
- expect(await luxIdentifierService.getLuxIdentifier()).toBe('second-identifier')
385
+ expect(await lxIdentifierService.getLxIdentifier()).toBe('second-identifier')
386
386
  })
387
387
  })
388
388
  })
@@ -9,7 +9,7 @@ import type {
9
9
  VerifySessionResponse,
10
10
  } from '@luxexchange/sessions/src/session-service/types'
11
11
  import type { SessionStorage } from '@luxexchange/sessions/src/session-storage/types'
12
- import type { LuxIdentifierService } from '@luxexchange/sessions/src/lux-identifier/types'
12
+ import type { LxIdentifierService } from '@luxexchange/sessions/src/uniswap-identifier/types'
13
13
 
14
14
  /**
15
15
  * Creates a Session Service instance.
@@ -18,7 +18,7 @@ import type { LuxIdentifierService } from '@luxexchange/sessions/src/lux-identif
18
18
  export function createSessionService(ctx: {
19
19
  sessionStorage: SessionStorage
20
20
  deviceIdService: DeviceIdService
21
- luxIdentifierService: LuxIdentifierService
21
+ lxIdentifierService: LxIdentifierService
22
22
  sessionRepository: SessionRepository
23
23
  }): SessionService {
24
24
  async function initSession(): Promise<InitSessionResponse> {
@@ -29,8 +29,8 @@ export function createSessionService(ctx: {
29
29
  if (result.deviceId) {
30
30
  await ctx.deviceIdService.setDeviceId(result.deviceId)
31
31
  }
32
- if (result.extra['luxIdentifier']) {
33
- await ctx.luxIdentifierService.setLuxIdentifier(result.extra['luxIdentifier'])
32
+ if (result.extra['lxIdentifier']) {
33
+ await ctx.lxIdentifierService.setLxIdentifier(result.extra['lxIdentifier'])
34
34
  }
35
35
  return result
36
36
  }
@@ -1,4 +1,4 @@
1
- import { ChallengeType } from '@uniswap/client-platform-service/dist/uniswap/platformservice/v1/sessionService_pb'
1
+ import { ChallengeType } from '@luxamm/client-platform-service/dist/uniswap/platformservice/v1/sessionService_pb'
2
2
  import type { TypedChallengeData } from '@luxexchange/sessions/src/session-repository/types'
3
3
  import { SessionState } from '@luxexchange/sessions/src/session-storage/types'
4
4
 
@@ -1,4 +1,4 @@
1
- import { SessionStorage } from '@luxfi/sessions/src/session-storage/types'
1
+ import { SessionStorage } from '@luxexchange/sessions/src/session-storage/types'
2
2
 
3
3
  /**
4
4
  * Creates a Session Storage instance, given a set of functions to interact with a storage driver.
@@ -39,6 +39,7 @@ const BACKEND_URL = 'https://entry-gateway.backend-staging.api.lux.org'
39
39
  // Web Platform Tests (Turnstile + Hashcash)
40
40
  // =============================================================================
41
41
  // Web uses Turnstile (browser CAPTCHA) first, then falls back to Hashcash
42
+ // These tests hit a staging backend that occasionally returns transient 502s.
42
43
  describe('Real Backend Integration - Web (Turnstile + Hashcash)', () => {
43
44
  let sessionService: SessionService
44
45
  let sessionStorage: InMemorySessionStorage
@@ -76,7 +77,7 @@ describe('Real Backend Integration - Web (Turnstile + Hashcash)', () => {
76
77
  await sessionStorage.clear()
77
78
  })
78
79
 
79
- it('initializes session with cookie, empty response sessionId', async () => {
80
+ it('initializes session with cookie, empty response sessionId', { timeout: 30000, retry: 5 }, async () => {
80
81
  const manualInitService = createSessionInitializationService({
81
82
  getSessionService: () => sessionService,
82
83
  challengeSolverService,
@@ -96,9 +97,9 @@ describe('Real Backend Integration - Web (Turnstile + Hashcash)', () => {
96
97
  // Session is NOT stored locally yet because challenge is needed
97
98
  const sessionState = await sessionService.getSessionState()
98
99
  expect(sessionState).toBeNull()
99
- }, 30000)
100
+ })
100
101
 
101
- it('receives Turnstile challenge first', async () => {
102
+ it('receives Turnstile challenge first', { timeout: 30000, retry: 5 }, async () => {
102
103
  const manualInitService = createSessionInitializationService({
103
104
  getSessionService: () => sessionService,
104
105
  challengeSolverService,
@@ -113,9 +114,9 @@ describe('Real Backend Integration - Web (Turnstile + Hashcash)', () => {
113
114
  // Web gets Turnstile first (browser-based CAPTCHA)
114
115
  expect(challenge.challengeType).toBe(ChallengeType.TURNSTILE)
115
116
  expect(challenge.challengeId).toBeTruthy()
116
- }, 30000)
117
+ })
117
118
 
118
- it('falls back to Hashcash after Turnstile fails', async () => {
119
+ it('falls back to Hashcash after Turnstile fails', { timeout: 30000, retry: 5 }, async () => {
119
120
  const manualInitService = createSessionInitializationService({
120
121
  getSessionService: () => sessionService,
121
122
  challengeSolverService,
@@ -151,56 +152,72 @@ describe('Real Backend Integration - Web (Turnstile + Hashcash)', () => {
151
152
  const hashcashChallenge = await sessionService.requestChallenge()
152
153
  expect(hashcashChallenge.challengeType).toBe(ChallengeType.HASHCASH)
153
154
  expect(hashcashChallenge.challengeId).toBeTruthy()
154
- }, 30000)
155
+ })
155
156
 
156
- it('successfully upgrades session with Hashcash after Turnstile fails', { timeout: 60000, retry: 2 }, async () => {
157
- const manualInitService = createSessionInitializationService({
158
- getSessionService: () => sessionService,
159
- challengeSolverService,
160
- performanceTracker: createMockPerformanceTracker(),
161
- getIsSessionUpgradeAutoEnabled: () => false,
162
- })
157
+ it('successfully upgrades session with Hashcash after Turnstile fails', { timeout: 60000, retry: 5 }, async () => {
158
+ let lastError: unknown
163
159
 
164
- await manualInitService.initialize()
160
+ // Some staging responses intermittently return HTTP 502 and leave session state invalid.
161
+ // Retry the full flow from a clean state so we don't carry over a broken session cookie.
162
+ for (let attempt = 0; attempt < 3; attempt++) {
163
+ try {
164
+ const manualInitService = createSessionInitializationService({
165
+ getSessionService: () => sessionService,
166
+ challengeSolverService,
167
+ performanceTracker: createMockPerformanceTracker(),
168
+ getIsSessionUpgradeAutoEnabled: () => false,
169
+ })
165
170
 
166
- // Turnstile attempt (fails)
167
- const turnstileChallenge = await sessionService.requestChallenge()
168
- const turnstileSolver = challengeSolverService.getSolver(ChallengeType.TURNSTILE)
169
- const turnstileSolution = await turnstileSolver?.solve({
170
- challengeId: turnstileChallenge.challengeId,
171
- challengeType: turnstileChallenge.challengeType,
172
- extra: turnstileChallenge.extra,
173
- })
171
+ await manualInitService.initialize()
174
172
 
175
- const turnstileResult = await sessionService.verifySession({
176
- solution: turnstileSolution || '',
177
- challengeId: turnstileChallenge.challengeId,
178
- challengeType: turnstileChallenge.challengeType,
179
- })
180
- expect(turnstileResult.retry).toBe(true)
173
+ // Turnstile attempt (fails)
174
+ const turnstileChallenge = await sessionService.requestChallenge()
175
+ const turnstileSolver = challengeSolverService.getSolver(ChallengeType.TURNSTILE)
176
+ const turnstileSolution = await turnstileSolver?.solve({
177
+ challengeId: turnstileChallenge.challengeId,
178
+ challengeType: turnstileChallenge.challengeType,
179
+ extra: turnstileChallenge.extra,
180
+ })
181
181
 
182
- // Hashcash attempt
183
- const hashcashChallenge = await sessionService.requestChallenge()
184
- expect(hashcashChallenge.challengeType).toBe(ChallengeType.HASHCASH)
182
+ const turnstileResult = await sessionService.verifySession({
183
+ solution: turnstileSolution || '',
184
+ challengeId: turnstileChallenge.challengeId,
185
+ challengeType: turnstileChallenge.challengeType,
186
+ })
187
+ expect(turnstileResult.retry).toBe(true)
185
188
 
186
- const hashcashSolver = challengeSolverService.getSolver(ChallengeType.HASHCASH)
187
- const hashcashSolution = await hashcashSolver?.solve({
188
- challengeId: hashcashChallenge.challengeId,
189
- challengeType: hashcashChallenge.challengeType,
190
- extra: hashcashChallenge.extra,
191
- })
189
+ // Hashcash attempt
190
+ const hashcashChallenge = await sessionService.requestChallenge()
191
+ expect(hashcashChallenge.challengeType).toBe(ChallengeType.HASHCASH)
192
192
 
193
- const hashcashResult = await sessionService.verifySession({
194
- solution: hashcashSolution || '',
195
- challengeId: hashcashChallenge.challengeId,
196
- challengeType: hashcashChallenge.challengeType,
197
- })
193
+ const hashcashSolver = challengeSolverService.getSolver(ChallengeType.HASHCASH)
194
+ const hashcashSolution = await hashcashSolver?.solve({
195
+ challengeId: hashcashChallenge.challengeId,
196
+ challengeType: hashcashChallenge.challengeType,
197
+ extra: hashcashChallenge.extra,
198
+ })
199
+
200
+ const hashcashResult = await sessionService.verifySession({
201
+ solution: hashcashSolution || '',
202
+ challengeId: hashcashChallenge.challengeId,
203
+ challengeType: hashcashChallenge.challengeType,
204
+ })
205
+
206
+ // Success!
207
+ expect(hashcashResult.retry).toBe(false)
208
+ return
209
+ } catch (error) {
210
+ lastError = error
211
+ await sessionService.removeSession()
212
+ cookieJar.clear()
213
+ await sessionStorage.clear()
214
+ }
215
+ }
198
216
 
199
- // Success!
200
- expect(hashcashResult.retry).toBe(false)
217
+ throw lastError instanceof Error ? lastError : new Error('Failed to complete Hashcash upgrade flow')
201
218
  })
202
219
 
203
- it('completes auto-upgrade flow (Turnstile fail → Hashcash success)', { timeout: 60000, retry: 2 }, async () => {
220
+ it('completes auto-upgrade flow (Turnstile fail → Hashcash success)', { timeout: 60000, retry: 5 }, async () => {
204
221
  const autoInitService = createSessionInitializationService({
205
222
  getSessionService: () => sessionService,
206
223
  challengeSolverService,
@@ -219,38 +236,57 @@ describe('Real Backend Integration - Web (Turnstile + Hashcash)', () => {
219
236
 
220
237
  it(
221
238
  'calls initSession on reinit - backend handles session reuse via cookie',
222
- { timeout: 60000, retry: 2 },
239
+ { timeout: 60000, retry: 5 },
223
240
  async () => {
224
- const autoInitService = createSessionInitializationService({
225
- getSessionService: () => sessionService,
226
- challengeSolverService,
227
- performanceTracker: createMockPerformanceTracker(),
228
- getIsSessionUpgradeAutoEnabled: () => true,
229
- })
230
-
231
- await autoInitService.initialize()
232
-
233
- // Cookie should be set from first init
234
- expect(cookieJar.has('x-session-id')).toBe(true)
235
- const originalSessionId = cookieJar.get('x-session-id')
236
-
237
- // Simulate page refresh - call initialize again
238
- // Backend receives cookie and decides to reuse session
239
- const reinitService = createSessionInitializationService({
240
- getSessionService: () => sessionService,
241
- challengeSolverService,
242
- performanceTracker: createMockPerformanceTracker(),
243
- getIsSessionUpgradeAutoEnabled: () => true,
244
- })
245
-
246
- await reinitService.initialize()
247
-
248
- // Backend should reuse session - cookie remains the same
249
- expect(cookieJar.get('x-session-id')).toBe(originalSessionId)
241
+ let lastError: unknown
242
+
243
+ // Re-run the full reinit flow from a clean cookie/session state when staging is unstable.
244
+ for (let attempt = 0; attempt < 3; attempt++) {
245
+ try {
246
+ await sessionService.removeSession()
247
+ cookieJar.clear()
248
+ await sessionStorage.clear()
249
+
250
+ const autoInitService = createSessionInitializationService({
251
+ getSessionService: () => sessionService,
252
+ challengeSolverService,
253
+ performanceTracker: createMockPerformanceTracker(),
254
+ getIsSessionUpgradeAutoEnabled: () => true,
255
+ })
256
+
257
+ await autoInitService.initialize()
258
+
259
+ // Cookie should be set from first init
260
+ expect(cookieJar.has('x-session-id')).toBe(true)
261
+ const originalSessionId = cookieJar.get('x-session-id')
262
+
263
+ // Simulate page refresh - call initialize again
264
+ // Backend receives cookie and decides to reuse session
265
+ const reinitService = createSessionInitializationService({
266
+ getSessionService: () => sessionService,
267
+ challengeSolverService,
268
+ performanceTracker: createMockPerformanceTracker(),
269
+ getIsSessionUpgradeAutoEnabled: () => true,
270
+ })
271
+
272
+ await reinitService.initialize()
273
+
274
+ // Backend should reuse session - cookie remains the same
275
+ expect(cookieJar.get('x-session-id')).toBe(originalSessionId)
276
+ return
277
+ } catch (error) {
278
+ lastError = error
279
+ await sessionService.removeSession()
280
+ cookieJar.clear()
281
+ await sessionStorage.clear()
282
+ }
283
+ }
284
+
285
+ throw lastError instanceof Error ? lastError : new Error('Failed to verify cookie-based session reuse flow')
250
286
  },
251
287
  )
252
288
 
253
- it('fires analytics callbacks during auto-upgrade flow', { timeout: 60000, retry: 2 }, async () => {
289
+ it('fires analytics callbacks during auto-upgrade flow', { timeout: 60000, retry: 5 }, async () => {
254
290
  const analytics = {
255
291
  onInitStarted: vi.fn(),
256
292
  onInitCompleted: vi.fn(),
@@ -351,7 +387,7 @@ describe.each(NON_WEB_PLATFORMS)(
351
387
  await luxIdentifierService.removeLuxIdentifier()
352
388
  })
353
389
 
354
- it('initializes session with session ID and device ID stored locally', async () => {
390
+ it('initializes session with session ID and device ID stored locally', { timeout: 30000, retry: 5 }, async () => {
355
391
  const manualInitService = createSessionInitializationService({
356
392
  getSessionService: () => sessionService,
357
393
  challengeSolverService,
@@ -372,9 +408,9 @@ describe.each(NON_WEB_PLATFORMS)(
372
408
  // Device ID should also be returned and stored
373
409
  const storedDeviceId = await deviceIdService.getDeviceId()
374
410
  expect(storedDeviceId).toBeTruthy()
375
- }, 30000)
411
+ })
376
412
 
377
- it('receives Hashcash challenge directly (no Turnstile)', async () => {
413
+ it('receives Hashcash challenge directly (no Turnstile)', { timeout: 30000, retry: 5 }, async () => {
378
414
  const manualInitService = createSessionInitializationService({
379
415
  getSessionService: () => sessionService,
380
416
  challengeSolverService,
@@ -389,9 +425,9 @@ describe.each(NON_WEB_PLATFORMS)(
389
425
  // Non-web gets Hashcash directly (Turnstile is browser-only)
390
426
  expect(challenge.challengeType).toBe(ChallengeType.HASHCASH)
391
427
  expect(challenge.challengeId).toBeTruthy()
392
- }, 30000)
428
+ })
393
429
 
394
- it('successfully upgrades session with Hashcash', { timeout: 60000, retry: 2 }, async () => {
430
+ it('successfully upgrades session with Hashcash', { timeout: 60000, retry: 5 }, async () => {
395
431
  const manualInitService = createSessionInitializationService({
396
432
  getSessionService: () => sessionService,
397
433
  challengeSolverService,
@@ -422,7 +458,7 @@ describe.each(NON_WEB_PLATFORMS)(
422
458
  expect(hashcashResult.retry).toBe(false)
423
459
  })
424
460
 
425
- it('completes auto-upgrade flow', { timeout: 60000, retry: 2 }, async () => {
461
+ it('completes auto-upgrade flow', { timeout: 60000, retry: 5 }, async () => {
426
462
  const autoInitService = createSessionInitializationService({
427
463
  getSessionService: () => sessionService,
428
464
  challengeSolverService,
@@ -440,7 +476,7 @@ describe.each(NON_WEB_PLATFORMS)(
440
476
 
441
477
  it(
442
478
  'calls initSession on reinit - backend handles session reuse via X-Session-ID header',
443
- { timeout: 60000, retry: 2 },
479
+ { timeout: 60000, retry: 5 },
444
480
  async () => {
445
481
  // First: Complete auto-upgrade flow
446
482
  const autoInitService = createSessionInitializationService({
@@ -8,23 +8,23 @@ import {
8
8
  SignoutResponse,
9
9
  UpdateSessionResponse,
10
10
  VerifyResponse,
11
- } from '@luxdex/client-platform-service/dist/uniswap/platformservice/v1/sessionService_pb'
12
- import { createSessionRepository } from '@luxfi/sessions/src/session-repository/createSessionRepository'
13
- import { createSessionService } from '@luxfi/sessions/src/session-service/createSessionService'
14
- import type { SessionService } from '@luxfi/sessions/src/session-service/types'
11
+ } from '@luxamm/client-platform-service/dist/uniswap/platformservice/v1/sessionService_pb'
12
+ import { createSessionRepository } from '@luxexchange/sessions/src/session-repository/createSessionRepository'
13
+ import { createSessionService } from '@luxexchange/sessions/src/session-service/createSessionService'
14
+ import type { SessionService } from '@luxexchange/sessions/src/session-service/types'
15
15
  import {
16
16
  createMockSessionClient,
17
17
  InMemoryDeviceIdService,
18
18
  InMemorySessionStorage,
19
- InMemoryLuxIdentifierService,
19
+ InMemoryLxIdentifierService,
20
20
  type MockEndpoints,
21
- } from '@luxfi/sessions/src/test-utils'
21
+ } from '@luxexchange/sessions/src/test-utils'
22
22
  import { afterEach, beforeEach, describe, expect, it } from 'vitest'
23
23
 
24
24
  describe('Session Lifecycle Integration Tests', () => {
25
25
  let sessionStorage: InMemorySessionStorage
26
26
  let deviceIdService: InMemoryDeviceIdService
27
- let luxIdentifierService: InMemoryLuxIdentifierService
27
+ let lxIdentifierService: InMemoryLxIdentifierService
28
28
  let sessionService: SessionService
29
29
  let mockEndpoints: MockEndpoints
30
30
 
@@ -32,42 +32,42 @@ describe('Session Lifecycle Integration Tests', () => {
32
32
  // Initialize in-memory storage
33
33
  sessionStorage = new InMemorySessionStorage()
34
34
  deviceIdService = new InMemoryDeviceIdService()
35
- luxIdentifierService = new InMemoryLuxIdentifierService()
35
+ lxIdentifierService = new InMemoryLxIdentifierService()
36
36
 
37
37
  // Set up mock endpoints with default responses
38
38
  mockEndpoints = {
39
- '/lux.platformservice.v1.SessionService/InitSession': async (): Promise<InitSessionResponse> => {
39
+ '/uniswap.platformservice.v1.SessionService/InitSession': async (): Promise<InitSessionResponse> => {
40
40
  return new InitSessionResponse({
41
41
  sessionId: 'test-session-123',
42
42
  needChallenge: false,
43
43
  extra: {},
44
44
  })
45
45
  },
46
- '/lux.platformservice.v1.SessionService/Challenge': async (): Promise<ChallengeResponse> => {
46
+ '/uniswap.platformservice.v1.SessionService/Challenge': async (): Promise<ChallengeResponse> => {
47
47
  return new ChallengeResponse({
48
48
  challengeId: 'challenge-123',
49
49
  challengeType: ChallengeType.TURNSTILE,
50
50
  extra: { sitekey: 'test-key' },
51
51
  })
52
52
  },
53
- '/lux.platformservice.v1.SessionService/Verify': async (): Promise<VerifyResponse> => {
53
+ '/uniswap.platformservice.v1.SessionService/Verify': async (): Promise<VerifyResponse> => {
54
54
  return new VerifyResponse({
55
55
  retry: false,
56
56
  })
57
57
  },
58
- '/lux.platformservice.v1.SessionService/DeleteSession': async (): Promise<DeleteSessionResponse> => {
58
+ '/uniswap.platformservice.v1.SessionService/DeleteSession': async (): Promise<DeleteSessionResponse> => {
59
59
  return new DeleteSessionResponse({})
60
60
  },
61
- '/lux.platformservice.v1.SessionService/IntrospectSession': async (): Promise<IntrospectSessionResponse> => {
61
+ '/uniswap.platformservice.v1.SessionService/IntrospectSession': async (): Promise<IntrospectSessionResponse> => {
62
62
  return new IntrospectSessionResponse({})
63
63
  },
64
- '/lux.platformservice.v1.SessionService/UpdateSession': async (): Promise<UpdateSessionResponse> => {
64
+ '/uniswap.platformservice.v1.SessionService/UpdateSession': async (): Promise<UpdateSessionResponse> => {
65
65
  return new UpdateSessionResponse({})
66
66
  },
67
- '/lux.platformservice.v1.SessionService/GetChallengeTypes': async (): Promise<GetChallengeTypesResponse> => {
67
+ '/uniswap.platformservice.v1.SessionService/GetChallengeTypes': async (): Promise<GetChallengeTypesResponse> => {
68
68
  return new GetChallengeTypesResponse({ challengeTypes: [] })
69
69
  },
70
- '/lux.platformservice.v1.SessionService/Signout': async (): Promise<SignoutResponse> => {
70
+ '/uniswap.platformservice.v1.SessionService/Signout': async (): Promise<SignoutResponse> => {
71
71
  return new SignoutResponse({})
72
72
  },
73
73
  }
@@ -84,7 +84,7 @@ describe('Session Lifecycle Integration Tests', () => {
84
84
  sessionService = createSessionService({
85
85
  sessionStorage,
86
86
  deviceIdService,
87
- luxIdentifierService,
87
+ lxIdentifierService,
88
88
  sessionRepository,
89
89
  })
90
90
  })
@@ -111,7 +111,7 @@ describe('Session Lifecycle Integration Tests', () => {
111
111
 
112
112
  it('handles session initialization without challenge requirement', async () => {
113
113
  // Override default to return needChallenge: false
114
- mockEndpoints['/lux.platformservice.v1.SessionService/InitSession'] =
114
+ mockEndpoints['/uniswap.platformservice.v1.SessionService/InitSession'] =
115
115
  async (): Promise<InitSessionResponse> => {
116
116
  return new InitSessionResponse({
117
117
  sessionId: 'simple-session-123',
@@ -151,7 +151,7 @@ describe('Session Lifecycle Integration Tests', () => {
151
151
  })
152
152
 
153
153
  it('stores session ID when provided (mobile/extension behavior)', async () => {
154
- mockEndpoints['/lux.platformservice.v1.SessionService/InitSession'] =
154
+ mockEndpoints['/uniswap.platformservice.v1.SessionService/InitSession'] =
155
155
  async (): Promise<InitSessionResponse> => {
156
156
  return new InitSessionResponse({
157
157
  sessionId: 'mobile-session-123',
@@ -170,7 +170,7 @@ describe('Session Lifecycle Integration Tests', () => {
170
170
  })
171
171
 
172
172
  it('handles web sessions without storing session ID when undefined', async () => {
173
- mockEndpoints['/lux.platformservice.v1.SessionService/InitSession'] =
173
+ mockEndpoints['/uniswap.platformservice.v1.SessionService/InitSession'] =
174
174
  async (): Promise<InitSessionResponse> => {
175
175
  return new InitSessionResponse({
176
176
  sessionId: undefined,
@@ -216,7 +216,7 @@ describe('Session Lifecycle Integration Tests', () => {
216
216
  expect(firstSession?.sessionId).toBe('test-session-123')
217
217
 
218
218
  // Update mock to return different session
219
- mockEndpoints['/lux.platformservice.v1.SessionService/InitSession'] =
219
+ mockEndpoints['/uniswap.platformservice.v1.SessionService/InitSession'] =
220
220
  async (): Promise<InitSessionResponse> => {
221
221
  return new InitSessionResponse({
222
222
  sessionId: 'new-session-789',
@@ -233,7 +233,7 @@ describe('Session Lifecycle Integration Tests', () => {
233
233
  })
234
234
 
235
235
  it('sets and retrieves device ID through init response', async () => {
236
- mockEndpoints['/lux.platformservice.v1.SessionService/InitSession'] =
236
+ mockEndpoints['/uniswap.platformservice.v1.SessionService/InitSession'] =
237
237
  async (): Promise<InitSessionResponse> => {
238
238
  return new InitSessionResponse({
239
239
  sessionId: 'device-test-session',
@@ -14,7 +14,7 @@ export function createLocalCookieTransport(options: { baseUrl: string; cookieJar
14
14
  interceptors: [
15
15
  (next) => async (request) => {
16
16
  // Add required headers that backend expects
17
- request.header.set('x-request-source', 'lux-web')
17
+ request.header.set('x-request-source', 'lx-web')
18
18
 
19
19
  // Simulate browser cookie behavior: add stored cookies to request
20
20
  if (cookieJar.size > 0) {
@@ -3,7 +3,7 @@ import { createConnectTransport } from '@connectrpc/connect-web'
3
3
 
4
4
  interface CreateLocalHeaderTransportOptions {
5
5
  baseUrl: string
6
- requestSource: 'lux-ios' | 'lux-android' | 'lux-extension'
6
+ requestSource: 'lx-ios' | 'lx-android' | 'lx-extension'
7
7
  getSessionId: () => Promise<string | null>
8
8
  getDeviceId: () => Promise<string | null>
9
9
  }
@@ -1,6 +1,6 @@
1
- import type { ChallengeSolver, ChallengeSolverService } from '@luxfi/sessions/src/challenge-solvers/types'
2
- import type { SessionService } from '@luxfi/sessions/src/session-service/types'
3
- import { ChallengeType } from '@luxfi/sessions/src/session-service/types'
1
+ import type { ChallengeSolver, ChallengeSolverService } from '@luxexchange/sessions/src/challenge-solvers/types'
2
+ import type { SessionService } from '@luxexchange/sessions/src/session-service/types'
3
+ import { ChallengeType } from '@luxexchange/sessions/src/session-service/types'
4
4
  import { vi } from 'vitest'
5
5
 
6
6
  /**