@luxexchange/sessions 1.0.1 → 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 (68) 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 +2 -8
  7. package/src/challenge-solvers/createChallengeSolverService.ts +5 -5
  8. package/src/challenge-solvers/createHashcashMockSolver.ts +1 -1
  9. package/src/challenge-solvers/createHashcashSolver.test.ts +10 -10
  10. package/src/challenge-solvers/createHashcashSolver.ts +22 -7
  11. package/src/challenge-solvers/createNoneMockSolver.ts +1 -1
  12. package/src/challenge-solvers/createTurnstileMockSolver.ts +1 -1
  13. package/src/challenge-solvers/createTurnstileSolver.ts +12 -8
  14. package/src/challenge-solvers/hashcash/core.native.ts +3 -3
  15. package/src/challenge-solvers/hashcash/core.test.ts +10 -10
  16. package/src/challenge-solvers/hashcash/core.ts +3 -3
  17. package/src/challenge-solvers/hashcash/core.web.ts +4 -4
  18. package/src/challenge-solvers/hashcash/createWorkerHashcashSolver.test.ts +7 -7
  19. package/src/challenge-solvers/hashcash/createWorkerHashcashSolver.ts +4 -4
  20. package/src/challenge-solvers/hashcash/worker/createHashcashMultiWorkerChannel.native.ts +1 -1
  21. package/src/challenge-solvers/hashcash/worker/createHashcashMultiWorkerChannel.ts +1 -1
  22. package/src/challenge-solvers/hashcash/worker/createHashcashMultiWorkerChannel.web.ts +2 -2
  23. package/src/challenge-solvers/hashcash/worker/createHashcashWorkerChannel.native.ts +1 -1
  24. package/src/challenge-solvers/hashcash/worker/createHashcashWorkerChannel.ts +1 -1
  25. package/src/challenge-solvers/hashcash/worker/createHashcashWorkerChannel.web.ts +2 -2
  26. package/src/challenge-solvers/hashcash/worker/hashcash.worker.ts +3 -3
  27. package/src/challenge-solvers/hashcash/worker/types.ts +1 -1
  28. package/src/challenge-solvers/turnstileErrors.ts +1 -1
  29. package/src/challenge-solvers/turnstileScriptLoader.ts +2 -2
  30. package/src/challenge-solvers/turnstileSolver.integration.test.ts +4 -4
  31. package/src/challenge-solvers/types.ts +2 -2
  32. package/src/challengeFlow.integration.test.ts +49 -49
  33. package/src/device-id/createDeviceIdService.ts +1 -1
  34. package/src/index.ts +50 -48
  35. package/src/oauth-service/createOAuthService.ts +2 -2
  36. package/src/oauth-service/types.ts +1 -1
  37. package/src/performance/createNoopPerformanceTracker.ts +2 -2
  38. package/src/performance/createPerformanceTracker.ts +1 -1
  39. package/src/performance/index.ts +3 -3
  40. package/src/session-initialization/createSessionInitializationService.test.ts +4 -4
  41. package/src/session-initialization/createSessionInitializationService.ts +32 -41
  42. package/src/session-repository/createSessionClient.ts +1 -1
  43. package/src/session-repository/createSessionRepository.test.ts +5 -5
  44. package/src/session-repository/createSessionRepository.ts +14 -14
  45. package/src/session-repository/errors.ts +1 -1
  46. package/src/session-repository/types.ts +1 -1
  47. package/src/session-service/createNoopSessionService.ts +2 -2
  48. package/src/session-service/createSessionService.test.ts +29 -29
  49. package/src/session-service/createSessionService.ts +8 -8
  50. package/src/session-service/types.ts +3 -3
  51. package/src/session-storage/createSessionStorage.ts +1 -1
  52. package/src/session.integration.test.ts +130 -94
  53. package/src/sessionLifecycle.integration.test.ts +22 -22
  54. package/src/test-utils/createLocalCookieTransport.ts +1 -1
  55. package/src/test-utils/createLocalHeaderTransport.ts +1 -1
  56. package/src/test-utils/mocks.ts +3 -3
  57. package/src/test-utils.ts +24 -24
  58. package/src/uniswap-identifier/createUniswapIdentifierService.ts +19 -0
  59. package/src/uniswap-identifier/types.ts +11 -0
  60. package/src/uniswap-identifier/uniswapIdentifierQuery.ts +20 -0
  61. package/tsconfig.json +10 -3
  62. package/tsconfig.lint.json +8 -0
  63. package/tsconfig.spec.json +8 -0
  64. package/vitest.config.ts +20 -0
  65. package/vitest.integration.config.ts +14 -0
  66. package/src/lux-identifier/createLuxIdentifierService.ts +0 -19
  67. package/src/lux-identifier/luxIdentifierQuery.ts +0 -20
  68. package/src/lux-identifier/types.ts +0 -11
@@ -1,24 +1,24 @@
1
- import { createChallengeSolverService } from '@universe/sessions/src/challenge-solvers/createChallengeSolverService'
2
- import { createHashcashSolver } from '@universe/sessions/src/challenge-solvers/createHashcashSolver'
3
- import { createNoneMockSolver } from '@universe/sessions/src/challenge-solvers/createNoneMockSolver'
4
- import { createTurnstileMockSolver } from '@universe/sessions/src/challenge-solvers/createTurnstileMockSolver'
5
- import type { PerformanceTracker } from '@universe/sessions/src/performance/types'
6
- import { createSessionInitializationService } from '@universe/sessions/src/session-initialization/createSessionInitializationService'
7
- import { createSessionClient } from '@universe/sessions/src/session-repository/createSessionClient'
8
- import { createSessionRepository } from '@universe/sessions/src/session-repository/createSessionRepository'
9
- import { createSessionService } from '@universe/sessions/src/session-service/createSessionService'
10
- import type { SessionService } from '@universe/sessions/src/session-service/types'
11
- import { ChallengeType } from '@universe/sessions/src/session-service/types'
1
+ import { createChallengeSolverService } from '@luxexchange/sessions/src/challenge-solvers/createChallengeSolverService'
2
+ import { createHashcashSolver } from '@luxexchange/sessions/src/challenge-solvers/createHashcashSolver'
3
+ import { createNoneMockSolver } from '@luxexchange/sessions/src/challenge-solvers/createNoneMockSolver'
4
+ import { createTurnstileMockSolver } from '@luxexchange/sessions/src/challenge-solvers/createTurnstileMockSolver'
5
+ import type { PerformanceTracker } from '@luxexchange/sessions/src/performance/types'
6
+ import { createSessionInitializationService } from '@luxexchange/sessions/src/session-initialization/createSessionInitializationService'
7
+ import { createSessionClient } from '@luxexchange/sessions/src/session-repository/createSessionClient'
8
+ import { createSessionRepository } from '@luxexchange/sessions/src/session-repository/createSessionRepository'
9
+ import { createSessionService } from '@luxexchange/sessions/src/session-service/createSessionService'
10
+ import type { SessionService } from '@luxexchange/sessions/src/session-service/types'
11
+ import { ChallengeType } from '@luxexchange/sessions/src/session-service/types'
12
12
  import {
13
13
  InMemoryDeviceIdService,
14
14
  InMemorySessionStorage,
15
15
  InMemoryLuxIdentifierService,
16
- } from '@universe/sessions/src/test-utils'
16
+ } from '@luxexchange/sessions/src/test-utils'
17
17
  import {
18
18
  createCookieJar,
19
19
  createLocalCookieTransport,
20
- } from '@universe/sessions/src/test-utils/createLocalCookieTransport'
21
- import { createLocalHeaderTransport } from '@universe/sessions/src/test-utils/createLocalHeaderTransport'
20
+ } from '@luxexchange/sessions/src/test-utils/createLocalCookieTransport'
21
+ import { createLocalHeaderTransport } from '@luxexchange/sessions/src/test-utils/createLocalHeaderTransport'
22
22
  import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
23
23
 
24
24
  // Mock performance tracker for testing
@@ -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
  /**
package/src/test-utils.ts CHANGED
@@ -17,30 +17,30 @@ import {
17
17
  type UpdateSessionResponse,
18
18
  type VerifyRequest,
19
19
  type VerifyResponse,
20
- } from '@luxdex/client-platform-service/dist/uniswap/platformservice/v1/sessionService_pb'
21
- import type { DeviceIdService } from '@luxfi/sessions/src/device-id/types'
22
- import type { SessionServiceClient } from '@luxfi/sessions/src/session-repository/createSessionClient'
23
- import type { SessionState, SessionStorage } from '@luxfi/sessions/src/session-storage/types'
24
- import type { LuxIdentifierService } from '@luxfi/sessions/src/lux-identifier/types'
20
+ } from '@luxamm/client-platform-service/dist/uniswap/platformservice/v1/sessionService_pb'
21
+ import type { DeviceIdService } from '@luxexchange/sessions/src/device-id/types'
22
+ import type { SessionServiceClient } from '@luxexchange/sessions/src/session-repository/createSessionClient'
23
+ import type { SessionState, SessionStorage } from '@luxexchange/sessions/src/session-storage/types'
24
+ import type { LxIdentifierService } from '@luxexchange/sessions/src/uniswap-identifier/types'
25
25
  // Types for our test transport
26
26
  export interface MockEndpointHandler {
27
27
  (request: any, headers: Record<string, string>): Promise<any>
28
28
  }
29
29
 
30
30
  export interface MockEndpoints {
31
- '/lux.platformservice.v1.SessionService/InitSession': MockEndpointHandler
32
- '/lux.platformservice.v1.SessionService/Challenge': MockEndpointHandler
33
- '/lux.platformservice.v1.SessionService/Verify': MockEndpointHandler
34
- '/lux.platformservice.v1.SessionService/IntrospectSession': MockEndpointHandler
35
- '/lux.platformservice.v1.SessionService/UpdateSession': MockEndpointHandler
36
- '/lux.platformservice.v1.SessionService/GetChallengeTypes': MockEndpointHandler
37
- '/lux.platformservice.v1.SessionService/Signout': MockEndpointHandler
31
+ '/uniswap.platformservice.v1.SessionService/InitSession': MockEndpointHandler
32
+ '/uniswap.platformservice.v1.SessionService/Challenge': MockEndpointHandler
33
+ '/uniswap.platformservice.v1.SessionService/Verify': MockEndpointHandler
34
+ '/uniswap.platformservice.v1.SessionService/IntrospectSession': MockEndpointHandler
35
+ '/uniswap.platformservice.v1.SessionService/UpdateSession': MockEndpointHandler
36
+ '/uniswap.platformservice.v1.SessionService/GetChallengeTypes': MockEndpointHandler
37
+ '/uniswap.platformservice.v1.SessionService/Signout': MockEndpointHandler
38
38
  }
39
39
 
40
40
  // Test transport that intercepts requests and returns mock responses
41
41
  export function createTestTransport(mockEndpoints: MockEndpoints): ReturnType<typeof createConnectTransport> {
42
42
  return createConnectTransport({
43
- baseUrl: 'https://test.api.lux.org',
43
+ baseUrl: 'https://test.api.lux.exchange',
44
44
  interceptors: [
45
45
  (_next) => async (request) => {
46
46
  const url = request.url
@@ -109,18 +109,18 @@ export class InMemoryDeviceIdService implements DeviceIdService {
109
109
  }
110
110
  }
111
111
 
112
- export class InMemoryLuxIdentifierService implements LuxIdentifierService {
112
+ export class InMemoryLxIdentifierService implements LxIdentifierService {
113
113
  private identifier: string | null = null
114
114
 
115
- async getLuxIdentifier(): Promise<string | null> {
115
+ async getLxIdentifier(): Promise<string | null> {
116
116
  return this.identifier
117
117
  }
118
118
 
119
- async setLuxIdentifier(id: string): Promise<void> {
119
+ async setLxIdentifier(id: string): Promise<void> {
120
120
  this.identifier = id
121
121
  }
122
122
 
123
- async removeLuxIdentifier(): Promise<void> {
123
+ async removeLxIdentifier(): Promise<void> {
124
124
  this.identifier = null
125
125
  }
126
126
  }
@@ -137,7 +137,7 @@ export function createMockSessionClient(
137
137
  request: PartialMessage<InitSessionRequest>,
138
138
  _options?: CallOptions,
139
139
  ): Promise<InitSessionResponse> => {
140
- const response = await mockEndpoints['/lux.platformservice.v1.SessionService/InitSession'](request, {})
140
+ const response = await mockEndpoints['/uniswap.platformservice.v1.SessionService/InitSession'](request, {})
141
141
  return response as InitSessionResponse
142
142
  },
143
143
  challenge: async (
@@ -154,7 +154,7 @@ export function createMockSessionClient(
154
154
  headers['X-Device-ID'] = deviceId
155
155
  }
156
156
 
157
- const response = await mockEndpoints['/lux.platformservice.v1.SessionService/Challenge'](request, headers)
157
+ const response = await mockEndpoints['/uniswap.platformservice.v1.SessionService/Challenge'](request, headers)
158
158
  return response as ChallengeResponse
159
159
  },
160
160
  verify: async (request: PartialMessage<VerifyRequest>, _options?: CallOptions): Promise<VerifyResponse> => {
@@ -168,32 +168,32 @@ export function createMockSessionClient(
168
168
  headers['X-Device-ID'] = deviceId
169
169
  }
170
170
 
171
- const response = await mockEndpoints['/lux.platformservice.v1.SessionService/Verify'](request, headers)
171
+ const response = await mockEndpoints['/uniswap.platformservice.v1.SessionService/Verify'](request, headers)
172
172
  return response as VerifyResponse
173
173
  },
174
174
  introspectSession: async (
175
175
  request: PartialMessage<IntrospectSessionRequest>,
176
176
  _options?: CallOptions,
177
177
  ): Promise<IntrospectSessionResponse> => {
178
- const response = await mockEndpoints['/lux.platformservice.v1.SessionService/IntrospectSession'](request, {})
178
+ const response = await mockEndpoints['/uniswap.platformservice.v1.SessionService/IntrospectSession'](request, {})
179
179
  return response as IntrospectSessionResponse
180
180
  },
181
181
  updateSession: async (
182
182
  request: PartialMessage<UpdateSessionRequest>,
183
183
  _options?: CallOptions,
184
184
  ): Promise<UpdateSessionResponse> => {
185
- const response = await mockEndpoints['/lux.platformservice.v1.SessionService/UpdateSession'](request, {})
185
+ const response = await mockEndpoints['/uniswap.platformservice.v1.SessionService/UpdateSession'](request, {})
186
186
  return response as UpdateSessionResponse
187
187
  },
188
188
  getChallengeTypes: async (
189
189
  request: PartialMessage<GetChallengeTypesRequest>,
190
190
  _options?: CallOptions,
191
191
  ): Promise<GetChallengeTypesResponse> => {
192
- const response = await mockEndpoints['/lux.platformservice.v1.SessionService/GetChallengeTypes'](request, {})
192
+ const response = await mockEndpoints['/uniswap.platformservice.v1.SessionService/GetChallengeTypes'](request, {})
193
193
  return response as GetChallengeTypesResponse
194
194
  },
195
195
  signout: async (request: PartialMessage<SignoutRequest>, _options?: CallOptions): Promise<SignoutResponse> => {
196
- const response = await mockEndpoints['/lux.platformservice.v1.SessionService/Signout'](request, {})
196
+ const response = await mockEndpoints['/uniswap.platformservice.v1.SessionService/Signout'](request, {})
197
197
  return response as SignoutResponse
198
198
  },
199
199
  }
@@ -0,0 +1,19 @@
1
+ import type { LxIdentifierService } from '@luxexchange/sessions/src/uniswap-identifier/types'
2
+
3
+ function createLxIdentifierService(ctx: {
4
+ getLxIdentifier: () => Promise<string | null>
5
+ setLxIdentifier: (identifier: string) => Promise<void>
6
+ removeLxIdentifier: () => Promise<void>
7
+ }): LxIdentifierService {
8
+ const getLxIdentifier = ctx.getLxIdentifier
9
+ const setLxIdentifier = ctx.setLxIdentifier
10
+ const removeLxIdentifier = ctx.removeLxIdentifier
11
+
12
+ return {
13
+ getLxIdentifier,
14
+ setLxIdentifier,
15
+ removeLxIdentifier,
16
+ }
17
+ }
18
+
19
+ export { createLxIdentifierService }