Updated on 2026-08-14
This commit is contained in:
commit
808cd4a301
503 changed files with 12306 additions and 3036 deletions
33
.idea/codeStyles/Project.xml
generated
33
.idea/codeStyles/Project.xml
generated
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -32,6 +33,30 @@ fun BaseTestCase.openMainScreen(
|
|||
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() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,116 @@
|
|||
package com.tangem.scenarios
|
||||
|
||||
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,
|
||||
withTransactions: Boolean = false,
|
||||
withWalletImage: Boolean = true
|
||||
) {
|
||||
step("Assert card title equal '$cardTitle'") {
|
||||
onMainScreen { walletNameText.assertTextEquals(cardTitle) }
|
||||
}
|
||||
if (withTransactions) {
|
||||
step("Assert 'Transactions' block is displayed") {
|
||||
onMainScreen { transactionsExplorerText().assertExists() }
|
||||
}
|
||||
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() }
|
||||
}
|
||||
}
|
||||
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("Assert 'Organize tokens' button is not displayed") {
|
||||
onMainScreen {
|
||||
assertElementDoesNotExist({ organizeTokensButtonWithoutLazySearch() }, "Organize tokens button")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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() }
|
||||
}
|
||||
}
|
||||
|
|
@ -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() }
|
||||
}
|
||||
}
|
||||
|
|
@ -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,6 +78,11 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
|
|||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val walletDevicesCount: KNode = child {
|
||||
hasTestTag(MainScreenTestTags.DEVICES_COUNT)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val marketPriceBlock: KNode = child {
|
||||
hasTestTag(MarketPriceBlockTestTags.BLOCK)
|
||||
useUnmergedTree = true
|
||||
|
|
@ -79,7 +104,7 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
|
|||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun transactionsExplorer(): KNode {
|
||||
fun transactionsExplorerText(): KNode {
|
||||
return child {
|
||||
hasTestTag(TransactionHistoryBlockTestTags.EXPLORER_TEXT)
|
||||
hasText(getResourceString(R.string.common_explorer))
|
||||
|
|
@ -87,6 +112,22 @@ class MainScreenPageObject(semanticsProvider: SemanticsNodeInteractionsProvider)
|
|||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
hasTestTag(NotificationTestTags.CONTAINER)
|
||||
useUnmergedTree = true
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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) =
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
196
app/src/androidTest/kotlin/com/tangem/tests/ScanCardTest.kt
Normal file
196
app/src/androidTest/kotlin/com/tangem/tests/ScanCardTest.kt
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -263,7 +263,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,
|
||||
|
|
@ -370,8 +370,8 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
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)
|
||||
}
|
||||
|
||||
|
|
@ -402,8 +402,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 {
|
||||
|
|
@ -447,9 +447,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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ lateinit var store: Store<AppState>
|
|||
lateinit var 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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 "
|
||||
}
|
||||
}
|
||||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ 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"
|
||||
|
||||
@Singleton
|
||||
internal class DefaultTangemPayStorage @Inject constructor(
|
||||
|
|
@ -54,21 +53,6 @@ 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) =
|
||||
withContext(dispatcherProvider.io) {
|
||||
secureStorage.store(
|
||||
customerWalletAddress.encodeToByteArray(throwOnInvalidSequence = true),
|
||||
DEFAULT_CUSTOMER_WALLET_ADDRESS_KEY,
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getCustomerWalletAddress(): String? = withContext(dispatcherProvider.io) {
|
||||
secureStorage.get(DEFAULT_CUSTOMER_WALLET_ADDRESS_KEY)?.decodeToString(throwOnInvalidSequence = true)
|
||||
}
|
||||
|
||||
override suspend fun clear(customerWalletAddress: String) = withContext(dispatcherProvider.io) {
|
||||
secureStorage.delete(createKey(customerWalletAddress))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import com.tangem.domain.transaction.FeeRepository
|
|||
import com.tangem.domain.transaction.error.FeeErrorResolver
|
||||
import com.tangem.domain.yield.supply.YieldSupplyTransactionRepository
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyEstimateEnterFeeUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetContractAddressUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyStartEarningUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyStopEarningUseCase
|
||||
import dagger.Module
|
||||
|
|
@ -47,4 +48,15 @@ internal object YieldSupplyDomainModule {
|
|||
feeErrorResolver = feeErrorResolver,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideYieldSupplyGetContractAddressUseCase(
|
||||
yieldSupplyTransactionRepository: YieldSupplyTransactionRepository,
|
||||
): YieldSupplyGetContractAddressUseCase {
|
||||
return YieldSupplyGetContractAddressUseCase(
|
||||
yieldSupplyTransactionRepository = yieldSupplyTransactionRepository,
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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>?>> {
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ internal class DefaultResetCardUseCase(
|
|||
null
|
||||
}
|
||||
|
||||
type?.let {
|
||||
if (type != null) {
|
||||
tangemSdkManager.setUserCodeRequestPolicy(policy = UserCodeRequestPolicy.Always(type))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
|
@ -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")
|
||||
}
|
||||
|
|
@ -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")
|
||||
}
|
||||
|
|
@ -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")
|
||||
}
|
||||
|
|
@ -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")
|
||||
}
|
||||
|
|
@ -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")
|
||||
}
|
||||
|
|
@ -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")
|
||||
}
|
||||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
@ -255,20 +255,20 @@ object Wallet2MockContent : MockContent {
|
|||
)
|
||||
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
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 Wallet2NoBackupNoWalletsMockContent : 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 = 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.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")
|
||||
}
|
||||
|
|
@ -42,7 +42,12 @@ class SignHashesTask(
|
|||
is CompletionResult.Failure -> {
|
||||
when {
|
||||
response.error is TangemSdkError.WalletNotFound && pairWalletPublicKey != null -> {
|
||||
sign(session, pairWalletPublicKey, publicKey.derivationPath, callback)
|
||||
sign(
|
||||
session = session,
|
||||
publicKey = pairWalletPublicKey,
|
||||
derivationPath = publicKey.derivationPath,
|
||||
callback = callback,
|
||||
)
|
||||
}
|
||||
else -> callback(CompletionResult.Failure(response.error))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,22 +64,28 @@ class CreateProductWalletTask(
|
|||
cardTypesResolver.isTangemTwins() ->
|
||||
throw UnsupportedOperationException("Use the TwinCardsManager to create a wallet")
|
||||
|
||||
else -> CreateWalletTangemWallet(mnemonic, passphrase, shouldReset, derivationStyleProvider, cardDto)
|
||||
else -> CreateWalletTangemWallet(
|
||||
mnemonic = mnemonic,
|
||||
passphrase = passphrase,
|
||||
shouldReset = shouldReset,
|
||||
derivationStyleProvider = derivationStyleProvider,
|
||||
cardDTO = cardDto,
|
||||
)
|
||||
}
|
||||
commandProcessor.proceed(cardDto, session) {
|
||||
when (it) {
|
||||
commandProcessor.proceed(cardDto, session) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
val result = when (commandProcessor) {
|
||||
val createProductWalletTaskResponse = when (commandProcessor) {
|
||||
is CreateWalletTangemWallet -> {
|
||||
it.data as CreateProductWalletTaskResponse
|
||||
result.data as CreateProductWalletTaskResponse
|
||||
}
|
||||
|
||||
else -> CreateProductWalletTaskResponse(card = session.environment.card!!)
|
||||
else -> CreateProductWalletTaskResponse(card = requireNotNull(session.environment.card))
|
||||
}
|
||||
callback(CompletionResult.Success(result))
|
||||
callback(CompletionResult.Success(createProductWalletTaskResponse))
|
||||
}
|
||||
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(it.error))
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -156,7 +162,12 @@ private class CreateWalletTangemWallet(
|
|||
CreateWalletsTask(cardConfig.mandatoryCurves, mnemonic, passphrase).run(session) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
checkIfAllWalletsCreated(card, session, result.data, callback)
|
||||
checkIfAllWalletsCreated(
|
||||
card = card,
|
||||
session = session,
|
||||
createResponse = result.data,
|
||||
callback = callback,
|
||||
)
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
callback(CompletionResult.Failure(result.error))
|
||||
|
|
@ -210,12 +221,16 @@ private class CreateWalletTangemWallet(
|
|||
callback: (result: CompletionResult<CreateProductWalletTaskResponse>) -> Unit,
|
||||
) {
|
||||
val resetCommand = ResetToFactorySettingsTask(allowsRequestAccessCodeFromRepository = false)
|
||||
resetCommand.run(session) {
|
||||
when (it) {
|
||||
resetCommand.run(session) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
createMultiWallet(card, session, callback)
|
||||
createMultiWallet(
|
||||
card = card,
|
||||
session = session,
|
||||
callback = callback,
|
||||
)
|
||||
}
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(it.error))
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -228,17 +243,27 @@ private class CreateWalletTangemWallet(
|
|||
) {
|
||||
when {
|
||||
card.settings.isBackupAllowed -> {
|
||||
linkPrimaryCard(card, createWalletResponses, session, callback)
|
||||
linkPrimaryCard(
|
||||
card = card,
|
||||
createWalletResponses = createWalletResponses,
|
||||
session = session,
|
||||
callback = callback,
|
||||
)
|
||||
}
|
||||
|
||||
card.settings.isHDWalletAllowed -> {
|
||||
deriveKeys(card, createWalletResponses, session, callback)
|
||||
deriveKeys(
|
||||
card = card,
|
||||
createWalletResponses = createWalletResponses,
|
||||
session = session,
|
||||
callback = callback,
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
callback(
|
||||
CompletionResult.Success(
|
||||
CreateProductWalletTaskResponse(card = session.environment.card!!),
|
||||
CreateProductWalletTaskResponse(card = requireNotNull(session.environment.card)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -247,7 +272,7 @@ private class CreateWalletTangemWallet(
|
|||
|
||||
private fun linkPrimaryCard(
|
||||
card: CardDTO,
|
||||
createWalletResponse: List<CreateWalletResponse>,
|
||||
createWalletResponses: List<CreateWalletResponse>,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<CreateProductWalletTaskResponse>) -> Unit,
|
||||
) {
|
||||
|
|
@ -257,14 +282,19 @@ private class CreateWalletTangemWallet(
|
|||
primaryCard = result.data
|
||||
when {
|
||||
card.settings.isHDWalletAllowed -> {
|
||||
deriveKeys(card, createWalletResponse, session, callback)
|
||||
deriveKeys(
|
||||
card = card,
|
||||
createWalletResponses = createWalletResponses,
|
||||
session = session,
|
||||
callback = callback,
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
callback(
|
||||
CompletionResult.Success(
|
||||
CreateProductWalletTaskResponse(
|
||||
card = session.environment.card!!,
|
||||
card = requireNotNull(session.environment.card),
|
||||
primaryCard = primaryCard,
|
||||
),
|
||||
),
|
||||
|
|
@ -282,13 +312,13 @@ private class CreateWalletTangemWallet(
|
|||
|
||||
private fun deriveKeys(
|
||||
card: CardDTO,
|
||||
createWalletResponse: List<CreateWalletResponse>,
|
||||
createWalletResponses: List<CreateWalletResponse>,
|
||||
session: CardSession,
|
||||
callback: (result: CompletionResult<CreateProductWalletTaskResponse>) -> Unit,
|
||||
) {
|
||||
val map = mutableMapOf<ByteArrayKey, List<DerivationPath>>()
|
||||
var isBlockchainsForCurvesExist = false
|
||||
createWalletResponse.forEach { response ->
|
||||
createWalletResponses.forEach { response ->
|
||||
val blockchainsForCurve = getBlockchains(response.cardId, card).filter {
|
||||
it.getSupportedCurves().contains(response.wallet.curve)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class CreateWalletsTask(
|
|||
callback: (result: CompletionResult<CreateWalletsResponse>) -> Unit,
|
||||
) {
|
||||
val extendedPrivateKey = mnemonic?.let {
|
||||
AnyMasterKeyFactory(mnemonic = it, passphrase = passphrase ?: "").makeMasterKey(curve)
|
||||
AnyMasterKeyFactory(mnemonic = it, passphrase = passphrase.orEmpty()).makeMasterKey(curve)
|
||||
}
|
||||
CreateWalletTask(curve, extendedPrivateKey).run(session) { result ->
|
||||
when (result) {
|
||||
|
|
|
|||
|
|
@ -34,12 +34,10 @@ internal class DerivationsFinder(
|
|||
val userWalletId = UserWalletIdBuilder.card(card).build() ?: return emptySet()
|
||||
val derivationStyle = derivationStyleProvider.getDerivationStyle()
|
||||
|
||||
var blockchains = withContext(dispatchers.io) {
|
||||
val blockchains = withContext(dispatchers.io) {
|
||||
getBlockchains(userWalletId)
|
||||
}
|
||||
|
||||
if (blockchains.isEmpty()) {
|
||||
blockchains = if (DemoHelper.isDemoCardId(card.cardId)) {
|
||||
}.ifEmpty {
|
||||
if (DemoHelper.isDemoCardId(card.cardId)) {
|
||||
getDemoBlockchains(derivationStyle)
|
||||
} else {
|
||||
getDefaultBlockchains(derivationStyle)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,12 @@ class ResetToFactorySettingsTask(
|
|||
}
|
||||
|
||||
private fun deleteWallets(session: CardSession, callback: (result: CompletionResult<Boolean>) -> Unit) {
|
||||
val wallet = session.environment.card?.wallets?.lastOrNull().guard {
|
||||
val wallet = session
|
||||
.environment
|
||||
.card
|
||||
?.wallets
|
||||
?.lastOrNull()
|
||||
.guard {
|
||||
resetBackup(session, callback)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,13 +111,13 @@ internal class ScanProductTask(
|
|||
}
|
||||
|
||||
private fun getErrorIfExcludedCard(cardDto: CardDTO, card: Card): TangemError? {
|
||||
if (cardDto.isExcluded) return TapSdkError.CardForDifferentApp
|
||||
if (cardDto.isNotSupportedInThatRelease) return TapSdkError.CardNotSupportedByRelease
|
||||
if (cardDto.isExcluded) return TapSdkError.CardForDifferentApp()
|
||||
if (cardDto.isNotSupportedInThatRelease) return TapSdkError.CardNotSupportedByRelease()
|
||||
// according ios decline card lower Ed25519Slip0010Available version and contains imported wallets
|
||||
if (card.firmwareVersion < FirmwareVersion.Ed25519Slip0010Available &&
|
||||
card.wallets.any { it.isImported }
|
||||
) {
|
||||
return TapSdkError.CardNotSupportedByRelease
|
||||
return TapSdkError.CardNotSupportedByRelease()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
|
@ -253,12 +253,13 @@ private class ScanWalletProcessor(
|
|||
callback: (result: CompletionResult<ScanResponse>) -> Unit,
|
||||
) {
|
||||
mainScope.launch {
|
||||
val activationInProgress = store.inject(DaggerGraphState::cardRepository)
|
||||
val isActivationInProgress = store.inject(DaggerGraphState::cardRepository)
|
||||
.isActivationInProgress(card.cardId)
|
||||
|
||||
@Suppress("ComplexCondition")
|
||||
if (card.backupStatus == CardDTO.BackupStatus.NoBackup && card.wallets.isNotEmpty() &&
|
||||
activationInProgress
|
||||
if (card.backupStatus == CardDTO.BackupStatus.NoBackup &&
|
||||
card.wallets.isNotEmpty() &&
|
||||
isActivationInProgress
|
||||
) {
|
||||
StartPrimaryCardLinkingTask().run(session) { linkingResult ->
|
||||
when (linkingResult) {
|
||||
|
|
@ -372,8 +373,8 @@ private class ScanTwinProcessor : ProductCommandProcessor<ScanResponse> {
|
|||
return@run
|
||||
}
|
||||
|
||||
val verified = TwinsHelper.verifyTwinPublicKey(readDataResult.data.issuerData, publicKey)
|
||||
val response = if (verified) {
|
||||
val isVerified = TwinsHelper.verifyTwinPublicKey(readDataResult.data.issuerData, publicKey)
|
||||
val response = if (isVerified) {
|
||||
val twinPublicKey = readDataResult.data.issuerData.sliceArray(0 until 65)
|
||||
val walletData = session.environment.walletData
|
||||
ScanResponse(
|
||||
|
|
|
|||
|
|
@ -153,9 +153,9 @@ class VisaCardActivationTask @AssistedInject constructor(
|
|||
val otpTaskDeferred = async { createOTP() }
|
||||
|
||||
val dataToSign = dataToSignDeferred.await()
|
||||
.getOrElse {
|
||||
.getOrElse { error ->
|
||||
otpTaskDeferred.cancel()
|
||||
return@coroutineScope CompletionResult.Failure(it)
|
||||
return@coroutineScope CompletionResult.Failure(error)
|
||||
}
|
||||
|
||||
otpTaskDeferred.await()
|
||||
|
|
|
|||
|
|
@ -115,8 +115,8 @@ class VisaCustomerWalletApproveTask(
|
|||
extendedPublicKey = extendedPublicKey,
|
||||
)
|
||||
|
||||
validationResult.onLeft {
|
||||
callback(CompletionResult.Failure(it.tangemError))
|
||||
validationResult.onLeft { error ->
|
||||
callback(CompletionResult.Failure(error.tangemError))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -137,8 +137,8 @@ class VisaCustomerWalletApproveTask(
|
|||
val publicKey = findKeyWithoutDerivation(
|
||||
targetAddress = visaDataForApprove.targetAddress,
|
||||
card = CardDTO(card),
|
||||
).getOrElse {
|
||||
callback(CompletionResult.Failure(it.tangemError))
|
||||
).getOrElse { error ->
|
||||
callback(CompletionResult.Failure(error.tangemError))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class CreateSecondTwinWalletTask(
|
|||
}
|
||||
|
||||
if (!TwinsHelper.isTwinsCompatible(firstCardId, card.cardId)) {
|
||||
callback(CompletionResult.Failure(IncompatibleTwinCard))
|
||||
callback(CompletionResult.Failure(IncompatibleTwinCard()))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class FinalizeTwinTask(
|
|||
when (readResult) {
|
||||
is CompletionResult.Success ->
|
||||
ScanProductTask(
|
||||
readResult.data,
|
||||
card = readResult.data,
|
||||
derivationsFinder = null,
|
||||
visaCardScanHandler = null,
|
||||
visaCoroutineScope = null,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import com.tangem.common.core.TangemError
|
|||
import com.tangem.tap.tangemSdkManager
|
||||
import com.tangem.wallet.R
|
||||
|
||||
object IncompatibleTwinCard : TangemError(code = 50005) {
|
||||
class IncompatibleTwinCard : TangemError(code = 50005) {
|
||||
override var customMessage: String = tangemSdkManager.getString(
|
||||
R.string.twin_error_wrong_twin,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class TwinCardsManager(card: CardDTO) {
|
|||
creatingWalletMessage: Message,
|
||||
): CompletionResult<CreateWalletResponse> {
|
||||
val response = tangemSdkManager.createSecondTwinWallet(
|
||||
firstPublicKey = currentCardPublicKey!!,
|
||||
firstPublicKey = requireNotNull(currentCardPublicKey),
|
||||
firstCardId = firstCardId,
|
||||
issuerKeys = getIssuerKeys(),
|
||||
preparingMessage = preparingMessage,
|
||||
|
|
@ -58,7 +58,7 @@ class TwinCardsManager(card: CardDTO) {
|
|||
|
||||
suspend fun complete(message: Message): CompletionResult<ScanResponse> {
|
||||
val response = tangemSdkManager.finalizeTwin(
|
||||
secondCardPublicKey = secondCardPublicKey!!.hexToBytes(),
|
||||
secondCardPublicKey = requireNotNull(secondCardPublicKey).hexToBytes(),
|
||||
issuerKeyPair = getIssuerKeys(),
|
||||
cardId = firstCardId,
|
||||
initialMessage = message,
|
||||
|
|
|
|||
|
|
@ -21,8 +21,9 @@ class WriteProtectedIssuerDataTask(
|
|||
|
||||
override fun run(session: CardSession, callback: (result: CompletionResult<SuccessResponse>) -> Unit) {
|
||||
SignHashCommand(
|
||||
twinPublicKey.calculateSha256(),
|
||||
session.environment.card!!.wallets.first().publicKey,
|
||||
hash = twinPublicKey.calculateSha256(),
|
||||
walletPublicKey = requireNotNull(session.environment.card)
|
||||
.wallets.first().publicKey,
|
||||
)
|
||||
.run(session) { signResult ->
|
||||
when (signResult) {
|
||||
|
|
@ -31,12 +32,12 @@ class WriteProtectedIssuerDataTask(
|
|||
when (readResult) {
|
||||
is CompletionResult.Success -> {
|
||||
writeIssuerData(
|
||||
twinPublicKey,
|
||||
issuerKeys,
|
||||
signResult.data.signature,
|
||||
readResult.data,
|
||||
session,
|
||||
callback,
|
||||
twinPublicKey = twinPublicKey,
|
||||
issuerKeys = issuerKeys,
|
||||
cardSignature = signResult.data.signature,
|
||||
readResponse = readResult.data,
|
||||
session = session,
|
||||
callback = callback,
|
||||
)
|
||||
}
|
||||
is CompletionResult.Failure -> callback(
|
||||
|
|
@ -78,7 +79,7 @@ class WriteProtectedIssuerDataTask(
|
|||
)
|
||||
WriteIssuerDataCommand(
|
||||
issuerData = data,
|
||||
issuerDataSignature = signedByIssuer.finalizingSignature!!,
|
||||
issuerDataSignature = requireNotNull(signedByIssuer.finalizingSignature),
|
||||
issuerDataCounter = counter,
|
||||
issuerPublicKey = issuerKeys.publicKey,
|
||||
).run(session, callback)
|
||||
|
|
|
|||
|
|
@ -57,12 +57,12 @@ internal class BiometricUserWalletsListManager(
|
|||
override val selectedUserWalletSync: UserWallet?
|
||||
get() = findSelectedUserWallet()
|
||||
|
||||
override val isLocked: Flow<Boolean>
|
||||
override val lockedState: Flow<Boolean>
|
||||
get() = state
|
||||
.mapLatest { it.isLocked }
|
||||
.distinctUntilChanged()
|
||||
|
||||
override val isLockedSync: Boolean
|
||||
override val isLocked: Boolean
|
||||
get() = state.value.isLocked
|
||||
|
||||
override val hasUserWallets: Boolean
|
||||
|
|
@ -103,7 +103,9 @@ internal class BiometricUserWalletsListManager(
|
|||
|
||||
override suspend fun select(userWalletId: UserWalletId): CompletionResult<UserWallet> = catching {
|
||||
if (state.value.selectedUserWalletId == userWalletId) {
|
||||
return@catching findSelectedUserWallet()!!
|
||||
return@catching requireNotNull(findSelectedUserWallet()) {
|
||||
"Wallet is not found"
|
||||
}
|
||||
}
|
||||
|
||||
selectedUserWalletRepository.set(userWalletId)
|
||||
|
|
|
|||
|
|
@ -93,23 +93,23 @@ internal class GeneralUserWalletsListManager(
|
|||
override val walletsCount: Int
|
||||
get() = requireImplementation.walletsCount
|
||||
|
||||
override val isLocked: Flow<Boolean>
|
||||
override val lockedState: Flow<Boolean>
|
||||
get() = implementation.transformLatest { impl ->
|
||||
if (impl == null) return@transformLatest
|
||||
|
||||
if (impl is UserWalletsListManager.Lockable) {
|
||||
emitAll(impl.isLocked)
|
||||
emitAll(impl.lockedState)
|
||||
} else {
|
||||
error("RuntimeUserWalletsListManager is not lockable")
|
||||
}
|
||||
}
|
||||
|
||||
override val isLockedSync: Boolean
|
||||
override val isLocked: Boolean
|
||||
get() {
|
||||
val impl = requireImplementation
|
||||
|
||||
return if (impl is UserWalletsListManager.Lockable) {
|
||||
impl.isLockedSync
|
||||
impl.isLocked
|
||||
} else {
|
||||
error("RuntimeUserWalletsListManager is not lockable")
|
||||
}
|
||||
|
|
@ -173,10 +173,10 @@ internal class GeneralUserWalletsListManager(
|
|||
}
|
||||
|
||||
if (possibleManager == implementation.value) {
|
||||
Timber.e("Switch to the same manager ${possibleManager::class.simpleName}")
|
||||
Timber.e("Switch to the same manager ${possibleManager::class.simpleName.orEmpty()}")
|
||||
}
|
||||
|
||||
Timber.i("Switch to ${possibleManager::class.simpleName}")
|
||||
Timber.i("Switch to ${possibleManager::class.simpleName.orEmpty()}")
|
||||
|
||||
val previousManager = implementation.value
|
||||
implementation.value = copySelectedUserWallet(
|
||||
|
|
|
|||
|
|
@ -74,11 +74,13 @@ internal class RuntimeUserWalletsListManager : UserWalletsListManager {
|
|||
?.takeIf { it.walletId == userWalletId }
|
||||
?: walletNotFound()
|
||||
|
||||
requireNotNull(
|
||||
state.updateAndGet { prevState ->
|
||||
prevState.copy(
|
||||
userWallet = update(wallet),
|
||||
)
|
||||
}.userWallet!!
|
||||
}.userWallet,
|
||||
) { "User wallet is null after update" }
|
||||
}
|
||||
|
||||
override suspend fun delete(userWalletIds: List<UserWalletId>): CompletionResult<Unit> = clear()
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ internal data class UserWalletSensitiveInformation(
|
|||
val mobileWallets: List<MobileWallet>? = null,
|
||||
)
|
||||
|
||||
@Suppress("BooleanPropertyNaming")
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class UserWalletPublicInformation(
|
||||
// Common
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ internal class DefaultUserWalletsListRepository(
|
|||
|
||||
// update the userWallets state and add if it doesn't exist
|
||||
updateWallets { currentWallets ->
|
||||
val wallets = currentWallets ?: emptyList()
|
||||
val wallets = currentWallets.orEmpty()
|
||||
if (wallets.any { it.walletId == userWallet.walletId }) {
|
||||
wallets.map { if (it.walletId == userWallet.walletId) userWallet else it }
|
||||
} else {
|
||||
|
|
@ -332,12 +332,12 @@ internal class DefaultUserWalletsListRepository(
|
|||
raise(LockWalletsError.NothingToLock)
|
||||
}
|
||||
|
||||
updateWallets {
|
||||
it?.map {
|
||||
if (it.walletId !in unsecuredWalletIds) {
|
||||
it.lock()
|
||||
updateWallets { wallets ->
|
||||
wallets?.map { wallet ->
|
||||
if (wallet.walletId !in unsecuredWalletIds) {
|
||||
wallet.lock()
|
||||
} else {
|
||||
it
|
||||
wallet
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -395,17 +395,17 @@ internal class DefaultUserWalletsListRepository(
|
|||
}
|
||||
|
||||
private suspend fun hasBiometry(): Boolean {
|
||||
val useBiometricAuthentication = appPreferencesStore.getSyncOrDefault(
|
||||
val isBiometricAuthenticationUsed = appPreferencesStore.getSyncOrDefault(
|
||||
key = PreferencesKeys.USE_BIOMETRIC_AUTHENTICATION_KEY,
|
||||
default = false,
|
||||
)
|
||||
|
||||
return tangemSdkManagerProvider.invoke().canUseBiometry && useBiometricAuthentication
|
||||
return tangemSdkManagerProvider.invoke().canUseBiometry && isBiometricAuthenticationUsed
|
||||
}
|
||||
|
||||
private fun updateWallets(block: (List<UserWallet>?) -> List<UserWallet>?) {
|
||||
userWallets.update {
|
||||
val updated = block(it)
|
||||
userWallets.update { wallets ->
|
||||
val updated = block(wallets)
|
||||
selectedUserWallet.update { currentSelected ->
|
||||
if (currentSelected == null) return@update null
|
||||
updated?.find { it.walletId == currentSelected.walletId }
|
||||
|
|
|
|||
|
|
@ -137,8 +137,7 @@ internal class UserWalletEncryptionKeysRepository(
|
|||
|
||||
private suspend fun UserWalletEncryptionKey.encode(): ByteArray {
|
||||
return withContext(dispatchers.default) {
|
||||
this@encode
|
||||
.let(encryptionKeyAdapter::toJson)
|
||||
encryptionKeyAdapter.toJson(this@encode)
|
||||
.encodeToByteArray(throwOnInvalidSequence = true)
|
||||
}
|
||||
}
|
||||
|
|
@ -153,8 +152,7 @@ internal class UserWalletEncryptionKeysRepository(
|
|||
|
||||
private suspend fun List<UserWalletId>.encode(): ByteArray {
|
||||
return withContext(dispatchers.default) {
|
||||
this@encode
|
||||
.let(userWalletsIdsListAdapter::toJson)
|
||||
userWalletsIdsListAdapter.toJson(this@encode)
|
||||
.encodeToByteArray(throwOnInvalidSequence = true)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,8 +164,7 @@ internal class BiometricUserWalletsKeysRepository(
|
|||
|
||||
private suspend fun UserWalletEncryptionKey.encode(): ByteArray {
|
||||
return withContext(Dispatchers.Default) {
|
||||
this@encode
|
||||
.let(encryptionKeyAdapter::toJson)
|
||||
encryptionKeyAdapter.toJson(this@encode)
|
||||
.encodeToByteArray(throwOnInvalidSequence = true)
|
||||
}
|
||||
}
|
||||
|
|
@ -180,8 +179,7 @@ internal class BiometricUserWalletsKeysRepository(
|
|||
|
||||
private suspend fun List<UserWalletId>.encode(): ByteArray {
|
||||
return withContext(Dispatchers.Default) {
|
||||
this@encode
|
||||
.let(userWalletsIdsListAdapter::toJson)
|
||||
userWalletsIdsListAdapter.toJson(this@encode)
|
||||
.encodeToByteArray(throwOnInvalidSequence = true)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,8 +80,7 @@ internal class DefaultUserWalletsPublicInformationRepository(
|
|||
@JvmName("saveWithPublicInformation")
|
||||
private suspend fun save(publicInformation: List<UserWalletPublicInformation>): CompletionResult<Unit> = catching {
|
||||
withContext(Dispatchers.IO) {
|
||||
publicInformation
|
||||
.let(publicInformationAdapter::toJson)
|
||||
publicInformationAdapter.toJson(publicInformation)
|
||||
.encodeToByteArray(throwOnInvalidSequence = true)
|
||||
.also { secureStorage.store(it, StorageKey.UserWalletPublicInformation.name) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,18 +110,18 @@ internal class DefaultUserWalletsSensitiveInformationRepository(
|
|||
|
||||
private suspend fun ByteArray.decodeToEncryptedSensitiveInformation(): Map<String, ByteArray>? {
|
||||
return withContext(Dispatchers.Default) {
|
||||
this@decodeToEncryptedSensitiveInformation
|
||||
.decodeToString(throwOnInvalidSequence = true)
|
||||
.let(encryptedSensitiveInformationMapAdapter::fromJson)
|
||||
encryptedSensitiveInformationMapAdapter.fromJson(
|
||||
this@decodeToEncryptedSensitiveInformation.decodeToString(throwOnInvalidSequence = true),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun ByteArray.decodeToSensitiveInformation(): UserWalletSensitiveInformation? {
|
||||
return withContext(Dispatchers.Default) {
|
||||
try {
|
||||
this@decodeToSensitiveInformation
|
||||
.decodeToString(throwOnInvalidSequence = true)
|
||||
.let(sensitiveInformationAdapter::fromJson)
|
||||
sensitiveInformationAdapter.fromJson(
|
||||
this@decodeToSensitiveInformation.decodeToString(throwOnInvalidSequence = true),
|
||||
)
|
||||
} catch (e: CharacterCodingException) {
|
||||
Timber.e(e, "Unable to decode sensitive information")
|
||||
|
||||
|
|
@ -132,16 +132,14 @@ internal class DefaultUserWalletsSensitiveInformationRepository(
|
|||
|
||||
private suspend fun UserWalletSensitiveInformation.encode(): ByteArray {
|
||||
return withContext(Dispatchers.Default) {
|
||||
this@encode
|
||||
.let(sensitiveInformationAdapter::toJson)
|
||||
sensitiveInformationAdapter.toJson(this@encode)
|
||||
.encodeToByteArray(throwOnInvalidSequence = true)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun Map<String, ByteArray>.encode(): ByteArray {
|
||||
return withContext(Dispatchers.Default) {
|
||||
this@encode
|
||||
.let(encryptedSensitiveInformationMapAdapter::toJson)
|
||||
encryptedSensitiveInformationMapAdapter.toJson(this@encode)
|
||||
.encodeToByteArray(throwOnInvalidSequence = true)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,14 +54,14 @@ internal fun UserWalletPublicInformation.toUserWallet(): UserWallet {
|
|||
walletId = walletId,
|
||||
hotWalletId = hotWalletId,
|
||||
wallets = null,
|
||||
backedUp = backedUp!!,
|
||||
backedUp = requireNotNull(backedUp),
|
||||
)
|
||||
} else {
|
||||
UserWallet.Cold(
|
||||
name = name,
|
||||
walletId = walletId,
|
||||
cardsInWallet = cardsInWallet,
|
||||
scanResponse = scanResponse!!,
|
||||
scanResponse = requireNotNull(scanResponse),
|
||||
isMultiCurrency = isMultiCurrency,
|
||||
hasBackupError = hasBackupError,
|
||||
)
|
||||
|
|
@ -78,7 +78,7 @@ internal fun UserWallet.updateWith(sensitiveInformation: UserWalletSensitiveInfo
|
|||
copy(
|
||||
scanResponse = scanResponse.copy(
|
||||
card = scanResponse.card.copy(
|
||||
wallets = sensitiveInformation.wallets!!,
|
||||
wallets = requireNotNull(sensitiveInformation.wallets),
|
||||
),
|
||||
visaCardActivationStatus = sensitiveInformation.visaCardActivationStatus,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -87,9 +87,9 @@ internal class VisaCardScanHandler @Inject constructor(
|
|||
cardId = card.cardId,
|
||||
// This is the wallet public key, not the address and it's alright, as the API expects it in this format
|
||||
cardWalletAddress = wallet.publicKey.toHexString(),
|
||||
).getOrElse {
|
||||
).getOrElse { error ->
|
||||
Timber.i("Failed to get Access token for Wallet public key authorization")
|
||||
return CompletionResult.Failure(it.tangemError)
|
||||
return CompletionResult.Failure(error.tangemError)
|
||||
}
|
||||
|
||||
val signChallengeResult = signChallengeWithWallet(
|
||||
|
|
@ -123,16 +123,16 @@ internal class VisaCardScanHandler @Inject constructor(
|
|||
signedChallenge: VisaAuthSignedChallenge,
|
||||
): CompletionResult<VisaCardActivationStatus> {
|
||||
val authorizationTokensResponse = visaAuthRemoteDataSource.getAccessTokens(signedChallenge = signedChallenge)
|
||||
.getOrElse {
|
||||
.getOrElse { error ->
|
||||
Timber.i("Failed to get Access token for Wallet public key authorization.")
|
||||
return if (
|
||||
it is VisaApiError.ProductInstanceIsNotActivated ||
|
||||
it is VisaApiError.ProductInstanceNotFoundActivationRequired
|
||||
error is VisaApiError.ProductInstanceIsNotActivated ||
|
||||
error is VisaApiError.ProductInstanceNotFoundActivationRequired
|
||||
) {
|
||||
Timber.i("Proceeding with card authorization.")
|
||||
handleCardAuthorization(cardWalletAddress = cardWalletAddress)
|
||||
} else {
|
||||
CompletionResult.Failure(it.tangemError)
|
||||
CompletionResult.Failure(error.tangemError)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -152,9 +152,9 @@ internal class VisaCardScanHandler @Inject constructor(
|
|||
val challengeResponse = visaAuthRemoteDataSource.getCardAuthChallenge(
|
||||
cardId = card.cardId,
|
||||
cardPublicKey = card.cardPublicKey.toHexString(),
|
||||
).getOrElse {
|
||||
Timber.e("Failed to get challenge for Card authorization. Plain error: ${it.errorCode}")
|
||||
return CompletionResult.Failure(it.tangemError)
|
||||
).getOrElse { error ->
|
||||
Timber.e("Failed to get challenge for Card authorization. Plain error: ${error.errorCode}")
|
||||
return CompletionResult.Failure(error.tangemError)
|
||||
}
|
||||
|
||||
Timber.i("Received challenge to sign: ${challengeResponse.challenge}")
|
||||
|
|
@ -179,9 +179,9 @@ internal class VisaCardScanHandler @Inject constructor(
|
|||
signedChallenge = attestCardKeyResponse.cardSignature.toHexString(),
|
||||
salt = attestCardKeyResponse.salt.toHexString(),
|
||||
),
|
||||
).getOrElse {
|
||||
Timber.e("Failed to sign challenge with Card public key. Plain error: ${it.errorCode}")
|
||||
return CompletionResult.Failure(it.tangemError)
|
||||
).getOrElse { error ->
|
||||
Timber.e("Failed to sign challenge with Card public key. Plain error: ${error.errorCode}")
|
||||
return CompletionResult.Failure(error.tangemError)
|
||||
}
|
||||
|
||||
visaAuthTokenStorage.store(
|
||||
|
|
@ -189,9 +189,9 @@ internal class VisaCardScanHandler @Inject constructor(
|
|||
tokens = authorizationTokensResponse,
|
||||
)
|
||||
|
||||
val activationRemoteState = visaActivationRepository.getActivationRemoteState().getOrElse {
|
||||
Timber.e("Failed to sign challenge with Card public key. Plain error: ${it.errorCode}")
|
||||
return CompletionResult.Failure(it.tangemError)
|
||||
val activationRemoteState = visaActivationRepository.getActivationRemoteState().getOrElse { error ->
|
||||
Timber.e("Failed to sign challenge with Card public key. Plain error: ${error.errorCode}")
|
||||
return CompletionResult.Failure(error.tangemError)
|
||||
}
|
||||
|
||||
val error = when (activationRemoteState) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.domain.models.scan.ScanResponse
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import org.rekotlin.Action
|
||||
|
||||
@Suppress("BooleanPropertyNaming")
|
||||
sealed class DetailsAction : Action {
|
||||
|
||||
data class PrepareScreen(
|
||||
|
|
@ -32,7 +33,7 @@ sealed class DetailsAction : Action {
|
|||
|
||||
data object EnrollBiometrics : AppSettings()
|
||||
data class BiometricsStatusChanged(
|
||||
val needEnrollBiometrics: Boolean,
|
||||
val isEnrollBiometricsNeeded: Boolean,
|
||||
) : AppSettings()
|
||||
|
||||
data class ChangeAppThemeMode(
|
||||
|
|
@ -40,7 +41,7 @@ sealed class DetailsAction : Action {
|
|||
) : AppSettings()
|
||||
|
||||
data class ChangeBalanceHiding(
|
||||
val hideBalance: Boolean,
|
||||
val shouldHideBalance: Boolean,
|
||||
) : AppSettings()
|
||||
|
||||
data class ChangeAppCurrency(
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ class DetailsMiddleware {
|
|||
changeAppThemeMode(action.appThemeMode)
|
||||
}
|
||||
is DetailsAction.AppSettings.ChangeBalanceHiding -> {
|
||||
changeBalanceHiding(action.hideBalance)
|
||||
changeBalanceHiding(action.shouldHideBalance)
|
||||
}
|
||||
is DetailsAction.AppSettings.ChangeAppCurrency -> {
|
||||
store.dispatch(GlobalAction.ChangeAppCurrency(action.currency))
|
||||
|
|
@ -153,9 +153,9 @@ class DetailsMiddleware {
|
|||
private suspend fun setBiometricLockForAllWallets() {
|
||||
val userWalletsListRepository = store.inject(DaggerGraphState::userWalletsListRepository)
|
||||
val userWallets = userWalletsListRepository.userWalletsSync()
|
||||
userWallets.forEach {
|
||||
userWallets.forEach { wallet ->
|
||||
userWalletsListRepository.setLock(
|
||||
userWalletId = it.walletId,
|
||||
userWalletId = wallet.walletId,
|
||||
lockMethod = LockMethod.Biometric,
|
||||
changeUnsecured = false,
|
||||
)
|
||||
|
|
@ -174,11 +174,11 @@ class DetailsMiddleware {
|
|||
deleteSavedAccessCodes()
|
||||
val userWalletsListRepository = store.inject(DaggerGraphState::userWalletsListRepository)
|
||||
val tangemHotSdk = store.inject(DaggerGraphState::tangemHotSdk)
|
||||
userWalletsListRepository.userWalletsSync().forEach {
|
||||
if (it is UserWallet.Hot) {
|
||||
userWalletsListRepository.userWalletsSync().forEach { wallet ->
|
||||
if (wallet is UserWallet.Hot) {
|
||||
userWalletsListRepository.saveWithoutLock(
|
||||
userWallet = it.copy(
|
||||
hotWalletId = tangemHotSdk.removeBiometryAuthIfPresented(it.hotWalletId),
|
||||
userWallet = wallet.copy(
|
||||
hotWalletId = tangemHotSdk.removeBiometryAuthIfPresented(wallet.hotWalletId),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -188,10 +188,10 @@ class DetailsMiddleware {
|
|||
private fun observeBiometricsStatusChanges(scope: CoroutineScope) {
|
||||
val needEnrollBiometricsFlow = flow {
|
||||
do {
|
||||
val needEnrollBiometrics = runCatching(tangemSdkManager::needEnrollBiometrics).getOrNull()
|
||||
val isEnrollBiometricsNeeded = runCatching(tangemSdkManager::needEnrollBiometrics).getOrNull()
|
||||
|
||||
if (needEnrollBiometrics != null) {
|
||||
emit(needEnrollBiometrics)
|
||||
if (isEnrollBiometricsNeeded != null) {
|
||||
emit(isEnrollBiometricsNeeded)
|
||||
}
|
||||
|
||||
delay(timeMillis = 200)
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ private fun handlePrivacyAction(action: DetailsAction.AppSettings, state: Detail
|
|||
)
|
||||
is DetailsAction.AppSettings.BiometricsStatusChanged -> state.copy(
|
||||
appSettingsState = state.appSettingsState.copy(
|
||||
needEnrollBiometrics = action.needEnrollBiometrics,
|
||||
needEnrollBiometrics = action.isEnrollBiometricsNeeded,
|
||||
),
|
||||
)
|
||||
is DetailsAction.AppSettings.ChangeAppThemeMode -> state.copy(
|
||||
|
|
@ -99,7 +99,7 @@ private fun handlePrivacyAction(action: DetailsAction.AppSettings, state: Detail
|
|||
)
|
||||
is DetailsAction.AppSettings.ChangeBalanceHiding -> state.copy(
|
||||
appSettingsState = state.appSettingsState.copy(
|
||||
isHidingEnabled = action.hideBalance,
|
||||
isHidingEnabled = action.shouldHideBalance,
|
||||
),
|
||||
)
|
||||
// state should be copied to avoid concurrent modifications from different sources
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ data class DetailsState(
|
|||
val appSettingsState: AppSettingsState = AppSettingsState(),
|
||||
) : StateType
|
||||
|
||||
@Suppress("BooleanPropertyNaming")
|
||||
data class AppSettingsState(
|
||||
@Deprecated("Delete after hot wallet release")
|
||||
val saveWallets: Boolean = false,
|
||||
|
|
|
|||
|
|
@ -341,16 +341,18 @@ private class AppCurrencySelectorStateProvider : CollectionPreviewParameterProvi
|
|||
.mapIndexed { index, s -> Currency(index.toString(), s) }
|
||||
.toPersistentList()
|
||||
|
||||
AppCurrencySelectorState.Loading(onBackClick = {}).let(::add)
|
||||
AppCurrencySelectorState.Default(
|
||||
this + AppCurrencySelectorState.Loading(onBackClick = {})
|
||||
|
||||
this + AppCurrencySelectorState.Default(
|
||||
selectedId = "0",
|
||||
items = items,
|
||||
scrollToSelected = consumedEvent(),
|
||||
onCurrencyClick = {},
|
||||
onBackClick = {},
|
||||
onTopBarActionClick = {},
|
||||
).let(::add)
|
||||
AppCurrencySelectorState.Search(
|
||||
)
|
||||
|
||||
this + AppCurrencySelectorState.Search(
|
||||
selectedId = "0",
|
||||
items = items,
|
||||
scrollToSelected = consumedEvent(),
|
||||
|
|
@ -358,7 +360,7 @@ private class AppCurrencySelectorStateProvider : CollectionPreviewParameterProvi
|
|||
onBackClick = {},
|
||||
onSearchInputChange = {},
|
||||
onTopBarActionClick = {},
|
||||
).let(::add)
|
||||
)
|
||||
},
|
||||
)
|
||||
// endregion Preview
|
||||
|
|
@ -15,8 +15,8 @@ import androidx.compose.ui.platform.LocalDensity
|
|||
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.res.TangemThemePreview
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.domain.apptheme.model.AppThemeMode
|
||||
import com.tangem.tap.features.details.ui.appsettings.AppSettingsScreenState.Item
|
||||
import com.tangem.tap.features.details.ui.appsettings.components.*
|
||||
|
|
@ -27,16 +27,16 @@ import kotlinx.collections.immutable.persistentListOf
|
|||
@Composable
|
||||
internal fun AppSettingsScreen(state: AppSettingsScreenState, onBackClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||
SettingsScreensScaffold(
|
||||
onBackClick = onBackClick,
|
||||
modifier = modifier,
|
||||
titleRes = R.string.app_settings_title,
|
||||
addBottomInsets = false,
|
||||
content = {
|
||||
when (state) {
|
||||
is AppSettingsScreenState.Content -> AppSettings(state = state)
|
||||
is AppSettingsScreenState.Loading -> Unit
|
||||
}
|
||||
},
|
||||
titleRes = R.string.app_settings_title,
|
||||
onBackClick = onBackClick,
|
||||
addBottomInsets = false,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -103,10 +103,10 @@ private class AppSettingsScreenStateProvider : CollectionPreviewParameterProvide
|
|||
itemsFactory.createSelectThemeModeButton(AppThemeMode.DEFAULT, {}),
|
||||
)
|
||||
|
||||
AppSettingsScreenState.Content(
|
||||
this + AppSettingsScreenState.Content(
|
||||
items = items,
|
||||
dialog = null,
|
||||
).let(::add)
|
||||
)
|
||||
},
|
||||
)
|
||||
// endregion Preview
|
||||
|
|
@ -47,8 +47,8 @@ private class AlertDialogProvider : CollectionPreviewParameterProvider<Dialog.Al
|
|||
collection = buildList {
|
||||
val dialogsFactory = AppSettingsDialogsFactory()
|
||||
|
||||
dialogsFactory.createDeleteSavedAccessCodesAlert({}, {}).let(::add)
|
||||
dialogsFactory.createDeleteSavedWalletsAlert({}, {}).let(::add)
|
||||
add(dialogsFactory.createDeleteSavedAccessCodesAlert({}, {}))
|
||||
add(dialogsFactory.createDeleteSavedWalletsAlert({}, {}))
|
||||
},
|
||||
)
|
||||
// endregion Preview
|
||||
|
|
@ -14,8 +14,8 @@ 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.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.tap.features.details.ui.appsettings.AppSettingsItemsFactory
|
||||
import com.tangem.tap.features.details.ui.appsettings.AppSettingsScreenState.Item
|
||||
|
||||
|
|
@ -64,10 +64,10 @@ private class ButtonItemProvider : CollectionPreviewParameterProvider<Item.Butto
|
|||
collection = buildList {
|
||||
val itemsFactory = AppSettingsItemsFactory()
|
||||
|
||||
itemsFactory.createSelectAppCurrencyButton(
|
||||
this + itemsFactory.createSelectAppCurrencyButton(
|
||||
currentAppCurrencyName = "US Dollar",
|
||||
onClick = { /* no-op */ },
|
||||
).let(::add)
|
||||
)
|
||||
},
|
||||
)
|
||||
// endregion Preview
|
||||
|
|
@ -16,8 +16,8 @@ import androidx.compose.ui.unit.dp
|
|||
import com.tangem.core.ui.components.SpacerH4
|
||||
import com.tangem.core.ui.components.SpacerW16
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.tap.features.details.ui.appsettings.AppSettingsItemsFactory
|
||||
import com.tangem.tap.features.details.ui.appsettings.AppSettingsScreenState.Item
|
||||
|
||||
|
|
@ -71,9 +71,7 @@ private class CardItemProvider : CollectionPreviewParameterProvider<Item.Card>(
|
|||
collection = buildList {
|
||||
val itemsFactory = AppSettingsItemsFactory()
|
||||
|
||||
itemsFactory.createEnrollBiometricsCard(
|
||||
onClick = { /* no-op */ },
|
||||
).let(::add)
|
||||
this + itemsFactory.createEnrollBiometricsCard(onClick = { /* no-op */ })
|
||||
},
|
||||
)
|
||||
// endregion Preview
|
||||
|
|
@ -17,8 +17,8 @@ import com.tangem.core.ui.components.SpacerH4
|
|||
import com.tangem.core.ui.components.SpacerW32
|
||||
import com.tangem.core.ui.components.TangemSwitch
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.tap.features.details.ui.appsettings.AppSettingsItemsFactory
|
||||
import com.tangem.tap.features.details.ui.appsettings.AppSettingsScreenState.Item
|
||||
|
||||
|
|
@ -85,26 +85,29 @@ private class SwitchItemProvider : CollectionPreviewParameterProvider<Item.Switc
|
|||
collection = buildList {
|
||||
val itemsFactory = AppSettingsItemsFactory()
|
||||
|
||||
itemsFactory.createSaveAccessCodeSwitch(
|
||||
this + itemsFactory.createSaveAccessCodeSwitch(
|
||||
isChecked = true,
|
||||
isEnabled = true,
|
||||
onCheckedChange = { /* no-op */ },
|
||||
).let(::add)
|
||||
itemsFactory.createSaveAccessCodeSwitch(
|
||||
)
|
||||
|
||||
this + itemsFactory.createSaveAccessCodeSwitch(
|
||||
isChecked = false,
|
||||
isEnabled = true,
|
||||
onCheckedChange = { /* no-op */ },
|
||||
).let(::add)
|
||||
itemsFactory.createSaveAccessCodeSwitch(
|
||||
)
|
||||
|
||||
this + itemsFactory.createSaveAccessCodeSwitch(
|
||||
isChecked = true,
|
||||
isEnabled = false,
|
||||
onCheckedChange = { /* no-op */ },
|
||||
).let(::add)
|
||||
itemsFactory.createSaveAccessCodeSwitch(
|
||||
)
|
||||
|
||||
this + itemsFactory.createSaveAccessCodeSwitch(
|
||||
isChecked = false,
|
||||
isEnabled = false,
|
||||
onCheckedChange = { /* no-op */ },
|
||||
).let(::add)
|
||||
)
|
||||
},
|
||||
)
|
||||
// endregion Preview
|
||||
|
|
@ -32,6 +32,7 @@ import com.tangem.tap.store
|
|||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.JobHolder
|
||||
import com.tangem.utils.coroutines.saveIn
|
||||
import com.tangem.utils.extensions.addIf
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
|
@ -99,60 +100,59 @@ internal class AppSettingsModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun buildItems(state: AppSettingsState): ImmutableList<AppSettingsScreenState.Item> {
|
||||
val items = buildList {
|
||||
if (state.needEnrollBiometrics) {
|
||||
itemsFactory.createEnrollBiometricsCard(
|
||||
onClick = ::enrollBiometrics,
|
||||
).let(::add)
|
||||
}
|
||||
val items = buildList<AppSettingsScreenState.Item> {
|
||||
addIf(
|
||||
condition = state.needEnrollBiometrics,
|
||||
element = itemsFactory.createEnrollBiometricsCard(onClick = ::enrollBiometrics),
|
||||
)
|
||||
|
||||
itemsFactory.createSelectAppCurrencyButton(
|
||||
this + itemsFactory.createSelectAppCurrencyButton(
|
||||
currentAppCurrencyName = state.selectedAppCurrency.name,
|
||||
onClick = ::showAppCurrencySelector,
|
||||
).let(::add)
|
||||
)
|
||||
|
||||
if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
val canUseBiometrics = !state.needEnrollBiometrics && !state.isInProgress
|
||||
|
||||
itemsFactory.createUseBiometricsSwitch(
|
||||
this + itemsFactory.createUseBiometricsSwitch(
|
||||
isChecked = state.useBiometricAuthentication,
|
||||
isEnabled = canUseBiometrics,
|
||||
onCheckedChange = ::onBiometricAuthenticationToggled,
|
||||
).let(::add)
|
||||
)
|
||||
|
||||
itemsFactory.createRequireAccessCodeSwitch(
|
||||
this + itemsFactory.createRequireAccessCodeSwitch(
|
||||
isChecked = state.requireAccessCode,
|
||||
isEnabled = canUseBiometrics && state.useBiometricAuthentication,
|
||||
onCheckedChange = ::onRequireAccessCodeToggled,
|
||||
).let(::add)
|
||||
)
|
||||
} else {
|
||||
if (state.isBiometricsAvailable) {
|
||||
val canUseBiometrics = !state.needEnrollBiometrics && !state.isInProgress
|
||||
|
||||
itemsFactory.createSaveWalletsSwitch(
|
||||
this + itemsFactory.createSaveWalletsSwitch(
|
||||
isChecked = state.saveWallets,
|
||||
isEnabled = canUseBiometrics,
|
||||
onCheckedChange = ::onSaveWalletsToggled,
|
||||
).let(::add)
|
||||
)
|
||||
|
||||
itemsFactory.createSaveAccessCodeSwitch(
|
||||
this + itemsFactory.createSaveAccessCodeSwitch(
|
||||
isChecked = state.saveAccessCodes,
|
||||
isEnabled = canUseBiometrics,
|
||||
onCheckedChange = ::onSaveAccessCodesToggled,
|
||||
).let(::add)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
itemsFactory.createFlipToHideBalanceSwitch(
|
||||
this + itemsFactory.createFlipToHideBalanceSwitch(
|
||||
isChecked = state.isHidingEnabled,
|
||||
isEnabled = true,
|
||||
onCheckedChange = ::onFlipToHideBalanceToggled,
|
||||
).let(::add)
|
||||
)
|
||||
|
||||
itemsFactory.createSelectThemeModeButton(
|
||||
this + itemsFactory.createSelectThemeModeButton(
|
||||
currentThemeMode = state.selectedThemeMode,
|
||||
onClick = { showThemeModeSelector(state.selectedThemeMode) },
|
||||
).let(::add)
|
||||
)
|
||||
}
|
||||
|
||||
return items.toImmutableList()
|
||||
|
|
@ -280,7 +280,7 @@ internal class AppSettingsModel @Inject constructor(
|
|||
val param = AnalyticsParam.OnOffState(enable)
|
||||
analyticsEventHandler.send(Settings.AppSettings.HideBalanceChanged(param))
|
||||
|
||||
store.dispatch(DetailsAction.AppSettings.ChangeBalanceHiding(hideBalance = enable))
|
||||
store.dispatch(DetailsAction.AppSettings.ChangeBalanceHiding(shouldHideBalance = enable))
|
||||
}
|
||||
|
||||
private fun dismissDialog() {
|
||||
|
|
@ -290,10 +290,10 @@ internal class AppSettingsModel @Inject constructor(
|
|||
private fun bootstrapAppCurrencyUpdates() {
|
||||
appCurrencyRepository
|
||||
.getSelectedAppCurrency()
|
||||
.onEach {
|
||||
if (it.code == store.state.globalState.appCurrency.code) return@onEach
|
||||
.onEach { appCurrency ->
|
||||
if (appCurrency.code == store.state.globalState.appCurrency.code) return@onEach
|
||||
|
||||
store.dispatchWithMain(DetailsAction.AppSettings.ChangeAppCurrency(it))
|
||||
store.dispatchWithMain(DetailsAction.AppSettings.ChangeAppCurrency(appCurrency))
|
||||
}
|
||||
.launchIn(scope)
|
||||
.saveIn(appCurrencyUpdatesJobHolder)
|
||||
|
|
|
|||
|
|
@ -26,19 +26,19 @@ import com.tangem.wallet.R
|
|||
|
||||
@Composable
|
||||
internal fun CardSettingsScreen(state: CardSettingsScreenState, modifier: Modifier = Modifier) {
|
||||
val needReadCard = state.cardDetails == null
|
||||
val isCardReadingNeeded = state.cardDetails == null
|
||||
|
||||
SettingsScreensScaffold(
|
||||
onBackClick = state.onBackClick,
|
||||
modifier = modifier,
|
||||
titleRes = R.string.card_settings_title,
|
||||
content = {
|
||||
if (needReadCard) {
|
||||
if (isCardReadingNeeded) {
|
||||
CardSettingsReadCard(state.onScanCardClick)
|
||||
} else {
|
||||
CardSettings(state = state)
|
||||
}
|
||||
},
|
||||
titleRes = R.string.card_settings_title,
|
||||
onBackClick = state.onBackClick,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -123,8 +123,8 @@ private fun CardSettings(state: CardSettingsScreenState) {
|
|||
.fillMaxWidth()
|
||||
.testTag(DeviceSettingsScreenTestTags.LAZY_LIST),
|
||||
) {
|
||||
items(state.cardDetails) {
|
||||
val paddingBottom = when (it) {
|
||||
items(state.cardDetails) { cardInfo ->
|
||||
val paddingBottom = when (cardInfo) {
|
||||
is CardInfo.CardId, is CardInfo.Issuer -> TangemTheme.dimens.spacing12
|
||||
is CardInfo.SignedHashes -> TangemTheme.dimens.spacing14
|
||||
is CardInfo.SecurityMode -> TangemTheme.dimens.spacing16
|
||||
|
|
@ -132,7 +132,7 @@ private fun CardSettings(state: CardSettingsScreenState) {
|
|||
is CardInfo.AccessCodeRecovery -> TangemTheme.dimens.spacing16
|
||||
is CardInfo.ResetToFactorySettings -> TangemTheme.dimens.spacing28
|
||||
}
|
||||
val paddingTop = when (it) {
|
||||
val paddingTop = when (cardInfo) {
|
||||
is CardInfo.CardId -> TangemTheme.dimens.spacing0
|
||||
is CardInfo.Issuer -> TangemTheme.dimens.spacing12
|
||||
is CardInfo.SignedHashes -> TangemTheme.dimens.spacing12
|
||||
|
|
@ -145,8 +145,8 @@ private fun CardSettings(state: CardSettingsScreenState) {
|
|||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(
|
||||
enabled = it.clickable,
|
||||
onClick = { state.onElementClick(it) },
|
||||
enabled = cardInfo.isClickable,
|
||||
onClick = { state.onElementClick(cardInfo) },
|
||||
)
|
||||
.padding(
|
||||
start = TangemTheme.dimens.spacing20,
|
||||
|
|
@ -155,25 +155,25 @@ private fun CardSettings(state: CardSettingsScreenState) {
|
|||
top = paddingTop,
|
||||
),
|
||||
) {
|
||||
val titleColor = if (it.clickable) {
|
||||
val titleColor = if (cardInfo.isClickable) {
|
||||
TangemTheme.colors.text.primary1
|
||||
} else {
|
||||
TangemTheme.colors.text.tertiary
|
||||
}
|
||||
val subtitleColor = if (it.clickable) {
|
||||
val subtitleColor = if (cardInfo.isClickable) {
|
||||
TangemTheme.colors.text.secondary
|
||||
} else {
|
||||
TangemTheme.colors.text.tertiary
|
||||
}
|
||||
Text(
|
||||
text = it.titleRes.resolveReference(),
|
||||
text = cardInfo.titleRes.resolveReference(),
|
||||
color = titleColor,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
modifier = Modifier.testTag(DeviceSettingsScreenTestTags.ITEM_TITLE),
|
||||
)
|
||||
Spacer(modifier = Modifier.size(TangemTheme.dimens.size4))
|
||||
Text(
|
||||
text = it.subtitle.resolveReference(),
|
||||
text = cardInfo.subtitle.resolveReference(),
|
||||
color = subtitleColor,
|
||||
style = TangemTheme.typography.body2,
|
||||
modifier = Modifier.testTag(DeviceSettingsScreenTestTags.ITEM_SUBTITLE),
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ internal data class CardSettingsScreenState(
|
|||
internal sealed class CardInfo(
|
||||
val titleRes: TextReference,
|
||||
val subtitle: TextReference,
|
||||
val clickable: Boolean = false,
|
||||
val isClickable: Boolean = false,
|
||||
) {
|
||||
class CardId(subtitle: String) : CardInfo(
|
||||
titleRes = TextReference.Res(R.string.details_row_title_cid),
|
||||
|
|
@ -38,29 +38,29 @@ internal sealed class CardInfo(
|
|||
class SecurityMode(securityOption: SecurityOption, clickable: Boolean) : CardInfo(
|
||||
titleRes = TextReference.Res(R.string.card_settings_security_mode),
|
||||
subtitle = TextReference.Res(securityOption.toTitleRes()),
|
||||
clickable = clickable,
|
||||
isClickable = clickable,
|
||||
)
|
||||
|
||||
data object ChangeAccessCode : CardInfo(
|
||||
titleRes = TextReference.Res(R.string.card_settings_change_access_code),
|
||||
subtitle = TextReference.Res(R.string.card_settings_change_access_code_footer),
|
||||
clickable = true,
|
||||
isClickable = true,
|
||||
)
|
||||
|
||||
class AccessCodeRecovery(val enabled: Boolean) : CardInfo(
|
||||
class AccessCodeRecovery(val isEnabled: Boolean) : CardInfo(
|
||||
titleRes = TextReference.Res(R.string.card_settings_access_code_recovery_title),
|
||||
subtitle = if (enabled) {
|
||||
subtitle = if (isEnabled) {
|
||||
TextReference.Res(R.string.common_enabled)
|
||||
} else {
|
||||
TextReference.Res(R.string.common_disabled)
|
||||
},
|
||||
clickable = true,
|
||||
isClickable = true,
|
||||
)
|
||||
|
||||
class ResetToFactorySettings(description: TextReference) : CardInfo(
|
||||
titleRes = TextReference.Res(R.string.card_settings_reset_card_to_factory),
|
||||
subtitle = description,
|
||||
clickable = true,
|
||||
isClickable = true,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ import com.tangem.wallet.R
|
|||
@Composable
|
||||
fun AccessCodeRecoveryScreen(state: AccessCodeRecoveryScreenState, onBackClick: () -> Unit) {
|
||||
SettingsScreensScaffold(
|
||||
content = { AccessCodeRecoveryOptions(state = state) },
|
||||
onBackClick = onBackClick,
|
||||
content = { AccessCodeRecoveryOptions(state = state) },
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -38,13 +38,13 @@ fun AccessCodeRecoveryOptions(state: AccessCodeRecoveryScreenState) {
|
|||
DetailsRadioButtonElement(
|
||||
title = stringResourceSafe(id = R.string.common_enabled),
|
||||
subtitle = stringResourceSafe(id = R.string.card_settings_access_code_recovery_enabled_description),
|
||||
selected = state.enabledSelection,
|
||||
isSelected = state.isEnabledSelection,
|
||||
onClick = { state.onOptionClick(true) },
|
||||
)
|
||||
DetailsRadioButtonElement(
|
||||
title = stringResourceSafe(id = R.string.common_disabled),
|
||||
subtitle = stringResourceSafe(id = R.string.card_settings_access_code_recovery_disabled_description),
|
||||
selected = !state.enabledSelection,
|
||||
isSelected = !state.isEnabledSelection,
|
||||
onClick = { state.onOptionClick(false) },
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
package com.tangem.tap.features.details.ui.cardsettings.coderecovery
|
||||
|
||||
/**
|
||||
* @property enabledOnCard Indicates whether access code recovery is enabled on the card
|
||||
* @property enabledSelection Represents the currently selected option in the app (not yet saved on the card)
|
||||
* @property isEnabledOnCard Indicates whether access code recovery is enabled on the card
|
||||
* @property isEnabledSelection Represents the currently selected option in the app (not yet saved on the card)
|
||||
* @property isSaveChangesEnabled Determines if the user is allowed to save their selection to the card
|
||||
* @property onSaveChangesClick Callback function called when the user wants to apply the selected option
|
||||
* @property onOptionClick Callback function called when the user selects an option
|
||||
* */
|
||||
data class AccessCodeRecoveryScreenState(
|
||||
val enabledOnCard: Boolean,
|
||||
val enabledSelection: Boolean,
|
||||
val isEnabledOnCard: Boolean,
|
||||
val isEnabledSelection: Boolean,
|
||||
val isSaveChangesEnabled: Boolean,
|
||||
val onSaveChangesClick: () -> Unit,
|
||||
val onOptionClick: (Boolean) -> Unit,
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ internal class AccessCodeRecoveryModel @Inject constructor(
|
|||
)
|
||||
|
||||
return AccessCodeRecoveryScreenState(
|
||||
enabledOnCard = isEnabled,
|
||||
enabledSelection = isEnabled,
|
||||
isEnabledOnCard = isEnabled,
|
||||
isEnabledSelection = isEnabled,
|
||||
isSaveChangesEnabled = false,
|
||||
onSaveChangesClick = ::saveChanges,
|
||||
onOptionClick = ::selectOption,
|
||||
|
|
@ -52,7 +52,7 @@ internal class AccessCodeRecoveryModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun saveChanges() = modelScope.launch {
|
||||
val isEnabled = screenState.value.enabledSelection
|
||||
val isEnabled = screenState.value.isEnabledSelection
|
||||
|
||||
tangemSdkManager
|
||||
.setAccessCodeRecoveryEnabled(scannedScanResponse.card.cardId, isEnabled)
|
||||
|
|
@ -78,10 +78,10 @@ internal class AccessCodeRecoveryModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun selectOption(isEnabled: Boolean) {
|
||||
screenState.update {
|
||||
it.copy(
|
||||
enabledSelection = isEnabled,
|
||||
isSaveChangesEnabled = isEnabled != it.enabledOnCard,
|
||||
screenState.update { state ->
|
||||
state.copy(
|
||||
isEnabledSelection = isEnabled,
|
||||
isSaveChangesEnabled = isEnabled != state.isEnabledOnCard,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ internal class CardSettingsInteractor @Inject constructor() {
|
|||
}
|
||||
|
||||
fun update(transform: (ScanResponse) -> ScanResponse) {
|
||||
_scannedScanResponse.update {
|
||||
requireNotNull(it)
|
||||
transform(it)
|
||||
_scannedScanResponse.update { scanResponse ->
|
||||
requireNotNull(scanResponse)
|
||||
transform(scanResponse)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ import com.tangem.core.decompose.model.Model
|
|||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.domain.card.CardTypesResolver
|
||||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.card.common.util.getBackupCardsCount
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.models.wallet.requireColdWallet
|
||||
|
|
@ -34,6 +34,7 @@ import com.tangem.tap.features.details.ui.cardsettings.domain.CardSettingsIntera
|
|||
import com.tangem.tap.features.details.ui.common.utils.*
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.extensions.addIf
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -57,7 +58,7 @@ internal class CardSettingsModel @Inject constructor(
|
|||
|
||||
private val params = paramsContainer.require<CardSettingsComponent.Params>()
|
||||
|
||||
private var previousBiometricsRequestPolicy: Boolean = false
|
||||
private var isBiometricsRequestPolicyPrevious: Boolean = false
|
||||
|
||||
private val userWalletId = params.userWalletId
|
||||
|
||||
|
|
@ -77,20 +78,19 @@ internal class CardSettingsModel @Inject constructor(
|
|||
// Reset card scanned data
|
||||
cardSettingsInteractor.clear()
|
||||
// Restore the previous value of access code request policy
|
||||
cardSdkConfigRepository.isBiometricsRequestPolicy = previousBiometricsRequestPolicy
|
||||
cardSdkConfigRepository.isBiometricsRequestPolicy = isBiometricsRequestPolicyPrevious
|
||||
}
|
||||
|
||||
private fun updateAccessCodeRequestPolicy() {
|
||||
runBlocking {
|
||||
// !!!IMPORTANT!!!: Do not forget to restore the previous value in onCleared() method
|
||||
previousBiometricsRequestPolicy = cardSdkConfigRepository.isBiometricsRequestPolicy
|
||||
isBiometricsRequestPolicyPrevious = cardSdkConfigRepository.isBiometricsRequestPolicy
|
||||
|
||||
val userWallet = getUserWalletUseCase(userWalletId)
|
||||
.getOrElse { error("User wallet $userWalletId not found") }
|
||||
.requireColdWallet()
|
||||
|
||||
cardSdkConfigRepository.isBiometricsRequestPolicy =
|
||||
userWallet.scanResponse.card.isAccessCodeSet &&
|
||||
cardSdkConfigRepository.isBiometricsRequestPolicy = userWallet.scanResponse.card.isAccessCodeSet &&
|
||||
settingsRepository.shouldSaveAccessCodes()
|
||||
}
|
||||
}
|
||||
|
|
@ -135,34 +135,39 @@ internal class CardSettingsModel @Inject constructor(
|
|||
)
|
||||
val isResetCardAllowed = isResetToFactoryAllowedByCard(card, cardTypesResolver)
|
||||
|
||||
val cardDetails = buildList {
|
||||
CardInfo.CardId(cardId).let(::add)
|
||||
CardInfo.Issuer(card.issuer.name).let(::add)
|
||||
val cardDetails: List<CardInfo> = buildList {
|
||||
add(CardInfo.CardId(cardId))
|
||||
add(CardInfo.Issuer(card.issuer.name))
|
||||
|
||||
if (!cardTypesResolver.isTangemTwins()) {
|
||||
CardInfo.SignedHashes(card.signedHashesCount().toString()).let(::add)
|
||||
}
|
||||
addIf(
|
||||
condition = !cardTypesResolver.isTangemTwins(),
|
||||
element = CardInfo.SignedHashes(card.signedHashesCount().toString()),
|
||||
)
|
||||
|
||||
add(
|
||||
CardInfo.SecurityMode(
|
||||
currentSecurityOption,
|
||||
securityOption = currentSecurityOption,
|
||||
clickable = allowedSecurityOptions.size > 1,
|
||||
).let(::add)
|
||||
),
|
||||
)
|
||||
|
||||
if (card.backupStatus?.isActive == true && card.isAccessCodeSet) {
|
||||
CardInfo.ChangeAccessCode.let(::add)
|
||||
}
|
||||
addIf(
|
||||
condition = card.backupStatus?.isActive == true && card.isAccessCodeSet,
|
||||
element = CardInfo.ChangeAccessCode,
|
||||
)
|
||||
|
||||
if (isAccessCodeRecoveryAllowed(cardTypesResolver)) {
|
||||
CardInfo.AccessCodeRecovery(isAccessCodeRecoveryEnabled(cardTypesResolver, card)).let(::add)
|
||||
}
|
||||
addIf(
|
||||
condition = isAccessCodeRecoveryAllowed(cardTypesResolver),
|
||||
element = CardInfo.AccessCodeRecovery(isAccessCodeRecoveryEnabled(cardTypesResolver, card)),
|
||||
)
|
||||
|
||||
if (isResetCardAllowed) {
|
||||
addIf(isResetCardAllowed) {
|
||||
CardInfo.ResetToFactorySettings(
|
||||
description = getResetToFactoryDescription(
|
||||
isActiveBackupStatus = card.backupStatus?.isActive == true,
|
||||
typesResolver = cardTypesResolver,
|
||||
),
|
||||
).let(::add)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@ import com.tangem.wallet.R
|
|||
@Composable
|
||||
internal fun SettingsScreensScaffold(
|
||||
onBackClick: () -> Unit,
|
||||
content: @Composable () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
@StringRes titleRes: Int? = null,
|
||||
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
|
||||
addBottomInsets: Boolean = true,
|
||||
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
|
||||
content: @Composable () -> Unit,
|
||||
fab: @Composable () -> Unit = {},
|
||||
) {
|
||||
val backgroundColor = TangemTheme.colors.background.secondary
|
||||
|
|
@ -129,18 +129,18 @@ internal fun DetailsMainButton(
|
|||
}
|
||||
|
||||
@Composable
|
||||
internal fun DetailsRadioButtonElement(title: String, subtitle: String, selected: Boolean, onClick: () -> Unit) {
|
||||
internal fun DetailsRadioButtonElement(title: String, subtitle: String, isSelected: Boolean, onClick: () -> Unit) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.selectable(
|
||||
selected = selected,
|
||||
selected = isSelected,
|
||||
onClick = { onClick() },
|
||||
)
|
||||
.padding(start = 20.dp, end = 20.dp, top = 16.dp, bottom = 16.dp),
|
||||
) {
|
||||
RadioButton(
|
||||
selected = selected,
|
||||
selected = isSelected,
|
||||
onClick = null,
|
||||
modifier = Modifier.padding(end = 20.dp),
|
||||
colors = RadioButtonDefaults.colors(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ internal fun isAccessCodeRecoveryAllowed(typeResolver: CardTypesResolver): Boole
|
|||
|
||||
internal fun isAccessCodeRecoveryEnabled(typeResolver: CardTypesResolver, card: CardDTO): Boolean =
|
||||
if (typeResolver.isWallet2()) {
|
||||
card.userSettings?.isUserCodeRecoveryAllowed ?: false
|
||||
card.userSettings?.isUserCodeRecoveryAllowed == true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
@ -27,11 +27,11 @@ import com.tangem.tap.features.details.ui.resetcard.ResetCardScreenState.Dialog
|
|||
@Composable
|
||||
internal fun ResetCardScreen(state: ResetCardScreenState, onBackClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||
SettingsScreensScaffold(
|
||||
onBackClick = onBackClick,
|
||||
modifier = modifier,
|
||||
content = {
|
||||
ResetCardView(state = state)
|
||||
},
|
||||
onBackClick = onBackClick,
|
||||
)
|
||||
|
||||
when (val dialog = state.dialog) {
|
||||
|
|
@ -65,7 +65,7 @@ private fun ResetCardView(state: ResetCardScreenState) {
|
|||
Conditions(state)
|
||||
DynamicSpacer(scrollState = scrollState)
|
||||
SpacerH16()
|
||||
ResetButton(enabled = state.resetButtonEnabled, onResetButtonClick = state.onResetButtonClick)
|
||||
ResetButton(enabled = state.isResetButtonEnabled, onResetButtonClick = state.onResetButtonClick)
|
||||
SpacerH16()
|
||||
}
|
||||
}
|
||||
|
|
@ -113,18 +113,18 @@ private fun Description(text: TextReference) {
|
|||
|
||||
@Composable
|
||||
private fun Conditions(state: ResetCardScreenState) {
|
||||
state.warningsToShow.forEach {
|
||||
when (it) {
|
||||
state.warningsToShow.forEach { warning ->
|
||||
when (warning) {
|
||||
ResetCardScreenState.WarningsToReset.LOST_WALLET_ACCESS -> {
|
||||
ConditionCheckBox(
|
||||
checkedState = state.acceptCondition1Checked,
|
||||
checkedState = state.isAcceptCondition1Checked,
|
||||
onCheckedChange = state.onAcceptCondition1ToggleClick,
|
||||
description = TextReference.Res(R.string.reset_card_to_factory_condition_1),
|
||||
)
|
||||
}
|
||||
ResetCardScreenState.WarningsToReset.LOST_PASSWORD_RESTORE -> {
|
||||
ConditionCheckBox(
|
||||
checkedState = state.acceptCondition2Checked,
|
||||
checkedState = state.isAcceptCondition2Checked,
|
||||
onCheckedChange = state.onAcceptCondition2ToggleClick,
|
||||
description = TextReference.Res(R.string.reset_card_to_factory_condition_2),
|
||||
)
|
||||
|
|
@ -238,12 +238,12 @@ private fun ResetCardScreenSample(modifier: Modifier = Modifier) {
|
|||
) {
|
||||
ResetCardScreen(
|
||||
state = ResetCardScreenState(
|
||||
resetButtonEnabled = true,
|
||||
showResetPasswordButton = false,
|
||||
isResetButtonEnabled = true,
|
||||
isResetPasswordButtonShown = false,
|
||||
warningsToShow = listOf(ResetCardScreenState.WarningsToReset.LOST_WALLET_ACCESS),
|
||||
descriptionText = TextReference.Res(R.string.reset_card_with_backup_to_factory_message),
|
||||
acceptCondition1Checked = false,
|
||||
acceptCondition2Checked = false,
|
||||
isAcceptCondition1Checked = false,
|
||||
isAcceptCondition2Checked = false,
|
||||
onAcceptCondition1ToggleClick = {},
|
||||
onAcceptCondition2ToggleClick = {},
|
||||
onResetButtonClick = {},
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ import com.tangem.tap.features.details.ui.cardsettings.TextReference
|
|||
import com.tangem.wallet.R
|
||||
|
||||
internal data class ResetCardScreenState(
|
||||
val resetButtonEnabled: Boolean,
|
||||
val isResetButtonEnabled: Boolean,
|
||||
val descriptionText: TextReference,
|
||||
val warningsToShow: List<WarningsToReset>,
|
||||
val showResetPasswordButton: Boolean,
|
||||
val acceptCondition1Checked: Boolean,
|
||||
val acceptCondition2Checked: Boolean,
|
||||
val isResetPasswordButtonShown: Boolean,
|
||||
val isAcceptCondition1Checked: Boolean,
|
||||
val isAcceptCondition2Checked: Boolean,
|
||||
val onAcceptCondition1ToggleClick: (Boolean) -> Unit,
|
||||
val onAcceptCondition2ToggleClick: (Boolean) -> Unit,
|
||||
val onResetButtonClick: () -> Unit,
|
||||
|
|
|
|||
|
|
@ -97,15 +97,15 @@ internal class ResetCardModel @Inject constructor(
|
|||
}
|
||||
|
||||
return ResetCardScreenState(
|
||||
resetButtonEnabled = false,
|
||||
isResetButtonEnabled = false,
|
||||
descriptionText = getResetToFactoryDescription(
|
||||
isActiveBackupStatus = isActiveBackupPrimaryCard,
|
||||
typesResolver = currentCardTypesResolver,
|
||||
),
|
||||
warningsToShow = warningsToShow,
|
||||
showResetPasswordButton = shouldShowResetPasswordButton,
|
||||
acceptCondition1Checked = false,
|
||||
acceptCondition2Checked = false,
|
||||
isResetPasswordButtonShown = shouldShowResetPasswordButton,
|
||||
isAcceptCondition1Checked = false,
|
||||
isAcceptCondition2Checked = false,
|
||||
onAcceptCondition1ToggleClick = ::toggleFirstCondition,
|
||||
onAcceptCondition2ToggleClick = ::toggleSecondCondition,
|
||||
onResetButtonClick = { showDialog(ResetCardDialog.StartResetDialog) },
|
||||
|
|
@ -121,26 +121,26 @@ internal class ResetCardModel @Inject constructor(
|
|||
|
||||
private fun toggleFirstCondition(isAccepted: Boolean) {
|
||||
screenState.update { prevState ->
|
||||
val resetButtonEnabled = if (prevState.showResetPasswordButton) {
|
||||
isAccepted && prevState.acceptCondition2Checked
|
||||
val isResetButtonEnabled = if (prevState.isResetPasswordButtonShown) {
|
||||
isAccepted && prevState.isAcceptCondition2Checked
|
||||
} else {
|
||||
isAccepted
|
||||
}
|
||||
|
||||
prevState.copy(
|
||||
acceptCondition1Checked = isAccepted,
|
||||
resetButtonEnabled = resetButtonEnabled,
|
||||
isAcceptCondition1Checked = isAccepted,
|
||||
isResetButtonEnabled = isResetButtonEnabled,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun toggleSecondCondition(isAccepted: Boolean) {
|
||||
screenState.update { prevState ->
|
||||
val resetButtonEnabled = prevState.acceptCondition1Checked && isAccepted
|
||||
val isResetButtonEnabled = prevState.isAcceptCondition1Checked && isAccepted
|
||||
|
||||
prevState.copy(
|
||||
acceptCondition2Checked = isAccepted,
|
||||
resetButtonEnabled = resetButtonEnabled,
|
||||
isAcceptCondition2Checked = isAccepted,
|
||||
isResetButtonEnabled = isResetButtonEnabled,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -183,14 +183,14 @@ internal class ResetCardModel @Inject constructor(
|
|||
modelScope.launch {
|
||||
resetCardUseCase(cardId = primaryCardId, params = currentUserCodeParams).onRight {
|
||||
deleteSavedAccessCodesUseCase(cardId = primaryCardId)
|
||||
val hasUserWallets = deleteWalletUseCase(userWalletId = currentUserWalletId).getOrElse {
|
||||
Timber.e("Unable to delete user wallet: $it")
|
||||
val hasUserWallets = deleteWalletUseCase(userWalletId = currentUserWalletId).getOrElse { error ->
|
||||
Timber.e("Unable to delete user wallet: $error")
|
||||
return@launch
|
||||
}
|
||||
|
||||
if (hasUserWallets) {
|
||||
val newSelectedWallet = getSelectedWalletSyncUseCase().getOrElse {
|
||||
error("Failed to get selected wallet: $it")
|
||||
val newSelectedWallet = getSelectedWalletSyncUseCase().getOrElse { error ->
|
||||
error("Failed to get selected wallet: $error")
|
||||
}
|
||||
|
||||
store.onUserWalletSelected(newSelectedWallet)
|
||||
|
|
@ -269,7 +269,7 @@ internal class ResetCardModel @Inject constructor(
|
|||
if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
store.dispatchNavigationAction { replaceAll(AppRoute.Home()) }
|
||||
} else {
|
||||
val isLocked = runCatching { userWalletsListManager.asLockable()?.isLockedSync }.isSuccess
|
||||
val isLocked = runCatching { userWalletsListManager.asLockable()?.isLocked }.isSuccess
|
||||
if (isLocked && userWalletsListManager.hasUserWallets) {
|
||||
store.dispatchNavigationAction { popTo<AppRoute.Welcome>() }
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ internal fun SecurityModeScreen(
|
|||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
SettingsScreensScaffold(
|
||||
onBackClick = onBackClick,
|
||||
modifier = modifier,
|
||||
content = { SecurityModeOptions(state = state) },
|
||||
// titleRes = R.string.card_settings_security_mode,
|
||||
onBackClick = onBackClick,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ private fun SecurityModeOptions(state: SecurityModeScreenState) {
|
|||
|
||||
@Composable
|
||||
private fun SecurityOption(option: SecurityOption, state: SecurityModeScreenState) {
|
||||
val selected = option == state.selectedSecurityMode
|
||||
val isSelected = option == state.selectedSecurityMode
|
||||
|
||||
val title = option.toTitleRes()
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ private fun SecurityOption(option: SecurityOption, state: SecurityModeScreenStat
|
|||
DetailsRadioButtonElement(
|
||||
title = stringResourceSafe(id = title),
|
||||
subtitle = stringResourceSafe(id = subtitle),
|
||||
selected = selected,
|
||||
isSelected = isSelected,
|
||||
onClick = { state.onNewModeSelected(option) },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,9 +77,9 @@ internal class SecurityModeModel @Inject constructor(
|
|||
SecurityOption.AccessCode -> tangemSdkManager.setAccessCode(cardId)
|
||||
}
|
||||
|
||||
cardSettingsInteractor.update {
|
||||
it.copy(
|
||||
card = it.card.copy(
|
||||
cardSettingsInteractor.update { scanResponse ->
|
||||
scanResponse.copy(
|
||||
card = scanResponse.card.copy(
|
||||
isAccessCodeSet = selectedOption == SecurityOption.AccessCode,
|
||||
isPasscodeSet = selectedOption == SecurityOption.PassCode,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ internal class MainViewModel @Inject constructor(
|
|||
prepareSelectedWalletFeedback()
|
||||
|
||||
// await while initial route stack is initialized
|
||||
appRouterConfig.isInitialized.first { it }
|
||||
appRouterConfig.initializedState.first { it }
|
||||
|
||||
isSplashScreenShown = false
|
||||
}
|
||||
|
|
@ -179,11 +179,9 @@ internal class MainViewModel @Inject constructor(
|
|||
private fun prepareSelectedWalletFeedback() {
|
||||
getSelectedWalletUseCase.invoke()
|
||||
.mapLeft { emptyFlow<UserWallet>() }
|
||||
.onRight {
|
||||
it.distinctUntilChanged()
|
||||
.onEach { userWallet ->
|
||||
Analytics.setContext(userWallet)
|
||||
}
|
||||
.onRight { wallet ->
|
||||
wallet.distinctUntilChanged()
|
||||
.onEach { Analytics.setContext(it) }
|
||||
.flowOn(dispatchers.io)
|
||||
.launchIn(viewModelScope)
|
||||
}
|
||||
|
|
@ -208,7 +206,7 @@ internal class MainViewModel @Inject constructor(
|
|||
return MoonPayService(
|
||||
apiKey = environmentConfig.moonPayApiKey,
|
||||
secretKey = environmentConfig.moonPayApiSecretKey,
|
||||
logEnabled = LogConfig.network.moonPayService,
|
||||
isLogEnabled = LogConfig.network.moonPayService,
|
||||
userWalletProvider = { getSelectedWalletUseCase.sync().getOrNull() },
|
||||
)
|
||||
}
|
||||
|
|
@ -224,8 +222,8 @@ internal class MainViewModel @Inject constructor(
|
|||
.filter {
|
||||
it.isBalanceHidingNotificationEnabled && it.isBalanceHidden
|
||||
}
|
||||
.onEach {
|
||||
if (!it.isUpdateFromToast) {
|
||||
.onEach { settings ->
|
||||
if (!settings.isUpdateFromToast) {
|
||||
listenToFlipsUseCase.changeUpdateEnabled(false)
|
||||
|
||||
val message = BottomSheetMessage.invoke(
|
||||
|
|
@ -354,6 +352,7 @@ internal class MainViewModel @Inject constructor(
|
|||
listenToFlipsUseCase.changeUpdateEnabled(isUpdateEnabled = true)
|
||||
}
|
||||
|
||||
@Suppress("NullableToStringCall")
|
||||
private fun sendKeyboardIdentifierEvent() {
|
||||
viewModelScope.launch {
|
||||
val keyboardId = keyboardValidator.getKeyboardId()
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ object OnboardingHelper {
|
|||
}
|
||||
|
||||
response.cardTypesResolver.isWallet2() || response.cardTypesResolver.isShibaWallet() -> {
|
||||
val emptyWallets = response.card.wallets.isEmpty()
|
||||
val activationInProgress = cardRepository.isActivationInProgress(cardId)
|
||||
val areWalletsEmpty = response.card.wallets.isEmpty()
|
||||
val isActivationInProgress = cardRepository.isActivationInProgress(cardId)
|
||||
val isNoBackup = response.card.backupStatus == CardDTO.BackupStatus.NoBackup &&
|
||||
!DemoHelper.isDemoCard(response)
|
||||
emptyWallets || activationInProgress || isNoBackup
|
||||
areWalletsEmpty || isActivationInProgress || isNoBackup
|
||||
}
|
||||
|
||||
response.card.wallets.isNotEmpty() -> cardRepository.isActivationInProgress(cardId)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue