Skip to content

Commit bbaeb99

Browse files
committed
Jade genuine check
1 parent f82d230 commit bbaeb99

File tree

37 files changed

+827
-59
lines changed

37 files changed

+827
-59
lines changed

common/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ kotlin {
9696
optIn("kotlin.experimental.ExperimentalObjCName")
9797
optIn("kotlinx.cinterop.ExperimentalForeignApi")
9898
optIn("kotlinx.coroutines.FlowPreview")
99+
optIn("kotlin.ExperimentalStdlibApi")
99100
}
100101
}
101102

common/src/androidUnitTest/kotlin/com/blockstream/common/models/TestViewModel.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ package com.blockstream.common.models
22

33
import com.blockstream.common.CountlyBase
44
import com.blockstream.common.data.AppInfo
5+
import com.blockstream.common.database.Database
56
import com.blockstream.common.managers.PromoManager
67
import com.blockstream.common.managers.SessionManager
8+
import com.blockstream.common.managers.SettingsManager
9+
import io.mockk.coEvery
710
import io.mockk.every
811
import io.mockk.mockkClass
912
import kotlinx.coroutines.Dispatchers
@@ -51,6 +54,14 @@ abstract class TestViewModel<VM : GreenViewModel>: KoinTest {
5154

5255
}
5356

57+
declareMock<Database> {
58+
coEvery { insertEvent(any()) } returns Unit
59+
}
60+
61+
declareMock<SettingsManager> {
62+
every { getCountlyDeviceId() } returns ""
63+
}
64+
5465
declareMock<PromoManager> {
5566
every { promos } returns MutableStateFlow(listOf())
5667
}

common/src/commonMain/composeResources/values/strings.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,4 +1592,21 @@
15921592
<string name="id_signer_unlocked">Signer Unlocked</string>
15931593
<string name="id_unlock_your_signing_device_before">Unlock your signing device before signing the transaction.</string>
15941594
<string name="id_unlock_jade">Unlock Jade</string>
1595+
<string name="id_retry">Retry</string>
1596+
<string name="id_genuine_check">Genuine Check</string>
1597+
<string name="id_new_jade_plus_connected">New Jade Plus Connected</string>
1598+
<string name="id_a_new_device_has_been_detected">A new device has been detected, please set it up to start using it.</string>
1599+
<string name="id_genuine_check_is_mandatory_for">Genuine Check is mandatory for first time Jade connection. This way we make sure that you have a safe Jade.</string>
1600+
<string name="id_verify_the_authenticity_of">Verify the authenticity of your Jade.</string>
1601+
<string name="id_continue_as_diy">Continue as DIY</string>
1602+
<string name="id_authenticate_your_jade">Authenticate you Jade</string>
1603+
<string name="id_confirm_your_jade">Confirm on your Jade</string>
1604+
<string name="id_continue_with_jade">Continue with Jade</string>
1605+
<string name="id_your_jade_is_genuine">Your Jade is genuine!</string>
1606+
<string name="id_this_jade_is_not_genuine">This Jade is not genuine</string>
1607+
<string name="id_genuine_check_canceled">Genuine check canceled</string>
1608+
<string name="id_we_were_unable_to_complete_the_genuine">We were unable to complete the genuine check because it was canceled on Jade.</string>
1609+
<string name="id_perform_a_genuine_check_to">Perform a genuine check to ensure that the Jade you received was manufactured by Blockstream.</string>
1610+
<string name="id_we_could_successfully_verify_your">We could successfully verify your Jade, enjoy the best Blockstream can offer you with your brand new jade.</string>
1611+
<string name="id_this_device_was_not_manufactured_by">This device was not manufactured by Blockstream. It could be DIY hardware or possibly a malicious clone. Please contact support for more assistance.</string>
15951612
</resources>

common/src/commonMain/kotlin/com/blockstream/common/data/WalletSettings.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package com.blockstream.common.data
22

33
import com.blockstream.common.events.Event
44
import com.blockstream.common.gdk.data.Network
5-
import com.blockstream.common.models.settings.WalletSettingsViewModel
65

