@ledgerhq/device-transport-kit-react-native-hid 0.0.0-try-to-fix-20250429171448 → 0.0.0-v0-transaction-unfunded-20250918091119

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 (57) hide show
  1. package/android/build.gradle +0 -9
  2. package/android/src/main/kotlin/com/ledger/androidtransporthid/TransportHidModule.kt +12 -3
  3. package/android/src/main/kotlin/com/ledger/androidtransporthid/bridge/serialization.kt +2 -0
  4. package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/DefaultAndroidUsbTransport.kt +85 -23
  5. package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/connection/AndroidUsbApduSender.kt +70 -29
  6. package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/utils/UsbDeviceMapper.kt +3 -0
  7. package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMainInternal/transport/deviceconnection/DeviceApduSender.kt +2 -1
  8. package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMainInternal/transport/deviceconnection/DeviceConnection.kt +5 -4
  9. package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMainInternal/transport/deviceconnection/DeviceConnectionStateMachine.kt +103 -33
  10. package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/apdu/SendApduResult.kt +4 -0
  11. package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/device/LedgerDevice.kt +16 -0
  12. package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/connection/InternalConnectedDevice.kt +1 -1
  13. package/android/src/test/kotlin/com/ledger/devicesdk/shared/androidMainInternal/transport/deviceconnection/DeviceConnectionStateMachineTest.kt +189 -46
  14. package/android/src/test/kotlin/com/ledger/devicesdk/shared/androidMainInternal/transport/deviceconnection/DeviceConnectionTest.kt +9 -5
  15. package/lib/cjs/api/bridge/DefaultNativeModuleWrapper.js +1 -1
  16. package/lib/cjs/api/bridge/DefaultNativeModuleWrapper.js.map +3 -3
  17. package/lib/cjs/api/bridge/mapper.js +1 -1
  18. package/lib/cjs/api/bridge/mapper.js.map +2 -2
  19. package/lib/cjs/api/bridge/mapper.test.js +1 -1
  20. package/lib/cjs/api/bridge/mapper.test.js.map +2 -2
  21. package/lib/cjs/api/bridge/types.js +1 -1
  22. package/lib/cjs/api/bridge/types.js.map +1 -1
  23. package/lib/cjs/api/transport/Errors.js +1 -1
  24. package/lib/cjs/api/transport/Errors.js.map +3 -3
  25. package/lib/cjs/api/transport/NativeModuleWrapper.js +1 -1
  26. package/lib/cjs/api/transport/NativeModuleWrapper.js.map +1 -1
  27. package/lib/cjs/api/transport/RNHidTransport.js +1 -1
  28. package/lib/cjs/api/transport/RNHidTransport.js.map +3 -3
  29. package/lib/cjs/api/transport/RNHidTransport.test.js +1 -1
  30. package/lib/cjs/api/transport/RNHidTransport.test.js.map +2 -2
  31. package/lib/cjs/package.json +11 -11
  32. package/lib/esm/api/bridge/DefaultNativeModuleWrapper.js +1 -1
  33. package/lib/esm/api/bridge/DefaultNativeModuleWrapper.js.map +3 -3
  34. package/lib/esm/api/bridge/mapper.js +1 -1
  35. package/lib/esm/api/bridge/mapper.js.map +3 -3
  36. package/lib/esm/api/bridge/mapper.test.js +1 -1
  37. package/lib/esm/api/bridge/mapper.test.js.map +3 -3
  38. package/lib/esm/api/bridge/types.js.map +1 -1
  39. package/lib/esm/api/transport/Errors.js +1 -1
  40. package/lib/esm/api/transport/Errors.js.map +3 -3
  41. package/lib/esm/api/transport/RNHidTransport.js +1 -1
  42. package/lib/esm/api/transport/RNHidTransport.js.map +3 -3
  43. package/lib/esm/api/transport/RNHidTransport.test.js +1 -1
  44. package/lib/esm/api/transport/RNHidTransport.test.js.map +3 -3
  45. package/lib/esm/package.json +11 -11
  46. package/lib/types/api/bridge/DefaultNativeModuleWrapper.d.ts +1 -1
  47. package/lib/types/api/bridge/DefaultNativeModuleWrapper.d.ts.map +1 -1
  48. package/lib/types/api/bridge/mapper.d.ts.map +1 -1
  49. package/lib/types/api/bridge/types.d.ts +2 -2
  50. package/lib/types/api/bridge/types.d.ts.map +1 -1
  51. package/lib/types/api/transport/Errors.d.ts +1 -1
  52. package/lib/types/api/transport/Errors.d.ts.map +1 -1
  53. package/lib/types/api/transport/NativeModuleWrapper.d.ts +1 -1
  54. package/lib/types/api/transport/NativeModuleWrapper.d.ts.map +1 -1
  55. package/lib/types/api/transport/RNHidTransport.d.ts.map +1 -1
  56. package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
  57. package/package.json +15 -15
@@ -2,6 +2,7 @@ package com.ledger.devicesdk.shared.androidMainInternal.transport.deviceconnecti
2
2
 
3
3
  import com.ledger.devicesdk.shared.api.apdu.SendApduFailureReason
4
4
  import com.ledger.devicesdk.shared.api.apdu.SendApduResult
5
+ import com.ledger.devicesdk.shared.api.utils.fromHexStringToBytesOrThrow
5
6
  import com.ledger.devicesdk.shared.internal.service.logger.LogInfo
6
7
  import com.ledger.devicesdk.shared.internal.service.logger.LoggerService
7
8
  import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -12,6 +13,7 @@ import kotlin.time.Duration
12
13
  import kotlin.time.Duration.Companion.seconds
13
14
  import kotlin.test.Test
14
15
  import org.junit.Assert.*
16
+ import kotlin.test.assertIs
15
17
  import kotlin.time.Duration.Companion.milliseconds
16
18
 
17
19
  @OptIn(ExperimentalCoroutinesApi::class)
@@ -25,7 +27,7 @@ class DeviceConnectionStateMachineTest {
25
27
  var sendApduResult: SendApduResult? = null
26
28
 
27
29
  val stateMachine = DeviceConnectionStateMachine(
28
- sendApduFn = { apdu -> sendApduCalled = apdu },
30
+ sendApduFn = { apdu, _ -> sendApduCalled = apdu },
29
31
  onTerminated = { terminated = true },
30
32
  isFatalSendApduFailure = { false },
31
33
  reconnectionTimeoutDuration = reconnectionTimeout,
@@ -38,7 +40,8 @@ class DeviceConnectionStateMachineTest {
38
40
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
39
41
  apdu = mockedRequestApduA,
40
42
  triggersDisconnection = false,
41
- resultCallback = { result -> sendApduResult = result }
43
+ resultCallback = { result -> sendApduResult = result },
44
+ abortTimeoutDuration = Duration.INFINITE
42
45
  ))
43
46
  assertArrayEquals(mockedRequestApduA, sendApduCalled)
44
47
 
@@ -65,7 +68,7 @@ class DeviceConnectionStateMachineTest {
65
68
  var error: Throwable? = null
66
69
 
67
70
  val stateMachine = DeviceConnectionStateMachine(
68
- sendApduFn = { },
71
+ sendApduFn = { _, _ -> },
69
72
  onTerminated = { terminated = true },
70
73
  isFatalSendApduFailure = { true }, // All failures are fatal
71
74
  reconnectionTimeoutDuration = reconnectionTimeout,
@@ -77,7 +80,8 @@ class DeviceConnectionStateMachineTest {
77
80
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
78
81
  apdu = mockedRequestApduA,
79
82
  triggersDisconnection = false,
80
- resultCallback = { result -> sendApduResult = result }
83
+ resultCallback = { result -> sendApduResult = result },
84
+ abortTimeoutDuration = Duration.INFINITE
81
85
  ))
82
86
 
83
87
  // Simulate a failure
@@ -86,7 +90,7 @@ class DeviceConnectionStateMachineTest {
86
90
  stateMachine.handleApduResult(mockedFailureResult)
87
91
 
88
92
  // Then
89
- assertEquals(sendApduResult, mockedFailureResult)
93
+ assertEquals(mockedFailureResult, sendApduResult)
90
94
  assertTrue(terminated)
91
95
  assertNull(error)
92
96
  }
@@ -99,7 +103,7 @@ class DeviceConnectionStateMachineTest {
99
103
  var error: Throwable? = null
100
104
 
101
105
  val stateMachine = DeviceConnectionStateMachine(
102
- sendApduFn = { },
106
+ sendApduFn = { _, _ -> },
103
107
  onTerminated = { terminated = true },
104
108
  isFatalSendApduFailure = { false },
105
109
  reconnectionTimeoutDuration = reconnectionTimeout,
@@ -112,7 +116,8 @@ class DeviceConnectionStateMachineTest {
112
116
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
113
117
  apdu = mockedRequestApduA,
114
118
  triggersDisconnection = false,
115
- resultCallback = { result -> sendApduResult = result }
119
+ resultCallback = { result -> sendApduResult = result },
120
+ abortTimeoutDuration = Duration.INFINITE
116
121
  ))
117
122
 
118
123
  // Simulate a failure
@@ -131,16 +136,15 @@ class DeviceConnectionStateMachineTest {
131
136
  }
132
137
 
133
138
  @Test
134
- fun `GIVEN the device connection state machine WHEN an APDU with triggersDisconnection is sent THEN the machine moves to WaitingForReconnection and recovers when device reconnects`() =
139
+ fun `GIVEN the device connection state machine WHEN an APDU with triggersDisconnection is sent and triggers a disconnection THEN the machine moves to WaitingForReconnection and recovers when device reconnects`() =
135
140
  runTest {
136
141
  var sendApduCalled: ByteArray? = null
137
142
  var sendApduResult: SendApduResult? = null
138
143
  var terminated = false
139
144
  var error: Throwable? = null
140
145
 
141
- val dispatcher = StandardTestDispatcher(testScheduler)
142
146
  val stateMachine = DeviceConnectionStateMachine(
143
- sendApduFn = { apdu -> sendApduCalled = apdu },
147
+ sendApduFn = { apdu, _ -> sendApduCalled = apdu },
144
148
  onTerminated = { terminated = true },
145
149
  isFatalSendApduFailure = { false },
146
150
  reconnectionTimeoutDuration = reconnectionTimeout,
@@ -153,7 +157,8 @@ class DeviceConnectionStateMachineTest {
153
157
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
154
158
  apdu = mockedRequestApduA,
155
159
  triggersDisconnection = true,
156
- resultCallback = { result -> sendApduResult = result }
160
+ resultCallback = { result -> sendApduResult = result },
161
+ abortTimeoutDuration = Duration.INFINITE
157
162
  ))
158
163
 
159
164
  // Send APDU should have been called
@@ -163,6 +168,10 @@ class DeviceConnectionStateMachineTest {
163
168
  val mockedSuccessApduResult = SendApduResult.Success(mockedResultApduSuccessA)
164
169
  stateMachine.handleApduResult(mockedSuccessApduResult)
165
170
 
171
+ assertNull(sendApduResult)
172
+ // Simulate a disconnection
173
+ stateMachine.handleDeviceDisconnected()
174
+
166
175
  // Result should have been returned
167
176
  assertEquals(mockedSuccessApduResult, sendApduResult)
168
177
 
@@ -180,7 +189,8 @@ class DeviceConnectionStateMachineTest {
180
189
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
181
190
  apdu = mockedRequestApduB,
182
191
  triggersDisconnection = false,
183
- resultCallback = { secondSendApduResult = it }
192
+ resultCallback = { secondSendApduResult = it },
193
+ abortTimeoutDuration = Duration.INFINITE
184
194
  ))
185
195
 
186
196
  // Send APDU should have been called
@@ -198,14 +208,125 @@ class DeviceConnectionStateMachineTest {
198
208
  }
199
209
 
200
210
  @Test
201
- fun `GIVEN the device connection state machine WHEN an APDU with triggersDisconnection is sent THEN the machine moves to WaitingForReconnection and the next APDU is queued until reconnection`() =
211
+ fun `GIVEN the device connection state machine WHEN an APDU with triggersDisconnection is sent and device does not disconnect THEN the machine moves to Connected`() =
212
+ runTest {
213
+ var sendApduCalled: ByteArray? = null
214
+ var sendApduResult: SendApduResult? = null
215
+ var terminated = false
216
+ var error: Throwable? = null
217
+
218
+ val stateMachine = DeviceConnectionStateMachine(
219
+ sendApduFn = { apdu, _ -> sendApduCalled = apdu },
220
+ onTerminated = { terminated = true },
221
+ isFatalSendApduFailure = { false },
222
+ reconnectionTimeoutDuration = reconnectionTimeout,
223
+ onError = { error = it },
224
+ loggerService = FakeLoggerService(),
225
+ coroutineDispatcher = StandardTestDispatcher(testScheduler)
226
+ )
227
+
228
+ // Request sending an APDU (with triggersDisconnection = true)
229
+ stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
230
+ apdu = mockedRequestApduA,
231
+ triggersDisconnection = true,
232
+ resultCallback = { result -> sendApduResult = result },
233
+ abortTimeoutDuration = Duration.INFINITE
234
+ ))
235
+
236
+ // Send APDU should have been called
237
+ assertArrayEquals(mockedRequestApduA, sendApduCalled)
238
+
239
+ // Simulate a successful response
240
+ val mockedSuccessApduResult = SendApduResult.Success(mockedResultApduSuccessA)
241
+ stateMachine.handleApduResult(mockedSuccessApduResult)
242
+
243
+ assertNull(sendApduResult)
244
+
245
+ // Simulate Response from GetAppAndVersion
246
+ val mockedSuccessApduResultGetAppAndVersion = SendApduResult.Success(mockedGetAppAndVersionSuccessfulResponse)
247
+ stateMachine.handleApduResult(mockedSuccessApduResultGetAppAndVersion)
248
+
249
+ // Should be in Connected state
250
+ assertEquals(
251
+ DeviceConnectionStateMachine.State.Connected,
252
+ stateMachine.getState()
253
+ )
254
+
255
+ // Response should have been returned
256
+ assertEquals(mockedSuccessApduResult, sendApduResult)
257
+ }
258
+
259
+ @Test
260
+ fun `GIVEN the device connection state machine WHEN an APDU with triggersDisconnection is sent and device does not disconnect but is first busy THEN the machine retries and moves to Connected`() =
261
+ runTest {
262
+ var sendApduCalled: ByteArray? = null
263
+ var sendApduResult: SendApduResult? = null
264
+ var terminated = false
265
+ var error: Throwable? = null
266
+
267
+ val stateMachine = DeviceConnectionStateMachine(
268
+ sendApduFn = { apdu, _ -> sendApduCalled = apdu },
269
+ onTerminated = { terminated = true },
270
+ isFatalSendApduFailure = { false },
271
+ reconnectionTimeoutDuration = reconnectionTimeout,
272
+ onError = { error = it },
273
+ loggerService = FakeLoggerService(),
274
+ coroutineDispatcher = StandardTestDispatcher(testScheduler)
275
+ )
276
+
277
+ // Request sending an APDU (with triggersDisconnection = true)
278
+ stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
279
+ apdu = mockedRequestApduA,
280
+ triggersDisconnection = true,
281
+ resultCallback = { result -> sendApduResult = result },
282
+ abortTimeoutDuration = Duration.INFINITE
283
+ ))
284
+
285
+ // Send APDU should have been called
286
+ assertArrayEquals(mockedRequestApduA, sendApduCalled)
287
+
288
+ // Simulate a successful response
289
+ val mockedSuccessApduResult = SendApduResult.Success(mockedResultApduSuccessA)
290
+ stateMachine.handleApduResult(mockedSuccessApduResult)
291
+
292
+ assertNull(sendApduResult)
293
+
294
+ assertIs<DeviceConnectionStateMachine.State.WaitingForDisconnection>(
295
+ stateMachine.getState()
296
+ )
297
+
298
+ // Simulate Busy Response from GetAppAndVersion
299
+ val mockedBusyApduResultGetAppAndVersion = SendApduResult.Success(mockedGetAppAndVersionBusyResponse)
300
+ stateMachine.handleApduResult(mockedBusyApduResultGetAppAndVersion)
301
+
302
+ assertIs<DeviceConnectionStateMachine.State.WaitingForDisconnection>(
303
+ stateMachine.getState()
304
+ )
305
+
306
+ // Simulate Successful Response from GetAppAndVersion
307
+ val mockedSuccessApduResultGetAppAndVersion = SendApduResult.Success(mockedGetAppAndVersionSuccessfulResponse)
308
+ stateMachine.handleApduResult(mockedSuccessApduResultGetAppAndVersion)
309
+
310
+ // Should be in Connected state
311
+ assertEquals(
312
+ DeviceConnectionStateMachine.State.Connected,
313
+ stateMachine.getState()
314
+ )
315
+
316
+ // Response should have been returned
317
+ assertEquals(mockedSuccessApduResult, sendApduResult)
318
+ }
319
+
320
+
321
+ @Test
322
+ fun `GIVEN the device connection state machine WHEN an APDU with triggersDisconnection is sent and triggers a disconnection THEN the machine moves to WaitingForReconnection and the next APDU is queued until reconnection`() =
202
323
  runTest {
203
324
  val sendApduCalled: MutableList<ByteArray> = mutableListOf()
204
325
  var terminated = false
205
326
  var error: Throwable? = null
206
327
 
207
328
  val stateMachine = DeviceConnectionStateMachine(
208
- sendApduFn = { apdu -> sendApduCalled += apdu },
329
+ sendApduFn = { apdu, _ -> sendApduCalled += apdu },
209
330
  onTerminated = { terminated = true },
210
331
  isFatalSendApduFailure = { false },
211
332
  reconnectionTimeoutDuration = reconnectionTimeout,
@@ -218,17 +339,27 @@ class DeviceConnectionStateMachineTest {
218
339
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
219
340
  apdu = mockedRequestApduA,
220
341
  triggersDisconnection = true,
221
- resultCallback = { }
342
+ resultCallback = { },
343
+ abortTimeoutDuration = Duration.INFINITE
222
344
  ))
223
345
 
224
346
  // Simulate a successful response
225
347
  val mockedSuccessApduResult = SendApduResult.Success(mockedResultApduSuccessA)
226
348
  stateMachine.handleApduResult(mockedSuccessApduResult)
227
349
 
228
- // sendApduFn should have been called once
229
- assertEquals(1, sendApduCalled.size)
350
+ // sendApduFn should have been called twice (for the mockedRequestApduA and an extra call for the getAppAndVersion APDU)
351
+ assertEquals(2, sendApduCalled.size)
352
+
353
+ // Should be in WaitingForDisconnection state
354
+ assertIs<DeviceConnectionStateMachine.State.WaitingForDisconnection>(
355
+ stateMachine.getState()
356
+ )
357
+
358
+ // Simulate disconnection
359
+ stateMachine.handleDeviceDisconnected()
360
+
361
+ // Should be in WaitingForReconnection state
230
362
 
231
- // Should be in waiting state
232
363
  assertEquals(
233
364
  DeviceConnectionStateMachine.State.WaitingForReconnection,
234
365
  stateMachine.getState()
@@ -239,7 +370,8 @@ class DeviceConnectionStateMachineTest {
239
370
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
240
371
  apdu = mockedRequestApduB,
241
372
  triggersDisconnection = false,
242
- resultCallback = { secondSendApduResult = it }
373
+ resultCallback = { secondSendApduResult = it },
374
+ abortTimeoutDuration = Duration.INFINITE
243
375
  ))
244
376
 
245
377
  // Should be in waiting state
@@ -249,7 +381,7 @@ class DeviceConnectionStateMachineTest {
249
381
  )
250
382
 
251
383
  // sendApduFn should not have been called one more time
252
- assertEquals(1, sendApduCalled.size)
384
+ assertEquals(2, sendApduCalled.size)
253
385
 
254
386
  // Simulate reconnection
255
387
  stateMachine.handleDeviceConnected()
@@ -260,9 +392,9 @@ class DeviceConnectionStateMachineTest {
260
392
  stateMachine.getState()::class
261
393
  )
262
394
 
263
- // Send APDU should have been called a second time, and the result should have been returned
264
- assertEquals(2, sendApduCalled.size)
265
- assertArrayEquals(mockedRequestApduB, sendApduCalled[1])
395
+ // Send APDU should have been called a 3rd time, and the result should have been returned
396
+ assertEquals(3, sendApduCalled.size)
397
+ assertArrayEquals(mockedRequestApduB, sendApduCalled[2])
266
398
 
267
399
  // Simulate a successful response
268
400
  val mockedSuccessApduResultB = SendApduResult.Success(mockedResultApduSuccessB)
@@ -289,7 +421,7 @@ class DeviceConnectionStateMachineTest {
289
421
  var error: Throwable? = null
290
422
 
291
423
  val stateMachine = DeviceConnectionStateMachine(
292
- sendApduFn = { },
424
+ sendApduFn = { _, _ -> },
293
425
  onTerminated = { terminated = true },
294
426
  isFatalSendApduFailure = { false },
295
427
  reconnectionTimeoutDuration = reconnectionTimeout,
@@ -302,7 +434,8 @@ class DeviceConnectionStateMachineTest {
302
434
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
303
435
  apdu = mockedRequestApduA,
304
436
  triggersDisconnection = false,
305
- resultCallback = { result -> sendApduResult = result }
437
+ resultCallback = { result -> sendApduResult = result },
438
+ abortTimeoutDuration = Duration.INFINITE
306
439
  ))
307
440
 
308
441
  // Should be in sending state
@@ -331,7 +464,7 @@ class DeviceConnectionStateMachineTest {
331
464
  var error: Throwable? = null
332
465
 
333
466
  val stateMachine = DeviceConnectionStateMachine(
334
- sendApduFn = { },
467
+ sendApduFn = { _,_ -> },
335
468
  onTerminated = { terminated = true },
336
469
  isFatalSendApduFailure = { false },
337
470
  reconnectionTimeoutDuration = reconnectionTimeout,
@@ -344,7 +477,8 @@ class DeviceConnectionStateMachineTest {
344
477
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
345
478
  apdu = mockedRequestApduA,
346
479
  triggersDisconnection = false,
347
- resultCallback = { result -> sendApduResult = result }
480
+ resultCallback = { result -> sendApduResult = result },
481
+ abortTimeoutDuration = Duration.INFINITE
348
482
  ))
349
483
 
350
484
  // Simulate a disconnection
@@ -384,7 +518,7 @@ class DeviceConnectionStateMachineTest {
384
518
  var error: Throwable? = null
385
519
 
386
520
  val stateMachine = DeviceConnectionStateMachine(
387
- sendApduFn = { },
521
+ sendApduFn = { _,_ -> },
388
522
  onTerminated = { terminated = true },
389
523
  isFatalSendApduFailure = { false },
390
524
  reconnectionTimeoutDuration = reconnectionTimeout,
@@ -397,7 +531,8 @@ class DeviceConnectionStateMachineTest {
397
531
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
398
532
  apdu = mockedRequestApduA,
399
533
  triggersDisconnection = false,
400
- resultCallback = { firstSendApduResult = it }
534
+ resultCallback = { firstSendApduResult = it },
535
+ abortTimeoutDuration = Duration.INFINITE
401
536
  ))
402
537
 
403
538
  // Should be in sending state.
@@ -410,7 +545,8 @@ class DeviceConnectionStateMachineTest {
410
545
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
411
546
  apdu = mockedRequestApduB,
412
547
  triggersDisconnection = false,
413
- resultCallback = { secondSendApduResult = it }
548
+ resultCallback = { secondSendApduResult = it },
549
+ abortTimeoutDuration = Duration.INFINITE
414
550
  ))
415
551
 
416
552
  assertEquals(
@@ -435,7 +571,7 @@ class DeviceConnectionStateMachineTest {
435
571
  var terminated = false
436
572
 
437
573
  val stateMachine = DeviceConnectionStateMachine(
438
- sendApduFn = { },
574
+ sendApduFn = { _,_ -> },
439
575
  onTerminated = { terminated = true },
440
576
  isFatalSendApduFailure = { false },
441
577
  reconnectionTimeoutDuration = reconnectionTimeout,
@@ -472,7 +608,7 @@ class DeviceConnectionStateMachineTest {
472
608
  var terminated = false
473
609
 
474
610
  val stateMachine = DeviceConnectionStateMachine(
475
- sendApduFn = { },
611
+ sendApduFn = { _,_ -> },
476
612
  onTerminated = { terminated = true },
477
613
  isFatalSendApduFailure = { false },
478
614
  reconnectionTimeoutDuration = 5.seconds,
@@ -507,7 +643,7 @@ class DeviceConnectionStateMachineTest {
507
643
  var error: Throwable? = null
508
644
 
509
645
  val stateMachine = DeviceConnectionStateMachine(
510
- sendApduFn = { apdu -> sendApduCalled = apdu },
646
+ sendApduFn = { apdu, _ -> sendApduCalled = apdu },
511
647
  onTerminated = { terminated = true },
512
648
  isFatalSendApduFailure = { false },
513
649
  reconnectionTimeoutDuration = 5.seconds,
@@ -523,7 +659,8 @@ class DeviceConnectionStateMachineTest {
523
659
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
524
660
  apdu = mockedRequestApduA,
525
661
  triggersDisconnection = false,
526
- resultCallback = { sendApduResult = it }
662
+ resultCallback = { sendApduResult = it },
663
+ abortTimeoutDuration = Duration.INFINITE
527
664
  ))
528
665
 
529
666
  // Send APDU should not have been called
@@ -552,7 +689,7 @@ class DeviceConnectionStateMachineTest {
552
689
  var error: Throwable? = null
553
690
 
554
691
  val stateMachine = DeviceConnectionStateMachine(
555
- sendApduFn = { },
692
+ sendApduFn = { _,_ -> },
556
693
  onTerminated = { terminated = true },
557
694
  isFatalSendApduFailure = { false },
558
695
  reconnectionTimeoutDuration = 5.seconds,
@@ -568,7 +705,8 @@ class DeviceConnectionStateMachineTest {
568
705
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
569
706
  apdu = mockedRequestApduA,
570
707
  triggersDisconnection = false,
571
- resultCallback = { result -> sendApduResult = result }
708
+ resultCallback = { result -> sendApduResult = result },
709
+ abortTimeoutDuration = Duration.INFINITE
572
710
  ))
573
711
 
574
712
  // Request closing the connection
@@ -592,7 +730,7 @@ class DeviceConnectionStateMachineTest {
592
730
  var error: Throwable? = null
593
731
 
594
732
  val stateMachine = DeviceConnectionStateMachine(
595
- sendApduFn = { },
733
+ sendApduFn = { _,_ -> },
596
734
  onTerminated = { terminated = true },
597
735
  isFatalSendApduFailure = { false },
598
736
  reconnectionTimeoutDuration = 5.seconds,
@@ -608,7 +746,8 @@ class DeviceConnectionStateMachineTest {
608
746
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
609
747
  apdu = byteArrayOf(0x0A),
610
748
  triggersDisconnection = false,
611
- resultCallback = { result -> sendApduResult = result }
749
+ resultCallback = { result -> sendApduResult = result },
750
+ abortTimeoutDuration = Duration.INFINITE
612
751
  ))
613
752
 
614
753
  // Simulate timeout
@@ -631,7 +770,7 @@ class DeviceConnectionStateMachineTest {
631
770
  var error: Throwable? = null
632
771
 
633
772
  val stateMachine = DeviceConnectionStateMachine(
634
- sendApduFn = { },
773
+ sendApduFn = { _,_ -> },
635
774
  onTerminated = { terminated = true },
636
775
  isFatalSendApduFailure = { false },
637
776
  reconnectionTimeoutDuration = 5.seconds,
@@ -647,14 +786,16 @@ class DeviceConnectionStateMachineTest {
647
786
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
648
787
  apdu = byteArrayOf(0x0A),
649
788
  triggersDisconnection = false,
650
- resultCallback = { firstSendApduResult = it }
789
+ resultCallback = { firstSendApduResult = it },
790
+ abortTimeoutDuration = Duration.INFINITE
651
791
  ))
652
792
 
653
793
  // Second APDU sending request
654
794
  stateMachine.requestSendApdu(DeviceConnectionStateMachine.SendApduRequestContent(
655
795
  apdu = byteArrayOf(0x0B),
656
796
  triggersDisconnection = false,
657
- resultCallback = { secondSendApduResult = it }
797
+ resultCallback = { secondSendApduResult = it },
798
+ abortTimeoutDuration = Duration.INFINITE
658
799
  ))
659
800
 
660
801
  // Second request should immediately return busy.
@@ -683,7 +824,7 @@ class DeviceConnectionStateMachineTest {
683
824
  var errorCalled: Throwable? = null
684
825
 
685
826
  val stateMachine = DeviceConnectionStateMachine(
686
- sendApduFn = { },
827
+ sendApduFn = { _,_ -> },
687
828
  onTerminated = { },
688
829
  isFatalSendApduFailure = { false },
689
830
  reconnectionTimeoutDuration = reconnectionTimeout,
@@ -705,9 +846,11 @@ class DeviceConnectionStateMachineTest {
705
846
  }
706
847
 
707
848
  val reconnectionTimeout: Duration = 5.seconds
708
- val mockedRequestApduA: ByteArray = byteArrayOf(0x01, 0x02)
709
- val mockedRequestApduB: ByteArray = byteArrayOf(0x03, 0x04)
710
- val mockedResultApduSuccessA: ByteArray = byteArrayOf(0x05, 0x06, 0x90.toByte(), 0x00)
711
- val mockedResultApduSuccessB: ByteArray = byteArrayOf(0x07, 0x08, 0x90.toByte(), 0x00)
849
+ val mockedRequestApduA: ByteArray = "1234".fromHexStringToBytesOrThrow()
850
+ val mockedRequestApduB: ByteArray = "5678".fromHexStringToBytesOrThrow()
851
+ val mockedGetAppAndVersionSuccessfulResponse: ByteArray = "12349000".fromHexStringToBytesOrThrow()
852
+ val mockedGetAppAndVersionBusyResponse: ByteArray = "12346601".fromHexStringToBytesOrThrow()
853
+ val mockedResultApduSuccessA: ByteArray = "56789000".fromHexStringToBytesOrThrow()
854
+ val mockedResultApduSuccessB: ByteArray = "abcd9000".fromHexStringToBytesOrThrow()
712
855
  }
713
856
  }
@@ -11,6 +11,7 @@ import kotlinx.coroutines.test.runTest
11
11
  import kotlin.time.Duration.Companion.seconds
12
12
  import kotlin.test.Test
13
13
  import org.junit.Assert.*
14
+ import kotlin.time.Duration
14
15
  import kotlin.time.Duration.Companion.milliseconds
15
16
 
16
17
  /**
@@ -34,7 +35,7 @@ class DeviceConnectionTest {
34
35
  )
35
36
 
36
37
  // Request sending an APDU
37
- deviceConnection.requestSendApdu(mockedApdu)
38
+ deviceConnection.requestSendApdu(apdu=mockedApdu, triggersDisconnection = false, abortTimeoutDuration = Duration.INFINITE)
38
39
 
39
40
  // Send APDU should have been called once with the correct apdu
40
41
  assertEquals(1, apduSender.sendCalls.size)
@@ -59,7 +60,7 @@ class DeviceConnectionTest {
59
60
  )
60
61
 
61
62
  // Request sending an apdu
62
- val result1 = deviceConnection.requestSendApdu(apduTriggeringDisconnection)
63
+ val result1 = deviceConnection.requestSendApdu(apdu=apduTriggeringDisconnection, triggersDisconnection = false, abortTimeoutDuration = Duration.INFINITE)
63
64
 
64
65
  // apduSender1.sendApdu should have been called once with the correct apdu
65
66
  assertEquals(1, apduSender1.sendCalls.size)
@@ -70,7 +71,7 @@ class DeviceConnectionTest {
70
71
 
71
72
  // Request sending a second apdu
72
73
  val result2 = async {
73
- deviceConnection.requestSendApdu(mockedApdu)
74
+ deviceConnection.requestSendApdu(apdu = mockedApdu, triggersDisconnection = false, abortTimeoutDuration = Duration.INFINITE)
74
75
  }
75
76
 
76
77
  // apduSender1.sendApdu shouldn't have been called again
@@ -139,7 +140,7 @@ class DeviceConnectionTest {
139
140
 
140
141
  // Request sending an APDU
141
142
  val result = async {
142
- deviceConnection.requestSendApdu(mockedApdu)
143
+ deviceConnection.requestSendApdu(apdu = mockedApdu, triggersDisconnection = false, abortTimeoutDuration = Duration.INFINITE)
143
144
  }
144
145
 
145
146
  // Simulate reconnection
@@ -202,7 +203,10 @@ class DeviceConnectionTest {
202
203
  val sendCalls: MutableList<ByteArray>
203
204
  get() = _sendCalls
204
205
 
205
- override suspend fun send(apdu: ByteArray): SendApduResult {
206
+ override suspend fun send(
207
+ apdu: ByteArray,
208
+ abortTimeoutDuration: Duration
209
+ ): SendApduResult {
206
210
  _sendCalls += apdu
207
211
  return nextResult
208
212
  }
@@ -1,2 +1,2 @@
1
- "use strict";var d=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var D=Object.prototype.hasOwnProperty;var m=(i,e)=>{for(var t in e)d(i,t,{get:e[t],enumerable:!0})},E=(i,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of p(e))!D.call(i,n)&&n!==t&&d(i,n,{get:()=>e[n],enumerable:!(o=l(e,n))||o.enumerable});return i};var y=i=>E(d({},"__esModule",{value:!0}),i);var T={};m(T,{DefaultNativeModuleWrapper:()=>M});module.exports=y(T);var s=require("react-native"),c=require("rxjs"),u=require("../helpers/base64Utils"),r=require("./mapper"),a=require("./types");class M{_nativeModule;_deviceModelDataSource;constructor(e){this._nativeModule=e.nativeModule,this._deviceModelDataSource=e.deviceModelDataSource}startScan(){return this._nativeModule.startScan()}stopScan(){return this._nativeModule.stopScan()}subscribeToDiscoveredDevicesEvents(){return new c.Observable(e=>{const o=new s.NativeEventEmitter(this._nativeModule).addListener(a.DISCOVERED_DEVICES_EVENT,n=>{e.next(n.map(v=>(0,r.mapNativeDiscoveryDeviceToTransportDiscoveredDevice)(v,this._deviceModelDataSource)).filter(v=>v!==null))});return()=>{o.remove()}})}subscribeToDeviceDisconnectedEvents(){return new c.Observable(e=>{const o=new s.NativeEventEmitter(this._nativeModule).addListener(a.DEVICE_DISCONNECTED_EVENT,n=>{e.next((0,r.mapNativeDeviceConnectionLostToDeviceDisconnected)(n))});return()=>{o.remove()}})}subscribeToTransportLogs(){return new c.Observable(e=>{const o=new s.NativeEventEmitter(this._nativeModule).addListener(a.TRANSPORT_LOG_EVENT,n=>{e.next((0,r.mapNativeTransportLogToLog)(n))});return()=>{o.remove()}})}async connectDevice(e){const t=await this._nativeModule.connectDevice(e);return(0,r.mapNativeConnectionResultToConnectionResult)(t,this._deviceModelDataSource)}async disconnectDevice(e){return this._nativeModule.disconnectDevice(e)}async sendApdu(e,t){const o=await this._nativeModule.sendApdu(e,(0,u.uint8ArrayToBase64)(t));return(0,r.mapNativeSendApduResultToSendApduResult)(o)}}0&&(module.exports={DefaultNativeModuleWrapper});
1
+ "use strict";var d=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var D=Object.prototype.hasOwnProperty;var m=(i,e)=>{for(var n in e)d(i,n,{get:e[n],enumerable:!0})},E=(i,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of p(e))!D.call(i,t)&&t!==n&&d(i,t,{get:()=>e[t],enumerable:!(o=l(e,t))||o.enumerable});return i};var y=i=>E(d({},"__esModule",{value:!0}),i);var T={};m(T,{DefaultNativeModuleWrapper:()=>M});module.exports=y(T);var c=require("react-native"),v=require("rxjs"),u=require("../helpers/base64Utils"),r=require("./mapper"),a=require("./types");class M{_nativeModule;_deviceModelDataSource;constructor(e){this._nativeModule=e.nativeModule,this._deviceModelDataSource=e.deviceModelDataSource}startScan(){return this._nativeModule.startScan()}stopScan(){return this._nativeModule.stopScan()}subscribeToDiscoveredDevicesEvents(){return new v.Observable(e=>{const o=new c.NativeEventEmitter(this._nativeModule).addListener(a.DISCOVERED_DEVICES_EVENT,t=>{e.next(t.map(s=>(0,r.mapNativeDiscoveryDeviceToTransportDiscoveredDevice)(s,this._deviceModelDataSource)).filter(s=>s!==null))});return()=>{o.remove()}})}subscribeToDeviceDisconnectedEvents(){return new v.Observable(e=>{const o=new c.NativeEventEmitter(this._nativeModule).addListener(a.DEVICE_DISCONNECTED_EVENT,t=>{e.next((0,r.mapNativeDeviceConnectionLostToDeviceDisconnected)(t))});return()=>{o.remove()}})}subscribeToTransportLogs(){return new v.Observable(e=>{const o=new c.NativeEventEmitter(this._nativeModule).addListener(a.TRANSPORT_LOG_EVENT,t=>{e.next((0,r.mapNativeTransportLogToLog)(t))});return()=>{o.remove()}})}async connectDevice(e){const n=await this._nativeModule.connectDevice(e);return(0,r.mapNativeConnectionResultToConnectionResult)(n,this._deviceModelDataSource)}async disconnectDevice(e){return this._nativeModule.disconnectDevice(e)}async sendApdu(e,n,o,t){const s=await this._nativeModule.sendApdu(e,(0,u.uint8ArrayToBase64)(n),o,t);return(0,r.mapNativeSendApduResultToSendApduResult)(s)}}0&&(module.exports={DefaultNativeModuleWrapper});
2
2
  //# sourceMappingURL=DefaultNativeModuleWrapper.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/api/bridge/DefaultNativeModuleWrapper.ts"],
4
- "sourcesContent": ["import { NativeEventEmitter } from \"react-native\";\nimport {\n type DeviceModelDataSource,\n type LogParams,\n type SendApduResult,\n type TransportDiscoveredDevice,\n} from \"@ledgerhq/device-management-kit\";\nimport { Observable } from \"rxjs\";\n\nimport { uint8ArrayToBase64 } from \"@api/helpers/base64Utils\";\nimport { type NativeModuleWrapper } from \"@api/transport/NativeModuleWrapper\";\nimport {\n type InternalConnectionResult,\n type InternalDeviceDisconnected,\n} from \"@api/transport/types\";\n\nimport {\n mapNativeConnectionResultToConnectionResult,\n mapNativeDeviceConnectionLostToDeviceDisconnected,\n mapNativeDiscoveryDeviceToTransportDiscoveredDevice,\n mapNativeSendApduResultToSendApduResult,\n mapNativeTransportLogToLog,\n} from \"./mapper\";\nimport {\n DEVICE_DISCONNECTED_EVENT,\n type DeviceDisconnectedEventPayload,\n DISCOVERED_DEVICES_EVENT,\n type DiscoveredDevicesEventPayload,\n type NativeLog,\n TRANSPORT_LOG_EVENT,\n} from \"./types\";\nimport { type NativeTransportModuleType } from \"./types\";\n\nexport class DefaultNativeModuleWrapper implements NativeModuleWrapper {\n private readonly _nativeModule: NativeTransportModuleType;\n private readonly _deviceModelDataSource: DeviceModelDataSource;\n\n constructor(args: {\n nativeModule: NativeTransportModuleType;\n deviceModelDataSource: DeviceModelDataSource;\n }) {\n this._nativeModule = args.nativeModule;\n this._deviceModelDataSource = args.deviceModelDataSource;\n }\n\n startScan() {\n return this._nativeModule.startScan();\n }\n\n stopScan() {\n return this._nativeModule.stopScan();\n }\n\n subscribeToDiscoveredDevicesEvents(): Observable<\n Array<TransportDiscoveredDevice>\n > {\n return new Observable((subscriber) => {\n const eventEmitter = new NativeEventEmitter(this._nativeModule);\n const eventListener = eventEmitter.addListener(\n DISCOVERED_DEVICES_EVENT,\n (discoveredDevices: DiscoveredDevicesEventPayload) => {\n subscriber.next(\n discoveredDevices\n .map((device) =>\n mapNativeDiscoveryDeviceToTransportDiscoveredDevice(\n device,\n this._deviceModelDataSource,\n ),\n )\n .filter((d) => d !== null),\n );\n },\n );\n\n return () => {\n eventListener.remove();\n };\n });\n }\n\n subscribeToDeviceDisconnectedEvents(): Observable<InternalDeviceDisconnected> {\n return new Observable((subscriber) => {\n const eventEmitter = new NativeEventEmitter(this._nativeModule);\n const eventListener = eventEmitter.addListener(\n DEVICE_DISCONNECTED_EVENT,\n (device: DeviceDisconnectedEventPayload) => {\n subscriber.next(\n mapNativeDeviceConnectionLostToDeviceDisconnected(device),\n );\n },\n );\n\n return () => {\n eventListener.remove();\n };\n });\n }\n\n subscribeToTransportLogs(): Observable<LogParams> {\n return new Observable((subscriber) => {\n const eventEmitter = new NativeEventEmitter(this._nativeModule);\n const eventListener = eventEmitter.addListener(\n TRANSPORT_LOG_EVENT,\n (logParams: NativeLog) => {\n subscriber.next(mapNativeTransportLogToLog(logParams));\n },\n );\n\n return () => {\n eventListener.remove();\n };\n });\n }\n\n async connectDevice(uid: string): Promise<InternalConnectionResult> {\n const nConnectionResult = await this._nativeModule.connectDevice(uid);\n return mapNativeConnectionResultToConnectionResult(\n nConnectionResult,\n this._deviceModelDataSource,\n );\n }\n\n async disconnectDevice(sessionId: string): Promise<void> {\n return this._nativeModule.disconnectDevice(sessionId);\n }\n\n async sendApdu(sessionId: string, apdu: Uint8Array): Promise<SendApduResult> {\n const nSendApduResult = await this._nativeModule.sendApdu(\n sessionId,\n uint8ArrayToBase64(apdu),\n );\n return mapNativeSendApduResultToSendApduResult(nSendApduResult);\n }\n}\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAmC,wBAOnCC,EAA2B,gBAE3BC,EAAmC,oCAOnCC,EAMO,oBACPC,EAOO,mBAGA,MAAMN,CAA0D,CACpD,cACA,uBAEjB,YAAYO,EAGT,CACD,KAAK,cAAgBA,EAAK,aAC1B,KAAK,uBAAyBA,EAAK,qBACrC,CAEA,WAAY,CACV,OAAO,KAAK,cAAc,UAAU,CACtC,CAEA,UAAW,CACT,OAAO,KAAK,cAAc,SAAS,CACrC,CAEA,oCAEE,CACA,OAAO,IAAI,aAAYC,GAAe,CAEpC,MAAMC,EADe,IAAI,qBAAmB,KAAK,aAAa,EAC3B,YACjC,2BACCC,GAAqD,CACpDF,EAAW,KACTE,EACG,IAAKC,MACJ,uDACEA,EACA,KAAK,sBACP,CACF,EACC,OAAQC,GAAMA,IAAM,IAAI,CAC7B,CACF,CACF,EAEA,MAAO,IAAM,CACXH,EAAc,OAAO,CACvB,CACF,CAAC,CACH,CAEA,qCAA8E,CAC5E,OAAO,IAAI,aAAYD,GAAe,CAEpC,MAAMC,EADe,IAAI,qBAAmB,KAAK,aAAa,EAC3B,YACjC,4BACCE,GAA2C,CAC1CH,EAAW,QACT,qDAAkDG,CAAM,CAC1D,CACF,CACF,EAEA,MAAO,IAAM,CACXF,EAAc,OAAO,CACvB,CACF,CAAC,CACH,CAEA,0BAAkD,CAChD,OAAO,IAAI,aAAYD,GAAe,CAEpC,MAAMC,EADe,IAAI,qBAAmB,KAAK,aAAa,EAC3B,YACjC,sBACCI,GAAyB,CACxBL,EAAW,QAAK,8BAA2BK,CAAS,CAAC,CACvD,CACF,EAEA,MAAO,IAAM,CACXJ,EAAc,OAAO,CACvB,CACF,CAAC,CACH,CAEA,MAAM,cAAcK,EAAgD,CAClE,MAAMC,EAAoB,MAAM,KAAK,cAAc,cAAcD,CAAG,EACpE,SAAO,+CACLC,EACA,KAAK,sBACP,CACF,CAEA,MAAM,iBAAiBC,EAAkC,CACvD,OAAO,KAAK,cAAc,iBAAiBA,CAAS,CACtD,CAEA,MAAM,SAASA,EAAmBC,EAA2C,CAC3E,MAAMC,EAAkB,MAAM,KAAK,cAAc,SAC/CF,KACA,sBAAmBC,CAAI,CACzB,EACA,SAAO,2CAAwCC,CAAe,CAChE,CACF",
6
- "names": ["DefaultNativeModuleWrapper_exports", "__export", "DefaultNativeModuleWrapper", "__toCommonJS", "import_react_native", "import_rxjs", "import_base64Utils", "import_mapper", "import_types", "args", "subscriber", "eventListener", "discoveredDevices", "device", "d", "logParams", "uid", "nConnectionResult", "sessionId", "apdu", "nSendApduResult"]
4
+ "sourcesContent": ["import { NativeEventEmitter } from \"react-native\";\nimport {\n type DeviceModelDataSource,\n type LogParams,\n type SendApduResult,\n type TransportDiscoveredDevice,\n} from \"@ledgerhq/device-management-kit\";\nimport { Observable } from \"rxjs\";\n\nimport { uint8ArrayToBase64 } from \"@api/helpers/base64Utils\";\nimport { type NativeModuleWrapper } from \"@api/transport/NativeModuleWrapper\";\nimport {\n type InternalConnectionResult,\n type InternalDeviceDisconnected,\n} from \"@api/transport/types\";\n\nimport {\n mapNativeConnectionResultToConnectionResult,\n mapNativeDeviceConnectionLostToDeviceDisconnected,\n mapNativeDiscoveryDeviceToTransportDiscoveredDevice,\n mapNativeSendApduResultToSendApduResult,\n mapNativeTransportLogToLog,\n} from \"./mapper\";\nimport {\n DEVICE_DISCONNECTED_EVENT,\n type DeviceDisconnectedEventPayload,\n DISCOVERED_DEVICES_EVENT,\n type DiscoveredDevicesEventPayload,\n type NativeLog,\n TRANSPORT_LOG_EVENT,\n} from \"./types\";\nimport { type NativeTransportModuleType } from \"./types\";\n\nexport class DefaultNativeModuleWrapper implements NativeModuleWrapper {\n private readonly _nativeModule: NativeTransportModuleType;\n private readonly _deviceModelDataSource: DeviceModelDataSource;\n\n constructor(args: {\n nativeModule: NativeTransportModuleType;\n deviceModelDataSource: DeviceModelDataSource;\n }) {\n this._nativeModule = args.nativeModule;\n this._deviceModelDataSource = args.deviceModelDataSource;\n }\n\n startScan() {\n return this._nativeModule.startScan();\n }\n\n stopScan() {\n return this._nativeModule.stopScan();\n }\n\n subscribeToDiscoveredDevicesEvents(): Observable<\n Array<TransportDiscoveredDevice>\n > {\n return new Observable((subscriber) => {\n const eventEmitter = new NativeEventEmitter(this._nativeModule);\n const eventListener = eventEmitter.addListener(\n DISCOVERED_DEVICES_EVENT,\n (discoveredDevices: DiscoveredDevicesEventPayload) => {\n subscriber.next(\n discoveredDevices\n .map((device) =>\n mapNativeDiscoveryDeviceToTransportDiscoveredDevice(\n device,\n this._deviceModelDataSource,\n ),\n )\n .filter((d) => d !== null),\n );\n },\n );\n\n return () => {\n eventListener.remove();\n };\n });\n }\n\n subscribeToDeviceDisconnectedEvents(): Observable<InternalDeviceDisconnected> {\n return new Observable((subscriber) => {\n const eventEmitter = new NativeEventEmitter(this._nativeModule);\n const eventListener = eventEmitter.addListener(\n DEVICE_DISCONNECTED_EVENT,\n (device: DeviceDisconnectedEventPayload) => {\n subscriber.next(\n mapNativeDeviceConnectionLostToDeviceDisconnected(device),\n );\n },\n );\n\n return () => {\n eventListener.remove();\n };\n });\n }\n\n subscribeToTransportLogs(): Observable<LogParams> {\n return new Observable((subscriber) => {\n const eventEmitter = new NativeEventEmitter(this._nativeModule);\n const eventListener = eventEmitter.addListener(\n TRANSPORT_LOG_EVENT,\n (logParams: NativeLog) => {\n subscriber.next(mapNativeTransportLogToLog(logParams));\n },\n );\n\n return () => {\n eventListener.remove();\n };\n });\n }\n\n async connectDevice(uid: string): Promise<InternalConnectionResult> {\n const nConnectionResult = await this._nativeModule.connectDevice(uid);\n return mapNativeConnectionResultToConnectionResult(\n nConnectionResult,\n this._deviceModelDataSource,\n );\n }\n\n async disconnectDevice(sessionId: string): Promise<void> {\n return this._nativeModule.disconnectDevice(sessionId);\n }\n\n async sendApdu(\n sessionId: string,\n apdu: Uint8Array,\n triggersDisconnection: boolean,\n abortTimeout: number,\n ): Promise<SendApduResult> {\n const nSendApduResult = await this._nativeModule.sendApdu(\n sessionId,\n uint8ArrayToBase64(apdu),\n triggersDisconnection,\n abortTimeout,\n );\n return mapNativeSendApduResultToSendApduResult(nSendApduResult);\n }\n}\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAmC,wBAOnCC,EAA2B,gBAE3BC,EAAmC,oCAOnCC,EAMO,oBACPC,EAOO,mBAGA,MAAMN,CAA0D,CACpD,cACA,uBAEjB,YAAYO,EAGT,CACD,KAAK,cAAgBA,EAAK,aAC1B,KAAK,uBAAyBA,EAAK,qBACrC,CAEA,WAAY,CACV,OAAO,KAAK,cAAc,UAAU,CACtC,CAEA,UAAW,CACT,OAAO,KAAK,cAAc,SAAS,CACrC,CAEA,oCAEE,CACA,OAAO,IAAI,aAAYC,GAAe,CAEpC,MAAMC,EADe,IAAI,qBAAmB,KAAK,aAAa,EAC3B,YACjC,2BACCC,GAAqD,CACpDF,EAAW,KACTE,EACG,IAAKC,MACJ,uDACEA,EACA,KAAK,sBACP,CACF,EACC,OAAQC,GAAMA,IAAM,IAAI,CAC7B,CACF,CACF,EAEA,MAAO,IAAM,CACXH,EAAc,OAAO,CACvB,CACF,CAAC,CACH,CAEA,qCAA8E,CAC5E,OAAO,IAAI,aAAYD,GAAe,CAEpC,MAAMC,EADe,IAAI,qBAAmB,KAAK,aAAa,EAC3B,YACjC,4BACCE,GAA2C,CAC1CH,EAAW,QACT,qDAAkDG,CAAM,CAC1D,CACF,CACF,EAEA,MAAO,IAAM,CACXF,EAAc,OAAO,CACvB,CACF,CAAC,CACH,CAEA,0BAAkD,CAChD,OAAO,IAAI,aAAYD,GAAe,CAEpC,MAAMC,EADe,IAAI,qBAAmB,KAAK,aAAa,EAC3B,YACjC,sBACCI,GAAyB,CACxBL,EAAW,QAAK,8BAA2BK,CAAS,CAAC,CACvD,CACF,EAEA,MAAO,IAAM,CACXJ,EAAc,OAAO,CACvB,CACF,CAAC,CACH,CAEA,MAAM,cAAcK,EAAgD,CAClE,MAAMC,EAAoB,MAAM,KAAK,cAAc,cAAcD,CAAG,EACpE,SAAO,+CACLC,EACA,KAAK,sBACP,CACF,CAEA,MAAM,iBAAiBC,EAAkC,CACvD,OAAO,KAAK,cAAc,iBAAiBA,CAAS,CACtD,CAEA,MAAM,SACJA,EACAC,EACAC,EACAC,EACyB,CACzB,MAAMC,EAAkB,MAAM,KAAK,cAAc,SAC/CJ,KACA,sBAAmBC,CAAI,EACvBC,EACAC,CACF,EACA,SAAO,2CAAwCC,CAAe,CAChE,CACF",
6
+ "names": ["DefaultNativeModuleWrapper_exports", "__export", "DefaultNativeModuleWrapper", "__toCommonJS", "import_react_native", "import_rxjs", "import_base64Utils", "import_mapper", "import_types", "args", "subscriber", "eventListener", "discoveredDevices", "device", "d", "logParams", "uid", "nConnectionResult", "sessionId", "apdu", "triggersDisconnection", "abortTimeout", "nSendApduResult"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var s=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var D=Object.prototype.hasOwnProperty;var m=(e,t)=>{for(var o in t)s(e,o,{get:t[o],enumerable:!0})},f=(e,t,o,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of l(t))!D.call(e,i)&&i!==o&&s(e,i,{get:()=>t[i],enumerable:!(a=v(t,i))||a.enumerable});return e};var N=e=>f(s({},"__esModule",{value:!0}),e);var b={};m(b,{mapNativeConnectionResultToConnectionResult:()=>L,mapNativeDeviceConnectionLostToDeviceDisconnected:()=>T,mapNativeDiscoveryDeviceToTransportDiscoveredDevice:()=>g,mapNativeLedgerDeviceToDeviceModel:()=>c,mapNativeSendApduResultToSendApduResult:()=>R,mapNativeTransportLogToLog:()=>y});module.exports=N(b);var n=require("@ledgerhq/device-management-kit"),r=require("purify-ts"),d=require("../helpers/base64Utils"),u=require("../transport/Errors"),p=require("../transport/rnHidTransportIdentifier");function c(e,t){return t.filterDeviceModels({usbProductId:Number.parseInt(e.usbProductIdMask,16)})[0]??null}function g(e,t){const o=c(e.ledgerDevice,t);return o==null?null:{id:e.uid,deviceModel:o,transport:p.TRANSPORT_IDENTIFIER,name:e.name}}function y(e){let t;switch(e.level){case"error":t=n.LogLevel.Error;break;case"warning":t=n.LogLevel.Warning;break;case"info":t=n.LogLevel.Info;break;case"debug":t=n.LogLevel.Debug;break;default:I(e.level),t=n.LogLevel.Info;break}return[t,e.message,{tag:e.tag,data:e.jsonPayload,timestamp:Number.parseInt(e.timestamp,10)}]}function I(e){throw new Error("Unexpected object: "+e)}function L(e,t){if(e.success){const o=c(e.ledgerDevice,t);return o?(0,r.Right)({sessionId:e.sessionId,transportDeviceModel:o}):(0,r.Left)(new n.OpeningConnectionError(`Could not find device model for the connected device with usbProductIdMask: ${e.ledgerDevice.usbProductIdMask}`))}else return(0,r.Left)(new n.OpeningConnectionError(e.error))}function R(e){if(e.success){const t=(0,d.base64ToUint8Array)(e.apdu),o=n.FramerUtils.getFirstBytesFrom(t,t.length-2),a=n.FramerUtils.getLastBytesFrom(t,2);return(0,r.Right)(new n.ApduResponse({data:o,statusCode:a}))}else return(0,r.Left)(new u.SendApduError(e.error))}function T(e){return{sessionId:e.id}}0&&(module.exports={mapNativeConnectionResultToConnectionResult,mapNativeDeviceConnectionLostToDeviceDisconnected,mapNativeDiscoveryDeviceToTransportDiscoveredDevice,mapNativeLedgerDeviceToDeviceModel,mapNativeSendApduResultToSendApduResult,mapNativeTransportLogToLog});
1
+ "use strict";var c=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var D=Object.prototype.hasOwnProperty;var m=(e,t)=>{for(var r in t)c(e,r,{get:t[r],enumerable:!0})},f=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of l(t))!D.call(e,i)&&i!==r&&c(e,i,{get:()=>t[i],enumerable:!(s=v(t,i))||s.enumerable});return e};var y=e=>f(c({},"__esModule",{value:!0}),e);var b={};m(b,{mapNativeConnectionResultToConnectionResult:()=>R,mapNativeDeviceConnectionLostToDeviceDisconnected:()=>L,mapNativeDiscoveryDeviceToTransportDiscoveredDevice:()=>N,mapNativeLedgerDeviceToDeviceModel:()=>a,mapNativeSendApduResultToSendApduResult:()=>T,mapNativeTransportLogToLog:()=>g});module.exports=y(b);var n=require("@ledgerhq/device-management-kit"),o=require("purify-ts"),d=require("../helpers/base64Utils"),p=require("../transport/Errors"),u=require("../transport/rnHidTransportIdentifier");function a(e,t){return t.filterDeviceModels({usbProductId:Number.parseInt(e.usbProductIdMask,16)})[0]??null}function N(e,t){const r=a(e.ledgerDevice,t);return r==null?null:{id:e.uid,deviceModel:r,transport:u.TRANSPORT_IDENTIFIER,name:e.name}}function g(e){let t;switch(e.level){case"error":t=n.LogLevel.Error;break;case"warning":t=n.LogLevel.Warning;break;case"info":t=n.LogLevel.Info;break;case"debug":t=n.LogLevel.Debug;break;default:I(e.level),t=n.LogLevel.Info;break}return[t,e.message,{tag:e.tag,data:e.jsonPayload,timestamp:Number.parseInt(e.timestamp,10)}]}function I(e){throw new Error("Unexpected object: "+e)}function R(e,t){if(e.success){const r=a(e.ledgerDevice,t);return r?(0,o.Right)({sessionId:e.sessionId,transportDeviceModel:r}):(0,o.Left)(new n.OpeningConnectionError(`Could not find device model for the connected device with usbProductIdMask: ${e.ledgerDevice.usbProductIdMask}`))}else return(0,o.Left)(new n.OpeningConnectionError(e.error))}function T(e){if(e.success){const t=(0,d.base64ToUint8Array)(e.apdu),r=n.FramerUtils.getFirstBytesFrom(t,t.length-2),s=n.FramerUtils.getLastBytesFrom(t,2);return(0,o.Right)(new n.ApduResponse({data:r,statusCode:s}))}else return e.error==="SendApduTimeout"?(0,o.Left)(new n.SendApduTimeoutError("Abort timeout")):e.error==="EmptyResponse"?(0,o.Left)(new n.SendApduEmptyResponseError("Empty response")):e.error==="DeviceDisconnected"?(0,o.Left)(new n.DeviceDisconnectedWhileSendingError("Device disconnected")):(0,o.Left)(new p.HidTransportSendApduUnknownError(e.error))}function L(e){return{sessionId:e.id}}0&&(module.exports={mapNativeConnectionResultToConnectionResult,mapNativeDeviceConnectionLostToDeviceDisconnected,mapNativeDiscoveryDeviceToTransportDiscoveredDevice,mapNativeLedgerDeviceToDeviceModel,mapNativeSendApduResultToSendApduResult,mapNativeTransportLogToLog});
2
2
  //# sourceMappingURL=mapper.js.map