@ledgerhq/device-transport-kit-react-native-hid 0.0.0-develop-20250415001140
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.
- package/LICENSE.MD +202 -0
- package/README.md +84 -0
- package/android/build.gradle +101 -0
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/android/gradle.properties +1 -0
- package/android/gradlew +252 -0
- package/android/gradlew.bat +94 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/kotlin/com/ledger/androidtransporthid/BridgeEvents.kt +42 -0
- package/android/src/main/kotlin/com/ledger/androidtransporthid/TransportHidModule.kt +241 -0
- package/android/src/main/kotlin/com/ledger/androidtransporthid/TransportHidPackage.kt +25 -0
- package/android/src/main/kotlin/com/ledger/androidtransporthid/bridge/serialization.kt +124 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/AndroidUsbTransport.kt +16 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/DefaultAndroidUsbTransport.kt +298 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/UsbPermissionRequester.kt +18 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/connection/AndroidUsbApduSender.kt +133 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/controller/UsbAttachedReceiverController.kt +59 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/controller/UsbDetachedReceiverController.kt +58 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/controller/UsbPermissionReceiver.kt +92 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/model/LedgerUsbDevice.kt +16 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/model/ProductId.kt +11 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/model/UsbPermissionEvent.kt +14 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/model/UsbState.kt +16 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/model/VendorId.kt +11 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/utils/UsbDeviceMapper.kt +46 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/utils/UsbMapper.kt +56 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMainInternal/transport/UsbConst.android.kt +8 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMainInternal/transport/deviceconnection/DeviceApduSender.kt +13 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMainInternal/transport/deviceconnection/DeviceConnection.kt +95 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMainInternal/transport/deviceconnection/DeviceConnectionStateMachine.kt +314 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/apdu/Apdu.kt +44 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/apdu/ApduBuilder.kt +88 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/apdu/ApduParser.kt +37 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/apdu/ApduUtils.kt +37 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/apdu/SendApduResult.kt +47 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/connection/ConnectedDevice.kt +25 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/connection/ConnectionResult.kt +45 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/device/BleInformation.kt +8 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/device/LedgerDevice.kt +89 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/device/UsbInfo.kt +7 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/disconnection/DisconnectionResult.kt +10 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/discovery/ConnectivityType.kt +10 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/discovery/DiscoveryDevice.kt +18 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/discovery/DiscoveryResult.kt +28 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/utils/ByteArrayExtension.kt +116 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/utils/StringExtension.kt +21 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/connection/InternalConnectedDevice.kt +13 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/connection/InternalConnectionResult.kt +41 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/coroutine/SDKScope.kt +25 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/coroutine/SDKScopeHandler.kt +18 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/event/SdkEventDispatcher.kt +19 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/service/logger/DisableLoggerService.kt +12 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/service/logger/LogInfo.kt +52 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/service/logger/LogLevel.kt +13 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/service/logger/LoggerService.kt +10 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/transport/Transport.kt +21 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/transport/TransportEvent.kt +18 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/transport/framer/FramerService.kt +210 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/transport/framer/FramerUtils.kt +35 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/transport/framer/model/ApduConst.kt +9 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/transport/framer/model/ApduFrame.kt +66 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/transport/framer/model/ApduFramerHeader.kt +74 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/transport/framer/model/FramerConst.kt +14 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/transport/utils/ByteExtension.kt +21 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/transport/utils/InternalByteArrayExtension.kt +18 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/utils/Controller.kt +12 -0
- package/android/src/test/kotlin/com/ledger/devicesdk/shared/androidMainInternal/transport/deviceconnection/DeviceConnectionStateMachineTest.kt +713 -0
- package/android/src/test/kotlin/com/ledger/devicesdk/shared/androidMainInternal/transport/deviceconnection/DeviceConnectionTest.kt +218 -0
- package/lib/cjs/api/RNHidTransportFactory.js +2 -0
- package/lib/cjs/api/RNHidTransportFactory.js.map +7 -0
- package/lib/cjs/api/bridge/DefaultNativeModuleWrapper.js +2 -0
- package/lib/cjs/api/bridge/DefaultNativeModuleWrapper.js.map +7 -0
- package/lib/cjs/api/bridge/NativeTransportModule.js +2 -0
- package/lib/cjs/api/bridge/NativeTransportModule.js.map +7 -0
- package/lib/cjs/api/bridge/StubNativeModuleWrapper.js +2 -0
- package/lib/cjs/api/bridge/StubNativeModuleWrapper.js.map +7 -0
- package/lib/cjs/api/bridge/mapper.js +2 -0
- package/lib/cjs/api/bridge/mapper.js.map +7 -0
- package/lib/cjs/api/bridge/mapper.test.js +2 -0
- package/lib/cjs/api/bridge/mapper.test.js.map +7 -0
- package/lib/cjs/api/bridge/types.js +2 -0
- package/lib/cjs/api/bridge/types.js.map +7 -0
- package/lib/cjs/api/helpers/base64Utils.js +2 -0
- package/lib/cjs/api/helpers/base64Utils.js.map +7 -0
- package/lib/cjs/api/helpers/base64Utils.test.js +2 -0
- package/lib/cjs/api/helpers/base64Utils.test.js.map +7 -0
- package/lib/cjs/api/helpers/getObservableOfArraysNewItems.js +2 -0
- package/lib/cjs/api/helpers/getObservableOfArraysNewItems.js.map +7 -0
- package/lib/cjs/api/helpers/getObservableOfArraysNewItems.test.js +2 -0
- package/lib/cjs/api/helpers/getObservableOfArraysNewItems.test.js.map +7 -0
- package/lib/cjs/api/transport/Errors.js +2 -0
- package/lib/cjs/api/transport/Errors.js.map +7 -0
- package/lib/cjs/api/transport/NativeModuleWrapper.js +2 -0
- package/lib/cjs/api/transport/NativeModuleWrapper.js.map +7 -0
- package/lib/cjs/api/transport/RNHidTransport.js +2 -0
- package/lib/cjs/api/transport/RNHidTransport.js.map +7 -0
- package/lib/cjs/api/transport/RNHidTransport.test.js +2 -0
- package/lib/cjs/api/transport/RNHidTransport.test.js.map +7 -0
- package/lib/cjs/api/transport/rnHidTransportIdentifier.js +2 -0
- package/lib/cjs/api/transport/rnHidTransportIdentifier.js.map +7 -0
- package/lib/cjs/api/transport/types.js +2 -0
- package/lib/cjs/api/transport/types.js.map +7 -0
- package/lib/cjs/index.js +2 -0
- package/lib/cjs/index.js.map +7 -0
- package/lib/cjs/package.json +61 -0
- package/lib/esm/api/RNHidTransportFactory.js +2 -0
- package/lib/esm/api/RNHidTransportFactory.js.map +7 -0
- package/lib/esm/api/bridge/DefaultNativeModuleWrapper.js +2 -0
- package/lib/esm/api/bridge/DefaultNativeModuleWrapper.js.map +7 -0
- package/lib/esm/api/bridge/NativeTransportModule.js +2 -0
- package/lib/esm/api/bridge/NativeTransportModule.js.map +7 -0
- package/lib/esm/api/bridge/StubNativeModuleWrapper.js +2 -0
- package/lib/esm/api/bridge/StubNativeModuleWrapper.js.map +7 -0
- package/lib/esm/api/bridge/mapper.js +2 -0
- package/lib/esm/api/bridge/mapper.js.map +7 -0
- package/lib/esm/api/bridge/mapper.test.js +2 -0
- package/lib/esm/api/bridge/mapper.test.js.map +7 -0
- package/lib/esm/api/bridge/types.js +2 -0
- package/lib/esm/api/bridge/types.js.map +7 -0
- package/lib/esm/api/helpers/base64Utils.js +2 -0
- package/lib/esm/api/helpers/base64Utils.js.map +7 -0
- package/lib/esm/api/helpers/base64Utils.test.js +2 -0
- package/lib/esm/api/helpers/base64Utils.test.js.map +7 -0
- package/lib/esm/api/helpers/getObservableOfArraysNewItems.js +2 -0
- package/lib/esm/api/helpers/getObservableOfArraysNewItems.js.map +7 -0
- package/lib/esm/api/helpers/getObservableOfArraysNewItems.test.js +2 -0
- package/lib/esm/api/helpers/getObservableOfArraysNewItems.test.js.map +7 -0
- package/lib/esm/api/transport/Errors.js +2 -0
- package/lib/esm/api/transport/Errors.js.map +7 -0
- package/lib/esm/api/transport/NativeModuleWrapper.js +1 -0
- package/lib/esm/api/transport/NativeModuleWrapper.js.map +7 -0
- package/lib/esm/api/transport/RNHidTransport.js +2 -0
- package/lib/esm/api/transport/RNHidTransport.js.map +7 -0
- package/lib/esm/api/transport/RNHidTransport.test.js +2 -0
- package/lib/esm/api/transport/RNHidTransport.test.js.map +7 -0
- package/lib/esm/api/transport/rnHidTransportIdentifier.js +2 -0
- package/lib/esm/api/transport/rnHidTransportIdentifier.js.map +7 -0
- package/lib/esm/api/transport/types.js +1 -0
- package/lib/esm/api/transport/types.js.map +7 -0
- package/lib/esm/index.js +2 -0
- package/lib/esm/index.js.map +7 -0
- package/lib/esm/package.json +61 -0
- package/lib/types/api/RNHidTransportFactory.d.ts +3 -0
- package/lib/types/api/RNHidTransportFactory.d.ts.map +1 -0
- package/lib/types/api/bridge/DefaultNativeModuleWrapper.d.ts +22 -0
- package/lib/types/api/bridge/DefaultNativeModuleWrapper.d.ts.map +1 -0
- package/lib/types/api/bridge/NativeTransportModule.d.ts +3 -0
- package/lib/types/api/bridge/NativeTransportModule.d.ts.map +1 -0
- package/lib/types/api/bridge/StubNativeModuleWrapper.d.ts +15 -0
- package/lib/types/api/bridge/StubNativeModuleWrapper.d.ts.map +1 -0
- package/lib/types/api/bridge/mapper.d.ts +10 -0
- package/lib/types/api/bridge/mapper.d.ts.map +1 -0
- package/lib/types/api/bridge/mapper.test.d.ts +2 -0
- package/lib/types/api/bridge/mapper.test.d.ts.map +1 -0
- package/lib/types/api/bridge/types.d.ts +61 -0
- package/lib/types/api/bridge/types.d.ts.map +1 -0
- package/lib/types/api/helpers/base64Utils.d.ts +13 -0
- package/lib/types/api/helpers/base64Utils.d.ts.map +1 -0
- package/lib/types/api/helpers/base64Utils.test.d.ts +2 -0
- package/lib/types/api/helpers/base64Utils.test.d.ts.map +1 -0
- package/lib/types/api/helpers/getObservableOfArraysNewItems.d.ts +15 -0
- package/lib/types/api/helpers/getObservableOfArraysNewItems.d.ts.map +1 -0
- package/lib/types/api/helpers/getObservableOfArraysNewItems.test.d.ts +2 -0
- package/lib/types/api/helpers/getObservableOfArraysNewItems.test.d.ts.map +1 -0
- package/lib/types/api/transport/Errors.d.ts +7 -0
- package/lib/types/api/transport/Errors.d.ts.map +1 -0
- package/lib/types/api/transport/NativeModuleWrapper.d.ts +23 -0
- package/lib/types/api/transport/NativeModuleWrapper.d.ts.map +1 -0
- package/lib/types/api/transport/RNHidTransport.d.ts +23 -0
- package/lib/types/api/transport/RNHidTransport.d.ts.map +1 -0
- package/lib/types/api/transport/RNHidTransport.test.d.ts +2 -0
- package/lib/types/api/transport/RNHidTransport.test.d.ts.map +1 -0
- package/lib/types/api/transport/rnHidTransportIdentifier.d.ts +2 -0
- package/lib/types/api/transport/rnHidTransportIdentifier.d.ts.map +1 -0
- package/lib/types/api/transport/types.d.ts +12 -0
- package/lib/types/api/transport/types.d.ts.map +1 -0
- package/lib/types/index.d.ts +3 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/tsconfig.prod.tsbuildinfo +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
package com.ledger.devicesdk.shared.androidMainInternal.transport.deviceconnection
|
|
2
|
+
|
|
3
|
+
import com.ledger.devicesdk.shared.api.apdu.SendApduResult
|
|
4
|
+
import com.ledger.devicesdk.shared.internal.service.logger.LogInfo
|
|
5
|
+
import com.ledger.devicesdk.shared.internal.service.logger.LoggerService
|
|
6
|
+
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
7
|
+
import kotlinx.coroutines.async
|
|
8
|
+
import kotlinx.coroutines.test.StandardTestDispatcher
|
|
9
|
+
import kotlinx.coroutines.test.advanceTimeBy
|
|
10
|
+
import kotlinx.coroutines.test.runTest
|
|
11
|
+
import kotlin.time.Duration.Companion.seconds
|
|
12
|
+
import kotlin.test.Test
|
|
13
|
+
import org.junit.Assert.*
|
|
14
|
+
import kotlin.time.Duration.Companion.milliseconds
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Those tests focus mainly on calling all public methods, and ensuring that the correct apduSender
|
|
18
|
+
* is used after reconnections.
|
|
19
|
+
* For full coverage of the possible scenarios, check the unit tests of DeviceConnectionStateMachine.
|
|
20
|
+
*/
|
|
21
|
+
class DeviceConnectionTest {
|
|
22
|
+
@Test
|
|
23
|
+
fun `GIVEN a device connection with an APDU sender WHEN requestSendApdu is called THEN the apduSender is used and the result is obtained`() = runTest {
|
|
24
|
+
val apduSender = MockedApduSender()
|
|
25
|
+
|
|
26
|
+
val deviceConnection = DeviceConnection(
|
|
27
|
+
sessionId = "mockId",
|
|
28
|
+
deviceApduSender = apduSender,
|
|
29
|
+
onTerminated = { },
|
|
30
|
+
isFatalSendApduFailure = { false },
|
|
31
|
+
reconnectionTimeoutDuration = 5.seconds,
|
|
32
|
+
loggerService = FakeLoggerService(),
|
|
33
|
+
coroutineDispatcher = StandardTestDispatcher(testScheduler),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
// Request sending an APDU
|
|
37
|
+
deviceConnection.requestSendApdu(mockedApdu)
|
|
38
|
+
|
|
39
|
+
// Send APDU should have been called once with the correct apdu
|
|
40
|
+
assertEquals(1, apduSender.sendCalls.size)
|
|
41
|
+
assertArrayEquals(mockedApdu, apduSender.sendCalls[0])
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@Test
|
|
45
|
+
fun `GIVEN a device connection with an initial APDU sender and an APDU that triggers disconnection WHEN requestSendApdu is called and a reconnection occurs THEN the second apduSender is used and the result is obtained`() =
|
|
46
|
+
runTest {
|
|
47
|
+
apdusTriggeringDisconnection.forEach { apduTriggeringDisconnection ->
|
|
48
|
+
val apduSender1 = MockedApduSender()
|
|
49
|
+
apduSender1.nextResult = mockedSuccessApduResult
|
|
50
|
+
|
|
51
|
+
val deviceConnection = DeviceConnection(
|
|
52
|
+
sessionId = "mockId",
|
|
53
|
+
deviceApduSender = apduSender1,
|
|
54
|
+
onTerminated = { },
|
|
55
|
+
isFatalSendApduFailure = { false },
|
|
56
|
+
reconnectionTimeoutDuration = 5.seconds,
|
|
57
|
+
loggerService = FakeLoggerService(),
|
|
58
|
+
coroutineDispatcher = StandardTestDispatcher(testScheduler),
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
// Request sending an apdu
|
|
62
|
+
val result1 = deviceConnection.requestSendApdu(apduTriggeringDisconnection)
|
|
63
|
+
|
|
64
|
+
// apduSender1.sendApdu should have been called once with the correct apdu
|
|
65
|
+
assertEquals(1, apduSender1.sendCalls.size)
|
|
66
|
+
assertArrayEquals(apduTriggeringDisconnection, apduSender1.sendCalls[0])
|
|
67
|
+
|
|
68
|
+
// The result should have been obtained
|
|
69
|
+
assertEquals(mockedSuccessApduResult, result1)
|
|
70
|
+
|
|
71
|
+
// Request sending a second apdu
|
|
72
|
+
val result2 = async {
|
|
73
|
+
deviceConnection.requestSendApdu(mockedApdu)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// apduSender1.sendApdu shouldn't have been called again
|
|
77
|
+
assertEquals(1, apduSender1.sendCalls.size)
|
|
78
|
+
|
|
79
|
+
// Simulate reconnection
|
|
80
|
+
val apduSender2 = MockedApduSender()
|
|
81
|
+
apduSender2.nextResult = mockedSuccessApduResult
|
|
82
|
+
deviceConnection.handleDeviceConnected(apduSender2)
|
|
83
|
+
|
|
84
|
+
// The result should have been obtained
|
|
85
|
+
assertEquals(mockedSuccessApduResult, result2.await())
|
|
86
|
+
|
|
87
|
+
// apduSender2.sendApdu should have been called once with the correct apdu
|
|
88
|
+
assertEquals(1, apduSender2.sendCalls.size)
|
|
89
|
+
assertArrayEquals(mockedApdu, apduSender2.sendCalls[0])
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@OptIn(ExperimentalCoroutinesApi::class)
|
|
94
|
+
@Test
|
|
95
|
+
fun `GIVEN a device connection WHEN handleDeviceDisconnected is called and the timeout elapses THEN onTerminated is triggered`() =
|
|
96
|
+
runTest {
|
|
97
|
+
var terminated = false
|
|
98
|
+
val apduSender = MockedApduSender()
|
|
99
|
+
|
|
100
|
+
val deviceConnection = DeviceConnection(
|
|
101
|
+
sessionId = "mockId",
|
|
102
|
+
deviceApduSender = apduSender,
|
|
103
|
+
onTerminated = {
|
|
104
|
+
terminated = true
|
|
105
|
+
},
|
|
106
|
+
isFatalSendApduFailure = { false },
|
|
107
|
+
reconnectionTimeoutDuration = 5.seconds,
|
|
108
|
+
loggerService = FakeLoggerService(),
|
|
109
|
+
coroutineDispatcher = StandardTestDispatcher(testScheduler),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
// Simulate disconnection
|
|
113
|
+
deviceConnection.handleDeviceDisconnected()
|
|
114
|
+
|
|
115
|
+
// Timeout
|
|
116
|
+
advanceTimeBy(5.seconds)
|
|
117
|
+
assertFalse(terminated)
|
|
118
|
+
advanceTimeBy(1.milliseconds)
|
|
119
|
+
assertTrue(terminated)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@Test
|
|
123
|
+
fun `GIVEN a disconnected device connection WHEN a device gets reconnected and an APDU is requested THEN the correct apduSender is used and the result is obtained`() =
|
|
124
|
+
runTest {
|
|
125
|
+
val apduSender1 = MockedApduSender()
|
|
126
|
+
|
|
127
|
+
val deviceConnection = DeviceConnection(
|
|
128
|
+
sessionId = "mockId",
|
|
129
|
+
deviceApduSender = apduSender1,
|
|
130
|
+
onTerminated = { },
|
|
131
|
+
isFatalSendApduFailure = { false },
|
|
132
|
+
reconnectionTimeoutDuration = 5.seconds,
|
|
133
|
+
loggerService = FakeLoggerService(),
|
|
134
|
+
coroutineDispatcher = StandardTestDispatcher(testScheduler),
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
// Simulate disconnection
|
|
138
|
+
deviceConnection.handleDeviceDisconnected()
|
|
139
|
+
|
|
140
|
+
// Request sending an APDU
|
|
141
|
+
val result = async {
|
|
142
|
+
deviceConnection.requestSendApdu(mockedApdu)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Simulate reconnection
|
|
146
|
+
val apduSender2 = MockedApduSender()
|
|
147
|
+
deviceConnection.handleDeviceConnected(apduSender2)
|
|
148
|
+
|
|
149
|
+
// The result should have been obtained
|
|
150
|
+
assertEquals(mockedSuccessApduResult, result.await())
|
|
151
|
+
|
|
152
|
+
// apduSender1.sendApdu should not have been called
|
|
153
|
+
assertEquals(0, apduSender1.sendCalls.size)
|
|
154
|
+
|
|
155
|
+
// apduSender2.sendApdu should have been called once with the correct apdu
|
|
156
|
+
assertEquals(1, apduSender2.sendCalls.size)
|
|
157
|
+
assertArrayEquals(mockedApdu, apduSender2.sendCalls[0])
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@Test
|
|
161
|
+
fun `GIVEN a device connection WHEN requestCloseConnection is called THEN onTerminated is triggered`() = runTest {
|
|
162
|
+
var terminated = false
|
|
163
|
+
|
|
164
|
+
val deviceConnection = DeviceConnection(
|
|
165
|
+
sessionId = "mockId",
|
|
166
|
+
deviceApduSender = MockedApduSender(),
|
|
167
|
+
onTerminated = {
|
|
168
|
+
terminated = true
|
|
169
|
+
},
|
|
170
|
+
isFatalSendApduFailure = { false },
|
|
171
|
+
reconnectionTimeoutDuration = 5.seconds,
|
|
172
|
+
loggerService = FakeLoggerService(),
|
|
173
|
+
coroutineDispatcher = StandardTestDispatcher(testScheduler),
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
// Request closing connection
|
|
177
|
+
deviceConnection.requestCloseConnection()
|
|
178
|
+
|
|
179
|
+
// onTerminated should have been called
|
|
180
|
+
assertTrue(terminated)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Helpers
|
|
184
|
+
companion object {
|
|
185
|
+
|
|
186
|
+
val mockedApdu: ByteArray = byteArrayOf(0x01, 0x02)
|
|
187
|
+
|
|
188
|
+
val apdusTriggeringDisconnection: List<ByteArray> = listOf(
|
|
189
|
+
byteArrayOf(0xe0.toByte(), 0xd8.toByte(), 0x01), // Open app
|
|
190
|
+
byteArrayOf(0xe0.toByte(), 0xd8.toByte(), 0x01) // Close app
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
val mockedSuccessApduResult =
|
|
194
|
+
SendApduResult.Success(byteArrayOf(0x05, 0x06, 0x90.toByte(), 0x00))
|
|
195
|
+
|
|
196
|
+
class MockedApduSender() : DeviceApduSender<String> {
|
|
197
|
+
// can be set from the outside for easy mocking
|
|
198
|
+
var nextResult: SendApduResult = mockedSuccessApduResult
|
|
199
|
+
|
|
200
|
+
private val _sendCalls: MutableList<ByteArray> = mutableListOf()
|
|
201
|
+
// to easily check from the outside the apdus sent
|
|
202
|
+
val sendCalls: MutableList<ByteArray>
|
|
203
|
+
get() = _sendCalls
|
|
204
|
+
|
|
205
|
+
override suspend fun send(apdu: ByteArray): SendApduResult {
|
|
206
|
+
_sendCalls += apdu
|
|
207
|
+
return nextResult
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
override val dependencies: String
|
|
211
|
+
get() = ""
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
internal class FakeLoggerService : LoggerService {
|
|
215
|
+
override fun log(info: LogInfo) {}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var p=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var c=(o,r)=>{for(var t in r)p(o,t,{get:r[t],enumerable:!0})},v=(o,r,t,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let e of f(r))!l.call(o,e)&&e!==t&&p(o,e,{get:()=>r[e],enumerable:!(a=u(r,e))||a.enumerable});return o};var M=o=>v(p({},"__esModule",{value:!0}),o);var T={};c(T,{RNHidTransportFactory:()=>N});module.exports=M(T);var i=require("react-native"),n=require("./bridge/DefaultNativeModuleWrapper"),m=require("./bridge/StubNativeModuleWrapper"),d=require("./transport/RNHidTransport"),s=require("./bridge/NativeTransportModule");const N=({deviceModelDataSource:o,loggerServiceFactory:r})=>{const t=i.Platform.OS==="android",a=i.Platform.OS==="android"?new n.DefaultNativeModuleWrapper({nativeModule:s.NativeTransportModule,deviceModelDataSource:o}):new m.StubNativeModuleWrapper;return new d.RNHidTransport(t,a,r)};0&&(module.exports={RNHidTransportFactory});
|
|
2
|
+
//# sourceMappingURL=RNHidTransportFactory.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/api/RNHidTransportFactory.ts"],
|
|
4
|
+
"sourcesContent": ["import { Platform } from \"react-native\";\nimport type { TransportFactory } from \"@ledgerhq/device-management-kit\";\n\nimport { DefaultNativeModuleWrapper } from \"@api/bridge/DefaultNativeModuleWrapper\";\nimport { StubNativeModuleWrapper } from \"@api/bridge/StubNativeModuleWrapper\";\nimport { RNHidTransport } from \"@api/transport/RNHidTransport\";\n\nimport { NativeTransportModule } from \"./bridge/NativeTransportModule\";\n\nexport const RNHidTransportFactory: TransportFactory = ({\n deviceModelDataSource,\n loggerServiceFactory,\n}) => {\n const isSupported = Platform.OS === \"android\";\n const nativeModuleWrapper =\n Platform.OS === \"android\"\n ? new DefaultNativeModuleWrapper({\n nativeModule: NativeTransportModule,\n deviceModelDataSource,\n })\n : new StubNativeModuleWrapper();\n\n return new RNHidTransport(\n isSupported,\n nativeModuleWrapper,\n loggerServiceFactory,\n );\n};\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,2BAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAyB,wBAGzBC,EAA2C,kDAC3CC,EAAwC,+CACxCC,EAA+B,yCAE/BC,EAAsC,0CAE/B,MAAMN,EAA0C,CAAC,CACtD,sBAAAO,EACA,qBAAAC,CACF,IAAM,CACJ,MAAMC,EAAc,WAAS,KAAO,UAC9BC,EACJ,WAAS,KAAO,UACZ,IAAI,6BAA2B,CAC7B,aAAc,wBACd,sBAAAH,CACF,CAAC,EACD,IAAI,0BAEV,OAAO,IAAI,iBACTE,EACAC,EACAF,CACF,CACF",
|
|
6
|
+
"names": ["RNHidTransportFactory_exports", "__export", "RNHidTransportFactory", "__toCommonJS", "import_react_native", "import_DefaultNativeModuleWrapper", "import_StubNativeModuleWrapper", "import_RNHidTransport", "import_NativeTransportModule", "deviceModelDataSource", "loggerServiceFactory", "isSupported", "nativeModuleWrapper"]
|
|
7
|
+
}
|
|
@@ -0,0 +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});
|
|
2
|
+
//# sourceMappingURL=DefaultNativeModuleWrapper.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 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"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var p=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var l=(e,o)=>{for(var r in o)p(e,r,{get:o[r],enumerable:!0})},n=(e,o,r,a)=>{if(o&&typeof o=="object"||typeof o=="function")for(let t of i(o))!d.call(e,t)&&t!==r&&p(e,t,{get:()=>o[t],enumerable:!(a=T(o,t))||a.enumerable});return e};var u=e=>n(p({},"__esModule",{value:!0}),e);var m={};l(m,{NativeTransportModule:()=>M});module.exports=u(m);var s=require("react-native");const M=s.NativeModules.RCTTransportHIDModule;0&&(module.exports={NativeTransportModule});
|
|
2
|
+
//# sourceMappingURL=NativeTransportModule.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/bridge/NativeTransportModule.ts"],
|
|
4
|
+
"sourcesContent": ["import { NativeModules } from \"react-native\";\n\nimport type { NativeTransportModuleType } from \"./types\";\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\nexport const NativeTransportModule: NativeTransportModuleType =\n NativeModules[\"RCTTransportHIDModule\"];\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,2BAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAA8B,wBAKvB,MAAMF,EACX,gBAAc",
|
|
6
|
+
"names": ["NativeTransportModule_exports", "__export", "NativeTransportModule", "__toCommonJS", "import_react_native"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var s=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var m=(r,e)=>{for(var o in e)s(r,o,{get:e[o],enumerable:!0})},d=(r,e,o,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of c(e))!p.call(r,t)&&t!==o&&s(r,t,{get:()=>e[t],enumerable:!(i=a(e,t))||i.enumerable});return r};var v=r=>d(s({},"__esModule",{value:!0}),r);var u={};m(u,{StubNativeModuleWrapper:()=>l});module.exports=v(u);var n=require("rxjs");class l{startScan(){return Promise.resolve()}stopScan(){return Promise.resolve()}subscribeToDiscoveredDevicesEvents(){return(0,n.from)([])}subscribeToTransportLogs(){return(0,n.from)([])}connectDevice(){throw new Error("Method not implemented.")}disconnectDevice(){throw new Error("Method not implemented.")}sendApdu(){throw new Error("Method not implemented.")}subscribeToDeviceDisconnectedEvents(){return(0,n.from)([])}}0&&(module.exports={StubNativeModuleWrapper});
|
|
2
|
+
//# sourceMappingURL=StubNativeModuleWrapper.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/bridge/StubNativeModuleWrapper.ts"],
|
|
4
|
+
"sourcesContent": ["import type {\n LogParams,\n SendApduResult,\n TransportDiscoveredDevice,\n} from \"@ledgerhq/device-management-kit\";\nimport { from, type Observable } from \"rxjs\";\n\nimport { type NativeModuleWrapper } from \"@api/transport/NativeModuleWrapper\";\nimport type {\n InternalConnectionResult,\n InternalDeviceDisconnected,\n} from \"@api/transport/types\";\n\nexport class StubNativeModuleWrapper implements NativeModuleWrapper {\n startScan() {\n return Promise.resolve();\n }\n\n stopScan() {\n return Promise.resolve();\n }\n\n subscribeToDiscoveredDevicesEvents(): Observable<\n Array<TransportDiscoveredDevice>\n > {\n return from([]);\n }\n\n subscribeToTransportLogs(): Observable<LogParams> {\n return from([]);\n }\n\n connectDevice(): Promise<InternalConnectionResult> {\n throw new Error(\"Method not implemented.\");\n }\n\n disconnectDevice(): Promise<void> {\n throw new Error(\"Method not implemented.\");\n }\n\n sendApdu(): Promise<SendApduResult> {\n throw new Error(\"Method not implemented.\");\n }\n\n subscribeToDeviceDisconnectedEvents(): Observable<InternalDeviceDisconnected> {\n return from([]);\n }\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,6BAAAE,IAAA,eAAAC,EAAAH,GAKA,IAAAI,EAAsC,gBAQ/B,MAAMF,CAAuD,CAClE,WAAY,CACV,OAAO,QAAQ,QAAQ,CACzB,CAEA,UAAW,CACT,OAAO,QAAQ,QAAQ,CACzB,CAEA,oCAEE,CACA,SAAO,QAAK,CAAC,CAAC,CAChB,CAEA,0BAAkD,CAChD,SAAO,QAAK,CAAC,CAAC,CAChB,CAEA,eAAmD,CACjD,MAAM,IAAI,MAAM,yBAAyB,CAC3C,CAEA,kBAAkC,CAChC,MAAM,IAAI,MAAM,yBAAyB,CAC3C,CAEA,UAAoC,CAClC,MAAM,IAAI,MAAM,yBAAyB,CAC3C,CAEA,qCAA8E,CAC5E,SAAO,QAAK,CAAC,CAAC,CAChB,CACF",
|
|
6
|
+
"names": ["StubNativeModuleWrapper_exports", "__export", "StubNativeModuleWrapper", "__toCommonJS", "import_rxjs"]
|
|
7
|
+
}
|
|
@@ -0,0 +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});
|
|
2
|
+
//# sourceMappingURL=mapper.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/bridge/mapper.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n ApduResponse,\n type DeviceModelDataSource,\n FramerUtils,\n LogLevel,\n type LogParams,\n OpeningConnectionError,\n type SendApduResult,\n type TransportDeviceModel,\n type TransportDiscoveredDevice,\n} from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\n\nimport { base64ToUint8Array } from \"@api/helpers/base64Utils\";\nimport { SendApduError } from \"@api/transport/Errors\";\nimport { TRANSPORT_IDENTIFIER } from \"@api/transport/rnHidTransportIdentifier\";\nimport {\n type InternalConnectionResult,\n type InternalDeviceDisconnected,\n} from \"@api/transport/types\";\n\nimport {\n type NativeDeviceConnectionLost,\n type NativeDiscoveryDevice,\n type NativeInternalConnectionResult,\n type NativeLedgerDevice,\n type NativeLog,\n type NativeSendApduResult,\n} from \"./types\";\n\nexport function mapNativeLedgerDeviceToDeviceModel(\n nativeLedgerDevice: NativeLedgerDevice,\n deviceModelDataSource: DeviceModelDataSource,\n): TransportDeviceModel | null {\n return (\n deviceModelDataSource.filterDeviceModels({\n usbProductId: Number.parseInt(nativeLedgerDevice.usbProductIdMask, 16),\n })[0] ?? null\n );\n}\n\nexport function mapNativeDiscoveryDeviceToTransportDiscoveredDevice(\n nativeDevice: NativeDiscoveryDevice,\n deviceModelDataSource: DeviceModelDataSource,\n): TransportDiscoveredDevice | null {\n const deviceModel = mapNativeLedgerDeviceToDeviceModel(\n nativeDevice.ledgerDevice,\n deviceModelDataSource,\n );\n if (deviceModel == null) return null;\n\n return {\n id: nativeDevice.uid,\n deviceModel,\n transport: TRANSPORT_IDENTIFIER,\n name: nativeDevice.name,\n };\n}\n\nexport function mapNativeTransportLogToLog(log: NativeLog): LogParams {\n let level: LogLevel;\n switch (log.level) {\n case \"error\":\n level = LogLevel.Error;\n break;\n case \"warning\":\n level = LogLevel.Warning;\n break;\n case \"info\":\n level = LogLevel.Info;\n break;\n case \"debug\":\n level = LogLevel.Debug;\n break;\n default:\n assertNever(log.level);\n level = LogLevel.Info;\n break;\n }\n\n return [\n level,\n log.message,\n {\n tag: log.tag,\n data: log.jsonPayload,\n timestamp: Number.parseInt(log.timestamp, 10),\n },\n ];\n}\n\nfunction assertNever(x: never) {\n throw new Error(\"Unexpected object: \" + x);\n}\n\nexport function mapNativeConnectionResultToConnectionResult(\n result: NativeInternalConnectionResult,\n deviceModelDataSource: DeviceModelDataSource,\n): InternalConnectionResult {\n if (result.success) {\n const transportDeviceModel = mapNativeLedgerDeviceToDeviceModel(\n result.ledgerDevice,\n deviceModelDataSource,\n );\n if (!transportDeviceModel)\n return Left(\n new OpeningConnectionError(\n `Could not find device model for the connected device with usbProductIdMask: ${result.ledgerDevice.usbProductIdMask}`,\n ),\n );\n return Right({ sessionId: result.sessionId, transportDeviceModel });\n } else {\n return Left(new OpeningConnectionError(result.error));\n }\n}\n\nexport function mapNativeSendApduResultToSendApduResult(\n result: NativeSendApduResult,\n): SendApduResult {\n if (result.success) {\n const responseBytes = base64ToUint8Array(result.apdu);\n const data = FramerUtils.getFirstBytesFrom(\n responseBytes,\n responseBytes.length - 2,\n );\n const statusCode = FramerUtils.getLastBytesFrom(responseBytes, 2);\n return Right(new ApduResponse({ data, statusCode }));\n } else {\n return Left(new SendApduError(result.error));\n }\n}\n\nexport function mapNativeDeviceConnectionLostToDeviceDisconnected(\n nativeDeviceConnectionLost: NativeDeviceConnectionLost,\n): InternalDeviceDisconnected {\n return {\n sessionId: nativeDeviceConnectionLost.id,\n };\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iDAAAE,EAAA,sDAAAC,EAAA,wDAAAC,EAAA,uCAAAC,EAAA,4CAAAC,EAAA,+BAAAC,IAAA,eAAAC,EAAAR,GAAA,IAAAS,EAUO,2CACPC,EAA4B,qBAE5BC,EAAmC,oCACnCC,EAA8B,iCAC9BC,EAAqC,mDAe9B,SAASR,EACdS,EACAC,EAC6B,CAC7B,OACEA,EAAsB,mBAAmB,CACvC,aAAc,OAAO,SAASD,EAAmB,iBAAkB,EAAE,CACvE,CAAC,EAAE,CAAC,GAAK,IAEb,CAEO,SAASV,EACdY,EACAD,EACkC,CAClC,MAAME,EAAcZ,EAClBW,EAAa,aACbD,CACF,EACA,OAAIE,GAAe,KAAa,KAEzB,CACL,GAAID,EAAa,IACjB,YAAAC,EACA,UAAW,uBACX,KAAMD,EAAa,IACrB,CACF,CAEO,SAAST,EAA2BW,EAA2B,CACpE,IAAIC,EACJ,OAAQD,EAAI,MAAO,CACjB,IAAK,QACHC,EAAQ,WAAS,MACjB,MACF,IAAK,UACHA,EAAQ,WAAS,QACjB,MACF,IAAK,OACHA,EAAQ,WAAS,KACjB,MACF,IAAK,QACHA,EAAQ,WAAS,MACjB,MACF,QACEC,EAAYF,EAAI,KAAK,EACrBC,EAAQ,WAAS,KACjB,KACJ,CAEA,MAAO,CACLA,EACAD,EAAI,QACJ,CACE,IAAKA,EAAI,IACT,KAAMA,EAAI,YACV,UAAW,OAAO,SAASA,EAAI,UAAW,EAAE,CAC9C,CACF,CACF,CAEA,SAASE,EAAYC,EAAU,CAC7B,MAAM,IAAI,MAAM,sBAAwBA,CAAC,CAC3C,CAEO,SAASnB,EACdoB,EACAP,EAC0B,CAC1B,GAAIO,EAAO,QAAS,CAClB,MAAMC,EAAuBlB,EAC3BiB,EAAO,aACPP,CACF,EACA,OAAKQ,KAME,SAAM,CAAE,UAAWD,EAAO,UAAW,qBAAAC,CAAqB,CAAC,KALzD,QACL,IAAI,yBACF,+EAA+ED,EAAO,aAAa,gBAAgB,EACrH,CACF,CAEJ,KACE,UAAO,QAAK,IAAI,yBAAuBA,EAAO,KAAK,CAAC,CAExD,CAEO,SAAShB,EACdgB,EACgB,CAChB,GAAIA,EAAO,QAAS,CAClB,MAAME,KAAgB,sBAAmBF,EAAO,IAAI,EAC9CG,EAAO,cAAY,kBACvBD,EACAA,EAAc,OAAS,CACzB,EACME,EAAa,cAAY,iBAAiBF,EAAe,CAAC,EAChE,SAAO,SAAM,IAAI,eAAa,CAAE,KAAAC,EAAM,WAAAC,CAAW,CAAC,CAAC,CACrD,KACE,UAAO,QAAK,IAAI,gBAAcJ,EAAO,KAAK,CAAC,CAE/C,CAEO,SAASnB,EACdwB,EAC4B,CAC5B,MAAO,CACL,UAAWA,EAA2B,EACxC,CACF",
|
|
6
|
+
"names": ["mapper_exports", "__export", "mapNativeConnectionResultToConnectionResult", "mapNativeDeviceConnectionLostToDeviceDisconnected", "mapNativeDiscoveryDeviceToTransportDiscoveredDevice", "mapNativeLedgerDeviceToDeviceModel", "mapNativeSendApduResultToSendApduResult", "mapNativeTransportLogToLog", "__toCommonJS", "import_device_management_kit", "import_purify_ts", "import_base64Utils", "import_Errors", "import_rnHidTransportIdentifier", "nativeLedgerDevice", "deviceModelDataSource", "nativeDevice", "deviceModel", "log", "level", "assertNever", "x", "result", "transportDeviceModel", "responseBytes", "data", "statusCode", "nativeDeviceConnectionLost"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("@ledgerhq/device-management-kit"),n=require("purify-ts"),c=require("../transport/Errors"),d=require("../transport/rnHidTransportIdentifier"),o=require("./mapper");describe("mapper",()=>{const a=new e.StaticDeviceModelDataSource;describe("mapNativeLedgerDeviceToDeviceModel",()=>{[{nativeLedgerDevice:{name:"NanoS",usbProductIdMask:"0x10"},deviceModel:a.getDeviceModel({id:e.DeviceModelId.NANO_S})},{nativeLedgerDevice:{name:"NanoX",usbProductIdMask:"0x40"},deviceModel:a.getDeviceModel({id:e.DeviceModelId.NANO_X})},{nativeLedgerDevice:{name:"NanoSPlus",usbProductIdMask:"0x50"},deviceModel:a.getDeviceModel({id:e.DeviceModelId.NANO_SP})},{nativeLedgerDevice:{name:"Stax",usbProductIdMask:"0x60"},deviceModel:a.getDeviceModel({id:e.DeviceModelId.STAX})},{nativeLedgerDevice:{name:"Flex",usbProductIdMask:"0x70"},deviceModel:a.getDeviceModel({id:e.DeviceModelId.FLEX})},{nativeLedgerDevice:{name:"NanoX",usbProductIdMask:"0x12345678"},deviceModel:null}].forEach(({nativeLedgerDevice:t,deviceModel:i})=>{it(`should map USB device with usbProductIdMask ${t.usbProductIdMask} to ${i?.productName??"null"}`,()=>{expect((0,o.mapNativeLedgerDeviceToDeviceModel)(t,a)).toEqual(i)})})}),describe("mapNativeDiscoveryDeviceToTransportDiscoveredDevice",()=>{it("should map NativeDiscoveryDevice to TransportDiscoveredDevice",()=>{const s={name:"NanoS",uid:"abcd",ledgerDevice:{name:"NanoS",usbProductIdMask:"0x10"}},t={id:"abcd",deviceModel:a.getDeviceModel({id:e.DeviceModelId.NANO_S}),transport:d.TRANSPORT_IDENTIFIER,name:"NanoS"};expect((0,o.mapNativeDiscoveryDeviceToTransportDiscoveredDevice)(s,a)).toEqual(t)}),it("should return null if the device model is not recognized",()=>{const s={name:"NanoX",uid:"efgh",ledgerDevice:{name:"NanoX",usbProductIdMask:"0x4567890"}};expect((0,o.mapNativeDiscoveryDeviceToTransportDiscoveredDevice)(s,a)).toEqual(null)})}),describe("mapNativeTransportLogToLog",()=>{[{nativeLog:{level:"debug",tag:"tag",message:"debug message",jsonPayload:{key:"value"},timestamp:"123456789"},log:[e.LogLevel.Debug,"debug message",{timestamp:123456789,tag:"tag",data:{key:"value"}}]},{nativeLog:{level:"info",tag:"tag",message:"info message",jsonPayload:{key:"value"},timestamp:"123456789"},log:[e.LogLevel.Info,"info message",{timestamp:123456789,tag:"tag",data:{key:"value"}}]},{nativeLog:{level:"error",tag:"tag",message:"error message",jsonPayload:{key:"value"},timestamp:"123456789"},log:[e.LogLevel.Error,"error message",{timestamp:123456789,tag:"tag",data:{key:"value"}}]},{nativeLog:{level:"warning",tag:"tag",message:"warning message",jsonPayload:{key:"value"},timestamp:"123456789"},log:[e.LogLevel.Warning,"warning message",{timestamp:123456789,tag:"tag",data:{key:"value"}}]}].forEach(({nativeLog:t,log:i})=>{it(`should map NativeLog with level "${t.level}" to Log`,()=>{expect((0,o.mapNativeTransportLogToLog)(t)).toEqual(i)})})}),describe("mapNativeConnectionResultToConnectionResult",()=>{[{testTitle:"Success",nativeConnectionResult:{success:!0,sessionId:"1234",ledgerDevice:{name:"NanoS",usbProductIdMask:"0x10"},deviceName:"NanoS"},connectionResult:(0,n.Right)({sessionId:"1234",transportDeviceModel:a.getDeviceModel({id:e.DeviceModelId.NANO_S})})},{testTitle:"Failure",nativeConnectionResult:{success:!1,error:"error message"},connectionResult:(0,n.Left)(new e.OpeningConnectionError("error message"))},{testTitle:"Unknown device model",nativeConnectionResult:{success:!0,sessionId:"1234",ledgerDevice:{name:"NanoX",usbProductIdMask:"0x12345678"},deviceName:"NanoX"},connectionResult:(0,n.Left)(new e.OpeningConnectionError("Could not find device model for the connected device with usbProductIdMask: 0x12345678"))}].forEach(({testTitle:t,nativeConnectionResult:i,connectionResult:r})=>{it(t,()=>{expect((0,o.mapNativeConnectionResultToConnectionResult)(i,a)).toEqual(r)})})}),describe("mapNativeSendApduResultToSendApduResult",()=>{test("success",()=>{const t={success:!0,apdu:"AQIDkAA="},i=(0,n.Right)(new e.ApduResponse({data:new Uint8Array([1,2,3]),statusCode:new Uint8Array([144,0])}));expect((0,o.mapNativeSendApduResultToSendApduResult)(t)).toEqual(i)}),test("failure",()=>{const s={success:!1,error:"error message"},t=(0,n.Left)(new c.SendApduError("error message"));expect((0,o.mapNativeSendApduResultToSendApduResult)(s)).toEqual(t)})}),describe("mapNativeDeviceConnectionLostToDeviceDisconnected",()=>{it("should map NativeDeviceConnectionLost to DeviceDisconnected",()=>{const s={id:"1234"},t={sessionId:"1234"};expect((0,o.mapNativeDeviceConnectionLostToDeviceDisconnected)(s)).toEqual(t)})})});
|
|
2
|
+
//# sourceMappingURL=mapper.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/bridge/mapper.test.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n ApduResponse,\n DeviceModelId,\n LogLevel,\n type LogParams,\n OpeningConnectionError,\n type SendApduResult,\n StaticDeviceModelDataSource,\n type TransportDeviceModel,\n type TransportDiscoveredDevice,\n} from \"@ledgerhq/device-management-kit\";\nimport { Left, Right } from \"purify-ts\";\n\nimport { SendApduError } from \"@api/transport/Errors\";\nimport { TRANSPORT_IDENTIFIER } from \"@api/transport/rnHidTransportIdentifier\";\nimport { type InternalConnectionResult } from \"@api/transport/types\";\n\nimport {\n mapNativeConnectionResultToConnectionResult,\n mapNativeDeviceConnectionLostToDeviceDisconnected,\n mapNativeDiscoveryDeviceToTransportDiscoveredDevice,\n mapNativeLedgerDeviceToDeviceModel,\n mapNativeSendApduResultToSendApduResult,\n mapNativeTransportLogToLog,\n} from \"./mapper\";\nimport {\n type NativeDiscoveryDevice,\n type NativeInternalConnectionResult,\n type NativeLedgerDevice,\n type NativeLog,\n type NativeSendApduResult,\n} from \"./types\";\n\ndescribe(\"mapper\", () => {\n const deviceModelDataSource = new StaticDeviceModelDataSource();\n\n describe(\"mapNativeLedgerDeviceToDeviceModel\", () => {\n const testCases: Array<{\n nativeLedgerDevice: NativeLedgerDevice;\n deviceModel: TransportDeviceModel | null;\n }> = [\n {\n nativeLedgerDevice: {\n name: \"NanoS\",\n usbProductIdMask: \"0x10\",\n },\n deviceModel: deviceModelDataSource.getDeviceModel({\n id: DeviceModelId.NANO_S,\n }),\n },\n {\n nativeLedgerDevice: {\n name: \"NanoX\",\n usbProductIdMask: \"0x40\",\n },\n deviceModel: deviceModelDataSource.getDeviceModel({\n id: DeviceModelId.NANO_X,\n }),\n },\n {\n nativeLedgerDevice: {\n name: \"NanoSPlus\",\n usbProductIdMask: \"0x50\",\n },\n deviceModel: deviceModelDataSource.getDeviceModel({\n id: DeviceModelId.NANO_SP,\n }),\n },\n {\n nativeLedgerDevice: {\n name: \"Stax\",\n usbProductIdMask: \"0x60\",\n },\n deviceModel: deviceModelDataSource.getDeviceModel({\n id: DeviceModelId.STAX,\n }),\n },\n {\n nativeLedgerDevice: {\n name: \"Flex\",\n usbProductIdMask: \"0x70\",\n },\n deviceModel: deviceModelDataSource.getDeviceModel({\n id: DeviceModelId.FLEX,\n }),\n },\n {\n nativeLedgerDevice: {\n name: \"NanoX\",\n usbProductIdMask: \"0x12345678\",\n },\n deviceModel: null, // because the usbProductIdMask is not recognized\n },\n ];\n testCases.forEach(({ nativeLedgerDevice, deviceModel }) => {\n it(`should map USB device with usbProductIdMask ${nativeLedgerDevice.usbProductIdMask} to ${\n deviceModel?.productName ?? \"null\"\n }`, () => {\n expect(\n mapNativeLedgerDeviceToDeviceModel(\n nativeLedgerDevice,\n deviceModelDataSource,\n ),\n ).toEqual(deviceModel);\n });\n });\n });\n\n describe(\"mapNativeDiscoveryDeviceToTransportDiscoveredDevice\", () => {\n it(\"should map NativeDiscoveryDevice to TransportDiscoveredDevice\", () => {\n const nativeDevice: NativeDiscoveryDevice = {\n name: \"NanoS\",\n uid: \"abcd\",\n ledgerDevice: {\n name: \"NanoS\",\n usbProductIdMask: \"0x10\",\n },\n };\n const expectedDiscoveredDevice: TransportDiscoveredDevice = {\n id: \"abcd\",\n deviceModel: deviceModelDataSource.getDeviceModel({\n id: DeviceModelId.NANO_S,\n }),\n transport: TRANSPORT_IDENTIFIER,\n name: \"NanoS\",\n };\n expect(\n mapNativeDiscoveryDeviceToTransportDiscoveredDevice(\n nativeDevice,\n deviceModelDataSource,\n ),\n ).toEqual(expectedDiscoveredDevice);\n });\n\n it(\"should return null if the device model is not recognized\", () => {\n const nativeDevice: NativeDiscoveryDevice = {\n name: \"NanoX\",\n uid: \"efgh\",\n ledgerDevice: {\n name: \"NanoX\",\n usbProductIdMask: \"0x4567890\", // some invalid value\n },\n };\n const expectedDiscoveredDevice = null; // because the usbProductIdMask is not recognized\n expect(\n mapNativeDiscoveryDeviceToTransportDiscoveredDevice(\n nativeDevice,\n deviceModelDataSource,\n ),\n ).toEqual(expectedDiscoveredDevice);\n });\n });\n\n describe(\"mapNativeTransportLogToLog\", () => {\n const testCases: Array<{\n nativeLog: NativeLog;\n log: LogParams;\n }> = [\n {\n // debug\n nativeLog: {\n level: \"debug\",\n tag: \"tag\",\n message: \"debug message\",\n jsonPayload: { key: \"value\" },\n timestamp: \"123456789\",\n },\n log: [\n LogLevel.Debug,\n \"debug message\",\n {\n timestamp: 123456789,\n tag: \"tag\",\n data: { key: \"value\" },\n },\n ],\n },\n // info\n {\n nativeLog: {\n level: \"info\",\n tag: \"tag\",\n message: \"info message\",\n jsonPayload: { key: \"value\" },\n timestamp: \"123456789\",\n },\n log: [\n LogLevel.Info,\n \"info message\",\n {\n timestamp: 123456789,\n tag: \"tag\",\n data: { key: \"value\" },\n },\n ],\n },\n // error\n {\n nativeLog: {\n level: \"error\",\n tag: \"tag\",\n message: \"error message\",\n jsonPayload: { key: \"value\" },\n timestamp: \"123456789\",\n },\n log: [\n LogLevel.Error,\n \"error message\",\n {\n timestamp: 123456789,\n tag: \"tag\",\n data: { key: \"value\" },\n },\n ],\n },\n // warning\n {\n nativeLog: {\n level: \"warning\",\n tag: \"tag\",\n message: \"warning message\",\n jsonPayload: { key: \"value\" },\n timestamp: \"123456789\",\n },\n log: [\n LogLevel.Warning,\n \"warning message\",\n {\n timestamp: 123456789,\n tag: \"tag\",\n data: { key: \"value\" },\n },\n ],\n },\n ];\n\n testCases.forEach(({ nativeLog, log }) => {\n it(`should map NativeLog with level \"${nativeLog.level}\" to Log`, () => {\n expect(mapNativeTransportLogToLog(nativeLog)).toEqual(log);\n });\n });\n });\n\n describe(\"mapNativeConnectionResultToConnectionResult\", () => {\n const testCases: Array<{\n nativeConnectionResult: NativeInternalConnectionResult;\n connectionResult: InternalConnectionResult;\n testTitle: string;\n }> = [\n {\n testTitle: \"Success\",\n nativeConnectionResult: {\n success: true,\n sessionId: \"1234\",\n ledgerDevice: {\n name: \"NanoS\",\n usbProductIdMask: \"0x10\",\n },\n deviceName: \"NanoS\",\n },\n connectionResult: Right({\n sessionId: \"1234\",\n transportDeviceModel: deviceModelDataSource.getDeviceModel({\n id: DeviceModelId.NANO_S,\n }),\n }),\n },\n {\n testTitle: \"Failure\",\n nativeConnectionResult: {\n success: false,\n error: \"error message\",\n },\n connectionResult: Left(new OpeningConnectionError(\"error message\")),\n },\n {\n testTitle: \"Unknown device model\",\n nativeConnectionResult: {\n success: true,\n sessionId: \"1234\",\n ledgerDevice: {\n name: \"NanoX\",\n usbProductIdMask: \"0x12345678\",\n },\n deviceName: \"NanoX\",\n },\n connectionResult: Left(\n new OpeningConnectionError(\n \"Could not find device model for the connected device with usbProductIdMask: 0x12345678\",\n ),\n ),\n },\n ];\n\n testCases.forEach(\n ({ testTitle, nativeConnectionResult, connectionResult }) => {\n it(testTitle, () => {\n expect(\n mapNativeConnectionResultToConnectionResult(\n nativeConnectionResult,\n deviceModelDataSource,\n ),\n ).toEqual(connectionResult);\n });\n },\n );\n });\n\n describe(\"mapNativeSendApduResultToSendApduResult\", () => {\n test(\"success\", () => {\n const resultApduString = \"AQIDkAA=\";\n const nativeSendApduResult: NativeSendApduResult = {\n success: true,\n apdu: resultApduString,\n };\n const expectedSendApduResult: SendApduResult = Right(\n new ApduResponse({\n data: new Uint8Array([0x01, 0x02, 0x03]),\n statusCode: new Uint8Array([0x90, 0x00]),\n }),\n );\n expect(\n mapNativeSendApduResultToSendApduResult(nativeSendApduResult),\n ).toEqual(expectedSendApduResult);\n });\n\n test(\"failure\", () => {\n const nativeSendApduResult: NativeSendApduResult = {\n success: false,\n error: \"error message\",\n };\n const expectedSendApduResult: SendApduResult = Left(\n new SendApduError(\"error message\"),\n );\n expect(\n mapNativeSendApduResultToSendApduResult(nativeSendApduResult),\n ).toEqual(expectedSendApduResult);\n });\n });\n\n describe(\"mapNativeDeviceConnectionLostToDeviceDisconnected\", () => {\n it(\"should map NativeDeviceConnectionLost to DeviceDisconnected\", () => {\n const nativeDeviceConnectionLost = {\n id: \"1234\",\n };\n const expectedDeviceDisconnected = {\n sessionId: \"1234\",\n };\n expect(\n mapNativeDeviceConnectionLostToDeviceDisconnected(\n nativeDeviceConnectionLost,\n ),\n ).toEqual(expectedDeviceDisconnected);\n });\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_device_management_kit", "import_purify_ts", "import_Errors", "import_rnHidTransportIdentifier", "import_mapper", "deviceModelDataSource", "nativeLedgerDevice", "deviceModel", "nativeDevice", "expectedDiscoveredDevice", "nativeLog", "log", "testTitle", "nativeConnectionResult", "connectionResult", "nativeSendApduResult", "expectedSendApduResult", "nativeDeviceConnectionLost", "expectedDeviceDisconnected"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var o=Object.defineProperty;var n=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var v=(t,e)=>{for(var s in e)o(t,s,{get:e[s],enumerable:!0})},d=(t,e,s,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of a(e))!c.call(t,i)&&i!==s&&o(t,i,{get:()=>e[i],enumerable:!(r=n(e,i))||r.enumerable});return t};var p=t=>d(o({},"__esModule",{value:!0}),t);var u={};v(u,{DEVICE_DISCONNECTED_EVENT:()=>D,DISCOVERED_DEVICES_EVENT:()=>g,TRANSPORT_LOG_EVENT:()=>N});module.exports=p(u);const g="DiscoveredDevices",N="TransportLog",D="DeviceDisconnected";0&&(module.exports={DEVICE_DISCONNECTED_EVENT,DISCOVERED_DEVICES_EVENT,TRANSPORT_LOG_EVENT});
|
|
2
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/bridge/types.ts"],
|
|
4
|
+
"sourcesContent": ["import { type NativeModule } from \"react-native\";\n\nexport type NativeLedgerDevice = {\n name: \"NanoS\" | \"NanoSPlus\" | \"NanoX\" | \"Flex\" | \"Stax\";\n usbProductIdMask: string;\n};\n\nexport type NativeDiscoveryDevice = {\n uid: string;\n name: string;\n ledgerDevice: NativeLedgerDevice;\n};\n\ntype NativeLogLevel = \"debug\" | \"info\" | \"warning\" | \"error\";\n\nexport type NativeLog = {\n level: NativeLogLevel;\n tag: string;\n message: string;\n jsonPayload: Record<string, string>;\n timestamp: string;\n};\n\nexport type NativeInternalConnectionResult =\n | {\n success: true;\n sessionId: string;\n ledgerDevice: NativeLedgerDevice;\n deviceName: string;\n }\n | {\n success: false;\n error: string;\n };\n\nexport type NativeSendApduResult =\n | {\n success: true;\n apdu: string;\n }\n | {\n success: false;\n error: string;\n };\n\nexport type NativeDeviceConnectionLost = {\n id: string;\n};\n\n/**\n * Events\n */\n\n/** DiscoveredDevices */\nexport const DISCOVERED_DEVICES_EVENT = \"DiscoveredDevices\";\nexport type DiscoveredDevicesEventPayload = Array<NativeDiscoveryDevice>;\n\n/** TransportLog */\nexport const TRANSPORT_LOG_EVENT = \"TransportLog\";\nexport type LogEventPayload = NativeLog;\n\n/** DeviceDisconnected */\nexport const DEVICE_DISCONNECTED_EVENT = \"DeviceDisconnected\";\nexport type DeviceDisconnectedEventPayload = NativeDeviceConnectionLost;\n\n/**\n * Signature of the native transport module.\n */\nexport type NativeTransportModuleType = {\n startScan: () => Promise<void>;\n stopScan: () => Promise<void>;\n connectDevice: (uid: string) => Promise<NativeInternalConnectionResult>;\n disconnectDevice: (sessionId: string) => Promise<void>;\n sendApdu: (sessionId: string, apdu: string) => Promise<NativeSendApduResult>;\n} & NativeModule;\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,+BAAAE,EAAA,6BAAAC,EAAA,wBAAAC,IAAA,eAAAC,EAAAL,GAsDO,MAAMG,EAA2B,oBAI3BC,EAAsB,eAItBF,EAA4B",
|
|
6
|
+
"names": ["types_exports", "__export", "DEVICE_DISCONNECTED_EVENT", "DISCOVERED_DEVICES_EVENT", "TRANSPORT_LOG_EVENT", "__toCommonJS"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var i=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var u=(t,r)=>{for(var n in r)i(t,n,{get:r[n],enumerable:!0})},b=(t,r,n,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of s(r))!y.call(t,o)&&o!==n&&i(t,o,{get:()=>r[o],enumerable:!(e=a(r,o))||e.enumerable});return t};var A=t=>b(i({},"__esModule",{value:!0}),t);var f={};u(f,{base64ToUint8Array:()=>g,uint8ArrayToBase64:()=>c});module.exports=A(f);function c(t){const r=t.reduce((n,e)=>(n+=String.fromCharCode(e),n),"");return btoa(r)}function g(t){const r=atob(t),n=new Uint8Array(r.length);for(let e=0;e<r.length;e++)n[e]=r.charCodeAt(e);return n}0&&(module.exports={base64ToUint8Array,uint8ArrayToBase64});
|
|
2
|
+
//# sourceMappingURL=base64Utils.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/helpers/base64Utils.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Encodes a Uint8Array to a Base64-encoded string.\n * @param byteArray - The Uint8Array to encode.\n * @returns A Base64-encoded string representing the byte array.\n */\nexport function uint8ArrayToBase64(byteArray: Uint8Array): string {\n const binary = byteArray.reduce((acc, byte) => {\n acc += String.fromCharCode(byte);\n return acc;\n }, \"\");\n return btoa(binary);\n}\n\n/**\n * Decodes a Base64-encoded string to a Uint8Array.\n * @param base64 - The Base64-encoded string to decode.\n * @returns A Uint8Array representing the decoded byte array.\n */\nexport function base64ToUint8Array(base64: string): Uint8Array {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,wBAAAE,EAAA,uBAAAC,IAAA,eAAAC,EAAAJ,GAKO,SAASG,EAAmBE,EAA+B,CAChE,MAAMC,EAASD,EAAU,OAAO,CAACE,EAAKC,KACpCD,GAAO,OAAO,aAAaC,CAAI,EACxBD,GACN,EAAE,EACL,OAAO,KAAKD,CAAM,CACpB,CAOO,SAASJ,EAAmBO,EAA4B,CAC7D,MAAMH,EAAS,KAAKG,CAAM,EACpBC,EAAQ,IAAI,WAAWJ,EAAO,MAAM,EAC1C,QAASK,EAAI,EAAGA,EAAIL,EAAO,OAAQK,IACjCD,EAAMC,CAAC,EAAIL,EAAO,WAAWK,CAAC,EAEhC,OAAOD,CACT",
|
|
6
|
+
"names": ["base64Utils_exports", "__export", "base64ToUint8Array", "uint8ArrayToBase64", "__toCommonJS", "byteArray", "binary", "acc", "byte", "base64", "bytes", "i"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("./base64Utils");const t="AQIDkAA=",a=new Uint8Array([1,2,3,144,0]);describe("base64Utils",()=>{describe("uint8ArrayToBase64",()=>{it("converts a Uint8Array to a Base64-encoded string",()=>{const r=(0,e.uint8ArrayToBase64)(a);expect(r).toBe(t)})}),describe("base64ToUint8Array",()=>{it("converts a Base64-encoded string to a Uint8Array",()=>{const r=(0,e.base64ToUint8Array)(t);expect(r).toEqual(a)})})});
|
|
2
|
+
//# sourceMappingURL=base64Utils.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/helpers/base64Utils.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { base64ToUint8Array, uint8ArrayToBase64 } from \"./base64Utils\";\n\nconst someBase64 = \"AQIDkAA=\";\nconst someUint8Array = new Uint8Array([0x01, 0x02, 0x03, 0x90, 0x00]);\n\ndescribe(\"base64Utils\", () => {\n describe(\"uint8ArrayToBase64\", () => {\n it(\"converts a Uint8Array to a Base64-encoded string\", () => {\n const base64 = uint8ArrayToBase64(someUint8Array);\n expect(base64).toBe(someBase64);\n });\n });\n\n describe(\"base64ToUint8Array\", () => {\n it(\"converts a Base64-encoded string to a Uint8Array\", () => {\n const byteArray = base64ToUint8Array(someBase64);\n expect(byteArray).toEqual(someUint8Array);\n });\n });\n});\n"],
|
|
5
|
+
"mappings": "aAAA,IAAAA,EAAuD,yBAEvD,MAAMC,EAAa,WACbC,EAAiB,IAAI,WAAW,CAAC,EAAM,EAAM,EAAM,IAAM,CAAI,CAAC,EAEpE,SAAS,cAAe,IAAM,CAC5B,SAAS,qBAAsB,IAAM,CACnC,GAAG,mDAAoD,IAAM,CAC3D,MAAMC,KAAS,sBAAmBD,CAAc,EAChD,OAAOC,CAAM,EAAE,KAAKF,CAAU,CAChC,CAAC,CACH,CAAC,EAED,SAAS,qBAAsB,IAAM,CACnC,GAAG,mDAAoD,IAAM,CAC3D,MAAMG,KAAY,sBAAmBH,CAAU,EAC/C,OAAOG,CAAS,EAAE,QAAQF,CAAc,CAC1C,CAAC,CACH,CAAC,CACH,CAAC",
|
|
6
|
+
"names": ["import_base64Utils", "someBase64", "someUint8Array", "base64", "byteArray"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var s=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var O=Object.prototype.hasOwnProperty;var l=(r,e)=>{for(var t in e)s(r,t,{get:e[t],enumerable:!0})},n=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let b of m(e))!O.call(r,b)&&b!==t&&s(r,b,{get:()=>e[b],enumerable:!(i=p(e,b))||i.enumerable});return r};var o=r=>n(s({},"__esModule",{value:!0}),r);var T={};l(T,{getObservableOfArraysNewItems:()=>v});module.exports=o(T);var a=require("rxjs");function v(r,e){return r.pipe((0,a.mergeMap)(t=>t),(0,a.distinct)(e))}0&&(module.exports={getObservableOfArraysNewItems});
|
|
2
|
+
//# sourceMappingURL=getObservableOfArraysNewItems.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/helpers/getObservableOfArraysNewItems.ts"],
|
|
4
|
+
"sourcesContent": ["import { distinct, mergeMap, type Observable } from \"rxjs\";\n\n/**\n * Returns an Observable that emits each unique item from arrays emitted by the source Observable.\n *\n * This function flattens the arrays emitted by the source Observable and uses the provided keySelector\n * to determine uniqueness. Each item is emitted only once, even if it appears in multiple arrays.\n *\n * @template T - The type of items in the arrays.\n * @template K - The type of the unique key extracted from each item.\n * @param observable - An Observable that emits arrays of items.\n * @param keySelector - A function that extracts a unique key from an item.\n * @returns An Observable emitting each unique item exactly once.\n */\nexport function getObservableOfArraysNewItems<T, K>(\n observable: Observable<Array<T>>,\n keySelector: (item: T) => K,\n): Observable<T> {\n return observable.pipe(\n mergeMap((items) => items),\n distinct(keySelector),\n );\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,mCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAoD,gBAc7C,SAASF,EACdG,EACAC,EACe,CACf,OAAOD,EAAW,QAChB,YAAUE,GAAUA,CAAK,KACzB,YAASD,CAAW,CACtB,CACF",
|
|
6
|
+
"names": ["getObservableOfArraysNewItems_exports", "__export", "getObservableOfArraysNewItems", "__toCommonJS", "import_rxjs", "observable", "keySelector", "items"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var t=require("rxjs"),r=require("./getObservableOfArraysNewItems");describe("getObservableOfArraysNewItems",()=>{it("transforms an Observable of arrays into an Observable that emits only new items",()=>new Promise((d,s)=>{const o=(0,t.from)([[{id:1},{id:2}],[{id:1},{id:2},{id:3}],[{id:1},{id:2},{id:3}],[{id:1},{id:2},{id:4}],[],[{id:1}]]),a=(0,r.getObservableOfArraysNewItems)(o,e=>e.id),m=[{id:1},{id:2},{id:3},{id:4},{id:1}];let i=0;a.subscribe({next:e=>{try{expect(e).toEqual(m[i]),i+=1}catch(b){s(b)}},complete:()=>{d()}})}))});
|
|
2
|
+
//# sourceMappingURL=getObservableOfArraysNewItems.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/helpers/getObservableOfArraysNewItems.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { from } from \"rxjs\";\n\nimport { getObservableOfArraysNewItems } from \"./getObservableOfArraysNewItems\";\n\ntype Item = { id: number };\n\ndescribe(\"getObservableOfArraysNewItems\", () => {\n it(\"transforms an Observable of arrays into an Observable that emits only new items\", () =>\n new Promise<void>((resolve, reject) => {\n const observable = from([\n [{ id: 1 }, { id: 2 }], // new items: [{ id: 1 }, { id: 2 }]\n [{ id: 1 }, { id: 2 }, { id: 3 }], // new items: [{ id: 3 }]\n [{ id: 1 }, { id: 2 }, { id: 3 }], // no new items: []\n [{ id: 1 }, { id: 2 }, { id: 4 }], // new items: [{ id: 4 }]\n [], // no new items: []\n [{ id: 1 }], // new items: [{ id: 1 }]\n ]);\n const result = getObservableOfArraysNewItems(\n observable,\n (a: Item) => a.id,\n );\n const expectedValues = [\n { id: 1 },\n { id: 2 },\n { id: 3 },\n { id: 4 },\n { id: 1 },\n ];\n\n let index = 0;\n result.subscribe({\n next: (value) => {\n try {\n expect(value).toEqual(expectedValues[index]);\n index += 1;\n } catch (e) {\n reject(e);\n }\n },\n complete: () => {\n resolve();\n },\n });\n }));\n});\n"],
|
|
5
|
+
"mappings": "aAAA,IAAAA,EAAqB,gBAErBC,EAA8C,2CAI9C,SAAS,gCAAiC,IAAM,CAC9C,GAAG,kFAAmF,IACpF,IAAI,QAAc,CAACC,EAASC,IAAW,CACrC,MAAMC,KAAa,QAAK,CACtB,CAAC,CAAE,GAAI,CAAE,EAAG,CAAE,GAAI,CAAE,CAAC,EACrB,CAAC,CAAE,GAAI,CAAE,EAAG,CAAE,GAAI,CAAE,EAAG,CAAE,GAAI,CAAE,CAAC,EAChC,CAAC,CAAE,GAAI,CAAE,EAAG,CAAE,GAAI,CAAE,EAAG,CAAE,GAAI,CAAE,CAAC,EAChC,CAAC,CAAE,GAAI,CAAE,EAAG,CAAE,GAAI,CAAE,EAAG,CAAE,GAAI,CAAE,CAAC,EAChC,CAAC,EACD,CAAC,CAAE,GAAI,CAAE,CAAC,CACZ,CAAC,EACKC,KAAS,iCACbD,EACCE,GAAYA,EAAE,EACjB,EACMC,EAAiB,CACrB,CAAE,GAAI,CAAE,EACR,CAAE,GAAI,CAAE,EACR,CAAE,GAAI,CAAE,EACR,CAAE,GAAI,CAAE,EACR,CAAE,GAAI,CAAE,CACV,EAEA,IAAIC,EAAQ,EACZH,EAAO,UAAU,CACf,KAAOI,GAAU,CACf,GAAI,CACF,OAAOA,CAAK,EAAE,QAAQF,EAAeC,CAAK,CAAC,EAC3CA,GAAS,CACX,OAASE,EAAG,CACVP,EAAOO,CAAC,CACV,CACF,EACA,SAAU,IAAM,CACdR,EAAQ,CACV,CACF,CAAC,CACH,CAAC,CAAC,CACN,CAAC",
|
|
6
|
+
"names": ["import_rxjs", "import_getObservableOfArraysNewItems", "resolve", "reject", "observable", "result", "a", "expectedValues", "index", "value", "e"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var d=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var l=(n,r)=>{for(var o in r)d(n,o,{get:r[o],enumerable:!0})},c=(n,r,o,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let e of s(r))!u.call(n,e)&&e!==o&&d(n,e,{get:()=>r[e],enumerable:!(t=p(r,e))||t.enumerable});return n};var i=n=>c(d({},"__esModule",{value:!0}),n);var m={};l(m,{SendApduError:()=>k});module.exports=i(m);var a=require("@ledgerhq/device-management-kit");class k extends a.GeneralDmkError{constructor(o){super(o);this.err=o}_tag="HidTransportSendApduUnknownError"}0&&(module.exports={SendApduError});
|
|
2
|
+
//# sourceMappingURL=Errors.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/transport/Errors.ts"],
|
|
4
|
+
"sourcesContent": ["import { GeneralDmkError } from \"@ledgerhq/device-management-kit\";\n\nexport class SendApduError extends GeneralDmkError {\n override readonly _tag = \"HidTransportSendApduUnknownError\";\n constructor(readonly err?: unknown) {\n super(err);\n }\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,mBAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAgC,2CAEzB,MAAMF,UAAsB,iBAAgB,CAEjD,YAAqBG,EAAe,CAClC,MAAMA,CAAG,EADU,SAAAA,CAErB,CAHkB,KAAO,kCAI3B",
|
|
6
|
+
"names": ["Errors_exports", "__export", "SendApduError", "__toCommonJS", "import_device_management_kit", "err"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var n=Object.defineProperty;var t=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var d=(r,e,o,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of c(e))!a.call(r,s)&&s!==o&&n(r,s,{get:()=>e[s],enumerable:!(i=t(e,s))||i.enumerable});return r};var v=r=>d(n({},"__esModule",{value:!0}),r);var p={};module.exports=v(p);
|
|
2
|
+
//# sourceMappingURL=NativeModuleWrapper.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/transport/NativeModuleWrapper.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n type LogParams,\n type SendApduResult,\n type TransportDiscoveredDevice,\n} from \"@ledgerhq/device-management-kit\";\nimport { type Observable } from \"rxjs\";\n\nimport {\n type InternalConnectionResult,\n type InternalDeviceDisconnected,\n} from \"./types\";\n\n/**\n * Interface for the native module wrapper.\n * This interface is used to abstract the native module implementation & its\n * types, basically the implementation of the \"bridge\".\n * It is useful in case the (future) iOS native module signature is different\n * from the Android one.\n * It allows the RNHidTransport implementation to be platform-agnostic and\n * independent from the native module implementation.\n */\nexport interface NativeModuleWrapper {\n startScan(): Promise<void>;\n stopScan(): Promise<void>;\n subscribeToDiscoveredDevicesEvents(): Observable<\n Array<TransportDiscoveredDevice>\n >;\n subscribeToDeviceDisconnectedEvents(): Observable<InternalDeviceDisconnected>;\n subscribeToTransportLogs(): Observable<LogParams>;\n connectDevice(uid: string): Promise<InternalConnectionResult>;\n disconnectDevice(uid: string): Promise<void>;\n sendApdu(sessionId: string, apdu: Uint8Array): Promise<SendApduResult>;\n}\n"],
|
|
5
|
+
"mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
|
+
"names": ["NativeModuleWrapper_exports", "__toCommonJS"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var v=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var S=(n,r)=>{for(var t in r)v(n,t,{get:r[t],enumerable:!0})},T=(n,r,t,i)=>{if(r&&typeof r=="object"||typeof r=="function")for(let e of D(r))!_.call(n,e)&&e!==t&&v(n,e,{get:()=>r[e],enumerable:!(i=h(r,e))||i.enumerable});return n};var m=n=>T(v({},"__esModule",{value:!0}),n);var E={};S(E,{RNHidTransport:()=>f});module.exports=m(E);var o=require("@ledgerhq/device-management-kit"),s=require("purify-ts"),d=require("rxjs"),g=require("../helpers/getObservableOfArraysNewItems"),l=require("../transport/rnHidTransportIdentifier"),u=require("./Errors");class f{constructor(r,t,i){this._isSupported=r;this._nativeModuleWrapper=t;this._loggerService=i("RNHidTransport"),this._nativeModuleWrapper.subscribeToTransportLogs().subscribe(e=>{const[a,c,p]=e,b={[o.LogLevel.Fatal]:this._loggerService.error.bind(this._loggerService),[o.LogLevel.Error]:this._loggerService.error.bind(this._loggerService),[o.LogLevel.Warning]:this._loggerService.warn.bind(this._loggerService),[o.LogLevel.Info]:this._loggerService.info.bind(this._loggerService),[o.LogLevel.Debug]:this._loggerService.debug.bind(this._loggerService)}[a];b(c,p)})}_loggerService;getIdentifier(){return l.TRANSPORT_IDENTIFIER}isSupported(){return this._isSupported}startDiscovering(){return new d.Observable(t=>{const i=(0,g.getObservableOfArraysNewItems)(this._nativeModuleWrapper.subscribeToDiscoveredDevicesEvents(),e=>e.id).subscribe(t);return this._nativeModuleWrapper.startScan().catch(e=>{t.error(e),this._loggerService.error("startDiscovering error",e)}),()=>i.unsubscribe()})}stopDiscovering(){this._nativeModuleWrapper.stopScan().catch(r=>{this._loggerService.error("stopDiscovering error",r)})}listenToAvailableDevices(){return new d.Observable(t=>{const i=this._nativeModuleWrapper.subscribeToDiscoveredDevicesEvents().subscribe(e=>{t.next(e)});return this._nativeModuleWrapper.startScan().catch(e=>{this._loggerService.error("startDiscovering error",e),t.error(e)}),()=>{i.unsubscribe(),this._nativeModuleWrapper.stopScan().catch(e=>{this._loggerService.error("stopDiscovering error",e)})}})}connect(r){return this._nativeModuleWrapper.connectDevice(r.deviceId).then(t=>t.map(({sessionId:i,transportDeviceModel:e})=>{const a=this._nativeModuleWrapper.subscribeToDeviceDisconnectedEvents().subscribe(c=>{c.sessionId===i&&(r.onDisconnect(i),a.unsubscribe())});return new o.TransportConnectedDevice({id:i,deviceModel:e,sendApdu:async c=>this._nativeModuleWrapper.sendApdu(i,c).catch(p=>(0,s.Left)(new u.SendApduError(p))),transport:this.getIdentifier(),type:"USB"})})).catch(t=>(0,s.Left)(new o.OpeningConnectionError(t)))}disconnect(r){return this._nativeModuleWrapper.disconnectDevice(r.connectedDevice.id).then(()=>(0,s.Right)(void 0)).catch(t=>(0,s.Left)(new o.DisconnectError(t)))}}0&&(module.exports={RNHidTransport});
|
|
2
|
+
//# sourceMappingURL=RNHidTransport.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/api/transport/RNHidTransport.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n type ConnectError,\n type DeviceId,\n DisconnectError,\n type DisconnectHandler,\n type DmkError,\n type LoggerPublisherService,\n LogLevel,\n OpeningConnectionError,\n type Transport,\n TransportConnectedDevice,\n type TransportDiscoveredDevice,\n type TransportIdentifier,\n} from \"@ledgerhq/device-management-kit\";\nimport { type Either, Left, Right } from \"purify-ts\";\nimport { Observable } from \"rxjs\";\n\nimport { getObservableOfArraysNewItems } from \"@api/helpers/getObservableOfArraysNewItems\";\nimport { TRANSPORT_IDENTIFIER } from \"@api/transport/rnHidTransportIdentifier\";\n\nimport { SendApduError } from \"./Errors\";\nimport { type NativeModuleWrapper } from \"./NativeModuleWrapper\";\n\nexport class RNHidTransport implements Transport {\n private _loggerService: LoggerPublisherService;\n\n constructor(\n private readonly _isSupported: boolean,\n private readonly _nativeModuleWrapper: NativeModuleWrapper,\n _loggerServiceFactory: (tag: string) => LoggerPublisherService,\n ) {\n this._loggerService = _loggerServiceFactory(\"RNHidTransport\");\n this._nativeModuleWrapper.subscribeToTransportLogs().subscribe((log) => {\n const [logLevel, message, options] = log;\n const logMethod = {\n [LogLevel.Fatal]: this._loggerService.error.bind(this._loggerService),\n [LogLevel.Error]: this._loggerService.error.bind(this._loggerService),\n [LogLevel.Warning]: this._loggerService.warn.bind(this._loggerService),\n [LogLevel.Info]: this._loggerService.info.bind(this._loggerService),\n [LogLevel.Debug]: this._loggerService.debug.bind(this._loggerService),\n }[logLevel];\n logMethod(message, options);\n });\n }\n\n getIdentifier(): TransportIdentifier {\n return TRANSPORT_IDENTIFIER;\n }\n\n isSupported(): boolean {\n return this._isSupported;\n }\n\n startDiscovering(): Observable<TransportDiscoveredDevice> {\n const observable = new Observable<TransportDiscoveredDevice>(\n (subscriber) => {\n const subscription = getObservableOfArraysNewItems(\n this._nativeModuleWrapper.subscribeToDiscoveredDevicesEvents(),\n (device) => device.id,\n ).subscribe(subscriber);\n\n this._nativeModuleWrapper.startScan().catch((error) => {\n subscriber.error(error);\n this._loggerService.error(\"startDiscovering error\", error);\n });\n return () => subscription.unsubscribe();\n },\n );\n return observable;\n }\n\n stopDiscovering(): void {\n this._nativeModuleWrapper.stopScan().catch((error) => {\n this._loggerService.error(\"stopDiscovering error\", error);\n });\n }\n\n listenToAvailableDevices(): Observable<TransportDiscoveredDevice[]> {\n /**\n * NB: here we need to define the unsubscribe logic as there is no\n * \"stopListeningToKnownDevices\" method.\n * That's why we create a new observable rather than returning the one\n * returned by subscribeToDiscoveredDevicesEvents.\n */\n const observable = new Observable<TransportDiscoveredDevice[]>(\n (subscriber) => {\n const subscription = this._nativeModuleWrapper\n .subscribeToDiscoveredDevicesEvents()\n .subscribe((devices) => {\n subscriber.next(devices);\n });\n this._nativeModuleWrapper.startScan().catch((error) => {\n this._loggerService.error(\"startDiscovering error\", error);\n subscriber.error(error);\n });\n return () => {\n subscription.unsubscribe();\n this._nativeModuleWrapper.stopScan().catch((error) => {\n this._loggerService.error(\"stopDiscovering error\", error);\n });\n };\n },\n );\n return observable;\n }\n\n connect(_params: {\n deviceId: DeviceId;\n onDisconnect: DisconnectHandler;\n }): Promise<Either<ConnectError, TransportConnectedDevice>> {\n return this._nativeModuleWrapper\n .connectDevice(_params.deviceId)\n .then((result) => {\n return result.map(\n ({ sessionId, transportDeviceModel: deviceModel }) => {\n const sub = this._nativeModuleWrapper\n .subscribeToDeviceDisconnectedEvents()\n .subscribe((device) => {\n if (device.sessionId === sessionId) {\n _params.onDisconnect(sessionId);\n sub.unsubscribe();\n }\n });\n\n return new TransportConnectedDevice({\n id: sessionId,\n deviceModel,\n sendApdu: async (apdu) => {\n return this._nativeModuleWrapper\n .sendApdu(sessionId, apdu)\n .catch((e) => Left(new SendApduError(e)));\n },\n transport: this.getIdentifier(),\n type: \"USB\",\n });\n },\n );\n })\n .catch((error) => {\n return Left(new OpeningConnectionError(error));\n });\n }\n\n disconnect(_params: {\n connectedDevice: TransportConnectedDevice;\n }): Promise<Either<DmkError, void>> {\n return this._nativeModuleWrapper\n .disconnectDevice(_params.connectedDevice.id)\n .then(() => Right(undefined))\n .catch((error) => {\n return Left(new DisconnectError(error));\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["RNHidTransport_exports", "__export", "RNHidTransport", "__toCommonJS", "import_device_management_kit", "import_purify_ts", "import_rxjs", "import_getObservableOfArraysNewItems", "import_rnHidTransportIdentifier", "import_Errors", "_isSupported", "_nativeModuleWrapper", "_loggerServiceFactory", "log", "logLevel", "message", "options", "logMethod", "subscriber", "subscription", "device", "error", "devices", "_params", "result", "sessionId", "deviceModel", "sub", "apdu", "e"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var l=require("@ledgerhq/device-management-kit"),a=require("purify-ts/Either"),T=require("rxjs"),h=require("../transport/rnHidTransportIdentifier"),E=require("./Errors"),s=require("./RNHidTransport");const M=new l.StaticDeviceModelDataSource,y=(p,D)=>({id:p,transport:h.TRANSPORT_IDENTIFIER,name:D,deviceModel:M.getDeviceModel({id:D})}),v=y("1",l.DeviceModelId.NANO_S),g=y("2",l.DeviceModelId.NANO_X),x=y("3",l.DeviceModelId.NANO_S);describe("RNHidTransport",()=>{let p,D,R,n;const S={error:vi.fn(),warn:vi.fn(),info:vi.fn(),debug:vi.fn(),subscribers:[]},c=vi.fn(()=>S),f=vi.fn(),w=vi.fn(),u=vi.fn(),k=vi.fn(),m=vi.fn();beforeEach(()=>{p=new T.Subject,D=new T.Subject,R=new T.Subject,vi.clearAllMocks(),f.mockResolvedValue(void 0),w.mockResolvedValue(void 0),u.mockResolvedValue(void 0),k.mockResolvedValue(void 0),m.mockResolvedValue(void 0),n={startScan:f,stopScan:w,subscribeToDiscoveredDevicesEvents:vi.fn(()=>p.asObservable()),subscribeToDeviceDisconnectedEvents:vi.fn(()=>D.asObservable()),subscribeToTransportLogs:vi.fn(()=>R.asObservable()),connectDevice:u,disconnectDevice:k,sendApdu:m}}),test("getIdentifier returns TRANSPORT_IDENTIFIER",()=>{const t=new s.RNHidTransport(!0,n,c);expect(t.getIdentifier()).toBe(h.TRANSPORT_IDENTIFIER)}),describe("isSupported returns the provided support flag",()=>{test("supported",()=>{const t=new s.RNHidTransport(!0,n,c);expect(t.isSupported()).toBe(!0)}),test("not supported",()=>{const t=new s.RNHidTransport(!1,n,c);expect(t.isSupported()).toBe(!1)})}),test("constructor subscribes to transport logs and calls logger methods",()=>{new s.RNHidTransport(!0,n,c);const t=[l.LogLevel.Info,"Test message",{tag:"TestTag",data:{key:"value"},timestamp:123456789}];R.next(t),expect(S.info).toHaveBeenCalledWith("Test message",{tag:"TestTag",data:{key:"value"},timestamp:123456789})}),describe("startDiscovering",()=>{it("calls startScan",()=>{new s.RNHidTransport(!0,n,c).startDiscovering().subscribe(),expect(f).toHaveBeenCalled()}),it("emits new discovered devices",()=>new Promise((t,e)=>{const r=new s.RNHidTransport(!0,n,c),o=[];r.startDiscovering().subscribe({next:i=>{if(o.push(i),o.length===3)try{expect(o).toEqual([v,g,x]),t()}catch(d){e(d)}},error:e}),p.next([v]),p.next([v,g]),p.next([v,g,x])})),it("propagates startScan error",()=>new Promise((t,e)=>{const r=new s.RNHidTransport(!0,n,c),o=new Error("scan failed");f.mockRejectedValueOnce(o),r.startDiscovering().subscribe({next:()=>{},error:i=>{try{expect(i).toBe(o),t()}catch(d){e(d)}}})}))}),describe("stopDiscovering",()=>{it("calls stopScan",async()=>{await new s.RNHidTransport(!0,n,c).stopDiscovering(),expect(n.stopScan).toHaveBeenCalled()}),it("logs error when stopScan fails",async()=>{const t=new s.RNHidTransport(!0,n,c),e=new Error("stop failed");w.mockRejectedValueOnce(e),await t.stopDiscovering(),expect(S.error).toHaveBeenCalledWith("stopDiscovering error",e)})}),describe("listenToKnownDevices",()=>{it("emits arrays of discovered devices",()=>new Promise((t,e)=>{const r=new s.RNHidTransport(!0,n,c),o=[];r.listenToAvailableDevices().subscribe({next:i=>{if(o.push(i),o.length===2)try{expect(o).toEqual([[v,g],[v,x]]),t()}catch(d){e(d)}},complete:()=>{e("should not complete")},error:e}),p.next([v,g]),p.next([v,x])})),it("propagates startScan error",()=>new Promise((t,e)=>{const r=new s.RNHidTransport(!0,n,c),o=new Error("start scan failed");f.mockRejectedValueOnce(o),r.listenToAvailableDevices().subscribe({error:i=>{try{expect(i).toBe(o),t()}catch(d){e(d)}}})})),it("calls stopScan on unsubscribe",()=>{const t=new s.RNHidTransport(!0,n,c),e=new Error("stop scan failed");w.mockRejectedValueOnce(e),t.listenToAvailableDevices().subscribe({}).unsubscribe(),expect(w).toHaveBeenCalled()})}),describe("connect",()=>{describe("connection successful",()=>{it("should return a Right(TransportConnectedDevice) on successful connection",async()=>{const t={model:"TestModel"},e="session123";u.mockResolvedValueOnce((0,a.Right)({sessionId:e,transportDeviceModel:t}));const o=await new s.RNHidTransport(!0,n,c).connect({deviceId:e,onDisconnect:vi.fn()});expect(o.isRight()).toBe(!0);const i=o.extract();expect(i).toBeInstanceOf(l.TransportConnectedDevice),expect(i.id).toBe(e),expect(i.deviceModel).toEqual(t),expect(i.transport).toBe(h.TRANSPORT_IDENTIFIER),expect(i.type).toBe("USB")}),test("should trigger onDisconnect when a matching disconnect event is emitted",async()=>{const t={model:"TestModel"},e="session123";u.mockResolvedValueOnce((0,a.Right)({sessionId:e,transportDeviceModel:t}));const r=new s.RNHidTransport(!0,n,c),o=vi.fn();await r.connect({deviceId:e,onDisconnect:o}),D.next({sessionId:e}),expect(o).toHaveBeenCalledWith(e)}),test("should handle sendApdu success (Right)",async()=>{const t={model:"TestModel"},e="session123";u.mockResolvedValueOnce((0,a.Right)({sessionId:e,transportDeviceModel:t}));const i=(await new s.RNHidTransport(!0,n,c).connect({deviceId:e,onDisconnect:vi.fn()})).extract();m.mockResolvedValueOnce((0,a.Right)("apduResponse"));const d=new Uint8Array([1,2,3]),b=await i.sendApdu(d);expect(n.sendApdu).toHaveBeenCalledWith(e,d),expect(b).toEqual((0,a.Right)("apduResponse"))}),test("should handle sendApdu failure (Left)",async()=>{const t={model:"TestModel"},e="session123";u.mockResolvedValueOnce((0,a.Right)({sessionId:e,transportDeviceModel:t}));const i=(await new s.RNHidTransport(!0,n,c).connect({deviceId:e,onDisconnect:vi.fn()})).extract();m.mockResolvedValueOnce((0,a.Left)("some error"));const d=new Uint8Array([1,2,3]),b=await i.sendApdu(d);expect(b).toEqual((0,a.Left)("some error"))}),test("should handle sendApdu rejection",async()=>{const t={model:"TestModel"},e="session123";u.mockResolvedValueOnce((0,a.Right)({sessionId:e,transportDeviceModel:t}));const i=(await new s.RNHidTransport(!0,n,c).connect({deviceId:e,onDisconnect:vi.fn()})).extract(),d=new Error("apdu failed");m.mockRejectedValueOnce(d);const b=await i.sendApdu(new Uint8Array([]));expect(b).toEqual((0,a.Left)(new E.SendApduError(d)))})}),describe("connection failure",()=>{test("should return a Left when nativeModuleWrapper.connectDevice resolves a Left",async()=>{const t=new s.RNHidTransport(!0,n,c),e=(0,a.Left)(new l.OpeningConnectionError("connection failed"));u.mockResolvedValueOnce(e);const r=await t.connect({deviceId:"any",onDisconnect:vi.fn()});expect(r).toEqual(e)}),test("should return a Left when nativeModuleWrapper.connectDevice rejects",async()=>{const t=new Error("connection failed"),e=new s.RNHidTransport(!0,n,c);u.mockRejectedValueOnce(t);const r=await e.connect({deviceId:"any",onDisconnect:vi.fn()});expect(r).toEqual((0,a.Left)(new l.OpeningConnectionError(t)))})})}),describe("disconnect",()=>{it("returns Right on successful disconnect",async()=>{const e=await new s.RNHidTransport(!0,n,c).disconnect({connectedDevice:{id:"session789"}});expect(n.disconnectDevice).toHaveBeenCalledWith("session789"),expect(e).toEqual((0,a.Right)(void 0))}),it("returns Left on disconnect failure",async()=>{const t=new s.RNHidTransport(!0,n,c),e=new Error("disconnect failed");k.mockRejectedValueOnce(e);const r=await t.disconnect({connectedDevice:{id:"session000"}});expect(r).toEqual((0,a.Left)(new l.DisconnectError(e)))})})});
|
|
2
|
+
//# sourceMappingURL=RNHidTransport.test.js.map
|