76
sealed class WalletSetting{
87
data object Logout : WalletSetting()
@@ -21,6 +20,7 @@ sealed class WalletSetting{
2120
data object TwoFactorAuthentication : WalletSetting()
2221
data class PgpKey(val enabled: Boolean) : WalletSetting()
2322
data class AutoLogoutTimeout(val timeout: Int) : WalletSetting()
23+
data object JadeGenuineCheck : WalletSetting()
2424
data object RecoveryPhrase : WalletSetting()
2525
data class Version(val version: String) : WalletSetting()
2626
data class TwoFactorMethod(

common/src/commonMain/kotlin/com/blockstream/common/database/Database.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,5 +231,21 @@ class Database(driverFactory: DriverFactory, val settingsManager: SettingsManage
231231
)
232232
}
233233

234+
suspend fun insertEvent(eventId: String) = io {
235+
db.eventsQueries.insertEvent(
236+
id = eventId
237+
)
238+
}
239+
240+
suspend fun eventExist(eventId: String) = io {
241+
db.eventsQueries.eventExists(
242+
id = eventId
243+
).executeAsOne()
244+
}
245+
246+
suspend fun deleteEvents() = io {
247+
db.eventsQueries.deleteEvents()
248+
}
249+
234250
companion object : Loggable()
235251
}

common/src/commonMain/kotlin/com/blockstream/common/devices/GreenDevice.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ interface GreenDevice: DeviceOperatingNetwork {
6262
fun canVerifyAddressOnDevice(account: Account): Boolean
6363
}
6464

65+
fun GreenDevice.jadeDevice(): JadeDevice? = this as? JadeDevice
66+
6567
abstract class GreenDeviceImpl constructor(
6668
override val deviceBrand: DeviceBrand,
6769
override val type: ConnectionType,

common/src/commonMain/kotlin/com/blockstream/common/devices/JadeDevice.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,17 @@ interface JadeDevice : JadeDeviceApi, GreenDevice
1111

1212
interface JadeDeviceApi : DeviceOperatingNetwork {
1313
var jadeApi: JadeAPI?
14+
15+
suspend fun supportsGenuineCheck(): Boolean
1416
}
1517

1618
class JadeDeviceApiImpl: JadeDeviceApi {
1719
override var jadeApi: JadeAPI? = null
1820

21+
override suspend fun supportsGenuineCheck(): Boolean {
22+
return jadeApi?.getVersionInfo(useCache = true)?.isBoardV2 == true
23+
}
24+
1925
override suspend fun getOperatingNetworkForEnviroment(greenDevice: GreenDevice, gdk: Gdk, isTestnet: Boolean): Network {
2026
return (greenDevice.gdkHardwareWallet as? JadeHWWallet)?.let { jadeHWWallet ->
2127
jadeHWWallet.getVersionInfo().jadeNetworks.let { networks ->

common/src/commonMain/kotlin/com/blockstream/common/di/ViewModels.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import com.blockstream.common.models.devices.DeviceInfoViewModel
1616
import com.blockstream.common.models.devices.DeviceListViewModel
1717
import com.blockstream.common.models.devices.DeviceScanViewModel
1818
import com.blockstream.common.models.devices.ImportPubKeyViewModel
19+
import com.blockstream.common.models.devices.JadeGenuineCheckViewModel
1920
import com.blockstream.common.models.devices.JadeGuideViewModel
2021
import com.blockstream.common.models.drawer.DrawerViewModel
2122
import com.blockstream.common.models.exchange.AccountExchangeViewModel
@@ -129,6 +130,9 @@ val factoryViewModels = module {
129130
factoryOf(::DeviceInfoViewModel)
130131
factoryOf(::DeviceScanViewModel)
131132
factoryOf(::JadeFirmwareUpdateViewModel)
133+
factory {
134+
JadeGenuineCheckViewModel(getOrNull(), getOrNull())
135+
}
132136
factory {
133137
PromoViewModel(get(), getOrNull())
134138
}

common/src/commonMain/kotlin/com/blockstream/common/gdk/GreenJson.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import kotlinx.serialization.Transient
88
import kotlinx.serialization.cbor.Cbor
99
import kotlinx.serialization.json.Json
1010
import kotlinx.serialization.json.JsonElement
11+
import org.kotlincrypto.hash.sha2.SHA256
1112

1213
@OptIn(ExperimentalSerializationApi::class)
1314
abstract class GreenJson<T>: JavaSerializable {
@@ -37,6 +38,8 @@ abstract class GreenJson<T>: JavaSerializable {
3738

3839
fun toJson() = toString()
3940

41+
fun sha256(): String = SHA256().digest(toJson().encodeToByteArray()).toHexString()
42+
4043
@Suppress("UNCHECKED_CAST")
4144
fun toCbor() = Cbor {
4245
encodeDefaults = encodeDefaultsValues()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.blockstream.common.gdk.events
2+
3+
import com.blockstream.common.gdk.GreenJson
4+
import kotlinx.datetime.Clock
5+
import kotlinx.serialization.KSerializer
6+
import kotlinx.serialization.Serializable
7+
8+
// deviceId creates uniqueness, else just timestamp can be reversed
9+
@Serializable
10+
data class GenericEvent constructor(val deviceId: String, val timestamp: Long = Clock.System.now().toEpochMilliseconds()): GreenJson<GenericEvent>() {
11+
override fun kSerializer(): KSerializer<GenericEvent> = serializer()
12+
}

0 commit comments

Comments
 (0)