@ledgerhq/device-transport-kit-react-native-hid 0.0.0-rn-hid-20250221115747 → 0.0.0-rn-hid-sync-onboarding-behavior-20250516092329
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/README.md +1 -1
- package/android/build.gradle +3 -1
- package/android/src/main/kotlin/com/ledger/androidtransporthid/TransportHidModule.kt +14 -5
- package/android/src/main/kotlin/com/ledger/androidtransporthid/bridge/serialization.kt +2 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/DefaultAndroidUsbTransport.kt +75 -32
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/connection/AndroidUsbApduSender.kt +72 -32
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/controller/UsbPermissionReceiver.kt +1 -1
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMain/transport/usb/utils/UsbDeviceMapper.kt +27 -36
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMainInternal/transport/UsbConst.android.kt +1 -1
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMainInternal/transport/deviceconnection/DeviceApduSender.kt +2 -1
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMainInternal/transport/deviceconnection/DeviceConnection.kt +11 -11
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/androidMainInternal/transport/deviceconnection/DeviceConnectionStateMachine.kt +8 -4
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/apdu/SendApduResult.kt +4 -0
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/device/LedgerDevice.kt +64 -49
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/device/UsbInfo.kt +4 -3
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/connection/InternalConnectedDevice.kt +1 -1
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/internal/transport/framer/FramerService.kt +1 -1
- 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/bridge/DefaultNativeModuleWrapper.js +1 -1
- package/lib/cjs/api/bridge/DefaultNativeModuleWrapper.js.map +3 -3
- package/lib/cjs/api/bridge/NativeTransportModule.js +1 -1
- package/lib/cjs/api/bridge/NativeTransportModule.js.map +1 -1
- package/lib/cjs/api/bridge/mapper.js +1 -1
- package/lib/cjs/api/bridge/mapper.js.map +2 -2
- package/lib/cjs/api/bridge/types.js +1 -1
- package/lib/cjs/api/bridge/types.js.map +1 -1
- package/lib/cjs/api/transport/NativeModuleWrapper.js +1 -1
- package/lib/cjs/api/transport/NativeModuleWrapper.js.map +1 -1
- package/lib/cjs/api/transport/RNHidTransport.js +1 -1
- package/lib/cjs/api/transport/RNHidTransport.js.map +3 -3
- package/lib/cjs/package.json +17 -12
- package/lib/esm/api/bridge/DefaultNativeModuleWrapper.js +1 -1
- package/lib/esm/api/bridge/DefaultNativeModuleWrapper.js.map +3 -3
- package/lib/esm/api/bridge/NativeTransportModule.js +1 -1
- package/lib/esm/api/bridge/NativeTransportModule.js.map +1 -1
- package/lib/esm/api/bridge/mapper.js +1 -1
- package/lib/esm/api/bridge/mapper.js.map +3 -3
- package/lib/esm/api/bridge/types.js.map +1 -1
- package/lib/esm/api/transport/RNHidTransport.js +1 -1
- package/lib/esm/api/transport/RNHidTransport.js.map +3 -3
- package/lib/esm/package.json +17 -12
- package/lib/types/api/bridge/DefaultNativeModuleWrapper.d.ts +1 -1
- package/lib/types/api/bridge/DefaultNativeModuleWrapper.d.ts.map +1 -1
- package/lib/types/api/bridge/NativeTransportModule.d.ts.map +1 -1
- package/lib/types/api/bridge/mapper.d.ts.map +1 -1
- package/lib/types/api/bridge/types.d.ts +2 -2
- package/lib/types/api/bridge/types.d.ts.map +1 -1
- package/lib/types/api/transport/NativeModuleWrapper.d.ts +1 -1
- package/lib/types/api/transport/NativeModuleWrapper.d.ts.map +1 -1
- package/lib/types/api/transport/RNHidTransport.d.ts.map +1 -1
- package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
- package/package.json +19 -14
- package/android/.settings/org.eclipse.buildship.core.prefs +0 -13
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +0 -7
- package/android/gradlew +0 -252
- package/android/gradlew.bat +0 -94
- package/android/src/main/kotlin/com/ledger/devicesdk/shared/api/DeviceAction.kt +0 -23
|
@@ -3,6 +3,7 @@ package com.ledger.devicesdk.shared.androidMainInternal.transport.deviceconnecti
|
|
|
3
3
|
import com.ledger.devicesdk.shared.api.apdu.SendApduResult
|
|
4
4
|
import com.ledger.devicesdk.shared.internal.service.logger.LoggerService
|
|
5
5
|
import com.ledger.devicesdk.shared.internal.service.logger.buildSimpleErrorLogInfo
|
|
6
|
+
import kotlinx.coroutines.CoroutineDispatcher
|
|
6
7
|
import kotlinx.coroutines.CoroutineScope
|
|
7
8
|
import kotlinx.coroutines.launch
|
|
8
9
|
import kotlin.coroutines.resume
|
|
@@ -14,17 +15,18 @@ internal class DeviceConnection<Dependencies>(
|
|
|
14
15
|
private var deviceApduSender: DeviceApduSender<Dependencies>,
|
|
15
16
|
isFatalSendApduFailure: (SendApduResult.Failure) -> Boolean,
|
|
16
17
|
reconnectionTimeoutDuration: Duration,
|
|
18
|
+
coroutineDispatcher: CoroutineDispatcher,
|
|
17
19
|
private val onTerminated: (DeviceConnection<Dependencies>) -> Unit,
|
|
18
|
-
private val coroutineScope: CoroutineScope,
|
|
19
20
|
private val loggerService: LoggerService,
|
|
20
21
|
) {
|
|
21
22
|
private val stateMachine: DeviceConnectionStateMachine
|
|
23
|
+
private val coroutineScope = CoroutineScope(coroutineDispatcher)
|
|
22
24
|
|
|
23
25
|
init {
|
|
24
26
|
stateMachine = DeviceConnectionStateMachine(
|
|
25
|
-
sendApduFn = {
|
|
27
|
+
sendApduFn = { apdu, abortTimeoutDuration ->
|
|
26
28
|
coroutineScope.launch {
|
|
27
|
-
val res = deviceApduSender.send(
|
|
29
|
+
val res = deviceApduSender.send(apdu, abortTimeoutDuration)
|
|
28
30
|
handleApduResult(res)
|
|
29
31
|
}
|
|
30
32
|
},
|
|
@@ -33,7 +35,7 @@ internal class DeviceConnection<Dependencies>(
|
|
|
33
35
|
},
|
|
34
36
|
isFatalSendApduFailure = isFatalSendApduFailure,
|
|
35
37
|
reconnectionTimeoutDuration = reconnectionTimeoutDuration,
|
|
36
|
-
|
|
38
|
+
coroutineDispatcher = coroutineDispatcher,
|
|
37
39
|
onError = {
|
|
38
40
|
loggerService.log(
|
|
39
41
|
buildSimpleErrorLogInfo(
|
|
@@ -51,15 +53,12 @@ internal class DeviceConnection<Dependencies>(
|
|
|
51
53
|
stateMachine.handleApduResult(result)
|
|
52
54
|
}
|
|
53
55
|
|
|
54
|
-
public fun setApduSender(apduSender: DeviceApduSender<Dependencies>) {
|
|
55
|
-
deviceApduSender = apduSender
|
|
56
|
-
}
|
|
57
|
-
|
|
58
56
|
public fun getApduSender(): DeviceApduSender<Dependencies> {
|
|
59
57
|
return deviceApduSender
|
|
60
58
|
}
|
|
61
59
|
|
|
62
|
-
public fun handleDeviceConnected() {
|
|
60
|
+
public fun handleDeviceConnected(apduSender: DeviceApduSender<Dependencies>) {
|
|
61
|
+
deviceApduSender = apduSender
|
|
63
62
|
stateMachine.handleDeviceConnected()
|
|
64
63
|
}
|
|
65
64
|
|
|
@@ -67,12 +66,13 @@ internal class DeviceConnection<Dependencies>(
|
|
|
67
66
|
stateMachine.handleDeviceDisconnected()
|
|
68
67
|
}
|
|
69
68
|
|
|
70
|
-
public suspend fun requestSendApdu(apdu: ByteArray): SendApduResult =
|
|
69
|
+
public suspend fun requestSendApdu(apdu: ByteArray, triggersDisconnection: Boolean, abortTimeoutDuration: Duration): SendApduResult =
|
|
71
70
|
suspendCoroutine { cont ->
|
|
72
71
|
stateMachine.requestSendApdu(
|
|
73
72
|
DeviceConnectionStateMachine.SendApduRequestContent(
|
|
74
73
|
apdu = apdu,
|
|
75
|
-
triggersDisconnection = apduTriggersDisconnection(apdu),
|
|
74
|
+
triggersDisconnection = apduTriggersDisconnection(apdu) || triggersDisconnection,
|
|
75
|
+
abortTimeoutDuration = abortTimeoutDuration,
|
|
76
76
|
resultCallback = cont::resume
|
|
77
77
|
)
|
|
78
78
|
)
|
|
@@ -5,28 +5,31 @@ import com.ledger.devicesdk.shared.api.apdu.SendApduResult
|
|
|
5
5
|
import com.ledger.devicesdk.shared.internal.service.logger.LoggerService
|
|
6
6
|
import com.ledger.devicesdk.shared.internal.service.logger.buildSimpleDebugLogInfo
|
|
7
7
|
import com.ledger.devicesdk.shared.internal.service.logger.buildSimpleInfoLogInfo
|
|
8
|
+
import kotlinx.coroutines.CoroutineDispatcher
|
|
8
9
|
import kotlinx.coroutines.CoroutineScope
|
|
9
10
|
import kotlinx.coroutines.Job
|
|
10
11
|
import kotlinx.coroutines.launch
|
|
11
12
|
import kotlin.time.Duration
|
|
12
13
|
|
|
13
14
|
internal class DeviceConnectionStateMachine(
|
|
14
|
-
private val sendApduFn: (apdu: ByteArray) -> Unit,
|
|
15
|
+
private val sendApduFn: (apdu: ByteArray, abortTimeoutDuration: Duration) -> Unit,
|
|
15
16
|
private val onTerminated: () -> Unit,
|
|
16
17
|
private val isFatalSendApduFailure: (SendApduResult.Failure) -> Boolean,
|
|
17
18
|
private val reconnectionTimeoutDuration: Duration,
|
|
18
|
-
private val coroutineScope: CoroutineScope,
|
|
19
19
|
private val onError: (Throwable) -> Unit,
|
|
20
20
|
private val loggerService: LoggerService,
|
|
21
|
+
coroutineDispatcher: CoroutineDispatcher,
|
|
21
22
|
) {
|
|
22
|
-
|
|
23
|
+
private val coroutineScope = CoroutineScope(coroutineDispatcher)
|
|
23
24
|
private var state: State = State.Connected
|
|
24
25
|
|
|
26
|
+
fun getState() = state
|
|
27
|
+
|
|
25
28
|
private fun pushState(newState: State) {
|
|
26
29
|
when (newState) {
|
|
27
30
|
is State.Connected -> {}
|
|
28
31
|
is State.SendingApdu -> {
|
|
29
|
-
sendApduFn(newState.requestContent.apdu)
|
|
32
|
+
sendApduFn(newState.requestContent.apdu, newState.requestContent.abortTimeoutDuration)
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
is State.WaitingForReconnection -> {
|
|
@@ -277,6 +280,7 @@ internal class DeviceConnectionStateMachine(
|
|
|
277
280
|
data class SendApduRequestContent(
|
|
278
281
|
val apdu: ByteArray,
|
|
279
282
|
val triggersDisconnection: Boolean,
|
|
283
|
+
val abortTimeoutDuration: Duration,
|
|
280
284
|
val resultCallback: (SendApduResult) -> Unit
|
|
281
285
|
)
|
|
282
286
|
|
|
@@ -44,4 +44,8 @@ public sealed class SendApduFailureReason {
|
|
|
44
44
|
public data object DeviceDisconnected : SendApduFailureReason()
|
|
45
45
|
|
|
46
46
|
public data object Unknown : SendApduFailureReason()
|
|
47
|
+
|
|
48
|
+
public data object AbortTimeout : SendApduFailureReason()
|
|
49
|
+
|
|
50
|
+
public data object EmptyResponse : SendApduFailureReason()
|
|
47
51
|
}
|
|
@@ -1,62 +1,76 @@
|
|
|
1
1
|
package com.ledger.devicesdk.shared.api.device
|
|
2
2
|
|
|
3
3
|
public sealed class LedgerDevice(
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
public val name: String,
|
|
5
|
+
public val usbInfo: UsbInfo,
|
|
6
|
+
public val bleInformation: BleInformation? = null,
|
|
7
7
|
) {
|
|
8
|
-
public data object Flex :
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
public data object Flex :
|
|
9
|
+
LedgerDevice(
|
|
10
|
+
name = "Ledger Flex",
|
|
11
|
+
usbInfo = UsbInfo(LEDGER_USB_VENDOR_ID, "0x70", "0x0007"),
|
|
12
|
+
bleInformation =
|
|
13
|
+
BleInformation(
|
|
14
|
+
serviceUuid = "13d63400-2c97-3004-0000-4c6564676572",
|
|
15
|
+
notifyCharacteristicUuid =
|
|
16
|
+
"13d63400-2c97-3004-0001-4c6564676572",
|
|
17
|
+
writeWithResponseCharacteristicUuid =
|
|
18
|
+
"13d63400-2c97-3004-0002-4c6564676572",
|
|
19
|
+
writeWithoutResponseCharacteristicUuid =
|
|
20
|
+
"13d63400-2c97-3004-0003-4c6564676572",
|
|
21
|
+
),
|
|
22
|
+
)
|
|
19
23
|
|
|
20
|
-
public data object Stax :
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
public data object Stax :
|
|
25
|
+
LedgerDevice(
|
|
26
|
+
name = "Ledger Stax",
|
|
27
|
+
usbInfo = UsbInfo(LEDGER_USB_VENDOR_ID, "0x60", "0x0006"),
|
|
28
|
+
bleInformation =
|
|
29
|
+
BleInformation(
|
|
30
|
+
serviceUuid = "13d63400-2c97-6004-0000-4c6564676572",
|
|
31
|
+
notifyCharacteristicUuid =
|
|
32
|
+
"13d63400-2c97-6004-0001-4c6564676572",
|
|
33
|
+
writeWithResponseCharacteristicUuid =
|
|
34
|
+
"13d63400-2c97-6004-0002-4c6564676572",
|
|
35
|
+
writeWithoutResponseCharacteristicUuid =
|
|
36
|
+
"13d63400-2c97-6004-0003-4c6564676572",
|
|
37
|
+
),
|
|
38
|
+
)
|
|
31
39
|
|
|
32
|
-
public data object NanoX :
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
public data object NanoX :
|
|
41
|
+
LedgerDevice(
|
|
42
|
+
name = "Nano X",
|
|
43
|
+
usbInfo = UsbInfo(LEDGER_USB_VENDOR_ID, "0x40", "0x0004"),
|
|
44
|
+
bleInformation =
|
|
45
|
+
BleInformation(
|
|
46
|
+
serviceUuid = "13d63400-2c97-0004-0000-4c6564676572",
|
|
47
|
+
notifyCharacteristicUuid =
|
|
48
|
+
"13d63400-2c97-0004-0001-4c6564676572",
|
|
49
|
+
writeWithResponseCharacteristicUuid =
|
|
50
|
+
"13d63400-2c97-0004-0002-4c6564676572",
|
|
51
|
+
writeWithoutResponseCharacteristicUuid =
|
|
52
|
+
"13d63400-2c97-0004-0003-4c6564676572",
|
|
53
|
+
),
|
|
54
|
+
)
|
|
43
55
|
|
|
44
|
-
public data object NanoSPlus :
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
56
|
+
public data object NanoSPlus :
|
|
57
|
+
LedgerDevice(
|
|
58
|
+
name = "Nano S Plus",
|
|
59
|
+
usbInfo = UsbInfo(LEDGER_USB_VENDOR_ID, "0x50", "0x0005"),
|
|
60
|
+
bleInformation = null,
|
|
61
|
+
)
|
|
49
62
|
|
|
50
|
-
public data object NanoS :
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
63
|
+
public data object NanoS :
|
|
64
|
+
LedgerDevice(
|
|
65
|
+
name = "Nano S",
|
|
66
|
+
usbInfo = UsbInfo(LEDGER_USB_VENDOR_ID, "0x10", "0x0001"),
|
|
67
|
+
bleInformation = null,
|
|
68
|
+
)
|
|
55
69
|
|
|
56
70
|
public companion object {
|
|
57
71
|
public const val LEDGER_USB_VENDOR_ID: String = "0x2c97"
|
|
58
72
|
|
|
59
|
-
//Cannot use reflexion here to get all subclasses as it depends of the JVM
|
|
73
|
+
// Cannot use reflexion here to get all subclasses as it depends of the JVM
|
|
60
74
|
private val subclasses = buildList {
|
|
61
75
|
add(Flex)
|
|
62
76
|
add(Stax)
|
|
@@ -69,6 +83,7 @@ public sealed class LedgerDevice(
|
|
|
69
83
|
return subclasses
|
|
70
84
|
}
|
|
71
85
|
|
|
72
|
-
public fun getAllDevicesWithBluetooth(): List<LedgerDevice> =
|
|
86
|
+
public fun getAllDevicesWithBluetooth(): List<LedgerDevice> =
|
|
87
|
+
getAllDevices().filter { it.bleInformation != null }
|
|
73
88
|
}
|
|
74
|
-
}
|
|
89
|
+
}
|
|
@@ -9,5 +9,5 @@ internal data class InternalConnectedDevice(
|
|
|
9
9
|
val name: String,
|
|
10
10
|
val ledgerDevice: LedgerDevice,
|
|
11
11
|
val connectivity: ConnectivityType,
|
|
12
|
-
val sendApduFn: suspend (ByteArray) -> SendApduResult,
|
|
12
|
+
val sendApduFn: suspend (apdu: ByteArray, triggersDisconnection: Boolean, abortTimeoutDuration: kotlin.time.Duration) -> SendApduResult,
|
|
13
13
|
)
|