Updated on 2026-08-14

This commit is contained in:
Tangem 2025-10-09 13:06:54 +03:00
commit aa10ef1182
1206 changed files with 26404 additions and 12548 deletions

1
.gitignore vendored
View file

@ -12,6 +12,7 @@
**/build/outputs/**
**/build/reports/**
**/build/tmp/**
**/test-results/**
# Local configuration file (sdk path, etc)
local.properties

View file

@ -5,6 +5,39 @@
<JavaCodeStyleSettings>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="5" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="3" />
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="" withSubpackages="true" static="false" module="true" />
<package name="android" withSubpackages="true" static="true" />
<package name="androidx" withSubpackages="true" static="true" />
<package name="com" withSubpackages="true" static="true" />
<package name="junit" withSubpackages="true" static="true" />
<package name="net" withSubpackages="true" static="true" />
<package name="org" withSubpackages="true" static="true" />
<package name="java" withSubpackages="true" static="true" />
<package name="javax" withSubpackages="true" static="true" />
<package name="" withSubpackages="true" static="true" />
<emptyLine />
<package name="android" withSubpackages="true" static="false" />
<emptyLine />
<package name="androidx" withSubpackages="true" static="false" />
<emptyLine />
<package name="com" withSubpackages="true" static="false" />
<emptyLine />
<package name="junit" withSubpackages="true" static="false" />
<emptyLine />
<package name="net" withSubpackages="true" static="false" />
<emptyLine />
<package name="org" withSubpackages="true" static="false" />
<emptyLine />
<package name="java" withSubpackages="true" static="false" />
<emptyLine />
<package name="javax" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="false" />
<emptyLine />
</value>
</option>
</JavaCodeStyleSettings>
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">

40
.idea/file.template.settings.xml generated Normal file
View file

@ -0,0 +1,40 @@
<application>
<component name="ExportableFileTemplateSettings">
<default_templates>
<template name="Decompose component.kt" file-name="${NAME}Component" reformat="true" live-template-enabled="false">
<template name="Decompose component.kt.child.5.kt" file-name="di/${NAME}ModelModule" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.4.kt" file-name="di/${NAME}ComponentModule" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.0.kt" file-name="entity/${NAME}UM" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.1.kt" file-name="ui/${NAME}Content" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.2.kt" file-name="model/${NAME}Model" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.3.kt" file-name="Default${NAME}Component" reformat="true" live-template-enabled="false" />
</template>
<template name="Decompose component.kt.child.0.kt" file-name="entity/${NAME}UM" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.1.kt" file-name="ui/${NAME}Content" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.2.kt" file-name="model/${NAME}Model" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.3.kt" file-name="Default${NAME}Component" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.4.kt" file-name="di/${NAME}ComponentModule" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.5.kt" file-name="di/${NAME}ModelModule" reformat="true" live-template-enabled="false" />
<template name="FeatureToggles.kt" file-name="${NAME}FeatureToggles" reformat="true" live-template-enabled="false">
<template name="FeatureToggles.kt.child.0.kt" file-name="Default${NAME}FeatureToggles" reformat="true" live-template-enabled="false" />
</template>
<template name="FeatureToggles.kt.child.0.kt" file-name="Default${NAME}FeatureToggles" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt" file-name="producer/${NAME}Producer" reformat="true" live-template-enabled="false">
<template name="FlowPackaging.kt.child.0.kt" file-name="di/${NAME}FetcherModule" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.1.kt" file-name="di/${NAME}ProducerFactoryModule" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.2.kt" file-name="di/${NAME}SupplierModule" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.3.kt" file-name="fetcher/Default${NAME}Fetcher" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.4.kt" file-name="producer/Default${NAME}Producer" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.5.kt" file-name="fetcher/${NAME}Fetcher" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.6.kt" file-name="supplier/${NAME}Supplier" reformat="true" live-template-enabled="false" />
</template>
<template name="FlowPackaging.kt.child.0.kt" file-name="di/${NAME}FetcherModule" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.1.kt" file-name="di/${NAME}ProducerFactoryModule" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.2.kt" file-name="di/${NAME}SupplierModule" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.3.kt" file-name="fetcher/Default${NAME}Fetcher" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.4.kt" file-name="producer/Default${NAME}Producer" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.5.kt" file-name="fetcher/${NAME}Fetcher" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.6.kt" file-name="supplier/${NAME}Supplier" reformat="true" live-template-enabled="false" />
</default_templates>
</component>
</application>

View file

@ -0,0 +1,13 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}#end
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableContentComponent
interface ${NAME}Component : ComposableContentComponent {
data class Params(
val data: Any, // TODO("Not yet implemented")
)
interface Factory : ComponentFactory<Params, ${NAME}Component>
}

View file

@ -0,0 +1,5 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.entity#end
internal data class ${NAME}UM(
val onBackClick: () -> Unit,
)

View file

@ -0,0 +1,56 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.ui#end
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import ${PACKAGE_NAME}.entity.${NAME}UM
@Composable
internal fun ${NAME}Content(state: ${NAME}UM, modifier: Modifier = Modifier) {
Column(
modifier = modifier
.background(color = TangemTheme.colors.background.secondary)
.fillMaxSize()
.imePadding()
.systemBarsPadding(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
AppBarWithBackButton(
onBackClick = state.onBackClick,
modifier = Modifier.height(TangemTheme.dimens.size56),
)
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = TangemTheme.dimens.spacing16)
.weight(1f),
) {
}
}
}
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun ${NAME}ContentPreview(@PreviewParameter(PreviewStateProvider::class) state: ${NAME}UM) {
TangemThemePreview {
${NAME}Content(state = state)
}
}
private class PreviewStateProvider : CollectionPreviewParameterProvider<${NAME}UM>(
buildList {
TODO("Not yet implemented")
},
)

View file

@ -0,0 +1,31 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.model#end
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.decompose.ui.UiMessageSender
import ${PACKAGE_NAME}.${NAME}Component
import ${PACKAGE_NAME}.entity.${NAME}UM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject
@ModelScoped
internal class ${NAME}Model @Inject constructor(
paramsContainer: ParamsContainer,
private val messageSender: UiMessageSender,
private val router: Router,
override val dispatchers: CoroutineDispatcherProvider,
) : Model() {
private val params = paramsContainer.require<${NAME}Component.Params>()
val uiState: StateFlow<${NAME}UM>
field: MutableStateFlow<${NAME}UM> = MutableStateFlow(getInitialState())
private fun getInitialState(): ${NAME}UM {
TODO("Not yet implemented")
}
}

View file

@ -0,0 +1,39 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}#end
import androidx.activity.compose.BackHandler
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
import ${PACKAGE_NAME}.model.${NAME}Model
import ${PACKAGE_NAME}.ui.${NAME}Content
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
internal class Default${NAME}Component @AssistedInject constructor(
@Assisted appComponentContext: AppComponentContext,
@Assisted params: ${NAME}Component.Params,
) : AppComponentContext by appComponentContext, ${NAME}Component {
private val model: ${NAME}Model = getOrCreateModel(params)
@Composable
override fun Content(modifier: Modifier) {
val state by model.uiState.collectAsStateWithLifecycle()
${NAME}Content(modifier = modifier, state = state)
BackHandler(onBack = state.onBackClick)
}
@AssistedFactory
interface Factory : ${NAME}Component.Factory {
override fun create(
context: AppComponentContext,
params: ${NAME}Component.Params,
): Default${NAME}Component
}
}

View file

@ -0,0 +1,20 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.di#end
import ${PACKAGE_NAME}.Default${NAME}Component
import ${PACKAGE_NAME}.${NAME}Component
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal interface ${NAME}ComponentModule {
@Binds
@Singleton
fun bind${NAME}ComponentFactory(
factory: Default${NAME}Component.Factory,
): ${NAME}Component.Factory
}

View file

@ -0,0 +1,20 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.di#end
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import ${PACKAGE_NAME}.model.${NAME}Model
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(ModelComponent::class)
internal interface ${NAME}ModelModule {
@Binds
@IntoMap
@ClassKey(${NAME}Model::class)
fun bind${NAME}Model(model: ${NAME}Model): Model
}

11
.idea/fileTemplates/FeatureToggles.kt generated Normal file
View file

@ -0,0 +1,11 @@
#if ($TOGGLE_NAME && $TOGGLE_NAME != "")
#set($TOGGLE = $TOGGLE_NAME)
#else
#set($TOGGLE = "TODO")
#end
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
interface ${NAME}FeatureToggles {
val isFeatureEnabled: Boolean
}

View file

@ -0,0 +1,16 @@
#if ($TOGGLE_NAME && $TOGGLE_NAME != "")
#set($TOGGLE = $TOGGLE_NAME)
#else
#set($TOGGLE = "TODO")
#end
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
internal class Default${NAME}FeatureToggles(
private val featureTogglesManager: FeatureTogglesManager,
) : ${NAME}FeatureToggles {
override val isFeatureEnabled: Boolean
get() = featureTogglesManager.isFeatureEnabled(name = "$TOGGLE")
}

17
.idea/fileTemplates/FlowPackaging.kt generated Normal file
View file

@ -0,0 +1,17 @@
#if ($FlowType && $FlowType != "")
#set($Type = $FlowType)
#else
#set($Type = "TODO")
#end
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.producer#end
import com.tangem.domain.core.flow.FlowProducer
interface ${NAME}Producer : FlowProducer<${FlowType}> {
data class Params(
val id: String, // TODO("Not yet implemented")
)
interface Factory : FlowProducer.Factory<Params, ${NAME}Producer>
}

View file

@ -0,0 +1,18 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.di#end
import ${PACKAGE_NAME}.fetcher.Default${NAME}Fetcher
import ${PACKAGE_NAME}.fetcher.${NAME}Fetcher
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal interface ${NAME}FetcherModule {
@Binds
@Singleton
fun bind${NAME}Fetcher(impl: Default${NAME}Fetcher): ${NAME}Fetcher
}

View file

@ -0,0 +1,20 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.di#end
import ${PACKAGE_NAME}.producer.Default${NAME}Producer
import ${PACKAGE_NAME}.producer.${NAME}Producer
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal interface ${NAME}ProducerFactoryModule {
@Binds
@Singleton
fun bind${NAME}ProducerFactory(
impl: Default${NAME}Producer.Factory,
): ${NAME}Producer.Factory
}

View file

@ -0,0 +1,23 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.di#end
import ${PACKAGE_NAME}.producer.${NAME}Producer
import ${PACKAGE_NAME}.supplier.${NAME}Supplier
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal object ${NAME}SupplierModule {
@Provides
@Singleton
fun provide${NAME}Supplier(factory: ${NAME}Producer.Factory): ${NAME}Supplier {
return object : ${NAME}Supplier(
factory = factory,
keyCreator = { TODO("Not yet implemented") },
) {}
}
}

View file

@ -0,0 +1,14 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.fetcher#end
import arrow.core.Either
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import javax.inject.Inject
internal class Default${NAME}Fetcher @Inject constructor(
private val dispatchers: CoroutineDispatcherProvider,
) : ${NAME}Fetcher {
override suspend fun invoke(params: ${NAME}Fetcher.Params): Either<Throwable, Unit> {
TODO("Not yet implemented")
}
}

View file

@ -0,0 +1,31 @@
#if ($FlowType && $FlowType != "")
#set($Type = $FlowType)
#else
#set($Type = "TODO")
#end
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.producer#end
import arrow.core.Option
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.Flow
internal class Default${NAME}Producer @AssistedInject constructor(
@Assisted val params: ${NAME}Producer.Params,
private val dispatchers: CoroutineDispatcherProvider,
) : TestProducer {
override val fallback: Option<$Type>
get() = TODO("Not yet implemented")
override fun produce(): Flow<$Type> {
TODO("Not yet implemented")
}
@AssistedFactory
interface Factory : ${NAME}Producer.Factory {
override fun create(params: ${NAME}Producer.Params): Default${NAME}Producer
}
}

View file

@ -0,0 +1,10 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.fetcher#end
import com.tangem.domain.core.flow.FlowFetcher
interface ${NAME}Fetcher : FlowFetcher<${NAME}Fetcher.Params> {
data class Params(
val id: String, // TODO("Not yet implemented")
)
}

View file

@ -0,0 +1,15 @@
#if ($FlowType && $FlowType != "")
#set($Type = $FlowType)
#else
#set($Type = "TODO")
#end
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.supplier#end
import ${PACKAGE_NAME}.producer.${NAME}Producer
import com.tangem.domain.core.flow.FlowCachingSupplier
import kotlinx.coroutines.flow.Flow
abstract class ${NAME}Supplier(
override val factory: ${NAME}Producer.Factory,
override val keyCreator: (${NAME}Producer.Params) -> String,
) : FlowCachingSupplier<${NAME}Producer, ${NAME}Producer.Params, $Type>()

View file

@ -28,6 +28,7 @@ android {
packaging {
jniLibs {
useLegacyPackaging = true
excludes.add("lib/x86_64/libargon2.so")
}
resources.excludes.add("META-INF/LICENSE.md")
resources.excludes.add("META-INF/NOTICE.md")
@ -96,6 +97,9 @@ configurations.all {
force(
"org.bouncycastle:bcpkix-jdk15on:1.70",
deps.kotlin.coroutines,
deps.kotlin.coroutines.jvm,
deps.kotlin.coroutines.android,
)
}
}
@ -111,6 +115,7 @@ dependencies {
implementation(projects.domain.account)
implementation(projects.domain.models)
implementation(projects.domain.core)
api(projects.domain.common)
implementation(projects.domain.card)
implementation(projects.domain.demo)
implementation(projects.domain.demo.models)
@ -154,6 +159,7 @@ dependencies {
implementation(projects.domain.walletManager)
implementation(projects.domain.walletManager.models)
implementation(projects.domain.yieldSupply)
implementation(projects.domain.blockaid)
implementation(projects.common)
implementation(projects.common.routing)

View file

@ -19,6 +19,7 @@ class ApplicationInjectionExecutionRule : TestRule {
OnComponentReadyRunner.addListener(
tangemApplication, ApplicationEntryPoint::class.java
) { _: ApplicationEntryPoint ->
tangemApplication.preInit()
tangemApplication.init()
}
base.evaluate()

View file

@ -100,6 +100,12 @@ abstract class BaseTestCase : TestCase(
value = false
)
}
appPreferencesStore.editData { mutablePreferences ->
mutablePreferences.set(
key = PreferencesKeys.getShouldShowNotificationKey("EnablePushesReminderNotification"),
value = false
)
}
promoRepository.setNeverToShowWalletPromo(PromoId.Sepa)
}
apiEnvironmentRule.setup(apiConfigsManager)
@ -130,15 +136,14 @@ abstract class BaseTestCase : TestCase(
composeTestRule.onRoot(useUnmergedTree = useUnmergedTree).printToLog(tag, maxDepth)
}
fun waitForIdle() = composeTestRule.waitForIdle()
private fun setFeatureToggles() {
runBlocking {
with(featureTogglesManager as MutableFeatureTogglesManager) {
changeToggle("WALLET_CONNECT_REDESIGN_ENABLED", true)
changeToggle("WALLET_BALANCE_FETCHER_ENABLED", true)
changeToggle("SEND_VIA_SWAP_ENABLED", true)
changeToggle("SWAP_REDESIGN_ENABLED", true)
changeToggle("SEND_REDESIGN_ENABLED", true)
changeToggle("NEW_ONRAMP_MAIN_ENABLED", true)
}
}

View file

@ -4,8 +4,10 @@ object TestConstants {
const val TOTAL_BALANCE = "$3,299.18"
const val RECIPIENT_ADDRESS = "0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0"
const val CARDANO_ADDRESS = "addr1q8f9499e58k4hhfd9vhawprxt3xd94x7rmlyp33ee4xkatakcl2zgkrg0p6ceqkndtkw4cumfe9enhdph8yhuswn785srksm9p"
const val WAIT_UNTIL_TIMEOUT = 20_000L
const val WAIT_UNTIL_TIMEOUT_LONG = 30_000L
const val MARKETS_MAIN_NETWORK_SUFFIX = "MAIN"

View file

@ -25,7 +25,7 @@ fun BaseTestCase.pullToRefresh() {
direction = SwipeDirection.DOWN,
startHeightRatio = 0.2f,
endHeightRatio = 0.8f,
steps = 2000
steps = 1000
)
}
@ -53,6 +53,31 @@ fun BaseTestCase.openTheAppFromRecents() {
device.uiDevice.click(centerX, centerY)
}
fun BaseTestCase.disableWiFi() {
device.uiDevice.executeShellCommand("svc wifi disable")
}
fun BaseTestCase.disableMobileData() {
device.uiDevice.executeShellCommand("svc data disable")
}
fun BaseTestCase.enableWiFi() {
device.uiDevice.executeShellCommand("svc wifi enable")
}
fun BaseTestCase.enableMobileData() {
device.uiDevice.executeShellCommand("svc data enable")
}
fun BaseTestCase.stopApp(packageName: String) {
device.apps.kill(packageName)
}
fun BaseTestCase.launchApp(packageName: String) {
device.apps.waitForAppLaunchAndReady(packageName = packageName)
device.apps.launch(packageName)
}
enum class SwipeDirection {
UP, DOWN
}

View file

@ -9,10 +9,11 @@ import com.tangem.tap.domain.sdk.mocks.MockContent
import com.tangem.tap.domain.sdk.mocks.MockProvider
import io.qameta.allure.kotlin.Allure.step
fun BaseTestCase.openMainScreen(
fun BaseTestCase.scanCard(
productType: ProductType? = null,
mockContent: MockContent? = null,
alreadyActivatedDialogIsShown : Boolean = false
alreadyActivatedDialogIsShown: Boolean = false,
isTwinsCard: Boolean = false,
) {
if (productType != null) {
MockProvider.setMocks(productType)
@ -28,10 +29,34 @@ fun BaseTestCase.openMainScreen(
}
if (alreadyActivatedDialogIsShown) {
step("Click on 'This is my wallet' button") {
composeTestRule.waitForIdle()
waitForIdle()
AlreadyUsedWalletDialogPageObject { thisIsMyWalletButton.click() }
}
}
if (isTwinsCard) {
step("Click on 'Continue' button") {
onOnboardingScreen { continueButton.clickWithAssertion() }
}
step("Click on 'Continue to my wallet' button") {
onOnboardingScreen { continueToMyWalletButton.clickWithAssertion() }
}
}
}
fun BaseTestCase.openMainScreen(
productType: ProductType? = null,
mockContent: MockContent? = null,
alreadyActivatedDialogIsShown: Boolean = false,
isTwinsCard: Boolean = false,
) {
step("Scan card") {
scanCard(
productType = productType,
mockContent = mockContent,
alreadyActivatedDialogIsShown = alreadyActivatedDialogIsShown,
isTwinsCard = isTwinsCard,
)
}
step("Assert 'Main' screen is displayed") {
onMainScreen { screenContainer.assertIsDisplayed() }
}
@ -51,6 +76,7 @@ fun BaseTestCase.synchronizeAddresses(balance: String) {
fun BaseTestCase.openDeviceSettingsScreen() {
step("Open wallet details") {
waitForIdle()
onTopBar { moreButton.clickWithAssertion() }
}
step("Open 'Wallet settings' screen") {

View file

@ -0,0 +1,118 @@
package com.tangem.scenarios
import com.tangem.common.BaseTestCase
import com.tangem.common.extensions.SwipeDirection
import com.tangem.common.extensions.swipeVertical
import com.tangem.screens.onMainScreen
import io.qameta.allure.kotlin.Allure.step
fun BaseTestCase.checkSingleCurrencyMainScreen(
cardBlockchain: String,
cardTitle: String,
withTransactions: Boolean = false,
withWalletImage: Boolean = true
) {
step("Assert card title equal '$cardTitle'") {
onMainScreen { walletNameText.assertTextEquals(cardTitle) }
}
if (withWalletImage) {
step("Assert card image is displayed") { //TODO: create assertion method for checking images
onMainScreen { walletImage.assertIsDisplayed() }
}
} else {
step("Assert card image is not displayed") {
onMainScreen { walletImage.assertIsNotDisplayed() }
}
}
step("Assert 'Receive' button is displayed") {
onMainScreen { receiveButton.assertIsDisplayed() }
}
step("Assert 'Buy' button is displayed") {
onMainScreen { buyButton.assertIsDisplayed() }
}
step("Assert 'Send' button is displayed") {
onMainScreen { sendButton.assertIsDisplayed() }
}
step("Assert 'Sell' button is displayed") {
onMainScreen { sellButton.assertIsDisplayed() }
}
step("Assert 'Swap' button is not displayed") {
onMainScreen { swapButton.assertIsNotDisplayed() }
}
step("Assert 'Market Price' on single card main screen is displayed") {
onMainScreen { marketPriceBlock().assertIsDisplayed() }
}
step("Assert 'Market Price' title equals $cardBlockchain Market Price") {
onMainScreen { marketPriceText.assertTextContains("$cardBlockchain Market Price") }
}
step("Swipe up") {
swipeVertical(SwipeDirection.UP)
}
if (withTransactions) {
step("Assert 'Transactions' block is displayed") {
onMainScreen { transactionsExplorerText.assertIsDisplayed() }
}
step("Assert 'Transactions' title is displayed") {
onMainScreen { transactionsTitle.assertIsDisplayed() }
}
step("Assert 'Explorer' icon is displayed") {
onMainScreen { transactionsExplorerIcon.assertIsDisplayed() }
}
} else {
step("Assert empty 'Transactions' block is displayed") {
onMainScreen { emptyTransactionBlock.assertIsDisplayed() }
}
step("Assert empty 'Transactions' block icon is displayed") {
onMainScreen { emptyTransactionBlockIcon.assertIsDisplayed() }
}
step("Assert empty 'Transactions' block text is displayed") {
onMainScreen { emptyTransactionBlockText.assertIsDisplayed() }
}
step("Assert empty 'Transactions' block 'Explore' button is displayed") {
onMainScreen { emptyTransactionBlockExploreButton.assertIsDisplayed() }
}
}
step("Assert 'Organize tokens' button is not displayed") {
onMainScreen { organizeTokensButtonWithoutLazySearch.assertIsNotDisplayed() }
}
}
fun BaseTestCase.checkMultiCurrencyMainScreen(
devicesCount: String,
cardTitle: String,
withWalletImage: Boolean = true
) {
step("Assert card title equal '$cardTitle'") {
onMainScreen { walletNameText.assertTextEquals(cardTitle) }
}
if (withWalletImage) {
step("Assert card image is displayed") {
onMainScreen { walletImage.assertIsDisplayed() }
}
} else {
step("Assert card image is not displayed") {
onMainScreen { walletImage.assertIsNotDisplayed() }
}
}
step("Assert devices count equal to '$devicesCount'") {
onMainScreen { walletDevicesCount.assertTextContains(devicesCount) }
}
step("Assert 'Buy' button is displayed") {
onMainScreen { buyButton.assertIsDisplayed() }
}
step("Assert 'Swap' button is displayed") {
onMainScreen { swapButton.assertIsDisplayed() }
}
step("Assert 'Sell' button is displayed") {
onMainScreen { sellButton.assertIsDisplayed() }
}
step("Assert 'Send' button is not displayed") {
onMainScreen { sendButton.assertIsNotDisplayed() }
}
step("Assert 'Receive' button is not displayed") {
onMainScreen { receiveButton.assertIsNotDisplayed() }
}
step("Assert 'Organize tokens' button is displayed") {
onMainScreen { organizeTokensButton().assertIsDisplayed() }
}
}

View file

@ -0,0 +1,112 @@
package com.tangem.scenarios
import com.tangem.common.BaseTestCase
import com.tangem.screens.onOnboardingScreen
import io.qameta.allure.kotlin.Allure.step
fun BaseTestCase.checkBackupScreen() {
step("Assert 'Creating a backup' top bar title is displayed") {
onOnboardingScreen { creatingBackupTobBarTitle.assertIsDisplayed() }
}
step("Assert 'Prepare your scan or ring' title is displayed") {
onOnboardingScreen { prepareYouCardOrRingTitle.assertIsDisplayed() }
}
step("Assert 'Start backup' text is displayed") {
onOnboardingScreen { startBackupText.assertIsDisplayed() }
}
step("Assert 'Scan card' button is displayed") {
onOnboardingScreen { scanCardButton.assertIsDisplayed() }
}
step("Assert 'Skip for later' button is not displayed") {
onOnboardingScreen { skipForLaterButton.assertIsNotDisplayed() }
}
}
fun BaseTestCase.checkCreateWalletScreenForWalletNoWallets() {
step("Assert 'Create wallet' tob bar title is displayed") {
onOnboardingScreen { createWalletTopBarTitle.assertIsDisplayed() }
}
step("Assert top bar 'Back' button is displayed") {
onOnboardingScreen { topBarBackButton.assertIsDisplayed() }
}
step("Assert top bar 'More' button is displayed") {
onOnboardingScreen { topBarMoreButton.assertIsDisplayed() }
}
step("Assert 'Create wallet' title is displayed") {
onOnboardingScreen { createWalletTitle.assertIsDisplayed() }
}
step("Assert 'Create wallet' text is displayed") {
onOnboardingScreen { createWalletText.assertIsDisplayed() }
}
step("Assert 'Create wallet' button is displayed") {
onOnboardingScreen { createWalletButton.assertIsDisplayed() }
}
}
fun BaseTestCase.openAndCheckBackupScreenForWalletNoWallets() {
step("Click on 'Create wallet' button") {
onOnboardingScreen { createWalletButton.performClick() }
}
step("Assert 'Getting started' top bar title is displayed") {
onOnboardingScreen { gettingStartedTobBarTitle.assertIsDisplayed() }
}
step("Assert 'Backup wallet' title is displayed") {
onOnboardingScreen { backupWalletTitle.assertIsDisplayed() }
}
step("Assert 'Backup wallet' text is displayed") {
onOnboardingScreen { backupWalletText.assertIsDisplayed() }
}
step("Assert 'Backup now' button is displayed") {
onOnboardingScreen { backupWalletButton.assertIsDisplayed() }
}
step("Assert 'Skip for later' button is not displayed") {
onOnboardingScreen { skipForLaterButton.assertIsNotDisplayed() }
}
}
fun BaseTestCase.checkCreateWalletScreenForWallet2NoWallets() {
step("Assert 'Create a wallet' top bar title is displayed") {
onOnboardingScreen { createWalletTopBarTitle.assertIsDisplayed() }
}
step("Assert top bar 'Back' button is displayed") {
onOnboardingScreen { topBarBackButton.assertIsDisplayed() }
}
step("Assert top bar 'More' button is displayed") {
onOnboardingScreen { topBarMoreButton.assertIsDisplayed() }
}
step("Assert 'Generate keys privately' title is displayed") {
onOnboardingScreen { generateKeysPrivatelyTitle.assertIsDisplayed() }
}
step("Assert 'Generate keys privately' text is displayed") {
onOnboardingScreen { generateKeysPrivatelyText.assertIsDisplayed() }
}
step("Assert 'Create wallet' button is displayed") {
onOnboardingScreen { createWalletButton.assertIsDisplayed() }
}
step("Assert 'Other options' button is displayed") {
onOnboardingScreen { otherOptionsButton.assertIsDisplayed() }
}
}
fun BaseTestCase.openAndCheckBackupScreenForWallet2NoWallets() {
step("Click on 'Create wallet' button") {
onOnboardingScreen { createWalletButton.performClick() }
}
step("Assert 'Creating a backup' top bar title is displayed") {
onOnboardingScreen { creatingBackupTobBarTitle.assertIsDisplayed() }
}
step("Assert 'No backup devices' title is displayed") {
onOnboardingScreen { noBackupDevicesTitle.assertIsDisplayed() }
}
step("Assert 'No backup devices' text is displayed") {
onOnboardingScreen { noBackupDevicesText.assertIsDisplayed() }
}
step("Assert 'Add card or ring' button is displayed") {
onOnboardingScreen { addCardOrRingButton.assertIsDisplayed() }
}
step("Assert 'Finalize backup' button is displayed") {
onOnboardingScreen { finalizeBackupButton.assertIsDisplayed() }
}
step("Assert 'Skip for later' button is not displayed") {
onOnboardingScreen { skipForLaterButton.assertIsNotDisplayed() }
}
}

View file

@ -3,15 +3,13 @@ package com.tangem.screens
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.common.BaseTestCase
import com.tangem.core.ui.R
import com.tangem.core.ui.test.BaseButtonTestTags
import com.tangem.core.ui.test.BuyTokenDetailsScreenTestTags
import com.tangem.core.ui.test.NotificationTestTags
import com.tangem.core.ui.test.TopAppBarTestTags
import com.tangem.core.ui.test.*
import io.github.kakaocup.compose.node.element.ComposeScreen
import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onComposeScreen
import io.github.kakaocup.compose.node.element.KNode
import io.github.kakaocup.kakao.common.utilities.getResourceString
import androidx.compose.ui.test.hasTestTag as withTestTag
import com.tangem.features.onramp.impl.R as OnrampImplR
class BuyTokenDetailsPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<BuyTokenDetailsPageObject>(semanticsProvider = semanticsProvider) {
@ -68,31 +66,65 @@ class BuyTokenDetailsPageObject(semanticsProvider: SemanticsNodeInteractionsProv
useUnmergedTree = true
}
val providerLoadingTitle: KNode = child {
hasTestTag(BuyTokenDetailsScreenTestTags.PROVIDER_LOADING_TITLE)
val recommendedTitle: KNode = child {
hasText(getResourceString(OnrampImplR.string.onramp_recommended_title))
}
val providerLoadingText: KNode = child {
hasTestTag(BuyTokenDetailsScreenTestTags.PROVIDER_LOADING_TEXT)
}
val providerTitle: KNode = child {
hasTestTag(BuyTokenDetailsScreenTestTags.PROVIDER_TITLE)
val bestRateIcon: KNode = child {
hasTestTag(OnrampOffersBlockTestTags.BEST_RATE_ICON)
useUnmergedTree = true
}
val providerText: KNode = child {
hasTestTag(BuyTokenDetailsScreenTestTags.PROVIDER_TEXT)
val bestRateTitle: KNode = child {
hasTestTag(OnrampOffersBlockTestTags.BEST_RATE_TITLE)
useUnmergedTree = true
}
val offerTokenAmount: KNode = child {
hasTestTag(OnrampOffersBlockTestTags.OFFER_TOKEN_AMOUNT)
useUnmergedTree = true
}
val timingIcon: KNode = child {
hasTestTag(OnrampOffersBlockTestTags.TIMING_ICON)
useUnmergedTree = true
}
val payWith: KNode = child {
hasTestTag(OnrampOffersBlockTestTags.PAY_WITH)
useUnmergedTree = true
}
val paymentMethodIcon: KNode = child {
hasTestTag(OnrampOffersBlockTestTags.PAYMENT_METHOD_ICON)
useUnmergedTree = true
}
val instantProcessingSpeedText: KNode = child {
hasText(getResourceString(R.string.onramp_instant_status))
useUnmergedTree = true
}
val providerName: KNode = child {
hasTestTag(OnrampOffersBlockTestTags.PROVIDER_NAME)
useUnmergedTree = true
}
val buyButton: KNode = child {
hasTestTag(BaseButtonTestTags.BUTTON)
hasTestTag(BaseButtonTestTags.TEXT)
hasText(getResourceString(R.string.common_buy))
useUnmergedTree = true
}
val toSBlock: KNode = child {
hasTestTag(BuyTokenDetailsScreenTestTags.TOS_BLOCK)
val continueButton: KNode = child {
hasTestTag(BaseButtonTestTags.TEXT)
hasText(getResourceString(R.string.common_continue))
useUnmergedTree = true
}
val allOffersButton: KNode = child {
hasTestTag(BaseButtonTestTags.TEXT)
hasText(getResourceString(R.string.onramp_all_offers_button_title))
useUnmergedTree = true
}
}

View file

@ -44,10 +44,30 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
}
val buyButton: KNode = child {
hasTestTag(MainScreenTestTags.MULTI_CURRENCY_ACTION_BUTTON)
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
hasText(getResourceString(R.string.common_buy))
}
val sendButton: KNode = child {
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
hasText(getResourceString(R.string.common_send))
}
val receiveButton: KNode = child {
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
hasText(getResourceString(R.string.common_receive))
}
val sellButton: KNode = child {
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
hasText(getResourceString(R.string.common_sell))
}
val swapButton: KNode = child {
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
hasText(getResourceString(R.string.common_swap))
}
val walletNameText: KNode = child {
hasTestTag(MainScreenTestTags.CARD_TITLE)
useUnmergedTree = true
@ -58,11 +78,19 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
useUnmergedTree = true
}
val marketPriceBlock: KNode = child {
hasTestTag(MarketPriceBlockTestTags.BLOCK)
val walletDevicesCount: KNode = child {
hasTestTag(MainScreenTestTags.DEVICES_COUNT)
useUnmergedTree = true
}
@OptIn(ExperimentalTestApi::class)
fun marketPriceBlock(): LazyListItemNode {
return lazyList.childWith<LazyListItemNode> {
hasTestTag(MarketPriceBlockTestTags.BLOCK)
useUnmergedTree = true
}
}
val marketPriceText: KNode = child {
hasTestTag(MarketPriceBlockTestTags.TEXT)
useUnmergedTree = true
@ -79,12 +107,26 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
useUnmergedTree = true
}
fun transactionsExplorer(): KNode {
return child {
hasTestTag(TransactionHistoryBlockTestTags.EXPLORER_TEXT)
hasText(getResourceString(R.string.common_explorer))
useUnmergedTree = true
}
val transactionsExplorerText: KNode = child {
hasTestTag(TransactionHistoryBlockTestTags.EXPLORER_TEXT)
hasText(getResourceString(R.string.common_explorer))
useUnmergedTree = true
}
val emptyTransactionBlock: KNode = child {
hasTestTag(EmptyTransactionBlockTestTags.BLOCK)
}
val emptyTransactionBlockIcon: KNode = child {
hasTestTag(EmptyTransactionBlockTestTags.ICON)
}
val emptyTransactionBlockText: KNode = child {
hasTestTag(EmptyTransactionBlockTestTags.TEXT)
}
val emptyTransactionBlockExploreButton: KNode = child {
hasTestTag(EmptyTransactionBlockTestTags.EXPLORE_BUTTON)
}
val notificationContainer: KNode = child {
@ -182,12 +224,10 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
}
}
fun organizeTokensButtonWithoutLazySearch(): KNode {
return child {
hasTestTag(MainScreenTestTags.ORGANIZE_TOKENS_BUTTON)
hasText(getResourceString(R.string.organize_tokens_title))
useUnmergedTree = true
}
val organizeTokensButtonWithoutLazySearch: KNode = child {
hasTestTag(MainScreenTestTags.ORGANIZE_TOKENS_BUTTON)
hasText(getResourceString(R.string.organize_tokens_title))
useUnmergedTree = true
}
fun tokenNetworkGroupTitle(tokenNetwork: String): KNode {

View file

@ -0,0 +1,163 @@
package com.tangem.screens
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.common.BaseTestCase
import com.tangem.core.ui.test.BaseButtonTestTags
import com.tangem.core.ui.test.StoriesScreenTestTags
import com.tangem.core.ui.test.TopAppBarTestTags
import com.tangem.wallet.R
import io.github.kakaocup.compose.node.element.ComposeScreen
import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onComposeScreen
import io.github.kakaocup.compose.node.element.KNode
import io.github.kakaocup.kakao.common.utilities.getResourceString
import io.github.kakaocup.kakao.common.views.KView
import io.github.kakaocup.kakao.text.KButton
import com.tangem.features.onboarding.v2.impl.R as OnboardingImplR
class OnboardingPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<OnboardingPageObject>(semanticsProvider = semanticsProvider) {
val topBarBackButton: KNode = child {
hasTestTag(TopAppBarTestTags.CLOSE_BUTTON)
useUnmergedTree = true
}
val continueButton: KNode = child {
hasTestTag(BaseButtonTestTags.TEXT)
hasText(getResourceString(R.string.common_continue))
useUnmergedTree = true
}
val continueToMyWalletButton: KNode = child {
hasTestTag(BaseButtonTestTags.TEXT)
hasText(getResourceString(R.string.onboarding_button_continue_wallet))
useUnmergedTree = true
}
val createWalletTopBarTitle: KNode = child {
hasTestTag(TopAppBarTestTags.TITLE)
hasText(getResourceString(OnboardingImplR.string.onboarding_create_wallet_header))
useUnmergedTree = true
}
val createWalletTitle: KNode = child {
hasTestTag(StoriesScreenTestTags.TITLE)
hasText(getResourceString(OnboardingImplR.string.onboarding_create_wallet_header))
useUnmergedTree = true
}
val createWalletText: KNode = child {
hasTestTag(StoriesScreenTestTags.TEXT)
hasText(getResourceString(OnboardingImplR.string.onboarding_create_wallet_body))
useUnmergedTree = true
}
val gettingStartedTobBarTitle: KNode = child {
hasTestTag(TopAppBarTestTags.TITLE)
hasText(getResourceString(OnboardingImplR.string.onboarding_getting_started))
useUnmergedTree = true
}
val creatingBackupTobBarTitle: KNode = child {
hasTestTag(TopAppBarTestTags.TITLE)
hasText(getResourceString(OnboardingImplR.string.onboarding_navbar_title_creating_backup))
useUnmergedTree = true
}
val prepareYouCardOrRingTitle: KNode = child {
hasText(getResourceString(OnboardingImplR.string.onboarding_title_scan_origin_card))
useUnmergedTree = true
}
val startBackupText: KNode = child {
hasText(getResourceString(OnboardingImplR.string.onboarding_subtitle_scan_primary))
useUnmergedTree = true
}
val topBarMoreButton: KNode = child {
hasTestTag(TopAppBarTestTags.MORE_BUTTON)
}
val backupWalletTitle: KNode = child {
hasText(getResourceString(OnboardingImplR.string.onboarding_wallet_info_title_first))
useUnmergedTree = true
}
val backupWalletText: KNode = child {
hasText(getResourceString(OnboardingImplR.string.onboarding_wallet_info_subtitle_first))
useUnmergedTree = true
}
val generateKeysPrivatelyTitle: KNode = child {
hasText(getResourceString(OnboardingImplR.string.onboarding_create_wallet_options_title))
useUnmergedTree = true
}
val generateKeysPrivatelyText: KNode = child {
hasText(getResourceString(OnboardingImplR.string.onboarding_create_wallet_options_message))
useUnmergedTree = true
}
val noBackupDevicesTitle: KNode = child {
hasText(getResourceString(OnboardingImplR.string.onboarding_subtitle_no_backup_cards))
useUnmergedTree = true
}
val noBackupDevicesText: KNode = child {
hasText(getResourceString(OnboardingImplR.string.onboarding_title_no_backup_cards))
useUnmergedTree = true
}
val createWalletButton: KNode = child {
hasTestTag(BaseButtonTestTags.TEXT)
hasText(getResourceString(OnboardingImplR.string.onboarding_create_wallet_button_create_wallet))
useUnmergedTree = true
}
val backupWalletButton: KNode = child {
hasTestTag(BaseButtonTestTags.TEXT)
hasText(getResourceString(OnboardingImplR.string.onboarding_button_backup_now))
useUnmergedTree = true
}
val scanCardButton: KNode = child {
hasTestTag(BaseButtonTestTags.TEXT)
hasText(getResourceString(OnboardingImplR.string.onboarding_button_backup_card))
useUnmergedTree = true
}
val otherOptionsButton: KNode = child {
hasTestTag(BaseButtonTestTags.TEXT)
hasText(getResourceString(OnboardingImplR.string.onboarding_create_wallet_options_button_options))
useUnmergedTree = true
}
val addCardOrRingButton: KNode = child {
hasTestTag(BaseButtonTestTags.TEXT)
hasText(getResourceString(OnboardingImplR.string.onboarding_button_add_backup_card))
useUnmergedTree = true
}
val finalizeBackupButton: KNode = child {
hasTestTag(BaseButtonTestTags.TEXT)
hasText(getResourceString(OnboardingImplR.string.onboarding_button_finalize_backup))
useUnmergedTree = true
}
val skipForLaterButton: KNode = child {
hasTestTag(BaseButtonTestTags.TEXT)
hasText(getResourceString(OnboardingImplR.string.onboarding_button_skip_backup))
useUnmergedTree = true
}
val enableNFCAlert: KView = KView {
withId(R.id.alertTitle)
}
val cancelButton: KButton = KButton {
withId(android.R.id.button2)
}
}
internal fun BaseTestCase.onOnboardingScreen(function: OnboardingPageObject.() -> Unit) =
onComposeScreen(composeTestRule, function)

View file

@ -1,17 +1,14 @@
package com.tangem.screens
import androidx.compose.ui.test.SemanticsMatcher
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.common.BaseTestCase
import com.tangem.common.utils.LazyListItemNode
import com.tangem.core.ui.test.BaseBottomSheetTestTags
import com.tangem.core.ui.test.OnrampOffersBlockTestTags
import com.tangem.core.ui.test.SelectPaymentMethodBottomSheetTestTags
import com.tangem.core.ui.test.TopAppBarTestTags
import com.tangem.core.ui.utils.LazyListItemPositionSemantics
import com.tangem.features.onramp.impl.R
import io.github.kakaocup.compose.node.element.ComposeScreen
import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onComposeScreen
import io.github.kakaocup.compose.node.element.KNode
import io.github.kakaocup.compose.node.element.lazylist.KLazyListNode
import io.github.kakaocup.kakao.common.utilities.getResourceString
import androidx.compose.ui.test.hasTestTag as withTestTag
import androidx.compose.ui.test.hasText as withText
@ -19,30 +16,31 @@ import androidx.compose.ui.test.hasText as withText
class SelectPaymentMethodPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<SelectPaymentMethodPageObject>(semanticsProvider = semanticsProvider) {
private val lazyList = KLazyListNode(
semanticsProvider = semanticsProvider,
viewBuilderAction = { hasTestTag(SelectPaymentMethodBottomSheetTestTags.LAZY_LIST) },
itemTypeBuilder = { itemType(::LazyListItemNode) },
positionMatcher = { position ->
SemanticsMatcher.expectValue(
LazyListItemPositionSemantics,
position
)
}
)
val title: KNode = child {
hasTestTag(TopAppBarTestTags.TITLE)
hasText(getResourceString(R.string.onramp_pay_with))
hasTestTag(BaseBottomSheetTestTags.TITLE)
hasText(getResourceString(R.string.onramp_all_offers_button_title))
}
fun paymentMethodWithNameAndIcon(name: String): KNode {
return lazyList.child<KNode> {
hasAnyDescendant(withText(name))
hasAnyDescendant(withTestTag(SelectPaymentMethodBottomSheetTestTags.PAYMENT_METHOD_ICON))
useUnmergedTree = true
}
val subtitle: KNode = child {
hasTestTag(BaseBottomSheetTestTags.SUBTITLE)
hasText(getResourceString(R.string.onramp_payment_method_subtitle))
}
val closeButton: KNode = child {
hasTestTag(BaseBottomSheetTestTags.CLOSE_BUTTON)
}
fun paymentMethodWithName(name: String): KNode = child {
hasTestTag(SelectPaymentMethodBottomSheetTestTags.PAYMENT_METHOD)
hasAnyDescendant(withText(name))
hasAnyDescendant(withTestTag(SelectPaymentMethodBottomSheetTestTags.PAYMENT_METHOD_ICON))
hasAnyDescendant(withTestTag(SelectPaymentMethodBottomSheetTestTags.TIMING_ICON))
hasAnyDescendant(withTestTag(OnrampOffersBlockTestTags.TIMING_TEXT))
hasAnyDescendant(withTestTag(SelectPaymentMethodBottomSheetTestTags.TOKEN_AMOUNT))
hasAnyDescendant(withTestTag(SelectPaymentMethodBottomSheetTestTags.PROVIDER_COUNT_ICON))
hasAnyDescendant(withTestTag(SelectPaymentMethodBottomSheetTestTags.PROVIDER_COUNT_TEXT))
hasAnyDescendant(withTestTag(SelectPaymentMethodBottomSheetTestTags.UP_TO_TEXT))
useUnmergedTree = true
}
}

View file

@ -2,87 +2,78 @@ package com.tangem.screens
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.common.BaseTestCase
import com.tangem.core.ui.test.SelectProviderBottomSheetTestTags
import com.tangem.core.ui.test.BaseBottomSheetTestTags
import com.tangem.core.ui.test.BaseButtonTestTags
import com.tangem.core.ui.test.OnrampOffersBlockTestTags
import com.tangem.features.onramp.impl.R
import io.github.kakaocup.compose.node.element.ComposeScreen
import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onComposeScreen
import io.github.kakaocup.compose.node.element.KNode
import io.github.kakaocup.kakao.common.utilities.getResourceString
import androidx.compose.ui.test.hasText as withText
import com.tangem.core.ui.R as CoreUiR
class SelectProviderPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<SelectProviderPageObject>(semanticsProvider = semanticsProvider) {
val title: KNode = child {
hasText(getResourceString(R.string.onramp_choose_provider_title_hint))
hasTestTag(BaseBottomSheetTestTags.TITLE)
hasText(getResourceString(R.string.onramp_all_offers_button_title))
}
val subtitle: KNode = child {
hasTestTag(BaseBottomSheetTestTags.SUBTITLE)
hasText(getResourceString(R.string.express_provider))
useUnmergedTree = true
}
val bestRateIcon: KNode = child {
hasTestTag(OnrampOffersBlockTestTags.BEST_RATE_ICON)
useUnmergedTree = true
}
val bestRateTitle: KNode = child {
hasTestTag(OnrampOffersBlockTestTags.BEST_RATE_TITLE)
useUnmergedTree = true
}
val offerTokenAmount: KNode = child {
hasTestTag(OnrampOffersBlockTestTags.OFFER_TOKEN_AMOUNT)
useUnmergedTree = true
}
val timingIcon: KNode = child {
hasTestTag(OnrampOffersBlockTestTags.TIMING_ICON)
useUnmergedTree = true
}
val payWith: KNode = child {
hasTestTag(OnrampOffersBlockTestTags.PAY_WITH)
useUnmergedTree = true
}
val youGetText: KNode = child {
hasText(getResourceString(R.string.onramp_title_you_get))
}
val paymentMethodIcon: KNode = child {
hasTestTag(SelectProviderBottomSheetTestTags.PAYMENT_METHOD_ICON)
hasTestTag(OnrampOffersBlockTestTags.PAYMENT_METHOD_ICON)
useUnmergedTree = true
}
val paymentMethodTitle: KNode = child {
hasTestTag(SelectProviderBottomSheetTestTags.PAYMENT_METHOD_NAME)
val providerName: KNode = child {
hasTestTag(OnrampOffersBlockTestTags.PROVIDER_NAME)
useUnmergedTree = true
}
val paymentMethodName: KNode = child {
hasTestTag(SelectProviderBottomSheetTestTags.PAYMENT_METHOD_NAME)
val instantProcessingSpeedText: KNode = child {
hasText(getResourceString(com.tangem.core.ui.R.string.onramp_instant_status))
useUnmergedTree = true
}
val paymentMethodExpandButton: KNode = child {
hasTestTag(SelectProviderBottomSheetTestTags.PAYMENT_METHOD_EXPAND_BUTTON)
useUnmergedTree = true
}
val availableProviderItem: KNode = child {
hasTestTag(SelectProviderBottomSheetTestTags.AVAILABLE_PROVIDER_ITEM)
useUnmergedTree = true
}
val availableProviderName: KNode = child {
hasTestTag(SelectProviderBottomSheetTestTags.AVAILABLE_PROVIDER_NAME)
useUnmergedTree = true
}
val tokenAmount: KNode = child {
hasTestTag(SelectProviderBottomSheetTestTags.TOKEN_AMOUNT)
useUnmergedTree = true
}
val unavailableProviderItem: KNode = child {
hasTestTag(SelectProviderBottomSheetTestTags.UNAVAILABLE_PROVIDER_ITEM)
useUnmergedTree = true
}
val unavailableProviderName: KNode = child {
hasTestTag(SelectProviderBottomSheetTestTags.UNAVAILABLE_PROVIDER_NAME)
useUnmergedTree = true
}
val moreProvidersIcon: KNode = child {
hasTestTag(SelectProviderBottomSheetTestTags.MORE_PROVIDERS_ICON)
useUnmergedTree = true
}
val moreProvidersText: KNode = child {
hasTestTag(SelectProviderBottomSheetTestTags.MORE_PROVIDERS_TEXT)
useUnmergedTree = true
}
val bestRateLabel: KNode = child {
hasTestTag(SelectProviderBottomSheetTestTags.BEST_RATE_LABEL)
useUnmergedTree = true
}
fun availableProviderWithName(name: String, tokenAmount: String, rate: String): KNode = child {
hasTestTag(SelectProviderBottomSheetTestTags.AVAILABLE_PROVIDER_ITEM)
hasAnyChild(withText(name))
hasAnyChild(withText(tokenAmount))
hasAnyChild(withText(rate))
val buyButton: KNode = child {
hasTestTag(BaseButtonTestTags.TEXT)
hasText(getResourceString(CoreUiR.string.common_buy))
useUnmergedTree = true
}
}

View file

@ -4,11 +4,14 @@ import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.common.BaseTestCase
import com.tangem.core.ui.R
import com.tangem.core.ui.test.BaseButtonTestTags
import com.tangem.core.ui.test.NotificationTestTags
import com.tangem.core.ui.test.TopAppBarTestTags
import io.github.kakaocup.compose.node.element.ComposeScreen
import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onComposeScreen
import io.github.kakaocup.compose.node.element.KNode
import io.github.kakaocup.kakao.common.utilities.getResourceString
import androidx.compose.ui.test.hasText as withText
import com.tangem.common.ui.R as CommonUiR
class SendConfirmPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<SendConfirmPageObject>(semanticsProvider = semanticsProvider) {
@ -24,6 +27,41 @@ class SendConfirmPageObject(semanticsProvider: SemanticsNodeInteractionsProvider
useUnmergedTree = true
}
val minimumSendAmountErrorTitle: KNode = child {
hasTestTag(NotificationTestTags.TITLE)
hasText(getResourceString(CommonUiR.string.send_notification_invalid_amount_title))
useUnmergedTree = true
}
fun minimumSendAmountErrorIcon(amount: String): KNode = child {
hasAnySibling(
withText(
getResourceString(
CommonUiR.string.send_notification_invalid_minimum_amount_text,
amount,
amount,
)
)
)
hasTestTag(NotificationTestTags.ICON)
useUnmergedTree = true
}
fun minimumSendAmountErrorMessage(
amount: String,
): KNode = child {
hasTestTag(NotificationTestTags.MESSAGE)
hasText(
getResourceString(
CommonUiR.string.send_notification_invalid_minimum_amount_text,
amount,
amount,
)
)
useUnmergedTree = true
}
}
internal fun BaseTestCase.onSendConfirmScreen(function: SendConfirmPageObject.() -> Unit) =

View file

@ -3,18 +3,12 @@ package com.tangem.screens
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.common.BaseTestCase
import com.tangem.core.ui.test.StoriesScreenTestTags
import com.tangem.wallet.R
import io.github.kakaocup.compose.node.element.ComposeScreen
import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onComposeScreen
import io.github.kakaocup.compose.node.element.KNode
import io.github.kakaocup.kakao.common.views.KView
import io.github.kakaocup.kakao.text.KButton
class StoriesPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
ComposeScreen<StoriesPageObject>(
semanticsProvider = semanticsProvider,
viewBuilderAction = { hasTestTag(StoriesScreenTestTags.SCREEN_CONTAINER) }
) {
ComposeScreen<StoriesPageObject>(semanticsProvider = semanticsProvider) {
val scanButton: KNode = child {
hasTestTag(StoriesScreenTestTags.SCAN_BUTTON)
@ -23,14 +17,6 @@ class StoriesPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
val orderButton: KNode = child {
hasTestTag(StoriesScreenTestTags.ORDER_BUTTON)
}
val enableNFCAlert: KView = KView {
withId(R.id.alertTitle)
}
val cancelButton: KButton = KButton {
withId(android.R.id.button2)
}
}
internal fun BaseTestCase.onStoriesScreen(function: StoriesPageObject.() -> Unit) =

View file

@ -5,6 +5,7 @@ import androidx.compose.ui.test.SemanticsMatcher
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.common.BaseTestCase
import com.tangem.common.utils.LazyListItemNode
import com.tangem.core.ui.test.BaseActionButtonsBlockTestTags
import com.tangem.core.ui.test.BaseButtonTestTags
import com.tangem.core.ui.test.NotificationTestTags
import com.tangem.core.ui.test.TokenDetailsScreenTestTags
@ -85,7 +86,7 @@ class TokenDetailsPageObject(semanticsProvider: SemanticsNodeInteractionsProvide
private val horizontalActionChips = KLazyListNode(
semanticsProvider = semanticsProvider,
viewBuilderAction = { hasTestTag(TokenDetailsScreenTestTags.HORIZONTAL_ACTION_CHIPS) },
viewBuilderAction = { hasTestTag(BaseActionButtonsBlockTestTags.HORIZONTAL_ACTION_CHIPS) },
itemTypeBuilder = { itemType(::LazyListItemNode) },
positionMatcher = { position ->
SemanticsMatcher.expectValue(
@ -97,25 +98,25 @@ class TokenDetailsPageObject(semanticsProvider: SemanticsNodeInteractionsProvide
@OptIn(ExperimentalTestApi::class)
val swapButton: LazyListItemNode = horizontalActionChips.childWith<LazyListItemNode> {
hasTestTag(TokenDetailsScreenTestTags.ACTION_BUTTON)
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
hasText(getResourceString(R.string.common_swap))
}
@OptIn(ExperimentalTestApi::class)
val sellButton: LazyListItemNode = horizontalActionChips.childWith<LazyListItemNode> {
hasTestTag(TokenDetailsScreenTestTags.ACTION_BUTTON)
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
hasText(getResourceString(R.string.common_sell))
}
@OptIn(ExperimentalTestApi::class)
val buyButton: LazyListItemNode = horizontalActionChips.childWith<LazyListItemNode> {
hasTestTag(TokenDetailsScreenTestTags.ACTION_BUTTON)
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
hasText(getResourceString(R.string.common_buy))
}
@OptIn(ExperimentalTestApi::class)
val sendButton: LazyListItemNode = horizontalActionChips.childWith<LazyListItemNode> {
hasTestTag(TokenDetailsScreenTestTags.ACTION_BUTTON)
hasTestTag(BaseActionButtonsBlockTestTags.ACTION_BUTTON)
hasText(getResourceString(R.string.common_send))
}
@ -131,6 +132,18 @@ class TokenDetailsPageObject(semanticsProvider: SemanticsNodeInteractionsProvide
useUnmergedTree = true
}
val topUpYourWalletNotificationTitle: KNode = child {
hasTestTag(NotificationTestTags.TITLE)
hasText(getResourceString(R.string.warning_no_account_title))
useUnmergedTree = true
}
val topUpYourWalletNotificationIcon: KNode = child {
hasAnySibling(withText(getResourceString(R.string.warning_no_account_title)))
hasTestTag(NotificationTestTags.ICON)
useUnmergedTree = true
}
fun networkFeeNotificationMessage(
currencyName: String,
networkName: String,
@ -151,6 +164,23 @@ class TokenDetailsPageObject(semanticsProvider: SemanticsNodeInteractionsProvide
useUnmergedTree = true
}
fun topUpYourWalletNotificationMessage(
networkName: String,
amount: String,
currencySymbol: String,
): KNode = child {
hasTestTag(NotificationTestTags.MESSAGE)
hasText(
getResourceString(
R.string.no_account_generic,
networkName,
amount,
currencySymbol,
)
)
useUnmergedTree = true
}
fun goToBuyCurrencyButton(feeCurrencySymbol: String): KNode = child {
hasTestTag(BaseButtonTestTags.TEXT)
hasText(getResourceString(R.string.common_buy_currency, feeCurrencySymbol))

View file

@ -2,6 +2,7 @@ package com.tangem.screens
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import com.tangem.common.BaseTestCase
import com.tangem.core.ui.test.BaseBottomSheetTestTags
import com.tangem.core.ui.test.BaseButtonTestTags
import com.tangem.core.ui.test.WalletConnectBottomSheetTestTags
import com.tangem.core.ui.test.WalletConnectDetailsBottomSheetTestTags
@ -15,18 +16,18 @@ class WalletConnectDetailsBottomSheetPageObject(semanticsProvider: SemanticsNode
ComposeScreen<WalletConnectDetailsBottomSheetPageObject>(semanticsProvider = semanticsProvider) {
val title: KNode = child {
hasTestTag(WalletConnectDetailsBottomSheetTestTags.TITLE)
hasTestTag(BaseBottomSheetTestTags.TITLE)
hasText(getResourceString(WalletConnectImplR.string.wc_connected_app_title))
useUnmergedTree = true
}
val date: KNode = child {
hasTestTag(WalletConnectDetailsBottomSheetTestTags.DATE)
hasTestTag(BaseBottomSheetTestTags.SUBTITLE)
useUnmergedTree = true
}
val closeButton: KNode = child {
hasTestTag(WalletConnectDetailsBottomSheetTestTags.CLOSE_BUTTON)
hasTestTag(BaseBottomSheetTestTags.CLOSE_BUTTON)
useUnmergedTree = true
}

View file

@ -1,35 +0,0 @@
package com.tangem.steps
import com.tangem.common.BaseTestCase
import com.tangem.common.extensions.assertElementDoesNotExist
import com.tangem.screens.onMainScreen
import io.qameta.allure.kotlin.Allure.step
fun BaseTestCase.checkSingleCurrencyMainScreen(cardBlockchain: String, cardTitle: String) {
step("Assert card title equal '$cardTitle'") {
onMainScreen { walletNameText.assertTextEquals(cardTitle) }
}
step("Assert 'Transactions' block is displayed") {
onMainScreen { transactionsExplorer().assertExists() }
}
step("Assert 'Transactions' title is displayer") {
onMainScreen { transactionsTitle.assertIsDisplayed() }
}
step("Assert 'Explorer Icon' is displayed") {
onMainScreen { transactionsExplorerIcon.assertIsDisplayed() }
}
step("Assert card image is displayed") { //TODO: Придумать нормальную проверку / реализовать скриншот-тестинг
onMainScreen { walletImage.assertIsDisplayed() }
}
step("Assert 'Market Price' on single card main screen is displayed") {
onMainScreen { marketPriceBlock.assertIsDisplayed() }
}
step("Assert 'Market Price' title equals $cardBlockchain Market Price") {
onMainScreen { marketPriceText.assertTextContains("$cardBlockchain Market Price") }
}
step("Assert 'Organize tokens' button is not displayed") {
onMainScreen {
assertElementDoesNotExist({ organizeTokensButtonWithoutLazySearch() }, "Organize tokens button")
}
}
}

View file

@ -0,0 +1,203 @@
package com.tangem.tests
import com.tangem.common.BaseTestCase
import com.tangem.common.constants.TestConstants.CARDANO_ADDRESS
import com.tangem.common.extensions.clickWithAssertion
import com.tangem.common.extensions.pullToRefresh
import com.tangem.common.utils.resetWireMockScenarioState
import com.tangem.common.utils.setWireMockScenarioState
import com.tangem.scenarios.openMainScreen
import com.tangem.scenarios.synchronizeAddresses
import com.tangem.screens.*
import com.tangem.screens.onMainScreen
import com.tangem.screens.onSendAddressScreen
import com.tangem.screens.onSendScreen
import com.tangem.screens.onTokenDetailsScreen
import dagger.hilt.android.testing.HiltAndroidTest
import io.qameta.allure.kotlin.AllureId
import io.qameta.allure.kotlin.junit4.DisplayName
import org.junit.Test
@HiltAndroidTest
class BlockchainTest : BaseTestCase() {
@AllureId("3644")
@DisplayName("ADA: Checking the min amount/change = 1ADA")
@Test
fun adaCheckMinAmountTest() {
val tokenName = "Cardano"
val balance = "$0.00"
val errorSendAmount = "0.1"
val validSendAmount = "10"
val minAmount = "ADA 1.00"
val address = CARDANO_ADDRESS
val scenarioName = "user_tokens_api"
val scenarioState = "Cardano"
setupHooks(
additionalAfterSection = {
resetWireMockScenarioState(scenarioName)
}
).run {
step("Set WireMock scenario: '$scenarioName' to state: '$scenarioState'") {
setWireMockScenarioState(scenarioName = scenarioName, state = scenarioState)
}
step("Open 'Main Screen'") {
openMainScreen()
}
step("Synchronize addresses") {
synchronizeAddresses(balance)
}
step("Click on token with name: '$tokenName'") {
onMainScreen { tokenWithTitleAndAddress(tokenName).clickWithAssertion() }
}
step("Click on 'Send' button") {
onTokenDetailsScreen { sendButton.performClick() }
}
step("Type '$errorSendAmount' in input text field") {
onSendScreen {
amountInputTextField.performClick()
amountInputTextField.performTextReplacement(errorSendAmount)
}
}
step("Click on 'Next' button") {
onSendScreen { nextButton.clickWithAssertion() }
}
step("Type address in input text field") {
onSendAddressScreen { addressTextField.performTextReplacement(address) }
}
step("Click on 'Next' button") {
onSendAddressScreen { nextButton.clickWithAssertion() }
}
step("Assert 'Invalid amount' error title is displayed") {
onSendConfirmScreen { minimumSendAmountErrorTitle.assertIsDisplayed() }
}
step("Assert 'Invalid amount' error icon is displayed") {
onSendConfirmScreen { minimumSendAmountErrorIcon(minAmount).assertIsDisplayed() }
}
step("Assert 'Invalid amount' error message is displayed") {
onSendConfirmScreen { minimumSendAmountErrorMessage(minAmount).assertIsDisplayed() }
}
step("Press system 'Back' button") {
device.uiDevice.pressBack()
}
step("Assert address text field is displayed") {
onSendAddressScreen { addressTextField.assertIsDisplayed() }
}
step("Press system 'Back' button") {
device.uiDevice.pressBack()
}
step("Type '$validSendAmount' in input text field") {
onSendScreen {
amountInputTextField.performClick()
amountInputTextField.performTextReplacement(errorSendAmount)
}
}
step("Click on 'Next' button") {
onSendScreen { nextButton.clickWithAssertion() }
}
step("Assert address text field is displayed") {
onSendAddressScreen { addressTextField.assertIsDisplayed() }
}
step("Click on 'Next' button") {
onSendAddressScreen { nextButton.clickWithAssertion() }
}
step("Assert 'Invalid amount' error title is not displayed") {
onSendConfirmScreen { minimumSendAmountErrorTitle.assertIsNotDisplayed() }
}
step("Assert 'Invalid amount' error icon is not displayed") {
onSendConfirmScreen { minimumSendAmountErrorIcon(minAmount).assertIsNotDisplayed() }
}
step("Assert 'Invalid amount' error message is not displayed") {
onSendConfirmScreen { minimumSendAmountErrorMessage(minAmount).assertIsNotDisplayed() }
}
}
}
@AllureId("990")
@DisplayName("XRP: Check warning")
@Test
fun xrpCheckWarningTest() {
val tokenName = "XRP Ledger"
val amount = "1.00"
val currencySymbol = "XRP"
val balance = "$0.00"
val userTokensScenarioName = "user_tokens_api"
val userTokensScenarioState = "XRP"
val rippleAccountInfoScenarioName = "ripple_account_info"
val rippleAccountInfoStartedState = "Started"
val rippleAccountInfoErrorState = "AccountNotFound"
val rippleAccountLinesScenarioName = "ripple_account_lines"
val rippleAccountLinesStartedState = "Started"
val rippleAccountLinesErrorState = "AccountNotFound"
setupHooks(
additionalAfterSection = {
resetWireMockScenarioState(userTokensScenarioName)
resetWireMockScenarioState(rippleAccountInfoScenarioName)
resetWireMockScenarioState(rippleAccountLinesScenarioName)
}
).run {
step("Set WireMock scenario: '$userTokensScenarioName' to state: '$userTokensScenarioState'") {
setWireMockScenarioState(scenarioName = userTokensScenarioName, state = userTokensScenarioState)
}
step("Set WireMock scenario: '$rippleAccountInfoScenarioName' to state: '$rippleAccountInfoErrorState'") {
setWireMockScenarioState(scenarioName = rippleAccountInfoScenarioName, state = rippleAccountInfoErrorState)
}
step("Set WireMock scenario: '$rippleAccountLinesScenarioName' to state: '$rippleAccountLinesErrorState'") {
setWireMockScenarioState(scenarioName = rippleAccountLinesScenarioName, state = rippleAccountLinesErrorState)
}
step("Open 'Main Screen'") {
openMainScreen()
}
step("Synchronize addresses") {
synchronizeAddresses(balance)
}
step("Click on token with name: '$tokenName'") {
onMainScreen { tokenWithTitleAndAddress(tokenName).performClick() }
}
step("Assert 'Top up wallet' notification title is displayed") {
onTokenDetailsScreen { topUpYourWalletNotificationTitle.assertIsDisplayed() }
}
step("Assert 'Top up wallet' notification message is displayed") {
onTokenDetailsScreen {
topUpYourWalletNotificationMessage(
networkName = tokenName,
amount = amount,
currencySymbol = currencySymbol,
).assertIsDisplayed()
}
}
step("Assert 'Top up wallet' notification icon is displayed") {
onTokenDetailsScreen { topUpYourWalletNotificationIcon.assertIsDisplayed() }
}
step("Set WireMock scenario: '$userTokensScenarioName' to state: '$userTokensScenarioState'") {
setWireMockScenarioState(scenarioName = userTokensScenarioName, state = userTokensScenarioState)
}
step("Set WireMock scenario: '$rippleAccountInfoScenarioName' to state: '$rippleAccountInfoStartedState'") {
setWireMockScenarioState(scenarioName = rippleAccountInfoScenarioName, state = rippleAccountInfoStartedState)
}
step("Set WireMock scenario: '$rippleAccountLinesScenarioName' to state: '$rippleAccountLinesStartedState'") {
setWireMockScenarioState(scenarioName = rippleAccountLinesScenarioName, state = rippleAccountLinesStartedState)
}
step("Pull to refresh") {
pullToRefresh()
}
step("Assert 'Top up wallet' notification title is not displayed") {
onTokenDetailsScreen { topUpYourWalletNotificationTitle.assertIsNotDisplayed() }
}
step("Assert 'Top up wallet' notification message not is displayed") {
onTokenDetailsScreen {
topUpYourWalletNotificationMessage(
networkName = tokenName,
amount = amount,
currencySymbol = currencySymbol,
).assertIsNotDisplayed()
}
}
step("Assert 'Top up wallet' notification icon not is displayed") {
onTokenDetailsScreen { topUpYourWalletNotificationIcon.assertIsNotDisplayed() }
}
}
}
}

View file

@ -2,13 +2,12 @@ package com.tangem.tests
import com.tangem.common.BaseTestCase
import com.tangem.common.constants.TestConstants.TOTAL_BALANCE
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT
import com.tangem.common.extensions.clickWithAssertion
import com.tangem.common.utils.resetWireMockScenarioState
import com.tangem.common.utils.setWireMockScenarioState
import com.tangem.screens.*
import com.tangem.scenarios.openMainScreen
import com.tangem.scenarios.synchronizeAddresses
import com.tangem.screens.*
import dagger.hilt.android.testing.HiltAndroidTest
import io.qameta.allure.kotlin.AllureId
import io.qameta.allure.kotlin.junit4.DisplayName
@ -74,7 +73,7 @@ class BuyTokenTest : BaseTestCase() {
val otherCurrenciesTitle = "Other currencies"
val australianDollar = "AUD"
val fiatAmount = "1"
val tokenAmount = "POL 488.24938338"
val tokenAmount = "~488.24938338 POL"
val scenarioName = "payment_methods"
step("Reset WireMock scenario '$scenarioName'") {
@ -102,18 +101,6 @@ class BuyTokenTest : BaseTestCase() {
step("Write fiat amount = '$fiatAmount'") {
onBuyTokenDetailsScreen { fiatAmountTextField.performTextInput(fiatAmount) }
}
step("Assert 'Provider loading block' is displayed") {
onBuyTokenDetailsScreen {
providerLoadingTitle.assertIsDisplayed()
providerLoadingText.assertIsDisplayed()
}
}
step("Assert 'Provider block' is displayed") {
onBuyTokenDetailsScreen {
providerTitle.assertIsDisplayed()
providerText.assertIsDisplayed()
}
}
step("Assert token amount = '$tokenAmount'") {
onBuyTokenDetailsScreen {
tokenAmountField.assertTextContains(tokenAmount)
@ -162,7 +149,7 @@ class BuyTokenTest : BaseTestCase() {
val balance = TOTAL_BALANCE
val euro = "EUR"
val fiatAmount = "1"
val tokenAmount = "POL 488.24938338"
val tokenAmount = "~488.24938338 POL"
val scenarioName = "payment_methods"
step("Reset WireMock scenario '$scenarioName'") {
@ -199,27 +186,45 @@ class BuyTokenTest : BaseTestCase() {
step("Assert fiat amount = '$fiatAmount'") {
onBuyTokenDetailsScreen { fiatAmountTextField.assertTextContains(euro + fiatAmount) }
}
step("Assert 'Provider loading block' is displayed") {
onBuyTokenDetailsScreen {
providerLoadingTitle.assertIsDisplayed()
providerLoadingText.assertIsDisplayed()
}
}
step("Assert 'Provider block' is displayed") {
onBuyTokenDetailsScreen {
providerTitle.assertIsDisplayed()
providerText.assertIsDisplayed()
}
}
step("Assert token amount = '$tokenAmount'") {
onBuyTokenDetailsScreen { tokenAmountField.assertTextContains(tokenAmount) }
}
step("Assert 'ToS' block is displayed") {
onBuyTokenDetailsScreen { toSBlock.assertIsDisplayed()}
step("Click on 'Continue' button") {
onBuyTokenDetailsScreen { continueButton.clickWithAssertion() }
}
step("Assert 'Recommended' title is displayed") {
onBuyTokenDetailsScreen { recommendedTitle.clickWithAssertion() }
}
step("Assert 'Best rate' icon is displayed") {
onBuyTokenDetailsScreen { bestRateIcon.assertIsDisplayed() }
}
step("Assert 'Best rate' title is displayed") {
onBuyTokenDetailsScreen { bestRateTitle.assertIsDisplayed() }
}
step("Assert offer amount is displayed") {
onBuyTokenDetailsScreen { offerTokenAmount.assertIsDisplayed() }
}
step("Assert 'Buy' button is displayed") {
onBuyTokenDetailsScreen { buyButton.assertIsDisplayed()}
}
step("Assert timing icon is displayed") {
onBuyTokenDetailsScreen { timingIcon.assertIsDisplayed() }
}
step("Assert 'Instant' processing time text is displayed") {
onBuyTokenDetailsScreen { instantProcessingSpeedText.assertIsDisplayed() }
}
step("Assert provider name is displayed") {
onBuyTokenDetailsScreen { providerName.assertIsDisplayed() }
}
step("Assert 'Pay with' is displayed") {
onBuyTokenDetailsScreen { payWith.assertIsDisplayed() }
}
step("Assert payment method icon is displayed") {
onBuyTokenDetailsScreen { paymentMethodIcon.assertIsDisplayed() }
}
step("Assert 'All offers' button is displayed") {
onBuyTokenDetailsScreen { allOffersButton.assertIsDisplayed() }
}
step("Assert 'Close' button in top bar is displayed") {
onBuyTokenDetailsScreen { topBarCloseButton.assertIsDisplayed() }
}
@ -314,13 +319,10 @@ class BuyTokenTest : BaseTestCase() {
setupHooks().run {
val tokenTitle = "Polygon"
val balance = TOTAL_BALANCE
val paymentMethod = "Card"
val paymentMethod = "Invoice Revolut Pay"
val fiatAmount = "1"
val providerNameMercuryo = "Mercuryo"
val providerNameSimplex = "Simplex"
val tokenAmount = "POL 488.24938338"
val bestRate = "Best rate"
val rate = "-0.00%"
val tokenAmount = "~488.24938338 POL"
val scenarioName = "payment_methods"
step("Reset WireMock scenario '$scenarioName'") {
@ -348,58 +350,53 @@ class BuyTokenTest : BaseTestCase() {
step("Write fiat amount = '$fiatAmount'") {
onBuyTokenDetailsScreen { fiatAmountTextField.performTextInput(fiatAmount) }
}
step("Assert token amount = '$tokenAmount'") {
onBuyTokenDetailsScreen { tokenAmountField.assertTextContains(tokenAmount) }
}
step("Click on 'Continue' button") {
onBuyTokenDetailsScreen { continueButton.clickWithAssertion() }
}
step("Assert 'Provider block' is displayed") {
onBuyTokenDetailsScreen {
providerTitle.assertIsDisplayed()
providerText.assertIsDisplayed()
}
onBuyTokenDetailsScreen { providerName.assertIsDisplayed() }
}
step("Open 'Select Provider' bottom sheet") {
onBuyTokenDetailsScreen { providerTitle.performClick() }
step("Click on 'All offers' button") {
onBuyTokenDetailsScreen { allOffersButton.clickWithAssertion() }
}
step("Assert available provider name is displayed") {
onSelectProviderBottomSheet {
flakySafely(WAIT_UNTIL_TIMEOUT) {
availableProviderItem.assertIsDisplayed()
}
}
step("Click on '$paymentMethod' payment method") {
onSelectPaymentMethodBottomSheet { paymentMethodWithName(paymentMethod).clickWithAssertion() }
}
step("Click on 'Expand payment methods' button") {
onSelectProviderBottomSheet { paymentMethodExpandButton.clickWithAssertion() }
}
step("Click on payment method: '$paymentMethod'") {
onSelectPaymentMethodBottomSheet { paymentMethodWithNameAndIcon(paymentMethod).clickWithAssertion() }
}
step("Assert 'Select Provider' bottom sheet title is displayed") {
step("Assert 'Provider' bottom sheet title is displayed") {
onSelectProviderBottomSheet { title.assertIsDisplayed() }
}
step("Assert 'Provider' bottom sheet subtitle is displayed") {
onSelectProviderBottomSheet { subtitle.assertIsDisplayed() }
}
step("Assert 'Best rate' icon is displayed") {
onSelectProviderBottomSheet { bestRateIcon.assertIsDisplayed() }
}
step("Assert 'Best rate' title is displayed") {
onSelectProviderBottomSheet { bestRateTitle.assertIsDisplayed() }
}
step("Assert offer token amount is displayed") {
onSelectProviderBottomSheet { offerTokenAmount.assertIsDisplayed() }
}
step("Assert 'Buy' button is displayed") {
onSelectProviderBottomSheet { buyButton.assertIsDisplayed() }
}
step("Assert timing icon is displayed") {
onSelectProviderBottomSheet { timingIcon.assertIsDisplayed() }
}
step("Assert 'Instant' processing time text is displayed") {
onSelectProviderBottomSheet { instantProcessingSpeedText.assertIsDisplayed() }
}
step("Assert 'Pay with' text is displayed") {
onSelectProviderBottomSheet { payWith.assertIsDisplayed() }
}
step("Assert payment method icon is displayed") {
onSelectProviderBottomSheet { paymentMethodIcon.assertIsDisplayed() }
}
step("Assert payment method title is displayed") {
onSelectProviderBottomSheet { paymentMethodTitle.assertIsDisplayed() }
}
step("Assert payment method name is displayed") {
onSelectProviderBottomSheet { paymentMethodName.assertIsDisplayed() }
}
step("Assert provider with name: '$providerNameMercuryo' and rate: '$bestRate' is displayed") {
onSelectProviderBottomSheet {
availableProviderWithName(providerNameMercuryo, tokenAmount, bestRate).assertIsDisplayed()
}
}
step("Assert provider with name: '$providerNameSimplex' and rate: '$rate' is displayed") {
onSelectProviderBottomSheet {
availableProviderWithName(providerNameSimplex, tokenAmount, rate).assertIsDisplayed()
}
}
step("Assert 'More providers' icon is displayed") {
onSelectProviderBottomSheet { moreProvidersIcon.assertIsDisplayed() }
}
step("Assert 'More providers' text is displayed") {
onSelectProviderBottomSheet { moreProvidersText.assertIsDisplayed() }
}
step("Assert 'Best rate' label is displayed") {
onSelectProviderBottomSheet { bestRateLabel.assertIsDisplayed() }
step("Assert provider name: '$providerNameMercuryo'") {
onSelectProviderBottomSheet { providerName.assertTextContains(providerNameMercuryo) }
}
}
}
@ -416,6 +413,7 @@ class BuyTokenTest : BaseTestCase() {
val invoiceRevolutPay = "Invoice Revolut Pay"
val sepa = "Sepa"
val fiatAmount = "1"
val tokenAmount = "~488.24938338 POL"
val scenarioName = "payment_methods"
step("Reset WireMock scenario '$scenarioName'") {
@ -443,40 +441,39 @@ class BuyTokenTest : BaseTestCase() {
step("Write fiat amount = '$fiatAmount'") {
onBuyTokenDetailsScreen { fiatAmountTextField.performTextInput(fiatAmount) }
}
step("Assert token amount = '$tokenAmount'") {
onBuyTokenDetailsScreen { tokenAmountField.assertTextContains(tokenAmount) }
}
step("Click on 'Continue' button") {
onBuyTokenDetailsScreen { continueButton.clickWithAssertion() }
}
step("Assert 'Provider block' is displayed") {
onBuyTokenDetailsScreen {
providerTitle.assertIsDisplayed()
providerText.assertIsDisplayed()
}
onBuyTokenDetailsScreen { providerName.assertIsDisplayed() }
}
step("Open 'Select Provider' bottom sheet") {
onBuyTokenDetailsScreen { providerTitle.performClick() }
}
step("Click on 'Expand payment methods' button") {
onSelectProviderBottomSheet { paymentMethodExpandButton.clickWithAssertion() }
step("Click on 'All offers' button") {
onBuyTokenDetailsScreen { allOffersButton.clickWithAssertion() }
}
step("Assert 'Select Payment Method' bottom sheet title is displayed") {
onSelectPaymentMethodBottomSheet { title.assertIsDisplayed() }
}
step("Assert 'Select Payment Method' bottom sheet subtitle is displayed") {
onSelectPaymentMethodBottomSheet { subtitle.assertIsDisplayed() }
}
step("Assert 'Select Payment Method' bottom sheet close button is displayed") {
onSelectPaymentMethodBottomSheet { closeButton.assertIsDisplayed() }
}
step("Assert payment method: '$card' is displayed") {
onSelectPaymentMethodBottomSheet { paymentMethodWithNameAndIcon(card).assertIsDisplayed() }
onSelectPaymentMethodBottomSheet { paymentMethodWithName(card).assertIsDisplayed() }
}
step("Assert payment method: '$googlePay' is displayed") {
onSelectPaymentMethodBottomSheet { paymentMethodWithNameAndIcon(googlePay).assertIsDisplayed() }
onSelectPaymentMethodBottomSheet { paymentMethodWithName(googlePay).assertIsDisplayed() }
}
step("Assert payment method: '$invoiceRevolutPay' is displayed") {
onSelectPaymentMethodBottomSheet { paymentMethodWithNameAndIcon(invoiceRevolutPay).assertIsDisplayed() }
onSelectPaymentMethodBottomSheet { paymentMethodWithName(invoiceRevolutPay).assertIsDisplayed() }
}
step("Assert payment method: '$sepa' is displayed") {
onSelectPaymentMethodBottomSheet { paymentMethodWithNameAndIcon(sepa).assertIsDisplayed() }
}
step("Press 'Back' button") {
onSelectPaymentMethodBottomSheet { device.uiDevice.pressBack() }
}
step("Assert 'Select Provider' bottom sheet title is displayed") {
onSelectProviderBottomSheet { title.assertIsDisplayed() }
onSelectPaymentMethodBottomSheet { paymentMethodWithName(sepa).assertIsDisplayed() }
}
}
}
}

View file

@ -87,12 +87,13 @@ class FeedbackTest : BaseTestCase() {
onSendScreen { nextButton.clickWithAssertion() }
}
step("Enter address") {
onSendAddressScreen { addressTextField.performTextReplacement(recipientAddress) }
onSendAddressScreen { addressTextField.performTextInput(recipientAddress) }
}
step("Click 'Next' button") {
onSendAddressScreen { nextButton.clickWithAssertion() }
}
step("Click 'Send' button") {
waitForIdle()
onSendConfirmScreen {
sendButton.assertIsEnabled()
sendButton.performClick()
@ -138,6 +139,7 @@ class FeedbackTest : BaseTestCase() {
}
}
step("Check 'Scan warning' dialog") {
waitForIdle()
checkScanWarningDialog()
}
step("Click on 'Request support' button") {

View file

@ -0,0 +1,64 @@
package com.tangem.tests
import com.tangem.common.BaseTestCase
import com.tangem.scenarios.*
import com.tangem.tap.domain.sdk.mocks.content.ShibaNoBackupMockContent
import com.tangem.tap.domain.sdk.mocks.content.ShibaNoBackupNoWalletsMockContent
import com.tangem.tap.domain.sdk.mocks.content.Wallet2NoBackupMockContent
import com.tangem.tap.domain.sdk.mocks.content.Wallet2NoBackupNoWalletsMockContent
import dagger.hilt.android.testing.HiltAndroidTest
import io.qameta.allure.kotlin.AllureId
import io.qameta.allure.kotlin.junit4.DisplayName
import org.junit.Test
@HiltAndroidTest
class OnboardingTest : BaseTestCase() {
@AllureId("248")
@DisplayName("Onboarding: 'Shiba' no wallets backup screen test")
@Test
fun shibaNoWalletsBackupScreenTest() {
setupHooks().run {
scanCard(mockContent = ShibaNoBackupNoWalletsMockContent)
checkCreateWalletScreenForWalletNoWallets()
openAndCheckBackupScreenForWalletNoWallets()
}
}
@AllureId("3989")
@DisplayName("Onboarding: 'Shiba' with wallets backup screen test")
@Test
fun shibaBackupScreenTest() {
setupHooks().run {
scanCard(
mockContent = ShibaNoBackupMockContent,
alreadyActivatedDialogIsShown = true
)
checkBackupScreen()
}
}
@AllureId("246")
@DisplayName("Onboarding: 'Wallet 2' no wallets backup screen test")
@Test
fun wallet2NoWalletsBackupScreenTest() {
setupHooks().run {
scanCard(mockContent = Wallet2NoBackupNoWalletsMockContent)
checkCreateWalletScreenForWallet2NoWallets()
openAndCheckBackupScreenForWallet2NoWallets()
}
}
@AllureId("3990")
@DisplayName("Onboarding: 'Wallet 2' with wallets backup screen test")
@Test
fun wallet2BackupScreenTest() {
setupHooks().run {
scanCard(
mockContent = Wallet2NoBackupMockContent,
alreadyActivatedDialogIsShown = true
)
checkBackupScreen()
}
}
}

View file

@ -0,0 +1,196 @@
package com.tangem.tests
import com.tangem.common.BaseTestCase
import com.tangem.domain.models.scan.ProductType
import com.tangem.scenarios.checkMultiCurrencyMainScreen
import com.tangem.scenarios.checkSingleCurrencyMainScreen
import com.tangem.scenarios.openMainScreen
import com.tangem.tap.domain.sdk.mocks.MockContent
import com.tangem.tap.domain.sdk.mocks.content.*
import dagger.hilt.android.testing.HiltAndroidTest
import io.qameta.allure.kotlin.AllureId
import io.qameta.allure.kotlin.junit4.DisplayName
import org.junit.Test
@HiltAndroidTest
class ScanCardTest : BaseTestCase() {
@AllureId("868")
@DisplayName("Scan: Scanning single-currency cards")
@Test
fun singleTokenNoteCardScanTest() {
val cardBlockchain = "DOGE"
val cardType: ProductType = ProductType.Note
setupHooks().run {
step("Open 'Main Screen' on '${cardType.name}' card") {
openMainScreen(cardType)
}
step("Check 'Main' screen for '${cardType.name}' $cardBlockchain card") {
checkSingleCurrencyMainScreen(
cardBlockchain = cardBlockchain,
cardTitle = cardType.name,
withTransactions = true
)
}
}
}
@AllureId("869")
@DisplayName("Scan: 'Twin' card")
@Test
fun twinsCardScanTest() {
val cardBlockchain = "BTC"
val cardType: MockContent = TwinsMockContent
val cardName = "Twin"
setupHooks().run {
step("Open 'Main Screen' on '$cardName' card") {
openMainScreen(mockContent = cardType, isTwinsCard = true)
}
step("Check 'Main' screen for '$cardName' $cardBlockchain card") {
checkSingleCurrencyMainScreen(cardBlockchain = cardBlockchain, cardTitle = cardName)
}
}
}
@AllureId("872")
@DisplayName("Scan: Card with Secp256k1 curve")
@Test
fun secpk1CurveCardScanTest() {
val devicesCount = "1 device"
val cardType: MockContent = Secpk1CurveMockContent
val cardName = "Wallet"
val card = "card with Secp256k1 curve"
setupHooks().run {
step("Open 'Main Screen' on $card") {
openMainScreen(mockContent = cardType, alreadyActivatedDialogIsShown = true)
}
step("Check 'Main' screen for $card curve with devices count = '$devicesCount'") {
checkMultiCurrencyMainScreen(
devicesCount = devicesCount,
cardTitle = cardName,
withWalletImage = false
)
}
}
}
@AllureId("870")
@DisplayName("Scan: Card with Ed25519 curve")
@Test
fun edCurveCardScanTest() {
val cardBlockchain = "XLM"
val cardType: MockContent = EdCurveMockContent
val cardName = "Tangem card"
val card = "card with Ed25519 curve"
setupHooks().run {
step("Open 'Main Screen' on $card") {
openMainScreen(mockContent = cardType)
}
step("Check 'Main' screen for $card with blockchain: '$cardBlockchain'") {
checkSingleCurrencyMainScreen(
cardBlockchain = cardBlockchain,
cardTitle = cardName,
withWalletImage = false
)
}
}
}
@AllureId("866")
@DisplayName("Scan: 'Shiba' card")
@Test
fun shibaCardScanTest() {
val devicesCount = "2 devices"
val cardType: MockContent = ShibaMockContent
val cardName = "Wallet"
val card = "Shiba"
setupHooks().run {
step("Open 'Main Screen' on '$card' card") {
openMainScreen(mockContent = cardType, alreadyActivatedDialogIsShown = true)
}
step("Check 'Main' screen for '$card' card with devices count = '$devicesCount'") {
checkMultiCurrencyMainScreen(devicesCount, cardName)
}
}
}
@AllureId("864")
@DisplayName("Scan: 'Ring'")
@Test
fun ringScanTest() {
val devicesCount = "3 devices"
val cardType: ProductType = ProductType.Ring
val cardName = "Wallet"
val ring = "Ring"
setupHooks().run {
step("Open 'Main Screen' on '$ring'") {
openMainScreen(productType = cardType, alreadyActivatedDialogIsShown = true)
}
step("Check 'Main' screen for '$ring' with devices count = '$devicesCount'") {
checkMultiCurrencyMainScreen(devicesCount, cardName)
}
}
}
@AllureId("867")
@DisplayName("Scan: 'Wallet' card")
@Test
fun walletCardScanTest() {
val devicesCount = "1 device"
val cardType: ProductType = ProductType.Wallet
val cardName = "Wallet"
setupHooks().run {
step("Open 'Main Screen' on '$cardName' card") {
openMainScreen(productType = cardType)
}
step("Check 'Main' screen for '$cardName' card with devices count = '$devicesCount'") {
checkMultiCurrencyMainScreen(devicesCount, cardName)
}
}
}
@AllureId("865")
@DisplayName("Scan: 'Wallet 2' card")
@Test
fun wallet2ScanTest() {
val devicesCount = "2 devices"
val cardType: MockContent = Wallet2MockContent
val cardName = "Wallet"
val card = "Wallet 2"
setupHooks().run {
step("Open 'Main Screen' on '$card' card") {
openMainScreen(mockContent = cardType, alreadyActivatedDialogIsShown = true)
}
step("Check 'Main' screen for '$card' card with devices count = '$devicesCount'") {
checkMultiCurrencyMainScreen(devicesCount, cardName)
}
}
}
@AllureId("871")
@DisplayName("Scan: Card with 4.12 firmware")
@Test
fun firmware412CardScanTest() {
val devicesCount = "1 device"
val cardType: MockContent = Firmware412MockContent
val cardName = "Tangem card"
val card = "card with 4.12 firmware"
setupHooks().run {
step("Open 'Main Screen' on '$card'") {
openMainScreen(mockContent = cardType)
}
step("Check 'Main' screen for '$card' with devices count = '$devicesCount'") {
checkMultiCurrencyMainScreen(devicesCount, cardName)
}
}
}
}

View file

@ -1,7 +1,9 @@
package com.tangem.tests
import com.tangem.common.BaseTestCase
import com.tangem.common.extensions.SwipeDirection
import com.tangem.common.extensions.clickWithAssertion
import com.tangem.common.extensions.swipeVertical
import com.tangem.common.utils.resetWireMockScenarioState
import com.tangem.common.utils.setWireMockScenarioState
import com.tangem.scenarios.openMainScreen
@ -42,6 +44,9 @@ class SendTest : BaseTestCase() {
step("Synchronize addresses") {
synchronizeAddresses(balance)
}
step("Swipe up") {
swipeVertical(SwipeDirection.UP)
}
step("Click on token with name: $currencyName") {
onMainScreen { tokenWithTitleAndAddress(currencyName).clickWithAssertion() }
}

View file

@ -1,31 +0,0 @@
package com.tangem.tests
import com.tangem.common.BaseTestCase
import com.tangem.domain.models.scan.ProductType
import com.tangem.scenarios.openMainScreen
import com.tangem.steps.checkSingleCurrencyMainScreen
import dagger.hilt.android.testing.HiltAndroidTest
import io.qameta.allure.kotlin.AllureId
import io.qameta.allure.kotlin.junit4.DisplayName
import org.junit.Test
@HiltAndroidTest
class SingleCurrencyCardsScan : BaseTestCase() {
@AllureId("868")
@DisplayName("Scan: Scanning single-currency cards")
@Test
fun singleTokenNoteScanTest() {
val cardBlockchain = "DOGE"
val cardType: ProductType = ProductType.Note
setupHooks().run {
step("Open 'Main Screen' on ${cardType.name} card") {
openMainScreen(cardType)
}
step("Check 'Main' screen for ${cardType.name} $cardBlockchain card") {
checkSingleCurrencyMainScreen(cardBlockchain = cardBlockchain, cardTitle = cardType.name)
}
}
}
}

View file

@ -2,7 +2,9 @@ package com.tangem.tests
import com.tangem.common.BaseTestCase
import com.tangem.common.constants.TestConstants.TOTAL_BALANCE
import com.tangem.common.extensions.SwipeDirection
import com.tangem.common.extensions.clickWithAssertion
import com.tangem.common.extensions.swipeVertical
import com.tangem.common.utils.resetWireMockScenarioState
import com.tangem.common.utils.setWireMockScenarioState
import com.tangem.screens.*
@ -44,6 +46,9 @@ class StakingTest : BaseTestCase() {
step("Assert 'Organize tokens' button is displayed") {
onMainScreen { organizeTokensButton().assertIsDisplayed() }
}
step("Swipe up") {
swipeVertical(SwipeDirection.UP)
}
step("Click on token with name: '$tokenTitle'") {
onMainScreen { tokenWithTitleAndAddress(tokenTitle).clickWithAssertion() }
}
@ -100,6 +105,9 @@ class StakingTest : BaseTestCase() {
step("Assert 'Organize tokens' button is displayed") {
onMainScreen { organizeTokensButton().assertIsDisplayed() }
}
step("Swipe up") {
swipeVertical(SwipeDirection.UP)
}
step("Click on token with name: '$tokenTitle'") {
onMainScreen { tokenWithTitleAndAddress(tokenTitle).clickWithAssertion() }
}
@ -252,6 +260,9 @@ class StakingTest : BaseTestCase() {
step("Assert 'Organize tokens' button is displayed") {
onMainScreen { organizeTokensButton().assertIsDisplayed() }
}
step("Swipe up") {
swipeVertical(SwipeDirection.UP)
}
step("Click on token with name: '$tokenTitle'") {
onMainScreen { tokenWithTitleAndAddress(tokenTitle).clickWithAssertion() }
}

View file

@ -6,7 +6,9 @@ import com.tangem.common.annotations.ApiEnv
import com.tangem.common.annotations.ApiEnvConfig
import com.tangem.common.constants.TestConstants.TOTAL_BALANCE
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT
import com.tangem.common.extensions.clickWithAssertion
import com.tangem.common.constants.TestConstants.WAIT_UNTIL_TIMEOUT_LONG
import com.tangem.common.extensions.*
import com.tangem.common.utils.*
import com.tangem.datasource.api.common.config.ApiConfig
import com.tangem.datasource.api.common.config.ApiEnvironment
import com.tangem.screens.*
@ -28,10 +30,12 @@ class SwapTokenTest : BaseTestCase() {
@Test
fun networkFeeTest() {
val inputAmount = "100"
setupHooks().run {
val tokenTitle = "Polygon"
val balance = TOTAL_BALANCE
val tokenTitle = "Polygon"
val balance = TOTAL_BALANCE
setupHooks().run {
resetWireMockScenarios()
step("Open 'Main Screen'") {
openMainScreen()
}
@ -71,7 +75,7 @@ class SwapTokenTest : BaseTestCase() {
}
}
step("Input swap amount = '$inputAmount'") {
composeTestRule.waitForIdle()
waitForIdle()
onSwapTokenScreen {
textInput.clickWithAssertion()
textInput.performTextReplacement(inputAmount)
@ -89,7 +93,7 @@ class SwapTokenTest : BaseTestCase() {
}
step("Assert 'Network fee' block is displayed") {
onSwapTokenScreen {
flakySafely(WAIT_UNTIL_TIMEOUT) {
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
networkFeeBlock.assertIsDisplayed()
}
}
@ -104,7 +108,12 @@ class SwapTokenTest : BaseTestCase() {
@DisplayName("Swap: network error test")
@Test
fun networkErrorSwapTest() {
setupHooks().run {
setupHooks(
additionalAfterSection = {
enableWiFi()
enableMobileData()
}
).run {
val tokenTitle = "Polygon"
val balance = TOTAL_BALANCE
@ -120,6 +129,10 @@ class SwapTokenTest : BaseTestCase() {
step("Click on token with name: '$tokenTitle'") {
onTokenDetailsScreen { title.assertIsDisplayed() }
}
step("Turn off Wi-Fi and Mobile Data") {
disableWiFi()
disableMobileData()
}
step("Click on 'Swap' button") {
onTokenDetailsScreen { swapButton.performClick() }
}
@ -189,7 +202,7 @@ class SwapTokenTest : BaseTestCase() {
}
}
step("Input swap amount = '$inputAmount'") {
composeTestRule.waitForIdle()
waitForIdle()
onSwapTokenScreen {
textInput.clickWithAssertion()
textInput.performTextReplacement(inputAmount)
@ -200,7 +213,7 @@ class SwapTokenTest : BaseTestCase() {
}
step("Click on 'Network fee' block") {
onSwapTokenScreen {
flakySafely(WAIT_UNTIL_TIMEOUT) {
flakySafely(WAIT_UNTIL_TIMEOUT_LONG) {
networkFeeBlock.clickWithAssertion()
}
}

View file

@ -2,9 +2,9 @@ package com.tangem.tests
import androidx.test.InstrumentationRegistry.getTargetContext
import com.tangem.common.BaseTestCase
import com.tangem.common.extensions.SwipeDirection
import com.tangem.common.extensions.clickWithAssertion
import com.tangem.common.extensions.swipeVertical
import com.tangem.common.extensions.launchApp
import com.tangem.common.extensions.stopApp
import com.tangem.screens.onDisclaimerScreen
import com.tangem.screens.onStoriesScreen
import dagger.hilt.android.testing.HiltAndroidTest
@ -49,8 +49,9 @@ class TermsOfServiceTest : BaseTestCase() {
@Test
fun acceptTermsOfServiceAfterAppRestart() {
val packageName = getTargetContext().packageName
val tosUrl = "https://tangem.com/tangem_tos.html"
setupHooks().run {
val tosUrl = "https://tangem.com/tangem_tos.html"
step("Assert title of 'Disclaimer screen' is displayed") {
onDisclaimerScreen { title.assertIsDisplayed() }
}
@ -65,14 +66,11 @@ class TermsOfServiceTest : BaseTestCase() {
step("'Accept' button is displayed") {
onDisclaimerScreen { acceptButton.assertIsDisplayed() }
}
step("Open recent apps") {
device.uiDevice.pressRecentApps()
}
step("Stop app by swipe") {
swipeVertical(SwipeDirection.UP, startHeightRatio = 0.5f)
step("Stop app") {
stopApp(packageName)
}
step("Launch app") {
device.apps.launch(packageName)
launchApp(packageName)
}
step("Assert title of 'Disclaimer screen' is displayed") {
onDisclaimerScreen { title.assertIsDisplayed() }
@ -86,16 +84,22 @@ class TermsOfServiceTest : BaseTestCase() {
}
}
step("Click on 'Accept' button") {
onDisclaimerScreen { acceptButton.clickWithAssertion() }
onDisclaimerScreen {
waitForIdle()
acceptButton.clickWithAssertion()
}
}
step("Open recent apps") {
device.uiDevice.pressRecentApps()
step("Assert 'Stories' screen is opened") {
onStoriesScreen {
scanButton.assertIsDisplayed()
orderButton.assertIsDisplayed()
}
}
step("Stop app by swipe") {
swipeVertical(SwipeDirection.UP, startHeightRatio = 0.5f)
step("Stop app") {
stopApp(packageName)
}
step("Launch app") {
device.apps.launch(packageName)
launchApp(packageName)
}
step("Assert 'Stories' screen is opened") {
onStoriesScreen {

View file

@ -74,7 +74,7 @@ class TotalBalanceUpdateTest : BaseTestCase() {
}
step("Open 'Markets screen'") {
swipeMarketsBlock(SwipeDirection.UP)
composeTestRule.waitForIdle()
waitForIdle()
}
step("Click on $tokenTitle token") {
onMarketsScreen { tokenWithTitle(tokenTitle).clickWithAssertion() }
@ -95,7 +95,7 @@ class TotalBalanceUpdateTest : BaseTestCase() {
onDialog { continueButton.assertIsNotDisplayed() }
}
step("Go back to 'Markets: tokens list'") {
composeTestRule.waitForIdle()
waitForIdle()
onMarketsScreen { topBarBackButton.clickWithAssertion() }
}
step("Close 'Markets screen'") {
@ -151,7 +151,7 @@ class TotalBalanceUpdateTest : BaseTestCase() {
onMainScreen { totalBalanceText.assertTextContains(TOTAL_BALANCE) }
}
step("Long click on token with name: '$tokenTitle'") {
composeTestRule.waitForIdle()
waitForIdle()
onMainScreen {
tokenWithTitleAndAddress(tokenTitle).performTouchInput {
longClick(

View file

@ -33,6 +33,7 @@
<application
android:name="com.tangem.tap.TangemHiltApplication"
android:theme="@style/AppTheme"
android:allowBackup="false"
android:dataExtractionRules="@xml/data_extraction_rules"
android:enableOnBackInvokedCallback="true"

View file

@ -28,7 +28,7 @@ import com.tangem.domain.apptheme.repository.AppThemeModeRepository
import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
import com.tangem.domain.card.ScanCardProcessor
import com.tangem.domain.card.repository.CardRepository
import com.tangem.domain.core.wallets.UserWalletsListRepository
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
import com.tangem.domain.onboarding.SaveTwinsOnboardingShownUseCase

View file

@ -13,9 +13,9 @@ object ForegroundActivityObserver {
val foregroundActivity: AppCompatActivity?
get() = activities.entries
.firstOrNull {
Timber.i("foregroundActivity: ${it.key} | ${it.value.isDestroyed}")
it.value.isDestroyed == false
.firstOrNull { entry ->
Timber.i("foregroundActivity: ${entry.key} | ${entry.value.isDestroyed}")
entry.value.isDestroyed == false
}
?.value
@ -28,9 +28,9 @@ object ForegroundActivityObserver {
override fun onActivityResumed(activity: Activity) {
Timber.i("onActivityResumed ${activity::class}")
(activity as? AppCompatActivity)?.let {
if (activity is AppCompatActivity) {
Timber.i("onActivityResumed store activity")
activities[activity::class] = it
activities[activity::class] = activity
}
}

View file

@ -4,10 +4,10 @@ import android.content.Context
import androidx.hilt.work.HiltWorker
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.settings.repositories.SettingsRepository
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.wallets.legacy.asLockable
import com.tangem.domain.core.wallets.UserWalletsListRepository
import com.tangem.features.hotwallet.HotWalletFeatureToggles
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject

View file

@ -7,10 +7,10 @@ import androidx.lifecycle.LifecycleOwner
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import com.tangem.common.routing.AppRoute
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.settings.repositories.SettingsRepository
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.wallets.legacy.asLockable
import com.tangem.domain.core.wallets.UserWalletsListRepository
import com.tangem.domain.wallets.usecase.ClearAllHotWalletContextualUnlockUseCase
import com.tangem.features.hotwallet.HotWalletFeatureToggles
import com.tangem.tap.LockTimerWorker.Companion.TAG
@ -22,6 +22,7 @@ import kotlinx.coroutines.launch
import timber.log.Timber
import java.util.concurrent.TimeUnit
import kotlin.time.Duration
import kotlin.time.Duration.Companion.minutes
@Suppress("LongParameterList")
internal class LockUserWalletsTimer(

View file

@ -38,7 +38,7 @@ import com.tangem.domain.apptheme.model.AppThemeMode
import com.tangem.domain.card.ScanCardUseCase
import com.tangem.domain.card.repository.CardRepository
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.core.wallets.UserWalletsListRepository
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.settings.SetGooglePayAvailabilityUseCase
import com.tangem.domain.settings.SetGoogleServicesAvailabilityUseCase
import com.tangem.domain.settings.ShouldInitiallyAskPermissionUseCase
@ -264,7 +264,7 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
tangemSdkManager = injectedTangemSdkManager
backupServiceHolder.createAndSetService(cardSdkConfigRepository.sdk, this)
backupService = backupServiceHolder.backupService.get()!! // will be deleted eventually
backupService = requireNotNull(backupServiceHolder.backupService.get()) // will be deleted eventually
lockUserWalletsTimer = LockUserWalletsTimer(
context = this,
@ -371,17 +371,15 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
}
}
override fun onNewIntent(intent: Intent?) {
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
val fromPush = intent?.extras?.containsKey(OPENED_FROM_GCM_PUSH) ?: false
if (fromPush) {
val isFromPush = intent.extras?.containsKey(OPENED_FROM_GCM_PUSH) == true
if (isFromPush) {
analyticsEventsHandler.send(Push.PushNotificationOpened)
}
if (intent != null) {
handleDeepLink(intent = intent, isFromOnNewIntent = true)
}
handleDeepLink(intent = intent, isFromOnNewIntent = true)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@ -406,8 +404,8 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
}
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
val result = WindowObscurationObserver.dispatchTouchEvent(event, analyticsEventsHandler)
return if (result) super.dispatchTouchEvent(event) else false
val isHandled = WindowObscurationObserver.dispatchTouchEvent(event, analyticsEventsHandler)
return if (isHandled) super.dispatchTouchEvent(event) else false
}
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
@ -451,9 +449,9 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
getPolkadotCheckHasImmortalUseCase()
.flowWithLifecycle(lifecycle, minActiveState = Lifecycle.State.CREATED)
.distinctUntilChanged()
.collect {
.collect { (_, hasImmortalTransaction) ->
analyticsEventsHandler.send(
WalletScreenAnalyticsEvent.Token.PolkadotImmortalTransactions(it.second),
WalletScreenAnalyticsEvent.Token.PolkadotImmortalTransactions(hasImmortalTransaction),
)
}
}

View file

@ -88,7 +88,7 @@ lateinit var store: Store<AppState>
val foregroundActivityObserver = ForegroundActivityObserver
internal lateinit var derivationsFinder: DerivationsFinder
abstract class TangemApplication : Application(), ImageLoaderFactory, Configuration.Provider {
open class TangemApplication : Application(), ImageLoaderFactory, Configuration.Provider {
// region DI
private val entryPoint: ApplicationEntryPoint
@ -290,7 +290,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory, Configurat
/**
* Initialize components that need to be initialized before [super.onCreate] is called
*/
private fun preInit() {
fun preInit() {
tangemAppLoggerInitializer.initialize()
registerActivityLifecycleCallbacks(foregroundActivityObserver.callbacks)
}

View file

@ -7,7 +7,7 @@ package com.tangem.tap.common
object TestActions {
// It used only for the test actions in debug or debug_beta builds
var testAmountInjectionForWalletManagerEnabled = false
var isTestAmountInjectionForWalletManagerEnabled = false
}
typealias TestAction = Pair<String, () -> Unit>

View file

@ -58,7 +58,7 @@ private class BlockchainSdkErrorConverter(
if (value.customMessage.contains(DemoTransactionSender.ID)) return emptyMap()
if (value is BlockchainSdkError.WrappedTangemError) {
return (value.tangemError as? TangemSdkError)?.let { cardSdkErrorConverter.convert(it) } ?: emptyMap()
return (value.tangemError as? TangemSdkError)?.let { cardSdkErrorConverter.convert(it) }.orEmpty()
}
return mapOf(

View file

@ -7,7 +7,7 @@ import com.tangem.core.analytics.models.AnalyticsEvent
*/
sealed class Chat(
event: String,
params: Map<String, String> = mapOf(),
params: Map<String, String> = emptyMap(),
) : AnalyticsEvent("Chat", event, params) {
class ScreenOpened : Chat("Chat Screen Opened")

View file

@ -8,7 +8,7 @@ import com.tangem.core.analytics.models.AnalyticsEvent
sealed class Onboarding(
category: String,
event: String,
params: Map<String, String> = mapOf(),
params: Map<String, String> = emptyMap(),
) : AnalyticsEvent(category, event, params) {
class Started : Onboarding("Onboarding", "Onboarding Started")
@ -16,7 +16,7 @@ sealed class Onboarding(
sealed class CreateWallet(
event: String,
params: Map<String, String> = mapOf(),
params: Map<String, String> = emptyMap(),
) : Onboarding("Onboarding / Create Wallet", event, params) {
class ScreenOpened : CreateWallet("Create Wallet Screen Opened")
@ -36,7 +36,7 @@ sealed class Onboarding(
sealed class Backup(
event: String,
params: Map<String, String> = mapOf(),
params: Map<String, String> = emptyMap(),
) : Onboarding("Onboarding / Backup", event, params) {
class ScreenOpened : Backup("Backup Screen Opened")
@ -64,7 +64,7 @@ sealed class Onboarding(
sealed class Topup(
event: String,
params: Map<String, String> = mapOf(),
params: Map<String, String> = emptyMap(),
) : Onboarding("Onboarding / Top Up", event, params) {
class ScreenOpened : Topup("Activation Screen Opened")
@ -79,7 +79,7 @@ sealed class Onboarding(
sealed class Twins(
event: String,
params: Map<String, String> = mapOf(),
params: Map<String, String> = emptyMap(),
) : Onboarding("Onboarding / Twins", event, params) {
class ScreenOpened : Twins("Twinning Screen Opened")

View file

@ -8,7 +8,7 @@ import com.tangem.core.analytics.models.AnalyticsEvent
sealed class Settings(
category: String = "Settings",
event: String,
params: Map<String, String> = mapOf(),
params: Map<String, String> = emptyMap(),
) : AnalyticsEvent(category, event, params) {
class ScreenOpened : Settings(event = "Settings Screen Opened")
@ -17,7 +17,7 @@ sealed class Settings(
sealed class CardSettings(
event: String,
params: Map<String, String> = mapOf(),
params: Map<String, String> = emptyMap(),
) : Settings("Settings / Card Settings", event, params) {
class ButtonFactoryReset : CardSettings("Button - Factory Reset")
@ -54,7 +54,7 @@ sealed class Settings(
sealed class AppSettings(
event: String,
params: Map<String, String> = mapOf(),
params: Map<String, String> = emptyMap(),
) : Settings(category = "Settings / App Settings", event = event, params = params) {
class SaveWalletSwitcherChanged(state: AnalyticsParam.OnOffState) : AppSettings(

View file

@ -7,7 +7,7 @@ import com.tangem.core.analytics.models.AnalyticsEvent
*/
sealed class SignIn(
event: String,
params: Map<String, String> = mapOf(),
params: Map<String, String> = emptyMap(),
) : AnalyticsEvent("Sign In", event, params) {
class ScreenOpened : SignIn(event = "Sign In Screen Opened")

View file

@ -9,12 +9,12 @@ import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN_PARAM
sealed class Token(
category: String,
event: String,
params: Map<String, String> = mapOf(),
params: Map<String, String> = emptyMap(),
) : AnalyticsEvent(category, event, params) {
sealed class Receive(
event: String,
params: Map<String, String> = mapOf(),
params: Map<String, String> = emptyMap(),
) : Token("Token / Receive", event, params) {
class ScreenOpened(
@ -29,7 +29,7 @@ sealed class Token(
sealed class Topup(
event: String,
params: Map<String, String> = mapOf(),
params: Map<String, String> = emptyMap(),
) : Token("Token / Topup", event, params) {
class ScreenOpened : Topup("Top Up Screen Opened")
@ -38,7 +38,7 @@ sealed class Token(
sealed class Withdraw(
event: String,
params: Map<String, String> = mapOf(),
params: Map<String, String> = emptyMap(),
) : Token("Token / Withdraw", event, params) {
class ScreenOpened : Withdraw("Withdraw Screen Opened")

View file

@ -19,6 +19,7 @@ internal class DefaultClipboardManager(private val clipboardManager: AndroidClip
clipboardManager.setPrimaryClip(clip)
}
@Suppress("UseIsNullOrEmpty")
override fun getText(default: String?): String? {
val clip = clipboardManager.primaryClip

View file

@ -90,6 +90,6 @@ fun Store<AppState>.dispatchNavigationAction(action: AppRouter.() -> Unit) {
inline fun <reified T> Store<AppState>.inject(getDependency: DaggerGraphState.() -> T?): T {
return requireNotNull(state.daggerGraphState.getDependency()) {
"${T::class.simpleName} isn't initialized "
"${T::class.simpleName.orEmpty()} isn't initialized "
}
}

View file

@ -22,9 +22,9 @@ import timber.log.Timber
)
@Suppress("MagicNumber")
suspend fun WalletManager.safeUpdate(isDemoCard: Boolean): Result<Wallet> = try {
if (isDemoCard || TestActions.testAmountInjectionForWalletManagerEnabled) {
if (isDemoCard || TestActions.isTestAmountInjectionForWalletManagerEnabled) {
delay(500)
TestActions.testAmountInjectionForWalletManagerEnabled = false
TestActions.isTestAmountInjectionForWalletManagerEnabled = false
Result.Success(wallet)
} else {
update()
@ -35,7 +35,7 @@ suspend fun WalletManager.safeUpdate(isDemoCard: Boolean): Result<Wallet> = try
val networkConnectionManager = store.inject(DaggerGraphState::networkConnectionManager)
if (!networkConnectionManager.isOnline) {
Result.Failure(TapError.NoInternetConnection)
Result.Failure(TapError.NoInternetConnection())
} else {
val blockchain = wallet.blockchain
val amountToCreateAccount = blockchain.amountToCreateAccount(this, wallet.getFirstToken())

View file

@ -44,6 +44,7 @@ class TangemAppLoggerInitializer(
}
}
@Suppress("BooleanPropertyNaming")
private companion object {
val IS_LOG_ENABLED: Boolean = BuildConfig.LOG_ENABLED
val PERMITTED_PRIORITY = listOf(Log.ERROR, Log.INFO)

View file

@ -20,6 +20,6 @@ data class GlobalState(
typealias CryptoCurrencyName = String
data class OnboardingState(
val onboardingStarted: Boolean = false,
val isOnboardingStarted: Boolean = false,
val shouldResetOnCreate: Boolean = false,
)

View file

@ -61,9 +61,9 @@ internal class AndroidEmailSender : EmailSender {
.setSubject(email.subject)
.setText(email.message)
email.attachment?.let {
email.attachment?.let { file ->
builder.setStream(
FileProvider.getUriForFile(activity, "${activity.packageName}.provider", it),
FileProvider.getUriForFile(activity, "${activity.packageName}.provider", file),
)
}

View file

@ -14,7 +14,7 @@ import javax.inject.Singleton
import kotlin.text.encodeToByteArray
private const val DEFAULT_KEY = "tangem_pay_default_key"
private const val DEFAULT_CUSTOMER_WALLET_ADDRESS_KEY = "tangem_pay_default_customer_wallet_address_key"
private const val ORDER_ID_KEY = "tangem_pay_order_id_key"
@Singleton
internal class DefaultTangemPayStorage @Inject constructor(
@ -54,24 +54,25 @@ internal class DefaultTangemPayStorage @Inject constructor(
?.let(tokensAdapter::fromJson)
}
/**
* Store the only customer wallet address, since for the f&f user can issue only one card tied to one address
*/
override suspend fun storeCustomerWalletAddress(customerWalletAddress: String) =
override suspend fun storeOrderId(customerWalletAddress: String, orderId: String) {
withContext(dispatcherProvider.io) {
secureStorage.store(
customerWalletAddress.encodeToByteArray(throwOnInvalidSequence = true),
DEFAULT_CUSTOMER_WALLET_ADDRESS_KEY,
orderId.encodeToByteArray(throwOnInvalidSequence = true),
createOrderIdKey(customerWalletAddress),
)
}
}
override suspend fun getCustomerWalletAddress(): String? = withContext(dispatcherProvider.io) {
secureStorage.get(DEFAULT_CUSTOMER_WALLET_ADDRESS_KEY)?.decodeToString(throwOnInvalidSequence = true)
override suspend fun getOrderId(customerWalletAddress: String): String? = withContext(dispatcherProvider.io) {
secureStorage.get(createOrderIdKey(customerWalletAddress))?.decodeToString(throwOnInvalidSequence = true)
}
override suspend fun clear(customerWalletAddress: String) = withContext(dispatcherProvider.io) {
secureStorage.delete(createKey(customerWalletAddress))
secureStorage.delete(createOrderIdKey(customerWalletAddress))
}
private fun createKey(cardId: String): String = "${DEFAULT_KEY}_$cardId"
private fun createKey(address: String): String = "${DEFAULT_KEY}_$address"
private fun createOrderIdKey(address: String): String = "${ORDER_ID_KEY}_$address"
}

View file

@ -3,7 +3,7 @@ package com.tangem.tap.data
import com.tangem.common.CompletionResult
import com.tangem.common.catching
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.core.wallets.UserWalletsListRepository
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import kotlinx.coroutines.flow.Flow

View file

@ -1,8 +1,8 @@
package com.tangem.tap.di.data
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.core.wallets.UserWalletsListRepository
import com.tangem.features.hotwallet.HotWalletFeatureToggles
import com.tangem.tap.data.RuntimeUserWalletsStore
import com.tangem.tap.data.UserWalletsStoreRepositoryProxy

View file

@ -1,7 +1,9 @@
package com.tangem.tap.di.domain
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
import com.tangem.domain.account.fetcher.SingleAccountListFetcher
import com.tangem.domain.account.repository.AccountsCRUDRepository
import com.tangem.domain.account.tokens.MainAccountTokensMigration
import com.tangem.domain.account.usecase.*
import dagger.Module
import dagger.Provides
@ -15,8 +17,16 @@ internal object AccountDomainModule {
@Provides
@Singleton
fun provideAddCryptoPortfolioUseCase(accountsCRUDRepository: AccountsCRUDRepository): AddCryptoPortfolioUseCase {
return AddCryptoPortfolioUseCase(crudRepository = accountsCRUDRepository)
fun provideAddCryptoPortfolioUseCase(
accountsCRUDRepository: AccountsCRUDRepository,
singleAccountListFetcher: SingleAccountListFetcher,
mainAccountTokensMigration: MainAccountTokensMigration,
): AddCryptoPortfolioUseCase {
return AddCryptoPortfolioUseCase(
crudRepository = accountsCRUDRepository,
singleAccountListFetcher = singleAccountListFetcher,
mainAccountTokensMigration = mainAccountTokensMigration,
)
}
@Provides

View file

@ -1,18 +1,16 @@
package com.tangem.tap.di.domain
import com.tangem.domain.card.*
import com.tangem.domain.card.DeleteSavedAccessCodesUseCase
import com.tangem.domain.card.ResetCardUseCase
import com.tangem.domain.card.SetCardWasScannedUseCase
import com.tangem.domain.card.repository.CardRepository
import com.tangem.domain.wallets.derivations.DerivationsRepository
import com.tangem.domain.demo.models.DemoConfig
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.demo.models.DemoConfig
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.derivations.DerivationsRepository
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.core.wallets.UserWalletsListRepository
import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase
import com.tangem.domain.wallets.usecase.GetExtendedPublicKeyForCurrencyUseCase
import com.tangem.domain.wallets.usecase.HasMissedDerivationsUseCase
import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase
import com.tangem.domain.wallets.usecase.NetworkHasDerivationUseCase
import com.tangem.domain.wallets.usecase.*
import com.tangem.features.hotwallet.HotWalletFeatureToggles
import com.tangem.sdk.api.TangemSdkManager
import com.tangem.tap.domain.card.DefaultDeleteSavedAccessCodesUseCase

View file

@ -2,8 +2,8 @@ package com.tangem.tap.di.domain
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
import com.tangem.domain.card.ScanCardProcessor
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.core.wallets.UserWalletsListRepository
import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase
import com.tangem.features.hotwallet.HotWalletFeatureToggles
import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles

View file

@ -1,7 +1,7 @@
package com.tangem.tap.di.domain
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.domain.wallets.derivations.DerivationsRepository
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.markets.*
import com.tangem.domain.markets.repositories.MarketsTokenRepository
import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher
@ -12,8 +12,8 @@ import com.tangem.domain.settings.repositories.SettingsRepository
import com.tangem.domain.staking.StakingIdFactory
import com.tangem.domain.staking.multi.MultiYieldBalanceFetcher
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.wallets.derivations.DerivationsRepository
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.core.wallets.UserWalletsListRepository
import com.tangem.features.hotwallet.HotWalletFeatureToggles
import dagger.Module
import dagger.Provides

View file

@ -179,6 +179,20 @@ internal object OnrampDomainModule {
)
}
@Provides
@Singleton
fun provideGetOnrampV2QuotesUseCase(
settingsRepository: SettingsRepository,
onrampRepository: OnrampRepository,
onrampErrorResolver: OnrampErrorResolver,
): GetOnrampV2QuotesUseCase {
return GetOnrampV2QuotesUseCase(
settingsRepository = settingsRepository,
repository = onrampRepository,
errorResolver = onrampErrorResolver,
)
}
@Provides
@Singleton
fun provideGetOnrampProviderWithQuoteUseCase(

View file

@ -24,6 +24,7 @@ import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
import com.tangem.domain.tokens.repository.PolkadotAccountHealthCheckRepository
import com.tangem.domain.tokens.repository.TokenReceiveWarningsViewedRepository
import com.tangem.domain.tokens.repository.YieldSupplyWarningsViewedRepository
import com.tangem.domain.tokens.wallet.WalletBalanceFetcher
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.tap.domain.tokens.DefaultTokensFeatureToggles
@ -455,4 +456,21 @@ internal object TokensDomainModule {
): SaveViewedTokenReceiveWarningUseCase {
return SaveViewedTokenReceiveWarningUseCase(tokenReceiveWarningsViewedRepository)
}
@Provides
@Singleton
fun provideNeedShowYieldSupplyDepositedWarningUseCase(
yieldSupplyWarningsViewedRepository: YieldSupplyWarningsViewedRepository,
dispatchers: CoroutineDispatcherProvider,
): NeedShowYieldSupplyDepositedWarningUseCase {
return NeedShowYieldSupplyDepositedWarningUseCase(yieldSupplyWarningsViewedRepository, dispatchers)
}
@Provides
@Singleton
fun provideSaveViewedYieldSupplyWarningUseCase(
yieldSupplyWarningsViewedRepository: YieldSupplyWarningsViewedRepository,
): SaveViewedYieldSupplyWarningUseCase {
return SaveViewedYieldSupplyWarningUseCase(yieldSupplyWarningsViewedRepository)
}
}

View file

@ -1,6 +1,6 @@
package com.tangem.tap.di.domain
import com.tangem.domain.core.wallets.UserWalletsListRepository
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.redux.ReduxStateHolder
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.transaction.WalletAddressServiceRepository
@ -16,6 +16,9 @@ import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.wallets.repository.WalletNamesMigrationRepository
import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.domain.wallets.usecase.*
import com.tangem.domain.yield.supply.YieldSupplyMarketRepository
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyUpdateUseCase
import com.tangem.feature.wallet.presentation.wallet.domain.IsWalletNFTEnabledSyncUseCase
import com.tangem.feature.wallet.presentation.wallet.domain.WalletNameMigrationUseCase
import com.tangem.features.hotwallet.HotWalletFeatureToggles
@ -448,4 +451,24 @@ internal object WalletsDomainModule {
userWalletUseCase = getUserWalletUseCase,
)
}
@Provides
@Singleton
fun provideYieldSupplyApyFlowUseCase(
yieldSupplyMarketRepository: YieldSupplyMarketRepository,
): YieldSupplyApyFlowUseCase {
return YieldSupplyApyFlowUseCase(
yieldSupplyMarketRepository = yieldSupplyMarketRepository,
)
}
@Provides
@Singleton
fun provideYieldSupplyApyUpdateUseCase(
yieldSupplyMarketRepository: YieldSupplyMarketRepository,
): YieldSupplyApyUpdateUseCase {
return YieldSupplyApyUpdateUseCase(
yieldSupplyMarketRepository = yieldSupplyMarketRepository,
)
}
}

View file

@ -1,11 +1,12 @@
package com.tangem.tap.di.domain
import com.tangem.domain.blockaid.BlockAidGasEstimate
import com.tangem.domain.transaction.FeeRepository
import com.tangem.domain.transaction.error.FeeErrorResolver
import com.tangem.domain.yield.supply.YieldSupplyErrorResolver
import com.tangem.domain.yield.supply.YieldSupplyMarketRepository
import com.tangem.domain.yield.supply.YieldSupplyTransactionRepository
import com.tangem.domain.yield.supply.usecase.YieldSupplyEstimateEnterFeeUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyStartEarningUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyStopEarningUseCase
import com.tangem.domain.yield.supply.usecase.*
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -20,9 +21,11 @@ internal object YieldSupplyDomainModule {
@Singleton
fun provideYieldSupplyStartEarningUseCase(
yieldSupplyTransactionRepository: YieldSupplyTransactionRepository,
yieldSupplyErrorResolver: YieldSupplyErrorResolver,
): YieldSupplyStartEarningUseCase {
return YieldSupplyStartEarningUseCase(
yieldSupplyTransactionRepository = yieldSupplyTransactionRepository,
yieldSupplyErrorResolver = yieldSupplyErrorResolver,
)
}
@ -30,9 +33,11 @@ internal object YieldSupplyDomainModule {
@Singleton
fun provideYieldSupplyStopEarningUseCase(
yieldSupplyTransactionRepository: YieldSupplyTransactionRepository,
yieldSupplyErrorResolver: YieldSupplyErrorResolver,
): YieldSupplyStopEarningUseCase {
return YieldSupplyStopEarningUseCase(
yieldSupplyTransactionRepository = yieldSupplyTransactionRepository,
yieldSupplyErrorResolver = yieldSupplyErrorResolver,
)
}
@ -41,10 +46,66 @@ internal object YieldSupplyDomainModule {
fun provideYieldSupplyEstimateEnterFeeUseCase(
feeRepository: FeeRepository,
feeErrorResolver: FeeErrorResolver,
blockAidGasEstimate: BlockAidGasEstimate,
): YieldSupplyEstimateEnterFeeUseCase {
return YieldSupplyEstimateEnterFeeUseCase(
feeRepository = feeRepository,
feeErrorResolver = feeErrorResolver,
blockAidGasEstimate = blockAidGasEstimate,
)
}
@Provides
@Singleton
fun provideYieldSupplyGetContractAddressUseCase(
yieldSupplyTransactionRepository: YieldSupplyTransactionRepository,
yieldSupplyErrorResolver: YieldSupplyErrorResolver,
): YieldSupplyGetContractAddressUseCase {
return YieldSupplyGetContractAddressUseCase(
yieldSupplyTransactionRepository = yieldSupplyTransactionRepository,
yieldSupplyErrorResolver = yieldSupplyErrorResolver,
)
}
@Provides
@Singleton
fun provideYieldSupplyGetProtocolBalanceUseCase(
yieldSupplyTransactionRepository: YieldSupplyTransactionRepository,
yieldSupplyErrorResolver: YieldSupplyErrorResolver,
): YieldSupplyGetProtocolBalanceUseCase {
return YieldSupplyGetProtocolBalanceUseCase(
yieldSupplyTransactionRepository = yieldSupplyTransactionRepository,
yieldSupplyErrorResolver = yieldSupplyErrorResolver,
)
}
@Provides
@Singleton
fun provideYieldSupplyGetTokenStatusUseCase(
yieldSupplyMarketRepository: YieldSupplyMarketRepository,
): YieldSupplyGetTokenStatusUseCase {
return YieldSupplyGetTokenStatusUseCase(
yieldSupplyMarketRepository = yieldSupplyMarketRepository,
)
}
@Provides
@Singleton
fun provideYieldSupplyGetApyUseCase(
yieldSupplyMarketRepository: YieldSupplyMarketRepository,
): YieldSupplyGetApyUseCase {
return YieldSupplyGetApyUseCase(
yieldSupplyMarketRepository = yieldSupplyMarketRepository,
)
}
@Provides
@Singleton
fun provideYieldSupplyGetChartUseCase(
yieldSupplyMarketRepository: YieldSupplyMarketRepository,
): YieldSupplyGetChartUseCase {
return YieldSupplyGetChartUseCase(
yieldSupplyMarketRepository = yieldSupplyMarketRepository,
)
}
}

View file

@ -39,7 +39,7 @@ class TangemSigner(
TangemSignerResponse(
totalSignedHashes = result.data.totalSignedHashes,
remainingSignatures = result.data.remainingSignatures,
isRing = result.data.batchId?.let(::isRing) ?: false,
isRing = result.data.batchId?.let(::isRing) == true,
),
)
if (continuation.isActive) {
@ -85,7 +85,7 @@ class TangemSigner(
TangemSignerResponse(
totalSignedHashes = result.data.totalSignedHashes,
remainingSignatures = result.data.remainingSignatures,
isRing = result.data.batchId?.let(::isRing) ?: false,
isRing = result.data.batchId?.let(::isRing) == true,
),
)
if (continuation.isActive) {

View file

@ -20,23 +20,23 @@ sealed class TapError(
override val args: List<Any>? = null,
) : Throwable(), TapErrors, ArgError {
object UnknownError : TapError(R.string.send_error_unknown)
class UnknownError : TapError(R.string.send_error_unknown)
open class CustomError(val customMessage: String) : TapError(R.string.common_custom_string, listOf(customMessage))
object NoInternetConnection : TapError(R.string.wallet_notification_no_internet)
class NoInternetConnection : TapError(R.string.wallet_notification_no_internet)
sealed class WalletManager {
class NoAccountError(amountToCreateAccount: String) : CustomError(amountToCreateAccount)
class InternalError(message: String) : CustomError(message)
object BlockchainIsUnreachableTryLater : TapError(R.string.wallet_balance_blockchain_unreachable_try_later)
class BlockchainIsUnreachableTryLater : TapError(R.string.wallet_balance_blockchain_unreachable_try_later)
}
}
sealed class TapSdkError(override val messageResId: Int?) : TangemError(code = 50100) {
override var customMessage: String = code.toString()
object CardForDifferentApp : TapSdkError(R.string.alert_unsupported_card)
object CardNotSupportedByRelease : TapSdkError(R.string.error_wrong_card_type)
class CardForDifferentApp : TapSdkError(R.string.alert_unsupported_card)
class CardNotSupportedByRelease : TapSdkError(R.string.error_wrong_card_type)
}
fun TapErrors.assembleErrors(): MutableList<Pair<Int, List<Any>?>> {

View file

@ -70,7 +70,7 @@ internal class DefaultResetCardUseCase(
null
}
type?.let {
if (type != null) {
tangemSdkManager.setUserCodeRequestPolicy(policy = UserCodeRequestPolicy.Always(type))
}
}

View file

@ -119,14 +119,14 @@ internal class LegacyScanProcessor @Inject constructor(
}
private fun sendAnalytics(analyticsEvent: AnalyticsEvent?, scanResponse: ScanResponse) {
analyticsEvent?.let {
analyticsEvent?.let { event ->
// this workaround needed to send CardWasScannedEvent without adding a context
val interceptor = CardContextInterceptor(scanResponse)
val params = it.params.toMutableMap()
val params = event.params.toMutableMap()
interceptor.intercept(params)
it.params = params.toMap()
event.params = params.toMap()
Analytics.send(it)
Analytics.send(event)
}
}

View file

@ -33,8 +33,8 @@ internal object UseCaseScanProcessor {
return scanCardUseCase(cardId, allowsRequestAccessCodeFromRepository)
.fold(
ifLeft = {
val error = scanCardExceptionConverter.convertBack(it)
ifLeft = { scanCardException ->
val error = scanCardExceptionConverter.convertBack(scanCardException)
Analytics.sendErrorEvent(TangemSdkErrorEvent(error))
CompletionResult.Failure(error)

View file

@ -8,10 +8,10 @@ sealed class ScanChainException : ScanCardException.ChainException() {
/**
* May be returned from [DisclaimerChain]
* */
data object DisclaimerWasCanceled : ScanChainException() {
class DisclaimerWasCanceled : ScanChainException() {
@Suppress("UnusedPrivateMember")
private fun readResolve(): Any = DisclaimerWasCanceled
private fun readResolve(): Any = DisclaimerWasCanceled()
}
/**

View file

@ -23,10 +23,10 @@ internal class ScanCardExceptionConverter : TwoWayConverter<TangemError, ScanCar
}
private fun convertTangemSdkError(value: TangemSdkError): ScanCardException = when (value) {
is TangemSdkError.UserCancelled -> ScanCardException.UserCancelled
is TangemSdkError.UserCancelled -> ScanCardException.UserCancelled()
is TangemSdkError.WrongAccessCode,
is TangemSdkError.WrongPasscode,
-> ScanCardException.WrongAccessCode
-> ScanCardException.WrongAccessCode()
is TangemSdkError.WrongCardNumber -> ScanCardException.WrongCardId(value.cardId)
else -> ScanCardException.UnknownException(value)
}

View file

@ -5,27 +5,25 @@ import com.tangem.common.core.TangemError
import com.tangem.common.core.TangemSdkError
import com.tangem.domain.models.scan.ProductType
import com.tangem.sdk.api.CreateProductWalletTaskResponse
import com.tangem.tap.domain.sdk.mocks.content.Wallet2WithSeedPhraseMockContent
import com.tangem.tap.domain.sdk.mocks.content.NoteMockContent
import com.tangem.tap.domain.sdk.mocks.content.WalletMockContent
import com.tangem.tap.domain.sdk.mocks.content.*
object MockProvider {
private var content: MockContent = getMockContent(ProductType.Wallet)
private var emulateError: Boolean = false
private var isEmulatingError: Boolean = false
private var emulatedError: TangemError = TangemSdkError.TagLost()
fun setEmulateError(error: TangemError? = null) {
emulateError = true
isEmulatingError = true
error?.let {
emulatedError = it
}
}
fun resetEmulateError() {
emulateError = false
isEmulatingError = false
}
fun setMocks(productType: ProductType) {
@ -69,12 +67,14 @@ object MockProvider {
ProductType.Wallet -> WalletMockContent
ProductType.Wallet2 -> Wallet2WithSeedPhraseMockContent
ProductType.Note -> NoteMockContent
ProductType.Ring -> RingMockContent
ProductType.Twins -> TwinsMockContent
else -> TODO()
}
}
private fun <T> CompletionResult.Success<T>.orFailure(): CompletionResult<T> {
return if (emulateError) {
return if (isEmulatingError) {
CompletionResult.Failure(emulatedError)
} else {
this

View file

@ -168,52 +168,52 @@ object BackupWalletMockContent : MockContent {
byteArrayOf(2, -109, 28, -27, -124, -58, -97, -61, 43, -84, 90, -9, -5, 4, 90, 17, 112, -125, -108, 44, 19, -79, -60, -23, 34, -20, -20, 61, 84, 113, 120, -90, -5),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/84'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/145'/0'/0/0") to ExtendedPublicKey( // bch
publicKey = byteArrayOf(2, 38, -6, 92, -37, -91, -59, -108, -18, -119, -55, 41, 38, -33, 44, 59, 24, -79, -14, -38, -10, -123, 106, 56, 39, 8, 112, 29, -41, 99, 70, -104, -121),
chainCode = byteArrayOf(105, -21, -61, -50, 68, -89, 119, 53, -96, -40, 119, 77, -122, 121, 16, 40, -50, -48, -105, -101, -74, -7, -94, -59, -90, 96, 59, 99, 43, -91, 115, -29),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/3'/0'/0/0") to ExtendedPublicKey( // doge
publicKey = byteArrayOf(3, -25, -24, -97, -124, 24, -89, 44, 75, 123, 92, -86, -73, -93, 25, -90, -89, -95, 88, 3, 107, 37, -1, -85, -32, -57, -123, -41, 108, -9, -96, 77, -124),
chainCode = byteArrayOf(119, 3, 41, 112, 71, 54, 72, 30, 39, 25, 25, -104, 92, 46, -109, 63, 93, 67, 43, -102, -87, 39, -95, 106, 45, 67, 109, -29, -35, 10, -107, 104),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/195'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/84'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/145'/0'/0/0") to ExtendedPublicKey( // bch
publicKey = byteArrayOf(2, 38, -6, 92, -37, -91, -59, -108, -18, -119, -55, 41, 38, -33, 44, 59, 24, -79, -14, -38, -10, -123, 106, 56, 39, 8, 112, 29, -41, 99, 70, -104, -121),
chainCode = byteArrayOf(105, -21, -61, -50, 68, -89, 119, 53, -96, -40, 119, 77, -122, 121, 16, 40, -50, -48, -105, -101, -74, -7, -94, -59, -90, 96, 59, 99, 43, -91, 115, -29),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/3'/0'/0/0") to ExtendedPublicKey( // doge
publicKey = byteArrayOf(3, -25, -24, -97, -124, 24, -89, 44, 75, 123, 92, -86, -73, -93, 25, -90, -89, -95, 88, 3, 107, 37, -1, -85, -32, -57, -123, -41, 108, -9, -96, 77, -124),
chainCode = byteArrayOf(119, 3, 41, 112, 71, 54, 72, 30, 39, 25, 25, -104, 92, 46, -109, 63, 93, 67, 43, -102, -87, 39, -95, 106, 45, 67, 109, -29, -35, 10, -107, 104),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/195'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
)
@ -234,24 +234,24 @@ object BackupWalletMockContent : MockContent {
byteArrayOf(2, -109, 28, -27, -124, -58, -97, -61, 43, -84, 90, -9, -5, 4, 90, 17, 112, -125, -108, 44, 19, -79, -60, -23, 34, -20, -20, 61, 84, 113, 120, -90, -5),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
primaryCard = primaryCard,
)

View file

@ -168,52 +168,52 @@ object DevWalletMockContent : MockContent {
byteArrayOf(2, -109, 28, -27, -124, -58, -97, -61, 43, -84, 90, -9, -5, 4, 90, 17, 112, -125, -108, 44, 19, -79, -60, -23, 34, -20, -20, 61, 84, 113, 120, -90, -5),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/84'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/145'/0'/0/0") to ExtendedPublicKey( // bch
publicKey = byteArrayOf(2, 38, -6, 92, -37, -91, -59, -108, -18, -119, -55, 41, 38, -33, 44, 59, 24, -79, -14, -38, -10, -123, 106, 56, 39, 8, 112, 29, -41, 99, 70, -104, -121),
chainCode = byteArrayOf(105, -21, -61, -50, 68, -89, 119, 53, -96, -40, 119, 77, -122, 121, 16, 40, -50, -48, -105, -101, -74, -7, -94, -59, -90, 96, 59, 99, 43, -91, 115, -29),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/3'/0'/0/0") to ExtendedPublicKey( // doge
publicKey = byteArrayOf(3, -25, -24, -97, -124, 24, -89, 44, 75, 123, 92, -86, -73, -93, 25, -90, -89, -95, 88, 3, 107, 37, -1, -85, -32, -57, -123, -41, 108, -9, -96, 77, -124),
chainCode = byteArrayOf(119, 3, 41, 112, 71, 54, 72, 30, 39, 25, 25, -104, 92, 46, -109, 63, 93, 67, 43, -102, -87, 39, -95, 106, 45, 67, 109, -29, -35, 10, -107, 104),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/195'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/84'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/145'/0'/0/0") to ExtendedPublicKey( // bch
publicKey = byteArrayOf(2, 38, -6, 92, -37, -91, -59, -108, -18, -119, -55, 41, 38, -33, 44, 59, 24, -79, -14, -38, -10, -123, 106, 56, 39, 8, 112, 29, -41, 99, 70, -104, -121),
chainCode = byteArrayOf(105, -21, -61, -50, 68, -89, 119, 53, -96, -40, 119, 77, -122, 121, 16, 40, -50, -48, -105, -101, -74, -7, -94, -59, -90, 96, 59, 99, 43, -91, 115, -29),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/3'/0'/0/0") to ExtendedPublicKey( // doge
publicKey = byteArrayOf(3, -25, -24, -97, -124, 24, -89, 44, 75, 123, 92, -86, -73, -93, 25, -90, -89, -95, 88, 3, 107, 37, -1, -85, -32, -57, -123, -41, 108, -9, -96, 77, -124),
chainCode = byteArrayOf(119, 3, 41, 112, 71, 54, 72, 30, 39, 25, 25, -104, 92, 46, -109, 63, 93, 67, 43, -102, -87, 39, -95, 106, 45, 67, 109, -29, -35, 10, -107, 104),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/195'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
)
@ -234,24 +234,24 @@ object DevWalletMockContent : MockContent {
byteArrayOf(2, -109, 28, -27, -124, -58, -97, -61, 43, -84, 90, -9, -5, 4, 90, 17, 112, -125, -108, 44, 19, -79, -60, -23, 34, -20, -20, 61, 84, 113, 120, -90, -5),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
primaryCard = primaryCard,
)

View file

@ -0,0 +1,116 @@
package com.tangem.tap.domain.sdk.mocks.content
import com.tangem.common.SuccessResponse
import com.tangem.common.card.*
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.operations.attestation.Attestation
import com.tangem.operations.derivation.DerivationTaskResponse
import com.tangem.operations.wallet.CreateWalletResponse
import com.tangem.sdk.api.CreateProductWalletTaskResponse
import com.tangem.tap.domain.sdk.mocks.MockContent
import java.util.Date
object EdCurveMockContent : MockContent {
override val cardDto = CardDTO(
cardId = "CB43000000000004",
batchId = "0052",
cardPublicKey = byteArrayOf(4, 20, -44, 84, -19, -94, 62, -88, 17, -60, -54, 115, 109, -105, 116, -4, 79, 74, 50, 55, -57, 118, -84, -17, -64, 74, 98, -104, -11, 101, 64, -85, -23, -69, 18, 96, -105, -125, -93, 87, -9, -96, -38, 32, -99, -116, 124, -34, -59, 64, -125, 96, 94, 47, -128, 61, 58, -100, 103, 84, 21, -103, 77, -91, 64),
firmwareVersion = CardDTO.FirmwareVersion(
major = 3,
minor = 5,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
manufacturer = CardDTO.Manufacturer(
name = "TANGEM",
manufactureDate = Date(1583971200),
signature = byteArrayOf(54, 94, -56, 20, 66, -33, 103, 86, -108, 28, -101, -113, 31, 118, -89, 86, 75, 4, 21, -70, -115, 82, -98, 45, -95, 92, 45, 29, -33, 53, -16, 9, -27, 44, 44, 13, 9, -71, -85, -43, -3, 58, -82, -40, -59, -114, 7, 89, 39, -16, -60, -58, 95, -87, -54, -71, -70, -95, -59, -44, 125, -42, -66, -26),
),
issuer = CardDTO.Issuer(
name = "TANGEM SDK",
publicKey = byteArrayOf(3, 86, -25, -61, 55, 99, 41, -33, -82, 115, -120, -33, 22, -107, 103, 3, -122, 16, 60, -110, 72, 106, -121, 100, 79, -87, -27, 18, -55, -49, 78, -110, -2),
),
settings = CardDTO.Settings(
securityDelay = 15000,
maxWalletsCount = 1,
isSettingAccessCodeAllowed = false,
isSettingPasscodeAllowed = true,
isResettingUserCodesAllowed = true,
isLinkedTerminalEnabled = true,
isBackupAllowed = false,
supportedEncryptionModes = listOf(EncryptionMode.Strong, EncryptionMode.Fast, EncryptionMode.None),
isFilesAllowed = true,
isHDWalletAllowed = false,
isKeysImportAllowed = false,
),
userSettings = CardDTO.UserSettings(isUserCodeRecoveryAllowed = false),
linkedTerminalStatus = CardDTO.LinkedTerminalStatus.None,
isAccessCodeSet = false,
isPasscodeSet = null,
supportedCurves = listOf(EllipticCurve.Ed25519),
wallets = listOf(
CardDTO.Wallet(
publicKey = byteArrayOf(71, -83, -58, -126, 43, 71, -27, 47, 85, -5, 120, -20, -124, -68, 14, 64, 61, 47, -95, -125, 76, -56, -98, 12, 70, 2, -18, -73, 4, -29, 62, -124),
chainCode = null,
curve = EllipticCurve.Ed25519,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
remainingSignatures = 1000000,
index = 0,
hasBackup = false,
derivedKeys = emptyMap(),
extendedPublicKey = null,
isImported = false,
),
),
attestation = Attestation(
cardKeyAttestation = Attestation.Status.Verified,
walletKeysAttestation = Attestation.Status.Skipped,
firmwareAttestation = Attestation.Status.Skipped,
cardUniquenessAttestation = Attestation.Status.Skipped,
),
backupStatus = null,
)
override val scanResponse = ScanResponse(
card = cardDto,
productType = ProductType.Wallet,
walletData = WalletData(
blockchain = "XLM",
token = null,
),
secondTwinPublicKey = null,
derivedKeys = emptyMap(),
primaryCard = null,
)
override val derivationTaskResponse = DerivationTaskResponse(
entries = emptyMap(),
)
override val extendedPublicKey
get() = error("Available only for Wallet+")
override val successResponse = SuccessResponse(cardId = "CB43000000000004")
override val createProductWalletTaskResponse = CreateProductWalletTaskResponse(
card = cardDto,
derivedKeys = emptyMap(),
primaryCard = null,
)
override val importWalletResponse: CreateProductWalletTaskResponse
get() = error("Available only for Wallet 2")
override val createFirstTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val createSecondTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val finalizeTwinResponse: ScanResponse
get() = error("Available only for Twin")
}

View file

@ -0,0 +1,266 @@
package com.tangem.tap.domain.sdk.mocks.content
import com.tangem.common.SuccessResponse
import com.tangem.common.card.*
import com.tangem.common.extensions.ByteArrayKey
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.operations.attestation.Attestation
import com.tangem.operations.backup.PrimaryCard
import com.tangem.operations.derivation.DerivationTaskResponse
import com.tangem.operations.derivation.ExtendedPublicKeysMap
import com.tangem.operations.wallet.CreateWalletResponse
import com.tangem.sdk.api.CreateProductWalletTaskResponse
import com.tangem.tap.domain.sdk.mocks.MockContent
import java.util.Date
object Firmware412MockContent : MockContent {
private val primaryCard = PrimaryCard(
cardId = "AC07000000035437",
batchId = "CB79",
cardPublicKey = byteArrayOf(2, -120, -3, -32, -122, -127, -120, -104, 59, 72, 76, 114, 94, 75, -37, -55, 55, 99, 66, 123, 85, -87, 80, 106, 105, -116, 87, -83, -12, 70, 108, -68, -39),
linkingKey = byteArrayOf(
2, 121, 98, 127, -70, 14, 5, -23, -76, 115, -30, -26, 111, 17, 110, 34, -100, -121,
-57, -123, 74, 3, -91, 56, -20, 56, 50, -40, -101, 96, 82, 70, -91,
),
existingWalletsCount = 3, isHDWalletAllowed = true,
issuer = Card.Issuer(
name = "TANGEM AG",
publicKey = byteArrayOf(3, 86, -25, -61, 55, 99, 41, -33, -82, 115, -120, -33, 22, -107, 103, 3, -122, 16, 60, -110, 72, 106, -121, 100, 79, -87, -27, 18, -55, -49, 78, -110, -2),
),
manufacturer = Card.Manufacturer(
name = "TANGEM",
manufactureDate = Date(1743759687),
signature = byteArrayOf(),
),
walletCurves = listOf(EllipticCurve.Secp256k1, EllipticCurve.Ed25519, EllipticCurve.Bls12381G2Aug),
firmwareVersion = FirmwareVersion(
major = 4,
minor = 12,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
isKeysImportAllowed = false,
certificate = null,
)
override val cardDto = CardDTO(
cardId = "AC07000000035437",
batchId = "CB79",
cardPublicKey = byteArrayOf(2, -120, -3, -32, -122, -127, -120, -104, 59, 72, 76, 114, 94, 75, -37, -55, 55, 99, 66, 123, 85, -87, 80, 106, 105, -116, 87, -83, -12, 70, 108, -68, -39),
firmwareVersion = CardDTO.FirmwareVersion(
major = 4,
minor = 12,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
manufacturer = CardDTO.Manufacturer(
name = "TANGEM",
manufactureDate = Date(1649635200000),
signature = byteArrayOf(-20, 98, -101, 94, -23, 73, 122, -21, 74, 76, 79, -55, -102, -62, -30, 44, -38, 118, 75, 121, -36, 118, -62, 60, -38, -63, 33, -14, -98, -69, 112, 22, 48, -43, 47, 65, -61, -56, 38, -94, -45, 44, 95, -22, 6, -31, -40, -25, 42, 38, 94, -99, 71, 98, -33, 27, -102, 30, 52, -7, 51, -27, 84, 66),
),
issuer = CardDTO.Issuer(
name = "TANGEM AG",
publicKey = byteArrayOf(3, 86, -25, -61, 55, 99, 41, -33, -82, 115, -120, -33, 22, -107, 103, 3, -122, 16, 60, -110, 72, 106, -121, 100, 79, -87, -27, 18, -55, -49, 78, -110, -2),
),
settings = CardDTO.Settings(
securityDelay = 15000,
maxWalletsCount = 20,
isSettingAccessCodeAllowed = false,
isSettingPasscodeAllowed = false,
isResettingUserCodesAllowed = true,
isLinkedTerminalEnabled = true,
isBackupAllowed = false,
supportedEncryptionModes = listOf(EncryptionMode.Strong, EncryptionMode.Fast, EncryptionMode.None),
isFilesAllowed = false,
isHDWalletAllowed = false,
isKeysImportAllowed = false,
),
userSettings = CardDTO.UserSettings(isUserCodeRecoveryAllowed = false),
linkedTerminalStatus = CardDTO.LinkedTerminalStatus.None,
isAccessCodeSet = false,
isPasscodeSet = false,
supportedCurves = listOf(
EllipticCurve.Secp256k1,
EllipticCurve.Ed25519,
EllipticCurve.Secp256r1,
),
wallets = listOf(
CardDTO.Wallet(
publicKey = byteArrayOf(2, -109, 28, -27, -124, -58, -97, -61, 43, -84, 90, -9, -5, 4, 90, 17, 112, -125, -108, 44, 19, -79, -60, -23, 34, -20, -20, 61, 84, 113, 120, -90, -5),
chainCode = byteArrayOf(80, 13, -8, -108, -35, 116, -92, 125, -65, -28, 85, 72, -113, 59, 83, 13, 5, -83, -102, 123, 124, -22, 94, 108, -71, 95, 65, -2, 38, 38, -108, 14),
curve = EllipticCurve.Secp256k1,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
remainingSignatures = null,
index = 0,
hasBackup = false,
derivedKeys = mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
),
DerivationPath("m/44'/1'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
),
DerivationPath("m/44'/195'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
),
),
extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(2, -109, 28, -27, -124, -58, -97, -61, 43, -84, 90, -9, -5, 4, 90, 17, 112, -125, -108, 44, 19, -79, -60, -23, 34, -20, -20, 61, 84, 113, 120, -90, -5),
chainCode = byteArrayOf(80, 13, -8, -108, -35, 116, -92, 125, -65, -28, 85, 72, -113, 59, 83, 13, 5, -83, -102, 123, 124, -22, 94, 108, -71, 95, 65, -2, 38, 38, -108, 14),
),
isImported = false,
),
CardDTO.Wallet(
publicKey = byteArrayOf(-65, -53, -62, -12, -57, -32, -38, -9, -128, -52, -83, -61, 73, 39, 41, 15, -74, -97, 38, 52, -101, 63, 74, -56, -20, 15, 57, -127, 114, -93, -17, -109),
chainCode = byteArrayOf(-81, 15, 125, 28, -115, -22, 87, 81, 87, -123, -25, -74, 86, 2, 1, 110, -115, 65, -110, 63, -64, 83, -93, -97, -104, 123, 12, -26, 94, 27, 84, -6),
curve = EllipticCurve.Ed25519,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
remainingSignatures = null,
index = 1,
hasBackup = false,
derivedKeys = emptyMap(),
extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(-65, -53, -62, -12, -57, -32, -38, -9, -128, -52, -83, -61, 73, 39, 41, 15, -74, -97, 38, 52, -101, 63, 74, -56, -20, 15, 57, -127, 114, -93, -17, -109),
chainCode = byteArrayOf(-81, 15, 125, 28, -115, -22, 87, 81, 87, -123, -25, -74, 86, 2, 1, 110, -115, 65, -110, 63, -64, 83, -93, -97, -104, 123, 12, -26, 94, 27, 84, -6),
),
isImported = false,
),
),
attestation = Attestation(
cardKeyAttestation = Attestation.Status.Verified,
walletKeysAttestation = Attestation.Status.Skipped,
firmwareAttestation = Attestation.Status.Skipped,
cardUniquenessAttestation = Attestation.Status.Skipped,
),
backupStatus = CardDTO.BackupStatus.NoBackup,
)
override val scanResponse = ScanResponse(
card = cardDto,
productType = ProductType.Wallet,
walletData = null,
secondTwinPublicKey = null,
derivedKeys = emptyMap(),
primaryCard = null,
)
override val derivationTaskResponse = DerivationTaskResponse(
entries = mapOf(
ByteArrayKey(
byteArrayOf(2, -109, 28, -27, -124, -58, -97, -61, 43, -84, 90, -9, -5, 4, 90, 17, 112, -125, -108, 44, 19, -79, -60, -23, 34, -20, -20, 61, 84, 113, 120, -90, -5),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/84'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/145'/0'/0/0") to ExtendedPublicKey( // bch
publicKey = byteArrayOf(2, 38, -6, 92, -37, -91, -59, -108, -18, -119, -55, 41, 38, -33, 44, 59, 24, -79, -14, -38, -10, -123, 106, 56, 39, 8, 112, 29, -41, 99, 70, -104, -121),
chainCode = byteArrayOf(105, -21, -61, -50, 68, -89, 119, 53, -96, -40, 119, 77, -122, 121, 16, 40, -50, -48, -105, -101, -74, -7, -94, -59, -90, 96, 59, 99, 43, -91, 115, -29),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/3'/0'/0/0") to ExtendedPublicKey( // doge
publicKey = byteArrayOf(3, -25, -24, -97, -124, 24, -89, 44, 75, 123, 92, -86, -73, -93, 25, -90, -89, -95, 88, 3, 107, 37, -1, -85, -32, -57, -123, -41, 108, -9, -96, 77, -124),
chainCode = byteArrayOf(119, 3, 41, 112, 71, 54, 72, 30, 39, 25, 25, -104, 92, 46, -109, 63, 93, 67, 43, -102, -87, 39, -95, 106, 45, 67, 109, -29, -35, 10, -107, 104),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/195'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
)
override val extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(3, 2, 95, 53, 40, -87, -60, 11, -8, -47, 41, 37, 100, 15, -69, 1, -122, 127, -20, -81, -32, -20, -24, 5, -28, 113, 106, -90, -59, -30, -27, -110, -110),
chainCode = byteArrayOf(-95, -87, -95, -25, 27, 96, -57, -92, -69, -106, -45, 10, 85, 4, -92, -68, 49, -24, -28, -50, -49, -77, -20, 118, -50, -27, 104, -93, 115, -50, -46, -34),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
)
override val successResponse = SuccessResponse(cardId = "AC07000000035437")
override val createProductWalletTaskResponse = CreateProductWalletTaskResponse(
card = cardDto,
derivedKeys = mapOf(
ByteArrayKey(
byteArrayOf(2, -109, 28, -27, -124, -58, -97, -61, 43, -84, 90, -9, -5, 4, 90, 17, 112, -125, -108, 44, 19, -79, -60, -23, 34, -20, -20, 61, 84, 113, 120, -90, -5),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
primaryCard = primaryCard,
)
override val importWalletResponse: CreateProductWalletTaskResponse
get() = error("Available only for Wallet 2")
override val createFirstTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val createSecondTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val finalizeTwinResponse: ScanResponse
get() = error("Available only for Twin")
}

View file

@ -0,0 +1,270 @@
package com.tangem.tap.domain.sdk.mocks.content
import com.tangem.common.SuccessResponse
import com.tangem.common.card.*
import com.tangem.common.extensions.ByteArrayKey
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.operations.attestation.Attestation
import com.tangem.operations.backup.PrimaryCard
import com.tangem.operations.derivation.DerivationTaskResponse
import com.tangem.operations.derivation.ExtendedPublicKeysMap
import com.tangem.operations.wallet.CreateWalletResponse
import com.tangem.sdk.api.CreateProductWalletTaskResponse
import com.tangem.tap.domain.sdk.mocks.MockContent
import java.util.Date
object RingMockContent : MockContent {
private val primaryCard = PrimaryCard(
cardId = "BA00000100129772",
batchId = "BA000001",
cardPublicKey = byteArrayOf(2, 48, 4, 54, -34, -33, 22, 53, -92, 8, 72, 50, 69, 1, 105, -53, 9, -126, -23, -61, -62, -85, -24, -112, -32, 76, -88, -66, -25, -83, -70, -95, 90),
linkingKey = byteArrayOf(
2, 121, 98, 127, -70, 14, 5, -23, -76, 115, -30, -26, 111, 17, 110, 34, -100, -121,
-57, -123, 74, 3, -91, 56, -20, 56, 50, -40, -101, 96, 82, 70, -91,
),
existingWalletsCount = 3, isHDWalletAllowed = true,
issuer = Card.Issuer(
name = "Tangem 2.0",
publicKey = byteArrayOf(2, 95, 22, -67, 29, 46, -81, -28, 99, -26, 42, 51, 90, 9, -26, -78, -69, -53, -48, 68, 82, 82, 104, -123, -53, 103, -97, -60, -46, 122, -15, -67, 34),
),
manufacturer = Card.Manufacturer(
name = "TANGEM",
manufactureDate = Date(1743759687),
signature = byteArrayOf(44, 8, 116, 111, -57, 20, -93, 101, -104, 97, -104, -15, 58, -8, 41, -53, 95, 99, 107, 47, -29, -118, 41, 64, 22, 94, 33, -81, 114, -47, 10, -16, 97, 14, 94, -36, -82, -108, 74, -9, 35, -38, 66, 67, -116, -55, 65, -30, -58, -33, 31, 120, -45, 42, -3, -120, -74, -97, 97, -102, -13, -28, 29, -41),
),
walletCurves = listOf(EllipticCurve.Secp256k1, EllipticCurve.Ed25519, EllipticCurve.Bls12381G2Aug),
firmwareVersion = FirmwareVersion(
major = 6,
minor = 33,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
isKeysImportAllowed = false,
certificate = null,
)
override val cardDto = CardDTO(
cardId = "BA00000100129772",
batchId = "BA000001",
cardPublicKey = byteArrayOf(2, 48, 4, 54, -34, -33, 22, 53, -92, 8, 72, 50, 69, 1, 105, -53, 9, -126, -23, -61, -62, -85, -24, -112, -32, 76, -88, -66, -25, -83, -70, -95, 90),
firmwareVersion = CardDTO.FirmwareVersion(
major = 6,
minor = 33,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
manufacturer = CardDTO.Manufacturer(
name = "TANGEM",
manufactureDate = Date(1649635200000),
signature = byteArrayOf(-20, 98, -101, 94, -23, 73, 122, -21, 74, 76, 79, -55, -102, -62, -30, 44, -38, 118, 75, 121, -36, 118, -62, 60, -38, -63, 33, -14, -98, -69, 112, 22, 48, -43, 47, 65, -61, -56, 38, -94, -45, 44, 95, -22, 6, -31, -40, -25, 42, 38, 94, -99, 71, 98, -33, 27, -102, 30, 52, -7, 51, -27, 84, 66),
),
issuer = CardDTO.Issuer(
name = "Tangem 2.0",
publicKey = byteArrayOf(3, 86, -25, -61, 55, 99, 41, -33, -82, 115, -120, -33, 22, -107, 103, 3, -122, 16, 60, -110, 72, 106, -121, 100, 79, -87, -27, 18, -55, -49, 78, -110, -2),
),
settings = CardDTO.Settings(
securityDelay = 15000,
maxWalletsCount = 20,
isSettingAccessCodeAllowed = true,
isSettingPasscodeAllowed = false,
isResettingUserCodesAllowed = true,
isLinkedTerminalEnabled = true,
isBackupAllowed = true,
supportedEncryptionModes = listOf(EncryptionMode.Strong, EncryptionMode.Fast, EncryptionMode.None),
isFilesAllowed = true,
isHDWalletAllowed = true,
isKeysImportAllowed = true,
),
userSettings = CardDTO.UserSettings(isUserCodeRecoveryAllowed = true),
linkedTerminalStatus = CardDTO.LinkedTerminalStatus.None,
isAccessCodeSet = true,
isPasscodeSet = false,
supportedCurves = listOf(
EllipticCurve.Secp256k1,
EllipticCurve.Ed25519,
EllipticCurve.Secp256r1,
EllipticCurve.Bls12381G2,
EllipticCurve.Bls12381G2Aug,
EllipticCurve.Bls12381G2Pop,
EllipticCurve.Bip0340,
),
wallets = listOf(
CardDTO.Wallet(
publicKey = byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
chainCode = byteArrayOf(74, -90, -85, -117, -116, -78, 98, 63, 83, 12, 43, -69, 43, -54, -119, -62, 80, 107, -127, 53, 73, 108, 114, -102, 81, -123, 68, 92, 65, -25, 107, 86),
curve = EllipticCurve.Secp256k1,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
remainingSignatures = null,
index = 0,
hasBackup = true,
derivedKeys = mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
),
DerivationPath("m/44'/1'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
),
DerivationPath("m/44'/195'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
),
),
extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
chainCode = byteArrayOf(80, 13, -8, -108, -35, 116, -92, 125, -65, -28, 85, 72, -113, 59, 83, 13, 5, -83, -102, 123, 124, -22, 94, 108, -71, 95, 65, -2, 38, 38, -108, 14),
),
isImported = false,
),
CardDTO.Wallet(
publicKey = byteArrayOf(-123, -48, -77, -113, -63, -124, -18, 36, -14, -127, 104, 89, 48, 103, 69, -12, 107, -103, 64, -2, 97, 126, -78, -99, -9, -72, 94, -68, 30, 43, 38, 42),
chainCode = byteArrayOf(104, 109, 56, -52, 125, -119, -49, -51, -46, -122, -111, 75, 51, 103, 15, 25, -101, 72, -101, 101, -128, -2, -51, 3, 74, 62, -49, -6, -95, 91, -104, -58),
curve = EllipticCurve.Ed25519,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
remainingSignatures = null,
index = 1,
hasBackup = true,
derivedKeys = emptyMap(),
extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(-65, -53, -62, -12, -57, -32, -38, -9, -128, -52, -83, -61, 73, 39, 41, 15, -74, -97, 38, 52, -101, 63, 74, -56, -20, 15, 57, -127, 114, -93, -17, -109),
chainCode = byteArrayOf(-81, 15, 125, 28, -115, -22, 87, 81, 87, -123, -25, -74, 86, 2, 1, 110, -115, 65, -110, 63, -64, 83, -93, -97, -104, 123, 12, -26, 94, 27, 84, -6),
),
isImported = false,
),
),
attestation = Attestation(
cardKeyAttestation = Attestation.Status.Verified,
walletKeysAttestation = Attestation.Status.Skipped,
firmwareAttestation = Attestation.Status.Skipped,
cardUniquenessAttestation = Attestation.Status.Skipped,
),
backupStatus = CardDTO.BackupStatus.Active(cardCount = 2),
)
override val scanResponse = ScanResponse(
card = cardDto,
productType = ProductType.Ring,
walletData = null,
secondTwinPublicKey = null,
derivedKeys = emptyMap(),
primaryCard = null,
)
override val derivationTaskResponse = DerivationTaskResponse(
entries = mapOf(
ByteArrayKey(
byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/84'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/145'/0'/0/0") to ExtendedPublicKey( // bch
publicKey = byteArrayOf(2, 38, -6, 92, -37, -91, -59, -108, -18, -119, -55, 41, 38, -33, 44, 59, 24, -79, -14, -38, -10, -123, 106, 56, 39, 8, 112, 29, -41, 99, 70, -104, -121),
chainCode = byteArrayOf(105, -21, -61, -50, 68, -89, 119, 53, -96, -40, 119, 77, -122, 121, 16, 40, -50, -48, -105, -101, -74, -7, -94, -59, -90, 96, 59, 99, 43, -91, 115, -29),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/3'/0'/0/0") to ExtendedPublicKey( // doge
publicKey = byteArrayOf(3, -25, -24, -97, -124, 24, -89, 44, 75, 123, 92, -86, -73, -93, 25, -90, -89, -95, 88, 3, 107, 37, -1, -85, -32, -57, -123, -41, 108, -9, -96, 77, -124),
chainCode = byteArrayOf(119, 3, 41, 112, 71, 54, 72, 30, 39, 25, 25, -104, 92, 46, -109, 63, 93, 67, 43, -102, -87, 39, -95, 106, 45, 67, 109, -29, -35, 10, -107, 104),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/195'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
)
override val extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(3, 2, 95, 53, 40, -87, -60, 11, -8, -47, 41, 37, 100, 15, -69, 1, -122, 127, -20, -81, -32, -20, -24, 5, -28, 113, 106, -90, -59, -30, -27, -110, -110),
chainCode = byteArrayOf(-95, -87, -95, -25, 27, 96, -57, -92, -69, -106, -45, 10, 85, 4, -92, -68, 49, -24, -28, -50, -49, -77, -20, 118, -50, -27, 104, -93, 115, -50, -46, -34),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
)
override val successResponse = SuccessResponse(cardId = "BA00000100129772")
override val createProductWalletTaskResponse = CreateProductWalletTaskResponse(
card = cardDto,
derivedKeys = mapOf(
ByteArrayKey(
byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
primaryCard = primaryCard,
)
override val importWalletResponse: CreateProductWalletTaskResponse
get() = error("Available only for Wallet 2")
override val createFirstTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val createSecondTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val finalizeTwinResponse: ScanResponse
get() = error("Available only for Twin")
}

View file

@ -0,0 +1,188 @@
package com.tangem.tap.domain.sdk.mocks.content
import com.tangem.common.SuccessResponse
import com.tangem.common.card.*
import com.tangem.common.extensions.ByteArrayKey
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.operations.attestation.Attestation
import com.tangem.operations.backup.PrimaryCard
import com.tangem.operations.derivation.DerivationTaskResponse
import com.tangem.operations.derivation.ExtendedPublicKeysMap
import com.tangem.operations.wallet.CreateWalletResponse
import com.tangem.sdk.api.CreateProductWalletTaskResponse
import com.tangem.tap.domain.sdk.mocks.MockContent
import java.util.Date
object Secpk1CurveMockContent : MockContent {
private val primaryCard = PrimaryCard(
cardId = "CB37000000000002",
batchId = "0045",
cardPublicKey = byteArrayOf(4, 9, -112, -60, 29, -62, 102, -43, -38, -63, 56, 87, -76, 74, 91, -68, 127, -98, -56, 15, 12, -52, 37, -99, -104, -104, -7, -111, 6, 86, -90, 44, 87, 18, 73, 126, -104, 9, 83, -17, -11, -80, 115, 86, -90, -97, 119, -66, 114, 48, -95, -40, 10, 64, 121, -40, -15, 92, -64, 31, -21, 126, -31, 0, -40),
linkingKey = byteArrayOf(
2, 121, 98, 127, -70, 14, 5, -23, -76, 115, -30, -26, 111, 17, 110, 34, -100, -121,
-57, -123, 74, 3, -91, 56, -20, 56, 50, -40, -101, 96, 82, 70, -91,
),
existingWalletsCount = 3,
isHDWalletAllowed = false,
issuer = Card.Issuer(
name = "TANGEM SDK",
publicKey = byteArrayOf(4, 95, 22, -67, 29, 46, -81, -28, 99, -26, 42, 51, 90, 9, -26, -78, -69, -53, -48, 68, 82, 82, 104, -123, -53, 103, -97, -60, -46, 122, -15, -67, 34, -11, 83, -57, -34, -17, -75, 79, -45, -44, -13, 97, -47, 78, 109, -61, -15, 27, 125, 78, -95, -125, 37, 10, 96, 114, 14, -67, -7, -31, 16, -51, 38),
),
manufacturer = Card.Manufacturer(
name = "TANGEM",
manufactureDate = Date(1743759687),
signature = byteArrayOf(18, -101, -119, 75, 82, 4, 71, -45, 4, 74, -109, 68, 100, 48, 49, 82, 35, 13, 35, -43, 14, -123, -15, -13, -94, 122, -8, 12, -73, -52, 48, 16, 112, 41, 17, 52, -51, 38, 123, 50, 97, -32, -12, 76, -102, 29, -39, 126, 55, 65, -5, -1, -32, -28, -10, -33, 77, 105, -24, 93, -30, 73, -77, 82),
),
walletCurves = listOf(EllipticCurve.Secp256k1),
firmwareVersion = FirmwareVersion(
major = 3,
minor = 5,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
isKeysImportAllowed = false,
certificate = null,
)
override val cardDto = CardDTO(
cardId = "CB37000000000002",
batchId = "0045",
cardPublicKey = byteArrayOf(4, 9, -112, -60, 29, -62, 102, -43, -38, -63, 56, 87, -76, 74, 91, -68, 127, -98, -56, 15, 12, -52, 37, -99, -104, -104, -7, -111, 6, 86, -90, 44, 87, 18, 73, 126, -104, 9, 83, -17, -11, -80, 115, 86, -90, -97, 119, -66, 114, 48, -95, -40, 10, 64, 121, -40, -15, 92, -64, 31, -21, 126, -31, 0, -40),
firmwareVersion = CardDTO.FirmwareVersion(
major = 3,
minor = 5,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
manufacturer = CardDTO.Manufacturer(
name = "TANGEM",
manufactureDate = Date(1649635200000),
signature = byteArrayOf(-20, 98, -101, 94, -23, 73, 122, -21, 74, 76, 79, -55, -102, -62, -30, 44, -38, 118, 75, 121, -36, 118, -62, 60, -38, -63, 33, -14, -98, -69, 112, 22, 48, -43, 47, 65, -61, -56, 38, -94, -45, 44, 95, -22, 6, -31, -40, -25, 42, 38, 94, -99, 71, 98, -33, 27, -102, 30, 52, -7, 51, -27, 84, 66),
),
issuer = CardDTO.Issuer(
name = "TANGEM SDk",
publicKey = byteArrayOf(3, 86, -25, -61, 55, 99, 41, -33, -82, 115, -120, -33, 22, -107, 103, 3, -122, 16, 60, -110, 72, 106, -121, 100, 79, -87, -27, 18, -55, -49, 78, -110, -2),
),
settings = CardDTO.Settings(
securityDelay = 15000,
maxWalletsCount = 1,
isSettingAccessCodeAllowed = false,
isSettingPasscodeAllowed = true,
isResettingUserCodesAllowed = true,
isLinkedTerminalEnabled = true,
isBackupAllowed = true,
supportedEncryptionModes = listOf(EncryptionMode.Strong, EncryptionMode.Fast, EncryptionMode.None),
isFilesAllowed = true,
isHDWalletAllowed = false,
isKeysImportAllowed = false,
),
userSettings = CardDTO.UserSettings(isUserCodeRecoveryAllowed = true),
linkedTerminalStatus = CardDTO.LinkedTerminalStatus.None,
isAccessCodeSet = true,
isPasscodeSet = false,
supportedCurves = listOf(EllipticCurve.Secp256k1),
wallets = listOf(
CardDTO.Wallet(
publicKey = byteArrayOf(4, -45, -28, -111, 109, -9, -113, 17, 107, -45, 43, -55, -126, 103, -70, -13, 79, -103, -59, -69, 83, -47, -37, -49, -18, -65, 55, 6, 121, 17, 54, 32, 105, 2, 25, -101, -118, 91, 109, 49, 99, -42, -113, 105, 21, 109, 66, -7, -57, 55, 25, -37, 63, 16, 22, -118, 121, -127, -13, 47, -89, -4, -38, -65, -27),
chainCode = null,
curve = EllipticCurve.Secp256k1,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
remainingSignatures = 1000000,
index = 0,
hasBackup = false,
derivedKeys = emptyMap(),
extendedPublicKey = null,
isImported = false,
),
),
attestation = Attestation(
cardKeyAttestation = Attestation.Status.Verified,
walletKeysAttestation = Attestation.Status.Skipped,
firmwareAttestation = Attestation.Status.Skipped,
cardUniquenessAttestation = Attestation.Status.Skipped,
),
backupStatus = null,
)
override val scanResponse = ScanResponse(
card = cardDto,
productType = ProductType.Wallet,
walletData = WalletData(
blockchain = "BTC",
token = null,
),
secondTwinPublicKey = null,
derivedKeys = emptyMap(),
primaryCard = null,
)
override val derivationTaskResponse = DerivationTaskResponse(
entries = mapOf(
ByteArrayKey(
byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
)
override val extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(3, 2, 95, 53, 40, -87, -60, 11, -8, -47, 41, 37, 100, 15, -69, 1, -122, 127, -20, -81, -32, -20, -24, 5, -28, 113, 106, -90, -59, -30, -27, -110, -110),
chainCode = byteArrayOf(-95, -87, -95, -25, 27, 96, -57, -92, -69, -106, -45, 10, 85, 4, -92, -68, 49, -24, -28, -50, -49, -77, -20, 118, -50, -27, 104, -93, 115, -50, -46, -34),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
)
override val successResponse = SuccessResponse(cardId = "CB37000000000002")
override val createProductWalletTaskResponse = CreateProductWalletTaskResponse(
card = cardDto,
derivedKeys = mapOf(
ByteArrayKey(
byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
primaryCard = primaryCard,
)
override val importWalletResponse: CreateProductWalletTaskResponse
get() = error("Available only for Wallet 2")
override val createFirstTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val createSecondTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val finalizeTwinResponse: ScanResponse
get() = error("Available only for Twin")
}

View file

@ -0,0 +1,270 @@
package com.tangem.tap.domain.sdk.mocks.content
import com.tangem.common.SuccessResponse
import com.tangem.common.card.*
import com.tangem.common.extensions.ByteArrayKey
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.operations.attestation.Attestation
import com.tangem.operations.backup.PrimaryCard
import com.tangem.operations.derivation.DerivationTaskResponse
import com.tangem.operations.derivation.ExtendedPublicKeysMap
import com.tangem.operations.wallet.CreateWalletResponse
import com.tangem.sdk.api.CreateProductWalletTaskResponse
import com.tangem.tap.domain.sdk.mocks.MockContent
import java.util.Date
object ShibaMockContent : MockContent {
private val primaryCard = PrimaryCard(
cardId = "AF02010000000002",
batchId = "AF02",
cardPublicKey = byteArrayOf(2, 48, 4, 54, -34, -33, 22, 53, -92, 8, 72, 50, 69, 1, 105, -53, 9, -126, -23, -61, -62, -85, -24, -112, -32, 76, -88, -66, -25, -83, -70, -95, 90),
linkingKey = byteArrayOf(
2, 121, 98, 127, -70, 14, 5, -23, -76, 115, -30, -26, 111, 17, 110, 34, -100, -121,
-57, -123, 74, 3, -91, 56, -20, 56, 50, -40, -101, 96, 82, 70, -91,
),
existingWalletsCount = 3, isHDWalletAllowed = true,
issuer = Card.Issuer(
name = "TANGEM SDK",
publicKey = byteArrayOf(2, 95, 22, -67, 29, 46, -81, -28, 99, -26, 42, 51, 90, 9, -26, -78, -69, -53, -48, 68, 82, 82, 104, -123, -53, 103, -97, -60, -46, 122, -15, -67, 34),
),
manufacturer = Card.Manufacturer(
name = "TANGEM",
manufactureDate = Date(1743759687),
signature = byteArrayOf(44, 8, 116, 111, -57, 20, -93, 101, -104, 97, -104, -15, 58, -8, 41, -53, 95, 99, 107, 47, -29, -118, 41, 64, 22, 94, 33, -81, 114, -47, 10, -16, 97, 14, 94, -36, -82, -108, 74, -9, 35, -38, 66, 67, -116, -55, 65, -30, -58, -33, 31, 120, -45, 42, -3, -120, -74, -97, 97, -102, -13, -28, 29, -41),
),
walletCurves = listOf(EllipticCurve.Secp256k1, EllipticCurve.Ed25519, EllipticCurve.Bls12381G2Aug),
firmwareVersion = FirmwareVersion(
major = 6,
minor = 21,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
isKeysImportAllowed = false,
certificate = null,
)
override val cardDto = CardDTO(
cardId = "AF02010000000002",
batchId = "AF02",
cardPublicKey = byteArrayOf(2, 48, 4, 54, -34, -33, 22, 53, -92, 8, 72, 50, 69, 1, 105, -53, 9, -126, -23, -61, -62, -85, -24, -112, -32, 76, -88, -66, -25, -83, -70, -95, 90),
firmwareVersion = CardDTO.FirmwareVersion(
major = 6,
minor = 21,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
manufacturer = CardDTO.Manufacturer(
name = "TANGEM SDK",
manufactureDate = Date(1649635200000),
signature = byteArrayOf(-20, 98, -101, 94, -23, 73, 122, -21, 74, 76, 79, -55, -102, -62, -30, 44, -38, 118, 75, 121, -36, 118, -62, 60, -38, -63, 33, -14, -98, -69, 112, 22, 48, -43, 47, 65, -61, -56, 38, -94, -45, 44, 95, -22, 6, -31, -40, -25, 42, 38, 94, -99, 71, 98, -33, 27, -102, 30, 52, -7, 51, -27, 84, 66),
),
issuer = CardDTO.Issuer(
name = "TANGEM",
publicKey = byteArrayOf(3, 86, -25, -61, 55, 99, 41, -33, -82, 115, -120, -33, 22, -107, 103, 3, -122, 16, 60, -110, 72, 106, -121, 100, 79, -87, -27, 18, -55, -49, 78, -110, -2),
),
settings = CardDTO.Settings(
securityDelay = 15000,
maxWalletsCount = 20,
isSettingAccessCodeAllowed = true,
isSettingPasscodeAllowed = false,
isResettingUserCodesAllowed = true,
isLinkedTerminalEnabled = true,
isBackupAllowed = true,
supportedEncryptionModes = listOf(EncryptionMode.Strong, EncryptionMode.Fast, EncryptionMode.None),
isFilesAllowed = true,
isHDWalletAllowed = true,
isKeysImportAllowed = true,
),
userSettings = CardDTO.UserSettings(isUserCodeRecoveryAllowed = true),
linkedTerminalStatus = CardDTO.LinkedTerminalStatus.None,
isAccessCodeSet = true,
isPasscodeSet = false,
supportedCurves = listOf(
EllipticCurve.Secp256k1,
EllipticCurve.Ed25519,
EllipticCurve.Secp256r1,
EllipticCurve.Bls12381G2,
EllipticCurve.Bls12381G2Aug,
EllipticCurve.Bls12381G2Pop,
EllipticCurve.Bip0340,
),
wallets = listOf(
CardDTO.Wallet(
publicKey = byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
chainCode = byteArrayOf(74, -90, -85, -117, -116, -78, 98, 63, 83, 12, 43, -69, 43, -54, -119, -62, 80, 107, -127, 53, 73, 108, 114, -102, 81, -123, 68, 92, 65, -25, 107, 86),
curve = EllipticCurve.Secp256k1,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
remainingSignatures = null,
index = 0,
hasBackup = false,
derivedKeys = mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
),
DerivationPath("m/44'/1'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
),
DerivationPath("m/44'/195'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
),
),
extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
chainCode = byteArrayOf(80, 13, -8, -108, -35, 116, -92, 125, -65, -28, 85, 72, -113, 59, 83, 13, 5, -83, -102, 123, 124, -22, 94, 108, -71, 95, 65, -2, 38, 38, -108, 14),
),
isImported = false,
),
CardDTO.Wallet(
publicKey = byteArrayOf(-123, -48, -77, -113, -63, -124, -18, 36, -14, -127, 104, 89, 48, 103, 69, -12, 107, -103, 64, -2, 97, 126, -78, -99, -9, -72, 94, -68, 30, 43, 38, 42),
chainCode = byteArrayOf(104, 109, 56, -52, 125, -119, -49, -51, -46, -122, -111, 75, 51, 103, 15, 25, -101, 72, -101, 101, -128, -2, -51, 3, 74, 62, -49, -6, -95, 91, -104, -58),
curve = EllipticCurve.Ed25519,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
remainingSignatures = null,
index = 1,
hasBackup = false,
derivedKeys = emptyMap(),
extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(-65, -53, -62, -12, -57, -32, -38, -9, -128, -52, -83, -61, 73, 39, 41, 15, -74, -97, 38, 52, -101, 63, 74, -56, -20, 15, 57, -127, 114, -93, -17, -109),
chainCode = byteArrayOf(-81, 15, 125, 28, -115, -22, 87, 81, 87, -123, -25, -74, 86, 2, 1, 110, -115, 65, -110, 63, -64, 83, -93, -97, -104, 123, 12, -26, 94, 27, 84, -6),
),
isImported = false,
),
),
attestation = Attestation(
cardKeyAttestation = Attestation.Status.Verified,
walletKeysAttestation = Attestation.Status.Skipped,
firmwareAttestation = Attestation.Status.Skipped,
cardUniquenessAttestation = Attestation.Status.Skipped,
),
backupStatus = CardDTO.BackupStatus.Active(cardCount = 1),
)
override val scanResponse = ScanResponse(
card = cardDto,
productType = ProductType.Wallet,
walletData = null,
secondTwinPublicKey = null,
derivedKeys = emptyMap(),
primaryCard = null,
)
override val derivationTaskResponse = DerivationTaskResponse(
entries = mapOf(
ByteArrayKey(
byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/84'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/145'/0'/0/0") to ExtendedPublicKey( // bch
publicKey = byteArrayOf(2, 38, -6, 92, -37, -91, -59, -108, -18, -119, -55, 41, 38, -33, 44, 59, 24, -79, -14, -38, -10, -123, 106, 56, 39, 8, 112, 29, -41, 99, 70, -104, -121),
chainCode = byteArrayOf(105, -21, -61, -50, 68, -89, 119, 53, -96, -40, 119, 77, -122, 121, 16, 40, -50, -48, -105, -101, -74, -7, -94, -59, -90, 96, 59, 99, 43, -91, 115, -29),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/3'/0'/0/0") to ExtendedPublicKey( // doge
publicKey = byteArrayOf(3, -25, -24, -97, -124, 24, -89, 44, 75, 123, 92, -86, -73, -93, 25, -90, -89, -95, 88, 3, 107, 37, -1, -85, -32, -57, -123, -41, 108, -9, -96, 77, -124),
chainCode = byteArrayOf(119, 3, 41, 112, 71, 54, 72, 30, 39, 25, 25, -104, 92, 46, -109, 63, 93, 67, 43, -102, -87, 39, -95, 106, 45, 67, 109, -29, -35, 10, -107, 104),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/195'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
)
override val extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(3, 2, 95, 53, 40, -87, -60, 11, -8, -47, 41, 37, 100, 15, -69, 1, -122, 127, -20, -81, -32, -20, -24, 5, -28, 113, 106, -90, -59, -30, -27, -110, -110),
chainCode = byteArrayOf(-95, -87, -95, -25, 27, 96, -57, -92, -69, -106, -45, 10, 85, 4, -92, -68, 49, -24, -28, -50, -49, -77, -20, 118, -50, -27, 104, -93, 115, -50, -46, -34),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
)
override val successResponse = SuccessResponse(cardId = "AF02010000000002")
override val createProductWalletTaskResponse = CreateProductWalletTaskResponse(
card = cardDto,
derivedKeys = mapOf(
ByteArrayKey(
byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
primaryCard = primaryCard,
)
override val importWalletResponse: CreateProductWalletTaskResponse
get() = error("Available only for Wallet 2")
override val createFirstTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val createSecondTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val finalizeTwinResponse: ScanResponse
get() = error("Available only for Twin")
}

View file

@ -0,0 +1,270 @@
package com.tangem.tap.domain.sdk.mocks.content
import com.tangem.common.SuccessResponse
import com.tangem.common.card.*
import com.tangem.common.extensions.ByteArrayKey
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.operations.attestation.Attestation
import com.tangem.operations.backup.PrimaryCard
import com.tangem.operations.derivation.DerivationTaskResponse
import com.tangem.operations.derivation.ExtendedPublicKeysMap
import com.tangem.operations.wallet.CreateWalletResponse
import com.tangem.sdk.api.CreateProductWalletTaskResponse
import com.tangem.tap.domain.sdk.mocks.MockContent
import java.util.Date
object ShibaNoBackupMockContent : MockContent {
private val primaryCard = PrimaryCard(
cardId = "AF02010000000002",
batchId = "AF02",
cardPublicKey = byteArrayOf(2, 48, 4, 54, -34, -33, 22, 53, -92, 8, 72, 50, 69, 1, 105, -53, 9, -126, -23, -61, -62, -85, -24, -112, -32, 76, -88, -66, -25, -83, -70, -95, 90),
linkingKey = byteArrayOf(
2, 121, 98, 127, -70, 14, 5, -23, -76, 115, -30, -26, 111, 17, 110, 34, -100, -121,
-57, -123, 74, 3, -91, 56, -20, 56, 50, -40, -101, 96, 82, 70, -91,
),
existingWalletsCount = 3, isHDWalletAllowed = true,
issuer = Card.Issuer(
name = "TANGEM SDK",
publicKey = byteArrayOf(2, 95, 22, -67, 29, 46, -81, -28, 99, -26, 42, 51, 90, 9, -26, -78, -69, -53, -48, 68, 82, 82, 104, -123, -53, 103, -97, -60, -46, 122, -15, -67, 34),
),
manufacturer = Card.Manufacturer(
name = "TANGEM",
manufactureDate = Date(1743759687),
signature = byteArrayOf(44, 8, 116, 111, -57, 20, -93, 101, -104, 97, -104, -15, 58, -8, 41, -53, 95, 99, 107, 47, -29, -118, 41, 64, 22, 94, 33, -81, 114, -47, 10, -16, 97, 14, 94, -36, -82, -108, 74, -9, 35, -38, 66, 67, -116, -55, 65, -30, -58, -33, 31, 120, -45, 42, -3, -120, -74, -97, 97, -102, -13, -28, 29, -41),
),
walletCurves = listOf(EllipticCurve.Secp256k1, EllipticCurve.Ed25519, EllipticCurve.Bls12381G2Aug),
firmwareVersion = FirmwareVersion(
major = 6,
minor = 21,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
isKeysImportAllowed = false,
certificate = null,
)
override val cardDto = CardDTO(
cardId = "AF02010000000002",
batchId = "AF02",
cardPublicKey = byteArrayOf(2, 48, 4, 54, -34, -33, 22, 53, -92, 8, 72, 50, 69, 1, 105, -53, 9, -126, -23, -61, -62, -85, -24, -112, -32, 76, -88, -66, -25, -83, -70, -95, 90),
firmwareVersion = CardDTO.FirmwareVersion(
major = 6,
minor = 21,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
manufacturer = CardDTO.Manufacturer(
name = "TANGEM SDK",
manufactureDate = Date(1649635200000),
signature = byteArrayOf(-20, 98, -101, 94, -23, 73, 122, -21, 74, 76, 79, -55, -102, -62, -30, 44, -38, 118, 75, 121, -36, 118, -62, 60, -38, -63, 33, -14, -98, -69, 112, 22, 48, -43, 47, 65, -61, -56, 38, -94, -45, 44, 95, -22, 6, -31, -40, -25, 42, 38, 94, -99, 71, 98, -33, 27, -102, 30, 52, -7, 51, -27, 84, 66),
),
issuer = CardDTO.Issuer(
name = "TANGEM",
publicKey = byteArrayOf(3, 86, -25, -61, 55, 99, 41, -33, -82, 115, -120, -33, 22, -107, 103, 3, -122, 16, 60, -110, 72, 106, -121, 100, 79, -87, -27, 18, -55, -49, 78, -110, -2),
),
settings = CardDTO.Settings(
securityDelay = 15000,
maxWalletsCount = 20,
isSettingAccessCodeAllowed = true,
isSettingPasscodeAllowed = false,
isResettingUserCodesAllowed = true,
isLinkedTerminalEnabled = true,
isBackupAllowed = true,
supportedEncryptionModes = listOf(EncryptionMode.Strong, EncryptionMode.Fast, EncryptionMode.None),
isFilesAllowed = true,
isHDWalletAllowed = true,
isKeysImportAllowed = true,
),
userSettings = CardDTO.UserSettings(isUserCodeRecoveryAllowed = true),
linkedTerminalStatus = CardDTO.LinkedTerminalStatus.None,
isAccessCodeSet = true,
isPasscodeSet = false,
supportedCurves = listOf(
EllipticCurve.Secp256k1,
EllipticCurve.Ed25519,
EllipticCurve.Secp256r1,
EllipticCurve.Bls12381G2,
EllipticCurve.Bls12381G2Aug,
EllipticCurve.Bls12381G2Pop,
EllipticCurve.Bip0340,
),
wallets = listOf(
CardDTO.Wallet(
publicKey = byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
chainCode = byteArrayOf(74, -90, -85, -117, -116, -78, 98, 63, 83, 12, 43, -69, 43, -54, -119, -62, 80, 107, -127, 53, 73, 108, 114, -102, 81, -123, 68, 92, 65, -25, 107, 86),
curve = EllipticCurve.Secp256k1,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
remainingSignatures = null,
index = 0,
hasBackup = false,
derivedKeys = mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
),
DerivationPath("m/44'/1'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
),
DerivationPath("m/44'/195'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
),
),
extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
chainCode = byteArrayOf(80, 13, -8, -108, -35, 116, -92, 125, -65, -28, 85, 72, -113, 59, 83, 13, 5, -83, -102, 123, 124, -22, 94, 108, -71, 95, 65, -2, 38, 38, -108, 14),
),
isImported = false,
),
CardDTO.Wallet(
publicKey = byteArrayOf(-123, -48, -77, -113, -63, -124, -18, 36, -14, -127, 104, 89, 48, 103, 69, -12, 107, -103, 64, -2, 97, 126, -78, -99, -9, -72, 94, -68, 30, 43, 38, 42),
chainCode = byteArrayOf(104, 109, 56, -52, 125, -119, -49, -51, -46, -122, -111, 75, 51, 103, 15, 25, -101, 72, -101, 101, -128, -2, -51, 3, 74, 62, -49, -6, -95, 91, -104, -58),
curve = EllipticCurve.Ed25519,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
remainingSignatures = null,
index = 1,
hasBackup = false,
derivedKeys = emptyMap(),
extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(-65, -53, -62, -12, -57, -32, -38, -9, -128, -52, -83, -61, 73, 39, 41, 15, -74, -97, 38, 52, -101, 63, 74, -56, -20, 15, 57, -127, 114, -93, -17, -109),
chainCode = byteArrayOf(-81, 15, 125, 28, -115, -22, 87, 81, 87, -123, -25, -74, 86, 2, 1, 110, -115, 65, -110, 63, -64, 83, -93, -97, -104, 123, 12, -26, 94, 27, 84, -6),
),
isImported = false,
),
),
attestation = Attestation(
cardKeyAttestation = Attestation.Status.Verified,
walletKeysAttestation = Attestation.Status.Skipped,
firmwareAttestation = Attestation.Status.Skipped,
cardUniquenessAttestation = Attestation.Status.Skipped,
),
backupStatus = CardDTO.BackupStatus.NoBackup,
)
override val scanResponse = ScanResponse(
card = cardDto,
productType = ProductType.Wallet,
walletData = null,
secondTwinPublicKey = null,
derivedKeys = emptyMap(),
primaryCard = null,
)
override val derivationTaskResponse = DerivationTaskResponse(
entries = mapOf(
ByteArrayKey(
byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/84'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/145'/0'/0/0") to ExtendedPublicKey( // bch
publicKey = byteArrayOf(2, 38, -6, 92, -37, -91, -59, -108, -18, -119, -55, 41, 38, -33, 44, 59, 24, -79, -14, -38, -10, -123, 106, 56, 39, 8, 112, 29, -41, 99, 70, -104, -121),
chainCode = byteArrayOf(105, -21, -61, -50, 68, -89, 119, 53, -96, -40, 119, 77, -122, 121, 16, 40, -50, -48, -105, -101, -74, -7, -94, -59, -90, 96, 59, 99, 43, -91, 115, -29),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/3'/0'/0/0") to ExtendedPublicKey( // doge
publicKey = byteArrayOf(3, -25, -24, -97, -124, 24, -89, 44, 75, 123, 92, -86, -73, -93, 25, -90, -89, -95, 88, 3, 107, 37, -1, -85, -32, -57, -123, -41, 108, -9, -96, 77, -124),
chainCode = byteArrayOf(119, 3, 41, 112, 71, 54, 72, 30, 39, 25, 25, -104, 92, 46, -109, 63, 93, 67, 43, -102, -87, 39, -95, 106, 45, 67, 109, -29, -35, 10, -107, 104),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/195'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
)
override val extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(3, 2, 95, 53, 40, -87, -60, 11, -8, -47, 41, 37, 100, 15, -69, 1, -122, 127, -20, -81, -32, -20, -24, 5, -28, 113, 106, -90, -59, -30, -27, -110, -110),
chainCode = byteArrayOf(-95, -87, -95, -25, 27, 96, -57, -92, -69, -106, -45, 10, 85, 4, -92, -68, 49, -24, -28, -50, -49, -77, -20, 118, -50, -27, 104, -93, 115, -50, -46, -34),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
)
override val successResponse = SuccessResponse(cardId = "AF02010000000002")
override val createProductWalletTaskResponse = CreateProductWalletTaskResponse(
card = cardDto,
derivedKeys = mapOf(
ByteArrayKey(
byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
primaryCard = primaryCard,
)
override val importWalletResponse: CreateProductWalletTaskResponse
get() = error("Available only for Wallet 2")
override val createFirstTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val createSecondTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val finalizeTwinResponse: ScanResponse
get() = error("Available only for Twin")
}

View file

@ -0,0 +1,223 @@
package com.tangem.tap.domain.sdk.mocks.content
import com.tangem.common.SuccessResponse
import com.tangem.common.card.Card
import com.tangem.common.card.EllipticCurve
import com.tangem.common.card.EncryptionMode
import com.tangem.common.card.FirmwareVersion
import com.tangem.common.extensions.ByteArrayKey
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.operations.attestation.Attestation
import com.tangem.operations.backup.PrimaryCard
import com.tangem.operations.derivation.DerivationTaskResponse
import com.tangem.operations.derivation.ExtendedPublicKeysMap
import com.tangem.operations.wallet.CreateWalletResponse
import com.tangem.sdk.api.CreateProductWalletTaskResponse
import com.tangem.tap.domain.sdk.mocks.MockContent
import java.util.Date
object ShibaNoBackupNoWalletsMockContent : MockContent {
private val primaryCard = PrimaryCard(
cardId = "AF02010000000002",
batchId = "AF02",
cardPublicKey = byteArrayOf(2, 48, 4, 54, -34, -33, 22, 53, -92, 8, 72, 50, 69, 1, 105, -53, 9, -126, -23, -61, -62, -85, -24, -112, -32, 76, -88, -66, -25, -83, -70, -95, 90),
linkingKey = byteArrayOf(
2, 121, 98, 127, -70, 14, 5, -23, -76, 115, -30, -26, 111, 17, 110, 34, -100, -121,
-57, -123, 74, 3, -91, 56, -20, 56, 50, -40, -101, 96, 82, 70, -91,
),
existingWalletsCount = 3, isHDWalletAllowed = true,
issuer = Card.Issuer(
name = "TANGEM SDK",
publicKey = byteArrayOf(2, 95, 22, -67, 29, 46, -81, -28, 99, -26, 42, 51, 90, 9, -26, -78, -69, -53, -48, 68, 82, 82, 104, -123, -53, 103, -97, -60, -46, 122, -15, -67, 34),
),
manufacturer = Card.Manufacturer(
name = "TANGEM",
manufactureDate = Date(1743759687),
signature = byteArrayOf(44, 8, 116, 111, -57, 20, -93, 101, -104, 97, -104, -15, 58, -8, 41, -53, 95, 99, 107, 47, -29, -118, 41, 64, 22, 94, 33, -81, 114, -47, 10, -16, 97, 14, 94, -36, -82, -108, 74, -9, 35, -38, 66, 67, -116, -55, 65, -30, -58, -33, 31, 120, -45, 42, -3, -120, -74, -97, 97, -102, -13, -28, 29, -41),
),
walletCurves = listOf(EllipticCurve.Secp256k1, EllipticCurve.Ed25519, EllipticCurve.Bls12381G2Aug),
firmwareVersion = FirmwareVersion(
major = 6,
minor = 21,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
isKeysImportAllowed = false,
certificate = null,
)
override val cardDto = CardDTO(
cardId = "AF02010000000002",
batchId = "AF02",
cardPublicKey = byteArrayOf(2, 48, 4, 54, -34, -33, 22, 53, -92, 8, 72, 50, 69, 1, 105, -53, 9, -126, -23, -61, -62, -85, -24, -112, -32, 76, -88, -66, -25, -83, -70, -95, 90),
firmwareVersion = CardDTO.FirmwareVersion(
major = 6,
minor = 21,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
manufacturer = CardDTO.Manufacturer(
name = "TANGEM SDK",
manufactureDate = Date(1649635200000),
signature = byteArrayOf(-20, 98, -101, 94, -23, 73, 122, -21, 74, 76, 79, -55, -102, -62, -30, 44, -38, 118, 75, 121, -36, 118, -62, 60, -38, -63, 33, -14, -98, -69, 112, 22, 48, -43, 47, 65, -61, -56, 38, -94, -45, 44, 95, -22, 6, -31, -40, -25, 42, 38, 94, -99, 71, 98, -33, 27, -102, 30, 52, -7, 51, -27, 84, 66),
),
issuer = CardDTO.Issuer(
name = "TANGEM",
publicKey = byteArrayOf(3, 86, -25, -61, 55, 99, 41, -33, -82, 115, -120, -33, 22, -107, 103, 3, -122, 16, 60, -110, 72, 106, -121, 100, 79, -87, -27, 18, -55, -49, 78, -110, -2),
),
settings = CardDTO.Settings(
securityDelay = 15000,
maxWalletsCount = 20,
isSettingAccessCodeAllowed = true,
isSettingPasscodeAllowed = false,
isResettingUserCodesAllowed = true,
isLinkedTerminalEnabled = true,
isBackupAllowed = true,
supportedEncryptionModes = listOf(EncryptionMode.Strong, EncryptionMode.Fast, EncryptionMode.None),
isFilesAllowed = true,
isHDWalletAllowed = true,
isKeysImportAllowed = true,
),
userSettings = CardDTO.UserSettings(isUserCodeRecoveryAllowed = true),
linkedTerminalStatus = CardDTO.LinkedTerminalStatus.None,
isAccessCodeSet = true,
isPasscodeSet = false,
supportedCurves = listOf(
EllipticCurve.Secp256k1,
EllipticCurve.Ed25519,
EllipticCurve.Secp256r1,
EllipticCurve.Bls12381G2,
EllipticCurve.Bls12381G2Aug,
EllipticCurve.Bls12381G2Pop,
EllipticCurve.Bip0340,
),
wallets = emptyList(),
attestation = Attestation(
cardKeyAttestation = Attestation.Status.Verified,
walletKeysAttestation = Attestation.Status.Skipped,
firmwareAttestation = Attestation.Status.Skipped,
cardUniquenessAttestation = Attestation.Status.Skipped,
),
backupStatus = CardDTO.BackupStatus.NoBackup,
)
override val scanResponse = ScanResponse(
card = cardDto,
productType = ProductType.Wallet,
walletData = null,
secondTwinPublicKey = null,
derivedKeys = emptyMap(),
primaryCard = null,
)
override val derivationTaskResponse = DerivationTaskResponse(
entries = mapOf(
ByteArrayKey(
byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/84'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/145'/0'/0/0") to ExtendedPublicKey( // bch
publicKey = byteArrayOf(2, 38, -6, 92, -37, -91, -59, -108, -18, -119, -55, 41, 38, -33, 44, 59, 24, -79, -14, -38, -10, -123, 106, 56, 39, 8, 112, 29, -41, 99, 70, -104, -121),
chainCode = byteArrayOf(105, -21, -61, -50, 68, -89, 119, 53, -96, -40, 119, 77, -122, 121, 16, 40, -50, -48, -105, -101, -74, -7, -94, -59, -90, 96, 59, 99, 43, -91, 115, -29),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/3'/0'/0/0") to ExtendedPublicKey( // doge
publicKey = byteArrayOf(3, -25, -24, -97, -124, 24, -89, 44, 75, 123, 92, -86, -73, -93, 25, -90, -89, -95, 88, 3, 107, 37, -1, -85, -32, -57, -123, -41, 108, -9, -96, 77, -124),
chainCode = byteArrayOf(119, 3, 41, 112, 71, 54, 72, 30, 39, 25, 25, -104, 92, 46, -109, 63, 93, 67, 43, -102, -87, 39, -95, 106, 45, 67, 109, -29, -35, 10, -107, 104),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/195'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
)
override val extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(3, 2, 95, 53, 40, -87, -60, 11, -8, -47, 41, 37, 100, 15, -69, 1, -122, 127, -20, -81, -32, -20, -24, 5, -28, 113, 106, -90, -59, -30, -27, -110, -110),
chainCode = byteArrayOf(-95, -87, -95, -25, 27, 96, -57, -92, -69, -106, -45, 10, 85, 4, -92, -68, 49, -24, -28, -50, -49, -77, -20, 118, -50, -27, 104, -93, 115, -50, -46, -34),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
)
override val successResponse = SuccessResponse(cardId = "AF02010000000002")
override val createProductWalletTaskResponse = CreateProductWalletTaskResponse(
card = cardDto,
derivedKeys = mapOf(
ByteArrayKey(
byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
primaryCard = primaryCard,
)
override val importWalletResponse: CreateProductWalletTaskResponse
get() = error("Available only for Wallet 2")
override val createFirstTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val createSecondTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val finalizeTwinResponse: ScanResponse
get() = error("Available only for Twin")
}

View file

@ -0,0 +1,208 @@
package com.tangem.tap.domain.sdk.mocks.content
import com.tangem.common.SuccessResponse
import com.tangem.common.card.*
import com.tangem.common.extensions.ByteArrayKey
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.operations.attestation.Attestation
import com.tangem.operations.backup.PrimaryCard
import com.tangem.operations.derivation.DerivationTaskResponse
import com.tangem.operations.derivation.ExtendedPublicKeysMap
import com.tangem.operations.wallet.CreateWalletResponse
import com.tangem.sdk.api.CreateProductWalletTaskResponse
import com.tangem.tap.domain.sdk.mocks.MockContent
import java.util.Date
object TwinsMockContent : MockContent {
private val primaryCard = PrimaryCard(
cardId = "CB64000000015006",
batchId = "CB64",
cardPublicKey = byteArrayOf(4, -122, 60, 93, 121, 108, 26, 78, -33, 36, 112, 61, -4, 108, 82, 6, 47, -50, 109, 37, -109, 58, -102, 3, 50, 127, -123, -68, -96, 18, -78, 56, -50, 102, -112, 51, -25, 96, -69, 97, 31, 35, -68, 22, 38, 61, 60, -97, -69, -51, -62, -37, -63, 91, 127, -103, 103, -39, 85, 85, 85, 92, -70, -58, 109),
linkingKey = byteArrayOf(
2, 121, 98, 127, -70, 14, 5, -23, -76, 115, -30, -26, 111, 17, 110, 34, -100, -121,
-57, -123, 74, 3, -91, 56, -20, 56, 50, -40, -101, 96, 82, 70, -91,
),
existingWalletsCount = 3, isHDWalletAllowed = false,
issuer = Card.Issuer(
name = "TANGEM SDK",
publicKey = byteArrayOf(4, 95, 22, -67, 29, 46, -81, -28, 99, -26, 42, 51, 90, 9, -26, -78, -69, -53, -48, 68, 82, 82, 104, -123, -53, 103, -97, -60, -46, 122, -15, -67, 34, -11, 83, -57, -34, -17, -75, 79, -45, -44, -13, 97, -47, 78, 109, -61, -15, 27, 125, 78, -95, -125, 37, 10, 96, 114, 14, -67, -7, -31, 16, -51, 38),
),
manufacturer = Card.Manufacturer(
name = "TANGEM",
manufactureDate = Date(1743759687),
signature = byteArrayOf(89, -15, -31, 86, 117, 59, -27, -111, 33, 23, -44, 15, -55, -46, -52, 63, 66, 41, -73, -22, 4, -26, 96, -33, -91, 28, 111, 55, -105, -83, -19, -10, 39, -88, 47, 60, 41, -71, 81, 50, -1, -121, 86, -48, -93, 103, -42, 12, -3, -126, -47, -79, 44, 115, 126, 8, -63, 10, 77, 2, 107, -87, -54, -65),
),
walletCurves = listOf(EllipticCurve.Secp256k1, EllipticCurve.Ed25519, EllipticCurve.Bls12381G2Aug),
firmwareVersion = FirmwareVersion(
major = 3,
minor = 38,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
isKeysImportAllowed = false,
certificate = null,
)
override val cardDto = CardDTO(
cardId = "CB64000000015006",
batchId = "CB64",
cardPublicKey = byteArrayOf(2, 48, 4, 54, -34, -33, 22, 53, -92, 8, 72, 50, 69, 1, 105, -53, 9, -126, -23, -61, -62, -85, -24, -112, -32, 76, -88, -66, -25, -83, -70, -95, 90),
firmwareVersion = CardDTO.FirmwareVersion(
major = 3,
minor = 38,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
manufacturer = CardDTO.Manufacturer(
name = "TANGEM",
manufactureDate = Date(1649635200000),
signature = byteArrayOf(89, -15, -31, 86, 117, 59, -27, -111, 33, 23, -44, 15, -55, -46, -52, 63, 66, 41, -73, -22, 4, -26, 96, -33, -91, 28, 111, 55, -105, -83, -19, -10, 39, -88, 47, 60, 41, -71, 81, 50, -1, -121, 86, -48, -93, 103, -42, 12, -3, -126, -47, -79, 44, 115, 126, 8, -63, 10, 77, 2, 107, -87, -54, -65),
),
issuer = CardDTO.Issuer(
name = "TANGEM SDK",
publicKey = byteArrayOf(4, 95, 22, -67, 29, 46, -81, -28, 99, -26, 42, 51, 90, 9, -26, -78, -69, -53, -48, 68, 82, 82, 104, -123, -53, 103, -97, -60, -46, 122, -15, -67, 34, -11, 83, -57, -34, -17, -75, 79, -45, -44, -13, 97, -47, 78, 109, -61, -15, 27, 125, 78, -95, -125, 37, 10, 96, 114, 14, -67, -7, -31, 16, -51, 38),
),
settings = CardDTO.Settings(
securityDelay = 15000,
maxWalletsCount = 1,
isSettingAccessCodeAllowed = true,
isSettingPasscodeAllowed = true,
isResettingUserCodesAllowed = true,
isLinkedTerminalEnabled = true,
isBackupAllowed = false,
supportedEncryptionModes = listOf(EncryptionMode.Strong, EncryptionMode.Fast, EncryptionMode.None),
isFilesAllowed = true,
isHDWalletAllowed = false,
isKeysImportAllowed = false,
),
userSettings = CardDTO.UserSettings(isUserCodeRecoveryAllowed = false),
linkedTerminalStatus = CardDTO.LinkedTerminalStatus.None,
isAccessCodeSet = false,
isPasscodeSet = null,
supportedCurves = listOf(
EllipticCurve.Secp256k1,
),
wallets = listOf(
CardDTO.Wallet(
publicKey = byteArrayOf(4, 42, -7, -17, 16, -16, -85, 8, 70, 36, -114, 18, 45, -126, 101, -89, 22, 96, 53, -107, 61, -109, -118, 83, 116, 100, -79, -90, 119, 123, -67, 23, -76, -49, -124, 71, 61, -50, -91, -18, -100, -34, 93, -48, 36, -82, -28, 45, 125, -3, 56, 8, 68, -40, 40, -34, -112, -67, -43, 35, 84, -106, 20, 62, -79),
chainCode = null,
curve = EllipticCurve.Secp256k1,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 1,
remainingSignatures = 999999,
index = 0,
hasBackup = false,
derivedKeys = emptyMap(),
extendedPublicKey = null,
isImported = false,
),
),
attestation = Attestation(
cardKeyAttestation = Attestation.Status.Verified,
walletKeysAttestation = Attestation.Status.Skipped,
firmwareAttestation = Attestation.Status.Skipped,
cardUniquenessAttestation = Attestation.Status.Skipped,
),
backupStatus = null,
)
override val scanResponse = ScanResponse(
card = cardDto,
productType = ProductType.Twins,
walletData = WalletData(
blockchain = "BTC",
token = null,
),
secondTwinPublicKey = "041535EF77F57A7E7C1541858E5BD3C096A81CEB39FCC72FB9354BBC55FEF86B3C2D5A44750FABE59D268BEC0CB1BAC854A7678F48A26BD355CE39FE197457E2FF",
derivedKeys = emptyMap(),
primaryCard = null,
)
override val derivationTaskResponse = DerivationTaskResponse(
entries = mapOf(
ByteArrayKey(
byteArrayOf(2, -74, 50, 45, -105, 119, 115, 87, -7, -110, 33, 10, -41, -9, -41, 1, 63, -73, 31, -77, 86, 66, -47, -31, 16, 32, 63, 122, 87, 94, 41, 68, 125),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
)
override val extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(3, 2, 95, 53, 40, -87, -60, 11, -8, -47, 41, 37, 100, 15, -69, 1, -122, 127, -20, -81, -32, -20, -24, 5, -28, 113, 106, -90, -59, -30, -27, -110, -110),
chainCode = byteArrayOf(-95, -87, -95, -25, 27, 96, -57, -92, -69, -106, -45, 10, 85, 4, -92, -68, 49, -24, -28, -50, -49, -77, -20, 118, -50, -27, 104, -93, 115, -50, -46, -34),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
)
override val successResponse = SuccessResponse(cardId = "CB61000000001264")
override val createProductWalletTaskResponse = CreateProductWalletTaskResponse(
card = cardDto,
derivedKeys = emptyMap(),
primaryCard = primaryCard,
)
override val importWalletResponse: CreateProductWalletTaskResponse
get() = error("Available only for Wallet 2")
override val createFirstTwinResponse: CreateWalletResponse = CreateWalletResponse(
cardId = "CB64000000015006",
wallet = CardWallet(
publicKey = byteArrayOf(4, 42, -7, -17, 16, -16, -85, 8, 70, 36, -114, 18, 45, -126, 101, -89, 22, 96, 53, -107, 61, -109, -118, 83, 116, 100, -79, -90, 119, 123, -67, 23, -76, -49, -124, 71, 61, -50, -91, -18, -100, -34, 93, -48, 36, -82, -28, 45, 125, -3, 56, 8, 68, -40, 40, -34, -112, -67, -43, 35, 84, -106, 20, 62, -79),
chainCode = null,
curve = EllipticCurve.Secp256k1,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 1,
remainingSignatures = 999999,
index = 0,
isImported = false,
hasBackup = false,
derivedKeys = emptyMap(),
),
)
override val createSecondTwinResponse: CreateWalletResponse = CreateWalletResponse(
cardId = "CB65000000015005",
wallet = CardWallet(
publicKey = byteArrayOf(4, 21, 53, -17, 119, -11, 122, 126, 124, 21, 65, -123, -114, 91, -45, -64, -106, -88, 28, -21, 57, -4, -57, 47, -71, 53, 75, -68, 85, -2, -8, 107, 60, 45, 90, 68, 117, 15, -85, -27, -99, 38, -117, -20, 12, -79, -70, -56, 84, -89, 103, -113, 72, -94, 107, -45, 85, -50, 57, -2, 25, 116, 87, -30, -1),
chainCode = null,
curve = EllipticCurve.Secp256k1,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 1,
remainingSignatures = 999999,
index = 0,
isImported = false,
hasBackup = false,
derivedKeys = emptyMap(),
),
)
override val finalizeTwinResponse: ScanResponse = ScanResponse(
card = cardDto,
productType = ProductType.Twins,
walletData = WalletData(
blockchain = "BTC",
token = null,
),
secondTwinPublicKey = "041535EF77F57A7E7C1541858E5BD3C096A81CEB39FCC72FB9354BBC55FEF86B3C2D5A44750FABE59D268BEC0CB1BAC854A7678F48A26BD355CE39FE197457E2FF",
derivedKeys = emptyMap(),
primaryCard = primaryCard,
)
}

View file

@ -20,20 +20,20 @@ import java.util.Date
object Wallet2MockContent : MockContent {
private val primaryCard = PrimaryCard(
cardId = "AF10000000981426",
batchId = "AF10",
cardPublicKey = byteArrayOf(3, 7, 80, -118, 6, 77, -15, -22, 107, 105, -64, 103, 77, -79, -102, 106, 46, 84, 21, -34, 47, -74, -56, 124, 17, -49, -29, 76, 84, 59, 50, -15, -52),
cardId = "AF05888888880018",
batchId = "AF05",
cardPublicKey = byteArrayOf(3, 23, -112, -57, 109, 60, -82, -36, 45, -14, -34, -12, 10, -89, 14, 37, 38, 36, -102, 37, 93, 90, 69, -113, -117, 120, -29, 12, -125, 43, -40, -31, 5),
linkingKey = byteArrayOf( //
2, 121, 98, 127, -70, 14, 5, -23, -76, 115, -30, -26, 111, 17, 110, 34, -100, -121,
-57, -123, 74, 3, -91, 56, -20, 56, 50, -40, -101, 96, 82, 70, -91,
),
existingWalletsCount = 5, isHDWalletAllowed = true,
issuer = Card.Issuer(
name = "TANGEM 2.0",
publicKey = byteArrayOf(2, -120, 89, -52, -60, 36, -73, -17, 103, 107, -110, -36, 3, 110, -122, 72, 43, -38, 8, 30, -50, 25, -23, -17, 38, 94, 5, -112, -20, 9, 54, -24, -32),
name = "TANGEM SDK",
publicKey = byteArrayOf(2, 95, 22, -67, 29, 46, -81, -28, 99, -26, 42, 51, 90, 9, -26, -78, -69, -53, -48, 68, 82, 82, 104, -123, -53, 103, -97, -60, -46, 122, -15, -67, 34),
),
manufacturer = Card.Manufacturer(
name = "TANGEM SDK",
name = "TANGEM",
manufactureDate = Date(1743759687),
signature = byteArrayOf(),
),
@ -58,9 +58,9 @@ object Wallet2MockContent : MockContent {
)
override val cardDto = CardDTO(
cardId = "AF10000000981426",
batchId = "AF10",
cardPublicKey = byteArrayOf(3, 7, 80, -118, 6, 77, -15, -22, 107, 105, -64, 103, 77, -79, -102, 106, 46, 84, 21, -34, 47, -74, -56, 124, 17, -49, -29, 76, 84, 59, 50, -15, -52),
cardId = "AF05888888880018",
batchId = "AF05",
cardPublicKey = byteArrayOf(3, 23, -112, -57, 109, 60, -82, -36, 45, -14, -34, -12, 10, -89, 14, 37, 38, 36, -102, 37, 93, 90, 69, -113, -117, 120, -29, 12, -125, 43, -40, -31, 5),
firmwareVersion = CardDTO.FirmwareVersion(
major = 6,
minor = 33,
@ -70,11 +70,11 @@ object Wallet2MockContent : MockContent {
manufacturer = CardDTO.Manufacturer(
name = "TANGEM",
manufactureDate = Date(1698094800000),
signature = byteArrayOf(71, -20, 9, 31, 25, 111, 61, 119, 109, -123, -63, 51, 58, -71, -44, 53, 57, 20, -16, 97, -87, -82, 1, -35, -48, 63, 77, -78, -89, -112, -27, 25, -10, 90, 7, -53, -84, -125, 112, 68, -14, -85, -100, -64, -115, 31, 42, 119, 87, -79, 127, 42, -87, -102, 13, -9, -10, -51, -29, -63, -1, -52, -117, 57),
signature = byteArrayOf(51, -12, 14, -56, 7, -39, 5, 63, 59, 24, 102, 99, -126, 124, -127, -108, -118, 71, -19, -71, 4, -47, -121, -46, 49, -51, -31, 100, -56, -15, 96, -37, 25, 82, 94, -88, 48, 98, -105, -97, -40, 41, 27, 116, 65, 26, 78, -85, 66, -94, -92, 15, 50, -2, 7, -69, 41, 56, -75, 59, 86, 68, -38, -3),
),
issuer = CardDTO.Issuer(
name = "TANGEM 2.0",
publicKey = byteArrayOf(2, -120, 89, -52, -60, 36, -73, -17, 103, 107, -110, -36, 3, 110, -122, 72, 43, -38, 8, 30, -50, 25, -23, -17, 38, 94, 5, -112, -20, 9, 54, -24, -32),
name = "TANGEM SDK",
publicKey = byteArrayOf(2, 95, 22, -67, 29, 46, -81, -28, 99, -26, 42, 51, 90, 9, -26, -78, -69, -53, -48, 68, 82, 82, 104, -123, -53, 103, -97, -60, -46, 122, -15, -67, 34),
),
settings = CardDTO.Settings(
securityDelay = 15000,
@ -87,7 +87,7 @@ object Wallet2MockContent : MockContent {
supportedEncryptionModes = listOf(EncryptionMode.Strong, EncryptionMode.Fast, EncryptionMode.None),
isFilesAllowed = true,
isHDWalletAllowed = true,
isKeysImportAllowed = false,
isKeysImportAllowed = true,
),
userSettings = CardDTO.UserSettings(isUserCodeRecoveryAllowed = true),
linkedTerminalStatus = CardDTO.LinkedTerminalStatus.None,
@ -105,11 +105,11 @@ object Wallet2MockContent : MockContent {
),
wallets = listOf(
CardDTO.Wallet(
publicKey = byteArrayOf(2, -114, -64, 120, -121, 11, -28, 89, -91, 114, 10, 84, -87, -36, 36, 19, -69, 95, 66, 14, 32, -35, -99, -67, 118, 51, 26, 71, -78, -36, 59, -126, -58),
chainCode = byteArrayOf(-47, -8, 74, 69, -1, 52, 10, -56, -85, 118, 56, 77, 125, -12, 85, -23, 42, -58, 99, 47, -87, -34, -83, 72, -122, -29, 88, -85, 46, -118, -26, 116),
publicKey = byteArrayOf(3, 17, 59, -102, -56, 66, 10, 36, 97, -106, -92, -117, -105, -88, -2, -3, -95, -75, -54, -2, 57, 27, -90, -19, 82, 103, -12, -52, -126, -105, -120, -55, -2),
chainCode = byteArrayOf(-34, -28, -28, -12, 80, -109, -90, -31, -74, 36, -78, -21, 39, -125, -39, -91, 63, 40, -26, 3, 66, 27, -62, -55, -97, 52, -65, -11, 26, -80, 33, -45),
curve = EllipticCurve.Secp256k1,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 73,
totalSignedHashes = 0,
remainingSignatures = null,
index = 0,
hasBackup = true,
@ -128,14 +128,14 @@ object Wallet2MockContent : MockContent {
),
),
extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(2, -114, -64, 120, -121, 11, -28, 89, -91, 114, 10, 84, -87, -36, 36, 19, -69, 95, 66, 14, 32, -35, -99, -67, 118, 51, 26, 71, -78, -36, 59, -126, -58),
chainCode = byteArrayOf(-47, -8, 74, 69, -1, 52, 10, -56, -85, 118, 56, 77, 125, -12, 85, -23, 42, -58, 99, 47, -87, -34, -83, 72, -122, -29, 88, -85, 46, -118, -26, 116),
publicKey = byteArrayOf(-109, 42, -80, -115, -12, 44, 48, -118, -89, 10, 21, 59, 98, -110, -86, -14, 123, 105, -30, -49, -40, -4, -7, 32, 60, 67, -88, -52, -96, -10, -14, 123),
chainCode = byteArrayOf(-101, -10, -92, 72, 19, 121, -38, 105, -55, -82, -68, 13, -6, 17, 66, -10, -75, 58, 119, -127, 74, 68, 82, 25, 45, -110, 3, 3, 108, -97, -51, -127),
),
isImported = false,
),
CardDTO.Wallet(
publicKey = byteArrayOf(-64, 18, -128, 121, -89, -37, -99, 44, -125, -72, -111, -79, 7, 85, 40, 67, -39, 117, 123, 11, 105, -6, -5, -79, 19, -10, -29, 20, -14, -40, 5, 90),
chainCode = byteArrayOf(33, -97, 53, -112, 61, 112, -24, 74, -87, -85, -124, -4, 103, -94, -97, 76, -41, -27, 118, 33, 55, 121, -17, -52, 60, 122, 27, 25, 29, -76, 78, 11),
publicKey = byteArrayOf(-109, 42, -80, -115, -12, 44, 48, -118, -89, 10, 21, 59, 98, -110, -86, -14, 123, 105, -30, -49, -40, -4, -7, 32, 60, 67, -88, -52, -96, -10, -14, 123),
chainCode = byteArrayOf(-101, -10, -92, 72, 19, 121, -38, 105, -55, -82, -68, 13, -6, 17, 66, -10, -75, 58, 119, -127, 74, 68, 82, 25, 45, -110, 3, 3, 108, -97, -51, -127),
curve = EllipticCurve.Ed25519,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
@ -150,7 +150,7 @@ object Wallet2MockContent : MockContent {
isImported = false,
),
CardDTO.Wallet(
publicKey = byteArrayOf(-94, 111, -89, -77, -62, -113, 16, -118, -46, -16, -20, 28, 53, -82, -109, 28, 99, -98, -54, 59, -3, 99, 16, -70, -73, 43, -6, 33, -53, -66, 76, -72, 6, -49, 83, -121, -122, 111, -111, -116, -119, 98, -94, -98, -121, -37, 20, -95),
publicKey = byteArrayOf(-118, -77, -109, 8, -119, 101, -91, 46, -44, 15, 52, -64, -92, 5, -102, 126, 52, 121, 63, -76, -54, 80, -82, -5, 31, -35, 105, -119, -96, -54, 38, 2, -6, 109, 117, -26, -47, -20, 108, 106, -69, 72, -37, -117, -30, -9, 104, -123),
chainCode = null,
curve = EllipticCurve.Bls12381G2Aug,
settings = CardWallet.Settings(isPermanent = false),
@ -163,8 +163,8 @@ object Wallet2MockContent : MockContent {
isImported = false,
),
CardDTO.Wallet(
publicKey = byteArrayOf(115, 14, 11, 0, -93, 81, -103, -95, -75, -84, 18, -120, -31, 76, -83, -81, 91, 25, -75, 36, -99, -53, -25, -15, -1, -57, 14, -39, 98, -116, -63, -123),
chainCode = byteArrayOf(23, 5, 38, -48, 67, -42, -31, -21, 89, 11, 22, -28, 44, -19, -115, -78, 123, -27, 57, 57, -24, -86, 55, 15, 104, 114, -36, 80, 81, -108, -41, 112),
publicKey = byteArrayOf(17, -78, 53, 101, 96, -110, -10, -48, -84, 88, -64, 58, -26, -13, -2, -6, -25, 23, -79, -45, 58, 77, 52, -75, -123, 121, 32, 92, 84, -74, -111, -8),
chainCode = byteArrayOf(-110, 73, -124, -65, -1, -70, 64, -89, 95, -74, 15, 46, -110, 87, 15, -61, 120, -51, 111, 111, -45, 37, 123, -114, 65, -116, 21, 39, -77, 86, -3, -26),
curve = EllipticCurve.Bip0340,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
@ -179,11 +179,11 @@ object Wallet2MockContent : MockContent {
isImported = false,
),
CardDTO.Wallet(
publicKey = byteArrayOf(-43, 1, -81, -47, -8, -103, -66, 42, 37, -7, 65, 54, 57, -24, 127, -89, 69, -112, 42, -46, -128, 36, -117, -28, 30, -48, 37, 52, 93, -47, 92, -47),
chainCode = byteArrayOf(4, -97, 81, -37, 76, -67, -87, -4, -82, -36, -45, -28, -117, -59, -62, 93, -73, 50, 65, -91, -83, 25, -95, 89, -64, -40, 113, 28, 59, 113, -99, 89),
publicKey = byteArrayOf(-52, -92, 64, 108, -8, -100, 87, -86, -60, 18, -18, -81, 114, -84, 76, -24, 84, 52, -34, 79, -30, -66, -112, -55, -35, -119, 127, -109, 35, 18, -29, -25),
chainCode = byteArrayOf(94, -33, -94, -63, 40, -20, -26, 71, 111, 9, 87, -36, -42, -33, 40, -53, 85, 31, -36, -29, 65, -121, 2, -23, -119, -51, 114, -17, -39, -74, 23, -97),
curve = EllipticCurve.Ed25519Slip0010,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 15,
totalSignedHashes = 0,
remainingSignatures = null,
index = 4,
hasBackup = true,
@ -219,76 +219,76 @@ object Wallet2MockContent : MockContent {
byteArrayOf(2, -109, 28, -27, -124, -58, -97, -61, 43, -84, 90, -9, -5, 4, 90, 17, 112, -125, -108, 44, 19, -79, -60, -23, 34, -20, -20, 61, 84, 113, 120, -90, -5),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/145'/0'/0/0") to ExtendedPublicKey( // bch
publicKey = byteArrayOf(2, 38, -6, 92, -37, -91, -59, -108, -18, -119, -55, 41, 38, -33, 44, 59, 24, -79, -14, -38, -10, -123, 106, 56, 39, 8, 112, 29, -41, 99, 70, -104, -121),
chainCode = byteArrayOf(105, -21, -61, -50, 68, -89, 119, 53, -96, -40, 119, 77, -122, 121, 16, 40, -50, -48, -105, -101, -74, -7, -94, -59, -90, 96, 59, 99, 43, -91, 115, -29),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/3'/0'/0/0") to ExtendedPublicKey( // doge
publicKey = byteArrayOf(3, -25, -24, -97, -124, 24, -89, 44, 75, 123, 92, -86, -73, -93, 25, -90, -89, -95, 88, 3, 107, 37, -1, -85, -32, -57, -123, -41, 108, -9, -96, 77, -124),
chainCode = byteArrayOf(119, 3, 41, 112, 71, 54, 72, 30, 39, 25, 25, -104, 92, 46, -109, 63, 93, 67, 43, -102, -87, 39, -95, 106, 45, 67, 109, -29, -35, 10, -107, 104),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/145'/0'/0/0") to ExtendedPublicKey( // bch
publicKey = byteArrayOf(2, 38, -6, 92, -37, -91, -59, -108, -18, -119, -55, 41, 38, -33, 44, 59, 24, -79, -14, -38, -10, -123, 106, 56, 39, 8, 112, 29, -41, 99, 70, -104, -121),
chainCode = byteArrayOf(105, -21, -61, -50, 68, -89, 119, 53, -96, -40, 119, 77, -122, 121, 16, 40, -50, -48, -105, -101, -74, -7, -94, -59, -90, 96, 59, 99, 43, -91, 115, -29),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/3'/0'/0/0") to ExtendedPublicKey( // doge
publicKey = byteArrayOf(3, -25, -24, -97, -124, 24, -89, 44, 75, 123, 92, -86, -73, -93, 25, -90, -89, -95, 88, 3, 107, 37, -1, -85, -32, -57, -123, -41, 108, -9, -96, 77, -124),
chainCode = byteArrayOf(119, 3, 41, 112, 71, 54, 72, 30, 39, 25, 25, -104, 92, 46, -109, 63, 93, 67, 43, -102, -87, 39, -95, 106, 45, 67, 109, -29, -35, 10, -107, 104),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
)
override val extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(3, 2, 95, 53, 40, -87, -60, 11, -8, -47, 41, 37, 100, 15, -69, 1, -122, 127, -20, -81, -32, -20, -24, 5, -28, 113, 106, -90, -59, -30, -27, -110, -110),
chainCode = byteArrayOf(-95, -87, -95, -25, 27, 96, -57, -92, -69, -106, -45, 10, 85, 4, -92, -68, 49, -24, -28, -50, -49, -77, -20, 118, -50, -27, 104, -93, 115, -50, -46, -34),
publicKey = byteArrayOf(2, -93, -36, -105, 121, -52, -30, -43, -67, -7, -31, -26, -35, 25, 99, 25, -20, 118, -20, -125, -89, 12, -101, -86, 74, -91, 23, -24, 93, -86, 20, -53, -8),
chainCode = byteArrayOf(32, 60, 63, -96, 97, 58, 121, 108, 75, 59, 63, -113, 60, -49, 47, 33, 15, -65, -69, 45, -7, -26, 65, -5, -91, -55, -42, -102, -127, -104, -111, 96),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
)
override val successResponse = SuccessResponse(cardId = "AF10000000981426")
override val successResponse = SuccessResponse(cardId = "AF05888888880018")
override val createProductWalletTaskResponse = CreateProductWalletTaskResponse(
card = cardDto,
derivedKeys = mapOf(
ByteArrayKey(
byteArrayOf(2, -109, 28, -27, -124, -58, -97, -61, 43, -84, 90, -9, -5, 4, 90, 17, 112, -125, -108, 44, 19, -79, -60, -23, 34, -20, -20, 61, 84, 113, 120, -90, -5),
byteArrayOf(3, 23, -112, -57, 109, 60, -82, -36, 45, -14, -34, -12, 10, -89, 14, 37, 38, 36, -102, 37, 93, 90, 69, -113, -117, 120, -29, 12, -125, 43, -40, -31, 5),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
primaryCard = primaryCard,
)

View file

@ -0,0 +1,307 @@
package com.tangem.tap.domain.sdk.mocks.content
import com.tangem.common.SuccessResponse
import com.tangem.common.card.*
import com.tangem.common.extensions.ByteArrayKey
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.crypto.hdWallet.bip32.ExtendedPublicKey
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.operations.attestation.Attestation
import com.tangem.operations.backup.PrimaryCard
import com.tangem.operations.derivation.DerivationTaskResponse
import com.tangem.operations.derivation.ExtendedPublicKeysMap
import com.tangem.operations.wallet.CreateWalletResponse
import com.tangem.sdk.api.CreateProductWalletTaskResponse
import com.tangem.tap.domain.sdk.mocks.MockContent
import java.util.Date
object Wallet2NoBackupMockContent : MockContent {
private val primaryCard = PrimaryCard(
cardId = "AF05888888880018",
batchId = "AF05",
cardPublicKey = byteArrayOf(3, 23, -112, -57, 109, 60, -82, -36, 45, -14, -34, -12, 10, -89, 14, 37, 38, 36, -102, 37, 93, 90, 69, -113, -117, 120, -29, 12, -125, 43, -40, -31, 5),
linkingKey = byteArrayOf( //
2, 121, 98, 127, -70, 14, 5, -23, -76, 115, -30, -26, 111, 17, 110, 34, -100, -121,
-57, -123, 74, 3, -91, 56, -20, 56, 50, -40, -101, 96, 82, 70, -91,
),
existingWalletsCount = 5, isHDWalletAllowed = true,
issuer = Card.Issuer(
name = "TANGEM SDK",
publicKey = byteArrayOf(2, 95, 22, -67, 29, 46, -81, -28, 99, -26, 42, 51, 90, 9, -26, -78, -69, -53, -48, 68, 82, 82, 104, -123, -53, 103, -97, -60, -46, 122, -15, -67, 34),
),
manufacturer = Card.Manufacturer(
name = "TANGEM",
manufactureDate = Date(1743759687),
signature = byteArrayOf(),
),
walletCurves = listOf(
EllipticCurve.Secp256k1,
EllipticCurve.Ed25519,
EllipticCurve.Bls12381G2Aug,
EllipticCurve.Secp256r1,
EllipticCurve.Ed25519Slip0010,
EllipticCurve.Bls12381G2,
EllipticCurve.Bls12381G2Pop,
EllipticCurve.Bip0340,
),
firmwareVersion = FirmwareVersion(
major = 6,
minor = 33,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
isKeysImportAllowed = false,
certificate = null,
)
override val cardDto = CardDTO(
cardId = "AF05888888880018",
batchId = "AF05",
cardPublicKey = byteArrayOf(3, 23, -112, -57, 109, 60, -82, -36, 45, -14, -34, -12, 10, -89, 14, 37, 38, 36, -102, 37, 93, 90, 69, -113, -117, 120, -29, 12, -125, 43, -40, -31, 5),
firmwareVersion = CardDTO.FirmwareVersion(
major = 6,
minor = 33,
patch = 0,
type = FirmwareVersion.FirmwareType.Release,
),
manufacturer = CardDTO.Manufacturer(
name = "TANGEM",
manufactureDate = Date(1698094800000),
signature = byteArrayOf(51, -12, 14, -56, 7, -39, 5, 63, 59, 24, 102, 99, -126, 124, -127, -108, -118, 71, -19, -71, 4, -47, -121, -46, 49, -51, -31, 100, -56, -15, 96, -37, 25, 82, 94, -88, 48, 98, -105, -97, -40, 41, 27, 116, 65, 26, 78, -85, 66, -94, -92, 15, 50, -2, 7, -69, 41, 56, -75, 59, 86, 68, -38, -3),
),
issuer = CardDTO.Issuer(
name = "TANGEM SDK",
publicKey = byteArrayOf(2, 95, 22, -67, 29, 46, -81, -28, 99, -26, 42, 51, 90, 9, -26, -78, -69, -53, -48, 68, 82, 82, 104, -123, -53, 103, -97, -60, -46, 122, -15, -67, 34),
),
settings = CardDTO.Settings(
securityDelay = 15000,
maxWalletsCount = 20,
isSettingAccessCodeAllowed = true,
isSettingPasscodeAllowed = true,
isResettingUserCodesAllowed = false,
isLinkedTerminalEnabled = true,
isBackupAllowed = true,
supportedEncryptionModes = listOf(EncryptionMode.Strong, EncryptionMode.Fast, EncryptionMode.None),
isFilesAllowed = true,
isHDWalletAllowed = true,
isKeysImportAllowed = true,
),
userSettings = CardDTO.UserSettings(isUserCodeRecoveryAllowed = true),
linkedTerminalStatus = CardDTO.LinkedTerminalStatus.None,
isAccessCodeSet = true,
isPasscodeSet = false,
supportedCurves = listOf(
EllipticCurve.Secp256k1,
EllipticCurve.Ed25519,
EllipticCurve.Bls12381G2Aug,
EllipticCurve.Secp256r1,
EllipticCurve.Ed25519Slip0010,
EllipticCurve.Bls12381G2,
EllipticCurve.Bls12381G2Pop,
EllipticCurve.Bip0340,
),
wallets = listOf(
CardDTO.Wallet(
publicKey = byteArrayOf(3, 17, 59, -102, -56, 66, 10, 36, 97, -106, -92, -117, -105, -88, -2, -3, -95, -75, -54, -2, 57, 27, -90, -19, 82, 103, -12, -52, -126, -105, -120, -55, -2),
chainCode = byteArrayOf(-34, -28, -28, -12, 80, -109, -90, -31, -74, 36, -78, -21, 39, -125, -39, -91, 63, 40, -26, 3, 66, 27, -62, -55, -97, 52, -65, -11, 26, -80, 33, -45),
curve = EllipticCurve.Secp256k1,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
remainingSignatures = null,
index = 0,
hasBackup = false,
derivedKeys = mapOf(
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, 55, -114, -94, -73, -61, -50, 51, -115, 55, -79, 63, -96, -44, -64, -24, -36, -122, -123, -38, 81, -15, -127, -97, -42, 72, -85, -62, -98, 46, 119, 16, -55),
chainCode = byteArrayOf(31, 17, 71, -28, -29, 17, 72, -29, -98, 112, 31, -8, 72, -75, 4, -11, 60, -100, 9, 35, 58, -42, -38, 96, -71, -68, 24, -119, -43, -18, -122, 72),
),
DerivationPath("m/84'/0'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -26, 103, 96, 112, 127, -125, 0, 7, 53, 30, -12, -82, 45, 14, 107, -9, 126, 75, 104, -67, -49, 35, -12, -82, -90, 101, -101, 125, -76, 88, -54, 99),
chainCode = byteArrayOf(-42, 36, 97, 65, -64, -113, 76, -91, -9, 11, 89, 123, -9, -3, 21, 103, -113, -60, 48, -31, -34, 108, 111, -38, -110, -80, 109, 17, -29, 2, 45, -71),
),
DerivationPath("m/44'/1'/0'/0/0") to ExtendedPublicKey(
publicKey = byteArrayOf(2, -96, -3, -83, 101, 63, -25, -125, -4, -65, -42, -56, 24, -52, 118, -11, -104, -105, 40, -59, 20, -109, -97, 29, -95, -6, -80, 2, 67, 103, -80, -22, -94),
chainCode = byteArrayOf(-125, 27, -91, 38, -66, 109, -92, 16, -37, 93, 107, -29, -128, -1, 115, -64, 108, -63, 17, 27, 58, 78, -2, 39, 88, -39, 44, 89, 32, -38, -16, -38),
),
),
extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(-109, 42, -80, -115, -12, 44, 48, -118, -89, 10, 21, 59, 98, -110, -86, -14, 123, 105, -30, -49, -40, -4, -7, 32, 60, 67, -88, -52, -96, -10, -14, 123),
chainCode = byteArrayOf(-101, -10, -92, 72, 19, 121, -38, 105, -55, -82, -68, 13, -6, 17, 66, -10, -75, 58, 119, -127, 74, 68, 82, 25, 45, -110, 3, 3, 108, -97, -51, -127),
),
isImported = false,
),
CardDTO.Wallet(
publicKey = byteArrayOf(-109, 42, -80, -115, -12, 44, 48, -118, -89, 10, 21, 59, 98, -110, -86, -14, 123, 105, -30, -49, -40, -4, -7, 32, 60, 67, -88, -52, -96, -10, -14, 123),
chainCode = byteArrayOf(-101, -10, -92, 72, 19, 121, -38, 105, -55, -82, -68, 13, -6, 17, 66, -10, -75, 58, 119, -127, 74, 68, 82, 25, 45, -110, 3, 3, 108, -97, -51, -127),
curve = EllipticCurve.Ed25519,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
remainingSignatures = null,
index = 1,
hasBackup = false,
derivedKeys = emptyMap(),
extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(-64, 18, -128, 121, -89, -37, -99, 44, -125, -72, -111, -79, 7, 85, 40, 67, -39, 117, 123, 11, 105, -6, -5, -79, 19, -10, -29, 20, -14, -40, 5, 90),
chainCode = byteArrayOf(33, -97, 53, -112, 61, 112, -24, 74, -87, -85, -124, -4, 103, -94, -97, 76, -41, -27, 118, 33, 55, 121, -17, -52, 60, 122, 27, 25, 29, -76, 78, 11),
),
isImported = false,
),
CardDTO.Wallet(
publicKey = byteArrayOf(-118, -77, -109, 8, -119, 101, -91, 46, -44, 15, 52, -64, -92, 5, -102, 126, 52, 121, 63, -76, -54, 80, -82, -5, 31, -35, 105, -119, -96, -54, 38, 2, -6, 109, 117, -26, -47, -20, 108, 106, -69, 72, -37, -117, -30, -9, 104, -123),
chainCode = null,
curve = EllipticCurve.Bls12381G2Aug,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 1,
remainingSignatures = null,
index = 2,
hasBackup = false,
derivedKeys = emptyMap(),
extendedPublicKey = null,
isImported = false,
),
CardDTO.Wallet(
publicKey = byteArrayOf(17, -78, 53, 101, 96, -110, -10, -48, -84, 88, -64, 58, -26, -13, -2, -6, -25, 23, -79, -45, 58, 77, 52, -75, -123, 121, 32, 92, 84, -74, -111, -8),
chainCode = byteArrayOf(-110, 73, -124, -65, -1, -70, 64, -89, 95, -74, 15, 46, -110, 87, 15, -61, 120, -51, 111, 111, -45, 37, 123, -114, 65, -116, 21, 39, -77, 86, -3, -26),
curve = EllipticCurve.Bip0340,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
remainingSignatures = null,
index = 3,
hasBackup = false,
derivedKeys = emptyMap(),
extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(115, 14, 11, 0, -93, 81, -103, -95, -75, -84, 18, -120, -31, 76, -83, -81, 91, 25, -75, 36, -99, -53, -25, -15, -1, -57, 14, -39, 98, -116, -63, -123),
chainCode = byteArrayOf(23, 5, 38, -48, 67, -42, -31, -21, 89, 11, 22, -28, 44, -19, -115, -78, 123, -27, 57, 57, -24, -86, 55, 15, 104, 114, -36, 80, 81, -108, -41, 112),
),
isImported = false,
),
CardDTO.Wallet(
publicKey = byteArrayOf(-52, -92, 64, 108, -8, -100, 87, -86, -60, 18, -18, -81, 114, -84, 76, -24, 84, 52, -34, 79, -30, -66, -112, -55, -35, -119, 127, -109, 35, 18, -29, -25),
chainCode = byteArrayOf(94, -33, -94, -63, 40, -20, -26, 71, 111, 9, 87, -36, -42, -33, 40, -53, 85, 31, -36, -29, 65, -121, 2, -23, -119, -51, 114, -17, -39, -74, 23, -97),
curve = EllipticCurve.Ed25519Slip0010,
settings = CardWallet.Settings(isPermanent = false),
totalSignedHashes = 0,
remainingSignatures = null,
index = 4,
hasBackup = false,
derivedKeys = emptyMap(),
extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(-43, 1, -81, -47, -8, -103, -66, 42, 37, -7, 65, 54, 57, -24, 127, -89, 69, -112, 42, -46, -128, 36, -117, -28, 30, -48, 37, 52, 93, -47, 92, -47),
chainCode = byteArrayOf(4, -97, 81, -37, 76, -67, -87, -4, -82, -36, -45, -28, -117, -59, -62, 93, -73, 50, 65, -91, -83, 25, -95, 89, -64, -40, 113, 28, 59, 113, -99, 89),
),
isImported = false,
),
),
attestation = Attestation(
cardKeyAttestation = Attestation.Status.Verified,
walletKeysAttestation = Attestation.Status.Skipped,
firmwareAttestation = Attestation.Status.Skipped,
cardUniquenessAttestation = Attestation.Status.Skipped,
),
backupStatus = CardDTO.BackupStatus.NoBackup,
)
override val scanResponse = ScanResponse(
card = cardDto,
productType = ProductType.Wallet2,
walletData = null,
secondTwinPublicKey = null,
derivedKeys = emptyMap(),
primaryCard = null,
)
override val derivationTaskResponse = DerivationTaskResponse(
entries = mapOf(
ByteArrayKey(
byteArrayOf(2, -109, 28, -27, -124, -58, -97, -61, 43, -84, 90, -9, -5, 4, 90, 17, 112, -125, -108, 44, 19, -79, -60, -23, 34, -20, -20, 61, 84, 113, 120, -90, -5),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/145'/0'/0/0") to ExtendedPublicKey( // bch
publicKey = byteArrayOf(2, 38, -6, 92, -37, -91, -59, -108, -18, -119, -55, 41, 38, -33, 44, 59, 24, -79, -14, -38, -10, -123, 106, 56, 39, 8, 112, 29, -41, 99, 70, -104, -121),
chainCode = byteArrayOf(105, -21, -61, -50, 68, -89, 119, 53, -96, -40, 119, 77, -122, 121, 16, 40, -50, -48, -105, -101, -74, -7, -94, -59, -90, 96, 59, 99, 43, -91, 115, -29),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/3'/0'/0/0") to ExtendedPublicKey( // doge
publicKey = byteArrayOf(3, -25, -24, -97, -124, 24, -89, 44, 75, 123, 92, -86, -73, -93, 25, -90, -89, -95, 88, 3, 107, 37, -1, -85, -32, -57, -123, -41, 108, -9, -96, 77, -124),
chainCode = byteArrayOf(119, 3, 41, 112, 71, 54, 72, 30, 39, 25, 25, -104, 92, 46, -109, 63, 93, 67, 43, -102, -87, 39, -95, 106, 45, 67, 109, -29, -35, 10, -107, 104),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
)
override val extendedPublicKey = ExtendedPublicKey(
publicKey = byteArrayOf(2, -93, -36, -105, 121, -52, -30, -43, -67, -7, -31, -26, -35, 25, 99, 25, -20, 118, -20, -125, -89, 12, -101, -86, 74, -91, 23, -24, 93, -86, 20, -53, -8),
chainCode = byteArrayOf(32, 60, 63, -96, 97, 58, 121, 108, 75, 59, 63, -113, 60, -49, 47, 33, 15, -65, -69, 45, -7, -26, 65, -5, -91, -55, -42, -102, -127, -104, -111, 96),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
)
override val successResponse = SuccessResponse(cardId = "AF05888888880018")
override val createProductWalletTaskResponse = CreateProductWalletTaskResponse(
card = cardDto,
derivedKeys = mapOf(
ByteArrayKey(
byteArrayOf(3, 23, -112, -57, 109, 60, -82, -36, 45, -14, -34, -12, 10, -89, 14, 37, 38, 36, -102, 37, 93, 90, 69, -113, -117, 120, -29, 12, -125, 43, -40, -31, 5),
)
to
ExtendedPublicKeysMap(
mapOf(
DerivationPath("m/44'/0'/0'/0/0") to ExtendedPublicKey( // btc
publicKey = byteArrayOf(3, 45, 58, -110, -52, -51, -83, -4, -45, -118, 119, 37, 123, -17, 66, -83, 61, -106, 115, 47, 121, 66, 84, -122, -57, -45, 7, -79, 70, -13, 28, -125, -52),
chainCode = byteArrayOf(93, 51, 52, -66, -39, -38, 34, -84, 50, 1, -127, -20, 80, -20, -30, -72, 2, 1, -78, -81, -17, 51, -52, -25, 12, 108, 50, 89, -66, 18, 65, 70),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
DerivationPath("m/44'/60'/0'/0/0") to ExtendedPublicKey( // eth
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82, -67),
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
depth = 0,
parentFingerprint = byteArrayOf(0, 0, 0, 0),
childNumber = 0,
),
),
),
),
primaryCard = primaryCard,
)
override val importWalletResponse: CreateProductWalletTaskResponse
get() = TODO("Not yet implemented")
override val createFirstTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val createSecondTwinResponse: CreateWalletResponse
get() = error("Available only for Twin")
override val finalizeTwinResponse: ScanResponse
get() = error("Available only for Twin")
}

Some files were not shown because too many files have changed in this diff Show more