From 3544fd7e4490f86cbc0bd6c1fc6c49800d62618f Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 13 Jul 2020 10:32:23 +0300 Subject: [PATCH] Updated on 2026-08-14 --- blockchain-demo/build.gradle | 5 +- blockchain/build.gradle | 3 +- build.gradle | 1 + settings.gradle | 2 +- tangem-core/.gitignore | 1 - tangem-core/build.gradle | 78 ---- .../src/main/java/com/tangem/CardFilter.kt | 14 - .../src/main/java/com/tangem/CardReader.kt | 53 --- .../src/main/java/com/tangem/CardSession.kt | 318 ------------- .../src/main/java/com/tangem/Config.kt | 53 --- tangem-core/src/main/java/com/tangem/Log.kt | 34 -- .../java/com/tangem/SessionEnvironment.kt | 63 --- .../com/tangem/SessionEnvironmentService.kt | 77 --- .../java/com/tangem/SessionViewDelegate.kt | 63 --- .../src/main/java/com/tangem/TangemSdk.kt | 440 ------------------ .../main/java/com/tangem/TangemSdkError.kt | 163 ------- .../com/tangem/commands/CheckWalletCommand.kt | 101 ---- .../main/java/com/tangem/commands/Command.kt | 237 ---------- .../tangem/commands/CreateWalletCommand.kt | 86 ---- .../com/tangem/commands/OpenSessionCommand.kt | 44 -- .../com/tangem/commands/PurgeWalletCommand.kt | 78 ---- .../java/com/tangem/commands/ReadCommand.kt | 396 ---------------- .../tangem/commands/ReadIssuerDataCommand.kt | 119 ----- .../commands/ReadIssuerExtraDataCommand.kt | 178 ------- .../tangem/commands/ReadUserDataCommand.kt | 82 ---- .../java/com/tangem/commands/SetPinCommand.kt | 82 ---- .../java/com/tangem/commands/SignCommand.kt | 121 ----- .../tangem/commands/WriteIssuerDataCommand.kt | 111 ----- .../commands/WriteIssuerExtraDataCommand.kt | 196 -------- .../tangem/commands/WriteUserDataCommand.kt | 80 ---- .../commands/common/CardDeserializer.kt | 67 --- .../tangem/commands/common/IssuerDataMode.kt | 44 -- .../commands/common/IssuerDataVerifier.kt | 40 -- .../commands/common/ResponseConverter.kt | 119 ----- .../commands/common/network/NetworkUtils.kt | 39 -- .../common/network/RetrofitBuilder.kt | 30 -- .../commands/common/network/TangemApi.kt | 17 - .../commands/common/network/TangemService.kt | 22 - .../personalization/DepersonalizeCommand.kt | 31 -- .../commands/personalization/NdefEncoder.kt | 88 ---- .../personalization/PersonalizeCommand.kt | 125 ----- .../personalization/entities/Acquirer.kt | 9 - .../personalization/entities/CardConfig.kt | 77 --- .../entities/CardConfigExtensions.kt | 81 ---- .../personalization/entities/Issuer.kt | 10 - .../personalization/entities/Manufacturer.kt | 8 - .../commands/verifycard/VerifyCardCommand.kt | 159 ------- .../commands/verifycard/VerifyCardRequest.kt | 60 --- .../com/tangem/common/CardValuesStorage.kt | 56 --- .../com/tangem/common/CompletionResult.kt | 13 - .../main/java/com/tangem/common/PinCode.kt | 10 - .../com/tangem/common/TerminalKeysService.kt | 14 - .../com/tangem/common/apdu/CommandApdu.kt | 89 ---- .../com/tangem/common/apdu/Instruction.kt | 32 -- .../com/tangem/common/apdu/ResponseApdu.kt | 64 --- .../java/com/tangem/common/apdu/StatusWord.kt | 49 -- .../tangem/common/extensions/BigDecimal.kt | 7 - .../com/tangem/common/extensions/ByteArray.kt | 74 --- .../java/com/tangem/common/extensions/Card.kt | 22 - .../tangem/common/extensions/IntExtensions.kt | 16 - .../java/com/tangem/common/extensions/List.kt | 13 - .../com/tangem/common/extensions/String.kt | 26 -- .../main/java/com/tangem/common/tlv/Tlv.kt | 105 ----- .../java/com/tangem/common/tlv/TlvBuilder.kt | 21 - .../java/com/tangem/common/tlv/TlvDecoder.kt | 162 ------- .../java/com/tangem/common/tlv/TlvEncoder.kt | 112 ----- .../main/java/com/tangem/common/tlv/TlvTag.kt | 150 ------ .../java/com/tangem/crypto/CryptoUtils.kt | 121 ----- .../main/java/com/tangem/crypto/Ed25519.kt | 55 --- .../com/tangem/crypto/EncryptionHelper.kt | 61 --- .../src/main/java/com/tangem/crypto/Pbkdf2.kt | 88 ---- .../main/java/com/tangem/crypto/Secp256k1.kt | 118 ----- .../java/com/tangem/tasks/ChangePinTask.kt | 101 ---- .../java/com/tangem/tasks/CreateWalletTask.kt | 45 -- .../main/java/com/tangem/tasks/ScanTask.kt | 87 ---- .../sqldelight/com/tangem/CardValuesEntity.sq | 34 -- .../com/tangem/common/apdu/CommandApduTest.kt | 55 --- .../tangem/common/apdu/ResponseApduTest.kt | 44 -- .../extensions/ByteArrayExtensionsTest.kt | 105 ----- .../common/extensions/IntExtensionsTest.kt | 24 - .../common/extensions/StringExtensionsTest.kt | 53 --- .../com/tangem/common/tlv/TlvDecoderTest.kt | 192 -------- .../java/com/tangem/common/tlv/TlvTest.kt | 111 ----- .../java/com/tangem/crypto/CryptoUtilsTest.kt | 50 -- tangem-devkit/.gitignore | 1 - tangem-devkit/build.gradle | 56 --- tangem-devkit/proguard-rules.pro | 21 - tangem-devkit/src/main/AndroidManifest.xml | 80 ---- .../src/main/ic_launcher-playstore.png | Bin 14393 -> 0 bytes .../java/com/tangem/devkit/AppTangemDemo.kt | 35 -- .../com/tangem/devkit/Old_MainActivity.kt | 143 ------ .../com/tangem/devkit/TestUserDataActivity.kt | 146 ------ .../tangem/devkit/_arch/SingleLiveEvent.kt | 44 -- .../devkit/_arch/structure/HelpAbstracts.kt | 16 - .../com/tangem/devkit/_arch/structure/Ids.kt | 25 - .../tangem/devkit/_arch/structure/Logger.kt | 36 -- .../_arch/structure/abstraction/Extension.kt | 29 -- .../_arch/structure/abstraction/Item.kt | 47 -- .../_arch/structure/abstraction/ItemGroup.kt | 56 --- .../structure/abstraction/ItemViewModel.kt | 115 ----- .../structure/abstraction/ModelConverter.kt | 20 - .../_arch/structure/abstraction/Plugin.kt | 10 - .../devkit/_arch/structure/impl/Items.kt | 39 -- .../devkit/_arch/widget/ItemWidgetBuilder.kt | 12 - .../devkit/_arch/widget/WidgetBuilder.kt | 36 -- .../_arch/widget/abstraction/ViewWidget.kt | 81 ---- .../_arch/widget/impl/LinearGroupWidget.kt | 18 - .../devkit/_arch/widget/impl/StubWidget.kt | 15 - .../com/tangem/devkit/_main/MainActivity.kt | 75 --- .../com/tangem/devkit/_main/MainViewModel.kt | 28 -- .../_main/entryPoint/ActionListFragment.kt | 78 ---- .../devkit/_main/entryPoint/RvActions.kt | 67 --- .../com/tangem/devkit/commons/Abstractions.kt | 16 - .../tangem/devkit/commons/DialogController.kt | 76 --- .../tangem/devkit/commons/GlobalFunctions.kt | 9 - .../java/com/tangem/devkit/commons/Logger.kt | 8 - .../devkit/commons/view/MultiActionView.kt | 85 ---- .../devkit/extensions/AndroidComponents.kt | 31 -- .../java/com/tangem/devkit/extensions/List.kt | 16 - .../devkit/extensions/view/Transitions.kt | 13 - .../com/tangem/devkit/ucase/NavigationOp.kt | 19 - .../devkit/ucase/domain/actions/Action.kt | 48 -- .../domain/actions/CreateWalletAction.kt | 23 - .../domain/actions/DepersonalizeAction.kt | 14 - .../ucase/domain/actions/PersonalizeAction.kt | 66 --- .../ucase/domain/actions/PurgeWalletAction.kt | 23 - .../domain/actions/ReadIssuerDataAction.kt | 23 - .../actions/ReadIssuerExtraDataAction.kt | 23 - .../domain/actions/ReadUserDataAction.kt | 23 - .../devkit/ucase/domain/actions/ScanAction.kt | 14 - .../devkit/ucase/domain/actions/SignAction.kt | 28 -- .../domain/actions/WriteIssuerDataAction.kt | 37 -- .../actions/WriteIssuerExtraDataAction.kt | 45 -- .../domain/actions/WriteUserDataAction.kt | 28 -- .../actions/WriteUserProtectedDataAction.kt | 29 -- .../domain/paramsManager/ItemsManager.kt | 39 -- .../managers/BaseItemsManager.kt | 74 --- .../managers/PersonalizationItemsManager.kt | 35 -- .../paramsManager/managers/SimpleManagers.kt | 107 ----- .../afterAction/AfterActionModifiers.kt | 16 - .../triggers/afterAction/AfterScanModifier.kt | 42 -- .../ParamChangeConsequence.kt | 30 -- .../com/tangem/devkit/ucase/resources/Ids.kt | 23 - .../ucase/resources/MainResourceHolder.kt | 48 -- .../devkit/ucase/resources/ResourseTypes.kt | 15 - .../resources/initializers/ActionResources.kt | 30 -- .../initializers/PersonalizationResources.kt | 128 ----- .../initializers/ResponseResources.kt | 114 ----- .../resources/initializers/TlvResources.kt | 24 - .../com/tangem/devkit/ucase/tunnel/Errors.kt | 17 - .../tangem/devkit/ucase/tunnel/ViewScreen.kt | 16 - .../tangem/devkit/ucase/ui/ActionViewModel.kt | 178 ------- .../devkit/ucase/ui/BaseCardActionFragment.kt | 162 ------- .../tangem/devkit/ucase/ui/BaseFragment.kt | 38 -- .../ucase/ui/widgets/ParameterWidget.kt | 119 ----- .../com/tangem/devkit/ucase/variants/Ids.kt | 15 - .../ui/CreateWalletActionFragment.kt | 10 - .../ui/DepersonalizeActionFragment.kt | 56 --- .../issuerdata/ui/ReadIssuerDataFragment.kt | 10 - .../ui/ReadIssuerExtraDataFragment.kt | 10 - .../issuerdata/ui/WriteIssuerDataFragment.kt | 10 - .../ui/WriteIssuerExtraDataFragment.kt | 10 - .../devkit/ucase/variants/personalize/Ids.kt | 110 ----- .../personalize/PersonalizationConfigStore.kt | 53 --- .../personalize/converter/DefaultValues.kt | 136 ------ .../personalize/converter/ItemTypes.kt | 118 ----- .../PersonalizationConfigConverter.kt | 301 ------------ .../converter/PersonalizationJsonConverter.kt | 204 -------- .../dto/DefaultPersonalizationParams.kt | 55 --- .../variants/personalize/dto/Manufacturer.kt | 53 --- .../personalize/dto/PersonalizationConfig.kt | 232 --------- .../personalize/dto/PersonalizationJson.kt | 148 ------ .../personalize/ui/PersonalizationFragment.kt | 271 ----------- .../presets/PersonalizationPresetManager.kt | 77 --- .../ui/presets/PersonalizationPresetView.kt | 9 - .../personalize/ui/presets/PresetRv.kt | 46 -- .../personalize/ui/widgets/BaseAppWidget.kt | 28 -- .../ui/widgets/DescriptionWidget.kt | 36 -- .../personalize/ui/widgets/EditTextWidget.kt | 48 -- .../personalize/ui/widgets/NumberWidget.kt | 59 --- .../ui/widgets/PersonalizationItemBuilder.kt | 23 - .../personalize/ui/widgets/SpinnerWidget.kt | 94 ---- .../personalize/ui/widgets/SwitchWidget.kt | 35 -- .../ui/widgets/TextHeaderWidget.kt | 19 - .../ui/PurgeWalletActionFragment.kt | 10 - .../devkit/ucase/variants/responses/Ids.kt | 90 ---- .../variants/responses/ResponseViewModel.kt | 60 --- .../converter/BaseResponseConverter.kt | 27 -- .../responses/converter/CardConverter.kt | 95 ---- .../responses/converter/ConvertersStore.kt | 22 - .../responses/converter/SimpleConverters.kt | 99 ---- .../ucase/variants/responses/item/TextItem.kt | 12 - .../variants/responses/ui/ResponseFragment.kt | 84 ---- .../responses/ui/widget/CheckBoxWidget.kt | 27 -- .../ui/widget/ResponseItemBuilder.kt | 23 - .../responses/ui/widget/ResponseTextWidget.kt | 45 -- .../responses/ui/widget/ResponseWidget.kt | 27 -- .../variants/scan/ui/ScanActionFragment.kt | 56 --- .../variants/sign/ui/SignActionFragment.kt | 13 - .../userdata/ui/ReadUserDataFragment.kt | 10 - .../ui/WriteProtectedUserDataFragment.kt | 10 - .../userdata/ui/WriteUserDataFragment.kt | 10 - tangem-devkit/src/main/res/anim/fade_in.xml | 22 - tangem-devkit/src/main/res/anim/fade_out.xml | 22 - .../src/main/res/anim/slide_in_left.xml | 10 - .../src/main/res/anim/slide_in_right.xml | 10 - .../src/main/res/anim/slide_out_left.xml | 10 - .../src/main/res/anim/slide_out_right.xml | 10 - .../res/color/menu_switch_color_thumb.xml | 5 - .../res/color/menu_switch_color_track.xml | 5 - .../res/color/mtrl_fab_bg_color_selector.xml | 6 - .../mtrl_fab_icon_text_color_selector.xml | 6 - .../drawable-v24/ic_launcher_foreground.xml | 34 -- .../src/main/res/drawable/ic_import.xml | 12 - .../res/drawable/ic_launcher_background.xml | 74 --- .../main/res/drawable/ic_share_white_18dp.xml | 9 - tangem-devkit/src/main/res/layout/a_main.xml | 23 - .../res/layout/activity_test_user_data.xml | 238 ---------- .../dlg_personalization_preset_load.xml | 21 - .../dlg_personalization_preset_save.xml | 25 - .../main/res/layout/fg_base_action_layout.xml | 21 - .../src/main/res/layout/fg_card_response.xml | 22 - .../src/main/res/layout/fg_entry_point.xml | 15 - .../res/layout/fg_personalization_footer.xml | 18 - .../src/main/res/layout/m_divider_h.xml | 6 - .../src/main/res/layout/m_divider_v.xml | 6 - .../src/main/res/layout/menu_item_switch.xml | 9 - .../src/main/res/layout/old_activity_main.xml | 132 ------ .../main/res/layout/v_content_container.xml | 20 - .../main/res/layout/v_export_import_json.xml | 37 -- .../main/res/layout/v_item_list_container.xml | 26 -- .../src/main/res/layout/vh_actions.xml | 35 -- .../layout/vh_personalization_preset_name.xml | 35 -- .../main/res/layout/vh_sp_dropdown_item.xml | 11 - .../src/main/res/layout/vh_sp_item.xml | 9 - .../res/layout/w_action_response_json.xml | 8 - .../main/res/layout/w_card_incoming_param.xml | 60 --- tangem-devkit/src/main/res/layout/w_empty.xml | 4 - .../main/res/layout/w_field_description.xml | 19 - .../layout/w_personalize_item_edit_text.xml | 47 -- .../res/layout/w_personalize_item_header.xml | 36 -- .../res/layout/w_personalize_item_number.xml | 48 -- .../res/layout/w_personalize_item_spinner.xml | 45 -- .../res/layout/w_personalize_item_switch.xml | 38 -- .../layout/w_personalize_widgets_together.xml | 21 - .../main/res/layout/w_personilize_block.xml | 5 - .../src/main/res/layout/w_response_item.xml | 45 -- .../res/layout/w_response_item_checkbox.xml | 41 -- .../res/layout/w_response_item_header.xml | 35 -- .../src/main/res/menu/menu_activity_main.xml | 11 - .../main/res/menu/menu_fg_peronalization.xml | 32 -- .../src/main/res/menu/menu_fg_response.xml | 11 - .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 - .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 - .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 1425 -> 0 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 1728 -> 0 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 3249 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 988 -> 0 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 1101 -> 0 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 2059 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 1953 -> 0 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 2465 -> 0 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 4553 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 3061 -> 0 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 4276 -> 0 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 7425 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 4348 -> 0 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 6231 -> 0 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 10769 -> 0 bytes .../src/main/res/navigation/navigation.xml | 149 ------ tangem-devkit/src/main/res/values/colors.xml | 26 -- tangem-devkit/src/main/res/values/dimens.xml | 10 - .../main/res/values/dimens_item_widget.xml | 12 - .../res/values/ic_launcher_background.xml | 4 - tangem-devkit/src/main/res/values/strings.xml | 45 -- .../src/main/res/values/strings_action.xml | 35 -- .../res/values/strings_personalization.xml | 178 ------- .../src/main/res/values/strings_response.xml | 179 ------- .../src/main/res/values/strings_scan.xml | 7 - .../src/main/res/values/strings_tlv.xml | 18 - tangem-devkit/src/main/res/values/styles.xml | 23 - .../src/main/res/values/theme_debug.xml | 73 --- .../src/main/res/xml/nfc_tech_filter.xml | 8 - tangem-sdk/.gitignore | 1 - tangem-sdk/build.gradle | 71 --- tangem-sdk/consumer-rules.pro | 0 tangem-sdk/proguard-rules.pro | 21 - tangem-sdk/src/main/AndroidManifest.xml | 5 - .../DefaultSessionViewDelegate.kt | 106 ----- .../tangem_sdk_new/NfcLifecycleObserver.kt | 28 -- .../SessionViewDelegateState.kt | 17 - .../tangem_sdk_new/TerminalKeysStorage.kt | 56 --- .../java/com/tangem/tangem_sdk_new/Utils.kt | 10 - .../tangem_sdk_new/extensions/TangemSdk.kt | 50 -- .../extensions/TangemSdkError.kt | 57 --- .../tangem/tangem_sdk_new/extensions/View.kt | 20 - .../tangem/tangem_sdk_new/nfc/NfcManager.kt | 111 ----- .../tangem/tangem_sdk_new/nfc/NfcReader.kt | 127 ----- .../tangem_sdk_new/nfc/SlixTagReader.kt | 123 ----- .../tangem_sdk_new/ui/NfcEnableDialog.kt | 29 -- .../tangem/tangem_sdk_new/ui/NfcLocation.kt | 245 ---------- .../tangem_sdk_new/ui/NfcSessionDialog.kt | 268 ----------- .../tangem_sdk_new/ui/TouchCardAnimation.kt | 99 ---- .../res/drawable/hand_card_horizontal.png | Bin 17362 -> 0 bytes .../main/res/drawable/hand_card_vertical.png | Bin 15582 -> 0 bytes .../main/res/drawable/ic_action_nfc_gray.png | Bin 536 -> 0 bytes .../src/main/res/drawable/ic_done_135dp.xml | 9 - tangem-sdk/src/main/res/drawable/ic_error.xml | 6 - .../res/drawable/ic_error_outline_135dp.xml | 4 - tangem-sdk/src/main/res/drawable/ic_nfc.xml | 10 - .../src/main/res/drawable/pb_circle.xml | 45 -- .../main/res/drawable/pb_simple_circle.xml | 21 - .../src/main/res/drawable/smartphone.png | Bin 4876 -> 0 bytes .../src/main/res/layout/layout_touch_card.xml | 70 --- .../src/main/res/layout/nfc_bottom_sheet.xml | 276 ----------- tangem-sdk/src/main/res/values/colors.xml | 11 - tangem-sdk/src/main/res/values/dimens.xml | 4 - tangem-sdk/src/main/res/values/strings.xml | 23 - .../src/main/res/values/strings_errors.xml | 33 -- 319 files changed, 6 insertions(+), 17138 deletions(-) delete mode 100644 tangem-core/.gitignore delete mode 100644 tangem-core/build.gradle delete mode 100644 tangem-core/src/main/java/com/tangem/CardFilter.kt delete mode 100644 tangem-core/src/main/java/com/tangem/CardReader.kt delete mode 100644 tangem-core/src/main/java/com/tangem/CardSession.kt delete mode 100644 tangem-core/src/main/java/com/tangem/Config.kt delete mode 100644 tangem-core/src/main/java/com/tangem/Log.kt delete mode 100644 tangem-core/src/main/java/com/tangem/SessionEnvironment.kt delete mode 100644 tangem-core/src/main/java/com/tangem/SessionEnvironmentService.kt delete mode 100644 tangem-core/src/main/java/com/tangem/SessionViewDelegate.kt delete mode 100644 tangem-core/src/main/java/com/tangem/TangemSdk.kt delete mode 100644 tangem-core/src/main/java/com/tangem/TangemSdkError.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/CheckWalletCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/Command.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/CreateWalletCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/OpenSessionCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/PurgeWalletCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/ReadCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/ReadIssuerDataCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/ReadIssuerExtraDataCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/ReadUserDataCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/SetPinCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/SignCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/WriteIssuerDataCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/WriteIssuerExtraDataCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/WriteUserDataCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/common/CardDeserializer.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/common/IssuerDataMode.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/common/IssuerDataVerifier.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/common/ResponseConverter.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/common/network/NetworkUtils.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/common/network/RetrofitBuilder.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/common/network/TangemApi.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/common/network/TangemService.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/personalization/DepersonalizeCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/personalization/NdefEncoder.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/personalization/entities/Acquirer.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfig.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfigExtensions.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/personalization/entities/Issuer.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/personalization/entities/Manufacturer.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/verifycard/VerifyCardCommand.kt delete mode 100644 tangem-core/src/main/java/com/tangem/commands/verifycard/VerifyCardRequest.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/CardValuesStorage.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/CompletionResult.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/PinCode.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/TerminalKeysService.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/apdu/CommandApdu.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/apdu/Instruction.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/apdu/ResponseApdu.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/apdu/StatusWord.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/extensions/BigDecimal.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/extensions/ByteArray.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/extensions/Card.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/extensions/IntExtensions.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/extensions/List.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/extensions/String.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/tlv/Tlv.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/tlv/TlvBuilder.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/tlv/TlvDecoder.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/tlv/TlvEncoder.kt delete mode 100644 tangem-core/src/main/java/com/tangem/common/tlv/TlvTag.kt delete mode 100644 tangem-core/src/main/java/com/tangem/crypto/CryptoUtils.kt delete mode 100644 tangem-core/src/main/java/com/tangem/crypto/Ed25519.kt delete mode 100644 tangem-core/src/main/java/com/tangem/crypto/EncryptionHelper.kt delete mode 100644 tangem-core/src/main/java/com/tangem/crypto/Pbkdf2.kt delete mode 100644 tangem-core/src/main/java/com/tangem/crypto/Secp256k1.kt delete mode 100644 tangem-core/src/main/java/com/tangem/tasks/ChangePinTask.kt delete mode 100644 tangem-core/src/main/java/com/tangem/tasks/CreateWalletTask.kt delete mode 100644 tangem-core/src/main/java/com/tangem/tasks/ScanTask.kt delete mode 100644 tangem-core/src/main/sqldelight/com/tangem/CardValuesEntity.sq delete mode 100644 tangem-core/src/test/java/com/tangem/common/apdu/CommandApduTest.kt delete mode 100644 tangem-core/src/test/java/com/tangem/common/apdu/ResponseApduTest.kt delete mode 100644 tangem-core/src/test/java/com/tangem/common/extensions/ByteArrayExtensionsTest.kt delete mode 100644 tangem-core/src/test/java/com/tangem/common/extensions/IntExtensionsTest.kt delete mode 100644 tangem-core/src/test/java/com/tangem/common/extensions/StringExtensionsTest.kt delete mode 100644 tangem-core/src/test/java/com/tangem/common/tlv/TlvDecoderTest.kt delete mode 100644 tangem-core/src/test/java/com/tangem/common/tlv/TlvTest.kt delete mode 100644 tangem-core/src/test/java/com/tangem/crypto/CryptoUtilsTest.kt delete mode 100644 tangem-devkit/.gitignore delete mode 100644 tangem-devkit/build.gradle delete mode 100644 tangem-devkit/proguard-rules.pro delete mode 100644 tangem-devkit/src/main/AndroidManifest.xml delete mode 100644 tangem-devkit/src/main/ic_launcher-playstore.png delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/AppTangemDemo.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/Old_MainActivity.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/TestUserDataActivity.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/SingleLiveEvent.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/HelpAbstracts.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/Ids.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/Logger.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/Extension.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/Item.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/ItemGroup.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/ItemViewModel.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/ModelConverter.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/Plugin.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/impl/Items.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/ItemWidgetBuilder.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/WidgetBuilder.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/abstraction/ViewWidget.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/impl/LinearGroupWidget.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/impl/StubWidget.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_main/MainActivity.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_main/MainViewModel.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_main/entryPoint/ActionListFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/_main/entryPoint/RvActions.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/commons/Abstractions.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/commons/DialogController.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/commons/GlobalFunctions.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/commons/Logger.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/commons/view/MultiActionView.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/extensions/AndroidComponents.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/extensions/List.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/extensions/view/Transitions.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/NavigationOp.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/Action.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/CreateWalletAction.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/DepersonalizeAction.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/PersonalizeAction.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/PurgeWalletAction.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ReadIssuerDataAction.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ReadIssuerExtraDataAction.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ReadUserDataAction.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ScanAction.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/SignAction.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteIssuerDataAction.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteIssuerExtraDataAction.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteUserDataAction.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteUserProtectedDataAction.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/ItemsManager.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/managers/BaseItemsManager.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/managers/PersonalizationItemsManager.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/managers/SimpleManagers.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/triggers/afterAction/AfterActionModifiers.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/triggers/afterAction/AfterScanModifier.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/triggers/changeConsequence/ParamChangeConsequence.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/Ids.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/MainResourceHolder.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/ResourseTypes.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/ActionResources.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/PersonalizationResources.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/ResponseResources.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/TlvResources.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/tunnel/Errors.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/tunnel/ViewScreen.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/ActionViewModel.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/BaseCardActionFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/BaseFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/widgets/ParameterWidget.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/Ids.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/createwallet/ui/CreateWalletActionFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/depersonalize/ui/DepersonalizeActionFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/ReadIssuerDataFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/ReadIssuerExtraDataFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/WriteIssuerDataFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/WriteIssuerExtraDataFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/Ids.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/PersonalizationConfigStore.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/DefaultValues.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/ItemTypes.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/PersonalizationConfigConverter.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/PersonalizationJsonConverter.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/DefaultPersonalizationParams.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/Manufacturer.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/PersonalizationConfig.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/PersonalizationJson.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/ui/PersonalizationFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/ui/presets/PersonalizationPresetManager.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/ui/presets/PersonalizationPresetView.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/ui/presets/PresetRv.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/ui/widgets/BaseAppWidget.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/ui/widgets/DescriptionWidget.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/ui/widgets/EditTextWidget.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/ui/widgets/NumberWidget.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/ui/widgets/PersonalizationItemBuilder.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/ui/widgets/SpinnerWidget.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/ui/widgets/SwitchWidget.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/ui/widgets/TextHeaderWidget.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/purgewallet/ui/PurgeWalletActionFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/responses/Ids.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/responses/ResponseViewModel.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/responses/converter/BaseResponseConverter.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/responses/converter/CardConverter.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/responses/converter/ConvertersStore.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/responses/converter/SimpleConverters.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/responses/item/TextItem.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/responses/ui/ResponseFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/responses/ui/widget/CheckBoxWidget.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/responses/ui/widget/ResponseItemBuilder.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/responses/ui/widget/ResponseTextWidget.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/responses/ui/widget/ResponseWidget.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/scan/ui/ScanActionFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/sign/ui/SignActionFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/userdata/ui/ReadUserDataFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/userdata/ui/WriteProtectedUserDataFragment.kt delete mode 100644 tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/userdata/ui/WriteUserDataFragment.kt delete mode 100644 tangem-devkit/src/main/res/anim/fade_in.xml delete mode 100644 tangem-devkit/src/main/res/anim/fade_out.xml delete mode 100644 tangem-devkit/src/main/res/anim/slide_in_left.xml delete mode 100644 tangem-devkit/src/main/res/anim/slide_in_right.xml delete mode 100644 tangem-devkit/src/main/res/anim/slide_out_left.xml delete mode 100644 tangem-devkit/src/main/res/anim/slide_out_right.xml delete mode 100644 tangem-devkit/src/main/res/color/menu_switch_color_thumb.xml delete mode 100644 tangem-devkit/src/main/res/color/menu_switch_color_track.xml delete mode 100644 tangem-devkit/src/main/res/color/mtrl_fab_bg_color_selector.xml delete mode 100644 tangem-devkit/src/main/res/color/mtrl_fab_icon_text_color_selector.xml delete mode 100644 tangem-devkit/src/main/res/drawable-v24/ic_launcher_foreground.xml delete mode 100644 tangem-devkit/src/main/res/drawable/ic_import.xml delete mode 100644 tangem-devkit/src/main/res/drawable/ic_launcher_background.xml delete mode 100644 tangem-devkit/src/main/res/drawable/ic_share_white_18dp.xml delete mode 100644 tangem-devkit/src/main/res/layout/a_main.xml delete mode 100644 tangem-devkit/src/main/res/layout/activity_test_user_data.xml delete mode 100644 tangem-devkit/src/main/res/layout/dlg_personalization_preset_load.xml delete mode 100644 tangem-devkit/src/main/res/layout/dlg_personalization_preset_save.xml delete mode 100644 tangem-devkit/src/main/res/layout/fg_base_action_layout.xml delete mode 100644 tangem-devkit/src/main/res/layout/fg_card_response.xml delete mode 100644 tangem-devkit/src/main/res/layout/fg_entry_point.xml delete mode 100644 tangem-devkit/src/main/res/layout/fg_personalization_footer.xml delete mode 100644 tangem-devkit/src/main/res/layout/m_divider_h.xml delete mode 100644 tangem-devkit/src/main/res/layout/m_divider_v.xml delete mode 100644 tangem-devkit/src/main/res/layout/menu_item_switch.xml delete mode 100644 tangem-devkit/src/main/res/layout/old_activity_main.xml delete mode 100644 tangem-devkit/src/main/res/layout/v_content_container.xml delete mode 100644 tangem-devkit/src/main/res/layout/v_export_import_json.xml delete mode 100644 tangem-devkit/src/main/res/layout/v_item_list_container.xml delete mode 100644 tangem-devkit/src/main/res/layout/vh_actions.xml delete mode 100644 tangem-devkit/src/main/res/layout/vh_personalization_preset_name.xml delete mode 100644 tangem-devkit/src/main/res/layout/vh_sp_dropdown_item.xml delete mode 100644 tangem-devkit/src/main/res/layout/vh_sp_item.xml delete mode 100644 tangem-devkit/src/main/res/layout/w_action_response_json.xml delete mode 100644 tangem-devkit/src/main/res/layout/w_card_incoming_param.xml delete mode 100644 tangem-devkit/src/main/res/layout/w_empty.xml delete mode 100644 tangem-devkit/src/main/res/layout/w_field_description.xml delete mode 100644 tangem-devkit/src/main/res/layout/w_personalize_item_edit_text.xml delete mode 100644 tangem-devkit/src/main/res/layout/w_personalize_item_header.xml delete mode 100644 tangem-devkit/src/main/res/layout/w_personalize_item_number.xml delete mode 100644 tangem-devkit/src/main/res/layout/w_personalize_item_spinner.xml delete mode 100644 tangem-devkit/src/main/res/layout/w_personalize_item_switch.xml delete mode 100644 tangem-devkit/src/main/res/layout/w_personalize_widgets_together.xml delete mode 100644 tangem-devkit/src/main/res/layout/w_personilize_block.xml delete mode 100644 tangem-devkit/src/main/res/layout/w_response_item.xml delete mode 100644 tangem-devkit/src/main/res/layout/w_response_item_checkbox.xml delete mode 100644 tangem-devkit/src/main/res/layout/w_response_item_header.xml delete mode 100644 tangem-devkit/src/main/res/menu/menu_activity_main.xml delete mode 100644 tangem-devkit/src/main/res/menu/menu_fg_peronalization.xml delete mode 100644 tangem-devkit/src/main/res/menu/menu_fg_response.xml delete mode 100644 tangem-devkit/src/main/res/mipmap-anydpi-v26/ic_launcher.xml delete mode 100644 tangem-devkit/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml delete mode 100644 tangem-devkit/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 tangem-devkit/src/main/res/mipmap-hdpi/ic_launcher_foreground.png delete mode 100644 tangem-devkit/src/main/res/mipmap-hdpi/ic_launcher_round.png delete mode 100644 tangem-devkit/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 tangem-devkit/src/main/res/mipmap-mdpi/ic_launcher_foreground.png delete mode 100644 tangem-devkit/src/main/res/mipmap-mdpi/ic_launcher_round.png delete mode 100644 tangem-devkit/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 tangem-devkit/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png delete mode 100644 tangem-devkit/src/main/res/mipmap-xhdpi/ic_launcher_round.png delete mode 100644 tangem-devkit/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 tangem-devkit/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png delete mode 100644 tangem-devkit/src/main/res/mipmap-xxhdpi/ic_launcher_round.png delete mode 100644 tangem-devkit/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 tangem-devkit/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png delete mode 100644 tangem-devkit/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png delete mode 100644 tangem-devkit/src/main/res/navigation/navigation.xml delete mode 100644 tangem-devkit/src/main/res/values/colors.xml delete mode 100644 tangem-devkit/src/main/res/values/dimens.xml delete mode 100644 tangem-devkit/src/main/res/values/dimens_item_widget.xml delete mode 100644 tangem-devkit/src/main/res/values/ic_launcher_background.xml delete mode 100644 tangem-devkit/src/main/res/values/strings.xml delete mode 100644 tangem-devkit/src/main/res/values/strings_action.xml delete mode 100644 tangem-devkit/src/main/res/values/strings_personalization.xml delete mode 100644 tangem-devkit/src/main/res/values/strings_response.xml delete mode 100644 tangem-devkit/src/main/res/values/strings_scan.xml delete mode 100644 tangem-devkit/src/main/res/values/strings_tlv.xml delete mode 100644 tangem-devkit/src/main/res/values/styles.xml delete mode 100644 tangem-devkit/src/main/res/values/theme_debug.xml delete mode 100644 tangem-devkit/src/main/res/xml/nfc_tech_filter.xml delete mode 100644 tangem-sdk/.gitignore delete mode 100644 tangem-sdk/build.gradle delete mode 100644 tangem-sdk/consumer-rules.pro delete mode 100644 tangem-sdk/proguard-rules.pro delete mode 100644 tangem-sdk/src/main/AndroidManifest.xml delete mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/DefaultSessionViewDelegate.kt delete mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/NfcLifecycleObserver.kt delete mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/SessionViewDelegateState.kt delete mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/TerminalKeysStorage.kt delete mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/Utils.kt delete mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/extensions/TangemSdk.kt delete mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/extensions/TangemSdkError.kt delete mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/extensions/View.kt delete mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/nfc/NfcManager.kt delete mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/nfc/NfcReader.kt delete mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/nfc/SlixTagReader.kt delete mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/ui/NfcEnableDialog.kt delete mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/ui/NfcLocation.kt delete mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/ui/NfcSessionDialog.kt delete mode 100644 tangem-sdk/src/main/java/com/tangem/tangem_sdk_new/ui/TouchCardAnimation.kt delete mode 100644 tangem-sdk/src/main/res/drawable/hand_card_horizontal.png delete mode 100644 tangem-sdk/src/main/res/drawable/hand_card_vertical.png delete mode 100644 tangem-sdk/src/main/res/drawable/ic_action_nfc_gray.png delete mode 100644 tangem-sdk/src/main/res/drawable/ic_done_135dp.xml delete mode 100644 tangem-sdk/src/main/res/drawable/ic_error.xml delete mode 100644 tangem-sdk/src/main/res/drawable/ic_error_outline_135dp.xml delete mode 100644 tangem-sdk/src/main/res/drawable/ic_nfc.xml delete mode 100644 tangem-sdk/src/main/res/drawable/pb_circle.xml delete mode 100644 tangem-sdk/src/main/res/drawable/pb_simple_circle.xml delete mode 100644 tangem-sdk/src/main/res/drawable/smartphone.png delete mode 100644 tangem-sdk/src/main/res/layout/layout_touch_card.xml delete mode 100644 tangem-sdk/src/main/res/layout/nfc_bottom_sheet.xml delete mode 100644 tangem-sdk/src/main/res/values/colors.xml delete mode 100644 tangem-sdk/src/main/res/values/dimens.xml delete mode 100644 tangem-sdk/src/main/res/values/strings.xml delete mode 100644 tangem-sdk/src/main/res/values/strings_errors.xml diff --git a/blockchain-demo/build.gradle b/blockchain-demo/build.gradle index 6567a8b453..934f45b26c 100644 --- a/blockchain-demo/build.gradle +++ b/blockchain-demo/build.gradle @@ -45,10 +45,11 @@ android { } dependencies { - implementation project(':tangem-core') - implementation project(':tangem-sdk') implementation project(':blockchain') + implementation 'com.tangem:core:0.10.4' + implementation 'com.tangem:sdk:0.10.4' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$versions.kotlin" implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.core:core-ktx:1.2.0' diff --git a/blockchain/build.gradle b/blockchain/build.gradle index 24ee17af7f..31c5286f39 100644 --- a/blockchain/build.gradle +++ b/blockchain/build.gradle @@ -40,8 +40,7 @@ android { dependencies { // implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation project(':tangem-core') - implementation project(':tangem-sdk') + implementation 'com.tangem:core:1.13' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$versions.kotlin" implementation 'androidx.appcompat:appcompat:1.1.0' diff --git a/build.gradle b/build.gradle index bbc8c94420..f1609ce70f 100644 --- a/build.gradle +++ b/build.gradle @@ -22,6 +22,7 @@ allprojects { google() jcenter() maven { url 'https://jitpack.io' } + maven { url "https://api.bitbucket.org/2.0/repositories/tangem/maven_repository/src/releases" } } } diff --git a/settings.gradle b/settings.gradle index 9a87107347..239e3ea7e9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':tangem-sdk-old', ':server-android', ':tangem-card-old', ':tangem-core', ':tangem-sdk', ':tangem-devkit', ':blockchain', ':blockchain-demo' \ No newline at end of file +include ':app', ':tangem-sdk-old', ':server-android', ':tangem-card-old', ':blockchain', ':blockchain-demo' \ No newline at end of file diff --git a/tangem-core/.gitignore b/tangem-core/.gitignore deleted file mode 100644 index 796b96d1c4..0000000000 --- a/tangem-core/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/tangem-core/build.gradle b/tangem-core/build.gradle deleted file mode 100644 index ce4d4d4c3e..0000000000 --- a/tangem-core/build.gradle +++ /dev/null @@ -1,78 +0,0 @@ -apply plugin: "kotlin" -apply plugin: 'org.jetbrains.dokka' -apply plugin: 'com.github.dcendents.android-maven' -apply from: '../dependencies.gradle' -apply from: '../jitpack.gradle' -apply plugin: 'kotlin-kapt' -apply plugin: 'com.squareup.sqldelight' - -group = "$jitpackSdk.group" -version "$jitpackSdk.version" - -dependencies { - // kotlin - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$versions.kotlin" - implementation "org.jetbrains.kotlin:kotlin-reflect:$versions.kotlidn" - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7' - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.3.7" - - // crypto - implementation "com.madgag.spongycastle:core:1.58.0.0" - implementation "com.madgag.spongycastle:prov:1.58.0.0" - implementation 'net.i2p.crypto:eddsa:0.3.0' - - // misc - implementation 'com.google.code.gson:gson:2.8.6' - implementation "com.squareup.sqldelight:sqlite-driver:1.4.0" - - //network - implementation 'com.squareup.retrofit2:retrofit:2.8.1' - implementation 'com.squareup.retrofit2:converter-moshi:2.6.0' - implementation 'com.squareup.moshi:moshi:1.9.2' - implementation "com.squareup.moshi:moshi-kotlin:1.9.2" - kapt("com.squareup.moshi:moshi-kotlin-codegen:1.9.2") - implementation 'com.squareup.okhttp3:logging-interceptor:4.2.2' - - // tests - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2' - testImplementation "com.google.truth:truth:1.0.1" -} - -sqldelight { - Database { - packageName = "com.tangem" - } -} - -sourceCompatibility = "8" -targetCompatibility = "8" - -buildscript { - ext.dokka_version = '0.10.0' - repositories { - mavenCentral() - jcenter() - } - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin" - classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokka_version" - } -} -repositories { - mavenCentral() - jcenter() -} -compileKotlin { - kotlinOptions { - jvmTarget = "1.8" - } -} -compileTestKotlin { - kotlinOptions { - jvmTarget = "1.8" - } -} - -task dokkaJavadoc(type: org.jetbrains.dokka.gradle.DokkaTask) { - outputFormat = 'markdown' -} diff --git a/tangem-core/src/main/java/com/tangem/CardFilter.kt b/tangem-core/src/main/java/com/tangem/CardFilter.kt deleted file mode 100644 index d1275d1d1d..0000000000 --- a/tangem-core/src/main/java/com/tangem/CardFilter.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.tangem - -import com.tangem.common.extensions.CardType -import java.util.* - -/** - * Filter that can be used to limit cards that can be interacted with in TangemSdk. - * - * @property allowedCardTypes Type of cards that are allowed to be interacted with in TangemSdk. - */ -data class CardFilter( - - var allowedCardTypes: EnumSet = EnumSet.allOf(CardType::class.java) -) \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/CardReader.kt b/tangem-core/src/main/java/com/tangem/CardReader.kt deleted file mode 100644 index deb1f33f14..0000000000 --- a/tangem-core/src/main/java/com/tangem/CardReader.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.tangem - -import com.tangem.common.CompletionResult -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.ResponseApdu -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.channels.BroadcastChannel - -/** - * Allows interaction between the phone or any other terminal and Tangem card. - * - * Its default implementation, NfcCardReader, is in our tangem-sdk module. - */ -interface CardReader { - - val tag: BroadcastChannel - var scope: CoroutineScope? - - /** - * Sends data to the card and receives the reply in an asynchronous way using coroutines. - * - * @param apdu Data to be sent. [CommandApdu] serializes it to a [ByteArray] - * @param callback Returns response from the card, - * [ResponseApdu] Allows to convert raw data to [Tlv] - */ - suspend fun transceiveApdu(apdu: CommandApdu): CompletionResult - - /** - * Sends data to the card and receives the reply. - * - * @param apdu Data to be sent. [CommandApdu] serializes it to a [ByteArray] - * @param callback Returns response from the card, - * [ResponseApdu] Allows to convert raw data to [Tlv] - */ - fun transceiveApdu(apdu: CommandApdu, callback: (response: CompletionResult) -> Unit) - - /** - * Signals to [CardReader] to become ready to transceive data. - */ - fun startSession() - - /** - * Signals to [CardReader] that no further NFC transition is expected. - */ - fun stopSession(cancelled: Boolean = false) - - fun readSlixTag(callback: (result: CompletionResult) -> Unit) - -} - -interface ReadingActiveListener { - var readingIsActive: Boolean -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/CardSession.kt b/tangem-core/src/main/java/com/tangem/CardSession.kt deleted file mode 100644 index 7b0ec51200..0000000000 --- a/tangem-core/src/main/java/com/tangem/CardSession.kt +++ /dev/null @@ -1,318 +0,0 @@ -package com.tangem - -import com.tangem.commands.Command -import com.tangem.commands.CommandResponse -import com.tangem.commands.OpenSessionCommand -import com.tangem.commands.ReadCommand -import com.tangem.common.CompletionResult -import com.tangem.common.PinCode -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.extensions.calculateSha256 -import com.tangem.common.extensions.getType -import com.tangem.crypto.EncryptionHelper -import com.tangem.crypto.pbkdf2Hash -import com.tangem.tasks.PinType -import kotlinx.coroutines.* -import kotlinx.coroutines.flow.* - -/** - * Basic interface for running tasks and [com.tangem.commands.Command] in a [CardSession] - */ -interface CardSessionRunnable { - - val requiresPin2: Boolean - - /** - * The starting point for custom business logic. - * Implement this interface and use [TangemSdk.startSessionWithRunnable] to run. - * @param session run commands in this [CardSession]. - * @param callback trigger the callback to complete the task. - */ - fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) -} - -enum class CardSessionState { - Inactive, - Active -} - -enum class TagType { - Nfc, - Slix -} - -/** - * Allows interaction with Tangem cards. Should be opened before sending commands. - * - * @property environment - * @property reader is an interface that is responsible for NFC connection and - * transfer of data to and from the Tangem Card. - * @property viewDelegate is an interface that allows interaction with users and shows relevant UI. - * @property cardId ID, Unique Tangem card ID number. If not null, the SDK will check that you the card - * with which you tapped a phone has this [cardId] and SDK will return - * the [TangemSdkError.WrongCardNumber] otherwise. - * @property initialMessage A custom description that will be shown at the beginning of the NFC session. - * If null, a default header and text body will be used. - */ -class CardSession( - private val environmentService: SessionEnvironmentService, - private val reader: CardReader, - val viewDelegate: SessionViewDelegate, - private var cardId: String? = null, - private val initialMessage: Message? = null -) { - - var connectedTag: TagType? = null - - /** - * True if some operation is still in progress. - */ - private var state = CardSessionState.Inactive - - val scope = CoroutineScope(Dispatchers.IO) + CoroutineExceptionHandler { _, ex -> - throw ex - } - - private val tag = this.javaClass.simpleName - - private var performPreflightRead = true - private var pin2Required = false - - val environment = environmentService.createEnvironment(cardId) - - /** - * This method starts a card session, performs preflight [ReadCommand], - * invokes [CardSessionRunnable.run] and closes the session. - * @param runnable [CardSessionRunnable] that will be performed in the session. - * @param callback will be triggered with a [CompletionResult] of a session. - */ - fun , R : CommandResponse> startWithRunnable( - runnable: T, callback: (result: CompletionResult) -> Unit - ) { - - if ((runnable as? Command<*>)?.performPreflightRead == false) performPreflightRead = false - pin2Required = runnable.requiresPin2 - - start() { session, error -> - if (error != null) { - callback(CompletionResult.Failure(error)) - return@start - } - - runnable.run(this) { result -> - when (result) { - is CompletionResult.Success -> stop() - is CompletionResult.Failure -> { - if (result.error is TangemSdkError.ExtendedLengthNotSupported) { - if (session.environment.terminalKeys != null) { - session.environment.terminalKeys = null - startWithRunnable(runnable, callback) - return@run - } - } - stopWithError(result.error) - } - } - callback(result) - } - } - } - - /** - * Starts a card session and performs preflight [ReadCommand]. - * @param callback: callback with the card session. Can contain [TangemSdkError] if something goes wrong. - */ - fun start( - callback: (session: CardSession, error: TangemSdkError?) -> Unit - ) { - - if (state != CardSessionState.Inactive) { - callback(this, TangemSdkError.Busy()) - return - } - - - if (environment.pin1 == null) { - viewDelegate.onSessionStarted(cardId) - viewDelegate.onPinRequested(PinType.Pin1) { - environment.pin1 = PinCode(it) - start(callback) - } - return - } - - if (pin2Required && environment.pin2 == null) { - viewDelegate.onSessionStarted(cardId) - viewDelegate.onPinRequested(PinType.Pin2) { - environment.pin2 = PinCode(it) - start(callback) - } - return - } - - state = CardSessionState.Active - viewDelegate.onSessionStarted(cardId) - - scope.launch { - reader.tag - .asFlow() - .collect { tagType -> - if (tagType == null && connectedTag != null) { - handleTagLost() - } else if (tagType != null) { - connectedTag = tagType - viewDelegate.onTagConnected() - - if (tagType == TagType.Nfc && performPreflightRead) { - preflightCheck(callback) - } else { - callback(this@CardSession, null) - } - } - } - } - reader.scope = scope - reader.startSession() - } - - private fun handleTagLost() { - connectedTag = null - environment.encryptionKey = null - viewDelegate.onTagLost() - } - - private fun preflightCheck(callback: (session: CardSession, error: TangemSdkError?) -> Unit) { - val readCommand = ReadCommand() - readCommand.run(this) { result -> - when (result) { - is CompletionResult.Failure -> { - stopWithError(result.error) - callback(this, result.error) - } - is CompletionResult.Success -> { - val receivedCardId = result.data.cardId - if (cardId != null && receivedCardId != cardId) { - viewDelegate.onWrongCard() - preflightCheck(callback) - return@run - } - val allowedCardTypes = environment.cardFilter.allowedCardTypes - if (!allowedCardTypes.contains(result.data.getType())) { - stopWithError(TangemSdkError.WrongCardType()) - callback(this, TangemSdkError.WrongCardType()) - return@run - } - environment.card = result.data - environmentService.updateEnvironment(environment, result.data.cardId) - cardId = receivedCardId - callback(this, null) - } - } - } - } - - fun readSlixTag(callback: (result: CompletionResult) -> Unit) { - reader.readSlixTag(callback) - } - - /** - * Stops the current session with the text message. - * @param message If null, the default message will be shown. - */ - private fun stop(message: Message? = null) { - stopSession() - viewDelegate.onSessionStopped(message) - } - - /** - * Stops the current session on error. - * @param error An error that will be shown. - */ - private fun stopWithError(error: TangemSdkError) { - stopSession() - if (error !is TangemSdkError.UserCancelled) { - Log.e(tag, "Finishing with error: ${error::class.simpleName}: ${error.code}") - viewDelegate.onError(error) - } else { - Log.i(tag, "User cancelled NFC session") - } - } - - private fun stopSession() { - environmentService.saveEnvironmentValues(environment, cardId) - reader.stopSession() - state = CardSessionState.Inactive - scope.cancel() - } - - fun send(apdu: CommandApdu, callback: (result: CompletionResult) -> Unit) { - val subscription = reader.tag.openSubscription() - scope.launch { - subscription.consumeAsFlow() - .filterNotNull() - .map { establishEncryptionIfNeeded() } - .map { apdu.encrypt(environment.encryptionMode, environment.encryptionKey) } - .map { encryptedApdu -> reader.transceiveApdu(encryptedApdu) } - .map { responseApdu -> decrypt(responseApdu) } - .catch { if (it is TangemSdkError) callback(CompletionResult.Failure(it)) } - .collect { result -> - subscription.cancel() - callback(result) - } - } - } - - fun pause() { - reader.stopSession() - } - - fun resume() { - reader.startSession() - } - - private suspend fun establishEncryptionIfNeeded(): CompletionResult { - if (environment.encryptionMode == EncryptionMode.NONE || environment.encryptionKey != null) { - return CompletionResult.Success(true) - } - - val encryptionHelper = EncryptionHelper.create(environment.encryptionMode) - ?: return CompletionResult.Success(true) - - val openSesssionCommand = OpenSessionCommand(encryptionHelper.keyA) - val apdu = openSesssionCommand.serialize(environment) - - val response = reader.transceiveApdu(apdu) - when (response) { - is CompletionResult.Success -> { - val result = try { - openSesssionCommand.deserialize(environment, response.data) - } catch (error: TangemSdkError) { - return CompletionResult.Failure(error) - } - val uid = result.uid - val protocolKey = environment.pin1!!.value.pbkdf2Hash(uid, 50) - val secret = encryptionHelper.generateSecret(result.sessionKeyB) - val sessionKey = (secret + protocolKey).calculateSha256() - environment.encryptionKey = sessionKey - return CompletionResult.Success(true) - } - is CompletionResult.Failure -> return CompletionResult.Failure(response.error) - } - } - - private fun decrypt(result: CompletionResult): CompletionResult { - return when (result) { - is CompletionResult.Success -> { - try { - CompletionResult.Success( - result.data.decrypt(environment.encryptionKey) - ) - } catch (error: TangemSdkError) { - return CompletionResult.Failure(error) - } - } - is CompletionResult.Failure -> result - } - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/Config.kt b/tangem-core/src/main/java/com/tangem/Config.kt deleted file mode 100644 index 7b643c5e1f..0000000000 --- a/tangem-core/src/main/java/com/tangem/Config.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.tangem - -class Config( - /** - * Enables or disables Linked Terminal feature. - - App can optionally generate ECDSA key pair Terminal_PrivateKey / Terminal_PublicKey. - And then submit Terminal_PublicKey to the card in any SIGN command. - Once SIGN is successfully executed by COS (Card Operation System), - including PIN2 verification and/or completion of security delay, the submitted - Terminal_PublicKey key is stored by COS. After that, the App instance is deemed trusted - by COS and COS will allow skipping security delay for subsequent SIGN operations - thus improving convenience without sacrificing security. - - In order to skip security delay, App should use Terminal_PrivateKey to compute the signature - of the data being submitted to SIGN command for signing and transmit this signature in - Terminal_Transaction_Signature parameter in the same SIGN command. COS will verify - the correctness of Terminal_Transaction_Signature using previously stored Terminal_PublicKey - and, if correct, will skip security delay for the current SIGN operation. - */ - var linkedTerminal: Boolean = true, - - /** - * If not null, it will be used to validate Issuer data and issuer extra data. - * If null, issuerPublicKey from current card will be used. - */ - var issuerPublicKey: ByteArray? = null, - - /** - * Level of encryption used in communication with a Tangem Card. - */ - var encryptionMode: EncryptionMode = EncryptionMode.NONE, - - /** - * Filter that can be used to limit cards that can be interacted with in TangemSdk. - */ - val cardFilter: CardFilter = CardFilter(), - - var handleErrors: Boolean = true, - - var defaultPin1: String = DEFAULT_PIN_1, - - var defaultPin2: String = DEFAULT_PIN_2, - - var savePin1InStaticField: Boolean = true, - - var savePin2InStaticField: Boolean = false -) { - companion object { - const val DEFAULT_PIN_1 = "000000" - const val DEFAULT_PIN_2 = "000" - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/Log.kt b/tangem-core/src/main/java/com/tangem/Log.kt deleted file mode 100644 index b03303b1a5..0000000000 --- a/tangem-core/src/main/java/com/tangem/Log.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.tangem - -object Log { - - private var loggerInstance: LoggerInterface? = null - - fun i(logTag: String, message: String) { - loggerInstance?.i(logTag, message) - } - - fun e(logTag: String, message: String) { - loggerInstance?.e(logTag, message) - } - - fun v(logTag: String, message: String) { - - loggerInstance?.v(logTag, message) - } - - fun setLogger(logger: LoggerInterface) { - loggerInstance = logger - } -} - -/** - * Interface for logging events within the SDK. - * - * It allows to use Android logger or to choose another. - */ -interface LoggerInterface { - fun i(logTag: String, message: String) - fun e(logTag: String, message: String) - fun v(logTag: String, message: String) -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/SessionEnvironment.kt b/tangem-core/src/main/java/com/tangem/SessionEnvironment.kt deleted file mode 100644 index e8afbb33e5..0000000000 --- a/tangem-core/src/main/java/com/tangem/SessionEnvironment.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.tangem - -import com.tangem.commands.Card -import com.tangem.commands.EllipticCurve -import com.tangem.common.PinCode -import com.tangem.crypto.CryptoUtils.generatePublicKey - - -/** - * Contains data relating to a Tangem card. It is used in constructing all the commands, - * and commands can return modified [SessionEnvironment]. - * - * @param cardId Card ID, if it is known before tapping the card. - * @property config sets a number of parameters for communication with Tangem cards. - * @param terminalKeysService is used to retrieve terminal keys used in Linked Terminal feature. - * @param cardValuesStorage is used to save and retrieve some values relating to a particular card. - * - * @property pin1 An access Code, required to get access to a card. A default value is set in [Config] - * @property pin2 A code, required to perform particular operations with a card. A default value is set in [Config] - * @property terminalKeys generated terminal keys used in Linked Terminal feature - * @property cardFilter a property that defines types of card that this SDK will be able to interact with - * @property handleErrors if true, the SDK parses internal card errors into concrete [TangemSdkError] - * @property encryptionMode preferred [EncryptionMode] for interaction with cards - * @property encryptionKey is used for encrypted communication with a card - * - */ -class SessionEnvironment( - var pin1: PinCode? = PinCode(Config.DEFAULT_PIN_1, true), - var pin2: PinCode? = PinCode(Config.DEFAULT_PIN_2, true), - var cvc: ByteArray? = null, - - var terminalKeys: KeyPair? = null, - var cardFilter: CardFilter = CardFilter(), - val handleErrors: Boolean = true, - - var encryptionMode: EncryptionMode = EncryptionMode.NONE, - var encryptionKey: ByteArray? = null, - - var cardVerification: VerificationState = VerificationState.NotVerified, - var cardValidation: VerificationState = VerificationState.NotVerified, - var codeVerification: VerificationState = VerificationState.NotVerified, - - var card: Card? = null -) - -/** - * All possible encryption modes. - */ -enum class EncryptionMode(val code: Int) { - NONE(0x0), - FAST(0x1), - STRONG(0x2) -} - -class KeyPair(val publicKey: ByteArray, val privateKey: ByteArray) { - - constructor(privateKey: ByteArray, curve: EllipticCurve = EllipticCurve.Secp256k1) : - this(generatePublicKey(privateKey, curve), privateKey) -} - -enum class VerificationState { - Passed, Offline, Failed, NotVerified, Cancelled -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/SessionEnvironmentService.kt b/tangem-core/src/main/java/com/tangem/SessionEnvironmentService.kt deleted file mode 100644 index d36c95c8ad..0000000000 --- a/tangem-core/src/main/java/com/tangem/SessionEnvironmentService.kt +++ /dev/null @@ -1,77 +0,0 @@ -package com.tangem - -import com.tangem.common.CardValuesStorage -import com.tangem.common.PinCode -import com.tangem.common.TerminalKeysService - -class SessionEnvironmentService( - private val config: Config, - private val terminalKeysService: TerminalKeysService?, - private val cardValuesStorage: CardValuesStorage? -) { - - fun createEnvironment(cardId: String?): SessionEnvironment { - val terminalKeys = if (config.linkedTerminal) terminalKeysService?.getKeys() else null - - val cardValues = cardId?.let { cardValuesStorage?.getValues(cardId) } - - val cardVerification = cardValues?.cardVerification ?: VerificationState.NotVerified - val cardValidation = cardValues?.cardValidation ?: VerificationState.NotVerified - val codeVerification = cardValues?.codeVerification ?: VerificationState.NotVerified - - val pin1 = TangemSdk.pin1 - ?: if (cardValues?.isPin1Default != false) { - PinCode(config.defaultPin1, true) - } else { - null - } - - val pin2 = cardId?.let { TangemSdk.pin2[it] } - ?: if (cardValues?.isPin2Default != false) { - PinCode(config.defaultPin2, true) - } else { - null - } - - return SessionEnvironment( - terminalKeys = terminalKeys, - cardFilter = config.cardFilter, - handleErrors = config.handleErrors, - - encryptionMode = config.encryptionMode, - - cardVerification = cardVerification, - cardValidation = cardValidation, - codeVerification = codeVerification, - - pin1 = pin1, - pin2 = pin2 - ) - } - - fun updateEnvironment(environment: SessionEnvironment, cardId: String) { - val cardValues = cardId.let { cardValuesStorage?.getValues(it) } - environment.cardVerification = cardValues?.cardVerification ?: VerificationState.NotVerified - environment.cardValidation = cardValues?.cardValidation ?: VerificationState.NotVerified - environment.codeVerification = cardValues?.codeVerification ?: VerificationState.NotVerified - - if (cardValues?.isPin1Default == false && environment.pin1?.isDefault == true) environment.pin1 = null - if (cardValues?.isPin2Default == false && environment.pin1?.isDefault == true) environment.pin2 = null - } - - fun saveEnvironmentValues(environment: SessionEnvironment, cardId: String?) { - if (config.savePin1InStaticField) { - TangemSdk.pin1 = environment.pin1 - } - if (config.savePin2InStaticField) { - cardId?.let { cardId -> TangemSdk.pin2[cardId] = environment.pin2 } - } - cardId?.let { cardId -> - cardValuesStorage?.saveValues(cardId, - environment.pin1?.isDefault ?: false, - environment.pin2?.isDefault ?: false, - environment.cardVerification, environment.cardVerification, - environment.codeVerification) - } - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/SessionViewDelegate.kt b/tangem-core/src/main/java/com/tangem/SessionViewDelegate.kt deleted file mode 100644 index a62716454b..0000000000 --- a/tangem-core/src/main/java/com/tangem/SessionViewDelegate.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.tangem - -import com.tangem.tasks.PinType - -/** - * Allows interaction with users and shows visual elements. - * - * Its default implementation, DefaultCardManagerDelegate, is in our tangem-sdk module. - */ -interface SessionViewDelegate { - - /** - * It is called when user is expected to scan a Tangem Card with an Android device. - */ - fun onSessionStarted(cardId: String?, message: Message? = null) - - /** - * It is called when security delay is triggered by the card. - * A user is expected to hold the card until the security delay is over. - */ - fun onSecurityDelay(ms: Int, totalDurationSeconds: Int) - - /** - * It is called when long tasks are performed. - * A user is expected to hold the card until the task is complete. - */ - fun onDelay(total: Int, current: Int, step: Int) - - /** - * It is called when user takes the card away from the Android device during the scanning - * (for example when security delay is in progress) and the TagLostException is received. - */ - fun onTagLost() - - fun onTagConnected() - - fun onWrongCard() - - /** - * It is called when NFC session was completed and a user can take the card away from the Android device. - */ - fun onSessionStopped(message: Message? = null) - - /** - * It is called when some error occur during NFC session. - */ - fun onError(error: TangemSdkError) - - /** - * It is called when a user is expected to enter pin code. - */ - fun onPinRequested(pinType: PinType, callback: (pin: String) -> Unit) - - /** - * It is called when a user wants to change pin code. - */ - fun onPinChangeRequested(pinType: PinType, callback: (pin: String) -> Unit) -} - -/** - * Wrapper for a message that can be shown to user after a start of NFC session. - */ -data class Message(val header: String? = null, val body: String? = null) \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/TangemSdk.kt b/tangem-core/src/main/java/com/tangem/TangemSdk.kt deleted file mode 100644 index 40b0a79848..0000000000 --- a/tangem-core/src/main/java/com/tangem/TangemSdk.kt +++ /dev/null @@ -1,440 +0,0 @@ -package com.tangem - -import com.tangem.commands.* -import com.tangem.commands.personalization.DepersonalizeCommand -import com.tangem.commands.personalization.DepersonalizeResponse -import com.tangem.commands.personalization.PersonalizeCommand -import com.tangem.commands.personalization.entities.Acquirer -import com.tangem.commands.personalization.entities.CardConfig -import com.tangem.commands.personalization.entities.Issuer -import com.tangem.commands.personalization.entities.Manufacturer -import com.tangem.commands.verifycard.VerifyCardCommand -import com.tangem.commands.verifycard.VerifyCardResponse -import com.tangem.common.CardValuesStorage -import com.tangem.common.CompletionResult -import com.tangem.common.PinCode -import com.tangem.common.TerminalKeysService -import com.tangem.crypto.CryptoUtils -import com.tangem.tasks.ChangePinTask -import com.tangem.tasks.CreateWalletTask -import com.tangem.tasks.PinType -import com.tangem.tasks.ScanTask - -/** - * The main interface of Tangem SDK that allows your app to communicate with Tangem cards. - * - * @property reader is an interface that is responsible for NFC connection and - * transfer of data to and from the Tangem Card. - * Its default implementation, NfcCardReader, is in our tangem-sdk module. - * @property viewDelegate An interface that allows interaction with users and shows relevant UI. - * Its default implementation, DefaultCardSessionViewDelegate, is in our tangem-sdk module. - * @property config allows to change a number of parameters for communication with Tangem cards. - * Do not change the default values unless you know what you are doing. - * @property terminalKeysService allows to retrieve saved terminal keys. - */ -class TangemSdk( - private val reader: CardReader, - private val viewDelegate: SessionViewDelegate, - var config: Config = Config(), - cardValuesStorage: CardValuesStorage, - terminalKeysService: TerminalKeysService? = null -) { - - private val environmentService = SessionEnvironmentService( - config, terminalKeysService, cardValuesStorage - ) - - init { - CryptoUtils.initCrypto() - } - - /** - * This method launches a [ScanTask] on a new thread. - * - * To start using any card, you first need to read it using the scanCard() method. - * This method launches an NFC session, and once it’s connected with the card, - * it obtains the card data. Optionally, if the card contains a wallet (private and public key pair), - * it proves that the wallet owns a private key that corresponds to a public one. - * - * @param callback is triggered on the completion of the [ScanTask] and provides card response - * in the form of [Card] if the task was performed successfully or [TangemSdkError] in case of an error. - */ - fun scanCard(initialMessage: Message? = null, callback: (result: CompletionResult) -> Unit) { - startSessionWithRunnable(ScanTask(), null, initialMessage, callback) - } - - /** - * This method launches a [SignCommand] on a new thread. - * - * It allows you to sign one or multiple hashes. - * Simultaneous signing of array of hashes in a single [SignCommand] is required to support - * Bitcoin-type multi-input blockchains (UTXO). - * The [SignCommand] will return a corresponding array of signatures. - * - * Please note that Tangem cards usually protect the signing with a security delay - * that may last up to 90 seconds, depending on a card. - * It is for [SessionViewDelegate] to notify users of security delay. - * - * @param hashes Array of transaction hashes. It can be from one or up to ten hashes of the same length. - * @param cardId CID, Unique Tangem card ID number - * @param callback is triggered on the completion of the [SignCommand] and provides card response - * in the form of [SignResponse] if the task was performed successfully - * or [TangemSdkError] in case of an error. - */ - fun sign(hashes: Array, cardId: String? = null, initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit) { - startSessionWithRunnable(SignCommand(hashes), cardId, initialMessage, callback) - } - - /** - * This method launches a [ReadIssuerDataCommand] on a new thread. - - * This command returns 512-byte Issuer Data field and its issuer’s signature. - * Issuer Data is never changed or parsed from within the Tangem COS. The issuer defines purpose of use, - * format and payload of Issuer Data. For example, this field may contain information about - * wallet balance signed by the issuer or additional issuer’s attestation data. - * - * @param cardId CID, Unique Tangem card ID number. - * @param callback is triggered on the completion of the [ReadIssuerDataCommand] and provides - * card response in the form of [ReadIssuerDataResponse] if the task was performed successfully - * or [TangemSdkError] in case of an error. - */ - fun readIssuerData(cardId: String? = null, initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit) { - startSessionWithRunnable(ReadIssuerDataCommand(config.issuerPublicKey), cardId, initialMessage, callback) - } - - /** - * This method launches a [ReadIssuerExtraDataCommand] on a new thread. - * - * This command retrieves Issuer Extra Data field and its issuer’s signature. - * Issuer Extra Data is never changed or parsed from within the Tangem COS. The issuer defines purpose of use, - * format and payload of Issuer Data. . For example, this field may contain photo or - * biometric information for ID card product. Because of the large size of Issuer_Extra_Data, - * a series of these commands have to be executed to read the entire Issuer_Extra_Data. - * - * @param cardId CID, Unique Tangem card ID number. - * @param callback is triggered on the completion of the [ReadIssuerExtraDataCommand] and provides - * card response in the form of [ReadIssuerExtraDataResponse] if the task was performed successfully - * or [TangemSdkError] in case of an error. - */ - fun readIssuerExtraData(cardId: String? = null, - callback: (result: CompletionResult) -> Unit) { - startSessionWithRunnable(ReadIssuerExtraDataCommand(config.issuerPublicKey), cardId, null, callback) - } - - /** - * This method launches a [WriteIssuerDataCommand] on a new thread. - * - * This command writes 512-byte Issuer Data field and its issuer’s signature. - * Issuer Data is never changed or parsed from within the Tangem COS. The issuer defines purpose of use, - * format and payload of Issuer Data. For example, this field may contain information about - * wallet balance signed by the issuer or additional issuer’s attestation data. - * - * @param cardId CID, Unique Tangem card ID number. - * @param issuerData Data provided by issuer. - * @param issuerDataSignature Issuer’s signature of [issuerData] with Issuer Data Private Key. - * @param issuerDataCounter An optional counter that protect issuer data against replay attack. - * @param callback is triggered on the completion of the [WriteIssuerDataCommand] and provides - * card response in the form of [WriteIssuerDataResponse] if the task was performed successfully - * or [TangemSdkError] in case of an error. - */ - fun writeIssuerData(cardId: String? = null, - issuerData: ByteArray, - issuerDataSignature: ByteArray, - issuerDataCounter: Int? = null, - initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit) { - val command = WriteIssuerDataCommand( - issuerData, - issuerDataSignature, - issuerDataCounter, - config.issuerPublicKey - ) - startSessionWithRunnable(command, cardId, initialMessage, callback) - } - - /** - * This method launches a [WriteIssuerExtraDataCommand] on a new thread. - * - * This command writes Issuer Extra Data field and its issuer’s signature. - * Issuer Extra Data is never changed or parsed from within the Tangem COS. - * The issuer defines purpose of use, format and payload of Issuer Data. - * For example, this field may contain a photo or biometric information for ID card products. - * Because of the large size of IssuerExtraData, a series of these commands have to be executed - * to write entire IssuerExtraData. - * - * @param cardId CID, Unique Tangem card ID number. - * @param issuerData Data provided by issuer. - * @param startingSignature Issuer’s signature with Issuer Data Private Key of [cardId], - * [issuerDataCounter] (if flags Protect_Issuer_Data_Against_Replay and - * Restrict_Overwrite_Issuer_Extra_Data are set in [SettingsMask]) and size of [issuerData]. - * @param finalizingSignature Issuer’s signature with Issuer Data Private Key of [cardId], - * [issuerData] and [issuerDataCounter] (the latter one only if flags Protect_Issuer_Data_Against_Replay - * andRestrict_Overwrite_Issuer_Extra_Data are set in [SettingsMask]). - * @param issuerDataCounter An optional counter that protect issuer data against replay attack. - * @param callback is triggered on the completion of the [WriteIssuerExtraDataCommand] and provides - * card response in the form of [WriteIssuerDataResponse] if the task was performed successfully - * or [TangemSdkError] in case of an error. - */ - fun writeIssuerExtraData(cardId: String? = null, - issuerData: ByteArray, - startingSignature: ByteArray, - finalizingSignature: ByteArray, - issuerDataCounter: Int? = null, - initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit) { - val command = WriteIssuerExtraDataCommand( - issuerData, - startingSignature, finalizingSignature, - issuerDataCounter, - config.issuerPublicKey - ) - startSessionWithRunnable(command, cardId, initialMessage, callback) - } - - /** - * This method launches a [WriteUserDataCommand] on a new thread, writing UserData and UserCounter fields. - * - * User_Data is never changed or parsed by the executable code the Tangem COS. - * The App defines purpose of use, format and its payload. For example, this field may contain cashed information - * from blockchain to accelerate preparing new transaction. - * The initial value of User_Counter can be set by an App and increased on every signing - * of new transaction (on SIGN command that calculate new signatures). The App defines purpose of use. - * For example, this fields may contain blockchain nonce value. - * - * Writing of UserCounter and UserData is protected only by PIN1. - */ - fun writeUserData( - cardId: String? = null, - userData: ByteArray? = null, - userCounter: Int? = null, - initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit - ) { - val command = WriteUserDataCommand(userData = userData, userCounter = userCounter) - startSessionWithRunnable(command, cardId, initialMessage, callback) - } - - /** - * This method launches a [WriteUserDataCommand] on a new thread, - * writing UserProtectedData and UserProtectedCounter fields. - * - * User_ProtectedData is never changed or parsed by the executable code the Tangem COS. - * The App defines purpose of use, format and its payload. For example, this field may contain cashed information - * from blockchain to accelerate preparing new transaction. - * The initial value of User_ProtectedCounter can be set by an App and increased on every signing - * of a new transaction (on SIGN command that calculate new signatures). The App defines the purpose of use. - * For example, this fields may contain blockchain nonce value. - * - * UserProtectedCounter and UserProtectedData require PIN2 for confirmation. - */ - fun writeProtectedUserData( - cardId: String? = null, - userProtectedData: ByteArray? = null, - userProtectedCounter: Int? = null, - initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit - ) { - val command = WriteUserDataCommand( - userProtectedData = userProtectedData, userProtectedCounter = userProtectedCounter - ) - startSessionWithRunnable(command, cardId, initialMessage, callback) - } - - /** - * This method launches a [ReadUserDataCommand] on a new thread. - * - * This command returns two up to 512-byte User_Data, User_Protected_Data and two counters User_Counter and - * User_Protected_Counter fields. - * User_Data and User_ProtectedData are never changed or parsed by the executable code the Tangem COS. - * The App defines purpose of use, format and it's payload. For example, this field may contain cashed information - * from blockchain to accelerate preparing new transaction. - * User_Counter and User_ProtectedCounter are counters, that initial values can be set by App and increased on every signing - * of new transaction (on SIGN command that calculate new signatures). The App defines purpose of use. - * For example, this fields may contain blockchain nonce value. - * - * @param cardId CID, Unique Tangem card ID number. - * @param callback is triggered on the completion of the [ReadUserDataCommand] and provides - * card response in the form of [ReadUserDataResponse] if the task was performed successfully - * or [TangemSdkError] in case of an error. - */ - fun readUserData(cardId: String? = null, initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit) { - startSessionWithRunnable(ReadUserDataCommand(), cardId, initialMessage, callback) - } - - /** - * This method launches a [CreateWalletTask] on a new thread. - * - * This this will create a new wallet on the card having ‘Empty’ state with [CreateWalletCommand] - * and will check the success of the operation by performing [CheckWalletCommand]. - * A key pair WalletPublicKey / WalletPrivateKey is generated and securely stored in the card. - * App will need to obtain Wallet_PublicKey from the [CreateWalletResponse] or from the - * response of [ReadCommand] and then transform it into an address of corresponding - * blockchain wallet according to a specific blockchain algorithm. - * WalletPrivateKey is never revealed by the card and will be used by [SignCommand] and [CheckWalletCommand]. - * RemainingSignature is set to MaxSignatures. - * - * @param cardId CID, Unique Tangem card ID number. - * @param callback is triggered on the completion of the [CreateWalletTask] and provides - * card response in the form of [CreateWalletResponse] if the task was performed successfully - * or [TangemSdkError] in case of an error. - */ - fun createWallet(cardId: String? = null, initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit) { - startSessionWithRunnable(CreateWalletTask(), cardId, initialMessage, callback) - } - - /** - * This method launches a [PurgeWalletCommand] on a new thread. - * - * This command deletes all wallet data. If IsReusable flag is enabled during personalization, - - * or [CreateWalletCommand]. - * If IsReusable flag is disabled, the card switches to ‘Purged’ state. - * ‘Purged’ state is final, it makes the card useless. - * - * @param cardId CID, Unique Tangem card ID number. - * @param callback is triggered on the completion of the [PurgeWalletCommand] and provides - * card response in the form of [PurgeWalletResponse] if the task was performed successfully - * or [TangemSdkError] in case of an error. - */ - fun purgeWallet(cardId: String? = null, initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit) { - startSessionWithRunnable(PurgeWalletCommand(), cardId, initialMessage, callback) - } - - /** - * This method launches a [VerifyCardCommand] on a new thread. - * - * The command to ensures the card has not been counterfeited. - * By using standard challenge-response scheme, the card proves possession of CardPrivateKey - * that corresponds to CardPublicKey returned by [ReadCommand]. Then the data is sent - * to Tangem server to prove that this card was indeed issued by Tangem. - * The online part of the verification is unavailable for DevKit cards. - * - * - * @param cardId CID, Unique Tangem card ID number. - * @param online flag that allows disable online verification - * @param callback is triggered on the completion of the [VerifyCardCommand] and provides - * card response in the form of [VerifyCardResponse] if the task was performed successfully - * or [TangemSdkError] in case of an error. - */ - fun verify(cardId: String? = null, online: Boolean = true, initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit) { - startSessionWithRunnable(VerifyCardCommand(online), cardId, initialMessage, callback) - } - - /** - * Command available on SDK cards only - * - * This method launches a [DepersonalizeCommand] on a new thread. - * - * This command resets card to initial state, - * erasing all data written during personalization and usage. - * - * @param cardId CID, Unique Tangem card ID number. - * @param callback is triggered on the completion of the [DepersonalizeCommand] and provides - * card response in the form of [DepersonalizeResponse] if the task was performed successfully - * or [TangemSdkError] in case of an error. - * */ - fun depersonalize(cardId: String? = null, initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit) { - startSessionWithRunnable(DepersonalizeCommand(), cardId, initialMessage, callback) - } - - /** - * Command available on SDK cards only - * - * This method launches a [PersonalizeCommand] on a new thread. - * - * Personalization is an initialization procedure, required before starting using a card. - * During this procedure a card setting is set up. - * During this procedure all data exchange is encrypted. - * @param config is a configuration file with all the card settings that are written on the card - * during personalization. - * @param issuer Issuer is a third-party team or company wishing to use Tangem cards. - * @param manufacturer Tangem Card Manufacturer. - * @param acquirer Acquirer is a trusted third-party company that operates proprietary - * (non-EMV) POS terminal infrastructure and transaction processing back-end. - * @param callback is triggered on the completion of the [PersonalizeCommand] and provides - * card response in the form of [Card] if the command was performed successfully - * or [TangemSdkError] in case of an error. - */ - fun personalize(config: CardConfig, - issuer: Issuer, manufacturer: Manufacturer, acquirer: Acquirer? = null, - initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit) { - val command = PersonalizeCommand(config, issuer, manufacturer, acquirer) - startSessionWithRunnable(command, null, initialMessage, callback) - } - - fun changePin1(cardId: String? = null, - pin: ByteArray? = null, - initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit) { - val command = ChangePinTask(PinType.Pin1, pin) - startSessionWithRunnable(command, cardId, initialMessage, callback) - } - - fun changePin2(cardId: String? = null, - pin: ByteArray? = null, - initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit) { - val command = ChangePinTask(PinType.Pin2, pin) - startSessionWithRunnable(command, cardId, initialMessage, callback) - } - - fun changePin3(cardId: String? = null, - pin: ByteArray? = null, - initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit) { - val command = ChangePinTask(PinType.Pin3, pin) - startSessionWithRunnable(command, cardId, initialMessage, callback) - } - - /** - * Allows running a custom bunch of commands in one [CardSession] by creating a custom task. - * [TangemSdk] will start a card session, perform preflight [ReadCommand], - * invoke [CardSessionRunnable.run] and close the session. - * You can find the current card in the [CardSession.environment]. - - * @runnable: A custom task, adopting [CardSessionRunnable] protocol - * @cardId: CID, Unique Tangem card ID number. If not null, the SDK will check that you the card - * with which you tapped a phone has this [cardId] and SDK will return - * the [TangemSdkError.WrongCardNumber] otherwise. - * @initialMessage: A custom description that shows at the beginning of the NFC session. - * If null, default message will be used. - * @callback: Standard [TangemSdk] callback. - */ - fun startSessionWithRunnable( - runnable: CardSessionRunnable, cardId: String? = null, initialMessage: Message? = null, - callback: (result: CompletionResult) -> Unit) { - val cardSession = CardSession(environmentService, reader, viewDelegate, cardId, initialMessage) - Thread().run { cardSession.startWithRunnable(runnable, callback) } - } - - /** - * Allows running a custom bunch of commands in one [CardSession] with lightweight closure syntax. - * Tangem SDK will start a card session and perform preflight [ReadCommand]. - - * @cardId: CID, Unique Tangem card ID number. If not null, the SDK will check that you the card - * with which you tapped a phone has this [cardId] and SDK will return - * the [TangemSdkError.WrongCardNumber] otherwise. - * @initialMessage: A custom description that shows at the beginning of the NFC session. - * If null, default message will be used. - * @callback: At first, you should check that the [TangemSdkError] is not null, - * then you can use the [CardSession] to interact with a card. - */ - fun startSession(cardId: String? = null, initialMessage: Message? = null, - callback: (session: CardSession, error: TangemSdkError?) -> Unit) { - val cardSession = CardSession(environmentService, reader, viewDelegate, cardId, initialMessage) - Thread().run { cardSession.start(callback = callback) } - } - - companion object { - var pin1: PinCode? = null - val pin2: MutableMap = mutableMapOf() - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/TangemSdkError.kt b/tangem-core/src/main/java/com/tangem/TangemSdkError.kt deleted file mode 100644 index d58771fc77..0000000000 --- a/tangem-core/src/main/java/com/tangem/TangemSdkError.kt +++ /dev/null @@ -1,163 +0,0 @@ -package com.tangem - -import com.tangem.commands.Card -import com.tangem.commands.ReadCommand -import com.tangem.common.apdu.StatusWord -import com.tangem.tasks.ScanTask - -/** - * An error class that represent typical errors that may occur when performing Tangem SDK tasks. - * Errors are propagated back to the caller in callbacks. - */ -sealed class TangemSdkError(val code: Int) : Exception(code.toString()) { - - /** - * This error is returned when Android NFC reader loses a tag - * (e.g. a user detaches card from the phone's NFC module) while the NFC session is in progress. - */ - class TagLost : TangemSdkError(10001) - /** - * This error is returned when NFC driver on an Android device does not support sending more than 261 bytes. - */ - class ExtendedLengthNotSupported : TangemSdkError(10002) - - - class SerializeCommandError : TangemSdkError(20001) - class DeserializeApduFailed : TangemSdkError(20002) - class EncodingFailedTypeMismatch : TangemSdkError(20003) - class EncodingFailed : TangemSdkError(20004) - class DecodingFailedMissingTag : TangemSdkError(20005) - class DecodingFailedTypeMismatch : TangemSdkError(20006) - class DecodingFailed : TangemSdkError(20007) - class InvalidResponse : TangemSdkError(20008) - - /** - * This error is returned when unknown [StatusWord] is received from a card. - */ - class UnknownStatus : TangemSdkError(30001) - /** - * This error is returned when a card's reply is [StatusWord.ErrorProcessingCommand]. - * The card sends this status in case of internal card error. - */ - class ErrorProcessingCommand : TangemSdkError(30002) - /** - * This error is returned when a card's reply is [StatusWord.InvalidState]. - * The card sends this status when command can not be executed in the current state of a card. - */ - class InvalidState : TangemSdkError(30003) - /** - * This error is returned when a card's reply is [StatusWord.InsNotSupported]. - * The card sends this status when the card cannot process the [com.tangem.common.apdu.Instruction]. - */ - class InsNotSupported : TangemSdkError(30004) - /** - * This error is returned when a card's reply is [StatusWord.InvalidParams]. - * The card sends this status when there are wrong or not sufficient parameters in TLV request, - * or wrong PIN1/PIN2. - * The error may be caused, for example, by wrong parameters of the [Task], [CommandSerializer], - * mapping or serialization errors. - */ - class InvalidParams : TangemSdkError(30005) - /** - * This error is returned when a card's reply is [StatusWord.NeedEncryption] - * and the encryption was not established by TangemSdk. - */ - class NeedEncryption : TangemSdkError(30006) - - //Personalization Errors - class AlreadyPersonalized : TangemSdkError(40101) - - //Depersonalization Errors - class CannotBeDepersonalized : TangemSdkError(40201) - - //Read Errors - class Pin1Required : TangemSdkError(40401) - - //CreateWallet Errors - class AlreadyCreated : TangemSdkError(40501) - - //PurgeWallet Errors - class PurgeWalletProhibited : TangemSdkError(40601) - - //SetPin Errors - class Pin1CannotBeChanged : TangemSdkError(40801) - class Pin2CannotBeChanged : TangemSdkError(40802) - class Pin1CannotBeDefault : TangemSdkError(40803) - - //Sign Errors - class NoRemainingSignatures : TangemSdkError(40901) - /** - * This error is returned when a [com.tangem.commands.SignCommand] - * receives only empty hashes for signature. - */ - class EmptyHashes : TangemSdkError(40902) - /** - * This error is returned when a [com.tangem.commands.SignCommand] - * receives hashes of different lengths for signature. - */ - class HashSizeMustBeEqual : TangemSdkError(40903) - class CardIsEmpty : TangemSdkError(40904) - class SignHashesNotAvailable : TangemSdkError(40905) - /** - * Tangem cards can sign currently up to 10 hashes during one [com.tangem.commands.SignCommand]. - * This error is returned when a [com.tangem.commands.SignCommand] receives more than 10 hashes to sign. - */ - class TooManyHashesInOneTransaction : TangemSdkError(40906) - - //Write Extra Issuer Data Errors - class ExtendedDataSizeTooLarge : TangemSdkError(41101) - - //General Errors - class NotPersonalized() : TangemSdkError(40001) - class NotActivated : TangemSdkError(40002) - class CardIsPurged : TangemSdkError(40003) - class Pin2OrCvcRequired : TangemSdkError(40004) - /** - * This error is returned when a [Task] checks unsuccessfully either - * a card's ability to sign with its private key, or the validity of issuer data. - */ - class VerificationFailed : TangemSdkError(40005) - class DataSizeTooLarge : TangemSdkError(40006) - - /** - * This error is returned when [ReadIssuerDataTask] or [ReadIssuerExtraDataTask] expects a counter - * (when the card's requires it), but the counter is missing. - */ - class MissingCounter : TangemSdkError(40007) - class OverwritingDataIsProhibited : TangemSdkError(40008) - class DataCannotBeWritten : TangemSdkError(40009) - class MissingIssuerPubicKey : TangemSdkError(40010) - - //SDK Errors - class UnknownError: TangemSdkError(50001) - /** - * This error is returned when a user manually closes NFC Reading Bottom Sheet Dialog. - */ - class UserCancelled: TangemSdkError(50002) - /** - * This error is returned when [com.tangem.TangemSdk] was called with a new [Task], - * while a previous [Task] is still in progress. - */ - class Busy : TangemSdkError(50003) - /** - * This error is returned when a task (such as [ScanTask]) requires that [ReadCommand] - * is executed before performing other commands. - */ - class MissingPreflightRead : TangemSdkError(50004) - /** - * This error is returned when a [Task] expects a user to use a particular card, - * but the user tries to use a different card. - */ - class WrongCardNumber : TangemSdkError(50005) - /** - * This error is returned when a user scans a card of a [com.tangem.common.extensions.CardType] - * that is not specified in [Config.cardFilter]. - */ - class WrongCardType : TangemSdkError(50006) - /** - * This error is returned when a [ScanTask] returns a [Card] without some of the essential fields. - */ - class CardError : TangemSdkError(50007) - -} - diff --git a/tangem-core/src/main/java/com/tangem/commands/CheckWalletCommand.kt b/tangem-core/src/main/java/com/tangem/commands/CheckWalletCommand.kt deleted file mode 100644 index 7b7116ba44..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/CheckWalletCommand.kt +++ /dev/null @@ -1,101 +0,0 @@ -package com.tangem.commands - -import com.tangem.CardSession -import com.tangem.SessionEnvironment -import com.tangem.TangemSdkError -import com.tangem.common.CompletionResult -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvDecoder -import com.tangem.common.tlv.TlvTag -import com.tangem.crypto.CryptoUtils - -/** - * Deserialized response from the Tangem card after [CheckWalletCommand]. - * - * @property cardId Unique Tangem card ID number - * @property salt Random salt generated by the card. - * @property walletSignature Challenge and salt signed with the wallet private key. - */ -class CheckWalletResponse( - val cardId: String, - val salt: ByteArray, - val walletSignature: ByteArray -) : CommandResponse { - - fun verify(curve: EllipticCurve, publicKey: ByteArray, challenge: ByteArray): Boolean { - return CryptoUtils.verify( - publicKey, - challenge + salt, - walletSignature, - curve) - } -} - -/** - * This command proves that the wallet private key from the card corresponds to the wallet public key. - * Standard challenge/response scheme is used. - * - * @property pin1 Hashed user’s pin 1 code to access the card. Default unhashed value: ‘000000’. - * @property cardId Unique Tangem card ID number - * @property challenge Random challenge generated by application - */ -class CheckWalletCommand( - private val curve: EllipticCurve, private val publicKey: ByteArray -) : Command() { - - private val challenge = CryptoUtils.generateRandomBytes(16) - - override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { - super.run(session) { result -> - when (result) { - is CompletionResult.Failure -> { - callback(CompletionResult.Failure(result.error)) - } - is CompletionResult.Success -> { - val verified = result.data.verify( - curve, - publicKey, - challenge - ) - if (verified) { - callback(CompletionResult.Success(result.data)) - } else { - callback(CompletionResult.Failure(TangemSdkError.VerificationFailed())) - } - } - } - } - } - - override fun performPreCheck(card: Card): TangemSdkError? { - if (card.status == CardStatus.NotPersonalized) { - return TangemSdkError.NotPersonalized() - } - if (card.isActivated) { - return TangemSdkError.NotActivated() - } - return null - } - - override fun serialize(environment: SessionEnvironment): CommandApdu { - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.Pin, environment.pin1?.value) - tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) - tlvBuilder.append(TlvTag.Challenge, challenge) - return CommandApdu(Instruction.CheckWallet, tlvBuilder.serialize()) - } - - override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): CheckWalletResponse { - val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() - - val decoder = TlvDecoder(tlvData) - return CheckWalletResponse( - cardId = decoder.decode(TlvTag.CardId), - salt = decoder.decode(TlvTag.Salt), - walletSignature = decoder.decode(TlvTag.Signature) - ) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/Command.kt b/tangem-core/src/main/java/com/tangem/commands/Command.kt deleted file mode 100644 index 870cf3b446..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/Command.kt +++ /dev/null @@ -1,237 +0,0 @@ -package com.tangem.commands - -import com.tangem.* -import com.tangem.common.CompletionResult -import com.tangem.common.PinCode -import com.tangem.common.apdu.* -import com.tangem.common.extensions.toInt -import com.tangem.common.tlv.TlvTag -import com.tangem.tasks.PinType - - -interface ApduSerializable { - /** - * Serializes data into an array of [com.tangem.common.tlv.Tlv], - * then creates [CommandApdu] with this data. - * @param environment [SessionEnvironment] of the current card - * @return command data converted to [CommandApdu] that allows to convert it to [ByteArray] - * that can be sent to a Tangem card - */ - fun serialize(environment: SessionEnvironment): CommandApdu - - /** - * Deserializes data received from a card and stored in [ResponseApdu] - * into an array of [com.tangem.common.tlv.Tlv]. Then maps it into a [CommandResponse]. - * @param environment [SessionEnvironment] of the current card. - * @param apdu received data. - * @return Card response converted to a [CommandResponse] of a type [T] - */ - fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): T -} - -/** - * Basic interface for a parsed response from [Command]. - */ -interface CommandResponse - -/** - * Basic class for Tangem card commands - */ -abstract class Command : ApduSerializable, CardSessionRunnable { - - open val performPreflightRead: Boolean = true - override val requiresPin2: Boolean = false - - override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { - Log.i("Command", "Initializing ${this::class.java.simpleName}") - transceive(session, callback) - } - - open fun performPreCheck(card: Card): TangemSdkError? = null - - open fun mapError(card: Card?, error: TangemSdkError): TangemSdkError = error - - fun transceive(session: CardSession, callback: (result: CompletionResult) -> Unit) { - val card = session.environment.card - if (session.environment.handleErrors && card != null) { - performPreCheck(card)?.let { error -> - callback(CompletionResult.Failure(error)) - return - } - } - if (requiresPin2 && session.environment.pin2?.isDefault == true) { - handlePin2(session, callback) - return - } - transceiveInternal(session, callback) - } - - private fun transceiveInternal(session: CardSession, callback: (result: CompletionResult) -> Unit) { - val apdu = serialize(session.environment) - transceiveApdu(apdu, session) { result -> - when (result) { - is CompletionResult.Failure -> { - if (session.environment.handleErrors) { - val error = mapError(session.environment.card, result.error) - if (error is TangemSdkError.Pin1Required) { - session.environment.pin1 = null - handlePin1(session, callback) - return@transceiveApdu - } - if (error is TangemSdkError.Pin2OrCvcRequired) { - session.environment.pin2 = null - handlePin2(session, callback) - return@transceiveApdu - } - callback(CompletionResult.Failure(error)) - return@transceiveApdu - - } - callback(CompletionResult.Failure(result.error)) - } - is CompletionResult.Success -> { - try { - val response = deserialize(session.environment, result.data) - callback(CompletionResult.Success(response)) - } catch (error: TangemSdkError) { - callback(CompletionResult.Failure(error)) - } - } - } - } - } - - private fun transceiveApdu( - apdu: CommandApdu, - session: CardSession, - callback: (result: CompletionResult) -> Unit - ) { - Log.i(this::class.simpleName!!, "transieve: ${Instruction.byCode(apdu.ins)}") - - session.send(apdu) { result -> - when (result) { - is CompletionResult.Success -> { - val responseApdu = result.data - - when (responseApdu.statusWord) { - StatusWord.ProcessCompleted, - StatusWord.Pin1Changed, StatusWord.Pin2Changed, StatusWord.Pins12Changed, - StatusWord.Pin3Changed, StatusWord.Pins13Changed, StatusWord.Pins23Changed, - StatusWord.Pins123Changed -> { - callback(CompletionResult.Success(responseApdu)) - } - StatusWord.NeedPause -> { - // NeedPause is returned from the card whenever security delay is triggered. - val remainingTime = - deserializeSecurityDelay(responseApdu) - if (remainingTime != null) { - session.viewDelegate.onSecurityDelay( - remainingTime, - session.environment.card?.pauseBeforePin2 ?: 0 - ) - } - Log.i( - this::class.simpleName!!, - "Nfc command ${this::class.simpleName!!} " + - "triggered security delay of $remainingTime milliseconds" - ) - transceiveApdu(apdu, session, callback) - } - StatusWord.NeedEncryption -> { - Log.i(this::class.simpleName!!, "Establishing encryption") - when (session.environment.encryptionMode) { - EncryptionMode.NONE -> { - session.environment.encryptionKey = null - session.environment.encryptionMode = EncryptionMode.FAST - } - EncryptionMode.FAST -> { - session.environment.encryptionKey = null - session.environment.encryptionMode = EncryptionMode.STRONG - } - EncryptionMode.STRONG -> { - Log.e(this::class.simpleName!!, "Encryption doesn't work") - callback(CompletionResult.Failure(TangemSdkError.NeedEncryption())) - return@send - } - } - transceiveApdu(apdu, session, callback) - } - else -> { - val error = responseApdu.statusWord.toTangemSdkError() - if (error != null) { - callback(CompletionResult.Failure(error)) - } else { - callback(CompletionResult.Failure(TangemSdkError.UnknownError())) - } - } - } - } - is CompletionResult.Failure -> - if (result.error is TangemSdkError.TagLost) { - session.viewDelegate.onTagLost() - } else { - callback(CompletionResult.Failure(result.error)) - } - } - } - } - - /** - * Helper method to parse security delay information received from a card. - * - * @return Remaining security delay in milliseconds. - */ - private fun deserializeSecurityDelay( - responseApdu: ResponseApdu - ): Int? { - val tlv = responseApdu.getTlvData() - return tlv?.find { it.tag == TlvTag.Pause }?.value?.toInt() - } - - private fun handlePin1( - session: CardSession, - callback: (result: CompletionResult) -> Unit - ) { - session.pause() - session.viewDelegate.onPinRequested(PinType.Pin1) { pin1 -> - session.environment.pin1 = PinCode(pin1) - session.resume() - transceive(session, callback) - } - } - - private fun handlePin2( - session: CardSession, - callback: (result: CompletionResult) -> Unit - ) { - val currentPin1 = session.environment.pin1?.value ?: run { - callback(CompletionResult.Failure(TangemSdkError.Pin1Required())) - return - } - val currentPin2 = session.environment.pin2?.value ?: run { - callback(CompletionResult.Failure(TangemSdkError.Pin2OrCvcRequired())) - return - } - - val checkPinCommand = SetPinCommand(currentPin1, currentPin2) - checkPinCommand.run(session) { result -> - when (result) { - is CompletionResult.Failure -> { - session.environment.pin2 = null - getPin2FromDelegate(session, callback) - } - is CompletionResult.Success -> { - transceiveInternal(session, callback) - } - } - } - } - - private fun getPin2FromDelegate(session: CardSession, - callback: (result: CompletionResult) -> Unit) { - session.viewDelegate.onPinRequested(PinType.Pin2) { pin2 -> - session.environment.pin2 = PinCode(pin2) - transceive(session, callback) - } - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/CreateWalletCommand.kt b/tangem-core/src/main/java/com/tangem/commands/CreateWalletCommand.kt deleted file mode 100644 index af6cce48b8..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/CreateWalletCommand.kt +++ /dev/null @@ -1,86 +0,0 @@ -package com.tangem.commands - -import com.tangem.SessionEnvironment -import com.tangem.TangemSdkError -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvDecoder -import com.tangem.common.tlv.TlvTag - -class CreateWalletResponse( - /** - * CID, Unique Tangem card ID number. - */ - val cardId: String, - /** - * Current status of the card [1 - Empty, 2 - Loaded, 3- Purged] - */ - val status: CardStatus, - /** - - */ - val walletPublicKey: ByteArray -) : CommandResponse - -/** - * This command will create a new wallet on the card having ‘Empty’ state. - * A key pair WalletPublicKey / WalletPrivateKey is generated and securely stored in the card. - * App will need to obtain Wallet_PublicKey from the response of [CreateWalletCommand] or [ReadCommand] - * and then transform it into an address of corresponding blockchain wallet - * according to a specific blockchain algorithm. - * WalletPrivateKey is never revealed by the card and will be used by [SignCommand] and [CheckWalletCommand]. - * RemainingSignature is set to MaxSignatures. - * - * @property cardId CID, Unique Tangem card ID number. - */ -class CreateWalletCommand : Command() { - - override val requiresPin2 = true - - override fun performPreCheck(card: Card): TangemSdkError? { - if (card.isActivated) { - return TangemSdkError.NotActivated() - } - - return when (card.status) { - CardStatus.Empty -> null - CardStatus.NotPersonalized -> TangemSdkError.NotPersonalized() - CardStatus.Loaded -> TangemSdkError.AlreadyCreated() - CardStatus.Purged -> TangemSdkError.CardIsPurged() - null -> TangemSdkError.CardError() - } - } - - override fun mapError(card: Card?, error: TangemSdkError): TangemSdkError { - if (error is TangemSdkError.InvalidParams) { - return TangemSdkError.Pin2OrCvcRequired() - } - return error - } - - override fun serialize(environment: SessionEnvironment): CommandApdu { - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.Pin, environment.pin1?.value) - tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) - tlvBuilder.append(TlvTag.Pin2, environment.pin2?.value) - tlvBuilder.append(TlvTag.Cvc, environment.cvc) - return CommandApdu(Instruction.CreateWallet, tlvBuilder.serialize()) - } - - override fun deserialize( - environment: SessionEnvironment, - apdu: ResponseApdu - ): CreateWalletResponse { - val tlvData = apdu.getTlvData() - ?: throw TangemSdkError.DeserializeApduFailed() - - val decoder = TlvDecoder(tlvData) - return CreateWalletResponse( - cardId = decoder.decode(TlvTag.CardId), - status = decoder.decode(TlvTag.Status), - walletPublicKey = decoder.decode(TlvTag.WalletPublicKey) - ) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/OpenSessionCommand.kt b/tangem-core/src/main/java/com/tangem/commands/OpenSessionCommand.kt deleted file mode 100644 index cb682706bb..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/OpenSessionCommand.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.tangem.commands - -import com.tangem.SessionEnvironment -import com.tangem.TangemSdkError -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvDecoder -import com.tangem.common.tlv.TlvTag - -class OpenSessionResponse( - val sessionKeyB: ByteArray, - val uid: ByteArray -) : CommandResponse - -/** - * In case of encrypted communication, App should setup a session before calling any further command. - * [OpenSessionCommand] generates secret session_key that is used by both host and card - * to encrypt and decrypt commands’ payload. - */ -class OpenSessionCommand(private val sessionKeyA: ByteArray) : ApduSerializable { - override fun serialize(environment: SessionEnvironment): CommandApdu { - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.SessionKeyA, sessionKeyA) - return CommandApdu( - Instruction.OpenSession.code, tlvBuilder.serialize(), 0, environment.encryptionMode.code - ) - } - - override fun deserialize( - environment: SessionEnvironment, - apdu: ResponseApdu - ): OpenSessionResponse { - val tlvData = apdu.getTlvData() - ?: throw TangemSdkError.DeserializeApduFailed() - - val decoder = TlvDecoder(tlvData) - return OpenSessionResponse( - sessionKeyB = decoder.decode(TlvTag.SessionKeyB), - uid = decoder.decode(TlvTag.Uid) - ) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/PurgeWalletCommand.kt b/tangem-core/src/main/java/com/tangem/commands/PurgeWalletCommand.kt deleted file mode 100644 index 3d0631f3df..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/PurgeWalletCommand.kt +++ /dev/null @@ -1,78 +0,0 @@ -package com.tangem.commands - -import com.tangem.SessionEnvironment -import com.tangem.TangemSdkError -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvDecoder -import com.tangem.common.tlv.TlvTag - -class PurgeWalletResponse( - /** - * CID, Unique Tangem card ID number. - */ - val cardId: String, - /** - * Current status of the card [1 - Empty, 2 - Loaded, 3- Purged] - */ - val status: CardStatus -) : CommandResponse - -/** - * This command deletes all wallet data. If Is_Reusable flag is enabled during personalization, - - * If Is_Reusable flag is disabled, the card switches to ‘Purged’ state. - * ‘Purged’ state is final, it makes the card useless. - * @property cardId CID, Unique Tangem card ID number. - */ -class PurgeWalletCommand : Command() { - - override val requiresPin2 = true - - override fun performPreCheck(card: Card): TangemSdkError? { - if (card.status == CardStatus.NotPersonalized) { - return TangemSdkError.NotPersonalized() - } - if (card.isActivated) { - return TangemSdkError.NotActivated() - } - if (card.settingsMask?.contains(Settings.ProhibitPurgeWallet) == true) { - return TangemSdkError.PurgeWalletProhibited() - } - - return when (card.status) { - CardStatus.Loaded -> null - CardStatus.NotPersonalized -> TangemSdkError.NotPersonalized() - CardStatus.Empty -> TangemSdkError.CardIsEmpty() - CardStatus.Purged -> TangemSdkError.CardIsPurged() - null -> TangemSdkError.CardError() - } - } - - override fun mapError(card: Card?, error: TangemSdkError): TangemSdkError { - if (error is TangemSdkError.InvalidParams) { - return TangemSdkError.Pin2OrCvcRequired() - } - return error - } - - - override fun serialize(environment: SessionEnvironment): CommandApdu { - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.Pin, environment.pin1?.value) - tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) - tlvBuilder.append(TlvTag.Pin2, environment.pin2?.value) - return CommandApdu(Instruction.PurgeWallet, tlvBuilder.serialize()) - } - - override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): PurgeWalletResponse { - val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() - - val decoder = TlvDecoder(tlvData) - return PurgeWalletResponse( - cardId = decoder.decode(TlvTag.CardId), - status = decoder.decode(TlvTag.Status)) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/ReadCommand.kt b/tangem-core/src/main/java/com/tangem/commands/ReadCommand.kt deleted file mode 100644 index 6ce78d98cc..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/ReadCommand.kt +++ /dev/null @@ -1,396 +0,0 @@ -package com.tangem.commands - -import com.google.gson.annotations.SerializedName -import com.tangem.SessionEnvironment -import com.tangem.TangemSdkError -import com.tangem.commands.common.CardDeserializer -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvTag -import java.util.* - -/** - * Determines which type of data is required for signing. - */ -data class SigningMethodMask(val rawValue: Int) { - - fun contains(signingMethod: SigningMethod): Boolean { - return if (rawValue and 0x80 == 0) { - signingMethod.code == rawValue - } else { - rawValue and (0x01 shl signingMethod.code) != 0 - } - } -} - -enum class SigningMethod(val code: Int) { - SignHash(0), - SignRaw(1), - SignHashValidateByIssuer(2), - SignRawValidateByIssuer(3), - SignHashValidateByIssuerWriteIssuerData(4), - SignRawValidateByIssuerWriteIssuerData(5), - SignPos(6) -} - -class SigningMethodMaskBuilder() { - - private val signingMethods = mutableSetOf() - - fun add(signingMethod: SigningMethod) { - signingMethods.add(signingMethod) - } - - fun build(): SigningMethodMask { - val rawValue: Int = when { - signingMethods.count() == 0 -> { - 0 - } - signingMethods.count() == 1 -> { - signingMethods.iterator().next().code - } - else -> { - signingMethods.fold( - 0x80, { acc, singingMethod -> acc + (0x01 shl singingMethod.code) } - ) - } - } - return SigningMethodMask(rawValue) - } -} - -/** - * Elliptic curve used for wallet key operations. - */ -enum class EllipticCurve(val curve: String) { - @SerializedName(value = "secp256k1") - Secp256k1("secp256k1"), - @SerializedName(value = "ed25519") - Ed25519("ed25519"); - - companion object { - private val values = values() - fun byName(curve: String): EllipticCurve? = values.find { it.curve == curve } - } -} - -/** - * Status of the card and its wallet. - */ -enum class CardStatus(val code: Int) { - NotPersonalized(0), - Empty(1), - Loaded(2), - Purged(3); - - companion object { - private val values = values() - fun byCode(code: Int): CardStatus? = values.find { it.code == code } - } -} - -/** - * Mask of products enabled on card - * @property rawValue Products mask values, - * while flags definitions and values are in [ProductMask.Companion] as constants. - */ -data class ProductMask(val rawValue: Int) { - - fun contains(product: Product): Boolean = (rawValue and product.code) != 0 - -} - -enum class Product(val code: Int) { - Note(0x01), - Tag(0x02), - IdCard(0x04), - IdIssuer(0x08) -} - -class ProductMaskBuilder() { - - private var productMaskValue = 0 - - fun add(product: Product) { - productMaskValue = productMaskValue or product.code - } - - fun build() = ProductMask(productMaskValue) - -} - -/** - * Stores and maps Tangem card settings. - * - * @property rawValue Card settings in a form of flags, - * while flags definitions and possible values are in [Settings]. - */ -data class SettingsMask(val rawValue: Int) { - fun contains(settings: Settings): Boolean = (rawValue and settings.code) != 0 -} - -enum class Settings(val code: Int) { - IsReusable(0x0001), - UseActivation(0x0002), - ProhibitPurgeWallet(0x0004), - UseBlock(0x0008), - - AllowSwapPIN(0x0010), - AllowSwapPIN2(0x0020), - UseCVC(0x0040), - ForbidDefaultPIN(0x0080), - - UseOneCommandAtTime(0x0100), - UseNdef(0x0200), - UseDynamicNdef(0x0400), - SmartSecurityDelay(0x0800), - - ProtocolAllowUnencrypted(0x1000), - ProtocolAllowStaticEncryption(0x2000), - - ProtectIssuerDataAgainstReplay(0x4000), - RestrictOverwriteIssuerDataEx(0x00100000), - - AllowSelectBlockchain(0x8000), - - DisablePrecomputedNdef(0x00010000), - - SkipSecurityDelayIfValidatedByLinkedTerminal(0x00080000), - SkipCheckPin2andCvcIfValidatedByIssuer(0x00040000), - SkipSecurityDelayIfValidatedByIssuer(0x00020000), - - RequireTermTxSignature(0x01000000), - RequireTermCertSignature(0x02000000), - CheckPIN3onCard(0x04000000) -} - - -class SettingsMaskBuilder() { - - private var settingsMaskValue = 0 - - fun add(settings: Settings) { - settingsMaskValue = settingsMaskValue or settings.code - } - - fun build() = SettingsMask(settingsMaskValue) - -} - -/** - * Detailed information about card contents. - */ -class CardData( - - /** - * Tangem internal manufacturing batch ID. - */ - val batchId: String?, - - /** - * Timestamp of manufacturing. - */ - val manufactureDateTime: Date?, - - /** - * Name of the issuer. - */ - val issuerName: String?, - - /** - * Name of the blockchain. - */ - val blockchainName: String?, - - /** - * Signature of CardId with manufacturer’s private key. - */ - val manufacturerSignature: ByteArray?, - - /** - * Mask of products enabled on card. - */ - val productMask: ProductMask?, - - /** - * Name of the token. - */ - val tokenSymbol: String?, - - /** - * Smart contract address. - */ - val tokenContractAddress: String?, - - /** - * Number of decimals in token value. - */ - val tokenDecimal: Int? -) - -/** - * Response for [ReadCommand]. Contains detailed card information. - */ -class Card( - - /** - * Unique Tangem card ID number. - */ - val cardId: String, - - /** - * Name of Tangem card manufacturer. - */ - val manufacturerName: String, - - /** - * Current status of the card. - */ - val status: CardStatus?, - - /** - * Version of Tangem COS. - */ - val firmwareVersion: String?, - - /** - * Public key that is used to authenticate the card against manufacturer’s database. - * It is generated one time during card manufacturing. - */ - val cardPublicKey: ByteArray?, - - /** - * Card settings defined by personalization (bit mask: 0 – Enabled, 1 – Disabled). - */ - val settingsMask: SettingsMask?, - - /** - * Public key that is used by the card issuer to sign IssuerData field. - */ - val issuerPublicKey: ByteArray?, - - /** - * Explicit text name of the elliptic curve used for all wallet key operations. - * Supported curves: ‘secp256k1’ and ‘ed25519’. - */ - val curve: EllipticCurve?, - - /** - * Total number of signatures allowed for the wallet when the card was personalized. - */ - val maxSignatures: Int?, - - /** - * Defines what data should be submitted to SIGN command. - */ - val signingMethods: SigningMethodMask?, - - /** - * Delay in seconds before COS executes commands protected by PIN2. - */ - val pauseBeforePin2: Int?, - - /** - * Public key of the blockchain wallet. - */ - val walletPublicKey: ByteArray?, - - /** - * Remaining number of [SignCommand] operations before the wallet will stop signing transactions. - */ - val walletRemainingSignatures: Int?, - - /** - * Total number of signed single hashes returned by the card in - * [SignCommand] responses since card personalization. - * Sums up array elements within all [SignCommand]. - */ - val walletSignedHashes: Int?, - - /** - * Any non-zero value indicates that the card experiences some hardware problems. - * User should withdraw the value to other blockchain wallet as soon as possible. - * Non-zero Health tag will also appear in responses of all other commands. - */ - val health: Int?, - - /** - * Whether the card requires issuer’s confirmation of activation. - * is "true" if the card requires activation, - * is 'false" if the card is activated or does not require activation - */ - val isActivated: Boolean, - - /** - * A random challenge generated by personalisation that should be signed and returned - * to COS by the issuer to confirm the card has been activated. - * This field will not be returned if the card is activated. - */ - val activationSeed: ByteArray?, - - /** - * Returned only if [SigningMethod.SignPos] enabling POS transactions is supported by card. - */ - val paymentFlowVersion: ByteArray?, - - /** - * This value can be initialized by terminal and will be increased by COS on execution of every [SignCommand]. - * For example, this field can store blockchain “nonce” for quick one-touch transaction on POS terminals. - * Returned only if [SigningMethod.SignPos] enabling POS transactions is supported by card. - */ - val userCounter: Int?, - - /** - * This value can be initialized by App (with PIN2 confirmation) and will be increased by COS - * with the execution of each [SignCommand]. For example, this field can store blockchain “nonce” - * for a quick one-touch transaction on POS terminals. Returned only if [SigningMethod.SignPos]. - */ - val userProtectedCounter: Int?, - - /** - * When this value is true, it means that the application is linked to the card, - * and COS will not enforce security delay if [SignCommand] will be called - * with [TlvTag.TerminalTransactionSignature] parameter containing a correct signature of raw data - * to be signed made with [TlvTag.TerminalPublicKey]. - */ - val terminalIsLinked: Boolean, - - /** - * Detailed information about card contents. Format is defined by the card issuer. - * Cards complaint with Tangem Wallet application should have TLV format. - */ - val cardData: CardData? -) : CommandResponse - -/** - * This command receives from the Tangem Card all the data about the card and the wallet, - * including unique card number (CID or cardId) that has to be submitted while calling all other commands. - */ -class ReadCommand : Command() { - - override fun mapError(card: Card?, error: TangemSdkError): TangemSdkError { - if (error is TangemSdkError.InvalidParams) { - return TangemSdkError.Pin1Required() - } - return error - } - - override fun serialize(environment: SessionEnvironment): CommandApdu { - val tlvBuilder = TlvBuilder() - /** - * [SessionEnvironment] stores the pin1 value. If no pin1 value was set, it will contain - * default value of ‘000000’. - * In order to obtain card’s data, [ReadCommand] should use the correct pin 1 value. - * The card will not respond if wrong pin 1 has been submitted. - */ - tlvBuilder.append(TlvTag.Pin, environment.pin1?.value) - tlvBuilder.append(TlvTag.TerminalPublicKey, environment.terminalKeys?.publicKey) - return CommandApdu(Instruction.Read, tlvBuilder.serialize()) - } - - override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): Card { - return CardDeserializer.deserialize(apdu) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/ReadIssuerDataCommand.kt b/tangem-core/src/main/java/com/tangem/commands/ReadIssuerDataCommand.kt deleted file mode 100644 index 4d2301675a..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/ReadIssuerDataCommand.kt +++ /dev/null @@ -1,119 +0,0 @@ -package com.tangem.commands - -import com.tangem.CardSession -import com.tangem.SessionEnvironment -import com.tangem.TangemSdkError -import com.tangem.commands.common.DefaultIssuerDataVerifier -import com.tangem.commands.common.IssuerDataMode -import com.tangem.commands.common.IssuerDataToVerify -import com.tangem.commands.common.IssuerDataVerifier -import com.tangem.common.CompletionResult -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvDecoder -import com.tangem.common.tlv.TlvTag - -class ReadIssuerDataResponse( - - /** - * CID, Unique Tangem card ID number. - */ - val cardId: String, - - /** - * Data defined by issuer. - */ - val issuerData: ByteArray, - - /** - * Issuer’s signature of [issuerData] with Issuer Data Private Key (which is kept on card). - * Issuer’s signature of SHA256-hashed [cardId] concatenated with [issuerData]: - * SHA256([cardId] | [issuerData]). - * When flag [Settings.ProtectIssuerDataAgainstReplay] set in [SettingsMask] then signature of - * SHA256-hashed CID Issuer_Data concatenated with and [issuerDataCounter]: - * SHA256([cardId] | [issuerData] | [issuerDataCounter]). - */ - val issuerDataSignature: ByteArray, - - /** - * An optional counter that protect issuer data against replay attack. - * When flag [Settings.ProtectIssuerDataAgainstReplay] set in [SettingsMask] - * then this value is mandatory and must increase on each execution of [WriteIssuerDataCommand]. - */ - val issuerDataCounter: Int? -) : CommandResponse - - -/** - * This command returns 512-byte Issuer Data field and its issuer’s signature. - * Issuer Data is never changed or parsed from within the Tangem COS. The issuer defines purpose of use, - * format and payload of Issuer Data. For example, this field may contain information about - * wallet balance signed by the issuer or additional issuer’s attestation data. - * @property cardId CID, Unique Tangem card ID number. - */ -class ReadIssuerDataCommand( - val issuerPublicKey: ByteArray? = null, - verifier: IssuerDataVerifier = DefaultIssuerDataVerifier() -) : Command(), IssuerDataVerifier by verifier { - - override fun run( - session: CardSession, - callback: (result: CompletionResult) -> Unit - ) { - - val publicKey = issuerPublicKey ?: session.environment.card?.issuerPublicKey - - super.run(session) { result -> - when (result) { - is CompletionResult.Failure -> callback(result) - is CompletionResult.Success -> { - if (result.data.issuerData.isEmpty()) { - callback(result) - return@run - } - val issuerDataToVerify = IssuerDataToVerify( - result.data.cardId, result.data.issuerData, result.data.issuerDataCounter - ) - if (verify(publicKey!!, result.data.issuerDataSignature, issuerDataToVerify)) { - callback(result) - } else { - callback(CompletionResult.Failure(TangemSdkError.VerificationFailed())) - } - } - } - } - } - - override fun performPreCheck(card: Card): TangemSdkError? { - if (card.status == CardStatus.NotPersonalized) { - return TangemSdkError.NotPersonalized() - } - issuerPublicKey ?: card.issuerPublicKey ?: return TangemSdkError.MissingIssuerPubicKey() - return null - } - - override fun serialize(environment: SessionEnvironment): CommandApdu { - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.Pin, environment.pin1?.value) - tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) - tlvBuilder.append(TlvTag.Mode, IssuerDataMode.ReadData) - return CommandApdu(Instruction.ReadIssuerData, tlvBuilder.serialize()) - } - - override fun deserialize( - environment: SessionEnvironment, - apdu: ResponseApdu - ): ReadIssuerDataResponse { - val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() - - val decoder = TlvDecoder(tlvData) - return ReadIssuerDataResponse( - cardId = decoder.decode(TlvTag.CardId), - issuerData = decoder.decode(TlvTag.IssuerData), - issuerDataSignature = decoder.decode(TlvTag.IssuerDataSignature), - issuerDataCounter = decoder.decodeOptional(TlvTag.IssuerDataCounter) - ) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/ReadIssuerExtraDataCommand.kt b/tangem-core/src/main/java/com/tangem/commands/ReadIssuerExtraDataCommand.kt deleted file mode 100644 index 88e5af5569..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/ReadIssuerExtraDataCommand.kt +++ /dev/null @@ -1,178 +0,0 @@ -package com.tangem.commands - -import com.tangem.CardSession -import com.tangem.SessionEnvironment -import com.tangem.TangemSdkError -import com.tangem.commands.common.DefaultIssuerDataVerifier -import com.tangem.commands.common.IssuerDataMode -import com.tangem.commands.common.IssuerDataToVerify -import com.tangem.commands.common.IssuerDataVerifier -import com.tangem.common.CompletionResult -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvDecoder -import com.tangem.common.tlv.TlvTag -import java.io.ByteArrayOutputStream - -class ReadIssuerExtraDataResponse( - - /** - * CID, Unique Tangem card ID number. - */ - val cardId: String, - - /** - * Size of all Issuer_Extra_Data field. - */ - val size: Int?, - - /** - * Data defined by issuer. - */ - val issuerData: ByteArray, - - /** - * Issuer’s signature of [issuerData] with Issuer Data Private Key (which is kept on card). - * Issuer’s signature of SHA256-hashed [cardId] concatenated with [issuerData]: - * SHA256([cardId] | [issuerData]). - * When flag [Settings.ProtectIssuerDataAgainstReplay] set in [SettingsMask] then signature of - * SHA256-hashed CID Issuer_Data concatenated with and [issuerDataCounter]: - * SHA256([cardId] | [issuerData] | [issuerDataCounter]). - */ - val issuerDataSignature: ByteArray?, - - /** - * An optional counter that protects issuer data against replay attack. - * When flag [Settings.ProtectIssuerDataAgainstReplay] set in [SettingsMask] - * then this value is mandatory and must increase on each execution of [WriteIssuerDataCommand]. - */ - val issuerDataCounter: Int? -) : CommandResponse - - -/** - * This command retrieves Issuer Extra Data field and its issuer’s signature. - * Issuer Extra Data is never changed or parsed from within the Tangem COS. The issuer defines purpose of use, - * format and payload of Issuer Data. . For example, this field may contain photo or - * biometric information for ID card product. Because of the large size of Issuer_Extra_Data, - * a series of these commands have to be executed to read the entire Issuer_Extra_Data. - */ -class ReadIssuerExtraDataCommand( - private val issuerPublicKey: ByteArray? = null, - verifier: IssuerDataVerifier = DefaultIssuerDataVerifier() -) : Command(), IssuerDataVerifier by verifier { - - private val issuerData = ByteArrayOutputStream() - private var offset: Int = 0 - private var issuerDataSize: Int = 0 - - override fun performPreCheck(card: Card): TangemSdkError? { - if (card.status == CardStatus.NotPersonalized) { - return TangemSdkError.NotPersonalized() - } - issuerPublicKey ?: card.issuerPublicKey ?: return TangemSdkError.MissingIssuerPubicKey() - return null - } - - override fun run( - session: CardSession, - callback: (result: CompletionResult) -> Unit - ) { - val publicKey = issuerPublicKey ?: session.environment.card?.issuerPublicKey - readIssuerData(session, publicKey!!, callback) - } - - private fun readIssuerData( - session: CardSession, publicKey: ByteArray, - callback: (result: CompletionResult) -> Unit - ) { - - if (issuerDataSize != 0) { - session.viewDelegate.onDelay( - issuerDataSize, offset, WriteIssuerExtraDataCommand.SINGLE_WRITE_SIZE - ) - } - - transceive(session) { result -> - when (result) { - is CompletionResult.Success -> { - if (result.data.size != null) { - if (result.data.size == 0) { - callback(CompletionResult.Success(result.data)) - return@transceive - } - issuerDataSize = result.data.size - } - issuerData.write(result.data.issuerData) - if (result.data.issuerDataSignature == null) { - offset = issuerData.size() - readIssuerData(session, publicKey, callback) - } else { - completeTask(result.data, publicKey, callback) - } - } - is CompletionResult.Failure -> { - callback(CompletionResult.Failure(result.error)) - } - } - } - } - - private fun completeTask( - data: ReadIssuerExtraDataResponse, publicKey: ByteArray, - callback: (result: CompletionResult) -> Unit - ) { - val dataToVerify = IssuerDataToVerify( - data.cardId, - issuerData.toByteArray(), - data.issuerDataCounter - ) - if (verify(publicKey, data.issuerDataSignature!!, dataToVerify)) { - val finalResult = ReadIssuerExtraDataResponse( - data.cardId, - issuerDataSize, - issuerData.toByteArray(), - data.issuerDataSignature, - data.issuerDataCounter - ) - callback(CompletionResult.Success(finalResult)) - } else { - callback(CompletionResult.Failure(TangemSdkError.VerificationFailed())) - } - } - - override fun serialize(environment: SessionEnvironment): CommandApdu { - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.Pin, environment.pin1?.value) - tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) - tlvBuilder.append(TlvTag.Mode, IssuerDataMode.ReadExtraData) - tlvBuilder.append(TlvTag.Offset, offset) - return CommandApdu(Instruction.ReadIssuerData, tlvBuilder.serialize()) - } - - override fun deserialize( - environment: SessionEnvironment, - apdu: ResponseApdu - ): ReadIssuerExtraDataResponse { - val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() - - val decoder = TlvDecoder(tlvData) - return ReadIssuerExtraDataResponse( - cardId = decoder.decode(TlvTag.CardId), - size = decoder.decodeOptional(TlvTag.Size), - issuerData = decoder.decodeOptional(TlvTag.IssuerData) ?: byteArrayOf(), - issuerDataSignature = decoder.decodeOptional(TlvTag.IssuerDataSignature), - issuerDataCounter = decoder.decodeOptional(TlvTag.IssuerDataCounter) - ) - } - - companion object { - /** - * This mode value specifies that this command retrieves Issuer EXTRA data from the card - * (with value 0 the command will get instead simple Issuer Data from the card). - */ - const val EXTRA_DATA_MODE = 1 - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/ReadUserDataCommand.kt b/tangem-core/src/main/java/com/tangem/commands/ReadUserDataCommand.kt deleted file mode 100644 index 58baea5b08..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/ReadUserDataCommand.kt +++ /dev/null @@ -1,82 +0,0 @@ -package com.tangem.commands - -import com.tangem.SessionEnvironment -import com.tangem.TangemSdkError -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvDecoder -import com.tangem.common.tlv.TlvTag - -class ReadUserDataResponse( - /** - * CID, Unique Tangem card ID number. - */ - val cardId: String, - - /** - * Data defined by user's App. - */ - val userData: ByteArray, - - /** - * Data defined by user's App (confirmed by PIN2). - */ - val userProtectedData: ByteArray, - - /** - * Counter initialized by user's App and increased on every signing of new transaction - */ - val userCounter: Int, - - /** - * Counter initialized by user's App (confirmed by PIN2) and increased on every signing of new transaction - */ - val userProtectedCounter: Int - -) : CommandResponse - -/** - * This command returns two up to 512-byte User_Data, User_Protected_Data and two counters User_Counter and - * User_Protected_Counter fields. - * User_Data and User_ProtectedData are never changed or parsed by the executable code the Tangem COS. - * The App defines purpose of use, format and it's payload. For example, this field may contain cashed information - * from blockchain to accelerate preparing new transaction. - * User_Counter and User_ProtectedCounter are counters, that initial values can be set by App and increased on every signing - * of new transaction (on SIGN command that calculate new signatures). The App defines purpose of use. - * For example, this fields may contain blockchain nonce value. - */ -class ReadUserDataCommand : Command() { - - override fun performPreCheck(card: Card): TangemSdkError? { - if (card.status == CardStatus.NotPersonalized) { - return TangemSdkError.NotPersonalized() - } - if (card.isActivated) { - return TangemSdkError.NotActivated() - } - return null - } - - override fun serialize(environment: SessionEnvironment): CommandApdu { - val builder = TlvBuilder() - builder.append(TlvTag.CardId, environment.card?.cardId) - builder.append(TlvTag.Pin, environment.pin1?.value) - - return CommandApdu(Instruction.ReadUserData, builder.serialize()) - } - - override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): ReadUserDataResponse { - val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() - - val decoder = TlvDecoder(tlvData) - return ReadUserDataResponse( - cardId = decoder.decode(TlvTag.CardId), - userData = decoder.decode(TlvTag.UserData), - userProtectedData = decoder.decode(TlvTag.UserProtectedData), - userCounter = decoder.decode(TlvTag.UserCounter), - userProtectedCounter = decoder.decode(TlvTag.UserProtectedCounter) - ) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/SetPinCommand.kt b/tangem-core/src/main/java/com/tangem/commands/SetPinCommand.kt deleted file mode 100644 index 6b7f12fa80..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/SetPinCommand.kt +++ /dev/null @@ -1,82 +0,0 @@ -package com.tangem.commands - -import com.tangem.SessionEnvironment -import com.tangem.TangemSdkError -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.apdu.StatusWord -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvDecoder -import com.tangem.common.tlv.TlvTag - -enum class SetPinStatus { - PinsNotChanged, - Pin1Changed, - Pin2Changed, - Pin3Changed, - Pins12Changed, - Pins13Changed, - Pins23Changed, - Pins123Changed, - ; - - companion object { - fun fromStatusWord(statusWord: StatusWord): SetPinStatus? { - return when (statusWord) { - StatusWord.ProcessCompleted -> PinsNotChanged - StatusWord.Pin1Changed -> Pin1Changed - StatusWord.Pin2Changed -> Pin2Changed - StatusWord.Pins12Changed -> Pins12Changed - StatusWord.Pin3Changed -> Pin3Changed - StatusWord.Pins13Changed -> Pins13Changed - StatusWord.Pins23Changed -> Pins23Changed - StatusWord.Pins123Changed -> Pins123Changed - else -> null - } - } - } -} - -class SetPinResponse( - /** - * CID, Unique Tangem card ID number. - */ - val cardId: String, - /** - * - */ - val status: SetPinStatus -) : CommandResponse - -class SetPinCommand( - private var newPin1: ByteArray, - private var newPin2: ByteArray, - private var newPin3: ByteArray? = null -) : Command() { - - override fun serialize(environment: SessionEnvironment): CommandApdu { - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.Pin, environment.pin1?.value) - tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) - tlvBuilder.append(TlvTag.Pin2, environment.pin2?.value) - tlvBuilder.append(TlvTag.Cvc, environment.cvc) - tlvBuilder.append(TlvTag.NewPin, newPin1) - tlvBuilder.append(TlvTag.NewPin2, newPin2) - tlvBuilder.append(TlvTag.NewPin3, newPin3) - return CommandApdu(Instruction.SetPin, tlvBuilder.serialize()) - } - - override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): SetPinResponse { - val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() - - val status = SetPinStatus.fromStatusWord(apdu.statusWord) - ?: throw TangemSdkError.DecodingFailed() - - val decoder = TlvDecoder(tlvData) - return SetPinResponse( - cardId = decoder.decode(TlvTag.CardId), - status = status - ) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/SignCommand.kt b/tangem-core/src/main/java/com/tangem/commands/SignCommand.kt deleted file mode 100644 index 21c003b64b..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/SignCommand.kt +++ /dev/null @@ -1,121 +0,0 @@ -package com.tangem.commands - -import com.tangem.SessionEnvironment -import com.tangem.TangemSdkError -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvDecoder -import com.tangem.common.tlv.TlvTag -import com.tangem.crypto.sign - -/** - * @param cardId CID, Unique Tangem card ID number - * @param signature Signed hashes (array of resulting signatures) - * @param walletRemainingSignatures Remaining number of sign operations before the wallet will stop signing transactions. - * @param walletSignedHashes Total number of signed single hashes returned by the card in sign command responses. - * Sums up array elements within all SIGN commands - */ -class SignResponse( - val cardId: String, - val signature: ByteArray, - val walletRemainingSignatures: Int, - val walletSignedHashes: Int -) : CommandResponse - -/** - * Signs transaction hashes using a wallet private key, stored on the card. - * - * @property hashes Array of transaction hashes. - * @property cardId CID, Unique Tangem card ID number - */ -class SignCommand(private val hashes: Array) : Command() { - - override val requiresPin2 = true - - //TODO: Allow signing more than 10 hashes - - private val hashSizes = if (hashes.isNotEmpty()) hashes.first().size else 0 - - override fun performPreCheck(card: Card): TangemSdkError? { - if (card.isActivated) { - return TangemSdkError.NotActivated() - } - if (card.walletRemainingSignatures == 0) { - return TangemSdkError.NoRemainingSignatures() - } - if (card.signingMethods?.contains(SigningMethod.SignHash) != true) { - return TangemSdkError.SignHashesNotAvailable() - } - if (hashSizes == 0) { - return TangemSdkError.EmptyHashes() - } - if (hashes.any { it.size != hashSizes }) { - return TangemSdkError.HashSizeMustBeEqual() - } - - return when (card.status) { - CardStatus.Loaded -> null - CardStatus.Empty -> TangemSdkError. - CardIsEmpty() - CardStatus.NotPersonalized -> TangemSdkError.NotPersonalized() - CardStatus.Purged -> TangemSdkError.CardIsPurged() - null -> TangemSdkError.CardError() - } - } - - override fun mapError(card: Card?, error: TangemSdkError): TangemSdkError { - if (error is TangemSdkError.InvalidParams) { - return TangemSdkError.Pin2OrCvcRequired() - } - return error - } - - override fun serialize(environment: SessionEnvironment): CommandApdu { - val dataToSign = flattenHashes() - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.Pin, environment.pin1?.value) - tlvBuilder.append(TlvTag.Pin2, environment.pin2?.value) - tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) - tlvBuilder.append(TlvTag.TransactionOutHashSize, byteArrayOf(hashSizes.toByte())) - tlvBuilder.append(TlvTag.TransactionOutHash, dataToSign) - tlvBuilder.append(TlvTag.Cvc, environment.cvc) - - addTerminalSignature(environment, dataToSign, tlvBuilder) - return CommandApdu(Instruction.Sign, tlvBuilder.serialize()) - } - - private fun flattenHashes(): ByteArray { - return hashes.reduce { arr1, arr2 -> arr1 + arr2 } - } - - /** - * Application can optionally submit a public key Terminal_PublicKey in [SignCommand]. - * Submitted key is stored by the Tangem card if it differs from a previous submitted Terminal_PublicKey. - * The Tangem card will not enforce security delay if [SignCommand] will be called with - * TerminalTransactionSignature parameter containing a correct signature of raw data to be signed made with TerminalPrivateKey - * (this key should be generated and securily stored by the application). - */ - private fun addTerminalSignature( - environment: SessionEnvironment, dataToSign: ByteArray, tlvBuilder: TlvBuilder - ) { - environment.terminalKeys?.let { terminalKeyPair -> - val signedData = dataToSign.sign(terminalKeyPair.privateKey) - tlvBuilder.append(TlvTag.TerminalTransactionSignature, signedData) - tlvBuilder.append(TlvTag.TerminalPublicKey, terminalKeyPair.publicKey) - } - } - - override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): SignResponse { - val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() - - val decoder = TlvDecoder(tlvData) - return SignResponse( - cardId = decoder.decode(TlvTag.CardId), - signature = decoder.decode(TlvTag.Signature), - walletRemainingSignatures = decoder.decode(TlvTag.RemainingSignatures), - walletSignedHashes = decoder.decode(TlvTag.SignedHashes) - ) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/WriteIssuerDataCommand.kt b/tangem-core/src/main/java/com/tangem/commands/WriteIssuerDataCommand.kt deleted file mode 100644 index 62c44269e2..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/WriteIssuerDataCommand.kt +++ /dev/null @@ -1,111 +0,0 @@ -package com.tangem.commands - -import com.tangem.SessionEnvironment -import com.tangem.TangemSdkError -import com.tangem.commands.common.DefaultIssuerDataVerifier -import com.tangem.commands.common.IssuerDataMode -import com.tangem.commands.common.IssuerDataToVerify -import com.tangem.commands.common.IssuerDataVerifier -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvDecoder -import com.tangem.common.tlv.TlvTag - -class WriteIssuerDataResponse( - /** - * CID, Unique Tangem card ID number. - */ - val cardId: String -) : CommandResponse - -/** - * This command writes 512-byte Issuer Data field and its issuer’s signature. - * Issuer Data is never changed or parsed from within the Tangem COS. The issuer defines purpose of use, - * format and payload of Issuer Data. For example, this field may contain information about - * wallet balance signed by the issuer or additional issuer’s attestation data. - * @property cardId CID, Unique Tangem card ID number. - * @property issuerData Data provided by issuer. - * @property issuerDataSignature Issuer’s signature of [issuerData] with Issuer Data Private Key (which is kept on card). - * @property issuerDataCounter An optional counter that protect issuer data against replay attack. - */ -class WriteIssuerDataCommand( - private val issuerData: ByteArray, - private val issuerDataSignature: ByteArray, - private val issuerDataCounter: Int? = null, - private val issuerPublicKey: ByteArray? = null, - verifier: IssuerDataVerifier = DefaultIssuerDataVerifier() -) : Command(), IssuerDataVerifier by verifier { - - override fun performPreCheck(card: Card): TangemSdkError? { - val publicKey = issuerPublicKey ?: card.issuerPublicKey - ?: return TangemSdkError.MissingIssuerPubicKey() - - if (card.status == CardStatus.NotPersonalized) { - return TangemSdkError.NotPersonalized() - } - if (card.isActivated) { - return TangemSdkError.NotActivated() - } - if (issuerData.size > MAX_SIZE) { - return TangemSdkError.DataSizeTooLarge() - } - if (!isCounterValid(issuerDataCounter, card)) { - return TangemSdkError.MissingCounter() - } - if (!verifySignature(publicKey, card.cardId)) { - return TangemSdkError.VerificationFailed() - } - return null - } - - override fun mapError(card: Card?, error: TangemSdkError): TangemSdkError { - if (error is TangemSdkError.InvalidParams && isCounterRequired(card)) { - return TangemSdkError.DataCannotBeWritten() - } - return error - } - - private fun isCounterValid(issuerDataCounter: Int?, card: Card): Boolean = - if (isCounterRequired(card)) issuerDataCounter != null else true - - private fun isCounterRequired(card: Card?): Boolean = - card?.settingsMask?.contains(Settings.ProtectIssuerDataAgainstReplay) == true - - private fun verifySignature(publicKey: ByteArray, cardId: String): Boolean { - return verify( - publicKey, - issuerDataSignature, - IssuerDataToVerify(cardId, issuerData, issuerDataCounter) - ) - } - - override fun serialize(environment: SessionEnvironment): CommandApdu { - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.Pin, environment.pin1?.value) - tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) - tlvBuilder.append(TlvTag.Mode, IssuerDataMode.WriteData) - tlvBuilder.append(TlvTag.IssuerData, issuerData) - tlvBuilder.append(TlvTag.IssuerDataSignature, issuerDataSignature) - tlvBuilder.append(TlvTag.IssuerDataCounter, issuerDataCounter) - - return CommandApdu(Instruction.WriteIssuerData, tlvBuilder.serialize()) - } - - override fun deserialize( - environment: SessionEnvironment, - apdu: ResponseApdu - ): WriteIssuerDataResponse { - val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() - - val decoder = TlvDecoder(tlvData) - return WriteIssuerDataResponse( - cardId = decoder.decode(TlvTag.CardId) - ) - } - - companion object { - const val MAX_SIZE = 512 - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/WriteIssuerExtraDataCommand.kt b/tangem-core/src/main/java/com/tangem/commands/WriteIssuerExtraDataCommand.kt deleted file mode 100644 index 6859aff915..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/WriteIssuerExtraDataCommand.kt +++ /dev/null @@ -1,196 +0,0 @@ -package com.tangem.commands - -import com.tangem.CardSession -import com.tangem.SessionEnvironment -import com.tangem.TangemSdkError -import com.tangem.commands.common.DefaultIssuerDataVerifier -import com.tangem.commands.common.IssuerDataMode -import com.tangem.commands.common.IssuerDataToVerify -import com.tangem.commands.common.IssuerDataVerifier -import com.tangem.common.CompletionResult -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvDecoder -import com.tangem.common.tlv.TlvTag - -/** - * This command writes Issuer Extra Data field and its issuer’s signature. - * Issuer Extra Data is never changed or parsed from within the Tangem COS. - * The issuer defines purpose of use, format and payload of Issuer Data. - * For example, this field may contain a photo or biometric information for ID card products. - * Because of the large size of Issuer_Extra_Data, a series of these commands have to be executed - * to write entire Issuer_Extra_Data. - * @param issuerData Data provided by issuer. - * @param startingSignature Issuer’s signature with Issuer Data Private Key of [cardId], - * [issuerDataCounter] (if flags Protect_Issuer_Data_Against_Replay and - * Restrict_Overwrite_Issuer_Extra_Data are set in [SettingsMask]) and size of [issuerData]. - * @param finalizingSignature Issuer’s signature with Issuer Data Private Key of [cardId], - * [issuerData] and [issuerDataCounter] (the latter one only if flags Protect_Issuer_Data_Against_Replay - * andRestrict_Overwrite_Issuer_Extra_Data are set in [SettingsMask]). - * @param issuerDataCounter An optional counter that protect issuer data against replay attack. - */ -class WriteIssuerExtraDataCommand( - private val issuerData: ByteArray, - private val startingSignature: ByteArray, - private val finalizingSignature: ByteArray, - private val issuerDataCounter: Int? = null, - private val issuerPublicKey: ByteArray? = null, - verifier: IssuerDataVerifier = DefaultIssuerDataVerifier() -) : Command(), IssuerDataVerifier by verifier { - - var mode: IssuerDataMode = IssuerDataMode.InitializeWritingExtraData - var offset: Int = 0 - - override fun run( - session: CardSession, - callback: (result: CompletionResult) -> Unit - ) { - writeIssuerData(session, callback) - } - - override fun performPreCheck(card: Card): TangemSdkError? { - val publicKey = issuerPublicKey ?: card.issuerPublicKey - ?: return TangemSdkError.MissingIssuerPubicKey() - - if (card.status == CardStatus.NotPersonalized) { - return TangemSdkError.NotPersonalized() - } - if (card.isActivated) { - return TangemSdkError.NotActivated() - } - if (issuerData.size > MAX_SIZE) { - return TangemSdkError.DataSizeTooLarge() - } - if (!isCounterValid(issuerDataCounter, card)) { - return TangemSdkError.MissingCounter() - } - if (!verifySignatures(publicKey, card.cardId)) { - return TangemSdkError.VerificationFailed() - } - return null - } - - override fun mapError(card: Card?, error: TangemSdkError): TangemSdkError { - if (error is TangemSdkError.InvalidParams && isCounterRequired(card)) { - return TangemSdkError.DataCannotBeWritten() - } - if (error is TangemSdkError.InvalidState && - card?.settingsMask?.contains(Settings.ProtectIssuerDataAgainstReplay) == true) { - return TangemSdkError.OverwritingDataIsProhibited() - } - return error - } - - private fun isCounterValid(issuerDataCounter: Int?, card: Card): Boolean = - if (isCounterRequired(card)) issuerDataCounter != null else true - - private fun isCounterRequired(card: Card?): Boolean = - card?.settingsMask?.contains(Settings.ProtectIssuerDataAgainstReplay) == true - - private fun verifySignatures(publicKey: ByteArray, cardId: String): Boolean { - - val firstData = IssuerDataToVerify(cardId, null, issuerDataCounter, issuerData.size) - val secondData = IssuerDataToVerify(cardId, issuerData, issuerDataCounter) - - return verify(publicKey, startingSignature, firstData) && - verify(publicKey, finalizingSignature, secondData) - } - - private fun writeIssuerData( - session: CardSession, - callback: (result: CompletionResult) -> Unit - ) { - - if (mode == IssuerDataMode.WriteExtraData) { - session.viewDelegate.onDelay( - issuerData.size, - offset, - SINGLE_WRITE_SIZE - ) - } - transceive(session) { result -> - when (result) { - is CompletionResult.Success -> { - when (mode) { - IssuerDataMode.InitializeWritingExtraData -> { - mode = IssuerDataMode.WriteExtraData - writeIssuerData(session, callback) - return@transceive - } - IssuerDataMode.WriteExtraData -> { - offset += WriteIssuerExtraDataCommand.SINGLE_WRITE_SIZE - if (offset >= issuerData.size) { - mode = IssuerDataMode.FinalizeExtraData - } - writeIssuerData(session, callback) - return@transceive - } - IssuerDataMode.FinalizeExtraData -> { - callback(CompletionResult.Success(result.data)) - } - } - } - is CompletionResult.Failure -> { - if (session.environment.handleErrors) { - mapError(session.environment.card, result.error)?.let { - callback(CompletionResult.Failure(it)) - } - } - callback(CompletionResult.Failure(result.error)) - } - } - } - - - } - - override fun serialize(environment: SessionEnvironment): CommandApdu { - val tlvBuilder = TlvBuilder() - - tlvBuilder.append(TlvTag.Pin, environment.pin1?.value) - tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) - tlvBuilder.append(TlvTag.Mode, mode) - - when (mode) { - IssuerDataMode.InitializeWritingExtraData -> { - tlvBuilder.append(TlvTag.Size, issuerData.size) - tlvBuilder.append(TlvTag.IssuerDataSignature, startingSignature) - tlvBuilder.append(TlvTag.IssuerDataCounter, issuerDataCounter) - } - IssuerDataMode.WriteExtraData -> { - tlvBuilder.append(TlvTag.IssuerData, getDataToWrite()) - tlvBuilder.append(TlvTag.Offset, offset) - } - IssuerDataMode.FinalizeExtraData -> { - tlvBuilder.append(TlvTag.IssuerDataSignature, finalizingSignature) - } - } - return CommandApdu(Instruction.WriteIssuerData, tlvBuilder.serialize()) - } - - private fun getDataToWrite(): ByteArray = - issuerData.copyOfRange(offset, offset + calculatePartSize()) - - private fun calculatePartSize(): Int { - val bytesLeft = issuerData.size - offset - return if (bytesLeft < SINGLE_WRITE_SIZE) bytesLeft else SINGLE_WRITE_SIZE - } - - override fun deserialize( - environment: SessionEnvironment, - apdu: ResponseApdu - ): WriteIssuerDataResponse { - val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() - - return WriteIssuerDataResponse( - cardId = TlvDecoder(tlvData).decode(TlvTag.CardId) - ) - } - - companion object { - const val SINGLE_WRITE_SIZE = 1524 - const val MAX_SIZE = 32 * 1024 - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/WriteUserDataCommand.kt b/tangem-core/src/main/java/com/tangem/commands/WriteUserDataCommand.kt deleted file mode 100644 index fadb16731d..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/WriteUserDataCommand.kt +++ /dev/null @@ -1,80 +0,0 @@ -package com.tangem.commands - -import com.tangem.SessionEnvironment -import com.tangem.TangemSdkError -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvDecoder -import com.tangem.common.tlv.TlvTag - -class WriteUserDataResponse( - /** - * CID, Unique Tangem card ID number. - */ - val cardId: String -) : CommandResponse - -/** - * This command writes to the card any of User_Data, User_ProtectedData, User_Counter and User_ProtectedCounter fields. - * User_Data and User_ProtectedData are never changed or parsed by the executable code the Tangem COS. - * The App defines purpose of use, format and it's payload. For example, this field may contain cashed information - * from blockchain to accelerate preparing new transaction. - * User_Counter and User_ProtectedCounter are counters, that initial values can be set by App and increased on every signing - * of new transaction (on SIGN command that calculate new signatures). The App defines purpose of use. - * For example, this fields may contain blockchain nonce value. - * - * Writing of User_Counter and User_Data protected only by PIN1. - * User_ProtectedCounter and User_ProtectedData additionaly need PIN2 to confirmation. - */ -class WriteUserDataCommand(private val userData: ByteArray? = null, private val userProtectedData: ByteArray? = null, - private val userCounter: Int? = null, - private val userProtectedCounter: Int? = null) : Command() { - - override val requiresPin2 = true - - override fun performPreCheck(card: Card): TangemSdkError? { - if (card.status == CardStatus.NotPersonalized) { - return TangemSdkError.NotPersonalized() - } - if (card.isActivated) { - return TangemSdkError.NotActivated() - } - if (userData?.size ?: 0 > MAX_SIZE || userProtectedData?.size ?: 0 > MAX_SIZE) { - return TangemSdkError.DataSizeTooLarge() - } - return null - } - - override fun mapError(card: Card?, error: TangemSdkError): TangemSdkError { - if (error is TangemSdkError.InvalidParams) { - return TangemSdkError.Pin2OrCvcRequired() - } - return error - } - - override fun serialize(environment: SessionEnvironment): CommandApdu { - val builder = TlvBuilder() - builder.append(TlvTag.CardId, environment.card?.cardId) - builder.append(TlvTag.Pin, environment.pin1?.value) - builder.append(TlvTag.UserData, userData) - builder.append(TlvTag.UserCounter, userCounter) - builder.append(TlvTag.UserProtectedData, userProtectedData) - builder.append(TlvTag.UserProtectedCounter, userProtectedCounter) - if (userProtectedCounter != null || userProtectedData != null) - builder.append(TlvTag.Pin2, environment.pin2) - - return CommandApdu(Instruction.WriteUserData, builder.serialize()) - } - - override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): WriteUserDataResponse { - val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() - - return WriteUserDataResponse(TlvDecoder(tlvData).decode(TlvTag.CardId)) - } - - companion object{ - const val MAX_SIZE = 512 - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/common/CardDeserializer.kt b/tangem-core/src/main/java/com/tangem/commands/common/CardDeserializer.kt deleted file mode 100644 index ccf809cf65..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/common/CardDeserializer.kt +++ /dev/null @@ -1,67 +0,0 @@ -package com.tangem.commands.common - -import com.tangem.TangemSdkError -import com.tangem.commands.Card -import com.tangem.commands.CardData -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.tlv.Tlv -import com.tangem.common.tlv.TlvDecoder -import com.tangem.common.tlv.TlvTag - -class CardDeserializer() { - companion object { - fun deserialize(apdu: ResponseApdu): Card { - val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() - - val decoder = TlvDecoder(tlvData) - - return Card( - cardId = decoder.decodeOptional(TlvTag.CardId) ?: "", - manufacturerName = decoder.decodeOptional(TlvTag.ManufactureId) ?: "", - status = decoder.decodeOptional(TlvTag.Status), - - firmwareVersion = decoder.decodeOptional(TlvTag.Firmware), - cardPublicKey = decoder.decodeOptional(TlvTag.CardPublicKey), - settingsMask = decoder.decodeOptional(TlvTag.SettingsMask), - issuerPublicKey = decoder.decodeOptional(TlvTag.IssuerDataPublicKey), - curve = decoder.decodeOptional(TlvTag.CurveId), - maxSignatures = decoder.decodeOptional(TlvTag.MaxSignatures), - signingMethods = decoder.decodeOptional(TlvTag.SigningMethod), - pauseBeforePin2 = decoder.decodeOptional(TlvTag.PauseBeforePin2), - walletPublicKey = decoder.decodeOptional(TlvTag.WalletPublicKey), - walletRemainingSignatures = decoder.decodeOptional(TlvTag.RemainingSignatures), - walletSignedHashes = decoder.decodeOptional(TlvTag.SignedHashes), - health = decoder.decodeOptional(TlvTag.Health), - isActivated = decoder.decode(TlvTag.IsActivated), - activationSeed = decoder.decodeOptional(TlvTag.ActivationSeed), - paymentFlowVersion = decoder.decodeOptional(TlvTag.PaymentFlowVersion), - userCounter = decoder.decodeOptional(TlvTag.UserCounter), - userProtectedCounter = decoder.decodeOptional(TlvTag.UserProtectedCounter), - terminalIsLinked = decoder.decode(TlvTag.TerminalIsLinked), - - cardData = deserializeCardData(tlvData) - ) - } - - private fun deserializeCardData(tlvData: List): CardData? { - val cardDataTlvs = tlvData.find { it.tag == TlvTag.CardData }?.let { - Tlv.deserialize(it.value) - } - if (cardDataTlvs.isNullOrEmpty()) return null - - val decoder = TlvDecoder(cardDataTlvs) - return CardData( - batchId = decoder.decodeOptional(TlvTag.Batch), - manufactureDateTime = decoder.decodeOptional(TlvTag.ManufactureDateTime), - issuerName = decoder.decodeOptional(TlvTag.IssuerId), - blockchainName = decoder.decodeOptional(TlvTag.BlockchainId), - manufacturerSignature = decoder.decodeOptional(TlvTag.ManufacturerSignature), - productMask = decoder.decodeOptional(TlvTag.ProductMask), - - tokenSymbol = decoder.decodeOptional(TlvTag.TokenSymbol), - tokenContractAddress = decoder.decodeOptional(TlvTag.TokenContractAddress), - tokenDecimal = decoder.decodeOptional(TlvTag.TokenDecimal) - ) - } - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/common/IssuerDataMode.kt b/tangem-core/src/main/java/com/tangem/commands/common/IssuerDataMode.kt deleted file mode 100644 index 2ebded1b6d..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/common/IssuerDataMode.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.tangem.commands.common - -import com.tangem.commands.WriteIssuerExtraDataCommand - -/** - * This enum specifies modes for [WriteIssuerExtraDataCommand]. - */ -enum class IssuerDataMode(val code: Byte) { - - - /** - * This mode is required to read issuer data from the card. - */ - ReadData(0), - - /** - * This mode is required to write issuer data to the card. - */ - WriteData(0), - /** - * This mode is required to read issuer extra data from the card. - */ - ReadExtraData(1), - /** - * This mode is required to initiate writing issuer extra data to the card. - */ - InitializeWritingExtraData(1), - /** - * With this mode, the command writes part of issuer extra data - * (block of a size [WriteIssuerExtraDataCommand.SINGLE_WRITE_SIZE]) to the card. - */ - WriteExtraData(2), - /** - * This mode is used after the issuer extra data was fully written to the card. - * Under this mode the command provides the issuer signature - * to confirm the validity of data that was written to card. - */ - FinalizeExtraData(3); - - companion object { - private val values = values() - fun byCode(code: Byte): IssuerDataMode? = values.find { it.code == code } - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/common/IssuerDataVerifier.kt b/tangem-core/src/main/java/com/tangem/commands/common/IssuerDataVerifier.kt deleted file mode 100644 index 03bf58d56e..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/common/IssuerDataVerifier.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.tangem.commands.common - -import com.tangem.common.tlv.TlvEncoder -import com.tangem.common.tlv.TlvTag -import com.tangem.crypto.CryptoUtils -import java.io.ByteArrayOutputStream - -interface IssuerDataVerifier { - fun verify( - issuerPublicKey: ByteArray, signature: ByteArray, issuerDataToVerify: IssuerDataToVerify - ): Boolean -} - -class IssuerDataToVerify( - val cardId: String, - val issuerData: ByteArray?, - val issuerDataCounter: Int? = null, - val issuerExtraDataSize: Int? = null -) - -class DefaultIssuerDataVerifier : IssuerDataVerifier { - override fun verify( - issuerPublicKey: ByteArray, - signature: ByteArray, - issuerDataToVerify: IssuerDataToVerify - ): Boolean { - - val tlvEncoder = TlvEncoder() - val dataToVerify = ByteArrayOutputStream() - dataToVerify.write(tlvEncoder.encodeValue(TlvTag.CardId, issuerDataToVerify.cardId)) - issuerDataToVerify.issuerData?.let { dataToVerify.write(it) } - issuerDataToVerify.issuerDataCounter?.let { counter -> - dataToVerify.write(tlvEncoder.encodeValue(TlvTag.IssuerDataCounter, counter)) - } - issuerDataToVerify.issuerExtraDataSize?.let { - dataToVerify.write(tlvEncoder.encodeValue(TlvTag.Size, it)) - } - return CryptoUtils.verify(issuerPublicKey, dataToVerify.toByteArray(), signature) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/common/ResponseConverter.kt b/tangem-core/src/main/java/com/tangem/commands/common/ResponseConverter.kt deleted file mode 100644 index 54d38798a1..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/common/ResponseConverter.kt +++ /dev/null @@ -1,119 +0,0 @@ -package com.tangem.commands.common - -import com.google.gson.* -import com.tangem.commands.* -import com.tangem.common.extensions.print -import com.tangem.common.extensions.toHexString -import java.lang.reflect.Type -import java.text.DateFormat -import java.util.* - -/** -[REDACTED_AUTHOR] - */ -class ResponseConverter { - - val gson: Gson by lazy { init() } - - private val fieldConverter = ResponseFieldConverter() - - private fun init(): Gson { - val builder = GsonBuilder().apply { - registerTypeAdapter(ByteArray::class.java, ByteTypeAdapter(fieldConverter)) - registerTypeAdapter(SigningMethodMask::class.java, SigningMethodTypeAdapter(fieldConverter)) - registerTypeAdapter(SettingsMask::class.java, SettingsMaskTypeAdapter(fieldConverter)) - registerTypeAdapter(ProductMask::class.java, ProductMaskTypeAdapter(fieldConverter)) - registerTypeAdapter(Date::class.java, DateTypeAdapter()) - } - builder.setPrettyPrinting() - return builder.create() - } - - fun convertResponse(response: CommandResponse?): String = gson.toJson(response) -} - -class ByteTypeAdapter( - private val fieldConverter: ResponseFieldConverter -) : JsonSerializer { - override fun serialize(src: ByteArray, typeOfSrc: Type, context: JsonSerializationContext): JsonElement { - return JsonPrimitive(fieldConverter.byteArrayToHex(src)) - } -} - -class SettingsMaskTypeAdapter( - private val fieldConverter: ResponseFieldConverter -) : JsonSerializer { - override fun serialize(src: SettingsMask, typeOfSrc: Type, context: JsonSerializationContext): JsonElement { - return JsonArray().apply { - fieldConverter.settingsMaskList(src).forEach { add(it) } - } - } -} - -class ProductMaskTypeAdapter( - private val fieldConverter: ResponseFieldConverter -) : JsonSerializer { - override fun serialize(src: ProductMask, typeOfSrc: Type, context: JsonSerializationContext): JsonElement { - return JsonArray().apply { - fieldConverter.productMaskList(src).forEach { add(it) } - } - } -} - -class SigningMethodTypeAdapter( - private val fieldConverter: ResponseFieldConverter -) : JsonSerializer { - override fun serialize(src: SigningMethodMask, typeOfSrc: Type, context: JsonSerializationContext): JsonElement { - return JsonArray().apply { - fieldConverter.signingMethodList(src).forEach { add(it) } - } - } -} - -class DateTypeAdapter : JsonSerializer { - override fun serialize(src: Date, typeOfSrc: Type, context: JsonSerializationContext): JsonElement { - val formatter = DateFormat.getDateInstance(DateFormat.DEFAULT, Locale("en_US")) - return JsonPrimitive(formatter.format(src).toString()) - } -} - -class ResponseFieldConverter { - - fun productMask(productMask: ProductMask?): String { - return productMaskList(productMask).print(wrap = false) - } - - fun productMaskList(productMask: ProductMask?): List { - val mask = productMask ?: return emptyList() - - return Product.values().filter { mask.contains(it) }.map { it.name } - } - - fun signingMethod(signingMask: SigningMethodMask?): String { - return signingMethodList(signingMask).print(wrap = false) - } - - fun signingMethodList(signingMask: SigningMethodMask?): List { - val mask = signingMask ?: return emptyList() - - return SigningMethod.values().filter { mask.contains(it) }.map { it.name } - } - - fun settingsMask(settingsMask: SettingsMask?): String { - return settingsMaskList(settingsMask).print(wrap = false) - } - - fun settingsMaskList(settingsMask: SettingsMask?): List { - val masks = settingsMask ?: return emptyList() - - return Settings.values().filter { masks.contains(it) }.map { it.name } - } - - fun byteArrayToHex(byteArray: ByteArray?): String? { - return byteArray?.toHexString() - } - - fun byteArrayToString(byteArray: ByteArray?): String? { - return if (byteArray == null) null else String(byteArray) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/common/network/NetworkUtils.kt b/tangem-core/src/main/java/com/tangem/commands/common/network/NetworkUtils.kt deleted file mode 100644 index 6ff62b1021..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/common/network/NetworkUtils.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.tangem.commands.common.network - -import com.tangem.Log -import kotlinx.coroutines.delay -import java.io.IOException - -suspend fun retryIO( - times: Int = 3, - initialDelay: Long = 100, - maxDelay: Long = 1000, - factor: Double = 2.0, - block: suspend () -> T): T -{ - var currentDelay = initialDelay - repeat(times - 1) { - try { - return block() - } catch (e: IOException) { - Log.i("Network", e.localizedMessage) - } - delay(currentDelay) - currentDelay = (currentDelay * factor).toLong().coerceAtMost(maxDelay) - } - return block() -} - -sealed class Result { - data class Success(val data: T) : Result() - data class Failure(val error: Throwable?) : Result() -} - -suspend fun performRequest(block: suspend () -> T): Result { - return try { - val result = retryIO { block() } - Result.Success(result) - } catch (exception: Exception) { - Result.Failure(exception) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/common/network/RetrofitBuilder.kt b/tangem-core/src/main/java/com/tangem/commands/common/network/RetrofitBuilder.kt deleted file mode 100644 index ffbf990666..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/common/network/RetrofitBuilder.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.tangem.commands.common.network - -import com.squareup.moshi.Moshi -import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory -import retrofit2.Retrofit -import retrofit2.converter.moshi.MoshiConverterFactory - - -class ApiTangem { - companion object { - const val TANGEM_ENDPOINT: String = "https://verify.tangem.com/" - - const val VERIFY = "verify" - const val VERIFY_AND_GET_INFO = "card/verify-and-get-info" - const val ARTWORK = "card/artwork" - } - -} - -private val moshi: Moshi by lazy { - Moshi.Builder() - .add(KotlinJsonAdapterFactory()) - .build() -} - -fun createRetrofitInstance(baseUrl: String): Retrofit = - Retrofit.Builder() - .baseUrl(baseUrl) - .addConverterFactory(MoshiConverterFactory.create(moshi)) - .build() \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/common/network/TangemApi.kt b/tangem-core/src/main/java/com/tangem/commands/common/network/TangemApi.kt deleted file mode 100644 index 75507687c6..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/common/network/TangemApi.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.tangem.commands.common.network - - -import com.tangem.commands.common.network.ApiTangem.Companion.VERIFY_AND_GET_INFO -import com.tangem.commands.verifycard.CardVerifyAndGetInfo -import retrofit2.http.Body -import retrofit2.http.Headers -import retrofit2.http.POST - -interface TangemApi { - - @Headers("Content-Type: application/json") - @POST(VERIFY_AND_GET_INFO) - suspend fun getCardVerifyAndGetInfo(@Body requestBody: CardVerifyAndGetInfo.Request): CardVerifyAndGetInfo.Response - - -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/common/network/TangemService.kt b/tangem-core/src/main/java/com/tangem/commands/common/network/TangemService.kt deleted file mode 100644 index 295536233d..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/common/network/TangemService.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.tangem.commands.common.network - -import com.tangem.commands.verifycard.CardVerifyAndGetInfo - -class TangemService { - - private val tangemApi: TangemApi by lazy { - createRetrofitInstance(ApiTangem.TANGEM_ENDPOINT).create(TangemApi::class.java) - } - - suspend fun verifyAndGetInfo( - cardId: String, - cardPublicKey: String - ): Result { - val requestsBody = CardVerifyAndGetInfo.Request() - requestsBody.requests = - listOf(CardVerifyAndGetInfo.Request.Item(cardId, cardPublicKey)) - - return performRequest { tangemApi.getCardVerifyAndGetInfo(requestsBody) } - } - -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/DepersonalizeCommand.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/DepersonalizeCommand.kt deleted file mode 100644 index 912bb15e5f..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/DepersonalizeCommand.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.tangem.commands.personalization - -import com.tangem.SessionEnvironment -import com.tangem.commands.Command -import com.tangem.commands.CommandResponse -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu - -data class DepersonalizeResponse(val success: Boolean) : CommandResponse - -/** - * Command available on SDK cards only - * - * This command resets card to initial state, - * erasing all data written during personalization and usage. - */ -class DepersonalizeCommand : Command() { - - override val performPreflightRead = false - - override fun serialize(environment: SessionEnvironment): CommandApdu { - return CommandApdu( - Instruction.Depersonalize, byteArrayOf() - ) - } - - override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): DepersonalizeResponse { - return DepersonalizeResponse(true) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/NdefEncoder.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/NdefEncoder.kt deleted file mode 100644 index 6c6103556e..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/NdefEncoder.kt +++ /dev/null @@ -1,88 +0,0 @@ -package com.tangem.commands.personalization - -import com.tangem.commands.personalization.entities.NdefRecord -import java.io.ByteArrayOutputStream -import java.nio.charset.StandardCharsets - -/** - * Encodes information that is to be written on the card as an Ndef Tag. - */ -class NdefEncoder(private val ndefRecords: List, private val useDinamicNdef: Boolean) { - - fun encode(): ByteArray { - val bs = ByteArrayOutputStream() - // space for size - bs.write(0) - bs.write(0) - - for (i in ndefRecords.indices) { - val headerValue = (if (i == 0) 0x80 else 0x00) or (if (!useDinamicNdef && i == ndefRecords.size - 1) 0x40 else 0x00) - var value: ByteArray = ndefRecords[i].value.toByteArray(StandardCharsets.UTF_8) - encodeValue(ndefRecords[i], headerValue, bs) - } - - val result = bs.toByteArray() - result[0] = (result.size - 2 shr 8).toByte() - result[1] = (result.size - 2 and 0xFF).toByte() - return result - - } - - - private fun encodeValue(ndefRecord: NdefRecord, headerValue: Int, bs: ByteArrayOutputStream) { - when (ndefRecord.type) { - NdefRecord.Type.AAR -> { - bs.write((headerValue or 0x14)) // NDEF Header - bs.write(0x0F) // Length of the record type - bs.write(ndefRecord.valueInBytes.size) // Length of the payload data - bs.write(byteArrayOf(0x61.toByte(), 0x6E.toByte(), 0x64.toByte(), 0x72.toByte(), 0x6F.toByte(), 0x69.toByte(), 0x64.toByte(), 0x2E.toByte(), 0x63.toByte(), 0x6F.toByte(), 0x6D.toByte(), 0x3A.toByte(), - 0x70.toByte(), 0x6B.toByte(), 0x67.toByte())) // type name - bs.write(ndefRecord.valueInBytes) - } - NdefRecord.Type.URI -> { - bs.write((headerValue or 0x11)) // NDEF Header - bs.write(0x01) // Length of the record type - val uriIdentifierCode: Byte - val prefix: String - when { - ndefRecord.value.startsWith("http://www.") -> { - uriIdentifierCode = 0x01.toByte() - prefix = "http://www." - } - ndefRecord.value.startsWith("https://www.") -> { - uriIdentifierCode = 0x02.toByte() - prefix = "https://www." - } - ndefRecord.value.startsWith("http://") -> { - uriIdentifierCode = 0x03.toByte() - prefix = "http://" - } - ndefRecord.value.startsWith("https://") -> { - uriIdentifierCode = 0x04.toByte() - prefix = "https://" - } - else -> { - throw Exception() - } - } - val value = ndefRecord.value.substring(prefix.length).toByteArray() - bs.write(value.size + 1) // Length of the payload data - bs.write(0x55) // URI - bs.write(uriIdentifierCode.toInt()) // ? - bs.write(value) - } - NdefRecord.Type.TEXT -> { - bs.write((headerValue or 0x11)) // NDEF Header - bs.write(0x01) // Length of the record type - bs.write(ndefRecord.valueInBytes.size.toByte() + 1 + "en".length) // Length of the payload data - bs.write(0x54) // Text - bs.write(0x02) // UTF8(MSB=0)|"en".length - bs.write("en".toByteArray(StandardCharsets.US_ASCII)) - bs.write(ndefRecord.valueInBytes) - } - else -> throw Exception("Invalid NDEF record in config!") - } - } - - -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt deleted file mode 100644 index 643b374a13..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/PersonalizeCommand.kt +++ /dev/null @@ -1,125 +0,0 @@ -package com.tangem.commands.personalization - -import com.tangem.CardSession -import com.tangem.EncryptionMode -import com.tangem.SessionEnvironment -import com.tangem.TangemSdkError -import com.tangem.commands.Card -import com.tangem.commands.CardData -import com.tangem.commands.CardStatus -import com.tangem.commands.Command -import com.tangem.commands.common.CardDeserializer -import com.tangem.commands.personalization.entities.* -import com.tangem.common.CompletionResult -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.extensions.calculateSha256 -import com.tangem.common.extensions.hexToBytes -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvTag -import com.tangem.crypto.sign - -/** - * Command available on SDK cards only - * - * Personalization is an initialization procedure, required before starting using a card. - * During this procedure a card setting is set up. - * During this procedure all data exchange is encrypted. - * @property config is a configuration file with all the card settings that are written on the card - * during personalization. - * @property issuer Issuer is a third-party team or company wishing to use Tangem cards. - * @property manufacturer Tangem Card Manufacturer. - * @property acquirer Acquirer is a trusted third-party company that operates proprietary - * (non-EMV) POS terminal infrastructure and transaction processing back-end. - */ -class PersonalizeCommand( - private val config: CardConfig, - private val issuer: Issuer, private val manufacturer: Manufacturer, - private val acquirer: Acquirer? = null -) : Command() { - - override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { - val encryptionMode = session.environment.encryptionMode - val encryptionKey = session.environment.encryptionKey - session.environment.encryptionMode = EncryptionMode.NONE - session.environment.encryptionKey = devPersonalizationKey - super.run(session) { result -> - session.environment.encryptionMode = encryptionMode - session.environment.encryptionKey = encryptionKey - callback(result) - } - } - - override fun performPreCheck(card: Card): TangemSdkError? { - if (card.status != CardStatus.NotPersonalized) { - return TangemSdkError.AlreadyPersonalized() - } - return null - } - - override fun serialize(environment: SessionEnvironment): CommandApdu { - return CommandApdu(Instruction.Personalize, serializePersonalizationData(config)) - } - - override fun deserialize(environment: SessionEnvironment, apdu: ResponseApdu): Card { - return CardDeserializer.deserialize(apdu) - } - - private fun serializePersonalizationData(config: CardConfig): ByteArray { - val cardId = config.createCardId() ?: throw TangemSdkError.SerializeCommandError() - - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.CardId, cardId) - tlvBuilder.append(TlvTag.CurveId, config.curveID) - tlvBuilder.append(TlvTag.MaxSignatures, config.maxSignatures) - tlvBuilder.append(TlvTag.SigningMethod, config.signingMethods) - tlvBuilder.append(TlvTag.SettingsMask, config.createSettingsMask()) - tlvBuilder.append(TlvTag.PauseBeforePin2, config.pauseBeforePin2 / 10) - tlvBuilder.append(TlvTag.Cvc, config.cvc.toByteArray()) - if (!config.ndefRecords.isNullOrEmpty()) - tlvBuilder.append(TlvTag.NdefData, serializeNdef(config)) - - tlvBuilder.append(TlvTag.CreateWalletAtPersonalize, config.createWallet) - - tlvBuilder.append(TlvTag.NewPin, config.pin) - tlvBuilder.append(TlvTag.NewPin2, config.pin2) - tlvBuilder.append(TlvTag.NewPin3, config.pin3) - tlvBuilder.append(TlvTag.CrExKey, config.hexCrExKey) - tlvBuilder.append(TlvTag.IssuerDataPublicKey, issuer.dataKeyPair.publicKey) - tlvBuilder.append(TlvTag.IssuerTransactionPublicKey, issuer.transactionKeyPair.publicKey) - - tlvBuilder.append(TlvTag.AcquirerPublicKey, acquirer?.keyPair?.publicKey) - - tlvBuilder.append(TlvTag.CardData, serializeCardData(cardId, config.cardData)) - return tlvBuilder.serialize() - } - - private fun serializeNdef(config: CardConfig): ByteArray { - return NdefEncoder(config.ndefRecords, config.useDynamicNdef).encode() - } - - private fun serializeCardData(cardId: String, cardData: CardData): ByteArray { - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.Batch, cardData.batchId) - tlvBuilder.append(TlvTag.ProductMask, cardData.productMask) - tlvBuilder.append(TlvTag.ManufactureDateTime, cardData.manufactureDateTime) - tlvBuilder.append(TlvTag.IssuerId, issuer.id) - tlvBuilder.append(TlvTag.BlockchainId, cardData.blockchainName) - - if (cardData.tokenSymbol != null) { - tlvBuilder.append(TlvTag.TokenSymbol, cardData.tokenSymbol) - tlvBuilder.append(TlvTag.TokenContractAddress, cardData.tokenContractAddress) - tlvBuilder.append(TlvTag.TokenDecimal, cardData.tokenDecimal) - } - tlvBuilder.append( - TlvTag.CardIdManufacturerSignature, - cardId.hexToBytes().sign(manufacturer.keyPair.privateKey) - ) - return tlvBuilder.serialize() - } - - companion object { - val devPersonalizationKey = "1234".calculateSha256().copyOf(32) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/Acquirer.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/entities/Acquirer.kt deleted file mode 100644 index ec4cff04b0..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/Acquirer.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.tangem.commands.personalization.entities - -import com.tangem.KeyPair - -data class Acquirer( - val keyPair: KeyPair, - val name: String? = null, - val id: String? = null -) \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfig.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfig.kt deleted file mode 100644 index 7241e6c4f8..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfig.kt +++ /dev/null @@ -1,77 +0,0 @@ -package com.tangem.commands.personalization.entities - -import com.tangem.commands.CardData -import com.tangem.commands.EllipticCurve -import com.tangem.commands.SigningMethodMask -import com.tangem.common.extensions.calculateSha256 - -data class NdefRecord( - val type: Type, - val value: String -) { - enum class Type { - URI, AAR, TEXT - } - - @delegate:Transient - val valueInBytes: ByteArray by lazy { value.toByteArray() } -} - -/** - * It is a configuration file with all the card settings that are written on the card - * during [PersonalizeCommand]. - */ -class CardConfig( - val issuerName: String? = null, - val acquirerName: String? = null, - val series: String? = null, - val startNumber: Long = 0, - val count: Int = 0, - pin: String, - pin2: String, - pin3: String, - val hexCrExKey: String?, - val cvc: String, - val pauseBeforePin2: Int, - val smartSecurityDelay: Boolean, - val curveID: EllipticCurve, - val signingMethods: SigningMethodMask, - val maxSignatures: Int, - val isReusable: Boolean, - val allowSwapPin: Boolean, - val allowSwapPin2: Boolean, - val useActivation: Boolean, - val useCvc: Boolean, - val useNdef: Boolean, - val useDynamicNdef: Boolean, - val useOneCommandAtTime: Boolean, - val useBlock: Boolean, - val allowSelectBlockchain: Boolean, - val forbidPurgeWallet: Boolean, - val protocolAllowUnencrypted: Boolean, - val protocolAllowStaticEncryption: Boolean, - val protectIssuerDataAgainstReplay: Boolean, - val forbidDefaultPin: Boolean, - val disablePrecomputedNdef: Boolean, - val skipSecurityDelayIfValidatedByIssuer: Boolean, - val skipCheckPIN2andCVCIfValidatedByIssuer: Boolean, - val skipSecurityDelayIfValidatedByLinkedTerminal: Boolean, - - val restrictOverwriteIssuerDataEx: Boolean, - - val requireTerminalTxSignature: Boolean, - val requireTerminalCertSignature: Boolean, - val checkPin3onCard: Boolean, - - val createWallet: Boolean, - - val cardData: CardData, - val ndefRecords: List -) { - - val pin: ByteArray = pin.calculateSha256() - val pin2: ByteArray = pin2.calculateSha256() - val pin3: ByteArray = pin3.calculateSha256() - - companion object -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfigExtensions.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfigExtensions.kt deleted file mode 100644 index 78e5709596..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/CardConfigExtensions.kt +++ /dev/null @@ -1,81 +0,0 @@ -package com.tangem.commands.personalization.entities - -import com.tangem.commands.Settings -import com.tangem.commands.SettingsMask -import com.tangem.commands.SettingsMaskBuilder - -internal fun CardConfig.createSettingsMask(): SettingsMask { - val builder = SettingsMaskBuilder() - - if (allowSwapPin) builder.add(Settings.AllowSwapPIN) - if (allowSwapPin2) builder.add(Settings.AllowSwapPIN2) - if (useCvc) builder.add(Settings.UseCVC) - if (isReusable) builder.add(Settings.IsReusable) - - if (useOneCommandAtTime) builder.add(Settings.UseOneCommandAtTime) - if (useNdef) builder.add(Settings.UseNdef) - if (useDynamicNdef) builder.add(Settings.UseDynamicNdef) - if (disablePrecomputedNdef) builder.add(Settings.DisablePrecomputedNdef) - - if (protocolAllowUnencrypted) builder.add(Settings.ProtocolAllowUnencrypted) - if (protocolAllowStaticEncryption) builder.add(Settings.ProtocolAllowStaticEncryption) - - if (forbidDefaultPin) builder.add(Settings.ForbidDefaultPIN) - - if (useActivation) builder.add(Settings.UseActivation) - - if (useBlock) builder.add(Settings.UseBlock) - if (smartSecurityDelay) builder.add(Settings.SmartSecurityDelay) - - if (protectIssuerDataAgainstReplay) builder.add(Settings.ProtectIssuerDataAgainstReplay) - - if (forbidPurgeWallet) builder.add(Settings.ProhibitPurgeWallet) - if (allowSelectBlockchain) builder.add(Settings.AllowSelectBlockchain) - - if (skipCheckPIN2andCVCIfValidatedByIssuer) builder.add(Settings.SkipCheckPin2andCvcIfValidatedByIssuer) - if (skipSecurityDelayIfValidatedByIssuer) builder.add(Settings.SkipSecurityDelayIfValidatedByIssuer) - - if (skipSecurityDelayIfValidatedByLinkedTerminal) builder.add(Settings.SkipSecurityDelayIfValidatedByLinkedTerminal) - if (restrictOverwriteIssuerDataEx) builder.add(Settings.RestrictOverwriteIssuerDataEx) - - if (requireTerminalTxSignature) builder.add(Settings.RequireTermTxSignature) - - if (requireTerminalCertSignature) builder.add(Settings.RequireTermCertSignature) - - if (checkPin3onCard) builder.add(Settings.CheckPIN3onCard) - - return builder.build() -} - -internal fun CardConfig.createCardId(): String? { - if (series == null) return null - if (startNumber <= 0 || (series.length != 2 && series.length != 4)) return null - - val Alf = "ABCDEF0123456789" - fun checkSeries(series: String): Boolean { - val containsList = series.filter { Alf.contains(it) } - return containsList.length == series.length - } - if (!checkSeries(series)) return null - - val tail = if (series.length == 2) String.format("%013d", startNumber) else String.format("%011d", startNumber) - var cardId = (series + tail).replace(" ", "") - if (cardId.length != 15 || Alf.indexOf(cardId[0]) == -1 || Alf.indexOf(cardId[1]) == -1) - return null - - cardId += "0" - val length = cardId.length - var sum = 0 - for (i in 0 until length) { - // get digits in reverse order - var digit: Int - val cDigit = cardId[length - i - 1] - digit = if (cDigit in '0'..'9') cDigit - '0' else cDigit - 'A' - - // every 2nd number multiply with 2 - if (i % 2 == 1) digit *= 2 - sum += if (digit > 9) digit - 9 else digit - } - val lunh = (10 - sum % 10) % 10 - return cardId.substring(0, 15) + String.format("%d", lunh) -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/Issuer.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/entities/Issuer.kt deleted file mode 100644 index ee7ab58fa7..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/Issuer.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.commands.personalization.entities - -import com.tangem.KeyPair - -data class Issuer( - val name: String, - val id: String, - val dataKeyPair: KeyPair, - val transactionKeyPair: KeyPair -) \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/Manufacturer.kt b/tangem-core/src/main/java/com/tangem/commands/personalization/entities/Manufacturer.kt deleted file mode 100644 index 9e30287bb0..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/personalization/entities/Manufacturer.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.tangem.commands.personalization.entities - -import com.tangem.KeyPair - -data class Manufacturer( - val keyPair: KeyPair, - val name: String? = null -) \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/verifycard/VerifyCardCommand.kt b/tangem-core/src/main/java/com/tangem/commands/verifycard/VerifyCardCommand.kt deleted file mode 100644 index bbb3454e66..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/verifycard/VerifyCardCommand.kt +++ /dev/null @@ -1,159 +0,0 @@ -package com.tangem.commands.verifycard - -import com.tangem.CardSession -import com.tangem.SessionEnvironment -import com.tangem.TangemSdkError -import com.tangem.commands.Card -import com.tangem.commands.CardStatus -import com.tangem.commands.Command -import com.tangem.commands.CommandResponse -import com.tangem.commands.common.network.Result -import com.tangem.commands.common.network.TangemService -import com.tangem.common.CompletionResult -import com.tangem.common.apdu.CommandApdu -import com.tangem.common.apdu.Instruction -import com.tangem.common.apdu.ResponseApdu -import com.tangem.common.extensions.CardType -import com.tangem.common.extensions.getType -import com.tangem.common.extensions.toHexString -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvDecoder -import com.tangem.common.tlv.TlvTag -import com.tangem.crypto.CryptoUtils -import kotlinx.coroutines.launch - -class VerifyCardResponse( - val cardId: String, - val verificationState: VerifyCardState? = null, - val artworkInfo: ArtworkInfo? = null, - internal val salt: ByteArray, - internal val cardSignature: ByteArray -) : CommandResponse { - - fun verify(publicKey: ByteArray, challenge: ByteArray): Boolean { - return CryptoUtils.verify( - publicKey, - challenge + salt, - cardSignature - ) - } -} - -enum class VerifyCardState { - VerifiedOnline, - VerifiedOffline, -} - -class VerifyCardCommand(private val onlineVerification: Boolean) : Command() { - - private val challenge = CryptoUtils.generateRandomBytes(16) - private val tangemService = TangemService() - - override fun run( - session: CardSession, - callback: (result: CompletionResult) -> Unit - ) { - val card = session.environment.card - val cardPublicKey = card?.cardPublicKey - if (cardPublicKey == null) { - callback(CompletionResult.Failure(TangemSdkError.MissingPreflightRead())) - return - } - super.run(session) { result -> - when (result) { - is CompletionResult.Failure -> { - callback(CompletionResult.Failure(result.error)) - } - is CompletionResult.Success -> { - val response = result.data - val verified = response.verify(cardPublicKey, challenge) - if (!verified) { - callback(CompletionResult.Failure(TangemSdkError.VerificationFailed())) - return@run - } - if (!onlineVerification || card.getType() != CardType.Release) { - callback( - CompletionResult.Success( - VerifyCardResponse( - response.cardId, VerifyCardState.VerifiedOffline, null, - response.salt, response.cardSignature - ) - ) - ) - } else { - verify(result.data, card.cardId, cardPublicKey, session, callback) - } - } - } - } - } - - private fun verify( - response: VerifyCardResponse, cardId: String, cardPublicKey: ByteArray, - session: CardSession, - callback: (result: CompletionResult) -> Unit - ) { - session.scope.launch { - val result = tangemService.verifyAndGetInfo(cardId, cardPublicKey.toHexString()) - - when (result) { - is Result.Success -> { - if (result.data.results?.firstOrNull()?.passed == true) { - callback( - CompletionResult.Success( - VerifyCardResponse( - response.cardId, VerifyCardState.VerifiedOnline, response.artworkInfo, - response.salt, response.cardSignature - ) - ) - ) - } else { - callback(CompletionResult.Failure(TangemSdkError.VerificationFailed())) - } - } - is Result.Failure -> { - callback( - CompletionResult.Success( - VerifyCardResponse( - response.cardId, VerifyCardState.VerifiedOffline, null, - response.salt, response.cardSignature - ) - ) - ) - } - } - } - } - - override fun performPreCheck(card: Card): TangemSdkError? { - if (card.status == CardStatus.NotPersonalized) { - return TangemSdkError.NotPersonalized() - } - if (card.isActivated) { - return TangemSdkError.NotActivated() - } - return null - } - - override fun serialize(environment: SessionEnvironment): CommandApdu { - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.Pin, environment.pin1?.value) - tlvBuilder.append(TlvTag.CardId, environment.card?.cardId) - tlvBuilder.append(TlvTag.Challenge, challenge) - return CommandApdu(Instruction.VerifyCard, tlvBuilder.serialize()) - } - - override fun deserialize( - environment: SessionEnvironment, - apdu: ResponseApdu - ): VerifyCardResponse { - val tlvData = apdu.getTlvData() ?: throw TangemSdkError.DeserializeApduFailed() - - val decoder = TlvDecoder(tlvData) - return VerifyCardResponse( - cardId = decoder.decode(TlvTag.CardId), - salt = decoder.decode(TlvTag.Salt), - cardSignature = decoder.decode(TlvTag.CardSignature) - ) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/commands/verifycard/VerifyCardRequest.kt b/tangem-core/src/main/java/com/tangem/commands/verifycard/VerifyCardRequest.kt deleted file mode 100644 index 8bc7efd052..0000000000 --- a/tangem-core/src/main/java/com/tangem/commands/verifycard/VerifyCardRequest.kt +++ /dev/null @@ -1,60 +0,0 @@ -package com.tangem.commands.verifycard - -import com.squareup.moshi.JsonClass -import java.text.SimpleDateFormat -import java.util.* - - -class CardVerifyAndGetInfo { - - @JsonClass(generateAdapter = true) - data class Request( - var requests: List? = null - ) { - @JsonClass(generateAdapter = true) - data class Item( - var CID: String = "", - var publicKey: String = "" - ) - } - - @JsonClass(generateAdapter = true) - data class Response( - var results: List? = null - ) { - @JsonClass(generateAdapter = true) - data class Item( - var error: String? = null, - var CID: String = "", - var passed: Boolean = false, - var batch: String = "", - var artwork: ArtworkInfo? = null, - var substitution: SubstitutionInfo? = null - ) { - - @JsonClass(generateAdapter = true) - data class SubstitutionInfo( - var data: String? = null, - var signature: String? = null - ) - - } - } -} - -@JsonClass(generateAdapter = true) -data class ArtworkInfo( - var id: String = "", - var hash: String = "", - var date: String = "" -) { - fun getUpdateDate(): Date? { - return try { - SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US).parse(date) - } catch (e: Exception) { - e.printStackTrace() - null - } - } - -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/CardValuesStorage.kt b/tangem-core/src/main/java/com/tangem/common/CardValuesStorage.kt deleted file mode 100644 index 26262ccddb..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/CardValuesStorage.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.tangem.common - -import com.squareup.sqldelight.EnumColumnAdapter -import com.squareup.sqldelight.db.SqlDriver -import com.squareup.sqldelight.sqlite.driver.JdbcSqliteDriver -import com.tangem.CardValues -import com.tangem.CardValuesEntityQueries -import com.tangem.Database -import com.tangem.VerificationState - -interface CardValuesStorage { - - fun saveValues(cardId: String, - isPin1Default: Boolean, isPin2Default: Boolean, - cardVerification: VerificationState?, - cardValidation: VerificationState?, - codeVerification: VerificationState?) - - fun getValues(cardId: String): CardValues? - -} - -class CardValuesDbStorage(driver: SqlDriver) : CardValuesStorage { - - private val cardValuesQueries: CardValuesEntityQueries - - init { - val database = Database(driver, cardValuesAdapter = CardValues.Adapter( - cardVerificationAdapter = EnumColumnAdapter(), - cardValidationAdapter = EnumColumnAdapter(), - codeVerificationAdapter = EnumColumnAdapter() - )) - cardValuesQueries = database.cardValuesEntityQueries - } - - override fun saveValues(cardId: String, - isPin1Default: Boolean, isPin2Default: Boolean, - cardVerification: VerificationState?, - cardValidation: VerificationState?, - codeVerification: VerificationState?) { - cardValuesQueries.insertOrReplace( - cardId, - isPin1Default, isPin2Default, - cardVerification, cardValidation, codeVerification - ) - } - - override fun getValues(cardId: String): CardValues? = - cardValuesQueries.selectByCardId(cardId).executeAsOneOrNull() - - companion object { - fun initJvm() = CardValuesDbStorage( - JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY).also { Database.Schema.create(it) } - ) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/CompletionResult.kt b/tangem-core/src/main/java/com/tangem/common/CompletionResult.kt deleted file mode 100644 index 52bf7a9351..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/CompletionResult.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.tangem.common - -import com.tangem.TangemSdkError -import com.tangem.common.CompletionResult.Success - -/** - * Response class encapsulating successful and failed results. - * @param T Type of data that is returned in [Success]. - */ -sealed class CompletionResult { - class Success(val data: T) : CompletionResult() - class Failure(val error: TangemSdkError) : CompletionResult() -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/PinCode.kt b/tangem-core/src/main/java/com/tangem/common/PinCode.kt deleted file mode 100644 index 0262089def..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/PinCode.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.common - -import com.tangem.common.extensions.calculateSha256 - -class PinCode( - val value: ByteArray, - val isDefault: Boolean -) { - constructor(value: String, isDefault: Boolean = false): this(value.calculateSha256(), isDefault) -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/TerminalKeysService.kt b/tangem-core/src/main/java/com/tangem/common/TerminalKeysService.kt deleted file mode 100644 index 3ba365247d..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/TerminalKeysService.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.tangem.common - -import com.tangem.KeyPair - -/** - * Interface for a service for managing Terminal keypair, used for Linked Terminal feature. - * Its implementation Needs to be provided to [com.tangem.TangemSdk] - * by calling [com.tangem.TangemSdk.setTerminalKeysService]. - * Default implementation is provided in tangem-sdk module: [TerminalKeysStorage]. - * Linked Terminal feature can be disabled manually by editing [com.tangem.Config]. - */ -interface TerminalKeysService { - fun getKeys(): KeyPair -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/apdu/CommandApdu.kt b/tangem-core/src/main/java/com/tangem/common/apdu/CommandApdu.kt deleted file mode 100644 index a152a5f2d2..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/apdu/CommandApdu.kt +++ /dev/null @@ -1,89 +0,0 @@ -package com.tangem.common.apdu - -import com.tangem.EncryptionMode -import com.tangem.common.extensions.calculateCrc16 -import com.tangem.common.extensions.toByteArray -import com.tangem.crypto.encrypt -import java.io.ByteArrayOutputStream - -/** - * Class that provides conversion of serialized request and Instruction code - * to a raw data that can be sent to the card. - * - * @property ins Instruction code that determines the type of request for the card. - * @property tlvs Tlvs encoded to a [ByteArray] that are to be sent to the card. - */ -class CommandApdu( - - val ins: Int, - private val tlvs: ByteArray, - - private val p1: Int, - private val p2: Int, - - private val le: Int = 0x00, - - private val cla: Int = ISO_CLA -) { - - constructor( - instruction: Instruction, - tlvs: ByteArray - ) : this( - instruction.code, - tlvs, - 0, - 0 - ) - - /** - * Request converted to a raw data - */ - val apduData: ByteArray - - init { - apduData = toBytes() - } - - - private fun toBytes(): ByteArray { - val data = tlvs - - val byteStream = ByteArrayOutputStream() - byteStream.write(cla) - byteStream.write(ins) - byteStream.write(p1) - byteStream.write(p2) - if (data.isNotEmpty()) { - byteStream.writeLength(data.size) - byteStream.write(data) - } - return byteStream.toByteArray() - } - - private fun ByteArrayOutputStream.writeLength(lc: Int) { - this.write(0) - this.write(lc shr 8) - this.write(lc and 0xFF) - } - - - fun encrypt( - encryptionMode: EncryptionMode, - encryptionKey: ByteArray? - ): CommandApdu { - - if (encryptionKey == null || p1 != EncryptionMode.NONE.code) { - return this - } - val crc: ByteArray = tlvs.calculateCrc16() - val dataToEncrypt = tlvs.size.toByteArray(2) + crc + tlvs - val encryptedData = dataToEncrypt.encrypt(encryptionKey) - - return CommandApdu(ins, encryptedData, encryptionMode.code, p2, le, cla) - } - - companion object { - const val ISO_CLA = 0x00 - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/apdu/Instruction.kt b/tangem-core/src/main/java/com/tangem/common/apdu/Instruction.kt deleted file mode 100644 index 02a5eabf7b..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/apdu/Instruction.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.tangem.common.apdu - -/** - * Instruction code that determines the type of the command that is sent to the Tangem card. - * It is used in the construction of [com.tangem.common.apdu.CommandApdu]. - */ -enum class Instruction(var code: Int) { - Unknown(0x00), - Personalize(0xF1), - Read(0xF2), - VerifyCard(0xF3), - ValidateCard(0xF4), - VerifyCode(0xF5), - WriteIssuerData(0xF6), - ReadIssuerData(0xF7), - CreateWallet(0xF8), - CheckWallet(0xF9), - SetPin(0xFA), - Sign(0xFB), - PurgeWallet(0xFC), - Activate(0xFE), - OpenSession(0xFF), - WriteUserData(0xE0), - ReadUserData(0xE1), - Depersonalize(0xE3); - - - companion object { - private val values = values() - fun byCode(code: Int): Instruction = values.find { it.code == code } ?: Unknown - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/apdu/ResponseApdu.kt b/tangem-core/src/main/java/com/tangem/common/apdu/ResponseApdu.kt deleted file mode 100644 index afc869f64a..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/apdu/ResponseApdu.kt +++ /dev/null @@ -1,64 +0,0 @@ -package com.tangem.common.apdu - -import com.tangem.TangemSdkError -import com.tangem.common.extensions.calculateCrc16 -import com.tangem.common.tlv.Tlv -import com.tangem.crypto.decrypt -import java.io.ByteArrayInputStream - -/** - * Stores response data from the card and parses it to [Tlv] and [StatusWord]. - * - * @property data Raw response from the card. - * @property sw Status word code, reflecting the status of the response. - * @property statusWord Parsed status word. - */ -class ResponseApdu(private val data: ByteArray) { - - private val sw1: Int = 0x00FF and data[data.size - 2].toInt() - private val sw2: Int = 0x00FF and data[data.size - 1].toInt() - - val sw: Int = sw1 shl 8 or sw2 - - val statusWord: StatusWord = StatusWord.byCode(sw) - - /** - * Converts raw response data to the list of TLVs. - * - * @param encryptionKey key to decrypt response. - * (Encryption / decryption functionality is not implemented yet.) - */ - fun getTlvData(): List? { - return if (data.size <= 2) { - null - } else { - Tlv.deserialize(data.copyOf(data.size - 2)) - } - } - - fun decrypt(encryptionKey: ByteArray?): ResponseApdu { - if (encryptionKey == null) return this - - //nothing to decrypt - if (data.size < 18) return this - - val responseData = data.copyOf(data.size - 2) - - val decryptedData: ByteArray = responseData.decrypt(encryptionKey) - - val inputStream = ByteArrayInputStream(decryptedData) - val baLength = ByteArray(2) - inputStream.read(baLength) - val length = (baLength[0].toInt() and 0xFF) * 256 + (baLength[1].toInt() and 0xFF) - if (length > decryptedData.size - 4) throw TangemSdkError.InvalidResponse() - val baCRC = ByteArray(2) - inputStream.read(baCRC) - val answerData = ByteArray(length) - inputStream.read(answerData) - val crc: ByteArray = answerData.calculateCrc16() - if (!baCRC.contentEquals(crc)) throw TangemSdkError.InvalidResponse() - - return ResponseApdu(answerData + data[data.size - 2] + data[data.size - 1]) - } - -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/apdu/StatusWord.kt b/tangem-core/src/main/java/com/tangem/common/apdu/StatusWord.kt deleted file mode 100644 index 0b60f3ff91..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/apdu/StatusWord.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.tangem.common.apdu - -import com.tangem.TangemSdkError - -/** - * Part of a response from the card, shows the status of the operation - */ -enum class StatusWord(val code: Int) { - - ProcessCompleted(0x9000), - InvalidParams(0x6A86), - ErrorProcessingCommand(0x6286), - InvalidState(0x6985), - - //PinsNotChanged(0x9000) is equal to ProcessCompleted(0x9000) - Pin1Changed(0x9001), - Pin2Changed(0x9002), - Pins12Changed(0x9003), - Pin3Changed(0x9004), - Pins13Changed(0x9005), - Pins23Changed(0x9006), - Pins123Changed(0x9007), - - - InsNotSupported(0x6D00), - NeedEncryption(0x6982), - NeedPause(0x9789), - Unknown(0x0000); - - companion object { - private val values = values() - fun byCode(code: Int): StatusWord = values.find { it.code == code } ?: Unknown - } -} - -fun StatusWord.toTangemSdkError(): TangemSdkError? { - return when (this) { - StatusWord.ProcessCompleted, StatusWord.Pin1Changed, - StatusWord.Pin2Changed, StatusWord.Pins12Changed, StatusWord.Pin3Changed, - StatusWord.Pins13Changed, StatusWord.Pins23Changed, StatusWord.Pins123Changed -> null - StatusWord.NeedPause -> null - StatusWord.InvalidParams -> TangemSdkError.InvalidParams() - StatusWord.ErrorProcessingCommand -> TangemSdkError.ErrorProcessingCommand() - StatusWord.InvalidState -> TangemSdkError.InvalidState() - StatusWord.InsNotSupported -> TangemSdkError.InsNotSupported() - StatusWord.NeedEncryption -> TangemSdkError.NeedEncryption() - StatusWord.Unknown -> TangemSdkError.UnknownStatus() - } -} diff --git a/tangem-core/src/main/java/com/tangem/common/extensions/BigDecimal.kt b/tangem-core/src/main/java/com/tangem/common/extensions/BigDecimal.kt deleted file mode 100644 index 6d23ffee09..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/extensions/BigDecimal.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.tangem.common.extensions - -import java.math.BigDecimal - -fun BigDecimal.isZero() : Boolean { - return this.compareTo(BigDecimal.ZERO) == 0 -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/extensions/ByteArray.kt b/tangem-core/src/main/java/com/tangem/common/extensions/ByteArray.kt deleted file mode 100644 index 226018b9d1..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/extensions/ByteArray.kt +++ /dev/null @@ -1,74 +0,0 @@ -package com.tangem.common.extensions - -import org.spongycastle.crypto.digests.RIPEMD160Digest -import org.spongycastle.jce.ECNamedCurveTable -import java.nio.ByteBuffer -import java.security.MessageDigest -import java.util.* -import kotlin.experimental.and -import kotlin.experimental.xor - -/** - * Extension functions for [ByteArray]. - */ - -fun ByteArray.toHexString(): String = joinToString("") { "%02X".format(it) } - -fun ByteArray.toUtf8(): String = String(this).removeSuffix("\u0000") - -fun ByteArray.toInt(): Int { - return when (this.size) { - 1 -> (this[0] and 0xFF.toByte()).toInt() - 2 -> ByteBuffer.wrap(this).short.toInt() - 4 -> ByteBuffer.wrap(this).int - else -> throw IllegalArgumentException("Length must be 1,2 or 4. Length = " + this.size) - } -} - -fun ByteArray.toDate(): Date { - val year = copyOfRange(0, 2).toInt() - val month = if (this.size > 2) this[2] - 1 else 0 - val day = if (this.size > 3) this[3].toInt() else 0 - val cd = Calendar.getInstance() - cd.set(year, month, day, 0, 0, 0) - return cd.time -} - -fun ByteArray.calculateSha512(): ByteArray = MessageDigest.getInstance("SHA-512").digest(this) - -fun ByteArray.calculateSha256(): ByteArray = MessageDigest.getInstance("SHA-256").digest(this) - -fun ByteArray.calculateRipemd160(): ByteArray { - val digest = RIPEMD160Digest() - digest.update(this, 0, this.size) - val out = ByteArray(20) - digest.doFinal(out, 0) - return out -} - -fun ByteArray.toCompressedPublicKey(): ByteArray { - return if (this.size == 65) { - val spec = ECNamedCurveTable.getParameterSpec("secp256k1") - val publicKeyPoint = spec.curve.decodePoint(this) - publicKeyPoint.getEncoded(true) - } else { - this - } -} - -fun ByteArray.calculateCrc16(): ByteArray { - var chBlock: Byte - // STEP 1 Initialize the CRC-16 value - var wCRC = 0x6363 // ITU-V.41 - var i = 0 - // STEP 2 Update data and Calucuate their CRC - do { - chBlock = this.get(i++) - chBlock = chBlock xor (wCRC and 0x00FF).toByte() - val chBlockInt = (chBlock.toInt() xor (chBlock.toInt() shl 4)) - wCRC = wCRC shr 8 xor (chBlockInt and 0xFF shl 8) and 0xFFFF xor (chBlockInt and 0xFF shl 3 and 0xFFFF) xor (chBlockInt and 0xFF shr 4 and 0xFFFF) - // (wCRC>>8)^((int)chBlock<<8)^((int) chBlock<<3)^((int)chBlock>>4); - } while (i < this.size) - - return byteArrayOf((wCRC and 0xFF).toByte(), (wCRC and 0xFFFF shr 8).toByte()) -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/extensions/Card.kt b/tangem-core/src/main/java/com/tangem/common/extensions/Card.kt deleted file mode 100644 index 97243f3655..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/extensions/Card.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.tangem.common.extensions - -import com.tangem.commands.Card - -fun Card.getType(): CardType { - val firmware = this.firmwareVersion ?: return CardType.Unknown - return when { - firmware.endsWith("d SDK") -> { - CardType.Sdk - } - firmware.endsWith("r") -> { - CardType.Release - } - else -> { - CardType.Unknown - } - } -} - -enum class CardType { - Sdk, Release, Unknown -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/extensions/IntExtensions.kt b/tangem-core/src/main/java/com/tangem/common/extensions/IntExtensions.kt deleted file mode 100644 index 0e8aa998da..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/extensions/IntExtensions.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.tangem.common.extensions - -import java.nio.ByteBuffer - -fun Int.toByteArray(size: Int = Int.SIZE_BYTES): ByteArray { - if (size == Int.SIZE_BYTES) { - val buffer = ByteBuffer.allocate(size) - buffer.putInt(this) - return buffer.array() - } else if (size == Short.SIZE_BYTES){ - return byteArrayOf( - (this ushr 8).toByte(), - this.toByte()) - } - return byteArrayOf() -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/extensions/List.kt b/tangem-core/src/main/java/com/tangem/common/extensions/List.kt deleted file mode 100644 index 2579809de6..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/extensions/List.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.tangem.common.extensions - -fun List.print(delimiter: String = ", ", wrap: Boolean = true): String { - val builder = StringBuilder() - forEach { builder.append(it).append(delimiter) } - val length = builder.length - if (length > delimiter.length) { - builder.delete(length - delimiter.length, length) - } - val result = builder.toString() - - return if (wrap) "[$result]" else result -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/extensions/String.kt b/tangem-core/src/main/java/com/tangem/common/extensions/String.kt deleted file mode 100644 index fbddb5829c..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/extensions/String.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.tangem.common.extensions - -import java.nio.charset.Charset -import java.security.MessageDigest - -/** - * Extension functions for [String]. - */ -fun String.calculateSha256(): ByteArray { - val sha256 = MessageDigest.getInstance("SHA-256") - val data = this.toByteArray(Charset.forName("UTF-8")) - return sha256.digest(data) -} - -fun String.calculateSha512(): ByteArray { - val sha = MessageDigest.getInstance("SHA-512") - val data = this.toByteArray(Charset.forName("UTF-8")) - return sha.digest(data) -} - -fun String.hexToBytes(): ByteArray { - return ByteArray(this.length / 2) - { i -> - Integer.parseInt(this.substring(2 * i, 2 * i + 2), 16).toByte() - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/tlv/Tlv.kt b/tangem-core/src/main/java/com/tangem/common/tlv/Tlv.kt deleted file mode 100644 index 5b0f5a47c5..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/tlv/Tlv.kt +++ /dev/null @@ -1,105 +0,0 @@ -package com.tangem.common.tlv - -import com.tangem.Log -import com.tangem.common.extensions.toHexString -import java.io.ByteArrayInputStream -import java.io.IOException - -/** - * The data converted to the Tag Length Value protocol. - */ -class Tlv { - - val tag: TlvTag - val value: ByteArray - val tagRaw: Int - - constructor(tagCode: Int, value: ByteArray = byteArrayOf()) { - this.tag = TlvTag.byCode(tagCode) - this.tagRaw = tagCode - this.value = value - } - - constructor(tag: TlvTag, value: ByteArray = byteArrayOf()) { - this.tag = tag - this.tagRaw = tag.code - this.value = value - } - - - companion object { - private fun tlvFromBytes(stream: ByteArrayInputStream): Tlv? { - val code = stream.read() - if (code == -1) return null - var len = stream.read() - if (len == -1) - throw IOException("Can't read TLV") - if (len == 0xFF) { - val lenH = stream.read() - if (lenH == -1) - throw IOException("Can't read TLV") - len = stream.read() - if (len == -1) - throw IOException("Can't read TLV") - len = len or (lenH shl 8) - } - val value = ByteArray(len) - if (len > 0) { - if (len != stream.read(value)) { - throw IOException("Can't read TLV") - } - } - val tag = TlvTag.byCode(code) - return if (tag == TlvTag.Unknown) Tlv(code, value) else Tlv(tag, value) - } - - - fun deserialize(data: ByteArray, nfcV: Boolean = false): List? { - val tlvList = mutableListOf() - val stream = ByteArrayInputStream(data) - var tlv: Tlv? - do { - try { - tlv = tlvFromBytes(stream) - if (tlv != null) tlvList.add(tlv) - } catch (e: IOException) { - Log.e(this::class.java.simpleName,"TLVError: " + e.message) - if (nfcV) break else return null - } - - } while (tlv != null) - return tlvList - } - } - - override fun toString(): String { - return "${this.tag} ($tagRaw): ${value.toHexString()}" - } - -} - -fun List.serialize(): ByteArray = - this.map { it.serialize() }.reduce { arr1, arr2 -> arr1 + arr2 } - -fun Tlv.serialize(): ByteArray { - val tag = byteArrayOf(this.tag.code.toByte()) - val length = getLengthInBytes(this.value.size) - val value = if (this.value.isNotEmpty()) this.value else byteArrayOf(0x00) - return tag + length + value -} - -private fun getLengthInBytes(tlvLength: Int): ByteArray { - return if (tlvLength > 0) { - if (tlvLength > 0xFE) { - byteArrayOf( - 0xFF.toByte(), - (tlvLength shr 8 and 0xFF).toByte(), - (tlvLength and 0xFF).toByte() - ) - } else { - byteArrayOf((tlvLength and 0xFF).toByte()) - } - } else { - byteArrayOf() - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/tlv/TlvBuilder.kt b/tangem-core/src/main/java/com/tangem/common/tlv/TlvBuilder.kt deleted file mode 100644 index 8c7ec12fad..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/tlv/TlvBuilder.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.tangem.common.tlv - -import com.tangem.Log - -class TlvBuilder { - private val tlvs = mutableListOf() - private val encoder = TlvEncoder() - - internal inline fun append(tag: TlvTag, value: T?) { - if (value == null) return - - tlvs.add(encoder.encode(tag, value)) - } - - fun serialize(): ByteArray { - Log.v("TLV", - "Data encoded to TLVs:\n${tlvs.joinToString("\n")}") - return tlvs.serialize() - } - -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/tlv/TlvDecoder.kt b/tangem-core/src/main/java/com/tangem/common/tlv/TlvDecoder.kt deleted file mode 100644 index 866fbbd41c..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/tlv/TlvDecoder.kt +++ /dev/null @@ -1,162 +0,0 @@ -package com.tangem.common.tlv - -import com.tangem.Log -import com.tangem.TangemSdkError -import com.tangem.commands.* -import com.tangem.commands.common.IssuerDataMode -import com.tangem.common.extensions.toDate -import com.tangem.common.extensions.toHexString -import com.tangem.common.extensions.toInt -import com.tangem.common.extensions.toUtf8 -import java.util.* - -/** - * Maps value fields in [Tlv] from raw [ByteArray] to concrete classes - * according to their [TlvTag] and corresponding [TlvValueType]. - * - * @property tlvList List of TLVs, which values are to be converted to particular classes. - */ -class TlvDecoder(val tlvList: List) { - - init { - Log.v("TLV", - "Decoding data from TLV:\n${tlvList.joinToString("\n")}") - } - - /** - * Finds [Tlv] by its [TlvTag]. - * Returns null if [Tlv] is not found, otherwise converts its value to [T]. - * - * @param tag [TlvTag] of a [Tlv] which value is to be returned. - * - * @return Value converted to a nullable type [T]. - */ - inline fun decodeOptional(tag: TlvTag): T? = - try { - decode(tag, false) - } catch (exception: TangemSdkError.DecodingFailedMissingTag) { - null - } - - /** - * Finds [Tlv] by its [TlvTag]. - * Throws [TaskError.MissingTag] if [Tlv] is not found, - * otherwise converts [Tlv] value to [T]. - * - * @param tag [TlvTag] of a [Tlv] which value is to be returned. - * - * @return [Tlv] value converted to a nullable type [T]. - * - * @throws [TangemSdkError.DecodingFailedMissingTag] exception if no [Tlv] is found by the Tag. - */ - inline fun decode(tag: TlvTag, logError: Boolean = true): T { - val tlvValue: ByteArray = tlvList.find { it.tag == tag }?.value - ?: if (tag.valueType() == TlvValueType.BoolValue && T::class == Boolean::class) { - return false as T - } else { - if (logError) { - Log.e(this::class.simpleName!!, "TLV $tag not found") - } else { - Log.v(this::class.simpleName!!, "TLV $tag not found, but it is not required") - } - throw TangemSdkError.DecodingFailedMissingTag() - } - - return when (tag.valueType()) { - TlvValueType.HexString, TlvValueType.HexStringToHash -> { - typeCheck(tag) - tlvValue.toHexString() as T - } - TlvValueType.Utf8String -> { - typeCheck(tag) - tlvValue.toUtf8() as T - } - TlvValueType.Uint16, TlvValueType.Uint32 -> { - typeCheck(tag) - try { - tlvValue.toInt() as T - } catch (exception: IllegalArgumentException) { - Log.e(this::class.simpleName!!, exception.message ?: "") - throw TangemSdkError.DecodingFailed() - } - } - TlvValueType.BoolValue -> { - typeCheck(tag) - true as T - } - TlvValueType.ByteArray -> { - typeCheck(tag) - tlvValue as T - } - TlvValueType.EllipticCurve -> { - typeCheck(tag) - try { - EllipticCurve.byName(tlvValue.toUtf8()) as T - } catch (exception: Exception) { - logException(tag, tlvValue.toUtf8(), exception) - throw TangemSdkError.DecodingFailed() - } - - - } - TlvValueType.DateTime -> { - typeCheck(tag) - try { - tlvValue.toDate() as T - } catch (exception: Exception) { - logException(tag, tlvValue.toHexString(), exception) - throw TangemSdkError.DecodingFailed() - } - } - TlvValueType.ProductMask -> { - typeCheck(tag) - ProductMask(tlvValue.toInt()) as T - } - TlvValueType.SettingsMask -> { - typeCheck(tag) - SettingsMask(tlvValue.toInt()) as T - } - TlvValueType.CardStatus -> { - typeCheck(tag) - try { - CardStatus.byCode(tlvValue.toInt()) as T - } catch (exception: Exception) { - logException(tag, tlvValue.toInt().toString(), exception) - throw TangemSdkError.DecodingFailed() - } - } - TlvValueType.SigningMethod -> { - typeCheck(tag) - try { - SigningMethodMask(tlvValue.toInt()) as T - } catch (exception: Exception) { - logException(tag, tlvValue.toInt().toString(), exception) - throw TangemSdkError.DecodingFailed() - } - } - TlvValueType.IssuerDataMode -> { - typeCheck(tag) - try { - IssuerDataMode.byCode(tlvValue.toInt().toByte()) as T - } catch (exception: Exception) { - logException(tag, tlvValue.toInt().toString(), exception) - throw TangemSdkError.DecodingFailed() - } - } - } - } - - fun logException(tag: TlvTag, value: String, exception: Exception) { - Log.e(this::class.simpleName!!, - "Unknown ${tag.name} with value of: value, \n${exception.message}") - } - - inline fun typeCheck(tag: TlvTag) { - if (T::class != ExpectedT::class) { - Log.e(this::class.simpleName!!, - "Mapping error. Type for tag: $tag must be ${tag.valueType()}. It is ${T::class}") - throw TangemSdkError.DecodingFailedTypeMismatch() - } - } - -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/tlv/TlvEncoder.kt b/tangem-core/src/main/java/com/tangem/common/tlv/TlvEncoder.kt deleted file mode 100644 index 99589b7d40..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/tlv/TlvEncoder.kt +++ /dev/null @@ -1,112 +0,0 @@ -package com.tangem.common.tlv - -import com.tangem.Log -import com.tangem.TangemSdkError -import com.tangem.commands.* -import com.tangem.commands.common.IssuerDataMode -import com.tangem.common.extensions.calculateSha256 -import com.tangem.common.extensions.hexToBytes -import com.tangem.common.extensions.toByteArray -import java.util.* - -/** - * Encodes information that is to be written on the card from parsed classes into [ByteArray] - * (according to the provided [TlvTag] and corresponding [TlvValueType]) - * and then forms [Tlv] with the encoded values. - */ -class TlvEncoder { - /** - - * @param value information that is to be encoded into [Tlv]. - */ - internal inline fun encode(tag: TlvTag, value: T?): Tlv { - if (value != null) { - return Tlv(tag, encodeValue(tag, value)) - } else { - Log.e(this::class.simpleName!!, "Encoding error. Value for tag $tag is null") - throw TangemSdkError.EncodingFailed() - } - } - - internal inline fun encodeValue(tag: TlvTag, value: T): ByteArray { - return when (tag.valueType()) { - TlvValueType.HexString -> { - typeCheck(tag) - (value as String).hexToBytes() - } - TlvValueType.HexStringToHash -> { - typeCheck(tag) - (value as String).calculateSha256() - } - TlvValueType.Utf8String -> { - typeCheck(tag) - (value as String).toByteArray() - } - TlvValueType.Uint16 -> { - typeCheck(tag) - (value as Int).toByteArray(2) - } - TlvValueType.Uint32 -> { - typeCheck(tag) - (value as Int).toByteArray() - } - TlvValueType.BoolValue -> { - typeCheck(tag) - val booleanValue = value as Boolean - if (booleanValue) byteArrayOf(1) else byteArrayOf(0) - } - TlvValueType.ByteArray -> { - typeCheck(tag) - value as ByteArray - } - TlvValueType.EllipticCurve -> { - typeCheck(tag) - (value as EllipticCurve).curve.toByteArray() - } - TlvValueType.DateTime -> { - typeCheck(tag) - val calendar = Calendar.getInstance().apply { time = (value as Date) } - val year = calendar.get(Calendar.YEAR) - val month = calendar.get(Calendar.MONTH) + 1 - val day = calendar.get(Calendar.DAY_OF_MONTH) - return year.toByteArray(2) + month.toByte() + day.toByte() - } - TlvValueType.ProductMask -> { - typeCheck(tag) - byteArrayOf( - (value as ProductMask).rawValue.toByte() - ) - } - TlvValueType.SettingsMask -> { - typeCheck(tag) - val rawValue = (value as SettingsMask).rawValue - rawValue.toByteArray(determineByteArraySize(rawValue)) - } - TlvValueType.CardStatus -> { - typeCheck(tag) - (value as CardStatus).code.toByteArray() - } - TlvValueType.SigningMethod -> { - typeCheck(tag) - byteArrayOf((value as SigningMethodMask).rawValue.toByte()) - } - TlvValueType.IssuerDataMode -> { - typeCheck(tag) - byteArrayOf((value as IssuerDataMode).code) - } - } - } - - private fun determineByteArraySize(value: Int): Int { - val mask = 0xFFFF0000.toInt() - return if ((value and mask) != 0) 4 else 2 - } - - private inline fun typeCheck(tag: TlvTag) { - if (T::class != ExpectedT::class) { - Log.e(this::class.simpleName!!, - "Mapping error. Type for tag: $tag must be ${tag.valueType()}. It is ${T::class}") - throw TangemSdkError.EncodingFailedTypeMismatch() - } - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/common/tlv/TlvTag.kt b/tangem-core/src/main/java/com/tangem/common/tlv/TlvTag.kt deleted file mode 100644 index 944ee4cc24..0000000000 --- a/tangem-core/src/main/java/com/tangem/common/tlv/TlvTag.kt +++ /dev/null @@ -1,150 +0,0 @@ -package com.tangem.common.tlv - -/** - * Contains all possible value types that value for [TlvTag] can contain. - */ -enum class TlvValueType { - HexString, - HexStringToHash, - Utf8String, - Uint16, - Uint32, - BoolValue, - ByteArray, - EllipticCurve, - DateTime, - ProductMask, - SettingsMask, - CardStatus, - SigningMethod, - IssuerDataMode -} - -/** - * Contains all TLV tags, with their code and descriptive name. - */ -enum class TlvTag(val code: Int) { - Unknown(0x00), - CardId(0x01), - Status(0x02), - CardPublicKey(0x03), - CardSignature(0x04), - CurveId(0x05), - HashAlgID(0x06), - SigningMethod(0x07), - MaxSignatures(0x08), - PauseBeforePin2(0x09), - SettingsMask(0x0A), - CardData(0x0C), - NdefData(0x0D), - CreateWalletAtPersonalize(0x0E), - Health(0x0F), - - Pin(0x10), - Pin2(0x11), - NewPin(0x12), - NewPin2(0x13), - NewPinHash(0x14), - NewPin2Hash(0x15), - Challenge(0x16), - Salt(0x17), - ValidationCounter(0x18), - Cvc(0x19), - - SessionKeyA(0x1A), - SessionKeyB(0x1B), - Pause(0x1C), - NewPin3(0x1E), - CrExKey(0x1F), - - Uid(0x0B), - - ManufactureId(0x20), - ManufacturerSignature(0x86), - - IssuerDataPublicKey(0x30), - IssuerTransactionPublicKey(0x31), - IssuerData(0x32), - IssuerDataSignature(0x33), - IssuerTransactionSignature(0x34), - IssuerDataCounter(0x35), - AcquirerPublicKey(0x37), - - Size(0x25), - Mode(0x23), - Offset(0x24), - - IsActivated(0x3A), - ActivationSeed(0x3B), - ResetPin(0x36), - - CodePageAddress(0x40), - CodePageCount(0x41), - CodeHash(0x42), - - TransactionOutHash(0x50), - TransactionOutHashSize(0x51), - TransactionOutRaw(0x52), - - WalletPublicKey(0x60), - Signature(0x61), - RemainingSignatures(0x62), - SignedHashes(0x63), - - Firmware(0x80), - Batch(0x81), - ManufactureDateTime(0x82), - IssuerId(0x83), - BlockchainId(0x84), - ManufacturerPublicKey(0x85), - CardIdManufacturerSignature(0x86), - - ProductMask(0x8A), - PaymentFlowVersion(0x54), - - TokenSymbol(0xA0), - TokenContractAddress(0xA1), - TokenDecimal(0xA2), - Denomination(0xC0), - ValidatedBalance(0xC1), - LastSignDate(0xC2), - DenominationText(0xC3), - - TerminalIsLinked(0x58), - TerminalPublicKey(0x5C), - TerminalTransactionSignature(0x57), - - UserData(0x2A), - UserProtectedData(0x2B), - UserCounter(0x2C), - UserProtectedCounter(0x2D); - - /** - * @return [TlvValueType] associated with a [TlvTag] - */ - fun valueType(): TlvValueType { - return when (this) { - CardId, Batch, CrExKey -> TlvValueType.HexString - ManufactureId, Firmware, IssuerId, BlockchainId, TokenSymbol, TokenContractAddress -> - TlvValueType.Utf8String - CurveId -> TlvValueType.EllipticCurve - PauseBeforePin2, RemainingSignatures, SignedHashes, Health, TokenDecimal, - Offset, Size -> TlvValueType.Uint16 - MaxSignatures, UserCounter, UserProtectedCounter, IssuerDataCounter -> TlvValueType.Uint32 - IsActivated, TerminalIsLinked, CreateWalletAtPersonalize -> TlvValueType.BoolValue - ManufactureDateTime -> TlvValueType.DateTime - ProductMask -> TlvValueType.ProductMask - SettingsMask -> TlvValueType.SettingsMask - Status -> TlvValueType.CardStatus - SigningMethod -> TlvValueType.SigningMethod - Mode -> TlvValueType.IssuerDataMode - else -> TlvValueType.ByteArray - } - } - - companion object { - private val values = values() - fun byCode(code: Int): TlvTag = values.find { it.code == code } ?: Unknown - } -} - diff --git a/tangem-core/src/main/java/com/tangem/crypto/CryptoUtils.kt b/tangem-core/src/main/java/com/tangem/crypto/CryptoUtils.kt deleted file mode 100644 index af6f5e2b76..0000000000 --- a/tangem-core/src/main/java/com/tangem/crypto/CryptoUtils.kt +++ /dev/null @@ -1,121 +0,0 @@ -package com.tangem.crypto - -import com.tangem.commands.EllipticCurve -import net.i2p.crypto.eddsa.EdDSASecurityProvider -import org.spongycastle.jce.provider.BouncyCastleProvider -import java.security.PublicKey -import java.security.SecureRandom -import java.security.Security -import javax.crypto.Cipher -import javax.crypto.spec.IvParameterSpec -import javax.crypto.spec.SecretKeySpec - - -object CryptoUtils { - - fun initCrypto() { - Security.insertProviderAt(BouncyCastleProvider(), 1) - Security.addProvider(EdDSASecurityProvider()) - } - - /** - * Generates ByteArray of random bytes. - * It is used, among other things, to generate helper private keys - * (not the one for the blockchains, that one is generated on the card and does not leave the card). - * - * @param length length of the ByteArray that is to be generated. - */ - fun generateRandomBytes(length: Int): ByteArray { - val bytes = ByteArray(length) - SecureRandom().nextBytes(bytes) - return bytes - } - - /** - * Helper function to verify that the data was signed with a private key that corresponds - * to the provided public key. - * - * @param publicKey Corresponding to the private key that was used to sing a message - * @param message The data that was signed - * @param signature Signed data - * @param curve Elliptic curve used - * - * @return Result of a verification - */ - fun verify(publicKey: ByteArray, message: ByteArray, signature: ByteArray, - curve: EllipticCurve = EllipticCurve.Secp256k1): Boolean { - return when (curve) { - EllipticCurve.Secp256k1 -> Secp256k1.verify(publicKey, message, signature) - EllipticCurve.Ed25519 -> Ed25519.verify(publicKey, message, signature) - } - } - - /** - * Helper function that generates public key from a private key. - * - * @param privateKeyArray A private key from which a public key is generated - * @param curve Elliptic curve used - * - * @return Public key [ByteArray] - */ - fun generatePublicKey( - privateKeyArray: ByteArray, - curve: EllipticCurve = EllipticCurve.Secp256k1 - ): ByteArray { - return when (curve) { - EllipticCurve.Secp256k1 -> Secp256k1.generatePublicKey(privateKeyArray) - EllipticCurve.Ed25519 -> Ed25519.generatePublicKey(privateKeyArray) - } - } - - fun loadPublicKey( - publicKey: ByteArray, - curve: EllipticCurve = EllipticCurve.Secp256k1 - ): PublicKey { - return when (curve) { - EllipticCurve.Secp256k1 -> Secp256k1.loadPublicKey(publicKey) - EllipticCurve.Ed25519 -> Ed25519.loadPublicKey(publicKey) - } - } -} - -/** - * Extension function to sign a ByteArray with an elliptic curve cryptography. - * - * @param privateKeyArray Key to sign data - * @param curve Elliptic curve that is used to sign data - * - * @return Signed data - */ -fun ByteArray.sign(privateKeyArray: ByteArray, curve: EllipticCurve = EllipticCurve.Secp256k1): ByteArray { - return when (curve) { - EllipticCurve.Secp256k1 -> Secp256k1.sign(this, privateKeyArray) - EllipticCurve.Ed25519 -> Ed25519.sign(this, privateKeyArray) - } -} - -fun ByteArray.encrypt(key: ByteArray, usePkcs7: Boolean = true): ByteArray { - val spec = if (usePkcs7) ENCRYPTION_SPEC_PKCS7 else ENCRYPTION_SPEC_NO_PADDING - val secretKeySpec = SecretKeySpec(key, spec) - val cipher = Cipher.getInstance(spec, "SC") - cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, IvParameterSpec(ByteArray(16))) - return cipher.doFinal(this) -} - -fun ByteArray.decrypt(key: ByteArray, usePkcs7: Boolean = true): ByteArray { - val spec = if (usePkcs7) ENCRYPTION_SPEC_PKCS7 else ENCRYPTION_SPEC_NO_PADDING - val secretKeySpec = SecretKeySpec(key, spec) - val cipher = Cipher.getInstance(spec) - cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, IvParameterSpec(ByteArray(16))) - return cipher.doFinal(this.copyOfRange(0, this.size)) -} - -fun ByteArray.pbkdf2Hash(salt: ByteArray, iterations: Int): ByteArray { - return Pbkdf2().deriveKey(this, salt, iterations) -} - -private const val ENCRYPTION_SPEC_PKCS7 = "AES/CBC/PKCS7PADDING" -private const val ENCRYPTION_SPEC_NO_PADDING = "AES/CBC/NOPADDING" - - - diff --git a/tangem-core/src/main/java/com/tangem/crypto/Ed25519.kt b/tangem-core/src/main/java/com/tangem/crypto/Ed25519.kt deleted file mode 100644 index 5c07b5a4e9..0000000000 --- a/tangem-core/src/main/java/com/tangem/crypto/Ed25519.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.tangem.crypto - -import com.tangem.common.extensions.calculateSha512 -import net.i2p.crypto.eddsa.EdDSAEngine -import net.i2p.crypto.eddsa.EdDSAPrivateKey -import net.i2p.crypto.eddsa.EdDSAPublicKey -import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable -import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec -import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec -import java.security.MessageDigest -import java.security.PublicKey - -object Ed25519 { - - internal fun verify(publicKey: ByteArray, message: ByteArray, signature: ByteArray): Boolean { - val messageSha512 = message.calculateSha512() - val loadedPublicKey = loadPublicKey(publicKey) - val spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519) - val signatureInstance = EdDSAEngine(MessageDigest.getInstance(spec.hashAlgorithm)) - signatureInstance.initVerify(loadedPublicKey) - - signatureInstance.update(messageSha512) - - return signatureInstance.verify(signature) - } - - internal fun loadPublicKey(publicKeyArray: ByteArray): PublicKey { - val spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519) - val pubKey = EdDSAPublicKeySpec(publicKeyArray, spec) - return EdDSAPublicKey(pubKey) - } - - internal fun sign(data: ByteArray, privateKeyArray: ByteArray): ByteArray { - - val dataSha512 = data.calculateSha512() - val spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519) - val signatureInstance = EdDSAEngine(MessageDigest.getInstance(spec.hashAlgorithm)) - - val privateKeySpec = EdDSAPrivateKeySpec(privateKeyArray, spec) - val privateKey = EdDSAPrivateKey(privateKeySpec) - - signatureInstance.initSign(privateKey) - signatureInstance.update(dataSha512) - - return signatureInstance.sign() - } - - internal fun generatePublicKey(privateKeyArray: ByteArray): ByteArray { - val spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519) - val privateKeySpec = EdDSAPrivateKeySpec(privateKeyArray, spec) - val publicKeySpec = EdDSAPublicKeySpec(privateKeySpec.a, spec) - val publicKey = EdDSAPublicKey(publicKeySpec) - return publicKey.abyte - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/crypto/EncryptionHelper.kt b/tangem-core/src/main/java/com/tangem/crypto/EncryptionHelper.kt deleted file mode 100644 index 1360914241..0000000000 --- a/tangem-core/src/main/java/com/tangem/crypto/EncryptionHelper.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.tangem.crypto - -import com.tangem.EncryptionMode -import org.spongycastle.jce.interfaces.ECPublicKey -import java.security.KeyPair -import java.security.KeyPairGenerator -import java.security.SecureRandom -import java.security.spec.ECGenParameterSpec -import javax.crypto.KeyAgreement - -interface EncryptionHelper { - val keyA: ByteArray - - fun generateSecret(keyB: ByteArray): ByteArray - - companion object { - fun create(encryptionMode: EncryptionMode): EncryptionHelper? { - return when (encryptionMode) { - EncryptionMode.NONE -> null - EncryptionMode.FAST -> FastEncryptionHelper() - EncryptionMode.STRONG -> StrongEncryptionHelper() - } - } - } -} - -class StrongEncryptionHelper : EncryptionHelper { - private val keyPair = generateKeyPair() - private val keyAgreement = generateKeyAgreement(keyPair) - override val keyA = provideKeyA(keyPair) - - override fun generateSecret(keyB: ByteArray): ByteArray { - keyAgreement.doPhase(CryptoUtils.loadPublicKey(keyB), true) - return keyAgreement.generateSecret() - } - - private fun generateKeyPair(): KeyPair { - val kpgen = KeyPairGenerator.getInstance("ECDH", "SC") - kpgen.initialize(ECGenParameterSpec("secp256k1"), SecureRandom()) - return kpgen.generateKeyPair() - } - - private fun generateKeyAgreement(keyPair: KeyPair): KeyAgreement { - val keyAgreement = KeyAgreement.getInstance("ECDH", "SC") - keyAgreement.init(keyPair.private) - return keyAgreement - } - - private fun provideKeyA(keyPair: KeyPair): ByteArray { - val eckey = keyPair.public as ECPublicKey - return eckey.q.getEncoded(false) - } -} - -class FastEncryptionHelper : EncryptionHelper { - override val keyA = CryptoUtils.generateRandomBytes(16) - - override fun generateSecret(keyB: ByteArray): ByteArray { - return keyA + keyB - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/crypto/Pbkdf2.kt b/tangem-core/src/main/java/com/tangem/crypto/Pbkdf2.kt deleted file mode 100644 index 4c532b3692..0000000000 --- a/tangem-core/src/main/java/com/tangem/crypto/Pbkdf2.kt +++ /dev/null @@ -1,88 +0,0 @@ -package com.tangem.crypto - -import org.spongycastle.crypto.CipherParameters -import org.spongycastle.crypto.digests.SHA256Digest -import org.spongycastle.crypto.macs.HMac -import org.spongycastle.crypto.params.KeyParameter -import java.security.InvalidKeyException -import java.util.* -import kotlin.experimental.xor -import kotlin.math.min -import kotlin.math.pow - -class Pbkdf2 { - private val F: HMac = HMac(SHA256Digest()) - - fun deriveKey(password: ByteArray, salt: ByteArray, iterations: Int): ByteArray { - - val macSize = F.macSize - // Check key length - if (macSize > (2.0.pow(32.0) - 1) * macSize) throw InvalidKeyException("Derived key to long") - - val derivedKey = ByteArray(macSize) - - val J = 0 - val K: Int = macSize - val U: Int = macSize shl 1 - val B = K + U - val workingArray = ByteArray(K + U + 4) - - // Initialize F - val macParams: CipherParameters = KeyParameter(password) - F.init(macParams) - - // Perform iterations - var kpos = 0 - var blk = 1 - while (kpos < macSize) { - storeInt32BE(blk, workingArray, B) - F.update(salt, 0, salt.size) - F.reset() - F.update(salt, 0, salt.size) - F.update(workingArray, B, 4) - F.doFinal(workingArray, U) - System.arraycopy(workingArray, U, workingArray, J, K) - var i = 1 - var j = J - var k = K - while (i < iterations) { - F.init(macParams) - F.update(workingArray, j, K) - F.doFinal(workingArray, k) - var u = U - var v = k - while (u < B) { - workingArray[u] = workingArray[u] xor workingArray[v] - u++ - v++ - } - val swp = k - k = j - j = swp - i++ - } - val tocpy = min(macSize - kpos, K) - System.arraycopy(workingArray, U, derivedKey, kpos, tocpy) - kpos += K - blk++ - } - Arrays.fill(workingArray, 0.toByte()) - return derivedKey - } - - /** - * Convert a 32-bit integer value into a big-endian byte array - * - * @param value The integer value to convert - * @param bytes The byte array to store the converted value - * @param offSet The offset in the output byte array - */ - private fun storeInt32BE(value: Int, bytes: ByteArray, offSet: Int) { - bytes[offSet + 3] = value.toByte() - bytes[offSet + 2] = (value ushr 8).toByte() - bytes[offSet + 1] = (value ushr 16).toByte() - bytes[offSet] = (value ushr 24).toByte() - } - - -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/crypto/Secp256k1.kt b/tangem-core/src/main/java/com/tangem/crypto/Secp256k1.kt deleted file mode 100644 index 97eba2a81c..0000000000 --- a/tangem-core/src/main/java/com/tangem/crypto/Secp256k1.kt +++ /dev/null @@ -1,118 +0,0 @@ -package com.tangem.crypto - -import com.tangem.common.extensions.toHexString -import org.spongycastle.asn1.ASN1EncodableVector -import org.spongycastle.asn1.ASN1Integer -import org.spongycastle.asn1.DERSequence -import org.spongycastle.jce.ECNamedCurveTable -import org.spongycastle.jce.spec.ECPrivateKeySpec -import org.spongycastle.jce.spec.ECPublicKeySpec -import java.math.BigInteger -import java.security.KeyFactory -import java.security.PublicKey -import java.security.Signature - -object Secp256k1 { - - internal fun verify(publicKey: ByteArray, message: ByteArray, signature: ByteArray): Boolean { - val signatureInstance = Signature.getInstance("SHA256withECDSA") - val loadedPublicKey = loadPublicKey(publicKey) - signatureInstance.initVerify(loadedPublicKey) - signatureInstance.update(message) - - val v = ASN1EncodableVector() - val size = signature.size / 2 - v.add(calculateR(signature, size)) - v.add(calculateS(signature, size)) - val sigDer = DERSequence(v).encoded - - return signatureInstance.verify(sigDer) - } - - internal fun loadPublicKey(publicKeyArray: ByteArray): PublicKey { - - val spec = ECNamedCurveTable.getParameterSpec("secp256k1") - val factory = KeyFactory.getInstance("EC", "SC") - - val p1 = spec.curve.decodePoint(publicKeyArray) - val keySpec = ECPublicKeySpec(p1, spec) - - return factory.generatePublic(keySpec) - } - - private fun calculateR(signature: ByteArray, size: Int): ASN1Integer = - ASN1Integer(BigInteger(1, signature.copyOfRange(0, size))) - - private fun calculateS(signature: ByteArray, size: Int): ASN1Integer = - ASN1Integer(BigInteger(1, signature.copyOfRange(size, size * 2))) - - - internal fun sign(data: ByteArray, privateKeyArray: ByteArray): ByteArray { - - val spec = ECNamedCurveTable.getParameterSpec("secp256k1") - val factory = KeyFactory.getInstance("EC", "SC") - - val keySpecP = ECPrivateKeySpec(BigInteger(1, privateKeyArray), spec) - - val signature = Signature.getInstance("SHA256withECDSA") - - val privateKey = factory.generatePrivate(keySpecP) - signature.initSign(privateKey) - signature.update(data) - - val enc = signature.sign() - checkSignatureForErrors(enc) - - val res = toByte64(enc) - - if (!verify(generatePublicKey(privateKeyArray), data, res)) { - throw Exception("Signature self verify failed - ,enc:" + enc.toHexString() + ",res:" + res.toHexString()) - } - - return res - } - - private fun checkSignatureForErrors(enc: ByteArray) { - if (enc[0].toInt() != 0x30) throw Exception("bad encoding 1") - if (enc[1].toInt() and 0x80 != 0) throw Exception("unsupported length encoding 1") - if (enc[2].toInt() != 0x02) throw Exception("bad encoding 2") - if (enc[3].toInt() and 0x80 != 0) throw Exception("unsupported length encoding 2") - var rLength = enc[3].toInt() - if (enc[4 + rLength].toInt() != 0x02) throw Exception("bad encoding 3") - if (enc[5 + rLength].toInt() and 0x80 != 0) - throw Exception("unsupported length encoding 3") - } - - private fun toByte64(enc: ByteArray): ByteArray { - - var rLength = enc[3].toInt() - var sLength = enc[5 + rLength].toInt() - - val sPos = 6 + rLength - val res = ByteArray(64) - if (rLength <= 32) { - System.arraycopy(enc, 4, res, 32 - rLength, rLength) - rLength = 32 - } else if (rLength == 33 && enc[4].toInt() == 0) { - rLength-- - System.arraycopy(enc, 5, res, 0, rLength) - } else { - throw Exception("unsupported r-length - r-length:" + rLength.toString() + ",s-length:" + sLength.toString() + ",enc:" + enc.toHexString()) - } - if (sLength <= 32) { - System.arraycopy(enc, sPos, res, rLength + 32 - sLength, sLength) - sLength = 32 - } else if (sLength == 33 && enc[sPos].toInt() == 0) { - System.arraycopy(enc, sPos + 1, res, rLength, sLength - 1) - } else { - throw Exception("unsupported s-length - r-length:" + rLength.toString() + ",s-length:" + sLength.toString() + ",enc:" + enc.toHexString()) - } - - return res - } - - internal fun generatePublicKey(privateKeyArray: ByteArray): ByteArray { - val spec = ECNamedCurveTable.getParameterSpec("secp256k1") - return spec.g.multiply(BigInteger(1, privateKeyArray)).getEncoded(false) - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/tasks/ChangePinTask.kt b/tangem-core/src/main/java/com/tangem/tasks/ChangePinTask.kt deleted file mode 100644 index fed66d31b3..0000000000 --- a/tangem-core/src/main/java/com/tangem/tasks/ChangePinTask.kt +++ /dev/null @@ -1,101 +0,0 @@ -package com.tangem.tasks - -import com.tangem.CardSession -import com.tangem.CardSessionRunnable -import com.tangem.SessionEnvironment -import com.tangem.SessionViewDelegate -import com.tangem.commands.SetPinCommand -import com.tangem.commands.SetPinResponse -import com.tangem.common.CompletionResult -import com.tangem.common.PinCode -import com.tangem.common.extensions.calculateSha256 -import kotlinx.coroutines.launch -import kotlinx.coroutines.suspendCancellableCoroutine -import kotlin.coroutines.resume - -enum class PinType { - Pin1, - Pin2, - Pin3, - ; -} - -class ChangePinTask( - private val pinType: PinType, - private val pin: ByteArray? = null -) : CardSessionRunnable { - override val requiresPin2 = false - - override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { - session.scope.launch { - val pin = this@ChangePinTask.pin - ?: requestNewPin(pinType, session.viewDelegate).calculateSha256() - runSetPin(pin, session, callback) - } - } - - private suspend fun runSetPin(pin: ByteArray, session: CardSession, callback: (result: CompletionResult) -> Unit) { - val pin1: ByteArray - val pin2: ByteArray - val pin3: ByteArray? - - if (session.environment.pin1 == null) { - session.environment.pin1 = PinCode(requestPin(PinType.Pin1, session.viewDelegate)) - } - if (session.environment.pin2 == null) { - session.environment.pin2 = PinCode(requestPin(PinType.Pin2, session.viewDelegate)) - } - - when (pinType) { - PinType.Pin1 -> { - pin1 = pin - pin2 = session.environment.pin2!!.value - pin3 = null - } - PinType.Pin2 -> { - pin1 = session.environment.pin1!!.value - pin2 = pin - pin3 = null - } - PinType.Pin3 -> { - pin1 = session.environment.pin1!!.value - pin2 = session.environment.pin2!!.value - pin3 = pin - } - } - val command = SetPinCommand(pin1, pin2, pin3) - command.run(session) { result -> - when (result) { - is CompletionResult.Success -> { - savePin(pin, session.environment) - callback(result) - } - is CompletionResult.Failure -> callback(result) - } - } - } - - private suspend fun requestPin(pinType: PinType, viewDelegate: SessionViewDelegate): String = - suspendCancellableCoroutine { continuation -> - viewDelegate.onPinRequested(pinType) { result -> - if (continuation.isActive) continuation.resume(result) - } - } - - private suspend fun requestNewPin(pinType: PinType, viewDelegate: SessionViewDelegate): String = - suspendCancellableCoroutine { continuation -> - viewDelegate.onPinChangeRequested(pinType) { result -> - if (continuation.isActive) continuation.resume(result) - } - } - - private fun savePin(pin: ByteArray, environment: SessionEnvironment) { - when (pinType) { - PinType.Pin1 -> environment.pin1 = PinCode(pin, false) - PinType.Pin2 -> environment.pin2 = PinCode(pin, false) - PinType.Pin3 -> {} - } - } - - -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/tasks/CreateWalletTask.kt b/tangem-core/src/main/java/com/tangem/tasks/CreateWalletTask.kt deleted file mode 100644 index a4bb23d8b5..0000000000 --- a/tangem-core/src/main/java/com/tangem/tasks/CreateWalletTask.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.tangem.tasks - -import com.tangem.CardSession -import com.tangem.CardSessionRunnable -import com.tangem.TangemSdkError -import com.tangem.commands.CardStatus -import com.tangem.commands.CheckWalletCommand -import com.tangem.commands.CreateWalletCommand -import com.tangem.commands.CreateWalletResponse -import com.tangem.common.CompletionResult - -class CreateWalletTask : CardSessionRunnable { - - override val requiresPin2 = false - - override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { - val curve = session.environment.card?.curve - if (curve == null) { - callback(CompletionResult.Failure(TangemSdkError.CardError())) - return - } - - val command = CreateWalletCommand() - command.run(session) { createWalletResult -> - when (createWalletResult) { - is CompletionResult.Failure -> callback(createWalletResult) - is CompletionResult.Success -> { - if (createWalletResult.data.status != CardStatus.Loaded) { - callback(CompletionResult.Failure(TangemSdkError.UnknownError())) - } else { - val checkWalletCommand = CheckWalletCommand( - curve, createWalletResult.data.walletPublicKey - ) - checkWalletCommand.run(session) { result -> - when (result) { - is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error)) - is CompletionResult.Success -> callback(createWalletResult) - } - } - } - } - } - } - } -} \ No newline at end of file diff --git a/tangem-core/src/main/java/com/tangem/tasks/ScanTask.kt b/tangem-core/src/main/java/com/tangem/tasks/ScanTask.kt deleted file mode 100644 index d9702f5a6d..0000000000 --- a/tangem-core/src/main/java/com/tangem/tasks/ScanTask.kt +++ /dev/null @@ -1,87 +0,0 @@ -package com.tangem.tasks - -import com.tangem.CardSession -import com.tangem.CardSessionRunnable -import com.tangem.TagType -import com.tangem.TangemSdkError -import com.tangem.commands.* -import com.tangem.commands.common.CardDeserializer -import com.tangem.common.CompletionResult - -/** - * Task that allows to read Tangem card and verify its private key. - * - * It performs two commands, [ReadCommand] and [CheckWalletCommand], subsequently. - */ -internal class ScanTask : CardSessionRunnable { - - override val requiresPin2 = false - - override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { - if (session.connectedTag == TagType.Slix) { - readSlixTag(session, callback) - return - } - val card = session.environment.card - if (card == null) { - callback(CompletionResult.Failure(TangemSdkError.CardError())) - return - } - if (session.environment.pin1 != null && session.environment.pin2 != null) { - val checkPinCommand = SetPinCommand(session.environment.pin1!!.value, session.environment.pin2!!.value) - checkPinCommand.run(session) { result -> - when (result) { - is CompletionResult.Failure -> { - session.environment.pin2 = null - } - } - runCheckWalletIfNeeded(card, session, callback) - } - } else { - runCheckWalletIfNeeded(card, session, callback) - } - - } - - private fun runCheckWalletIfNeeded( - card: Card, session: CardSession, - callback: (result: CompletionResult) -> Unit - ) { - if (card.cardData?.productMask?.contains(Product.Tag) != false) { - callback(CompletionResult.Success(card)) - - } else if (card.status != CardStatus.Loaded) { - callback(CompletionResult.Success(card)) - - } else if (card.curve == null || card.walletPublicKey == null) { - callback(CompletionResult.Failure(TangemSdkError.CardError())) - - } else { - val checkWalletCommand = CheckWalletCommand(card.curve, card.walletPublicKey) - checkWalletCommand.run(session) { result -> - when (result) { - is CompletionResult.Success -> callback(CompletionResult.Success(card)) - is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error)) - } - } - } - } - - private fun readSlixTag(session: CardSession, callback: (result: CompletionResult) -> Unit) { - session.readSlixTag { result -> - when (result) { - is CompletionResult.Success -> { - try { - val card = CardDeserializer.deserialize(result.data) - callback(CompletionResult.Success(card)) - } catch (error: TangemSdkError) { - callback(CompletionResult.Failure(error)) - } - } - is CompletionResult.Failure -> { - callback(CompletionResult.Failure(result.error)) - } - } - } - } -} \ No newline at end of file diff --git a/tangem-core/src/main/sqldelight/com/tangem/CardValuesEntity.sq b/tangem-core/src/main/sqldelight/com/tangem/CardValuesEntity.sq deleted file mode 100644 index 7ac4521e98..0000000000 --- a/tangem-core/src/main/sqldelight/com/tangem/CardValuesEntity.sq +++ /dev/null @@ -1,34 +0,0 @@ -import com.tangem.VerificationState; - -CREATE TABLE cardValues ( - cardId TEXT NOT NULL UNIQUE PRIMARY KEY, - isPin1Default INTEGER AS Boolean DEFAULT 1, - isPin2Default INTEGER AS Boolean DEFAULT 1, - cardVerification TEXT AS VerificationState, - cardValidation TEXT AS VerificationState, - codeVerification TEXT AS VerificationState -); - -insertOrReplace: -INSERT OR REPLACE INTO cardValues( - cardId, - isPin1Default, - isPin2Default, - cardVerification, - cardValidation, - codeVerification -) -VALUES (?, ?, ?, ?, ?, ?); - -selectByCardId: -SELECT * -FROM cardValues -WHERE cardId = ?; - -deleteAll: -DELETE FROM cardValues; - -deleteByCardId: -DELETE -FROM cardValues -WHERE cardId = ?; \ No newline at end of file diff --git a/tangem-core/src/test/java/com/tangem/common/apdu/CommandApduTest.kt b/tangem-core/src/test/java/com/tangem/common/apdu/CommandApduTest.kt deleted file mode 100644 index 67ac0cf109..0000000000 --- a/tangem-core/src/test/java/com/tangem/common/apdu/CommandApduTest.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.tangem.common.apdu - -import com.google.common.truth.Truth.assertThat -import com.tangem.SessionEnvironment -import com.tangem.common.tlv.TlvBuilder -import com.tangem.common.tlv.TlvTag -import org.junit.Test - - -class CommandApduTest { - - private val sessionEnvironment = SessionEnvironment() - - @Test - fun `simple READ command to bytes`() { - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.Pin, sessionEnvironment.pin1?.value) - val commandApdu = CommandApdu( - Instruction.Read, - tlvBuilder.serialize() - ) - val expected = byteArrayOf(0, -14, 0, 0, 0, 0, 34, 16, 32, -111, -76, -47, 66, -126, 63, 125, - 32, -59, -16, -115, -10, -111, 34, -34, 67, -13, 95, 5, 122, -104, -115, -106, 25, -10, - -45, 19, -124, -123, -55, -94, 3) - - assertThat(commandApdu.apduData) - .isEqualTo(expected) - assertThat(listOf(1, 2)).containsExactlyElementsIn(listOf(1, 2)) - } - - @Test - fun `READ with terminal key to bytes`() { - val terminalPublicKey = byteArrayOf(4, 80, -122, 58, -42, 74, -121, -82, -118, 47, -24, 60, - 26, -15, -88, 64, 60, -75, 63, 83, -28, -122, -40, 81, 29, -83, -118, 4, -120, 126, - 91, 35, 82, 44, -44, 112, 36, 52, 83, -94, -103, -6, -98, 119, 35, 119, 22, 16, 58, - -68, 17, -95, -33, 56, -123, 94, -42, -14, -18, 24, 126, -100, 88, 43, -90) - val tlvBuilder = TlvBuilder() - tlvBuilder.append(TlvTag.Pin, sessionEnvironment.pin1?.value) - tlvBuilder.append(TlvTag.TerminalPublicKey, terminalPublicKey) - val commandApdu = CommandApdu( - Instruction.Read, - tlvBuilder.serialize() - ) - - val expected = byteArrayOf(0, -14, 0, 0, 0, 0, 101, 16, 32, -111, -76, -47, 66, -126, 63, - 125, 32, -59, -16, -115, -10, -111, 34, -34, 67, -13, 95, 5, 122, -104, -115, -106, 25, - -10, -45, 19, -124, -123, -55, -94, 3, 92, 65, 4, 80, -122, 58, -42, 74, -121, -82, -118, - 47, -24, 60, 26, -15, -88, 64, 60, -75, 63, 83, -28, -122, -40, 81, 29, -83, -118, 4, -120, - 126, 91, 35, 82, 44, -44, 112, 36, 52, 83, -94, -103, -6, -98, 119, 35, 119, 22, 16, 58, - -68, 17, -95, -33, 56, -123, 94, -42, -14, -18, 24, 126, -100, 88, 43, -90) - - assertThat(commandApdu.apduData) - .isEqualTo(expected) - } -} \ No newline at end of file diff --git a/tangem-core/src/test/java/com/tangem/common/apdu/ResponseApduTest.kt b/tangem-core/src/test/java/com/tangem/common/apdu/ResponseApduTest.kt deleted file mode 100644 index 0b6f7fc8b9..0000000000 --- a/tangem-core/src/test/java/com/tangem/common/apdu/ResponseApduTest.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.tangem.common.apdu - -import com.google.common.truth.Truth.assertThat -import com.tangem.common.tlv.TlvTag -import org.junit.Test - -class ResponseApduTest { - - @Test - fun `get StatusWord returns Unknown`() { - val corruptData = byteArrayOf(0, 0, 0, 0) - val responseApdu = ResponseApdu(corruptData) - assertThat(responseApdu.statusWord) - .isEqualTo(StatusWord.Unknown) - } - - @Test - fun `get StatusWord returns ProcessCompleted`() { - val data = byteArrayOf(0, 0, 0, 0, -112, 0) - val responseApdu = ResponseApdu(data) - assertThat(responseApdu.statusWord) - .isEqualTo(StatusWord.ProcessCompleted) - } - - @Test - fun `corrupt response, getTlvData returns null`() { - val corruptData = byteArrayOf(0, 0, 0) - val responseApdu = ResponseApdu(corruptData) - assertThat(responseApdu.getTlvData()) - .isNull() - } - - @Test - fun `response, getTlvData returns cardId`() { - val data = byteArrayOf(1, 8, -53, 34, 0, 0, 0, 2, 115, 116, 32, 11, 83, 77, 65, 82, 84, 32, 67, 65, 83, 72, 0, 2, 1, 2, -128, 6, 50, 46, 49, 49, 114, 0, 3, 65, 4, -49, 11, -50, -66, -121, -25, -2, 65, 65, -13, 14, 49, 27, -82, -33, -85, -113, 65, 20, 8, -39, -75, 57, 45, 65, -31, 35, 44, 38, 40, 63, -44, 113, -45, -75, -95, -118, 118, 29, 65, 117, -24, -53, 82, -72, 91, -20, -96, -77, -103, -14, -63, 52, -127, -123, -27, -16, -128, -67, -3, -104, -26, -22, 65, 10, 4, 0, 0, 126, 33, 12, 90, -127, 2, 0, 41, -126, 4, 7, -29, 5, 2, -125, 7, 84, 65, 78, 71, 69, 77, 0, -124, 3, 69, 84, 72, -122, 64, 111, -103, 48, -114, -40, 18, -103, 26, -102, -12, -38, -78, -90, -9, -98, 88, -47, -100, -24, 24, -105, -70, -72, 6, 94, -96, -77, 11, -123, -28, -118, 37, 63, 107, -55, -11, 23, -12, 13, -23, -121, -63, 36, -59, 70, 116, 91, -125, -34, -69, 23, -112, 6, 17, 4, -49, 68, -56, 29, -45, 81, 10, 97, 83, 48, 65, 4, -127, -106, -86, 75, 65, 10, -60, 74, 59, -100, -50, 24, -25, -66, 34, 106, -22, 7, 10, -52, -125, -87, -49, 103, 84, 15, -84, 73, -81, 37, 18, -97, 106, 83, -118, 40, -83, 99, 65, 53, -114, 60, 79, -103, 99, 6, 79, 126, 54, 83, 114, -90, 81, -45, 116, -27, -62, 60, -35, 55, -3, 9, -101, -14, 5, 10, 115, 101, 99, 112, 50, 53, 54, 107, 49, 0, 8, 4, 0, 15, 66, 64, 7, 1, 0, 9, 2, 11, -72, 96, 65, 4, -42, -5, -41, -84, -23, 88, 2, 86, -63, -118, -123, -10, -66, -82, -107, -68, -93, 111, 47, 93, -20, -86, 74, 28, 21, 81, 93, -21, -124, -57, -102, 55, 17, 84, -66, -68, -22, -128, 126, -99, -65, -54, -42, 59, -25, -21, -124, 5, 59, -16, -72, 73, 48, 16, -27, 103, -112, -73, 2, 96, -51, 41, -42, 116, 98, 4, 0, 15, 66, 52, 99, 4, 0, 0, 0, 13, 15, 1, 0, -112, 0) - val responseApdu = ResponseApdu(data) - assertThat(responseApdu.getTlvData()) - .isNotNull() - assertThat(responseApdu.getTlvData()) - .isNotEmpty() - assertThat(responseApdu.getTlvData()?.filter { it.tag == TlvTag.Unknown }) - .isEmpty() - } -} \ No newline at end of file diff --git a/tangem-core/src/test/java/com/tangem/common/extensions/ByteArrayExtensionsTest.kt b/tangem-core/src/test/java/com/tangem/common/extensions/ByteArrayExtensionsTest.kt deleted file mode 100644 index 42cdecc708..0000000000 --- a/tangem-core/src/test/java/com/tangem/common/extensions/ByteArrayExtensionsTest.kt +++ /dev/null @@ -1,105 +0,0 @@ -package com.tangem.common.extensions - -import com.google.common.truth.Truth.assertThat -import org.junit.Test -import java.util.* - - -class ByteArrayExtensionsTest { - - @Test - fun `card Id to Hex String`() { - val hex = "CB22000000027374" - val bytes = byteArrayOf(-53, 34, 0, 0, 0, 2, 115, 116) - assertThat(bytes.toHexString()) - .matches(hex) - } - - @Test - fun `batch Id to Hex String`() { - val hex = "0029" - val bytes = byteArrayOf(0, 41) - assertThat(bytes.toHexString()) - .matches(hex) - } - - @Test - fun `curve name to Utf8`() { - val bytes = byteArrayOf(115, 101, 99, 112, 50, 53, 54, 107, 49, 0) - val expected = "secp256k1" - val converted = bytes.toUtf8() - assertThat(converted) - .matches(expected) - } - - @Test - fun `empty byteArray to Utf8 returns empty String`() { - val bytes = byteArrayOf() - val expected = "" - assertThat(bytes.toUtf8()) - .matches(expected) - } - - @Test - fun `blockchain name to Utf8`() { - val bytes = byteArrayOf(69, 84, 72) - val expected = "ETH" - val converted = bytes.toUtf8() - assertThat(converted) - .matches(expected) - } - - @Test - fun `bytes to int`() { - val bytes = byteArrayOf(0, 2, 106, 3) - val expected = 158211 - assertThat(bytes.toInt()) - .isEqualTo(expected) - - val bytes1 = byteArrayOf(0, 0, 0, 13) - val expected1 = 13 - assertThat(bytes1.toInt()) - .isEqualTo(expected1) - } - - @Test - fun `zero to int`() { - val bytes = byteArrayOf(0) - val expected = 0 - assertThat(bytes.toInt()) - .isEqualTo(expected) - } - - @Test - fun toDate() { - val bytes1 = byteArrayOf(7, -30, 7, 27) - val expected1 = Calendar.getInstance().apply { this.set(2018, 6, 27, 0, 0, 0) }.time - val converted1 = bytes1.toDate() - assertThat(converted1.toString()) - .isEqualTo(expected1.toString()) - - val bytes2 = byteArrayOf(7, -30, 7, 27, 30) - val expected2 = Calendar.getInstance().apply { this.set(2018, 6, 27, 0, 0, 0) }.time - val converted2 = bytes2.toDate() - assertThat(converted2.toString()) - .isEqualTo(expected2.toString()) - - val bytes3 = byteArrayOf(7, -30, 7) - val expected3 = Calendar.getInstance().apply { this.set(2018, 6, 0, 0, 0, 0) }.time - val converted3 = bytes3.toDate() - assertThat(converted3.toString()) - .isEqualTo(expected3.toString()) - } - - @Test - fun `calculate sha512`() { - val bytes = ByteArray(64) { 5 } - val expected = byteArrayOf( - -123, 96, 121, 57, -117, -23, -108, 57, 25, -119, -22, 97, 11, -91, - 74, -19, -88, 21, -108, -116, -100, 111, 6, -78, 114, -115, 70, -121, 29, 102, 104, 65, - -21, -68, -111, 121, -51, 109, -94, -24, -40, 108, -25, 70, -26, 61, 38, 12, -127, -34, - -77, -81, 81, -32, -89, -112, -31, -33, 91, 114, 89, 127, -123, -58) - assertThat(bytes.calculateSha512()) - .isEqualTo(expected) - } -} \ No newline at end of file diff --git a/tangem-core/src/test/java/com/tangem/common/extensions/IntExtensionsTest.kt b/tangem-core/src/test/java/com/tangem/common/extensions/IntExtensionsTest.kt deleted file mode 100644 index 710f817e28..0000000000 --- a/tangem-core/src/test/java/com/tangem/common/extensions/IntExtensionsTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.tangem.common.extensions - -import com.google.common.truth.Truth.assertThat -import org.junit.jupiter.api.Test - - -class IntExtensionsTest { - - @Test - fun `small int toByteArray`() { - val int = 13 - val expected = byteArrayOf(0, 0, 0, 13) - assertThat(int.toByteArray()) - .isEqualTo(expected) - } - - @Test - fun `int toByteArray`() { - val int = 999 - val expected = byteArrayOf(0, 0, 3, -25) - assertThat(int.toByteArray()) - .isEqualTo(expected) - } -} \ No newline at end of file diff --git a/tangem-core/src/test/java/com/tangem/common/extensions/StringExtensionsTest.kt b/tangem-core/src/test/java/com/tangem/common/extensions/StringExtensionsTest.kt deleted file mode 100644 index ba5b3add73..0000000000 --- a/tangem-core/src/test/java/com/tangem/common/extensions/StringExtensionsTest.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.tangem.common.extensions - -import com.google.common.truth.Truth.assertThat -import org.junit.Test - -class StringExtensionsTest { - - @Test - fun `calculate SHA 256 for default PIN 1`() { - val pin = "000000" - val expected = byteArrayOf(-111, -76, -47, 66, -126, 63, 125, 32, -59, -16, -115, -10, -111, - 34, -34, 67, -13, 95, 5, 122, -104, -115, -106, 25, -10, -45, 19, -124, -123, -55, -94, 3) - assertThat(pin.calculateSha256()) - .isEqualTo(expected) - } - - @Test - fun `calculate SHA 256 for default PIN 2`() { - val pin = "000" - val expected = byteArrayOf(42, -55, -90, 116, 106, -54, 84, 58, -8, -33, -13, -104, -108, -49, - -24, 23, 58, -5, -94, 30, -80, 28, 111, -82, 51, -43, 41, 71, 34, 40, 85, -17) - assertThat(pin.calculateSha256()) - .isEqualTo(expected) - } - - @Test - fun `calculate SHA 256 for a sample PIN 1`() { - val pin = "999999" - val expected = byteArrayOf(-109, 115, 119, -16, 86, 22, 15, -60, -79, 94, 11, 119, 12, 103, - 19, 106, 95, 3, -63, 82, 5, -76, -45, -65, -111, -126, 104, -2, -6, 44, 109, 10) - assertThat(pin.calculateSha256()) - .isEqualTo(expected) - } - - @Test - fun `calculate SHA 256 for a sample PIN 2`() { - val pin = "999" - val expected = byteArrayOf(-125, -49, -117, 96, -99, -26, 0, 54, -88, 39, 123, -48, -23, 97, - 53, 117, 27, -68, 7, -21, 35, 66, 86, -44, -74, 91, -119, 51, 96, 101, 27, -14) - assertThat(pin.calculateSha256()) - .isEqualTo(expected) - } - - @Test - fun `card ID hex to bytes`() { - val cardId = "cb22000000027374" - val expected = byteArrayOf(-53, 34, 0, 0, 0, 2, 115, 116) - assertThat(cardId.hexToBytes()) - .isEqualTo(expected) - } - - -} \ No newline at end of file diff --git a/tangem-core/src/test/java/com/tangem/common/tlv/TlvDecoderTest.kt b/tangem-core/src/test/java/com/tangem/common/tlv/TlvDecoderTest.kt deleted file mode 100644 index d0cc8a62e7..0000000000 --- a/tangem-core/src/test/java/com/tangem/common/tlv/TlvDecoderTest.kt +++ /dev/null @@ -1,192 +0,0 @@ -package com.tangem.common.tlv - -import com.google.common.truth.Truth.assertThat -import com.tangem.TangemSdkError -import com.tangem.commands.* -import com.tangem.common.extensions.hexToBytes -import org.junit.Test -import org.junit.jupiter.api.assertThrows -import java.util.* - -class TlvDecoderTest { - - private val rawData = byteArrayOf(1, 8, -53, 34, 0, 0, 0, 2, 115, 116, 32, 11, 83, 77, 65, 82, 84, 32, 67, 65, 83, 72, 0, 2, 1, 2, -128, 6, 50, 46, 49, 49, 114, 0, 3, 65, 4, -49, 11, -50, -66, -121, -25, -2, 65, 65, -13, 14, 49, 27, -82, -33, -85, -113, 65, 20, 8, -39, -75, 57, 45, 65, -31, 35, 44, 38, 40, 63, -44, 113, -45, -75, -95, -118, 118, 29, 65, 117, -24, -53, 82, -72, 91, -20, -96, -77, -103, -14, -63, 52, -127, -123, -27, -16, -128, -67, -3, -104, -26, -22, 65, 10, 4, 0, 0, 126, 33, 12, 90, -127, 2, 0, 41, -126, 4, 7, -29, 5, 2, -125, 7, 84, 65, 78, 71, 69, 77, 0, -124, 3, 69, 84, 72, -122, 64, 111, -103, 48, -114, -40, 18, -103, 26, -102, -12, -38, -78, -90, -9, -98, 88, -47, -100, -24, 24, -105, -70, -72, 6, 94, -96, -77, 11, -123, -28, -118, 37, 63, 107, -55, -11, 23, -12, 13, -23, -121, -63, 36, -59, 70, 116, 91, -125, -34, -69, 23, -112, 6, 17, 4, -49, 68, -56, 29, -45, 81, 10, 97, 83, 48, 65, 4, -127, -106, -86, 75, 65, 10, -60, 74, 59, -100, -50, 24, -25, -66, 34, 106, -22, 7, 10, -52, -125, -87, -49, 103, 84, 15, -84, 73, -81, 37, 18, -97, 106, 83, -118, 40, -83, 99, 65, 53, -114, 60, 79, -103, 99, 6, 79, 126, 54, 83, 114, -90, 81, -45, 116, -27, -62, 60, -35, 55, -3, 9, -101, -14, 5, 10, 115, 101, 99, 112, 50, 53, 54, 107, 49, 0, 8, 4, 0, 15, 66, 64, 7, 1, 0, 9, 2, 11, -72, 96, 65, 4, -42, -5, -41, -84, -23, 88, 2, 86, -63, -118, -123, -10, -66, -82, -107, -68, -93, 111, 47, 93, -20, -86, 74, 28, 21, 81, 93, -21, -124, -57, -102, 55, 17, 84, -66, -68, -22, -128, 126, -99, -65, -54, -42, 59, -25, -21, -124, 5, 59, -16, -72, 73, 48, 16, -27, 103, -112, -73, 2, 96, -51, 41, -42, 116, 98, 4, 0, 15, 66, 52, 99, 4, 0, 0, 0, 13, 15, 1, 0) - - private val tlvData = Tlv.deserialize(rawData) - - private val tlvMapper = TlvDecoder(tlvData!!) - - private val cardDataRaw: ByteArray = tlvMapper.decode(TlvTag.CardData) - private val cardDataMapper = TlvDecoder(Tlv.deserialize(cardDataRaw)!!) - - @Test - fun `map optional when value is present`() { - val settingsMask: SettingsMask? = tlvMapper.decodeOptional(TlvTag.SettingsMask) - assertThat(settingsMask) - .isNotNull() - } - - @Test - fun `map optional when no tag returns null`() { - val tokenSymbol: String? = tlvMapper.decodeOptional(TlvTag.TokenSymbol) - assertThat(tokenSymbol) - .isNull() - } - - @Test - fun `map when value is null throws MissingTagException`() { - assertThrows { - tlvMapper.decode(TlvTag.TokenSymbol) - } - } - - @Test - fun `map optional to wrong type throws WrongTypeException`() { - assertThrows { - tlvMapper.decodeOptional(TlvTag.CardData) - } - } - - @Test - fun `map to wrong type throws WrongTypeException`() { - assertThrows { - tlvMapper.decode(TlvTag.CardData) - } - } - - @Test - fun `map boolean missing flag returns false`() { - val terminalIsLinked: Boolean = tlvMapper.decode(TlvTag.TerminalIsLinked) - assertThat(terminalIsLinked) - .isFalse() - } - - @Test - fun `map SettingsMask returns correct value`() { - val settingsMask: SettingsMask = tlvMapper.decode(TlvTag.SettingsMask) - assertThat(settingsMask) - .isNotNull() - assertThat(settingsMask.rawValue) - .isEqualTo(32289) - assertThat(settingsMask.contains(Settings.SkipSecurityDelayIfValidatedByLinkedTerminal)) - .isFalse() - assertThat(settingsMask.contains(Settings.IsReusable)) - .isTrue() - assertThat(settingsMask.contains(Settings.AllowSwapPIN2)) - .isTrue() - assertThat(settingsMask.contains(Settings.UseDynamicNdef)) - .isTrue() - assertThat(settingsMask.contains(Settings.ProhibitPurgeWallet)) - .isFalse() - } - - @Test - fun `map SigningMethods single value returns correct value`() { - val signingMethods: SigningMethodMask = tlvMapper.decode(TlvTag.SigningMethod) - assertThat(signingMethods.contains(SigningMethod.SignHash)) - .isTrue() - } - - @Test - fun `map SigningMethods set of methods returns correct value`() { - val localMapper = TlvDecoder(Tlv.deserialize("070195".hexToBytes())!!) - - val signingMethods: SigningMethodMask = localMapper.decode(TlvTag.SigningMethod) - assertThat(signingMethods.contains(SigningMethod.SignHash)) - .isTrue() - assertThat(signingMethods.contains(SigningMethod.SignHashValidateByIssuer)) - .isTrue() - assertThat(signingMethods.contains(SigningMethod.SignHashValidateByIssuerWriteIssuerData)) - .isTrue() - assertThat(signingMethods.contains(SigningMethod.SignRaw)) - .isFalse() - assertThat(signingMethods.contains(SigningMethod.SignRawValidateByIssuer)) - .isFalse() - assertThat(signingMethods.contains(SigningMethod.SignRawValidateByIssuerWriteIssuerData)) - .isFalse() - assertThat(signingMethods.contains(SigningMethod.SignPos)) - .isFalse() - } - - @Test - fun `map CardStatus returns correct value`() { - val cardStatus: CardStatus = tlvMapper.decode(TlvTag.Status) - assertThat(cardStatus) - .isEqualTo(CardStatus.Loaded) - } - - @Test - fun `map ProductMask with raw value 5 returns correct value`() { - val localMapper = TlvDecoder(listOf(Tlv(TlvTag.ProductMask, byteArrayOf(5)))) - val productMask: ProductMask = localMapper.decode(TlvTag.ProductMask) - assertThat(productMask.contains(Product.Note) && productMask.contains(Product.IdCard)) - .isTrue() - } - - @Test - fun `map ProductMask with raw value 1 returns correct value`() { - val localMapper = TlvDecoder(listOf(Tlv(TlvTag.ProductMask, byteArrayOf(1)))) - val productMask: ProductMask = localMapper.decode(TlvTag.ProductMask) - assertThat(productMask.contains(Product.Note)) - .isTrue() - } - - @Test - fun `map Enum with unknown code throws ConversionException error`() { - val localMapper = TlvDecoder(listOf(Tlv(TlvTag.CurveId, "test".toByteArray()))) - assertThrows { - localMapper.decode(TlvTag.CurveId) - } - } - - @Test - fun `map DateTime returns correct value`() { - val date: Date = cardDataMapper.decode(TlvTag.ManufactureDateTime) - val expected = Calendar.getInstance().apply { this.set(2019, 4, 2, 0, 0, 0) }.time - assertThat(date.toString()) - .isEqualTo(expected.toString()) - } - - @Test - fun `map EllipticCurve returns correct value`() { - val ellipticCurve: EllipticCurve = tlvMapper.decode(TlvTag.CurveId) - assertThat(ellipticCurve) - .isEqualTo(EllipticCurve.Secp256k1) - } - - @Test - fun `map ByteArray returns correctly`() { - val cardPublicKey: ByteArray = tlvMapper.decode(TlvTag.CardPublicKey) - assertThat(cardPublicKey) - .isInstanceOf(ByteArray::class.java) - } - - @Test - fun `map Int returns correct value`() { - val signedHashes: Int = tlvMapper.decode(TlvTag.SignedHashes) - assertThat(signedHashes) - .isEqualTo(13) - } - - @Test - fun `map Int with wrong value throws ConversionException`() { - val localMapper = TlvDecoder(listOf(Tlv(TlvTag.SignedHashes, byteArrayOf(1, 2, 3, 4, 5)))) - assertThrows { - localMapper.decode(TlvTag.SignedHashes) - } - } - - @Test - fun `map UTF8 returns correct value`() { - val blockchainId: String = cardDataMapper.decode(TlvTag.BlockchainId) - assertThat(blockchainId) - .isEqualTo("ETH") - } - - @Test - fun `map Hex returns correct value`() { - val cardId: String = tlvMapper.decode(TlvTag.CardId) - assertThat(cardId) - .isEqualTo("CB22000000027374") - } -} \ No newline at end of file diff --git a/tangem-core/src/test/java/com/tangem/common/tlv/TlvTest.kt b/tangem-core/src/test/java/com/tangem/common/tlv/TlvTest.kt deleted file mode 100644 index c2d1e0e09d..0000000000 --- a/tangem-core/src/test/java/com/tangem/common/tlv/TlvTest.kt +++ /dev/null @@ -1,111 +0,0 @@ -package com.tangem.common.tlv - -import com.google.common.truth.Truth.assertThat -import com.tangem.common.extensions.calculateSha256 -import com.tangem.common.extensions.hexToBytes -import org.junit.Test - - -class TlvTest { - - @Test - fun `TLVs to bytes, only PIN`() { - val tlvs = listOf( - Tlv(TlvTag.Pin, "000000".calculateSha256()) - ) - val expected = byteArrayOf(16, 32, -111, -76, -47, 66, -126, 63, 125, 32, -59, -16, -115, - -10, -111, 34, -34, 67, -13, 95, 5, 122, -104, -115, -106, 25, -10, -45, 19, -124, - -123, -55, -94, 3) - - assertThat(tlvs.serialize()) - .isEqualTo(expected) - } - - @Test - fun `TLVs to bytes, check wallet`() { - val tlvs = listOf( - Tlv(TlvTag.Pin, "000000".calculateSha256()), - Tlv(TlvTag.CardId, "cb22000000027374".hexToBytes()), - Tlv(TlvTag.Challenge, byteArrayOf(-82, -78, -31, 34, 66, -19, -86, -1, 26, 8, 100, -126, -74, 20, -28, 83)) - ) - - val expected = byteArrayOf(16, 32, -111, -76, -47, 66, -126, 63, 125, 32, -59, -16, -115, -10, - -111, 34, -34, 67, -13, 95, 5, 122, -104, -115, -106, 25, -10, -45, 19, -124, -123, - -55, -94, 3, 1, 8, -53, 34, 0, 0, 0, 2, 115, 116, 22, 16, -82, -78, -31, 34, 66, -19, - -86, -1, 26, 8, 100, -126, -74, 20, -28, 83) - - assertThat(tlvs.serialize()) - .isEqualTo(expected) - } - - @Test - fun `Bytes to Tlvs, only PIN`() { - val bytes = byteArrayOf(16, 32, -111, -76, -47, 66, -126, 63, 125, 32, -59, -16, -115, - -10, -111, 34, -34, 67, -13, 95, 5, 122, -104, -115, -106, 25, -10, -45, 19, -124, - -123, -55, -94, 3) - - val tlvs = Tlv.deserialize(bytes) - - assertThat(tlvs) - .isNotNull() - assertThat(tlvs) - .isNotEmpty() - - val pin = tlvs!!.find { it.tag == TlvTag.Pin }?.value - val pinExpected = "000000".calculateSha256() - - assertThat(pin) - .isEqualTo(pinExpected) - } - - @Test - fun `Bytes to TLVs, check wallet TLVs`() { - val bytes = byteArrayOf(16, 32, -111, -76, -47, 66, -126, 63, 125, 32, -59, -16, -115, -10, - -111, 34, -34, 67, -13, 95, 5, 122, -104, -115, -106, 25, -10, -45, 19, -124, -123, - -55, -94, 3, 1, 8, -53, 34, 0, 0, 0, 2, 115, 116, 22, 16, -82, -78, -31, 34, 66, -19, - -86, -1, 26, 8, 100, -126, -74, 20, -28, 83) - - val tlvs = Tlv.deserialize(bytes) - - assertThat(tlvs) - .isNotNull() - assertThat(tlvs) - .isNotEmpty() - - val pin = tlvs!!.find { it.tag == TlvTag.Pin }?.value - val pinExpected = "000000".calculateSha256() - assertThat(pin) - .isEqualTo(pinExpected) - - val cardId = tlvs.find { it.tag == TlvTag.CardId }?.value - val cardIdExpected = "cb22000000027374".hexToBytes() - assertThat(cardId) - .isEqualTo(cardIdExpected) - - val challenge = tlvs.find { it.tag == TlvTag.Challenge }?.value - val challengeExpected = byteArrayOf(-82, -78, -31, 34, 66, -19, -86, -1, 26, 8, 100, -126, -74, 20, -28, 83) - assertThat(challenge) - .isEqualTo(challengeExpected) - } - - @Test - fun `Bytes to TLVs, wrong values`() { - val bytes = byteArrayOf(0) - val tlvs = Tlv.deserialize(bytes) - assertThat(tlvs) - .isNull() - - val bytes1 = byteArrayOf(0, 0, 0, 0, 0, 0, 0) - val tlvs1 = Tlv.deserialize(bytes1) - assertThat(tlvs1) - .isNull() - } - - @Test - fun `parse Slix tag response`() { - val response = "03ff010f91010b550474616e67656d2e636f6d140f11616e64726f69642e636f6d3a706b67636f6d2e74616e67656d2e77616c6c65745411c974616e67656d2e636f6d3a77616c6c657490000c618102ffff8a0102820407e40109830b54414e47454d2053444b008403584c4d86400e71c1f060387029688254320b90abeae471bcafbbe8ea3880903bdb8d1cc389d032b982e1ffd7ef49e66f1780123b763dd2f3a9a9494eb0fad4ae8cf306672c60207c967a51077c14fc49d867f23b8d0eaf60cad479a56587e894571b7fb33690176140345fbe53f5be0ec871e91c317cde2bd0396d47e4b945c138c153b0271f636a73cf531df1bc54ac4fcdbce42f81b40d58e0265d34e28121a4c50fdfe329a97f6000fe000000000000000000000000000000000000000000000000000000000000000000000000000000" - val tlvs = Tlv.deserialize(response.hexToBytes(), true) - assertThat(tlvs) - .isNotEmpty() - } -} \ No newline at end of file diff --git a/tangem-core/src/test/java/com/tangem/crypto/CryptoUtilsTest.kt b/tangem-core/src/test/java/com/tangem/crypto/CryptoUtilsTest.kt deleted file mode 100644 index afdb6da581..0000000000 --- a/tangem-core/src/test/java/com/tangem/crypto/CryptoUtilsTest.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.tangem.crypto - -import com.google.common.truth.Truth.assertThat -import com.tangem.commands.EllipticCurve -import com.tangem.crypto.CryptoUtils.generatePublicKey -import com.tangem.crypto.CryptoUtils.generateRandomBytes -import com.tangem.crypto.CryptoUtils.verify -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test - - -class CryptoUtilsTest { - - @BeforeEach - internal fun setUp() { - CryptoUtils.initCrypto() - } - - @Test - fun generateRandomBytesTest() { - val privateKey: ByteArray = generateRandomBytes(32) - assertThat(privateKey) - .hasLength(32) - assertThat(privateKey.sum()) - .isNotEqualTo(0) - } - - @Test - internal fun verifyEd25519Test() { - val verified = verifySignature_withSampleData(EllipticCurve.Ed25519) - assertThat(verified) - .isTrue() - } - - @Test - internal fun verifySecp256k1Test() { - val verified = verifySignature_withSampleData(EllipticCurve.Secp256k1) - assertThat(verified) - .isTrue() - } - - private fun verifySignature_withSampleData(curve: EllipticCurve): Boolean { - val privateKey = ByteArray(32) { 1 } - val publicKey = generatePublicKey(privateKey, curve) - val message = ByteArray(64) { 5 } - val signature = message.sign(privateKey, curve) - return verify(publicKey, message, signature, curve) - } - -} \ No newline at end of file diff --git a/tangem-devkit/.gitignore b/tangem-devkit/.gitignore deleted file mode 100644 index 796b96d1c4..0000000000 --- a/tangem-devkit/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/tangem-devkit/build.gradle b/tangem-devkit/build.gradle deleted file mode 100644 index fd35b8f7ed..0000000000 --- a/tangem-devkit/build.gradle +++ /dev/null @@ -1,56 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' -android { - compileSdkVersion 29 - buildToolsVersion "29.0.3" - - defaultConfig { - applicationId "com.tangem.devkit" - minSdkVersion 21 - targetSdkVersion 29 - versionCode 4 - versionName "1.2" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } -} - -dependencies { - implementation project(':tangem-core') - implementation project(':tangem-sdk') - implementation fileTree(dir: 'libs', include: ['*.jar']) - - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test:runner:1.2.0' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' - - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$versions.kotlin" - - implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'androidx.core:core-ktx:1.2.0' - implementation "androidx.constraintlayout:constraintlayout:2.0.0-beta4" - implementation "androidx.navigation:navigation-fragment-ktx:2.2.1" - implementation "androidx.navigation:navigation-ui-ktx:2.2.1" - implementation "androidx.recyclerview:recyclerview:1.2.0-alpha02" - implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" - implementation "com.google.android.material:material:1.2.0-alpha05" - implementation "androidx.viewpager2:viewpager2:1.0.0" - - implementation 'com.google.code.gson:gson:2.8.6' - implementation 'com.github.gbIxaHue:eu4d:0.3.8' -} diff --git a/tangem-devkit/proguard-rules.pro b/tangem-devkit/proguard-rules.pro deleted file mode 100644 index f1b424510d..0000000000 --- a/tangem-devkit/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/tangem-devkit/src/main/AndroidManifest.xml b/tangem-devkit/src/main/AndroidManifest.xml deleted file mode 100644 index b74aaf74df..0000000000 --- a/tangem-devkit/src/main/AndroidManifest.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tangem-devkit/src/main/ic_launcher-playstore.png b/tangem-devkit/src/main/ic_launcher-playstore.png deleted file mode 100644 index 6e5af9f8f6193aa9ddfbfa06c4a00ab3c06f605e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14393 zcmdUWXIN9+*5FA11w=r)(iH*eh*E@*s1)g<^s1l&q99E=i3Owxh)5GDQUs+-?;uTS zk=_Ipq(dT*5K2hq1by#&zj^N5x%18ZnfRQ?u+QGB?X_3iD`8jlHILGtpa%fpsMZy= zYXATRzd`}pL*RcnpTS)KPz1EpE*klauT36KoHR}$yH#RqdhTOBSPlxwC20u@qO@5J zt$A2tw_2hTqL#?bU9?lT;xxN>MzFsG5Yvv8($+x;AUbt>$w5dt zhwYx80y%Gi>PcY_$g#OTs8&2h!pIpy}1DxfBEds6jfI!3P080QmQRcYwkc zE%*q44+?w^`224S{9lmp&uskPknqn`BLGxMK4(lJBLXN6+TWGciV-}vG;S0)AAyF^ z0<hwa{lFA##d}uZ9aO6NdB6#ZM;tm=xJu7g8N*N!xte_Y?jExIu41dh+B+rfp`i z&-M?^{or)iWIOHaIPQ=ZI56ek zcxG+CT_NJL@SDJ?kG6i;y{R;P#hY3e_Et*=^b{sv@ga%pGo}23po(0-3S>C{!qj5* z9a49CJQv?$wTi~q&pX}dts5MHE8}rnImcmvZKlV@j0O_kp%at*9D21k<)_cC)vORb zM{kmor0RZUl-aduLlMB&wR~y4<*u+!a=fLBUK;V|8K=rgg6@9leAaQpB|@(@ERY?N z%f_|7KZ*mXd$|N_`I5FWl~j7<7*}GcxnIkatM+tmD4B{W|H_j-ZnJJW8G{!5j7S6GG_AN?oOm2EfIUV^H#9(<`i_a}rt;cHfxx*u zhpcDF%_|nQF4nSiW=sGC!MO!6po!LL!v);h(JC8eyEq4Zy$P4f%Y9;tXN*bIh%A4( z0uj{(s+Kgu6sc^52h!WNsOQYA$p6`T>BV3RzJ<_)umu3Ww9;P-dCwe!BeABNL0FAejd#)7GFMyh+VDqlz7BD@d2TMob)YZPGXKYzJjWClEw zfY$!BAH(F#rC%*%@t)+$+lD)uOij& zu~G%@LSn=x#ER{$yJ*OwbO^O{&8G5)r(lNE}%vW+CfO-C#a174G*ZmCD5#a ze={EgHI;JWLzzK)c`v*i4q=XQqi@NF(i0go03NDIZD58NdgO=fcMhW@D z_g^yn&shC;6djhMAVLcF2T}uZodgH}SKNcI|Jz&OI6|*|Jmx7gO8tm9s266y z9k%0Aw4mNkrV)LkaiFH>maYr3027NFWXL<|()phMOmz9D9Ky?Z#^Tu5L&t&Xz zc2p8b<&9<9rm*ugH$pxc9&8=zj3{ujA5UTIdhrJThkyqog~xePsbrjO40i~yVSy8k?OvVZMM8sP^|O4Nnr#FLsl zZbmhmy|w*c(<#=%T8T+O=*C>U?_~d;Q25q zK~l56nAt!+^iP=Keyww${P=$UIX_tPr+w_E7Vvd0PLF5HkhJT$Kh@ma+&67*{Y$@$ zIW3>Qgq2-4bAfH-R8HK2YQUS#?~CQDgZ_!wXByGwdqC3Lqc#r8SoI(nYv9qfDXO^< zOOi*B)KFTCNukG%th03Gf^r;e4%?;R5lO z;)TnPi?2hOqmMVbezY-A4qJI$dUxmp?q{q4M^WwT?b_|i4YY#)YPs`BRLpyQ=4kfl zCQhK%ayCg+UV zo7g72G2yqjuX32(St&RLEZRXrFA-il7iy6SNOD5&g_ZoM`PEXi{xoT;av+$~CQ+&$ z*N@xBBH{bE9JrqMH#becU(JUH?4w~OM3R1`Rp$4`^>%J$lAo}jBfL33lod=U$E$X!Zdu>?_+Lz znrXh7A<mfzB4bqlbz6j%U+5r3b;M)frbs#PT>o2CDDQTqK+AleZD_B+#cHG zW5GMehZ1c{kTCCGACZe8?oX2gcXN=tIk*p|^+9-=8r~<7G~guql1z zwO75$*t$y(FDR`Zqah_U66e5U_HAZA51$%OCY2Wj-mlr7iO`&G{0MyWTPawYCht#2 zj7+VL-zy(7Sz3UTeJ5Iu&yA$e2#Apf^py*$hRba(7fkcRM+OFBr@&pxNp`7mqIw(F zsf-z_dX@~EhZ9@iSx*=*i0=Osfgc|bXQ>wybXn)(9;i1LcPrxaUoC0#7^VVatY8?> z>>9M0jGI?zRNC+3-#6SXnBFbWLc5Z;Tse0J;QIp^0)aiwHnIAOKc0HFv7557d;5l_ zPlii!mi3(_6_Iy~a^~=5FCAbj=4~Ss%B62D9)@pU?1^7F?(imtgu#*ut5kdVRn>CDqmEFlGx5oyJCH7+3GPY;= z$yEg-S1}vtFcUx8?k-!>#>~!;zjP=1OanODm}Zy=N)!rdar(3{HJ8994%1uY7ycykUaH@^oxo7 z%SrNC+Jy0Cm>B?pM(mPIG@E9QZ^(z;5o z%4T=Q9QiQv*WsgWr$~}Pt^r5Kb{3GN1-s7z79{+wQ(`z18Ua6zOI#nG`F;d$9UC*F z5wN*TixQ;xNtyTc5W`Wm4AUFUk7?Qho;rR}zxk%4s@58qIp2P(j8L}#)3cmbl4bZ+ zj}3JFRJzbbRuF4mfMI>T#L*kmuJ!ogHmgS#u_w|PA)i@~&hq)<`ZOc%W_vYi%nx}Vyr32n_b@jj?lTtu6`yQOU z30EfsmAY*D)J;uI&0J`^)v2G~80{SR&8>qy&aQyIk?7rb`N3zwXIaUv4b?8eN@LI$ z&-5?7>4lSt=a3{~Unjg0!);9JTLV3l?x=GGLkuPM(msN4DH+M*YFB2sx<6{DXpp7~ zOYvKN-&TjRknGl{Mda8Th_hd&MdXL%2K82R!)tJrlMg5Qq*gaP@_Ri}H{al5q64yg z>Sx(e8^11kzHP*K6*>D!tI@2RBJrk6udeH#!KCF}2RmdZtDZjfQ1q`8C+^wEj)D z;KimU#BRGngP}^t@==EilE6A~##_H#Ml)#59LQ)hFJkAj9>WG={UbW-$G9F|xm4#} z^5I4uE3lc>B``0brp|*dHJm$!B!5h(&o`?vEt+}50Ld*RW?rh_=oBAlBz85j)pHaW zh4^;E#mHu_$3Ix<8v!5l)eO|XQALJ`jxWKS2U}!qAfI6>f`G5 zgH{qZtFJlbFo)Ai(J!0biBG823jtoGt=!rI)ZU(8zmiWV!q<5y1Tavw_Lr#$_2-|A zntQdz823v2-J2H$xje~qh`K1VGtBkuku}{Smw`_1Wi=XZ0>+luW;4vzt(=zj)f#v2 zlGH41and7%j5 zILOVS!*1{MZg`dag$?CC$M3vBnDm~;jUe|&^hAhr1SR35c6@YL?3xh?bX1F8pOk9Z2F09jR zQlk-I3I2%$eKF_cM&DVi=L~+KHO=0;Jh5yz_i+RgIlVV!%0Tr>L~B@^Bg>XJ!#R85 zh+vQu{Z69uu^AJRb$O6$owTf`U}gG>7n4Ce(CW`WA|pQ@)>&+m*SKpFPVfc!mG+Cx zFrL6{^n-^e)!~?qb%%#^8|;LK>IprTo+1TRwCtI)eqQaHwKL^Yz6&WeWIBMh>49B= zrweRIc`<94v}D+|?uJ?(SjgYNTC)zkg4}%G#-7oQl~}uCo7i6o&kbTP_I(%$+CgkgE5$CIET@)UwB7XHd!O4d@gWR2cKf$@svElR(KyJ5UkDdt1RIDD@cR zbFgi-Iw!mSy_ceykrThzBFV+awgyfo{~ARf5g!Y`F2iwQQ7-~A#<#s(2; z)tLs>#BPFq0`wHUe5hr)*;&~c=Jf5!0*S^5Xy8)+NCvqqSi&y;WJY`w0fTxq*`%|e ztGZK};PAO45xIJldDGz1JK^zcy#sI2-bZz{NI`&4gnrSiJ?;q3g2rEJl{D{45|*^C zDH|28N~RI8&CE@--Cs6U2y~r!-R2ZAO`KQIbf~P{^|QMoT=6y1#H;l5ZCM77-KCt7 zNn*}*=+*eP+&X)CKV7~8)l+YWUk(No8|ZFF#FNz?Y6*b}k^sQVhO*+Cmzn~DiQ>f8 z_yy>>*Eo*2LFK9SsG14%!|O~4o1@GvfS@WqOVqW7EpBtYgWuM3q4L6E0kn3sq^+g- z^#)M(Y_(h!8>C8cphQ9{ek;zOV+Q~17aorvVt-ZF4!4cYCC+|c$|YXryRZ{PNh_IA zj5y$DcECD5(LU-p49GEQHnCyhTB(}-9`C}55-993cSteL|5C`2x#1E~J>x$yF(qHa zQ#_lY*=D3AqgGuZd4~@>S^O$tuJw8 z@F*(O_zOWO%#Maqr`PdFHMIACO8ji%@?|JFjIZMma&KZ9v#SJD)9|zVSrII-20Iq& zOxh9yRu%WmyZj-oR^eSzwfUpD@5eCieJ#x53KmNw{vxn`g23#Az70v-JXTZ-qWj3z zo`^Iexw*dbzj%PlwxkMPz!8bf&Xfv(p-R?oA@Cy{6zEgbQqWvh-TuqhbtS(xh{i7+s!_2 zYIIXT9_^$FxVN!(VeBw1paEJ9iSx2b9+fSbim$m135^d}&F2!4l2>L?sv$R$@I{=k zL$QLux_=rN#${9D<*JSuRma=UK5ti#V&vm>+8bD6s~unmC89)XNa!coI~fY&;S~Ws z2KUstYd`530q){w<)4Qg4YT7>vUruEznaRqAfOgeJ5;i?F-2GMO0v*EML*NtX4Ab% zvFL3dGlI_nKKooQe8dV{w?j;ntrQR|eaIN%WD3mGM?cAOpPLQ`T8lq}S(&-6?mbUc zY6xi0j6hj3f0aU!3MJyJoZe z1^7D)B5KaC;hqjNzswFWIoqRupUbD8i#Zw^{u54`g@?DKjr(HOXb}yh0+%D!s-Kro zRE(mGMPW8s76j;Th5t+=Ae`B@9VA}Rrug&c?n+USQngDRR3<6R+Q6hguz%xNDjDH5*2*h29Ys zln-|1Yx=0D2;-2`-~dZlN4T@K>+NQ_(?Iozz!q)j&1kdZFPXycI*8wbf_4J>ivbM@ zeOxdca4fiICt{*d4yHDS=L{f}4VbZ3gzKIu1$M04e?|XtW zIph|Y`6=>LjQwKfkbMFjXk%%cG`>g9h85w;Swvd{dTIRDpWB17}$CT!` z;dF33enaY4#)C*Ne2IKe2K0r<%eF%oq-7kJ`z*CFl?o-cpUly{pd3q zF19&V>X2hvH^bhx{KBLntXG+;;m1)|QO4&VDy`2Q93B=(Xza9|&bUbhGLl|7KJffF zhGM{mkvtk~BZ3x@Df%id_bhp47g@(LRV!y^*BRl&Ul|=4eKH8#yVXWAsjd7ol$rgr zLC{9*%=X-!7QuD7%5UynRnseBw1_g|?7h%Ym~4epRKX+5F#-}^=d52;KUztO^cQ?M>g=#G1BP!qzUVhfauhGm6%@+% z+@~>f=Dw$i8opTn&54~a20GNboG=+7-f|-UQ&H3$|w~62X1E}4UWN(*Xa>PZ`Mie z9?!#-F{M|!Q+y~fvPw}M^+y}5X2UbPP@yduMex2VVk)8T+zU$K5M2zs8u^v>aNJ3K zB&goR$=7L|Qd+R9_s;CVm_R;<2?i&obM_n6yBXk@PzMPcL2;^du|Hb-ZIWZ#9*={h z?oY6gXwqa@B574s%p7NRQ!|@0jNnKKu1&(vjUN^);`uBBYnYRCJw7Ssa}owQa3AR{ zQ09W}#HR_h-rSMSnhD-2BYruPUZub*e~6vCCGIh$=93vayPU$v6*muRJa}VdlOk2S z`mqd5kIv;2?KdV3HF=G%w5y2~JY=Gxhdj@Go;d+GB~~96An~Bd&bE6NB{hO#l^O&s zB}4OeweEl$FZjU7`1^4VlvS~2vx@6fUC7EWkDL5*b?}Xt=yTt$I*8$bR*%S=D4*#Q zDXE+z=fsGKS2$;PDA`4X5?ds-fIiQ2zWCe+Y5I^*}io9Fxm^`{YMV0qH(zrT5~VnQWjtTAP{k!(6fkqJW^V9dl=c~M>YZfzRQpLN}^RUVX9&zyo6QXRkBWU-9w{6s6`~uM z_^|I$wZbNrr5=@xp9*;$z8M6k@V%;)n*gCd!q`m z5$^>6-}49~3|^k5(|)()mdqAosCGp_N>`l26zh+TE@^4uZao|#Cb%snN2j=2o-gAC3dYPT?CnHfAL) zul-2*{WE0${6_5HRy8P6i)j9qi?aF02%4p-s5jeVRncIDZoJR`Ov4?)Ttez^(-aQ8 zinc6}8ok@|J?im!lEJ-2mWf&oaS3VLyz&nJ>a!7@H^H)M+pXrs-TNkP6}9XSK-FE{ z1Zy}OW)GEPzuv9y-EK5&>WFWQ41v5hCRU3GiM8pwq$nprnTz1UPbdkwl*xs27VKAH zvKvZhUwuQRcAi%Oyqkf>SUl@NH2)HKCBEaX12^5yGbzv}O!>PSGPnDXi94Geo@4X( zEmznFV?;mCY)?DxE3ibbgT<3J@A)K$cb2a8<)g&;r7PX`v`KXB;(R+6nhAm38_`1m zSb(bPm3?10_N%j97+6=P)Td|aqi#Q4tDD;1QIFtY&x3YeKJwc{Xw2~J(j4JnV|P~q zGnof5+ob!h{+8?K?^t!bzbD((SX5M$7|d&5Ty5ECnBc|75n5ETu9I(%E+F5L9DE4g zg?c0@d%KL^NxmO`9B-ic5L9GJ5&m3(r^S1~o=bqwxpu9Bn^01_KE)4K^LbMa%YyZ| zqKm5E9n%80oP6GR;!T=M){WlCb2*%PYBsO;i~&N?#KAMUncts(%8qNb*T|mk)Lpyc ztBN27+|%|Tu6IPII*xQcx&Q_VQxd`~=<`T;QrHN72aOE6#JbiAlT!Hh;Igb{MjY$r zUE}aR{|8{9-t{H)#X?-GRp?@yDE9fNV`jPv{|&H^bEeQX(^rxri|aOku=t$EcaITd zw-s_hdD>jU%h|zh+=u%6lD@8r3V!gqh|!PuXV!KJjjZ~LZ*#deZ0LK$LO0Gfn>Owa zsWWxG69VR{g?$ae5?i^%b!OHtmEAomJ#+%}-hYT*PMKPSU4l-puvl-4q)$oPiF zMIP?))@rQb*LM2H4=uB+uYF^q{!S@wboc=q?+`i(QoOu}93OtP3*e8trF%ufl{7&2 zQCDq_HTII_(tg+iZ|u&vZ)2Y6+g7Yqwfk+i`wQJk*EhSL_@M=bnKAW*sW!35jlw6l z`@;9!!8R00x+WX{HDhAHj_d_Nz%Bi{Ro)#|-b~K>(}4uZc?EEn&Rbq}%k92JkI0KH zv4fhHg(KG^Y@e?P)wo}*eGg{F9Nr>g&+0TujLNGrcam;ro{sM`<|`#97d!$JPqn#$ zaNuWZ=prQXN^lavv}&zlBK#C;^UJdy#-p8ZRvjZs4L_>)nW%^jnsT2MPc0C_pK(|q zsA1?!UO_`gA6Tk6p+LEjq-4d8W;gXKfWe7xBJ^Jr`|fw}dP@x3+q$)}XR?+Ei=9t? z33z^(>9NK<<8i;zg2571)hfLu(9d14`uFxNiw>uQ-35wEvIIa^4VWRcUqyT~*s1y{ zp;9iC9$*`y*e3L8)cpcqrb>qZi}h~77Vs2MV`{oZhsZpYK8q~{xS#+8G5PpH2rz?4 z5|t6o{21{`hEMs9rDij`Gsb(|DF@fg6eN=Z#vN@xg6FD&Oqi7@7w*ZH^^%BBSEF159b8&*-ue(I*qzD!&Cbcic@Zxm#X z7v->q&E4&Ly?Sd!Ce+z?A3wr5Avv;J@5W*y)DV69$-2!?JT~P-xG14j1_Pyw%@LQ!RAI|=A=EUu){ zXSt!EVYq+HUy(m}b?P**IHL_$T`a#QbtAj{C)DW24sNOiKNa2lp-MA3Cjk4>6pE6P zQkm_>#fkH4i<{*0#438LfNfyt@Hp{^(l!3)D%&?ezyB;;?i+i0iilY54}b6N*9tYZ zrmtpHtcg_rr^m&<}eK`Y~V8&dOdt;VxYy=$O9o8RCFr=)&I+5q;rY=o%0Ce zJM|-+IZ9NPSyNMwz`n7{mrCk>dxx(@m!%vJEFHilmG*a=d-M}0x2|wXTBZ&k4FR$Y z>6%(;zV~VJ>xiUQox5L;uW*|0CJmZaW9sEJ`%Py9-CU!p;c41)==#!#BADB>N#SJK z5-jfQjfXWe;d%Yz=bZ<3o8O*ury7Z}d<}N}i0OhIdDJ)hUY3o0OUO!{5>+`I4n0Tz zC{_ES?B(`2Q8Nc47U+ZK;4Te6;F|0qJ>bGAAR1O7CTZ>G4tn0TYX<1<&Ol`=Upxo< z*y_w~bOZk>H&@2#FaL;d+<9{slytYyDZQCendTxkVN zwk1?t+?KJ^_ly8Pv0w!D3gm+IxW1HQ4jz}C@-Qha-nx$X{$sz--NXKXNj9s2%KJqK zEhN#fddkpO-LEr_{CV$ePrZ_GCd<{+V8d0K>Z!toZqKiU z?LHPdU$1?jxp4#Rv%xV&rNoMAI048X(gEtfNdFrtAw{xxc(0Z6x{zWM0|kzfC-8e01yE+g|5E|{FmZBn0LV3 z?*)G(_OaR0iz-z_o@9$8^GfRQ2(V12Xs;3QYbsn z1px9#VJMUSoRNnm`cDM@OK~5t_SZp&P+0%><_m;(Fzb(a{{y-X_(y56qT1LYiKaVE z=#v2TAIW~T*0`F2cXD(TEwEI0#Ssj2r&{hb5tulEQ-+G5@A%rr9^|C~y0sUmhHz?J zPF^ADV)k=0O>n1bN)m45Zv22PWkqK{dQ`10I4*Y$U<*cldI_d`~1x%d5-g>DJ;Ne6d+H*RPDGPu30O*8S?Zf+mK;?9hrp49w zxw{TW+1Sb54UaOoA81Uko}};DI$KbQGy>+MX;JPkfqVJTUo*$|oh;D#KhS=%kOvQC zsUK`>s=lWDFyR;qPoXn8Gz_->gO7(NpDoMaoqB}+70Y`&{dR{Q7?A`a17g#SRsAfY zVsa;CZbHo9XIG)nVp%$b!StILtV4Ec27Ws2(0sSfg6#uCi_(YICr%7ffqiLlG>%|h z=V}vJKDg|+PxilD!c$y?)PF5+ej3=4 z9h0-j=F}z45u##&wSwX|svDqu(`!HL0BN09ElOtIdUoch#@dw6I*S#c9%Y=Dv7di1 zaw8x`_S$=`SzZ1y1Ht+0-L}P=>VQVYwp^u05M72L;`- zjl*KLhr`1g&9+RdZTy`7CY8_sp0QxQTTzWI9q=v`Xnoq0$g}%2gTh9b)}6M6F9m-l5K?rfP@To3fPW}6*Xexo_nY3$=%CQQmL5)bv%2lQ3e zTg&jnmeKT0zic>^cK9S6#3qYM@79q@M(n2ME#HCtI54p9Uu!7`zVGCwm&x!s4h|6j z5<%4o@^t?0)wa=OoX2MX)~-w~8i+4(O9pALRdH{baw;3vc%8`mOuBn(-iUGO1`P6r z(QWW={llx|VQohJJ*@ZD3#-K~1JOugY#)r1EjML0OeFORrT1Xq?K3`$YRp~^6{BKt z6`cF_-Km7bQFo?09TYaUyot^w-B_G-pb~h=HMBJ4kJU3!-TCR54WH*Z2A;x3KyBq5 zfm-c0`z%sc3G9wFeFwIDicbb?O7}-9Oc{NNJZ0;uuW-fKMO%SLY}XdEb*++}^jo>V z1m-NC>1ZHi39y~Y-X6V*Y%pEcb5H=jddb0+%MN~ z^!6`@pa;6yMH?bOqTN{;6Z+KMJuBZhIZ^IA4;;&6dQRd8z0TWy7*IK#Z+|@y+(U&r z&1V{_vle>-0GB0mSt91ez{WAjS2X4{`#oAY}aB>P?KOmBNQT zFUJp4MHDX-D*!m@28(cOKx$>_ng(laCy^i^Q@RO>70VsLW)1g7VFDil06!1_^aS7s z3O@gwDgQSH5EM8dJPvqeBkH*d_VyB|LzxU#WCw-$VY12bX1iV6@_apb$zwM IOE(_>4+!d&v;Y7A diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/AppTangemDemo.kt b/tangem-devkit/src/main/java/com/tangem/devkit/AppTangemDemo.kt deleted file mode 100644 index 60ee3d4564..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/AppTangemDemo.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.tangem.devkit - -import android.app.Application -import android.content.Context -import android.content.SharedPreferences -import com.tangem.devkit._arch.structure.ILog -import com.tangem.devkit._arch.structure.ItemLogger -import com.tangem.devkit.commons.TangemLogger -import ru.dev.gbixahue.eu4d.lib.android.global.log.Log - -/** -[REDACTED_AUTHOR] - */ -class AppTangemDemo : Application() { - - override fun onCreate() { - super.onCreate() - - AppTangemDemo.appInstance = this - setupLoggers() - } - - private fun setupLoggers() { - Log.setLogger(TangemLogger()) - ILog.setLogger(ItemLogger()) - } - - fun sharedPreferences(name: String = "DevKitApp", mode: Int = Context.MODE_PRIVATE): SharedPreferences { - return getSharedPreferences(name, mode) - } - - companion object { - lateinit var appInstance: AppTangemDemo - } -} diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/Old_MainActivity.kt b/tangem-devkit/src/main/java/com/tangem/devkit/Old_MainActivity.kt deleted file mode 100644 index ffccc70603..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/Old_MainActivity.kt +++ /dev/null @@ -1,143 +0,0 @@ -package com.tangem.devkit - -import android.content.Intent -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.tangem.TangemSdk -import com.tangem.common.CompletionResult -import com.tangem.tangem_sdk_new.extensions.init -import kotlinx.android.synthetic.main.old_activity_main.* - -class Old_MainActivity : AppCompatActivity() { - - private lateinit var tangemSdk: TangemSdk - private lateinit var cardId: String - private lateinit var issuerData: ByteArray - private lateinit var issuerDataSignature: ByteArray - private var issuerDataCounter: Int = 1 - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.old_activity_main) - - tangemSdk = TangemSdk.init(this) - - btn_scan?.setOnClickListener { _ -> - tangemSdk.scanCard { taskEvent -> - when (taskEvent) { - is CompletionResult.Success -> { - // Handle returned card data - val card = taskEvent.data - cardId = card.cardId - runOnUiThread { - tv_card_cid?.text = cardId - btn_create_wallet.isEnabled = true - tv_card_cid?.text = cardId - btn_sign.isEnabled = true - btn_read_issuer_data.isEnabled = true - btn_read_issuer_extra_data.isEnabled = true - btn_write_issuer_data.isEnabled = true - btn_purge_wallet.isEnabled = true - btn_create_wallet.isEnabled = true - - } - } - } - } - } - btn_sign?.setOnClickListener { _ -> - tangemSdk.sign( - createSampleHashes(), - cardId) { - when (it) { - is CompletionResult.Failure -> { - runOnUiThread { tv_card_cid?.text = it.error::class.simpleName } - } - is CompletionResult.Success -> runOnUiThread { tv_card_cid?.text = cardId + "was used to sign sample hashes." } - } - } - } - btn_read_issuer_data?.setOnClickListener { _ -> - tangemSdk.readIssuerData(cardId) { - when (it) { - is CompletionResult.Failure -> { - runOnUiThread { tv_card_cid?.text = it.error::class.simpleName } - } - is CompletionResult.Success -> runOnUiThread { - btn_write_issuer_data.isEnabled = true - tv_card_cid?.text = it.data.issuerData.contentToString() - issuerData = it.data.issuerData - issuerDataSignature = it.data.issuerDataSignature - } - } - } - } - btn_write_issuer_data?.setOnClickListener { _ -> - tangemSdk.writeIssuerData( - cardId, - issuerData, - issuerDataSignature) { - when (it) { - is CompletionResult.Failure -> { - runOnUiThread { tv_card_cid?.text = it.error::class.simpleName } - } - is CompletionResult.Success -> runOnUiThread { - tv_card_cid?.text = it.data.cardId - } - } - } - } - btn_read_issuer_extra_data?.setOnClickListener { _ -> - tangemSdk.readIssuerExtraData(cardId) { - when (it) { - is CompletionResult.Failure -> { - runOnUiThread { tv_card_cid?.text = it.error::class.simpleName } - } - is CompletionResult.Success -> runOnUiThread { - issuerDataCounter = (it.data.issuerDataCounter ?: 0) + 1 - btn_write_issuer_data.isEnabled = true - tv_card_cid?.text = "Read ${it.data.issuerData.size} bytes of data." - } - } - } - } - btn_purge_wallet?.setOnClickListener { _ -> - tangemSdk.purgeWallet( - cardId) { - when (it) { - is CompletionResult.Failure -> { - runOnUiThread { tv_card_cid?.text = it.error::class.simpleName } - } - is CompletionResult.Success -> runOnUiThread { - tv_card_cid?.text = it.data.status.name - } - } - } - } - btn_create_wallet?.setOnClickListener { _ -> - tangemSdk.createWallet( - cardId) { - when (it) { - is CompletionResult.Failure -> { - runOnUiThread { tv_card_cid?.text = it.error::class.simpleName } - } - is CompletionResult.Success -> runOnUiThread { - tv_card_cid?.text = it.data.status.name - btn_sign.isEnabled = true - btn_read_issuer_data.isEnabled = true - btn_purge_wallet.isEnabled = true - btn_create_wallet.isEnabled = false - - } - } - } - } - btn_read_write_user_data?.setOnClickListener { startActivity(Intent(this, TestUserDataActivity::class.java)) } - } - - private fun createSampleHashes(): Array { - val hash1 = ByteArray(32) { 1 } - val hash2 = ByteArray(32) { 2 } - return arrayOf(hash1, hash2) - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/TestUserDataActivity.kt b/tangem-devkit/src/main/java/com/tangem/devkit/TestUserDataActivity.kt deleted file mode 100644 index 2be072959f..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/TestUserDataActivity.kt +++ /dev/null @@ -1,146 +0,0 @@ -package com.tangem.devkit - -import android.os.Bundle -import android.view.View -import android.widget.CompoundButton -import android.widget.TextView -import androidx.appcompat.app.AppCompatActivity -import com.tangem.TangemSdk -import com.tangem.TangemSdkError -import com.tangem.common.CompletionResult -import com.tangem.tangem_sdk_new.extensions.init -import kotlinx.android.synthetic.main.activity_test_user_data.* -import java.nio.charset.StandardCharsets - -/** -[REDACTED_AUTHOR] - */ -class TestUserDataActivity : AppCompatActivity() { - - private lateinit var tangemSdk: TangemSdk - private lateinit var writeOptions: WriteOptions - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_test_user_data) - - init() - initWriteOptions() - } - - private fun init() { - tangemSdk = TangemSdk.init(this) - - btn_scan?.setOnClickListener { _ -> - tangemSdk.scanCard { taskEvent -> - when (taskEvent) { - is CompletionResult.Success -> { - // Handle returned card data - writeOptions.cardId = taskEvent.data.cardId - runOnUiThread { showReadWriteSection(true) } - } - } - } - } - - btn_write.setOnClickListener { - if (writeOptions.cardId == null) return@setOnClickListener - - tangemSdk.writeUserData( - writeOptions.cardId!!, - writeOptions.userData, - writeOptions.userCounter - ) { - when (it) { - is CompletionResult.Failure -> handleError(tv_write_result, it.error) - is CompletionResult.Success -> { - runOnUiThread { tv_write_result?.text = "Success" } - } - } - } - } - - btn_read.setOnClickListener { - if (writeOptions.cardId == null) return@setOnClickListener - - tangemSdk.readUserData(writeOptions.cardId!!) { - when (it) { - is CompletionResult.Failure -> handleError(tv_write_result, it.error) - is CompletionResult.Success -> { - runOnUiThread { - - tv_read_result?.text = "Success" - - writeOptions.userData = it.data.userData - writeOptions.userProtectedData = it.data.userProtectedData - writeOptions.userCounter = it.data.userCounter - writeOptions.userProtectedCounter = it.data.userProtectedCounter - - tv_card_cid.text = it.data.cardId - tv_data.text = String(it.data.userData, StandardCharsets.US_ASCII) - tv_protected_data.text = String(it.data.userProtectedData, StandardCharsets.US_ASCII) - tv_counter.text = it.data.userCounter.toString() - tv_protected_counter.text = it.data.userProtectedCounter.toString() - } - - } - } - } - } - } - - private fun handleError(tv: TextView, error: TangemSdkError) { - if (error is TangemSdkError.UserCancelled) return - - runOnUiThread { tv.text = error::class.simpleName } - } - - private fun initWriteOptions() { - writeOptions = WriteOptions() - - chb_with_ud.setOnCheckedChangeListener { buttonView, isChecked -> writeOptions.updateData(buttonView) } - chb_with_ud_protected.setOnCheckedChangeListener { buttonView, isChecked -> writeOptions.updateProtectedData(buttonView) } - chb_with_counter.setOnCheckedChangeListener { buttonView, isChecked -> writeOptions.updateCounter(buttonView) } - chb_with_protected_counter.setOnCheckedChangeListener { buttonView, isChecked -> writeOptions.updateProtectedCounter(buttonView) } -// chb_with_pin2.setOnCheckedChangeListener { buttonView, isChecked -> writeOptions.updatePin2(buttonView) } - } - - private fun showReadWriteSection(show: Boolean) { - val state = if (show) View.VISIBLE else View.GONE - cl_read_write.visibility = state - } -} - -class WriteOptions { - var cardId: String? = null - var userData: ByteArray? = null - var userProtectedData: ByteArray? = null - var userCounter: Int? = null - var userProtectedCounter: Int? = null - var pin2: String? = null - - fun updateData(chbx: CompoundButton) { - val value = "simple user data".toByteArray() - userData = if (chbx.isChecked) value else null - } - - fun updateProtectedData(chbx: CompoundButton) { - val value = "protected user data".toByteArray() - userProtectedData = if (chbx.isChecked) value else null - } - - fun updateCounter(chbx: CompoundButton) { - val value = if (userCounter == null) 0 else userCounter!! + 1 - userCounter = if (chbx.isChecked) value else null - } - - fun updateProtectedCounter(chbx: CompoundButton) { - val value = if (userProtectedCounter == null) 0 else userProtectedCounter!! + 1 - userProtectedCounter = if (chbx.isChecked) value else null - } - -// fun updatePin2(chbx: CompoundButton) { -// val value = SessionEnvironment.pin1.DEFAULT_PIN2 -// pin2 = if (chbx.isChecked) value else null -// } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/SingleLiveEvent.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/SingleLiveEvent.kt deleted file mode 100644 index 1e6ed8667e..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/SingleLiveEvent.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.tangem.devkit._arch - -import android.util.Log -import androidx.annotation.MainThread -import androidx.annotation.Nullable -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.Observer -import java.util.concurrent.atomic.AtomicBoolean - -/** -[REDACTED_AUTHOR] - */ -class SingleLiveEvent : MutableLiveData() { - private val mPending: AtomicBoolean = AtomicBoolean(false) - - override fun observe(owner: LifecycleOwner, observer: Observer) { - if (hasActiveObservers()) { - Log.w(TAG, "Multiple observers registered but only one will be notified of changes.") - } - - // Observe the internal MutableLiveData - super.observe(owner, Observer { - if (mPending.compareAndSet(true, false)) { - observer.onChanged(it) - } - }) - } - - @MainThread - override fun setValue(@Nullable t: T?) { - mPending.set(true) - super.setValue(t) - } - - @MainThread - fun call() { - setValue(null) - } - - companion object { - private const val TAG = "SingleLiveEvent" - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/HelpAbstracts.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/HelpAbstracts.kt deleted file mode 100644 index 018e074061..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/HelpAbstracts.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.tangem.devkit._arch.structure - -/** -[REDACTED_AUTHOR] - */ -typealias Payload = MutableMap - -interface PayloadHolder { - val payload: Payload - - fun get(key: String): Any? = payload[key] - fun remove(key: String): Any? = payload.remove(key) - fun set(key: String, value: Any?) { - payload[key] = value - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/Ids.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/Ids.kt deleted file mode 100644 index bc05f80fca..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/Ids.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.tangem.devkit._arch.structure - -/** -[REDACTED_AUTHOR] - */ -interface Id { - - companion object { - fun getTag(id: Id): String { - val className = id.javaClass.simpleName - return if (id is Enum<*>) "$className.${id.name}" else className - } - } -} - -class StringId(val value: String) : Id - -class StringResId(val value: Int) : Id - -enum class Additional : Id { - UNDEFINED, - JSON_INCOMING, - JSON_OUTGOING, - JSON_TAILS, -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/Logger.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/Logger.kt deleted file mode 100644 index 5ba36bbbaa..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/Logger.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.tangem.devkit._arch.structure - -import ru.dev.gbixahue.eu4d.lib.android.global.log.Logger -import ru.dev.gbixahue.eu4d.lib.android.global.log.TagLogger -import ru.dev.gbixahue.eu4d.lib.android.global.log.profiling.SimpleLogProfiler -import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf - -/** -[REDACTED_AUTHOR] - */ -object ILog { - - private var logger: Logger? = null - - fun setLogger(logger: Logger) { - ILog.logger = logger - } - - fun d(from: Any, msg: Any?, value: Any? = null) { - logger?.d(from, stringOf(msg), value) - } - - fun w(from: Any, msg: Any?, value: Any? = null) { - logger?.w(from, stringOf(msg), value) - } - - fun e(from: Any, msg: Any?, value: Any? = null) { - logger?.e(from, stringOf(msg), value) - } -} - -class ItemLogger : TagLogger("ITEM") { - init { - msProfiler = SimpleLogProfiler() - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/Extension.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/Extension.kt deleted file mode 100644 index 41a4aab5ae..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/Extension.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.tangem.devkit._arch.structure.abstraction - -import com.tangem.devkit._arch.structure.Id - -/** -[REDACTED_AUTHOR] - */ -fun List.findItem(id: Id): Item? { - var foundItem: Item? = null - iterate { - if (it.id == id) { - foundItem = it - return@iterate - } - } - return foundItem -} - -fun List.iterate(func: (Item) -> Unit) { - forEach { - when (it) { - is BaseItem -> func(it) - is ItemGroup -> { - func(it) - it.itemList.iterate(func) - } - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/Item.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/Item.kt deleted file mode 100644 index d1fae9c535..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/Item.kt +++ /dev/null @@ -1,47 +0,0 @@ -package com.tangem.devkit._arch.structure.abstraction - -import com.tangem.devkit._arch.structure.Id - -/** -[REDACTED_AUTHOR] - */ - -interface UpdateBy{ - fun update(value: B) -} - -interface Item: UpdateBy { - val id: Id - var parent: Item? - var viewModel: ItemViewModel - - fun added(parent: Item) { - this.parent = parent - } - - fun removed(parent: Item) { - this.parent = null - } - - fun getData(): D? = viewModel.data as? D - - fun setData(value: Any?) { - viewModel.data = value - } - - fun restoreDefaultData() { - setData(viewModel.defaultData) - } -} - -open class BaseItem( - override val id: Id, - override var viewModel: ItemViewModel -) : Item { - - override var parent: Item? = null - - override fun update(value: Item) { - viewModel.update(value.viewModel) - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/ItemGroup.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/ItemGroup.kt deleted file mode 100644 index 1d38ba6f6d..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/ItemGroup.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.tangem.devkit._arch.structure.abstraction - -import com.tangem.devkit._arch.structure.ILog -import com.tangem.devkit._arch.structure.Id - -/** -[REDACTED_AUTHOR] - */ -interface ItemGroup : Item { - val itemList: MutableList - - fun setItems(list: MutableList) - fun getItems(): MutableList - fun addItem(item: Item) - fun removeItem(item: Item) - fun clear() -} - -open class SimpleItemGroup( - override val id: Id, - override var viewModel: ItemViewModel = BaseItemViewModel() -) : ItemGroup { - - override var parent: Item? = null - override val itemList: MutableList = mutableListOf() - - override fun setItems(list: MutableList) { - ILog.d(this, "setItems into: $id, count: ${list.size}") - itemList.forEach { it.removed(this) } - itemList.clear() - list.forEach { addItem(it) } - } - - override fun getItems(): MutableList = itemList - - override fun addItem(item: Item) { - ILog.d(this, "addItem into: $id, who: ${item.id}") - itemList.add(item) - item.added(this) - } - - override fun removeItem(item: Item) { - ILog.d(this, "removeItem from: $id, which: ${item.id}") - itemList.remove(item) - item.removed(this) - } - - override fun clear() { - ILog.d(this, "clear $id") - itemList.clear() - } - - override fun update(value: Item) { - // nothing to do - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/ItemViewModel.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/ItemViewModel.kt deleted file mode 100644 index eead6c8e3d..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/ItemViewModel.kt +++ /dev/null @@ -1,115 +0,0 @@ -package com.tangem.devkit._arch.structure.abstraction - -import com.tangem.devkit._arch.structure.ILog -import com.tangem.devkit._arch.structure.Payload -import com.tangem.devkit._arch.structure.PayloadHolder - - -/** -[REDACTED_AUTHOR] - */ -typealias ValueChanged = (V?) -> Unit -typealias SafeValueChanged = (V) -> Unit - -class KeyValue(val key: String, val value: Any) - -class ViewState( - isVisible: Boolean? = null, - bgColor: Int? = -1 -) : UpdateBy { - - class State( - stateValue: T, - var onValueChanged: SafeValueChanged? = null - ) { - var value = stateValue - set(value) { - if (preventSameChanges && field == value) return - - field = value - onValueChanged?.invoke(value) - } - - internal var preventSameChanges = true - } - - var isVisibleState = State(isVisible) - var backgroundColor = State(bgColor) - var descriptionVisibility = State(0x00000008) - - internal fun preventSameChanges(isPrevented: Boolean) { - val states = listOf(isVisibleState, backgroundColor, descriptionVisibility) - states.forEach { it.preventSameChanges = isPrevented } - } - - override fun update(value: ViewState) { -// isVisibleState.update(value.isVisibleState) -// backgroundColor.update(value.backgroundColor) -// descriptionVisibility.update(value.descriptionVisibility) - } -} - -interface ItemViewModel : PayloadHolder, UpdateBy { - val viewState: ViewState - var data: Any? - var defaultData: Any? - var onDataUpdated: ValueChanged? - - fun updateDataByView(data: Any?) -} - -open class BaseItemViewModel( - value: Any? = null, - override val viewState: ViewState = ViewState() -) : ItemViewModel { - - override val payload: Payload = mutableMapOf() - - // Don't update it directly from a View. Use for it updateDataByView() - override var data: Any? = value - set(value) { - if (handleDataUpdates(value)) field = value - } - - // Data for restoring initial value - override var defaultData: Any? = value - set(value) { - field = value - data = value - } - - // Use it for handling data updates in View - override var onDataUpdated: ValueChanged? = null - - // When data updates directly it invokes onDataUpdated - // return true = data will update - // return false = data won't update - protected open fun handleDataUpdates(value: Any?): Boolean { - ILog.d(this, "handleDateUpdates: $value") - onDataUpdated?.invoke(value) - return true - } - - // Use it to update the data from a View. It disables onDataUpdated to prevent a callback loop - override fun updateDataByView(data: Any?) { - ILog.d(this, "data changed: $data") - val callback = onDataUpdated - onDataUpdated = null - this.data = data - onDataUpdated = callback - } - - override fun update(value: ItemViewModel) { - viewState.update(value.viewState) - defaultData = value.defaultData - data = value.data - payload.clear() - payload.putAll(value.payload) - } -} - -class ListViewModel( - val itemList: List, - var selectedItem: Any?, - override val viewState: ViewState = ViewState() -) : BaseItemViewModel(selectedItem) \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/ModelConverter.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/ModelConverter.kt deleted file mode 100644 index 30c69cd6b2..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/ModelConverter.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.tangem.devkit._arch.structure.abstraction - -import ru.dev.gbixahue.eu4d.lib.kotlin.common.Converter - -/** -[REDACTED_AUTHOR] - */ -interface DefaultConverter { - fun convert(from: A, default: B): B -} - -interface TwoWayConverter { - fun aToB(from: A): B - fun bToA(from: B): A -} - -interface ItemsToModel : DefaultConverter, M> -interface ModelToItems : Converter> - -interface ModelConverter : DefaultConverter, M>, Converter> \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/Plugin.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/Plugin.kt deleted file mode 100644 index aaa6254d7c..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/abstraction/Plugin.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.devkit._arch.structure.abstraction - -/** -[REDACTED_AUTHOR] - */ -typealias PluginCallBackResult = (Any?) -> Item - -interface Plugin : Item { - fun invoke(data: Any?, asyncCallback: PluginCallBackResult? = null): Any? -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/impl/Items.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/impl/Items.kt deleted file mode 100644 index 80145d31e4..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/structure/impl/Items.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.tangem.devkit._arch.structure.impl - -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.abstraction.* - -/** -[REDACTED_AUTHOR] - */ - -open class TypedItem(id: Id, viewModel: ItemViewModel) : BaseItem(id, viewModel) { - open fun getTypedData(): D? = viewModel.data as? D -} - -open class TextItem(id: Id, viewModel: ItemViewModel) : TypedItem(id, viewModel) { - constructor(id: Id, value: String? = null, viewState: ViewState = ViewState()) - : this(id, BaseItemViewModel(value, viewState)) -} - -open class NumberItem(id: Id, viewModel: ItemViewModel) : TypedItem(id, viewModel) { - constructor(id: Id, value: Number? = null, viewState: ViewState = ViewState()) - : this(id, BaseItemViewModel(value, viewState)) -} - -open class BoolItem(id: Id, viewModel: ItemViewModel) : TypedItem(id, viewModel) { - constructor(id: Id, value: Boolean? = null, viewState: ViewState = ViewState()) - : this(id, BaseItemViewModel(value, viewState)) -} - - -open class EditTextItem(id: Id, viewModel: ItemViewModel) : TypedItem(id, viewModel) { - constructor(id: Id, value: String? = null, viewState: ViewState = ViewState()) - : this(id, BaseItemViewModel(value, viewState)) -} - - -open class SpinnerItem(id: Id, viewModel: ListViewModel) : TypedItem(id, viewModel) { - constructor(id: Id, list: List, selectedValue: Any?, viewState: ViewState = ViewState()) - : this(id, ListViewModel(list, selectedValue, viewState)) -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/ItemWidgetBuilder.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/ItemWidgetBuilder.kt deleted file mode 100644 index 4659c0ac49..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/ItemWidgetBuilder.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.tangem.devkit._arch.widget - -import android.view.ViewGroup -import com.tangem.devkit._arch.structure.abstraction.BaseItem -import com.tangem.devkit._arch.widget.abstraction.ViewWidget - -/** -[REDACTED_AUTHOR] - */ -interface ItemWidgetBuilder { - fun build(item: BaseItem, parent: ViewGroup): ViewWidget? -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/WidgetBuilder.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/WidgetBuilder.kt deleted file mode 100644 index cb39aa9072..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/WidgetBuilder.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.tangem.devkit._arch.widget - -import android.view.ViewGroup -import com.tangem.devkit._arch.structure.abstraction.BaseItem -import com.tangem.devkit._arch.structure.abstraction.Item -import com.tangem.devkit._arch.structure.abstraction.ItemGroup -import com.tangem.devkit._arch.widget.abstraction.ViewWidget -import com.tangem.devkit._arch.widget.impl.LinearGroupWidget -import com.tangem.devkit._arch.widget.impl.StubWidget - -/** -[REDACTED_AUTHOR] - */ -class WidgetBuilder( - private val itemBuilder: ItemWidgetBuilder -) { - - fun build(item: Item, parent: ViewGroup): ViewWidget? { - return when (item) { - is ItemGroup -> buildBlock(item, parent) - is BaseItem -> itemBuilder.build(item, parent) - else -> StubWidget(item.id, parent) - } - } - - private fun buildBlock(itemGroup: ItemGroup, parent: ViewGroup): ViewWidget { - return when (itemGroup) { - is ItemGroup -> { - val linearBlock = LinearGroupWidget(parent, itemGroup) - itemGroup.getItems().forEach { build(it, linearBlock.view as ViewGroup) } - linearBlock - } - else -> StubWidget(itemGroup.id, parent) - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/abstraction/ViewWidget.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/abstraction/ViewWidget.kt deleted file mode 100644 index e414e89cf7..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/abstraction/ViewWidget.kt +++ /dev/null @@ -1,81 +0,0 @@ -package com.tangem.devkit._arch.widget.abstraction - -import android.graphics.drawable.ColorDrawable -import android.graphics.drawable.Drawable -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.annotation.ColorRes -import com.tangem.devkit.R -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.StringId -import com.tangem.devkit._arch.structure.StringResId -import com.tangem.devkit._arch.structure.abstraction.Item -import com.tangem.devkit._arch.structure.abstraction.ViewState -import ru.dev.gbixahue.eu4d.lib.android._android.views.colorFrom -import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder - -/** -[REDACTED_AUTHOR] - */ -interface ViewWidget : LayoutHolder { - val view: View - var item: Item - - fun getName(): String - fun setBackgroundColor(@ColorRes colorId: Int?) -} - -abstract class BaseViewWidget( - parent: ViewGroup, - override var item: Item -) : ViewWidget { - - override val view: View = inflate(getLayoutId(), parent) - - private var defaultBackground: Drawable? = view.background - - init { - subscribeToViewStateChanges(item.viewModel.viewState) - initViewState(item.viewModel.viewState) - view.tag = Id.getTag(item.id) - } - - protected open fun subscribeToViewStateChanges(viewState: ViewState) { - viewState.isVisibleState.onValueChanged = { state -> - state?.let { view.visibility = if (it) View.VISIBLE else View.GONE } - } - viewState.backgroundColor.onValueChanged = { setBackgroundColor(it) } - } - - protected open fun initViewState(viewState: ViewState) { - viewState.preventSameChanges(false) - viewState.isVisibleState.value = viewState.isVisibleState.value - if (viewState.backgroundColor.value != -1) setBackgroundColor(viewState.backgroundColor.value) - viewState.preventSameChanges(true) - } - - override fun getName(): String { - return when (val id = item.id) { - is StringId -> id.value - is StringResId -> view.resources.getString(id.value) - else -> view.resources.getString(R.string.unknown) - } - } - - override fun setBackgroundColor(colorId: Int?) { - val background = when { - colorId == null -> null - colorId == -1 -> defaultBackground - else -> ColorDrawable(view.colorFrom(colorId)) - } - view.background = background - } -} - -internal fun inflate(id: Int, parent: ViewGroup): View { - val layoutId = if (id <= 0) R.layout.w_empty else id - val inflatedView = LayoutInflater.from(parent.context).inflate(layoutId, parent, false) - parent.addView(inflatedView) - return inflatedView -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/impl/LinearGroupWidget.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/impl/LinearGroupWidget.kt deleted file mode 100644 index 54948387de..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/impl/LinearGroupWidget.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.tangem.devkit._arch.widget.impl - -import android.view.ViewGroup -import com.tangem.devkit.R -import com.tangem.devkit._arch.structure.abstraction.ItemGroup -import com.tangem.devkit._arch.widget.abstraction.BaseViewWidget - -/** -[REDACTED_AUTHOR] - */ -class LinearGroupWidget( - parent: ViewGroup, - itemGroup: ItemGroup -) : BaseViewWidget(parent, itemGroup) { - - override fun getLayoutId(): Int = R.layout.w_personilize_block - -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/impl/StubWidget.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/impl/StubWidget.kt deleted file mode 100644 index 0edc41b3be..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_arch/widget/impl/StubWidget.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.tangem.devkit._arch.widget.impl - -import android.view.ViewGroup -import com.tangem.devkit.R -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.abstraction.BaseItem -import com.tangem.devkit._arch.structure.abstraction.BaseItemViewModel -import com.tangem.devkit._arch.widget.abstraction.BaseViewWidget - -/** -[REDACTED_AUTHOR] - */ -class StubWidget(id: Id, parent: ViewGroup) : BaseViewWidget(parent, BaseItem(id, BaseItemViewModel())) { - override fun getLayoutId(): Int = R.layout.w_empty -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_main/MainActivity.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_main/MainActivity.kt deleted file mode 100644 index dbfd82105f..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_main/MainActivity.kt +++ /dev/null @@ -1,75 +0,0 @@ -package com.tangem.devkit._main - -import android.content.res.Resources -import android.os.Bundle -import android.view.Menu -import android.view.MenuItem -import androidx.activity.viewModels -import androidx.appcompat.app.AppCompatActivity -import androidx.appcompat.widget.Toolbar -import androidx.navigation.findNavController -import androidx.navigation.fragment.NavHostFragment -import androidx.navigation.ui.AppBarConfiguration -import androidx.navigation.ui.navigateUp -import androidx.navigation.ui.setupWithNavController -import com.tangem.devkit.R -import ru.dev.gbixahue.eu4d.lib.android.global.log.Log - -/** -[REDACTED_AUTHOR] - */ -class MainActivity : AppCompatActivity() { - - private val mainVM: MainViewModel by viewModels() - private lateinit var appBarConfiguration: AppBarConfiguration - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.a_main) - - val toolbar = findViewById(R.id.toolbar) - setSupportActionBar(toolbar) - - val host: NavHostFragment = supportFragmentManager - .findFragmentById(R.id.nav_host_fragment) as NavHostFragment? ?: return - - val navController = host.navController - appBarConfiguration = AppBarConfiguration(navController.graph) - toolbar.setupWithNavController(navController, appBarConfiguration) - - navController.addOnDestinationChangedListener { _, destination, _ -> - val dest: String = try { - resources.getResourceName(destination.id) - } catch (e: Resources.NotFoundException) { - destination.id.toString() - } - Log.d(this, "Navigated to $dest") - } - } - - override fun onSupportNavigateUp(): Boolean { - return findNavController(R.id.nav_host_fragment).navigateUp(appBarConfiguration) - } - - override fun onCreateOptionsMenu(menu: Menu): Boolean { - menuInflater.inflate(R.menu.menu_activity_main, menu) - return true - } - - override fun onPrepareOptionsMenu(menu: Menu): Boolean { - val switchItem = menu.findItem(R.id.action_toggle_description_visibility) - switchItem.isChecked = mainVM.descriptionSwitchState - return super.onPrepareOptionsMenu(menu) - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - val result = when (item.itemId) { - R.id.action_toggle_description_visibility -> { - item.isChecked = !item.isChecked - mainVM.switchToggled(item.isChecked) - } - else -> null - } - return if (result == null) super.onOptionsItemSelected(item) else true - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_main/MainViewModel.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_main/MainViewModel.kt deleted file mode 100644 index 6766c6d77f..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_main/MainViewModel.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.tangem.devkit._main - -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import com.tangem.commands.CommandResponse -import ru.dev.gbixahue.eu4d.lib.android.global.log.Log - -/** -[REDACTED_AUTHOR] - */ -class MainViewModel : ViewModel() { - val ldDescriptionSwitch = MutableLiveData(false) - var descriptionSwitchState = false - - var commandResponse: CommandResponse? = null - - fun switchToggled(state: Boolean) { - descriptionSwitchState = state - ldDescriptionSwitch.postValue(state) - } - - fun changeResponseEvent(commandResponse: CommandResponse?) { - Log.d(this, "changeResponseEvent") - val response = commandResponse ?: return - - this.commandResponse = response - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_main/entryPoint/ActionListFragment.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_main/entryPoint/ActionListFragment.kt deleted file mode 100644 index 2656204d6b..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_main/entryPoint/ActionListFragment.kt +++ /dev/null @@ -1,78 +0,0 @@ -package com.tangem.devkit._main.entryPoint - -import android.os.Bundle -import android.view.View -import androidx.fragment.app.activityViewModels -import androidx.lifecycle.Observer -import androidx.recyclerview.widget.DividerItemDecoration -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.tangem.devkit.R -import com.tangem.devkit._main.MainViewModel -import com.tangem.devkit.extensions.view.beginDelayedTransition -import com.tangem.devkit.ucase.getDefaultNavigationOptions -import com.tangem.devkit.ucase.resources.ActionType -import com.tangem.devkit.ucase.resources.MainResourceHolder -import com.tangem.devkit.ucase.ui.BaseFragment -import kotlinx.android.synthetic.main.fg_entry_point.* - -/** -[REDACTED_AUTHOR] - */ -class ActionListFragment : BaseFragment() { - - private lateinit var rvActions: RecyclerView - - private val mainActivityVM: MainViewModel by activityViewModels() - - override fun getLayoutId(): Int = R.layout.fg_entry_point - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - initRecyclerView() - } - - private fun initRecyclerView() { - val layoutManager = LinearLayoutManager(activity) - rvActions = rv_actions - rvActions.layoutManager = layoutManager - rvActions.addItemDecoration(DividerItemDecoration(activity, layoutManager.orientation)) - - val vhDataWrapper = VhExDataWrapper(MainResourceHolder, false) - - rvActions.adapter = RvActionsAdapter(vhDataWrapper) { type, position, data -> - navigateTo(data, options = getDefaultNavigationOptions()) - } - mainActivityVM.ldDescriptionSwitch.observe(viewLifecycleOwner, Observer { - vhDataWrapper.descriptionIsVisible = it - rvActions.beginDelayedTransition() - rvActions.adapter?.notifyDataSetChanged() - }) - } - - override fun onResume() { - super.onResume() - val adapter: RvActionsAdapter = rvActions.adapter as? RvActionsAdapter ?: return - - adapter.setItemList(getNavigateOptions()) - adapter.notifyDataSetChanged() - } - - private fun getNavigateOptions(): MutableList { - return mutableListOf( - ActionType.Scan, - ActionType.Sign, - ActionType.Personalize, - ActionType.Depersonalize, - ActionType.CreateWallet, - ActionType.PurgeWallet, - ActionType.ReadIssuerData, - ActionType.WriteIssuerData, - ActionType.ReadIssuerExData, - ActionType.WriteIssuerExData, - ActionType.ReadUserData, - ActionType.WriteUserData, - ActionType.WriteProtectedUserData - ) - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/_main/entryPoint/RvActions.kt b/tangem-devkit/src/main/java/com/tangem/devkit/_main/entryPoint/RvActions.kt deleted file mode 100644 index 01162d2eee..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/_main/entryPoint/RvActions.kt +++ /dev/null @@ -1,67 +0,0 @@ -package com.tangem.devkit._main.entryPoint - -import android.view.View -import android.view.ViewGroup -import android.widget.TextView -import androidx.annotation.StringRes -import androidx.recyclerview.widget.RecyclerView -import com.tangem.devkit.R -import com.tangem.devkit.ucase.resources.ActionRes -import com.tangem.devkit.ucase.resources.ActionType -import com.tangem.devkit.ucase.resources.MainResourceHolder -import ru.dev.gbixahue.eu4d.lib.android._android.views.inflate -import ru.dev.gbixahue.eu4d.lib.android._android.views.recycler_view.RvBaseAdapter -import ru.dev.gbixahue.eu4d.lib.android._android.views.recycler_view.RvBaseVH -import ru.dev.gbixahue.eu4d.lib.android._android.views.recycler_view.RvCallback - -/** -[REDACTED_AUTHOR] - */ -class RvActionsAdapter( - private val wrapper: VhExDataWrapper, - private val callback: RvCallback -) : RvBaseAdapter() { - - override fun onBindViewHolder(holder: RvActionsVH, position: Int) { - holder.bindData(itemList[position]) - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RvActionsVH { - val view = parent.inflate(R.layout.vh_actions, false) - return RvActionsVH(view, wrapper, callback) - } - -} - -class VhExDataWrapper( - val resHolder: MainResourceHolder, - var descriptionIsVisible: Boolean -) - -class RvActionsVH( - itemView: View, - private val wrapper: VhExDataWrapper, - private val callback: RvCallback? -) : RvBaseVH(itemView) { - - private val tvAction = itemView.findViewById(R.id.tv_title) - private val containerDescription = itemView.findViewById(R.id.container_description) - private val tvDescription = itemView.findViewById(R.id.tv_description) - - override fun bindData(data: ActionType) { - val res: ActionRes = wrapper.resHolder.safeGet(data) - tvAction.text = getString(res.resName) - tvDescription.text = getString(res.resDescription) - - itemView.setOnClickListener { - res.resNavigation?.let { callback?.invoke(itemViewType, adapterPosition, it) } - } - - containerDescription.visibility = if (wrapper.descriptionIsVisible) View.VISIBLE else View.GONE - } -} - -fun RecyclerView.ViewHolder.getString(@StringRes id: Int?, ifNull: String = ""): String { - val reqId = id ?: return ifNull - return itemView.context.getString(reqId) -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/commons/Abstractions.kt b/tangem-devkit/src/main/java/com/tangem/devkit/commons/Abstractions.kt deleted file mode 100644 index 3a1776e7c6..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/commons/Abstractions.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.tangem.devkit.commons - -/** -[REDACTED_AUTHOR] - */ -interface Store { - fun save(value: M) - fun restore(): M -} - -interface KeyedStore { - fun save(key: String, value: M) - fun restore(key: String): M - fun restoreAll(): MutableMap - fun delete(key: String) -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/commons/DialogController.kt b/tangem-devkit/src/main/java/com/tangem/devkit/commons/DialogController.kt deleted file mode 100644 index 5d4c924409..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/commons/DialogController.kt +++ /dev/null @@ -1,76 +0,0 @@ -package com.tangem.devkit.commons - -import android.app.Activity -import android.app.Dialog -import android.view.LayoutInflater -import android.view.View -import androidx.appcompat.app.AlertDialog - -class DialogController { - var onDismissCallback: (() -> Unit)? = null - var onShowCallback: (() -> Unit)? = null - var view: View? = null - - private var rawDialog: Dialog? = null - - private var inShowingProcess = false - private var inDismissingProcess = false - private var autoReleaseOnDismiss = false - - fun createAlert(context: Activity, resLayout: Int): AlertDialog { - view = LayoutInflater.from(context).inflate(resLayout, null) - rawDialog = AlertDialog.Builder(context).setView(view).create().apply { - setOnShowListener { onShow() } - setOnDismissListener { onDismiss() } - } - return rawDialog as AlertDialog - } - - fun set(dialog: Dialog) { - rawDialog = dialog - dialog.setOnShowListener { onShow() } - dialog.setOnDismissListener { onDismiss() } - } - - private fun onShow() { - inShowingProcess = false - onShowCallback?.invoke() - } - - private fun onDismiss() { - inDismissingProcess = false - if (autoReleaseOnDismiss) release() - onDismissCallback?.invoke() - } - - fun show() { - val dialog = rawDialog ?: return - if (inShowingProcess) return - if (dialog.isShowing) return - - inShowingProcess = true - dialog.show() - } - - fun dismiss(autoRelease: Boolean = true) { - val dialog = rawDialog ?: return - if (inDismissingProcess) return - if (!dialog.isShowing) return - - autoReleaseOnDismiss = autoRelease - inDismissingProcess = true - dialog.dismiss() - } - - fun release() { - onDismissCallback = null - onShowCallback = null - - inShowingProcess = false - inDismissingProcess = false - autoReleaseOnDismiss = false - - view = null - rawDialog = null - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/commons/GlobalFunctions.kt b/tangem-devkit/src/main/java/com/tangem/devkit/commons/GlobalFunctions.kt deleted file mode 100644 index 0f80ba2e83..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/commons/GlobalFunctions.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.tangem.devkit.commons - -/** -[REDACTED_AUTHOR] - */ -fun performAction(a: A?, b: B?, action: (A, B) -> Unit, onFail: (() -> Unit)? = null) { - if (a != null && b != null) action(a, b) - else onFail?.invoke() -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/commons/Logger.kt b/tangem-devkit/src/main/java/com/tangem/devkit/commons/Logger.kt deleted file mode 100644 index 94e709455a..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/commons/Logger.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.tangem.devkit.commons - -import ru.dev.gbixahue.eu4d.lib.android.global.log.TagLogger - -/** -[REDACTED_AUTHOR] - */ -class TangemLogger : TagLogger("TangemDemo") \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/commons/view/MultiActionView.kt b/tangem-devkit/src/main/java/com/tangem/devkit/commons/view/MultiActionView.kt deleted file mode 100644 index 4e134e0336..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/commons/view/MultiActionView.kt +++ /dev/null @@ -1,85 +0,0 @@ -package com.tangem.devkit.commons.view - -import android.widget.TextView -import androidx.annotation.StringRes -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.StringId -import com.tangem.devkit._arch.structure.abstraction.SafeValueChanged -import ru.dev.gbixahue.eu4d.lib.android.global.log.Log -import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf - -/** -[REDACTED_AUTHOR] - */ -open class MultiActionView( - stateActionList: MutableList, - val child: V -) { - - interface State { - val id: Id - - fun getAction(): SimpleFunction - fun getResNameId(): Int - } - - var afterAction: SafeValueChanged? = null - - var state: Id = DefaultId.default - set(value) { - if (field == value) return - - field = value - Log.d(this, "state changed to: ${getKey(value)}") - btnState = stateHolder[getKey(value)] - } - - init { - child.setOnClickListener { - val state = btnState ?: return@setOnClickListener - - Log.d(this, "child handled OnClick for: ${getKey(state.id)}") - state.getAction().invoke() - afterAction?.invoke(state.id) - } - } - - protected var btnState: State? = null - set(value) { - if (value == null) return - - field = value - Log.d(this, "btnState changed to: ${getKey(value.id)}") - child.setText(value.getResNameId()) - } - - protected val stateHolder: MutableMap = stateActionList.associateBy { getKey(it.id) }.toMutableMap() - - fun performAction(id: Id) { - Log.d(this, "performAction ${getKey(id)}") - state = id - child.performClick() - } - - protected open fun getKey(id: Id): String { - return when (id) { - is StringId -> id.value - else -> stringOf(id) - } - } -} - -enum class DefaultId : Id { default } - -typealias SimpleFunction = () -> Unit - -class ViewAction( - override val id: Id, - @StringRes val name: Int, - private val action: SimpleFunction -) : MultiActionView.State { - - override fun getAction(): SimpleFunction = action - - override fun getResNameId(): Int = name -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/extensions/AndroidComponents.kt b/tangem-devkit/src/main/java/com/tangem/devkit/extensions/AndroidComponents.kt deleted file mode 100644 index d7ae706d37..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/extensions/AndroidComponents.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.tangem.devkit.extensions - -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context -import android.content.Intent -import androidx.fragment.app.Fragment - -/** -[REDACTED_AUTHOR] - */ -fun Context.copyToClipboard(value: Any, label: String = "") { - val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager ?: return - - val clip: ClipData = ClipData.newPlainText(label, value.toString()) - clipboard.setPrimaryClip(clip) -} - -fun Context.shareText(text: String) { - val sendIntent: Intent = Intent().apply { - action = Intent.ACTION_SEND - putExtra(Intent.EXTRA_TEXT, text) - type = "text/plain" - } - val shareIntent = Intent.createChooser(sendIntent, null) - startActivity(shareIntent) -} - -fun Fragment.shareText(text: String) { - requireContext().shareText(text) -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/extensions/List.kt b/tangem-devkit/src/main/java/com/tangem/devkit/extensions/List.kt deleted file mode 100644 index f40be815b4..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/extensions/List.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.tangem.devkit.extensions - -/** -[REDACTED_AUTHOR] - */ -fun List.print(delimiter: String = ", ", wrap: Boolean = true): String { - val builder = StringBuilder() - forEach { builder.append(it).append(delimiter) } - val length = builder.length - if (length > delimiter.length) { - builder.delete(length - delimiter.length, length) - } - val result = builder.toString() - - return if (wrap) "[$result]" else result -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/extensions/view/Transitions.kt b/tangem-devkit/src/main/java/com/tangem/devkit/extensions/view/Transitions.kt deleted file mode 100644 index 1a6762eca0..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/extensions/view/Transitions.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.tangem.devkit.extensions.view - -import android.view.ViewGroup -import androidx.transition.AutoTransition -import androidx.transition.Transition -import androidx.transition.TransitionManager - -/** -[REDACTED_AUTHOR] - */ -fun ViewGroup.beginDelayedTransition(transition: Transition = AutoTransition()) { - TransitionManager.beginDelayedTransition(this, transition) -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/NavigationOp.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/NavigationOp.kt deleted file mode 100644 index c006bf6aa4..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/NavigationOp.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.tangem.devkit.ucase - -import androidx.navigation.NavOptions -import androidx.navigation.navOptions -import com.tangem.devkit.R - -/** -[REDACTED_AUTHOR] - */ -fun getDefaultNavigationOptions(): NavOptions { - return navOptions { - anim { - enter = R.anim.slide_in_right - exit = R.anim.slide_out_left - popEnter = R.anim.slide_in_left - popExit = R.anim.slide_out_right - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/Action.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/Action.kt deleted file mode 100644 index f0c92ad43e..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/Action.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.tangem.devkit.ucase.domain.actions - -import com.tangem.TangemSdk -import com.tangem.common.CompletionResult -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.Payload -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.Item -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.domain.paramsManager.triggers.afterAction.AfterActionModification -import com.tangem.devkit.ucase.domain.paramsManager.triggers.changeConsequence.ItemsChangeConsequence - -/** -[REDACTED_AUTHOR] - * - * The Card Action class family is designed for calling Card Manager functions - * and then processing the response. It also allows you to extract the main action as a lambda expression - */ -data class AttrForAction( - val tangemSdk: TangemSdk, - val itemList: List, - val payload: Payload, - val consequence: ItemsChangeConsequence? -) - -interface Action { - fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) - fun getActionByTag(payload: PayloadHolder, id: Id, attrs: AttrForAction): ((ActionCallback) -> Unit)? = null -} - -abstract class BaseAction : Action { - protected open fun handleResult( - payload: PayloadHolder, - commandResult: CompletionResult<*>, - modifier: AfterActionModification?, - attrs: AttrForAction, - callback: ActionCallback - ) { - val modifiedItems = mutableListOf() - modifier?.modify(payload, commandResult, attrs.itemList)?.forEach { item -> - modifiedItems.add(item) - attrs.consequence?.affectChanges(payload, item, attrs.itemList)?.let { modifiedItems.addAll(it) } - } - callback(commandResult, modifiedItems) - } - - override fun getActionByTag(payload: PayloadHolder, id: Id, attrs: AttrForAction): ((ActionCallback) -> Unit)? = null -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/CreateWalletAction.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/CreateWalletAction.kt deleted file mode 100644 index 0e02ca670f..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/CreateWalletAction.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.tangem.devkit.ucase.domain.actions - -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.findItem -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.variants.TlvId - -class CreateWalletAction : BaseAction() { - override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - val item = attrs.itemList.findItem(TlvId.CardId) ?: return - val cardId = item.viewModel.data as? String ?: return - - attrs.tangemSdk.createWallet(cardId) { handleResult(payload, it, null, attrs, callback) } - } - - override fun getActionByTag(payload: PayloadHolder, id: Id, attrs: AttrForAction): ((ActionCallback) -> Unit)? { - return when (id) { - TlvId.CardId -> { callback -> ScanAction().executeMainAction(payload, attrs, callback) } - else -> null - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/DepersonalizeAction.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/DepersonalizeAction.kt deleted file mode 100644 index 9cfec29492..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/DepersonalizeAction.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.tangem.devkit.ucase.domain.actions - -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.domain.paramsManager.triggers.afterAction.AfterScanModifier - -/** -[REDACTED_AUTHOR] - */ -class DepersonalizeAction : BaseAction() { - override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - attrs.tangemSdk.depersonalize { handleResult(payload, it, AfterScanModifier(), attrs, callback) } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/PersonalizeAction.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/PersonalizeAction.kt deleted file mode 100644 index 5e0519b5ce..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/PersonalizeAction.kt +++ /dev/null @@ -1,66 +0,0 @@ -package com.tangem.devkit.ucase.domain.actions - -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.Item -import com.tangem.devkit._arch.structure.abstraction.findItem -import com.tangem.devkit._arch.structure.impl.EditTextItem -import com.tangem.devkit._arch.structure.impl.NumberItem -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.domain.paramsManager.PayloadKey -import com.tangem.devkit.ucase.tunnel.ActionView -import com.tangem.devkit.ucase.tunnel.ItemError -import com.tangem.devkit.ucase.variants.personalize.CardNumberId -import com.tangem.devkit.ucase.variants.personalize.converter.PersonalizationConfigConverter -import com.tangem.devkit.ucase.variants.personalize.converter.PersonalizationJsonConverter -import com.tangem.devkit.ucase.variants.personalize.dto.DefaultPersonalizationParams -import com.tangem.devkit.ucase.variants.personalize.dto.PersonalizationConfig -import com.tangem.devkit.ucase.variants.personalize.dto.toCardConfig -import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf - -/** -[REDACTED_AUTHOR] - */ -class PersonalizeAction : BaseAction() { - override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - val itemList = attrs.payload[PayloadKey.itemList] as? List ?: return - val actionView = attrs.payload[PayloadKey.actionView] as? ActionView ?: return - - if (!checkSeries(itemList)) { - actionView.showSnackbar(ItemError.BadSeries) - return - } - if (!checkNumber(itemList)) { - actionView.showSnackbar(ItemError.BadCardNumber) - return - } - - val issuer = DefaultPersonalizationParams.issuer() - val acquirer = DefaultPersonalizationParams.acquirer() - val manufacturer = DefaultPersonalizationParams.manufacturer() - - val config = PersonalizationConfigConverter().convert(itemList, PersonalizationConfig.default()) - val jsonDto = PersonalizationJsonConverter().bToA(config) - - attrs.tangemSdk.personalize(jsonDto.toCardConfig(), issuer, manufacturer, acquirer) { - handleResult(payload, it, null, attrs, callback) - } - } - - private fun checkSeries(itemList: List): Boolean { - val seriesItem = itemList.findItem(CardNumberId.Series) as? EditTextItem ?: return false - val data = seriesItem.getData() as? String ?: return false - - seriesItem.setData(data.toUpperCase()) - return data.length == 2 || data.length == 4 - } - - private fun checkNumber(itemList: List): Boolean { - val seriesItem = itemList.findItem(CardNumberId.Series) as? EditTextItem ?: return false - val numberItem = itemList.findItem(CardNumberId.Number) as? NumberItem ?: return false - val seriesData = seriesItem.getData() as? String ?: return false - val numberData = stringOf(numberItem.getData() as? Number) - - return if (seriesData.length == 2 && numberData.length > 13) false - else !(seriesData.length == 4 && numberData.length > 11) - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/PurgeWalletAction.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/PurgeWalletAction.kt deleted file mode 100644 index 4c2efe395e..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/PurgeWalletAction.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.tangem.devkit.ucase.domain.actions - -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.findItem -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.variants.TlvId - -class PurgeWalletAction : BaseAction() { - override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - val item = attrs.itemList.findItem(TlvId.CardId) ?: return - val cardId = item.viewModel.data as? String ?: return - - attrs.tangemSdk.purgeWallet(cardId) { handleResult(payload, it, null, attrs, callback) } - } - - override fun getActionByTag(payload: PayloadHolder, id: Id, attrs: AttrForAction): ((ActionCallback) -> Unit)? { - return when (id) { - TlvId.CardId -> { callback -> ScanAction().executeMainAction(payload, attrs, callback) } - else -> null - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ReadIssuerDataAction.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ReadIssuerDataAction.kt deleted file mode 100644 index 580e43d4f2..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ReadIssuerDataAction.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.tangem.devkit.ucase.domain.actions - -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.findItem -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.variants.TlvId - -class ReadIssuerDataAction : BaseAction() { - override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - val item = attrs.itemList.findItem(TlvId.CardId) ?: return - val cardId = item.viewModel.data as? String ?: return - - attrs.tangemSdk.readIssuerData(cardId) { handleResult(payload, it, null, attrs, callback) } - } - - override fun getActionByTag(payload: PayloadHolder, id: Id, attrs: AttrForAction): ((ActionCallback) -> Unit)? { - return when (id) { - TlvId.CardId -> { callback -> ScanAction().executeMainAction(payload, attrs, callback) } - else -> null - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ReadIssuerExtraDataAction.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ReadIssuerExtraDataAction.kt deleted file mode 100644 index 4483a0bd78..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ReadIssuerExtraDataAction.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.tangem.devkit.ucase.domain.actions - -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.findItem -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.variants.TlvId - -class ReadIssuerExtraDataAction : BaseAction() { - override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - val item = attrs.itemList.findItem(TlvId.CardId) ?: return - val cardId = item.viewModel.data as? String ?: return - - attrs.tangemSdk.readIssuerExtraData(cardId) { handleResult(payload, it, null, attrs, callback) } - } - - override fun getActionByTag(payload: PayloadHolder, id: Id, attrs: AttrForAction): ((ActionCallback) -> Unit)? { - return when (id) { - TlvId.CardId -> { callback -> ScanAction().executeMainAction(payload, attrs, callback) } - else -> null - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ReadUserDataAction.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ReadUserDataAction.kt deleted file mode 100644 index 6014c60757..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ReadUserDataAction.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.tangem.devkit.ucase.domain.actions - -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.findItem -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.variants.TlvId - -class ReadUserDataAction : BaseAction() { - override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - val item = attrs.itemList.findItem(TlvId.CardId) ?: return - val cardId = item.viewModel.data as? String ?: return - - attrs.tangemSdk.readUserData(cardId) { handleResult(payload, it, null, attrs, callback) } - } - - override fun getActionByTag(payload: PayloadHolder, id: Id, attrs: AttrForAction): ((ActionCallback) -> Unit)? { - return when (id) { - TlvId.CardId -> { callback -> ScanAction().executeMainAction(payload, attrs, callback) } - else -> null - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ScanAction.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ScanAction.kt deleted file mode 100644 index 5e4e42aa08..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/ScanAction.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.tangem.devkit.ucase.domain.actions - -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.domain.paramsManager.triggers.afterAction.AfterScanModifier - -/** -[REDACTED_AUTHOR] - */ -class ScanAction : BaseAction() { - override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - attrs.tangemSdk.scanCard { handleResult(payload, it, AfterScanModifier(), attrs, callback) } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/SignAction.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/SignAction.kt deleted file mode 100644 index a1cf64ae35..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/SignAction.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.tangem.devkit.ucase.domain.actions - -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.findItem -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.variants.TlvId -import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf - -/** -[REDACTED_AUTHOR] - */ -class SignAction : BaseAction() { - override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - val dataForHashing = attrs.itemList.findItem(TlvId.TransactionOutHash) ?: return - val hash = dataForHashing.getData() as? String ?: return - val cardId = attrs.itemList.findItem(TlvId.CardId)?.viewModel?.data ?: return - - attrs.tangemSdk.sign(arrayOf(hash.toByteArray()), stringOf(cardId)) { handleResult(payload, it, null, attrs, callback) } - } - - override fun getActionByTag(payload: PayloadHolder, id: Id, attrs: AttrForAction): ((ActionCallback) -> Unit)? { - return when (id) { - TlvId.CardId -> { callback -> ScanAction().executeMainAction(payload, attrs, callback) } - else -> null - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteIssuerDataAction.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteIssuerDataAction.kt deleted file mode 100644 index c93f5edfc1..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteIssuerDataAction.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.tangem.devkit.ucase.domain.actions - -import com.tangem.common.extensions.hexToBytes -import com.tangem.common.extensions.toByteArray -import com.tangem.crypto.sign -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.findItem -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.variants.TlvId -import com.tangem.devkit.ucase.variants.personalize.dto.DefaultPersonalizationParams -import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf - -class WriteIssuerDataAction : BaseAction() { - override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - val cardId = attrs.itemList.findItem(TlvId.CardId)?.viewModel?.data ?: return - val counter = (attrs.itemList.findItem(TlvId.Counter)?.viewModel?.data as? Int) ?: 1 - - val issuerDataItem = attrs.itemList.findItem(TlvId.IssuerData) ?: return - val issuerData = (issuerDataItem.getData() as? String)?.toByteArray() ?: return - - val signedIssuerData = ( - stringOf(cardId).hexToBytes() + issuerData + counter.toByteArray(4)) - .sign(DefaultPersonalizationParams.issuer().dataKeyPair.privateKey) - - attrs.tangemSdk.writeIssuerData(stringOf(cardId), issuerData, signedIssuerData, counter) { - handleResult(payload, it, null, attrs, callback) - } - } - - override fun getActionByTag(payload: PayloadHolder, id: Id, attrs: AttrForAction): ((ActionCallback) -> Unit)? { - return when (id) { - TlvId.CardId -> { callback -> ScanAction().executeMainAction(payload, attrs, callback) } - else -> null - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteIssuerExtraDataAction.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteIssuerExtraDataAction.kt deleted file mode 100644 index 17c5052f9f..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteIssuerExtraDataAction.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.tangem.devkit.ucase.domain.actions - -import com.tangem.commands.WriteIssuerExtraDataCommand -import com.tangem.common.extensions.hexToBytes -import com.tangem.common.extensions.toByteArray -import com.tangem.crypto.CryptoUtils -import com.tangem.crypto.sign -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.findItem -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.variants.TlvId -import com.tangem.devkit.ucase.variants.personalize.dto.DefaultPersonalizationParams -import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf - -class WriteIssuerExtraDataAction : BaseAction() { - override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - val cardId = attrs.itemList.findItem(TlvId.CardId)?.viewModel?.data ?: return - val counter = (attrs.itemList.findItem(TlvId.Counter)?.viewModel?.data as? String)?.toInt() ?: 1 - - val issuerData = CryptoUtils.generateRandomBytes(WriteIssuerExtraDataCommand.SINGLE_WRITE_SIZE * 5) - - - val startingSignature = ( - stringOf(cardId).hexToBytes() + counter.toByteArray(4) + issuerData.size.toByteArray(2)) - .sign(DefaultPersonalizationParams.issuer().dataKeyPair.privateKey) - - val finalizingSignature = ( - stringOf(cardId).hexToBytes() + issuerData + counter.toByteArray(4)) - .sign(DefaultPersonalizationParams.issuer().dataKeyPair.privateKey) - - attrs.tangemSdk.writeIssuerExtraData( - stringOf(cardId), issuerData, startingSignature, finalizingSignature, counter - ) { - handleResult(payload, it, null, attrs, callback) - } - } - - override fun getActionByTag(payload: PayloadHolder, id: Id, attrs: AttrForAction): ((ActionCallback) -> Unit)? { - return when (id) { - TlvId.CardId -> { callback -> ScanAction().executeMainAction(payload, attrs, callback) } - else -> null - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteUserDataAction.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteUserDataAction.kt deleted file mode 100644 index 7727546c05..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteUserDataAction.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.tangem.devkit.ucase.domain.actions - -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.findItem -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.variants.TlvId -import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf - -class WriteUserDataAction : BaseAction() { - override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - val userData = (attrs.itemList.findItem(TlvId.UserData)?.getData() as? String)?.toByteArray() - ?: return - val cardId = attrs.itemList.findItem(TlvId.CardId)?.viewModel?.data ?: return - val counter = (attrs.itemList.findItem(TlvId.Counter)?.viewModel?.data as? Int) ?: 1 - - attrs.tangemSdk.writeUserData(stringOf(cardId), userData, counter) { - handleResult(payload, it, null, attrs, callback) - } - } - - override fun getActionByTag(payload: PayloadHolder, id: Id, attrs: AttrForAction): ((ActionCallback) -> Unit)? { - return when (id) { - TlvId.CardId -> { callback -> ScanAction().executeMainAction(payload, attrs, callback) } - else -> null - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteUserProtectedDataAction.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteUserProtectedDataAction.kt deleted file mode 100644 index e315107b8b..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/actions/WriteUserProtectedDataAction.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.tangem.devkit.ucase.domain.actions - -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.findItem -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.variants.TlvId -import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf - - -class WriteUserProtectedDataAction : BaseAction() { - override fun executeMainAction(payload: PayloadHolder, attrs: AttrForAction, callback: ActionCallback) { - val protectedUserData = (attrs.itemList.findItem(TlvId.ProtectedUserData)?.getData() as? String)?.toByteArray() - ?: return - val cardId = attrs.itemList.findItem(TlvId.CardId)?.viewModel?.data ?: return - val counter = (attrs.itemList.findItem(TlvId.Counter)?.viewModel?.data as? Int) ?: 1 - - attrs.tangemSdk.writeProtectedUserData(stringOf(cardId), protectedUserData, counter) { - handleResult(payload, it, null, attrs, callback) - } - } - - override fun getActionByTag(payload: PayloadHolder, id: Id, attrs: AttrForAction): ((ActionCallback) -> Unit)? { - return when (id) { - TlvId.CardId -> { callback -> ScanAction().executeMainAction(payload, attrs, callback) } - else -> null - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/ItemsManager.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/ItemsManager.kt deleted file mode 100644 index 35022b0af4..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/ItemsManager.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.tangem.devkit.ucase.domain.paramsManager - -import com.tangem.TangemSdk -import com.tangem.common.CompletionResult -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.Payload -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.Item -import com.tangem.devkit.ucase.domain.paramsManager.triggers.changeConsequence.ItemsChangeConsequence - -typealias ActionResponse = CompletionResult<*> -typealias AffectedList = List -typealias AffectedItemsCallback = (AffectedList) -> Unit -typealias ActionCallback = (ActionResponse, AffectedList) -> Unit - -/** -[REDACTED_AUTHOR] - */ -interface ItemsManager : PayloadHolder { - - fun itemChanged(id: Id, value: Any?, callback: AffectedItemsCallback? = null) - fun setItems(items: List) - fun getItems(): List - fun setItemChangeConsequences(consequence: ItemsChangeConsequence?) - fun invokeMainAction(tangemSdk: TangemSdk, callback: ActionCallback) - fun getActionByTag(id: Id, tangemSdk: TangemSdk): ((ActionCallback) -> Unit)? - fun attachPayload(payload: Payload) - fun updateByItemList(list: List) -} - -interface PayloadKey { - companion object { - val cardConfig: String = "cardConfig" - val incomingJson: String = "incomingJson" - val card = "card" - val actionView = "actionView" - val itemList = "itemList" - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/managers/BaseItemsManager.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/managers/BaseItemsManager.kt deleted file mode 100644 index 7fcba9d02c..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/managers/BaseItemsManager.kt +++ /dev/null @@ -1,74 +0,0 @@ -package com.tangem.devkit.ucase.domain.paramsManager.managers - -import androidx.lifecycle.LifecycleObserver -import com.tangem.TangemSdk -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.Payload -import com.tangem.devkit._arch.structure.abstraction.Item -import com.tangem.devkit._arch.structure.abstraction.findItem -import com.tangem.devkit._arch.structure.abstraction.iterate -import com.tangem.devkit.ucase.domain.actions.Action -import com.tangem.devkit.ucase.domain.actions.AttrForAction -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.domain.paramsManager.AffectedItemsCallback -import com.tangem.devkit.ucase.domain.paramsManager.ItemsManager -import com.tangem.devkit.ucase.domain.paramsManager.triggers.changeConsequence.ItemsChangeConsequence -import ru.dev.gbixahue.eu4d.lib.android.global.log.Log - -/** -[REDACTED_AUTHOR] - */ -open class BaseItemsManager(protected val action: Action) : ItemsManager, LifecycleObserver { - - init { - Log.d(this, "new instance created") - } - - override val payload: MutableMap = mutableMapOf() - - protected var changeConsequence: ItemsChangeConsequence? = null - protected val itemList: MutableList = mutableListOf() - - override fun itemChanged(id: Id, value: Any?, callback: AffectedItemsCallback?) { - if (itemList.isEmpty()) return - val foundItem = itemList.findItem(id) ?: return - - foundItem.setData(value) - applyChangesByAffectedItems(foundItem, callback) - } - - override fun setItems(items: List) { - itemList.clear() - itemList.addAll(items) - } - - override fun getItems(): List = itemList - - override fun setItemChangeConsequences(consequence: ItemsChangeConsequence?) { - this.changeConsequence = consequence - } - - override fun updateByItemList(list: List) { - list.iterate { itemList.findItem(it.id)?.update(it) } - } - - override fun invokeMainAction(tangemSdk: TangemSdk, callback: ActionCallback) { - action.executeMainAction(this, getAttrsForAction(tangemSdk), callback) - } - - override fun getActionByTag(id: Id, tangemSdk: TangemSdk): ((ActionCallback) -> Unit)? { - return action.getActionByTag(this, id, getAttrsForAction(tangemSdk)) - } - - override fun attachPayload(payload: Payload) { - payload.forEach { this.payload[it.key] = it.value } - } - - // Use it if current item needs to be affect any other items - protected open fun applyChangesByAffectedItems(param: Item, callback: AffectedItemsCallback?) { - changeConsequence?.affectChanges(this, param, itemList)?.let { callback?.invoke(it) } - } - - protected fun getAttrsForAction(tangemSdk: TangemSdk) - : AttrForAction = AttrForAction(tangemSdk, itemList, payload, changeConsequence) -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/managers/PersonalizationItemsManager.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/managers/PersonalizationItemsManager.kt deleted file mode 100644 index a8125f2a51..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/managers/PersonalizationItemsManager.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.tangem.devkit.ucase.domain.paramsManager.managers - -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.OnLifecycleEvent -import com.tangem.TangemSdk -import com.tangem.devkit.commons.Store -import com.tangem.devkit.ucase.domain.actions.PersonalizeAction -import com.tangem.devkit.ucase.domain.paramsManager.ActionCallback -import com.tangem.devkit.ucase.variants.personalize.converter.PersonalizationConfigConverter -import com.tangem.devkit.ucase.variants.personalize.dto.PersonalizationConfig - -/** -[REDACTED_AUTHOR] - */ -class PersonalizationItemsManager( - private val store: Store -) : BaseItemsManager(PersonalizeAction()) { - - private val converter = PersonalizationConfigConverter() - - init { - val config = store.restore() - setItems(converter.convert(config)) - } - - override fun invokeMainAction(tangemSdk: TangemSdk, callback: ActionCallback) { - action.executeMainAction(this, getAttrsForAction(tangemSdk), callback) - } - - @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) - fun onDestroy() { - val config = converter.convert(itemList, PersonalizationConfig.default()) - store.save(config) - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/managers/SimpleManagers.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/managers/SimpleManagers.kt deleted file mode 100644 index 350a72b9f1..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/managers/SimpleManagers.kt +++ /dev/null @@ -1,107 +0,0 @@ -package com.tangem.devkit.ucase.domain.paramsManager.managers - -import com.tangem.devkit._arch.structure.impl.EditTextItem -import com.tangem.devkit.ucase.domain.actions.* -import com.tangem.devkit.ucase.domain.paramsManager.triggers.changeConsequence.CardIdConsequence -import com.tangem.devkit.ucase.variants.TlvId - -/** -[REDACTED_AUTHOR] - */ -class ScanItemsManager : BaseItemsManager(ScanAction()) - -class DepersonalizeItemsManager : BaseItemsManager(DepersonalizeAction()) - -class SignItemsManager : BaseItemsManager(SignAction()) { - - init { - setItemChangeConsequences(CardIdConsequence()) - setItems(listOf( - EditTextItem(TlvId.CardId, null), - EditTextItem(TlvId.TransactionOutHash, "Data used for hashing") - )) - } -} - -class CreateWalletItemsManager : BaseItemsManager(CreateWalletAction()) { - - init { - setItemChangeConsequences(CardIdConsequence()) - setItems(listOf(EditTextItem(TlvId.CardId, null))) - } -} - -class PurgeWalletItemsManager : BaseItemsManager(PurgeWalletAction()) { - - init { - setItemChangeConsequences(CardIdConsequence()) - setItems(listOf(EditTextItem(TlvId.CardId, null))) - } -} - -class ReadIssuerDataItemsManager : BaseItemsManager(ReadIssuerDataAction()) { - - init { - setItemChangeConsequences(CardIdConsequence()) - setItems(listOf(EditTextItem(TlvId.CardId, null))) - } -} - -class WriteIssuerDataItemsManager : BaseItemsManager(WriteIssuerDataAction()) { - init { - setItemChangeConsequences(CardIdConsequence()) - setItems(listOf( - EditTextItem(TlvId.CardId, null), - EditTextItem(TlvId.IssuerData, "Data to be written on a card as issuer data"), - EditTextItem(TlvId.Counter, "1") - )) - } -} - -class ReadIssuerExtraDataItemsManager : BaseItemsManager(ReadIssuerExtraDataAction()) { - - init { - setItemChangeConsequences(CardIdConsequence()) - setItems(listOf(EditTextItem(TlvId.CardId, null))) - } -} - -class WriteIssuerExtraDataItemsManager : BaseItemsManager(WriteIssuerExtraDataAction()) { - init { - setItemChangeConsequences(CardIdConsequence()) - setItems(listOf( - EditTextItem(TlvId.CardId, null), - EditTextItem(TlvId.Counter, "1") - )) - } -} - -class ReadUserDataItemsManager : BaseItemsManager(ReadUserDataAction()) { - - init { - setItemChangeConsequences(CardIdConsequence()) - setItems(listOf(EditTextItem(TlvId.CardId, null))) - } -} - -class WriteUserDataItemsManager : BaseItemsManager(WriteUserDataAction()) { - init { - setItemChangeConsequences(CardIdConsequence()) - setItems(listOf( - EditTextItem(TlvId.CardId, null), - EditTextItem(TlvId.Counter, "1"), - EditTextItem(TlvId.UserData, "User data to be written on a card") - )) - } -} - - class WriteProtectedUserDataItemsManager : BaseItemsManager(WriteUserProtectedDataAction()) { - init { - setItemChangeConsequences(CardIdConsequence()) - setItems(listOf( - EditTextItem(TlvId.CardId, null), - EditTextItem(TlvId.Counter, "1"), - EditTextItem(TlvId.ProtectedUserData, "Protected user data to be written on a card") - )) - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/triggers/afterAction/AfterActionModifiers.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/triggers/afterAction/AfterActionModifiers.kt deleted file mode 100644 index 74940b79d1..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/triggers/afterAction/AfterActionModifiers.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.tangem.devkit.ucase.domain.paramsManager.triggers.afterAction - -import com.tangem.common.CompletionResult -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.Item - -/** -[REDACTED_AUTHOR] - * - * The After Action Modification class family is intended for modifying items (if necessary) - * after calling CardManager.anyAction. - * Returns a list of items that have been modified - */ -interface AfterActionModification { - fun modify(payload: PayloadHolder, commandResult: CompletionResult<*>, itemList: List): List -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/triggers/afterAction/AfterScanModifier.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/triggers/afterAction/AfterScanModifier.kt deleted file mode 100644 index 219f6a72c9..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/triggers/afterAction/AfterScanModifier.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.tangem.devkit.ucase.domain.paramsManager.triggers.afterAction - -import com.tangem.commands.Card -import com.tangem.commands.CardStatus -import com.tangem.common.CompletionResult -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.Item -import com.tangem.devkit._arch.structure.abstraction.findItem -import com.tangem.devkit.ucase.domain.paramsManager.PayloadKey -import com.tangem.devkit.ucase.tunnel.ActionView -import com.tangem.devkit.ucase.tunnel.CardError -import com.tangem.devkit.ucase.variants.TlvId - -import ru.dev.gbixahue.eu4d.lib.android.global.threading.postUI - -/** -[REDACTED_AUTHOR] - */ -class AfterScanModifier : AfterActionModification { - override fun modify(payload: PayloadHolder, commandResult: CompletionResult<*>, itemList: List): List { - val foundItem = itemList.findItem(TlvId.CardId) ?: return listOf() - val card = smartCast(commandResult) ?: return listOf() - val actionView = payload.get(PayloadKey.actionView) as? ActionView ?: return listOf() - - return if (isNotPersonalized(card)) { - actionView.showSnackbar(CardError.NotPersonalized) - postUI { actionView.enableActionFab(false) } - listOf() - } else { - payload.set(PayloadKey.card, card) - foundItem.setData(card.cardId) - postUI { actionView.enableActionFab(true) } - listOf(foundItem) - } - } - - private fun smartCast(commandResult: CompletionResult<*>): Card? { - return (commandResult as? CompletionResult.Success)?.data - } - - private fun isNotPersonalized(card: Card): Boolean = card.status == CardStatus.NotPersonalized -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/triggers/changeConsequence/ParamChangeConsequence.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/triggers/changeConsequence/ParamChangeConsequence.kt deleted file mode 100644 index 6da18ea8b7..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/domain/paramsManager/triggers/changeConsequence/ParamChangeConsequence.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.tangem.devkit.ucase.domain.paramsManager.triggers.changeConsequence - -import com.tangem.devkit._arch.structure.PayloadHolder -import com.tangem.devkit._arch.structure.abstraction.Item -import com.tangem.devkit.ucase.domain.paramsManager.PayloadKey -import com.tangem.devkit.ucase.tunnel.ActionView -import com.tangem.devkit.ucase.variants.TlvId -import ru.dev.gbixahue.eu4d.lib.android.global.threading.postUI - -/** -[REDACTED_AUTHOR] - * - * The ParamsChangeConsequence class family modifies parameters depending on the state - * of the incoming parameter - */ -interface ItemsChangeConsequence { - fun affectChanges(payload: PayloadHolder, changedItem: Item, itemList: List): List -} - -class CardIdConsequence : ItemsChangeConsequence { - - override fun affectChanges(payload: PayloadHolder, changedItem: Item, itemList: List): List { - val affectedList = mutableListOf() - if (changedItem.id != TlvId.CardId) return affectedList - - val cidDataIsNull = changedItem.getData() == null - postUI { (payload.get(PayloadKey.actionView) as? ActionView)?.enableActionFab(!cidDataIsNull) } - return affectedList - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/Ids.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/Ids.kt deleted file mode 100644 index 90e2d54588..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/Ids.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.tangem.devkit.ucase.resources - -import com.tangem.devkit._arch.structure.Id - -/** -[REDACTED_AUTHOR] - */ -enum class ActionType : Id { - Scan, - Sign, - CreateWallet, - PurgeWallet, - ReadIssuerData, - WriteIssuerData, - ReadIssuerExData, - WriteIssuerExData, - ReadUserData, - WriteUserData, - WriteProtectedUserData, - Personalize, - Depersonalize, - Unknown, -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/MainResourceHolder.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/MainResourceHolder.kt deleted file mode 100644 index e62d993f69..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/MainResourceHolder.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.tangem.devkit.ucase.resources - -import com.tangem.devkit.AppTangemDemo -import com.tangem.devkit.R -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.StringId -import com.tangem.devkit._arch.structure.StringResId -import com.tangem.devkit.ucase.resources.initializers.ActionResources -import com.tangem.devkit.ucase.resources.initializers.PersonalizationResources -import com.tangem.devkit.ucase.resources.initializers.ResponseResources -import com.tangem.devkit.ucase.resources.initializers.TlvResources -import ru.dev.gbixahue.eu4d.lib.kotlin.common.BaseTypedHolder - -/** -[REDACTED_AUTHOR] - */ -open class ResourceHolder : BaseTypedHolder() - -object MainResourceHolder : ResourceHolder() { - init { - PersonalizationResources().init(this) - ActionResources().init(this) - TlvResources().init(this) - ResponseResources().init(this) - } - - override fun get(type: Id): Resources? { - return when(type) { - is StringId -> getResourcesFromName(type.value) - is StringResId -> Resources(type.value) - else -> super.get(type) - } - } - - private fun getResourcesFromName(resName: String): Resources? { - val context = AppTangemDemo.appInstance.applicationContext - val resNameId = context.resources.getIdentifier(resName, "string", context.packageName) - val resInfoId = context.resources.getIdentifier("info_$resName", "string", context.packageName) - if (resNameId == 0) return null - - return Resources(resNameId, if (resInfoId == 0) null else resInfoId) - } - - inline fun safeGet(id: Id): Res { - val result = super.get(id) ?: Resources(R.string.unknown, R.string.unknown) - return result as Res - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/ResourseTypes.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/ResourseTypes.kt deleted file mode 100644 index 8ba64f087d..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/ResourseTypes.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.tangem.devkit.ucase.resources - -/** -[REDACTED_AUTHOR] - */ -open class Resources( - val resName: Int, - val resDescription: Int? = null -) - -class ActionRes( - resName: Int, - resDescription: Int? = null, - val resNavigation: Int? = null -) : Resources(resName, resDescription) \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/ActionResources.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/ActionResources.kt deleted file mode 100644 index 7ca4301b5f..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/ActionResources.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.tangem.devkit.ucase.resources.initializers - -import com.tangem.devkit.R -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit.ucase.resources.ActionRes -import com.tangem.devkit.ucase.resources.ActionType -import com.tangem.devkit.ucase.resources.ResourceHolder - -/** -[REDACTED_AUTHOR] - */ -class ActionResources { - - fun init(holder: ResourceHolder) { - holder.register(ActionType.Scan, ActionRes(R.string.action_card_scan, R.string.info_action_card_scan, R.id.action_nav_entry_point_to_nav_scan)) - holder.register(ActionType.Sign, ActionRes(R.string.action_card_sign, R.string.info_action_card_sign, R.id.action_nav_entry_point_to_nav_sign)) - holder.register(ActionType.Personalize, ActionRes(R.string.action_personalize, R.string.info_action_personalize, R.id.action_nav_entry_point_to_nav_personalize)) - holder.register(ActionType.Depersonalize, ActionRes(R.string.action_depersonalize, R.string.info_action_depersonalize, R.id.action_nav_entry_point_to_nav_depersonalize)) - holder.register(ActionType.CreateWallet, ActionRes(R.string.action_wallet_create, R.string.info_action_wallet_create, R.id.action_nav_entry_point_to_nav_wallet_create)) - holder.register(ActionType.PurgeWallet, ActionRes(R.string.action_wallet_purge, R.string.info_action_wallet_purge, R.id.action_nav_entry_point_to_nav_wallet_purge)) - holder.register(ActionType.ReadIssuerData, ActionRes(R.string.action_issuer_read_data, R.string.info_action_issuer_read_data, R.id.action_nav_entry_point_to_nav_issuer_read_data)) - holder.register(ActionType.WriteIssuerData, ActionRes(R.string.action_issuer_write_data, R.string.info_action_issuer_write_data, R.id.action_nav_entry_point_to_nav_issuer_write_data)) - holder.register(ActionType.ReadIssuerExData, ActionRes(R.string.action_issuer_read_ex_data, R.string.info_action_issuer_read_ex_data, R.id.action_nav_entry_point_to_nav_issuer_read_ex_data)) - holder.register(ActionType.WriteIssuerExData, ActionRes(R.string.action_issuer_write_ex_data, R.string.info_action_issuer_write_ex_data, R.id.action_nav_entry_point_to_nav_issuer_write_ex_data)) - holder.register(ActionType.ReadUserData, ActionRes(R.string.action_user_read_data, R.string.info_action_user_read_data, R.id.action_nav_entry_point_to_nav_user_read_data)) - holder.register(ActionType.WriteUserData, ActionRes(R.string.action_user_write_data, R.string.info_action_user_write_data, R.id.action_nav_entry_point_to_nav_user_write_data)) - holder.register(ActionType.WriteProtectedUserData, ActionRes(R.string.action_user_write_protected_data, R.string.info_action_user_write_protected_data, R.id.action_nav_entry_point_to_nav_user_write_protected_data)) -// holder.register(ActionType.Unknown, getIfNotContains()) - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/PersonalizationResources.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/PersonalizationResources.kt deleted file mode 100644 index 2319076b7b..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/PersonalizationResources.kt +++ /dev/null @@ -1,128 +0,0 @@ -package com.tangem.devkit.ucase.resources.initializers - -import com.tangem.devkit.R -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit.ucase.resources.ResourceHolder -import com.tangem.devkit.ucase.resources.Resources -import com.tangem.devkit.ucase.variants.personalize.* -import ru.dev.gbixahue.eu4d.lib.kotlin.common.TypedHolder - -/** -[REDACTED_AUTHOR] - */ -class PersonalizationResources() { - fun init(holder: ResourceHolder) { - initBlock(holder) - initCardNumber(holder) - initCommon(holder) - initSigningMethod(holder) - initSignHashExProp(holder) - initToken(holder) - initProductMask(holder) - initSettingsMask(holder) - initSettingsMaskProtocolEnc(holder) - initSettingsMaskNdef(holder) - initPins(holder) - } - - private fun initBlock(holder: TypedHolder) { - holder.register(BlockId.CardNumber, Resources(R.string.pers_block_card_number, R.string.info_pers_block_card_number)) - holder.register(BlockId.Common, Resources(R.string.pers_block_common, R.string.info_pers_block_common)) - holder.register(BlockId.SigningMethod, Resources(R.string.pers_block_signing_method, R.string.info_pers_block_signing_method)) - holder.register(BlockId.SignHashExProp, Resources(R.string.pers_block_sign_hash_ex_prop, R.string.info_pers_block_sign_hash_ex_prop)) - holder.register(BlockId.Denomination, Resources(R.string.pers_block_denomination, R.string.info_pers_block_denomination)) - holder.register(BlockId.Token, Resources(R.string.pers_block_token, R.string.info_pers_block_token)) - holder.register(BlockId.ProdMask, Resources(R.string.pers_block_product_mask, R.string.info_pers_block_product_mask)) - holder.register(BlockId.SettingsMask, Resources(R.string.pers_block_settings_mask, R.string.info_pers_block_settings_mask)) - holder.register(BlockId.SettingsMaskProtocolEnc, Resources(R.string.pers_block_settings_mask_protocol_enc, R.string.info_pers_block_settings_mask_protocol_enc)) - holder.register(BlockId.SettingsMaskNdef, Resources(R.string.pers_block_settings_mask_ndef, R.string.info_pers_block_settings_mask_ndef)) - holder.register(BlockId.Pins, Resources(R.string.pers_block_pins, R.string.info_pers_block_pins)) - } - - private fun initCardNumber(holder: TypedHolder) { - holder.register(CardNumberId.Series, Resources(R.string.pers_item_series, R.string.info_pers_item_series)) - holder.register(CardNumberId.Number, Resources(R.string.pers_item_number, R.string.info_pers_item_number)) - holder.register(CardNumberId.BatchId, Resources(R.string.pers_item_batch_id, R.string.info_pers_item_batch_id)) - } - - private fun initCommon(holder: TypedHolder) { - holder.register(CommonId.Curve, Resources(R.string.pers_item_curve, R.string.info_pers_item_curve)) - holder.register(CommonId.Blockchain, Resources(R.string.pers_item_blockchain, R.string.info_pers_item_blockchain)) - holder.register(CommonId.BlockchainCustom, Resources(R.string.pers_item_custom_blockchain, R.string.info_pers_item_custom_blockchain)) - holder.register(CommonId.MaxSignatures, Resources(R.string.pers_item_max_signatures, R.string.info_pers_item_max_signatures)) - holder.register(CommonId.CreateWallet, Resources(R.string.pers_item_create_wallet, R.string.info_pers_item_create_wallet)) - } - - private fun initSigningMethod(holder: TypedHolder) { - holder.register(SigningMethodId.SignTx, Resources(R.string.pers_item_sign_tx_hashes, R.string.info_pers_item_sign_tx_hashes)) - holder.register(SigningMethodId.SignTxRaw, Resources(R.string.pers_item_sign_raw_tx, R.string.info_pers_item_sign_raw_tx)) - holder.register(SigningMethodId.SignValidatedTx, Resources(R.string.pers_item_sign_validated_tx_hashes, R.string.info_pers_item_sign_validated_tx_hashes)) - holder.register(SigningMethodId.SignValidatedTxRaw, Resources(R.string.pers_item_sign_validated_raw_tx, R.string.info_pers_item_sign_validated_raw_tx)) - holder.register(SigningMethodId.SignValidatedTxIssuer, Resources(R.string.pers_item_sign_validated_tx_hashes_with_iss_data, R.string.info_pers_item_sign_validated_tx_hashes_with_iss_data)) - holder.register(SigningMethodId.SignValidatedTxRawIssuer, Resources(R.string.pers_item_sign_validated_raw_tx_with_iss_data, R.string.info_pers_item_sign_validated_raw_tx_with_iss_data)) - holder.register(SigningMethodId.SignExternal, Resources(R.string.pers_item_sign_hash_ex, R.string.info_pers_item_sign_hash_ex)) - } - - private fun initSignHashExProp(holder: TypedHolder) { - holder.register(SignHashExPropId.PinLessFloorLimit, Resources(R.string.pers_item_pin_less_floor_limit, R.string.info_pers_item_pin_less_floor_limit)) - holder.register(SignHashExPropId.CryptoExKey, Resources(R.string.pers_item_cr_ex_key, R.string.info_pers_item_cr_ex_key)) - holder.register(SignHashExPropId.RequireTerminalCertSig, Resources(R.string.pers_item_require_terminal_cert_sig, R.string.info_pers_item_require_terminal_cert_sig)) - holder.register(SignHashExPropId.RequireTerminalTxSig, Resources(R.string.pers_item_require_terminal_tx_sig, R.string.info_pers_item_require_terminal_tx_sig)) - holder.register(SignHashExPropId.CheckPin3, Resources(R.string.pers_item_check_pin3_on_card, R.string.info_pers_item_check_pin3_on_card)) - } - - private fun initToken(holder: TypedHolder) { - holder.register(TokenId.ItsToken, Resources(R.string.pers_item_its_token, R.string.info_pers_item_its_token)) - holder.register(TokenId.Symbol, Resources(R.string.pers_item_symbol, R.string.info_pers_item_symbol)) - holder.register(TokenId.ContractAddress, Resources(R.string.pers_item_contract_address, R.string.info_pers_item_contract_address)) - holder.register(TokenId.Decimal, Resources(R.string.pers_item_decimal, R.string.info_pers_item_decimal)) - } - - private fun initProductMask(holder: TypedHolder) { - holder.register(ProductMaskId.Note, Resources(R.string.pers_item_note, R.string.info_pers_item_note)) - holder.register(ProductMaskId.Tag, Resources(R.string.pers_item_tag, R.string.info_pers_item_tag)) - holder.register(ProductMaskId.IdCard, Resources(R.string.pers_item_id_card, R.string.info_pers_item_id_card)) - holder.register(ProductMaskId.IdIssuerCard, Resources(R.string.pers_item_id_issuer_card, R.string.info_pers_item_id_issuer_card)) - } - - private fun initSettingsMask(holder: TypedHolder) { - holder.register(SettingsMaskId.IsReusable, Resources(R.string.pers_item_is_reusable, R.string.info_pers_item_is_reusable)) - holder.register(SettingsMaskId.NeedActivation, Resources(R.string.pers_item_need_activation, R.string.info_pers_item_need_activation)) - holder.register(SettingsMaskId.ForbidPurge, Resources(R.string.pers_item_forbid_purge, R.string.info_pers_item_forbid_purge)) - holder.register(SettingsMaskId.AllowSelectBlockchain, Resources(R.string.pers_item_allow_select_blockchain, R.string.info_pers_item_allow_select_blockchain)) - holder.register(SettingsMaskId.UseBlock, Resources(R.string.pers_item_use_block, R.string.info_pers_item_use_block)) - holder.register(SettingsMaskId.OneApdu, Resources(R.string.pers_item_one_apdu_at_once, R.string.info_pers_item_one_apdu_at_once)) - holder.register(SettingsMaskId.UseCvc, Resources(R.string.pers_item_use_cvc, R.string.info_pers_item_use_cvc)) - holder.register(SettingsMaskId.AllowSwapPin, Resources(R.string.pers_item_allow_swap_pin, R.string.info_pers_item_allow_swap_pin)) - holder.register(SettingsMaskId.AllowSwapPin2, Resources(R.string.pers_item_allow_swap_pin2, R.string.info_pers_item_allow_swap_pin2)) - holder.register(SettingsMaskId.ForbidDefaultPin, Resources(R.string.pers_item_forbid_default_pin, R.string.info_pers_item_forbid_default_pin)) - holder.register(SettingsMaskId.SmartSecurityDelay, Resources(R.string.pers_item_smart_security_delay, R.string.info_pers_item_smart_security_delay)) - holder.register(SettingsMaskId.ProtectIssuerDataAgainstReplay, Resources(R.string.pers_item_protect_issuer_data_against_replay, R.string.info_pers_item_protect_issuer_data_against_replay)) - holder.register(SettingsMaskId.SkipSecurityDelayIfValidated, Resources(R.string.pers_item_skip_security_delay_if_validated, R.string.info_pers_item_skip_security_delay_if_validated)) - holder.register(SettingsMaskId.SkipPin2CvcIfValidated, Resources(R.string.pers_item_skip_pin2_and_cvc_if_validated, R.string.info_pers_item_skip_pin2_and_cvc_if_validated)) - holder.register(SettingsMaskId.SkipSecurityDelayOnLinkedTerminal, Resources(R.string.pers_item_skip_security_delay_on_linked_terminal, R.string.info_pers_item_skip_security_delay_on_linked_terminal)) - holder.register(SettingsMaskId.RestrictOverwriteExtraIssuerData, Resources(R.string.pers_item_restrict_overwrite_ex_issuer_data, R.string.info_pers_item_restrict_overwrite_ex_issuer_data)) - } - - private fun initSettingsMaskProtocolEnc(holder: TypedHolder) { - holder.register(SettingsMaskProtocolEncId.AllowUnencrypted, Resources(R.string.pers_item_allow_unencrypted, R.string.info_pers_item_allow_unencrypted)) - holder.register(SettingsMaskProtocolEncId.AllowStaticEncryption, Resources(R.string.pers_item_allow_fast_encryption, R.string.info_pers_item_allow_fast_encryption)) - } - - private fun initSettingsMaskNdef(holder: TypedHolder) { - holder.register(SettingsMaskNdefId.UseNdef, Resources(R.string.pers_item_use_ndef, R.string.info_pers_item_use_ndef)) - holder.register(SettingsMaskNdefId.DynamicNdef, Resources(R.string.pers_item_dynamic_ndef, R.string.info_pers_item_dynamic_ndef)) - holder.register(SettingsMaskNdefId.DisablePrecomputedNdef, Resources(R.string.pers_item_disable_precomputed_ndef, R.string.info_pers_item_disable_precomputed_ndef)) - holder.register(SettingsMaskNdefId.Aar, Resources(R.string.pers_item_aar, R.string.info_pers_item_aar)) - holder.register(SettingsMaskNdefId.AarCustom, Resources(R.string.pers_item_custom_aar_package_name, R.string.info_pers_item_custom_aar_package_name)) - holder.register(SettingsMaskNdefId.Uri, Resources(R.string.pers_item_uri, R.string.info_pers_item_uri)) - } - - private fun initPins(holder: TypedHolder) { - holder.register(PinsId.Pin, Resources(R.string.pers_item_pin, R.string.info_pers_item_pin)) - holder.register(PinsId.Pin2, Resources(R.string.pers_item_pin2, R.string.info_pers_item_pin2)) - holder.register(PinsId.Pin3, Resources(R.string.pers_item_pin3, R.string.info_pers_item_pin3)) - holder.register(PinsId.Cvc, Resources(R.string.pers_item_cvc, R.string.info_pers_item_cvc)) - holder.register(PinsId.PauseBeforePin2, Resources(R.string.pers_item_pause_before_pin2, R.string.info_pers_item_pause_before_pin2)) - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/ResponseResources.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/ResponseResources.kt deleted file mode 100644 index 792a4ee0cb..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/ResponseResources.kt +++ /dev/null @@ -1,114 +0,0 @@ -package com.tangem.devkit.ucase.resources.initializers - -import com.tangem.devkit.R -import com.tangem.devkit.ucase.resources.MainResourceHolder -import com.tangem.devkit.ucase.resources.Resources -import com.tangem.devkit.ucase.variants.responses.* - -/** -[REDACTED_AUTHOR] - */ -class ResponseResources { - fun init(holder: MainResourceHolder) { - initCard(holder) - initCardData(holder) - initSignResponse(holder) - initDepersonalizeResponse(holder) - initCreateWalletResponse(holder) - initPurgeWalletResponse(holder) - initReadIssuerDataResponse(holder) - initWriteIssuerDataResponse(holder) - initReadIssuerExtraDataResponse(holder) - initReadUserDataResponse(holder) - initWriteUserDataResponse(holder) - } - - private fun initCard(holder: MainResourceHolder) { - holder.register(CardId.cardId, Resources(R.string.response_card_cid, R.string.info_response_card_cid)) - holder.register(CardId.manufacturerName, Resources(R.string.response_card_manufacturer_name, R.string.info_response_card_manufacturer_name)) - holder.register(CardId.status, Resources(R.string.response_card_status, R.string.info_response_card_status)) - holder.register(CardId.firmwareVersion, Resources(R.string.response_card_firmware_version, R.string.info_response_card_firmware_version)) - holder.register(CardId.cardPublicKey, Resources(R.string.response_card_public_key, R.string.info_response_card_public_key)) - holder.register(CardId.settingsMask, Resources(R.string.response_card_settings_mask, R.string.info_response_card_settings_mask)) - holder.register(CardId.cardData, Resources(R.string.response_card_card_data, R.string.info_response_card_card_data)) - holder.register(CardId.issuerPublicKey, Resources(R.string.response_card_issuer_data_public_key, R.string.info_response_card_issuer_data_public_key)) - holder.register(CardId.curve, Resources(R.string.response_card_curve, R.string.info_response_card_curve)) - holder.register(CardId.maxSignatures, Resources(R.string.response_card_max_signatures, R.string.info_response_card_max_signatures)) - holder.register(CardId.signingMethod, Resources(R.string.response_card_signing_method, R.string.info_response_card_signing_method)) - holder.register(CardId.pauseBeforePin2, Resources(R.string.response_card_pause_before_pin2, R.string.info_response_card_allow_pin2)) - holder.register(CardId.walletPublicKey, Resources(R.string.response_card_wallet_public_key, R.string.info_response_card_wallet_public_key)) - holder.register(CardId.walletRemainingSignatures, Resources(R.string.response_card_wallet_remaining_signatures, R.string.info_response_card_wallet_remaining_signatures)) - holder.register(CardId.walletSignedHashes, Resources(R.string.response_card_wallet_signed_hashes, R.string.info_response_card_wallet_signed_hashes)) - holder.register(CardId.health, Resources(R.string.response_card_health, R.string.info_response_card_health)) - holder.register(CardId.isActivated, Resources(R.string.response_card_is_activated, R.string.info_response_card_is_activated)) - holder.register(CardId.activationSeed, Resources(R.string.response_card_activation_seed, R.string.info_response_card_activation_seed)) - holder.register(CardId.paymentFlowVersion, Resources(R.string.response_card_payment_flow_version, R.string.info_response_card_payment_flow_version)) - holder.register(CardId.userCounter, Resources(R.string.response_card_user_counter, R.string.info_response_card_user_counter)) - holder.register(CardId.userProtectedCounter, Resources(R.string.response_card_user_protected_counter, R.string.info_response_card_user_protected_counter)) - } - - private fun initCardData(holder: MainResourceHolder) { - holder.register(CardDataId.batchId, Resources(R.string.response_card_card_data_batch_id, R.string.info_response_card_card_data_batch_id)) - holder.register(CardDataId.manufactureDateTime, Resources(R.string.response_card_card_data_manufacture_date_time, R.string.info_response_card_card_data_manufacture_date_time)) - holder.register(CardDataId.issuerName, Resources(R.string.response_card_card_data_issuer_name, R.string.info_response_card_card_data_issuer_name)) - holder.register(CardDataId.blockchainName, Resources(R.string.response_card_card_data_blockchain_name, R.string.info_response_card_card_data_blockchain_name)) - holder.register(CardDataId.manufacturerSignature, Resources(R.string.response_card_card_data_manufacturer_signature, R.string.info_response_card_card_data_manufacturer_signature)) - holder.register(CardDataId.productMask, Resources(R.string.response_card_card_data_product_mask, R.string.info_response_card_card_data_product_mask)) - holder.register(CardDataId.tokenSymbol, Resources(R.string.response_card_card_data_token_symbol, R.string.info_response_card_card_data_token_symbol)) - holder.register(CardDataId.tokenContractAddress, Resources(R.string.response_card_card_data_token_contract_address, R.string.info_response_card_card_data_token_contract_address)) - holder.register(CardDataId.tokenDecimal, Resources(R.string.response_card_card_data_token_decimal, R.string.info_response_card_card_data_token_decimal)) - } - - private fun initSignResponse(holder: MainResourceHolder) { - holder.register(SignId.cid, Resources(R.string.response_sign_cid, R.string.info_response_sign_cid)) - holder.register(SignId.walletSignedHashes, Resources(R.string.response_sign_wallet_signed_hashes, R.string.info_response_sign_wallet_signed_hashes)) - holder.register(SignId.walletRemainingSignatures, Resources(R.string.response_sign_wallet_remaining_signatures, R.string.info_response_sign_wallet_remaining_signatures)) - holder.register(SignId.signature, Resources(R.string.response_sign_signature, R.string.info_response_sign_signature)) - } - - private fun initDepersonalizeResponse(holder: MainResourceHolder) { - holder.register(DepersonalizeId.isSuccess, Resources(R.string.response_depersonalize_is_success, R.string.info_response_depersonalize_is_success)) - } - - private fun initCreateWalletResponse(holder: MainResourceHolder) { - holder.register(CreateWalletId.cid, Resources(R.string.response_card_cid, R.string.info_response_card_cid)) - holder.register(CreateWalletId.cardStatus, Resources(R.string.response_card_status, R.string.info_response_card_status)) - holder.register(CreateWalletId.walletPublicKey, Resources(R.string.response_card_wallet_public_key, R.string.info_response_card_wallet_public_key)) - } - - private fun initPurgeWalletResponse(holder: MainResourceHolder) { - holder.register(PurgeWalletId.cid, Resources(R.string.response_card_cid, R.string.info_response_card_cid)) - holder.register(PurgeWalletId.cardStatus, Resources(R.string.response_card_status, R.string.info_response_card_status)) - } - - private fun initReadIssuerDataResponse(holder: MainResourceHolder) { - holder.register(ReadIssuerDataId.cid, Resources(R.string.response_card_cid, R.string.info_response_card_cid)) - holder.register(ReadIssuerDataId.issuerData, Resources(R.string.response_issuer_data, R.string.info_response_issuer_data)) - holder.register(ReadIssuerDataId.issuerDataSignature, Resources(R.string.response_issuer_data_signature, R.string.info_response_issuer_data_signature)) - holder.register(ReadIssuerDataId.issuerDataCounter, Resources(R.string.response_issuer_data_counter, R.string.info_response_issuer_data_counter)) - } - - private fun initWriteIssuerDataResponse(holder: MainResourceHolder) { - holder.register(ReadIssuerDataId.cid, Resources(R.string.response_card_cid, R.string.info_response_card_cid)) - } - - private fun initReadIssuerExtraDataResponse(holder: MainResourceHolder) { - holder.register(ReadIssuerExtraDataId.cid, Resources(R.string.response_card_cid, R.string.info_response_card_cid)) - holder.register(ReadIssuerExtraDataId.size, Resources(R.string.response_issuer_data_size, R.string.info_response_issuer_data_size)) - holder.register(ReadIssuerExtraDataId.issuerData, Resources(R.string.response_issuer_data, R.string.info_response_issuer_data)) - holder.register(ReadIssuerExtraDataId.issuerDataSignature, Resources(R.string.response_issuer_data_signature, R.string.info_response_issuer_data_signature)) - holder.register(ReadIssuerExtraDataId.issuerDataCounter, Resources(R.string.response_issuer_data_counter, R.string.info_response_issuer_data_counter)) - } - - private fun initReadUserDataResponse(holder: MainResourceHolder) { - holder.register(ReadUserDataId.cid, Resources(R.string.response_card_cid, R.string.info_response_card_cid)) - holder.register(ReadUserDataId.userData, Resources(R.string.response_user_data, R.string.info_response_user_data)) - holder.register(ReadUserDataId.userProtectedData, Resources(R.string.response_user_protected_data, R.string.info_response_user_protected_data)) - holder.register(ReadUserDataId.userCounter, Resources(R.string.response_user_data_counter, R.string.info_response_user_data_counter)) - holder.register(ReadUserDataId.userProtectedCounter, Resources(R.string.response_user_data_protected_counter, R.string.info_response_user_data_protected_counter)) - } - - private fun initWriteUserDataResponse(holder: MainResourceHolder) { - holder.register(ReadIssuerDataId.cid, Resources(R.string.response_card_cid, R.string.info_response_card_cid)) - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/TlvResources.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/TlvResources.kt deleted file mode 100644 index c7527b36ed..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/resources/initializers/TlvResources.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.tangem.devkit.ucase.resources.initializers - -import com.tangem.devkit.R -import com.tangem.devkit.ucase.resources.MainResourceHolder -import com.tangem.devkit.ucase.resources.Resources -import com.tangem.devkit.ucase.variants.TlvId - -/** -[REDACTED_AUTHOR] - */ -class TlvResources { - fun init(holder: MainResourceHolder) { - initScan(holder) - } - - private fun initScan(holder: MainResourceHolder) { - holder.register(TlvId.CardId, Resources(R.string.tlv_card_id, R.string.info_tlv_card_id)) - holder.register(TlvId.TransactionOutHash, Resources(R.string.tlv_transaction_out_hash, R.string.info_tlv_transaction_out_hash)) - holder.register(TlvId.Counter, Resources(R.string.tlv_counter, R.string.info_tlv_counter)) - holder.register(TlvId.IssuerData, Resources(R.string.tlv_issuer_data, R.string.info_tlv_issuer_data)) - holder.register(TlvId.UserData, Resources(R.string.tlv_user_data, R.string.info_tlv_user_data)) - holder.register(TlvId.ProtectedUserData, Resources(R.string.tlv_user_protected_data, R.string.info_tlv_protected_user_data)) - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/tunnel/Errors.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/tunnel/Errors.kt deleted file mode 100644 index 72cbde4699..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/tunnel/Errors.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.tangem.devkit.ucase.tunnel - -import com.tangem.devkit._arch.structure.Id - -/** -[REDACTED_AUTHOR] - */ -interface Errors : Id - -enum class CardError : Errors { - NotPersonalized, -} - -enum class ItemError : Errors { - BadSeries, - BadCardNumber, -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/tunnel/ViewScreen.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/tunnel/ViewScreen.kt deleted file mode 100644 index 64aa754c6b..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/tunnel/ViewScreen.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.tangem.devkit.ucase.tunnel - -import com.google.android.material.snackbar.Snackbar -import com.tangem.devkit._arch.structure.Id - -interface SnackbarHolder { - fun showSnackbar(message: String, length: Int = Snackbar.LENGTH_SHORT) - fun showSnackbar(id: Int, length: Int = Snackbar.LENGTH_SHORT) -} - -interface ViewScreen - -interface ActionView : ViewScreen, SnackbarHolder { - fun enableActionFab(enable: Boolean) - fun showSnackbar(id: Id, additionalHandler: ((Id) -> Int)? = null) -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/ActionViewModel.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/ActionViewModel.kt deleted file mode 100644 index 272bb11671..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/ActionViewModel.kt +++ /dev/null @@ -1,178 +0,0 @@ -package com.tangem.devkit.ucase.ui - -import android.view.View -import androidx.annotation.UiThread -import androidx.lifecycle.* -import com.google.gson.Gson -import com.tangem.TangemSdk -import com.tangem.TangemSdkError -import com.tangem.commands.Card -import com.tangem.commands.CommandResponse -import com.tangem.common.CompletionResult -import com.tangem.common.extensions.CardType -import com.tangem.devkit._arch.SingleLiveEvent -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.Payload -import com.tangem.devkit._arch.structure.abstraction.Item -import com.tangem.devkit._arch.structure.abstraction.iterate -import com.tangem.devkit.ucase.domain.paramsManager.ItemsManager -import com.tangem.devkit.ucase.resources.ActionType -import com.tangem.devkit.ucase.tunnel.ViewScreen -import com.tangem.devkit.ucase.variants.personalize.converter.ItemTypes -import ru.dev.gbixahue.eu4d.lib.android.global.log.Log -import java.util.* - -/** -[REDACTED_AUTHOR] - */ -class ActionViewModelFactory(private val manager: ItemsManager) : ViewModelProvider.NewInstanceFactory() { - override fun create(modelClass: Class): T = ActionViewModel(manager) as T -} - -class ActionViewModel(private val itemsManager: ItemsManager) : ViewModel(), LifecycleObserver { - - val seResponse = SingleLiveEvent() - val seResponseData = SingleLiveEvent() - val seResponseCardData = SingleLiveEvent() - - val ldItemList = MutableLiveData(itemsManager.getItems()) - val seError: MutableLiveData = SingleLiveEvent() - val seChangedItems: MutableLiveData> = SingleLiveEvent() - - private val notifier: Notifier = Notifier(this) - private lateinit var tangemSdk: TangemSdk - - fun setCardManager(tangemSdk: TangemSdk) { - this.tangemSdk = tangemSdk - this.tangemSdk.config.cardFilter.allowedCardTypes = EnumSet.of(CardType.Sdk) - } - - @Deprecated("Events must be send directly from the Widget") - fun userChangedItem(id: Id, value: Any?) { - itemChanged(id, value) - } - - private fun itemChanged(id: Id, value: Any?) { - itemsManager.itemChanged(id, value) { notifier.notifyItemsChanged(it) } - } - - //invokes Scan, Sign etc... - fun invokeMainAction() { - if (!::tangemSdk.isInitialized) { - Log.e(this, "TangemSdk isn't initialized") - return - } - itemsManager.invokeMainAction(tangemSdk) { response, listOfChangedParams -> - notifier.handleActionResult(response, listOfChangedParams) - } - } - - fun getItemAction(id: Id): (() -> Unit)? { - val itemFunction = itemsManager.getActionByTag(id, tangemSdk) ?: return null - - return { - itemFunction { response, listOfChangedParams -> - notifier.handleActionResult(response, listOfChangedParams) - } - } - } - - fun toggleDescriptionVisibility(state: Boolean) { - ldItemList.value?.iterate { - it.viewModel.viewState.descriptionVisibility.value = if (state) View.VISIBLE else View.GONE - } - } - - fun attachToPayload(payload: Payload) { - itemsManager.attachPayload(payload) - } - - @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) - fun viewOnDestroy() { - val keyList = mutableListOf() - itemsManager.payload.filterValues { it is ViewScreen }.forEach { keyList.add(it.key) } - keyList.forEach { itemsManager.payload.remove(it) } - } - - fun showFields(type: ActionType) { - toggleFieldsVisibility(type, true) - } - - fun hideFields(type: ActionType) { - toggleFieldsVisibility(type, false) - } - - private fun toggleFieldsVisibility(type: ActionType, show: Boolean) { - val oftenUsed = getItemsForTogglingVisibilityState(type) - val hidden = getItemIdsWhichWontShows(type) - itemsManager.getItems().iterate { - if (!hidden.contains(it.id)) { - if (!oftenUsed.contains(it.id)) { - it.viewModel.viewState.isVisibleState.value = show - } - } - - } - } - - private fun getItemsForTogglingVisibilityState(type: ActionType): List { - return when (type) { - ActionType.Personalize -> ItemTypes().oftenUsedList - else -> emptyList() - } - } - - private fun getItemIdsWhichWontShows(type: ActionType): List { - return when (type) { - ActionType.Personalize -> ItemTypes().hiddenList - else -> emptyList() - } - } -} - -internal class Notifier(private val vm: ActionViewModel) { - - private var notShowedError: TangemSdkError? = null - - fun handleActionResult(result: CompletionResult<*>, list: List) { - if (list.isNotEmpty()) notifyItemsChanged(list) - handleCompletionResult(result) - } - - @UiThread - fun notifyItemsChanged(list: List) { - vm.seChangedItems.postValue(list) - } - - fun handleCompletionResult(result: CompletionResult<*>) { - val commandResponse = result as? CompletionResult ?: return - - when (commandResponse) { - is CompletionResult.Success -> handleData(commandResponse.data) - is CompletionResult.Failure -> handleError(commandResponse.error) - } - } - - private fun handleData(event: CommandResponse?) { - vm.seResponse.postValue(event) - when (event) { - is Card -> vm.seResponseCardData.postValue(event) - else -> vm.seResponseData.postValue(event) - } - } - - private fun handleError(error: TangemSdkError) { - Log.d(this, "error = $error") - when (error) { - is TangemSdkError.UserCancelled -> { - if (notShowedError == null) { - vm.seError.postValue("User canceled the action") - } else { - vm.seError.postValue("${notShowedError!!::class.simpleName}") - notShowedError = null - } - } - else -> notShowedError = error - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/BaseCardActionFragment.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/BaseCardActionFragment.kt deleted file mode 100644 index 36cf46321e..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/BaseCardActionFragment.kt +++ /dev/null @@ -1,162 +0,0 @@ -package com.tangem.devkit.ucase.ui - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.core.view.plusAssign -import androidx.fragment.app.activityViewModels -import androidx.fragment.app.viewModels -import androidx.lifecycle.Observer -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout -import com.google.android.material.floatingactionbutton.FloatingActionButton -import com.tangem.TangemSdk -import com.tangem.commands.Card -import com.tangem.commands.CommandResponse -import com.tangem.devkit.R -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._main.MainViewModel -import com.tangem.devkit.ucase.domain.paramsManager.ItemsManager -import com.tangem.devkit.ucase.domain.paramsManager.PayloadKey -import com.tangem.devkit.ucase.tunnel.ActionView -import com.tangem.devkit.ucase.tunnel.CardError -import com.tangem.devkit.ucase.ui.widgets.ParameterWidget -import com.tangem.tangem_sdk_new.extensions.init -import ru.dev.gbixahue.eu4d.lib.android._android.views.enable -import ru.dev.gbixahue.eu4d.lib.android.global.log.Log - -/** -[REDACTED_AUTHOR] - */ -abstract class BaseCardActionFragment : BaseFragment(), ActionView { - - protected lateinit var swrLayout: SwipeRefreshLayout - protected lateinit var contentContainer: ViewGroup - protected lateinit var actionFab: FloatingActionButton - - protected abstract val itemsManager: ItemsManager - protected val mainActivityVM by activityViewModels() - protected val actionVM: ActionViewModel by viewModels { ActionViewModelFactory(itemsManager) } - protected val UNDEFINED = -1 - - private val paramsWidgetList = mutableListOf() - - override fun getLayoutId(): Int = R.layout.fg_base_action_layout - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - Log.d(this, "onViewCreated") - - bindViews() - viewLifecycleOwner.lifecycle.addObserver(actionVM) - actionVM.setCardManager(TangemSdk.init(requireActivity())) - actionVM.attachToPayload(mutableMapOf(PayloadKey.actionView to this as ActionView)) - - initViews() - createWidgets { - widgetsWasCreated() - subscribeToViewModelChanges() - } - } - - protected open fun widgetsWasCreated() {} - - protected open fun bindViews() { - swrLayout = mainView.findViewById(R.id.swr_layout) - contentContainer = mainView.findViewById(R.id.ll_content_container) - actionFab = mainView.findViewById(R.id.fab_action) - } - - protected open fun initViews() { - swrLayout.isEnabled = false - enableActionFab(false) - actionFab.setOnClickListener { actionVM.invokeMainAction() } - } - - protected open fun createWidgets(widgetCreatedCallback: () -> Unit) { - Log.d(this, "createWidgets") - actionVM.ldItemList.observe(viewLifecycleOwner, Observer { itemList -> - itemList.forEach { param -> - val widget = ParameterWidget(inflateParamView(contentContainer), param) - widget.onValueChanged = { id, value -> actionVM.userChangedItem(id, value) } - widget.onActionBtnClickListener = actionVM.getItemAction(param.id) - paramsWidgetList.add(widget) - } - widgetCreatedCallback() - }) - } - - protected open fun subscribeToViewModelChanges() { - Log.d(this, "subscribeToViewModelChanges") - actionVM.seResponse.observe(viewLifecycleOwner, Observer { - Log.d(this, "handle response: $it") - handleResponse(it) - }) - actionVM.seResponseData.observe(viewLifecycleOwner, Observer { - Log.d(this, "handle responseData: $it") - handleResponseData(it) - }) - actionVM.seResponseCardData.observe(viewLifecycleOwner, Observer { - Log.d(this, "handle responseCardData: $it") - handleResponseCardData(it) - }) - actionVM.seError.observe(viewLifecycleOwner, Observer { - Log.d(this, "handle error: $it") - handleError(it) - }) - mainActivityVM.ldDescriptionSwitch.observe(viewLifecycleOwner, Observer { - Log.d(this, "handle descriptionVisibilityState: $it") - handleDescriptionSwitchChanges(it) - }) - listenChangedItems() - } - - protected open fun handleResponse(response: CommandResponse) { - mainActivityVM.changeResponseEvent(response) - } - - protected open fun handleResponseData(response: CommandResponse) { - navigateTo(R.id.action_nav_card_action_to_response_screen, options = null) - } - - protected open fun handleResponseCardData(card: Card) {} - - protected open fun handleError(error: String) { - showSnackbar(error) - } - - protected open fun handleDescriptionSwitchChanges(descriptionVisibilityState: Boolean) { - actionVM.toggleDescriptionVisibility(descriptionVisibilityState) - paramsWidgetList.forEach { it.toggleDescriptionVisibility(descriptionVisibilityState) } - } - - @Deprecated("Start to use itemViewModel") - protected open fun listenChangedItems() { - actionVM.seChangedItems.observe(viewLifecycleOwner, Observer { itemList -> - itemList.forEach { item -> - Log.d(this, "item changed from VM - name: ${item.id}, value:${item.viewModel.data}") - paramsWidgetList.firstOrNull { it.id == item.id }?.changeParamValue(item.viewModel.data) - } - }) - } - - protected fun inflateParamView(where: ViewGroup): ViewGroup { - val inflater = LayoutInflater.from(where.context) - val view = inflater.inflate(R.layout.w_card_incoming_param, where, false) - where.plusAssign(view) - return view as ViewGroup - } - - override fun enableActionFab(enable: Boolean) { - actionFab.enable(enable) - } - - override fun showSnackbar(id: Id, additionalHandler: ((Id) -> Int)?) { - val resourceId = when (id) { - CardError.NotPersonalized -> R.string.card_error_not_personalized - else -> additionalHandler?.invoke(id) ?: UNDEFINED - } - - if (resourceId != UNDEFINED) showSnackbar(resourceId) - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/BaseFragment.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/BaseFragment.kt deleted file mode 100644 index e3b6f16cad..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/BaseFragment.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.tangem.devkit.ucase.ui - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.fragment.app.Fragment -import androidx.navigation.NavOptions -import androidx.navigation.fragment.NavHostFragment.findNavController -import com.google.android.material.snackbar.Snackbar -import com.tangem.devkit.ucase.getDefaultNavigationOptions -import com.tangem.devkit.ucase.tunnel.SnackbarHolder -import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder - -/** -[REDACTED_AUTHOR] - */ -abstract class BaseFragment : Fragment(), LayoutHolder, SnackbarHolder { - - protected lateinit var mainView: View - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - mainView = inflater.inflate(getLayoutId(), container, false) - return mainView - } - - protected fun navigateTo(navigationId: Int, bundle: Bundle? = null, options: NavOptions? = getDefaultNavigationOptions()) { - findNavController(this).navigate(navigationId, bundle, options) - } - - override fun showSnackbar(id: Int, length: Int) { - showSnackbar(requireContext().getString(id), length) - } - - override fun showSnackbar(message: String, length: Int) { - Snackbar.make(mainView, message, length).show() - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/widgets/ParameterWidget.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/widgets/ParameterWidget.kt deleted file mode 100644 index 366a99e449..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/ui/widgets/ParameterWidget.kt +++ /dev/null @@ -1,119 +0,0 @@ -package com.tangem.devkit.ucase.ui.widgets - -import android.text.Editable -import android.text.TextWatcher -import android.view.View -import android.view.ViewGroup -import android.widget.Button -import android.widget.TextView -import com.google.android.material.textfield.TextInputEditText -import com.google.android.material.textfield.TextInputLayout -import com.tangem.devkit.R -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.abstraction.Item -import com.tangem.devkit._arch.structure.impl.EditTextItem -import com.tangem.devkit.extensions.view.beginDelayedTransition -import com.tangem.devkit.ucase.resources.ActionType -import com.tangem.devkit.ucase.resources.MainResourceHolder -import com.tangem.devkit.ucase.resources.Resources -import ru.dev.gbixahue.eu4d.lib.android.global.log.Log -import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf - -/** -[REDACTED_AUTHOR] - */ -class ParameterWidget( - private val parent: ViewGroup, - item: Item -) { - - val id: Id = item.id - val typedItem = item as EditTextItem - - var onValueChanged: ((Id, Any?) -> Unit)? = null - var onActionBtnClickListener: (() -> Unit)? = null - set(value) { - field = value - toggleActionBtnVisibility() - } - - private val tilValue: TextInputLayout = parent.findViewById(R.id.til_param) - private val etValue: TextInputEditText = parent.findViewById(R.id.et_param) - private val btnAction: Button = parent.findViewById(R.id.btn_action) - private val valueWatcher: TextWatcher by lazy { getWatcher() } - - private val descriptionContainer: ViewGroup by lazy { parent.findViewById(R.id.container_description) } - private val tvDescription: TextView? by lazy { descriptionContainer.findViewById(R.id.tv_description) } - - private var actionBtnVisibilityState: Int = btnAction.visibility - private var value: Any? = typedItem.viewModel.data - - init { - tilValue.hint = tilValue.context.getString(getResNameId()) - etValue.setText(stringOf(typedItem.viewModel.data)) - etValue.addTextChangedListener(valueWatcher) - btnAction.setOnClickListener { onActionBtnClickListener?.invoke() } - btnAction.setText(getResNameId(ActionType.Scan)) - toggleActionBtnVisibility() - initDescriptionWidget() - parent.tag = Id.getTag(typedItem.id) - } - - fun changeParamValue(data: Any?, silent: Boolean = true) { - Log.d(this, "changeParamValue: tag: $id, value: $data") - value = data - toggleActionBtnVisibility() - if (silent) { - etValue.removeTextChangedListener(valueWatcher) - etValue.setText(stringOf(value)) - etValue.addTextChangedListener(valueWatcher) - } else { - etValue.setText(stringOf(value)) - } - } - - fun toggleDescriptionVisibility(state: Boolean) { - (parent.parent as ViewGroup).beginDelayedTransition() - descriptionContainer.visibility = if (state) View.VISIBLE else View.GONE - } - - private fun getWatcher(): TextWatcher { - return object : TextWatcher { - override fun afterTextChanged(editable: Editable?) { - Log.d(this, "afterTextChanged $editable") - value = if (editable.isNullOrEmpty()) null else editable.toString() - toggleActionBtnVisibility() - onValueChanged?.invoke(id, value) - } - - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} - - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} - } - } - - private fun toggleActionBtnVisibility() { - fun switchVisibilityState(newState: Int) { - actionBtnVisibilityState = newState - parent.beginDelayedTransition() - btnAction.visibility = actionBtnVisibilityState - } - when { - onActionBtnClickListener == null -> { - if (actionBtnVisibilityState == View.GONE) return - switchVisibilityState(View.GONE) - } - value == null && actionBtnVisibilityState != View.VISIBLE -> switchVisibilityState(View.VISIBLE) - value != null && actionBtnVisibilityState != View.GONE -> switchVisibilityState(View.GONE) - } - } - - private fun initDescriptionWidget() { - getResDescription()?.let { tvDescription?.setText(it) } - } -} - -fun ParameterWidget.getResNameId(id: Id? = null): Int = MainResourceHolder.safeGet(id - ?: this.id).resName - -fun ParameterWidget.getResDescription(): Int? = MainResourceHolder.safeGet(id).resDescription \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/Ids.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/Ids.kt deleted file mode 100644 index 2200b40724..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/Ids.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.tangem.devkit.ucase.variants - -import com.tangem.devkit._arch.structure.Id - -/** -[REDACTED_AUTHOR] - */ -enum class TlvId : Id { - CardId, - TransactionOutHash, - IssuerData, - Counter, - UserData, - ProtectedUserData -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/createwallet/ui/CreateWalletActionFragment.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/createwallet/ui/CreateWalletActionFragment.kt deleted file mode 100644 index 605f9dd649..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/createwallet/ui/CreateWalletActionFragment.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.devkit.ucase.variants.createwallet.ui - -import com.tangem.devkit.ucase.domain.paramsManager.ItemsManager -import com.tangem.devkit.ucase.domain.paramsManager.managers.CreateWalletItemsManager -import com.tangem.devkit.ucase.ui.BaseCardActionFragment - -class CreateWalletActionFragment : BaseCardActionFragment() { - - override val itemsManager: ItemsManager by lazy { CreateWalletItemsManager() } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/depersonalize/ui/DepersonalizeActionFragment.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/depersonalize/ui/DepersonalizeActionFragment.kt deleted file mode 100644 index 9d1409d58d..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/depersonalize/ui/DepersonalizeActionFragment.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.tangem.devkit.ucase.variants.depersonalize.ui - -import android.os.Bundle -import android.util.TypedValue -import android.view.Gravity -import android.view.View -import android.widget.FrameLayout -import android.widget.TextView -import com.tangem.commands.Card -import com.tangem.devkit.R -import com.tangem.devkit.ucase.domain.paramsManager.ItemsManager -import com.tangem.devkit.ucase.domain.paramsManager.managers.DepersonalizeItemsManager -import com.tangem.devkit.ucase.ui.BaseCardActionFragment -import com.tangem.devkit.ucase.variants.responses.ui.ResponseFragment -import ru.dev.gbixahue.eu4d.lib.android._android.views.dpToPx - -/** -[REDACTED_AUTHOR] - */ -class DepersonalizeActionFragment : BaseCardActionFragment() { - - override val itemsManager: ItemsManager by lazy { DepersonalizeItemsManager() } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - val howToUseView = createHowToUse() - contentContainer.layoutParams = FrameLayout.LayoutParams(-1, -1, Gravity.CENTER) - contentContainer.addView(howToUseView) - } - - private fun createHowToUse(): View { - val fl = FrameLayout(requireContext()) - fl.layoutParams = FrameLayout.LayoutParams(-1, -1, Gravity.CENTER) - val tv = TextView(requireContext()).apply { - val padding = dpToPx(16f).toInt() - setPadding(padding, 0, padding, 0) - gravity = Gravity.CENTER - setTextSize(TypedValue.COMPLEX_UNIT_SP, 18f) - setText(R.string.htu_depersonalize_action) - } - fl.addView(tv) - return fl - } - - override fun initViews() { - swrLayout.isEnabled = false - actionFab.setOnClickListener { actionVM.invokeMainAction() } - } - - override fun handleResponseCardData(card: Card) { - super.handleResponseCardData(card) - val bundle = ResponseFragment.setTittle(R.string.fg_name_response_depersonalization) - navigateTo(R.id.action_nav_card_action_to_response_screen, bundle, null) - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/ReadIssuerDataFragment.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/ReadIssuerDataFragment.kt deleted file mode 100644 index 6d3ac9be86..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/ReadIssuerDataFragment.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.devkit.ucase.variants.issuerdata.ui - -import com.tangem.devkit.ucase.domain.paramsManager.ItemsManager -import com.tangem.devkit.ucase.domain.paramsManager.managers.ReadIssuerDataItemsManager -import com.tangem.devkit.ucase.ui.BaseCardActionFragment - -class ReadIssuerDataFragment : BaseCardActionFragment() { - - override val itemsManager: ItemsManager by lazy { ReadIssuerDataItemsManager() } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/ReadIssuerExtraDataFragment.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/ReadIssuerExtraDataFragment.kt deleted file mode 100644 index 74024ca176..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/ReadIssuerExtraDataFragment.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.devkit.ucase.variants.issuerdata.ui - -import com.tangem.devkit.ucase.domain.paramsManager.ItemsManager -import com.tangem.devkit.ucase.domain.paramsManager.managers.ReadIssuerExtraDataItemsManager -import com.tangem.devkit.ucase.ui.BaseCardActionFragment - -class ReadIssuerExtraDataFragment : BaseCardActionFragment() { - - override val itemsManager: ItemsManager by lazy { ReadIssuerExtraDataItemsManager() } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/WriteIssuerDataFragment.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/WriteIssuerDataFragment.kt deleted file mode 100644 index 88e956818c..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/WriteIssuerDataFragment.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.devkit.ucase.variants.issuerdata.ui - -import com.tangem.devkit.ucase.domain.paramsManager.ItemsManager -import com.tangem.devkit.ucase.domain.paramsManager.managers.WriteIssuerDataItemsManager -import com.tangem.devkit.ucase.ui.BaseCardActionFragment - -class WriteIssuerDataFragment : BaseCardActionFragment() { - - override val itemsManager: ItemsManager by lazy { WriteIssuerDataItemsManager() } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/WriteIssuerExtraDataFragment.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/WriteIssuerExtraDataFragment.kt deleted file mode 100644 index a90fce5e7a..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/issuerdata/ui/WriteIssuerExtraDataFragment.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.devkit.ucase.variants.issuerdata.ui - -import com.tangem.devkit.ucase.domain.paramsManager.ItemsManager -import com.tangem.devkit.ucase.domain.paramsManager.managers.WriteIssuerExtraDataItemsManager -import com.tangem.devkit.ucase.ui.BaseCardActionFragment - -class WriteIssuerExtraDataFragment : BaseCardActionFragment() { - - override val itemsManager: ItemsManager by lazy { WriteIssuerExtraDataItemsManager() } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/Ids.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/Ids.kt deleted file mode 100644 index fef98a3cbc..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/Ids.kt +++ /dev/null @@ -1,110 +0,0 @@ -package com.tangem.devkit.ucase.variants.personalize - -import com.tangem.devkit._arch.structure.Id - -/** -[REDACTED_AUTHOR] - */ - -interface PersonalizationId : Id - -enum class BlockId : PersonalizationId { - CardNumber, - Common, - SigningMethod, - SignHashExProp, - Denomination, - Token, - ProdMask, - SettingsMask, - SettingsMaskProtocolEnc, - SettingsMaskNdef, - Pins, -} - -enum class CardNumberId : PersonalizationId { - Series, - Number, - BatchId, -} - -enum class CommonId : PersonalizationId { - Curve, - Blockchain, - BlockchainCustom, - MaxSignatures, - CreateWallet, -} - -enum class SigningMethodId : PersonalizationId { - SignTx, - SignTxRaw, - SignValidatedTx, - SignValidatedTxRaw, - SignValidatedTxIssuer, - SignValidatedTxRawIssuer, - SignExternal, -} - -enum class SignHashExPropId : PersonalizationId { - PinLessFloorLimit, - CryptoExKey, - RequireTerminalCertSig, - RequireTerminalTxSig, - CheckPin3, -} - -enum class TokenId : PersonalizationId { - ItsToken, - Symbol, - ContractAddress, - Decimal -} - -enum class ProductMaskId : PersonalizationId { - Note, - Tag, - IdCard, - IdIssuerCard -} - -enum class SettingsMaskId : PersonalizationId { - IsReusable, - NeedActivation, - ForbidPurge, - AllowSelectBlockchain, - UseBlock, - OneApdu, - UseCvc, - AllowSwapPin, - AllowSwapPin2, - ForbidDefaultPin, - SmartSecurityDelay, - ProtectIssuerDataAgainstReplay, - SkipSecurityDelayIfValidated, - SkipPin2CvcIfValidated, - SkipSecurityDelayOnLinkedTerminal, - RestrictOverwriteExtraIssuerData, -} - -enum class SettingsMaskProtocolEncId : PersonalizationId { - AllowUnencrypted, - AllowStaticEncryption -} - -enum class SettingsMaskNdefId : PersonalizationId { - UseNdef, - DynamicNdef, - DisablePrecomputedNdef, - Aar, - AarCustom, - Uri, -} - -enum class PinsId : PersonalizationId { - Pin, - Pin2, - Pin3, - Cvc, - PauseBeforePin2 -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/PersonalizationConfigStore.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/PersonalizationConfigStore.kt deleted file mode 100644 index a0c9435a4f..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/PersonalizationConfigStore.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.tangem.devkit.ucase.variants.personalize - -import android.content.Context -import android.content.SharedPreferences -import androidx.core.content.edit -import com.google.gson.Gson -import com.tangem.devkit.AppTangemDemo -import com.tangem.devkit.commons.KeyedStore -import com.tangem.devkit.commons.Store -import com.tangem.devkit.ucase.variants.personalize.dto.PersonalizationConfig - -class PersonalizationConfigStore(context: Context) : Store, KeyedStore { - - companion object { - val defaultKey = "default" - } - - private val sharedPreferencesKey = "personalization_presets" - - private val sp: SharedPreferences = (context.applicationContext as AppTangemDemo).sharedPreferences(sharedPreferencesKey) - private val gson: Gson = Gson() - - override fun save(value: PersonalizationConfig) { - save(defaultKey, value) - } - - override fun restore(): PersonalizationConfig = restore(defaultKey) - - override fun save(key: String, value: PersonalizationConfig) { - sp.edit(true) { putString(key, toJson(value)) } - } - - override fun restore(key: String): PersonalizationConfig { - val json = sp.getString(key, toJson(getDefaultConfig())) - return fromJson(json!!) - } - - override fun restoreAll(): MutableMap { - val map = mutableMapOf() - sp.all.forEach { map[it.key] = fromJson(it.value as String) } - return map.toSortedMap() - } - - override fun delete(key: String) { - sp.edit(true) { remove(key) } - } - - private fun getDefaultConfig(): PersonalizationConfig = PersonalizationConfig.default() - - private fun toJson(value: PersonalizationConfig): String = gson.toJson(value) - - private fun fromJson(json: String): PersonalizationConfig = gson.fromJson(json, PersonalizationConfig::class.java) -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/DefaultValues.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/DefaultValues.kt deleted file mode 100644 index 4af4f57691..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/DefaultValues.kt +++ /dev/null @@ -1,136 +0,0 @@ -package com.tangem.devkit.ucase.variants.personalize.converter - -import com.tangem.commands.EllipticCurve -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.abstraction.KeyValue -import com.tangem.devkit.ucase.variants.personalize.* -import com.tangem.devkit.ucase.variants.personalize.dto.PersonalizationConfig -import com.tangem.devkit.ucase.variants.personalize.dto.PersonalizationJson -import ru.dev.gbixahue.eu4d.lib.kotlin.common.BaseTypedHolder - -/** -[REDACTED_AUTHOR] - */ -class ConfigValuesHolder : BaseTypedHolder() { - - // All registered association values can't be objects - fun init(default: PersonalizationConfig) { - register(CardNumberId.Series, Value(default.series)) - register(CardNumberId.Number, Value(default.startNumber)) - register(CardNumberId.BatchId, Value(default.cardData.batch)) - register(CommonId.Curve, Value(default.curveID, Helper.listOfCurves())) - register(CommonId.Blockchain, Value(default.cardData.blockchain, Helper.listOfBlockchain())) - register(CommonId.BlockchainCustom, Value(default.blockchainCustom)) - register(CommonId.MaxSignatures, Value(default.MaxSignatures)) - register(CommonId.CreateWallet, Value(default.createWallet)) - register(SigningMethodId.SignTx, Value(default.SigningMethod0)) - register(SigningMethodId.SignTxRaw, Value(default.SigningMethod1)) - register(SigningMethodId.SignValidatedTx, Value(default.SigningMethod2)) - register(SigningMethodId.SignValidatedTxRaw, Value(default.SigningMethod3)) - register(SigningMethodId.SignValidatedTxIssuer, Value(default.SigningMethod4)) - register(SigningMethodId.SignValidatedTxRawIssuer, Value(default.SigningMethod5)) - register(SigningMethodId.SignExternal, Value(default.SigningMethod6)) - register(SignHashExPropId.PinLessFloorLimit, Value(default.pinLessFloorLimit)) - register(SignHashExPropId.CryptoExKey, Value(default.hexCrExKey)) - register(SignHashExPropId.RequireTerminalCertSig, Value(default.requireTerminalCertSignature)) - register(SignHashExPropId.RequireTerminalTxSig, Value(default.requireTerminalTxSignature)) - register(SignHashExPropId.CheckPin3, Value(default.checkPIN3onCard)) - register(TokenId.ItsToken, Value(default.itsToken)) - register(TokenId.Symbol, Value(default.cardData.token_symbol)) - register(TokenId.ContractAddress, Value(default.cardData.token_contract_address)) - register(TokenId.Decimal, Value(default.cardData.token_decimal)) - register(ProductMaskId.Note, Value(default.cardData.product_note)) - register(ProductMaskId.Tag, Value(default.cardData.product_tag)) - register(ProductMaskId.IdCard, Value(default.cardData.product_id_card)) - register(ProductMaskId.IdIssuerCard, Value(default.cardData.product_id_issuer)) - register(SettingsMaskId.IsReusable, Value(default.isReusable)) - register(SettingsMaskId.NeedActivation, Value(default.useActivation)) - register(SettingsMaskId.ForbidPurge, Value(default.forbidPurgeWallet)) - register(SettingsMaskId.AllowSelectBlockchain, Value(default.allowSelectBlockchain)) - register(SettingsMaskId.UseBlock, Value(default.useBlock)) - register(SettingsMaskId.OneApdu, Value(default.useOneCommandAtTime)) - register(SettingsMaskId.UseCvc, Value(default.useCVC)) - register(SettingsMaskId.AllowSwapPin, Value(default.allowSwapPIN)) - register(SettingsMaskId.AllowSwapPin2, Value(default.allowSwapPIN2)) - register(SettingsMaskId.ForbidDefaultPin, Value(default.forbidDefaultPIN)) - register(SettingsMaskId.SmartSecurityDelay, Value(default.smartSecurityDelay)) - register(SettingsMaskId.ProtectIssuerDataAgainstReplay, Value(default.protectIssuerDataAgainstReplay)) - register(SettingsMaskId.SkipSecurityDelayIfValidated, Value(default.skipSecurityDelayIfValidatedByIssuer)) - register(SettingsMaskId.SkipPin2CvcIfValidated, Value(default.skipCheckPIN2andCVCIfValidatedByIssuer)) - register(SettingsMaskId.SkipSecurityDelayOnLinkedTerminal, Value(default.skipSecurityDelayIfValidatedByLinkedTerminal)) - register(SettingsMaskId.RestrictOverwriteExtraIssuerData, Value(default.restrictOverwriteIssuerDataEx)) - register(SettingsMaskProtocolEncId.AllowUnencrypted, Value(default.protocolAllowUnencrypted)) - register(SettingsMaskProtocolEncId.AllowStaticEncryption, Value(default.protocolAllowStaticEncryption)) - register(SettingsMaskNdefId.UseNdef, Value(default.useNDEF)) - register(SettingsMaskNdefId.DynamicNdef, Value(default.useDynamicNDEF)) - register(SettingsMaskNdefId.DisablePrecomputedNdef, Value(default.disablePrecomputedNDEF)) - register(SettingsMaskNdefId.Aar, Value(default.aar, Helper.aarList())) - register(SettingsMaskNdefId.AarCustom, Value(default.aarCustom)) - register(SettingsMaskNdefId.Uri, Value(default.uri)) - register(PinsId.Pin, Value(default.PIN)) - register(PinsId.Pin2, Value(default.PIN2)) - register(PinsId.Pin3, Value(default.PIN3)) - register(PinsId.Cvc, Value(default.CVC)) - register(PinsId.PauseBeforePin2, Value(default.pauseBeforePIN2, Helper.pauseBeforePin())) - } -} - -class Value( - private var value: Any? = null, - val list: List? = mutableListOf() -) { - fun get(): Any? = value - fun set(newValue: Any?) { - value = newValue - } -} - -internal class Helper { - companion object { - fun listOfCurves(): List { - return EllipticCurve.values().map { KeyValue(it.name, it.curve) } - } - - fun listOfBlockchain(): List { - return mutableListOf( - KeyValue(PersonalizationJson.CUSTOM, PersonalizationJson.CUSTOM), - KeyValue("BTC", "BTC"), - KeyValue("BTC/test", "BTC/test"), - KeyValue("ETH", "ETH"), - KeyValue("ETH/test", "ETH/test"), - KeyValue("BCH", "BCH"), - KeyValue("BCH/test", "BCH/test"), - KeyValue("LTC", "LTC"), - KeyValue("XLM", "XLM"), - KeyValue("XLM/test", "XLM/test"), - KeyValue("RSK", "RSK"), - KeyValue("XPR", "XPR"), - KeyValue("CARDANO", "CARDANO"), - KeyValue("BNB", "BINANCE"), - KeyValue("XTZ", "TEZOS"), - KeyValue("DUC", "DUC") - ) - } - - fun aarList(): List { - return mutableListOf( - KeyValue(PersonalizationJson.CUSTOM, PersonalizationJson.CUSTOM), - KeyValue("Release APP", "com.tangem.wallet"), - KeyValue("Debug APP", "com.tangem.wallet.debug"), - KeyValue("None", "") - ) - } - - fun pauseBeforePin(): List { - return mutableListOf( - KeyValue("immediately", 0L), - KeyValue("2 seconds", 2000L), - KeyValue("5 seconds", 5000L), - KeyValue("15 seconds", 15000L), - KeyValue("30 seconds", 30000L), - KeyValue("1 minute", 60000L), - KeyValue("2 minute", 120000L) - ) - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/ItemTypes.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/ItemTypes.kt deleted file mode 100644 index 052430a792..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/ItemTypes.kt +++ /dev/null @@ -1,118 +0,0 @@ -package com.tangem.devkit.ucase.variants.personalize.converter - -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit.ucase.variants.personalize.* - -class ItemTypes { - - val blockIdList = mutableListOf( - BlockId.CardNumber, BlockId.Common, BlockId.SigningMethod, BlockId.SignHashExProp, BlockId.Denomination, - BlockId.Token, BlockId.ProdMask, BlockId.SettingsMask, BlockId.SettingsMaskProtocolEnc, - BlockId.SettingsMaskNdef, BlockId.Pins - ) - - val listItemList = mutableListOf(CommonId.Curve, CommonId.Blockchain, SettingsMaskNdefId.Aar, PinsId.PauseBeforePin2) - - val boolList = mutableListOf( - CommonId.CreateWallet, SigningMethodId.SignTx, SigningMethodId.SignTxRaw, SigningMethodId.SignValidatedTx, - SigningMethodId.SignValidatedTxRaw, SigningMethodId.SignValidatedTxIssuer, - SigningMethodId.SignValidatedTxRawIssuer, SigningMethodId.SignExternal, SignHashExPropId.RequireTerminalCertSig, - SignHashExPropId.RequireTerminalTxSig, SignHashExPropId.CheckPin3, TokenId.ItsToken, - ProductMaskId.Note, ProductMaskId.Tag, ProductMaskId.IdCard, ProductMaskId.IdIssuerCard, SettingsMaskId.IsReusable, SettingsMaskId.NeedActivation, - SettingsMaskId.ForbidPurge, SettingsMaskId.AllowSelectBlockchain, SettingsMaskId.UseBlock, SettingsMaskId.OneApdu, - SettingsMaskId.UseCvc, SettingsMaskId.AllowSwapPin, SettingsMaskId.AllowSwapPin2, SettingsMaskId.ForbidDefaultPin, - SettingsMaskId.SmartSecurityDelay, SettingsMaskId.ProtectIssuerDataAgainstReplay, - SettingsMaskId.SkipSecurityDelayIfValidated, SettingsMaskId.SkipPin2CvcIfValidated, - SettingsMaskId.SkipSecurityDelayOnLinkedTerminal, SettingsMaskId.RestrictOverwriteExtraIssuerData, - SettingsMaskProtocolEncId.AllowUnencrypted, SettingsMaskProtocolEncId.AllowStaticEncryption, - SettingsMaskNdefId.UseNdef, SettingsMaskNdefId.DynamicNdef, SettingsMaskNdefId.DisablePrecomputedNdef - ) - - val editTextList = mutableListOf( - CardNumberId.Series, CardNumberId.BatchId, CommonId.BlockchainCustom, SignHashExPropId.CryptoExKey, TokenId.Symbol, - TokenId.ContractAddress, PinsId.Pin, PinsId.Pin2, PinsId.Pin3, PinsId.Cvc, SettingsMaskNdefId.AarCustom, SettingsMaskNdefId.Uri - ) - - val numberList = mutableListOf( - CardNumberId.Number, CommonId.MaxSignatures, SignHashExPropId.PinLessFloorLimit, TokenId.Decimal - ) - - val hiddenList = mutableListOf( - CardNumberId.Series, CardNumberId.BatchId, SigningMethodId.SignExternal, - SignHashExPropId.CryptoExKey, SignHashExPropId.CheckPin3, SettingsMaskId.OneApdu, - SettingsMaskId.UseBlock, SettingsMaskId.ProtectIssuerDataAgainstReplay, - SignHashExPropId.RequireTerminalCertSig, SignHashExPropId.RequireTerminalTxSig, - BlockId.Pins, PinsId.Pin, PinsId.Pin2, PinsId.Pin3, PinsId.Cvc - ) - - val oftenUsedList = listOf( -// BlockId.CardNumber, - BlockId.Common, -// BlockId.SigningMethod, -// BlockId.SignHashExProp, -// BlockId.Denomination, -// BlockId.Token, - BlockId.ProdMask, -// BlockId.SettingsMask, -// BlockId.SettingsMaskProtocolEnc, - BlockId.SettingsMaskNdef, -// BlockId.Pins, - CommonId.Curve, - CommonId.Blockchain, - CommonId.BlockchainCustom, -// Common.MaxSignatures, - CommonId.CreateWallet, -// SigningMethod.SignTx, -// SigningMethod.SignTxRaw, -// SigningMethod.SignValidatedTx, -// SigningMethod.SignValidatedTxRaw, -// SigningMethod.SignValidatedTxIssuer, -// SigningMethod.SignValidatedTxRawIssuer, -// SigningMethod.SignExternal, -// SignHashExProp.PinLessFloorLimit, -// SignHashExProp.CryptoExKey, -// SignHashExProp.RequireTerminalCertSig, -// SignHashExProp.RequireTerminalTxSig, -// SignHashExProp.CheckPin3, -// Denomination.WriteOnPersonalize, -// Denomination.Denomination, -// Token.ItsToken, -// Token.Symbol, -// Token.ContractAddress, -// Token.Decimal, - ProductMaskId.Note, - ProductMaskId.Tag, - ProductMaskId.IdCard, - ProductMaskId.IdIssuerCard, -// SettingsMask.IsReusable, -// SettingsMask.NeedActivation, -// SettingsMask.ForbidPurge, -// SettingsMask.AllowSelectBlockchain, -// SettingsMask.UseBlock, -// SettingsMask.OneApdu, -// SettingsMask.UseCvc, -// SettingsMask.AllowSwapPin, -// SettingsMask.AllowSwapPin2, -// SettingsMask.ForbidDefaultPin, -// SettingsMask.SmartSecurityDelay, -// SettingsMask.ProtectIssuerDataAgainstReplay, -// SettingsMask.SkipSecurityDelayIfValidated, -// SettingsMask.SkipPin2CvcIfValidated, -// SettingsMask.SkipSecurityDelayOnLinkedTerminal, -// SettingsMask.RestrictOverwriteExtraIssuerData, -// SettingsMaskProtocolEnc.AllowUnencrypted, -// SettingsMaskProtocolEnc.AllowStaticEncryption, -// SettingsMaskNdef.UseNdef, -// SettingsMaskNdef.DynamicNdef, -// SettingsMaskNdef.DisablePrecomputedNdef, - SettingsMaskNdefId.Aar, - SettingsMaskNdefId.AarCustom, - SettingsMaskNdefId.Uri, -// Pins.Pin, -// Pins.Pin2, -// Pins.Pin3, -// Pins.Cvc, - PinsId.PauseBeforePin2 - ) - -} diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/PersonalizationConfigConverter.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/PersonalizationConfigConverter.kt deleted file mode 100644 index ce10098ef1..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/PersonalizationConfigConverter.kt +++ /dev/null @@ -1,301 +0,0 @@ -package com.tangem.devkit.ucase.variants.personalize.converter - -import com.tangem.devkit._arch.structure.Additional -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.abstraction.* -import com.tangem.devkit._arch.structure.impl.* -import com.tangem.devkit.ucase.variants.personalize.* -import com.tangem.devkit.ucase.variants.personalize.dto.PersonalizationConfig -import ru.dev.gbixahue.eu4d.lib.android.global.log.Log - -/** -[REDACTED_AUTHOR] - */ -class PersonalizationConfigConverter : ModelConverter { - - private val toModel: ItemsToModel = ItemsToPersonalizationConfig() - private val toItems: ModelToItems = PersonalizationConfigToItems() - - override fun convert(from: List, default: PersonalizationConfig): PersonalizationConfig { - return toModel.convert(from, default) - } - - override fun convert(from: PersonalizationConfig): List { - return toItems.convert(from) - } -} - -class ItemsToPersonalizationConfig : ItemsToModel { - protected val valuesHolder = ConfigValuesHolder() - - override fun convert(from: List, default: PersonalizationConfig): PersonalizationConfig { - valuesHolder.init(default) - mapListItems(from) - return createModel() - } - - private fun mapListItems(itemList: List) { - itemList.iterate { item -> mapItemToHolder(item) } - } - - private fun mapItemToHolder(item: Item) { - when (item) { - is ItemGroup -> mapListItems(item.itemList) - is BaseItem -> { - val defValue = valuesHolder.get(item.id) ?: return - defValue.set(item.viewModel.data) - } - } - } - - private fun createModel(): PersonalizationConfig { - val export = PersonalizationConfig() - export.series = getTyped(CardNumberId.Series) - export.startNumber = getTyped(CardNumberId.Number) - export.cardData.batch = getTyped(CardNumberId.BatchId) - export.curveID = getTyped(CommonId.Curve) - export.cardData.blockchain = getTyped(CommonId.Blockchain) - export.blockchainCustom = getTyped(CommonId.BlockchainCustom) - export.MaxSignatures = getTyped(CommonId.MaxSignatures) - export.createWallet = getTyped(CommonId.CreateWallet) - export.SigningMethod0 = getTyped(SigningMethodId.SignTx) - export.SigningMethod1 = getTyped(SigningMethodId.SignTxRaw) - export.SigningMethod2 = getTyped(SigningMethodId.SignValidatedTx) - export.SigningMethod3 = getTyped(SigningMethodId.SignValidatedTxRaw) - export.SigningMethod4 = getTyped(SigningMethodId.SignValidatedTxIssuer) - export.SigningMethod5 = getTyped(SigningMethodId.SignValidatedTxRawIssuer) - export.SigningMethod6 = getTyped(SigningMethodId.SignExternal) - export.pinLessFloorLimit = getTyped(SignHashExPropId.PinLessFloorLimit) - export.hexCrExKey = getTyped(SignHashExPropId.CryptoExKey) - export.requireTerminalCertSignature = getTyped(SignHashExPropId.RequireTerminalCertSig) - export.requireTerminalTxSignature = getTyped(SignHashExPropId.RequireTerminalTxSig) - export.checkPIN3onCard = getTyped(SignHashExPropId.CheckPin3) - export.itsToken = getTyped(TokenId.ItsToken) - export.cardData.token_symbol = getTypedUnsafe(TokenId.Symbol) - export.cardData.token_contract_address = getTypedUnsafe(TokenId.ContractAddress) - export.cardData.token_decimal = getTypedUnsafe(TokenId.Decimal) - export.cardData = export.cardData.apply { this.product_note = getTyped(ProductMaskId.Note) } - export.cardData = export.cardData.apply { this.product_tag = getTyped(ProductMaskId.Tag) } - export.cardData = export.cardData.apply { this.product_id_card = getTyped(ProductMaskId.IdCard) } - export.cardData = export.cardData.apply { this.product_id_issuer = getTyped(ProductMaskId.IdIssuerCard) } - export.isReusable = getTyped(SettingsMaskId.IsReusable) - export.useActivation = getTyped(SettingsMaskId.NeedActivation) - export.forbidPurgeWallet = getTyped(SettingsMaskId.ForbidPurge) - export.allowSelectBlockchain = getTyped(SettingsMaskId.AllowSelectBlockchain) - export.useBlock = getTyped(SettingsMaskId.UseBlock) - export.useOneCommandAtTime = getTyped(SettingsMaskId.OneApdu) - export.useCVC = getTyped(SettingsMaskId.UseCvc) - export.allowSwapPIN = getTyped(SettingsMaskId.AllowSwapPin) - export.allowSwapPIN2 = getTyped(SettingsMaskId.AllowSwapPin2) - export.forbidDefaultPIN = getTyped(SettingsMaskId.ForbidDefaultPin) - export.smartSecurityDelay = getTyped(SettingsMaskId.SmartSecurityDelay) - export.protectIssuerDataAgainstReplay = getTyped(SettingsMaskId.ProtectIssuerDataAgainstReplay) - export.skipSecurityDelayIfValidatedByIssuer = getTyped(SettingsMaskId.SkipSecurityDelayIfValidated) - export.skipCheckPIN2andCVCIfValidatedByIssuer = getTyped(SettingsMaskId.SkipPin2CvcIfValidated) - export.skipSecurityDelayIfValidatedByLinkedTerminal = getTyped(SettingsMaskId.SkipSecurityDelayOnLinkedTerminal) - export.restrictOverwriteIssuerDataEx = getTyped(SettingsMaskId.RestrictOverwriteExtraIssuerData) - export.protocolAllowUnencrypted = getTyped(SettingsMaskProtocolEncId.AllowUnencrypted) - export.protocolAllowStaticEncryption = getTyped(SettingsMaskProtocolEncId.AllowStaticEncryption) - export.useNDEF = getTyped(SettingsMaskNdefId.UseNdef) - export.useDynamicNDEF = getTyped(SettingsMaskNdefId.DynamicNdef) - export.disablePrecomputedNDEF = getTyped(SettingsMaskNdefId.DisablePrecomputedNdef) - export.aar = getTyped(SettingsMaskNdefId.Aar) - export.aarCustom = getTyped(SettingsMaskNdefId.AarCustom) - export.uri = getTyped(SettingsMaskNdefId.Uri) - export.PIN = getTyped(PinsId.Pin) - export.PIN2 = getTyped(PinsId.Pin2) - export.PIN3 = getTyped(PinsId.Pin3) - export.CVC = getTyped(PinsId.Cvc) - export.pauseBeforePIN2 = getTyped(PinsId.PauseBeforePin2) - return export - } - - private inline fun getTyped(id: Id): Type { - return getTypedBy(valuesHolder, id)!! - } - - private inline fun getTypedUnsafe(id: Id): Type? { - return getTypedBy(valuesHolder, id) - } - - private inline fun getTypedBy(holder: ConfigValuesHolder, id: Id): Type? { - Log.d(this, "getTyped for id: $id") - var typedValue = holder.get(id)?.get() - - typedValue = when (typedValue) { - is ListViewModel -> typedValue.selectedItem as Type - else -> typedValue as? Type ?: null - } - return typedValue - } -} - -class PersonalizationConfigToItems : ModelToItems { - private val valuesHolder = ConfigValuesHolder() - private val itemTypes = ItemTypes() - - override fun convert(from: PersonalizationConfig): List { - valuesHolder.init(from) - val blocList = mutableListOf() - blocList.add(cardNumber()) - blocList.add(common()) - blocList.add(signingMethod()) - blocList.add(signHashExProperties()) - blocList.add(token()) - blocList.add(productMask()) - blocList.add(settingsMask()) - blocList.add(settingsMaskProtocolEnc()) - blocList.add(settingsMaskNdef()) - blocList.add(pins()) - blocList.iterate { - if (itemTypes.hiddenList.contains(it.id)) { - it.viewModel.viewState.isVisibleState.value = false - } - } - return blocList - } - - private fun cardNumber(): ItemGroup { - val block = createGroup(BlockId.CardNumber) - mutableListOf( - CardNumberId.Series, - CardNumberId.Number, - CardNumberId.BatchId - ).forEach { createItem(block, it as Id) } - return block - } - - private fun common(): ItemGroup { - val block = createGroup(BlockId.Common) - mutableListOf( - CommonId.Blockchain, - CommonId.BlockchainCustom, - CommonId.Curve, - CommonId.MaxSignatures, - CommonId.CreateWallet, - PinsId.PauseBeforePin2 - ).forEach { createItem(block, it as Id) } - return block - } - - private fun signingMethod(): ItemGroup { - val block = createGroup(BlockId.SigningMethod) - mutableListOf( - SigningMethodId.SignTx, - SigningMethodId.SignTxRaw, - SigningMethodId.SignValidatedTx, - SigningMethodId.SignValidatedTxRaw, - SigningMethodId.SignValidatedTxIssuer, - SigningMethodId.SignValidatedTxRawIssuer, - SigningMethodId.SignExternal - ).forEach { createItem(block, it) } - return block - } - - private fun signHashExProperties(): ItemGroup { - val block = createGroup(BlockId.SignHashExProp) - mutableListOf( - SignHashExPropId.PinLessFloorLimit, - SignHashExPropId.CryptoExKey, - SignHashExPropId.RequireTerminalCertSig, - SignHashExPropId.RequireTerminalTxSig, - SignHashExPropId.CheckPin3 - ).forEach { createItem(block, it) } - return block - } - - private fun token(): ItemGroup { - val block = createGroup(BlockId.Token) - mutableListOf( - TokenId.ItsToken, - TokenId.Symbol, - TokenId.ContractAddress, - TokenId.Decimal - ).forEach { createItem(block, it) } - return block - } - - private fun productMask(): ItemGroup { - val block = createGroup(BlockId.ProdMask) - mutableListOf( - ProductMaskId.Note, - ProductMaskId.Tag, - ProductMaskId.IdCard, - ProductMaskId.IdIssuerCard - ).forEach { createItem(block, it) } - return block - } - - private fun settingsMask(): ItemGroup { - val block = createGroup(BlockId.SettingsMask) - mutableListOf( - SettingsMaskId.IsReusable, - SettingsMaskId.NeedActivation, - SettingsMaskId.ForbidPurge, - SettingsMaskId.AllowSelectBlockchain, - SettingsMaskId.UseBlock, - SettingsMaskId.OneApdu, - SettingsMaskId.UseCvc, - SettingsMaskId.AllowSwapPin, - SettingsMaskId.AllowSwapPin2, - SettingsMaskId.ForbidDefaultPin, - SettingsMaskId.SmartSecurityDelay, - SettingsMaskId.ProtectIssuerDataAgainstReplay, - SettingsMaskId.SkipSecurityDelayIfValidated, - SettingsMaskId.SkipPin2CvcIfValidated, - SettingsMaskId.SkipSecurityDelayOnLinkedTerminal, - SettingsMaskId.RestrictOverwriteExtraIssuerData - ).forEach { createItem(block, it) } - return block - } - - private fun settingsMaskProtocolEnc(): ItemGroup { - val block = createGroup(BlockId.SettingsMaskProtocolEnc) - mutableListOf( - SettingsMaskProtocolEncId.AllowUnencrypted, - SettingsMaskProtocolEncId.AllowStaticEncryption - ).forEach { createItem(block, it) } - return block - } - - private fun settingsMaskNdef(): ItemGroup { - val block = createGroup(BlockId.SettingsMaskNdef) - mutableListOf( - SettingsMaskNdefId.UseNdef, - SettingsMaskNdefId.DynamicNdef, - SettingsMaskNdefId.DisablePrecomputedNdef, - SettingsMaskNdefId.Aar, - SettingsMaskNdefId.AarCustom, - SettingsMaskNdefId.Uri - ).forEach { createItem(block, it) } - return block - } - - private fun pins(): ItemGroup { - val block = createGroup(BlockId.Pins) - mutableListOf( - PinsId.Pin, - PinsId.Pin2, - PinsId.Pin3, - PinsId.Cvc - ).forEach { createItem(block, it) } - return block - } - - private fun createGroup(id: Id): ItemGroup { - return SimpleItemGroup(id).apply { addItem(TextItem(id)) } - } - - private fun createItem(itemGroup: ItemGroup, id: Id) { - val holder = valuesHolder.get(id) ?: return - val item = when { - itemTypes.blockIdList.contains(id) -> TextItem(id, holder.get() as? String) - itemTypes.listItemList.contains(id) -> SpinnerItem(id, holder.list as List, holder.get()) - itemTypes.boolList.contains(id) -> BoolItem(id, holder.get() as? Boolean) - itemTypes.editTextList.contains(id) -> EditTextItem(id, holder.get() as? String) - itemTypes.numberList.contains(id) -> NumberItem(id, holder.get() as? Number) - else -> SimpleItemGroup(Additional.UNDEFINED) - } - itemGroup.addItem(item) - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/PersonalizationJsonConverter.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/PersonalizationJsonConverter.kt deleted file mode 100644 index a2590ebb3c..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/converter/PersonalizationJsonConverter.kt +++ /dev/null @@ -1,204 +0,0 @@ -package com.tangem.devkit.ucase.variants.personalize.converter - -import com.tangem.commands.EllipticCurve -import com.tangem.commands.SigningMethod -import com.tangem.commands.SigningMethodMask -import com.tangem.commands.personalization.entities.NdefRecord -import com.tangem.devkit._arch.structure.abstraction.TwoWayConverter -import com.tangem.devkit.ucase.variants.personalize.dto.PersonalizationConfig -import com.tangem.devkit.ucase.variants.personalize.dto.PersonalizationJson -import ru.dev.gbixahue.eu4d.lib.kotlin.common.Converter - -/** -[REDACTED_AUTHOR] - */ -class PersonalizationJsonConverter : TwoWayConverter { - - override fun aToB(from: PersonalizationJson): PersonalizationConfig = JsonToConfig().convert(from) - - override fun bToA(from: PersonalizationConfig): PersonalizationJson = ConfigToJson().convert(from) -} - -internal class JsonToConfig : Converter { - - override fun convert(jsonDto: PersonalizationJson): PersonalizationConfig { - val config = PersonalizationConfig.default() - config.apply { - series = jsonDto.series - startNumber = jsonDto.startNumber - curveID = EllipticCurve.byName(jsonDto.curveID)?.curve ?: "" - blockchainCustom = "" - MaxSignatures = jsonDto.MaxSignatures - createWallet = jsonDto.createWallet != 0L - hexCrExKey = jsonDto.hexCrExKey - requireTerminalTxSignature = jsonDto.requireTerminalTxSignature - requireTerminalCertSignature = jsonDto.requireTerminalCertSignature - checkPIN3onCard = jsonDto.checkPIN3onCard - isReusable = jsonDto.isReusable - useActivation = jsonDto.useActivation - forbidPurgeWallet = jsonDto.forbidPurgeWallet - allowSelectBlockchain = jsonDto.allowSelectBlockchain - useBlock = jsonDto.useBlock - useOneCommandAtTime = jsonDto.useOneCommandAtTime - useCVC = jsonDto.useCVC - allowSwapPIN = jsonDto.allowSwapPIN - allowSwapPIN2 = jsonDto.allowSwapPIN2 - forbidDefaultPIN = jsonDto.forbidDefaultPIN - smartSecurityDelay = jsonDto.smartSecurityDelay - protectIssuerDataAgainstReplay = jsonDto.protectIssuerDataAgainstReplay - skipSecurityDelayIfValidatedByIssuer = jsonDto.skipSecurityDelayIfValidatedByIssuer - skipCheckPIN2andCVCIfValidatedByIssuer = jsonDto.skipCheckPIN2andCVCIfValidatedByIssuer - skipSecurityDelayIfValidatedByLinkedTerminal = jsonDto.skipSecurityDelayIfValidatedByLinkedTerminal - restrictOverwriteIssuerDataEx = jsonDto.restrictOverwriteIssuerDataEx - protocolAllowUnencrypted = jsonDto.protocolAllowUnencrypted - protocolAllowStaticEncryption = jsonDto.protocolAllowStaticEncryption - useNDEF = jsonDto.useNDEF - useDynamicNDEF = jsonDto.useDynamicNDEF - disablePrecomputedNDEF = jsonDto.disablePrecomputedNDEF - PIN = jsonDto.PIN - PIN2 = jsonDto.PIN2 - PIN3 = jsonDto.PIN3 - CVC = jsonDto.CVC - pauseBeforePIN2 = jsonDto.pauseBeforePIN2 - count = jsonDto.count - issuerName = jsonDto.issuerName - issuerData = jsonDto.issuerData -// numberFormat = from.numberFormat -// pinLessFloorLimit = 100000L - } - - fillCardData(jsonDto, config) - fillSigningMethod(jsonDto, config) - fillNdef(jsonDto, config) - - return config - } - - private fun fillCardData(jsonDto: PersonalizationJson, config: PersonalizationConfig) { - val jsonCardData = jsonDto.cardData - - // copy whole object and then checking tricky places - config.cardData.copyFrom(jsonCardData) - - config.itsToken = jsonCardData.token_contract_address?.isNotEmpty() ?: false - || jsonCardData.token_symbol?.isNotEmpty() ?: false - - val selectedBlockchain = Helper.listOfBlockchain().firstOrNull { it.value == jsonCardData.blockchain } - if (selectedBlockchain == null) { - config.cardData.blockchain = PersonalizationJson.CUSTOM - config.blockchainCustom = jsonCardData.blockchain - } - } - - private fun fillSigningMethod(jsonDto: PersonalizationJson, config: PersonalizationConfig) { - val mask = SigningMethodMask(jsonDto.SigningMethod.toInt()) - if (mask.contains(SigningMethod.SignHash)) config.SigningMethod0 = true - if (mask.contains(SigningMethod.SignRaw)) config.SigningMethod1 = true - if (mask.contains(SigningMethod.SignHashValidateByIssuer)) config.SigningMethod2 = true - if (mask.contains(SigningMethod.SignRawValidateByIssuer)) config.SigningMethod3 = true - if (mask.contains(SigningMethod.SignHashValidateByIssuerWriteIssuerData)) config.SigningMethod4 = true - if (mask.contains(SigningMethod.SignRawValidateByIssuerWriteIssuerData)) config.SigningMethod5 = true - } - - private fun fillNdef(jsonDto: PersonalizationJson, config: PersonalizationConfig) { - jsonDto.ndef.forEach { record -> - when (record.type) { - NdefRecord.Type.URI -> config.uri = record.value - NdefRecord.Type.AAR -> config.aar = record.value - NdefRecord.Type.TEXT -> { - } - } - } - val selectedAar = Helper.aarList().firstOrNull { it.value == config.aar } - if (selectedAar == null) { - config.aarCustom = config.aar - config.aar = "" - } - } -} - -internal class ConfigToJson : Converter { - - override fun convert(from: PersonalizationConfig): PersonalizationJson { - val jsonDto = PersonalizationJson() - jsonDto.apply { - releaseVersion = false - issuerName = from.issuerName - series = from.series - startNumber = from.startNumber - count = from.count - PIN = from.PIN - PIN2 = from.PIN2 - PIN3 = from.PIN3 - hexCrExKey = from.hexCrExKey - CVC = from.CVC - pauseBeforePIN2 = from.pauseBeforePIN2 - smartSecurityDelay = from.smartSecurityDelay - curveID = from.curveID - MaxSignatures = from.MaxSignatures - isReusable = from.isReusable - allowSwapPIN = from.allowSwapPIN - allowSwapPIN2 = from.allowSwapPIN2 - useActivation = from.useActivation - useCVC = from.useCVC - useNDEF = from.useNDEF - useDynamicNDEF = from.useDynamicNDEF - useOneCommandAtTime = from.useOneCommandAtTime - useBlock = from.useBlock - allowSelectBlockchain = from.allowSelectBlockchain - forbidPurgeWallet = from.forbidPurgeWallet - protocolAllowUnencrypted = from.protocolAllowUnencrypted - protocolAllowStaticEncryption = from.protocolAllowStaticEncryption - protectIssuerDataAgainstReplay = from.protectIssuerDataAgainstReplay - forbidDefaultPIN = from.forbidDefaultPIN - disablePrecomputedNDEF = from.disablePrecomputedNDEF - skipSecurityDelayIfValidatedByIssuer = from.skipSecurityDelayIfValidatedByIssuer - skipCheckPIN2andCVCIfValidatedByIssuer = from.skipCheckPIN2andCVCIfValidatedByIssuer - skipSecurityDelayIfValidatedByLinkedTerminal = from.skipSecurityDelayIfValidatedByLinkedTerminal - restrictOverwriteIssuerDataEx = from.restrictOverwriteIssuerDataEx - requireTerminalTxSignature = from.requireTerminalTxSignature - requireTerminalCertSignature = from.requireTerminalCertSignature - checkPIN3onCard = from.checkPIN3onCard - createWallet = if (from.createWallet) 1 else 0 - issuerData = from.issuerData -// numberFormat = from.numberFormat -// pinLessFloorLimit = 100000L - } - - fillCardData(from, jsonDto) - fillSigningMethod(from, jsonDto) - fillNdef(from, jsonDto) - return jsonDto - } - - private fun fillCardData(config: PersonalizationConfig, jsonDto: PersonalizationJson) { - jsonDto.cardData = config.cardData - if (config.cardData.blockchain == PersonalizationJson.CUSTOM) { - jsonDto.cardData.blockchain = config.blockchainCustom - } - if (config.itsToken) { - jsonDto.cardData.token_contract_address = config.cardData.token_contract_address - jsonDto.cardData.token_symbol = config.cardData.token_symbol - jsonDto.cardData.token_decimal = config.cardData.token_decimal - } else { - jsonDto.cardData.token_contract_address = null - jsonDto.cardData.token_symbol = null - jsonDto.cardData.token_decimal = null - } - } - - private fun fillSigningMethod(config: PersonalizationConfig, jsonDto: PersonalizationJson) { - jsonDto.SigningMethod = PersonalizationConfig.makeSigningMethodMask(config).rawValue.toLong() - } - - private fun fillNdef(config: PersonalizationConfig, jsonDto: PersonalizationJson) { - fun add(value: String, type: NdefRecord.Type) { - if (value.isNotEmpty()) jsonDto.ndef.add(NdefRecord(type, value)) - } - - if (config.aarCustom.isNotEmpty()) add(config.aarCustom, NdefRecord.Type.AAR) - else add(config.aar, NdefRecord.Type.AAR) - - add(config.uri, NdefRecord.Type.URI) - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/DefaultPersonalizationParams.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/DefaultPersonalizationParams.kt deleted file mode 100644 index aa68fb4215..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/DefaultPersonalizationParams.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.tangem.devkit.ucase.variants.personalize.dto - -import com.tangem.KeyPair -import com.tangem.commands.personalization.entities.Acquirer -import com.tangem.commands.personalization.entities.Issuer -import com.tangem.commands.personalization.entities.Manufacturer -import com.tangem.common.extensions.hexToBytes - -/** -[REDACTED_AUTHOR] - */ - -interface DefaultPersonalizationParams { - companion object { - - fun issuer(): Issuer { - val name = "TANGEM SDK" - return Issuer( - name = name, - id = name + "\u0000", - dataKeyPair = KeyPair( - ("045f16bd1d2eafe463e62a335a09e6b2bbcbd04452526885cb679fc4d27af1bd22f553c7deefb54fd3d4f" + - "361d14e6dc3f11b7d4ea183250a60720ebdf9e110cd26").hexToBytes(), - "11121314151617184771ED81F2BACF57479E4735EB1405083927372D40DA9E92".hexToBytes() - ), - transactionKeyPair = KeyPair( - ("0484c5192e9bfa6c528a344f442137a92b89ea835bfef1d04cb4362eb906b508c5889846cfea71ba6dc7b" + - "3120c2208df9c46127d3d85cb5cfbd1479e97133a39d8").hexToBytes(), - "11121314151617184771ED81F2BACF57479E4735EB1405081918171615141312".hexToBytes() - ) - ) - } - - fun acquirer(): Acquirer { - val name = "Smart Cash" - return Acquirer( - name = name, - id = name + "\u0000", - keyPair = KeyPair( - ("0456ad1a82b22bcb40c38fd08939f87e6b80e40dec5b3bdb351c55fcd709e47f9fb2ed00c2304d3a9" + - "86f79c5ae0ac3c84e88da46dc8f513b7542c716af8c9a2daf").hexToBytes(), - "21222324252627284771ED81F2BACF57479E4735EB1405083927372D40DA9E92".hexToBytes() - ) - ) - } - - fun manufacturer(): Manufacturer { - val keys = Manufacturer(com.tangem.devkit.ucase.variants.personalize.dto.Manufacturer.Mode.Developer) - return Manufacturer( - name = "Tangem", - keyPair = KeyPair(keys.publicKey, keys.privateKey) - ) - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/Manufacturer.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/Manufacturer.kt deleted file mode 100644 index eccc075888..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/Manufacturer.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.tangem.devkit.ucase.variants.personalize.dto - -class Manufacturer(private val mode: Mode) { - - private val devPrivateKeyArray = byteArrayOf( - 0x1B.toByte(), 0x48.toByte(), 0xCF.toByte(), 0xD2.toByte(), 0x4B.toByte(), 0xBB.toByte(), 0x5B.toByte(), 0x39.toByte(), - 0x47.toByte(), 0x71.toByte(), 0xED.toByte(), 0x81.toByte(), 0xF2.toByte(), 0xBA.toByte(), 0xCF.toByte(), 0x57.toByte(), - 0x47.toByte(), 0x9E.toByte(), 0x47.toByte(), 0x35.toByte(), 0xEB.toByte(), 0x14.toByte(), 0x05.toByte(), 0x08.toByte(), - 0x39.toByte(), 0x27.toByte(), 0x37.toByte(), 0x2D.toByte(), 0x40.toByte(), 0xDA.toByte(), 0x9E.toByte(), 0x92.toByte() - ) - private val devPublicKeyArray = byteArrayOf(0x04, - 0xBA.toByte(), 0xB8.toByte(), 0x6D.toByte(), 0x56.toByte(), 0x29.toByte(), 0x8C.toByte(), 0x99.toByte(), 0x6F.toByte(), - 0x56.toByte(), 0x4A.toByte(), 0x84.toByte(), 0xFC.toByte(), 0x88.toByte(), 0xE2.toByte(), 0x8A.toByte(), 0xED.toByte(), - 0x38.toByte(), 0x18.toByte(), 0x4B.toByte(), 0x12.toByte(), 0xF0.toByte(), 0x7E.toByte(), 0x51.toByte(), 0x91.toByte(), - 0x13.toByte(), 0xBE.toByte(), 0xF4.toByte(), 0x8C.toByte(), 0x76.toByte(), 0xF3.toByte(), 0xDF.toByte(), 0x3A.toByte(), - 0xDC.toByte(), 0x30.toByte(), 0x35.toByte(), 0x99.toByte(), 0xB0.toByte(), 0x8A.toByte(), 0xC0.toByte(), 0x5B.toByte(), - 0x55.toByte(), 0xEC.toByte(), 0x3D.toByte(), 0xF9.toByte(), 0x8D.toByte(), 0x93.toByte(), 0x38.toByte(), 0x57.toByte(), - 0x3A.toByte(), 0x62.toByte(), 0x42.toByte(), 0xF7.toByte(), 0x6F.toByte(), 0x5D.toByte(), 0x28.toByte(), 0xF4.toByte(), - 0xF0.toByte(), 0xF3.toByte(), 0x64.toByte(), 0xE8.toByte(), 0x7E.toByte(), 0x8F.toByte(), 0xCA.toByte(), 0x2F.toByte() - ) - private val releasePublicKeyArray = byteArrayOf(0x04.toByte(), - 0x2E.toByte(), 0xDE.toByte(), 0x11.toByte(), 0x9B.toByte(), 0xF3.toByte(), 0x37.toByte(), 0xB2.toByte(), 0x64.toByte(), - 0xFD.toByte(), 0xA1.toByte(), 0x32.toByte(), 0xCF.toByte(), 0xC7.toByte(), 0xC1.toByte(), 0x77.toByte(), 0x82.toByte(), - 0x4D.toByte(), 0x36.toByte(), 0x17.toByte(), 0xDA.toByte(), 0xC8.toByte(), 0x0F.toByte(), 0x25.toByte(), 0xDB.toByte(), - 0xB2.toByte(), 0xA4.toByte(), 0xA8.toByte(), 0xA1.toByte(), 0x18.toByte(), 0x3C.toByte(), 0x03.toByte(), 0xB9.toByte(), - 0x15.toByte(), 0x23.toByte(), 0x05.toByte(), 0xF8.toByte(), 0xF1.toByte(), 0xDB.toByte(), 0x97.toByte(), 0x00.toByte(), - 0x45.toByte(), 0x18.toByte(), 0x48.toByte(), 0x0D.toByte(), 0x50.toByte(), 0x91.toByte(), 0xAD.toByte(), 0xC1.toByte(), - 0xCA.toByte(), 0xB9.toByte(), 0xEA.toByte(), 0xCC.toByte(), 0xC1.toByte(), 0x8E.toByte(), 0x1B.toByte(), 0x9E.toByte(), - 0x9C.toByte(), 0x3B.toByte(), 0xEF.toByte(), 0xB2.toByte(), 0x93.toByte(), 0xDD.toByte(), 0x37.toByte(), 0xB2.toByte() - ) - - val publicKey: ByteArray - get() = if (mode == Mode.Developer) { - devPublicKeyArray - } else { - releasePublicKeyArray - } - - @get:Throws(Exception::class) - val privateKey: ByteArray - get() = if (mode == Mode.Developer) { - devPrivateKeyArray - } else { - throw Exception("Real manufacturer key is very secret!") - } - - val name: String - get() = if (mode == Mode.Release) "SMART CASH" else "SMART CASH SDK" - - enum class Mode { - Developer, Release - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/PersonalizationConfig.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/PersonalizationConfig.kt deleted file mode 100644 index c3bdaf8c09..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/PersonalizationConfig.kt +++ /dev/null @@ -1,232 +0,0 @@ -package com.tangem.devkit.ucase.variants.personalize.dto - -import com.tangem.commands.EllipticCurve -import com.tangem.commands.SigningMethod -import com.tangem.commands.SigningMethodMask -import com.tangem.commands.SigningMethodMaskBuilder - -/** -[REDACTED_AUTHOR] - */ -class PersonalizationConfig { - - // Card number - var series = "" - var startNumber: Long = 0 - - // Common - var curveID = "" - var blockchainCustom = "" - var MaxSignatures: Long = 0 - var createWallet = false - - // Signing method - var SigningMethod0 = false - var SigningMethod1 = false - var SigningMethod2 = false - var SigningMethod3 = false - var SigningMethod4 = false - var SigningMethod5 = false - var SigningMethod6 = false - - // Sign hash external properties - var pinLessFloorLimit: Long = 0 - var hexCrExKey = "" - var requireTerminalTxSignature = false - var requireTerminalCertSignature = false - var checkPIN3onCard = false - - // Token - var itsToken = false - - // Product mask - var cardData = CardData() - - // Settings mask - var isReusable = false - var useActivation = false - var forbidPurgeWallet = false - var allowSelectBlockchain = false - var useBlock = false - var useOneCommandAtTime = false - var useCVC = false - var allowSwapPIN = false - var allowSwapPIN2 = false - var forbidDefaultPIN = false - var smartSecurityDelay = false - var protectIssuerDataAgainstReplay = false - var skipSecurityDelayIfValidatedByIssuer = false - var skipCheckPIN2andCVCIfValidatedByIssuer = false - var skipSecurityDelayIfValidatedByLinkedTerminal = false - var restrictOverwriteIssuerDataEx = false - - // Settings mask - protocol encryption - var protocolAllowUnencrypted = false - var protocolAllowStaticEncryption = false - - // Settings mask - var useNDEF = false - var useDynamicNDEF = false - var disablePrecomputedNDEF = false - var aar = "" - var aarCustom = "" - var uri = "" - - // Pins - var PIN = "" - var PIN2 = "" - var PIN3 = "" - var CVC = "" - var pauseBeforePIN2: Long = 0 - - var count: Long = 0 - var issuerName = "" - var issuerData = null - - companion object { - - fun default(): PersonalizationConfig { - return PersonalizationConfig().apply { - // Card number - series = "BB" - startNumber = 300000000000L - - // Common - curveID = EllipticCurve.Secp256k1.curve - blockchainCustom = "" - MaxSignatures = 999999L - createWallet = true - - // Signing method - SigningMethod0 = true - SigningMethod1 = false - SigningMethod2 = false - SigningMethod3 = false - SigningMethod4 = false - SigningMethod5 = false - SigningMethod6 = false - - // Sign hash external properties - pinLessFloorLimit = 100000L - hexCrExKey = "00112233445566778899AABBCCDDEEFFFFEEDDCCBBAA998877665544332211000000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF" - requireTerminalTxSignature = false - requireTerminalCertSignature = false - checkPIN3onCard = true - - // Token - itsToken = false - - cardData = CardData.default() - - // Settings mask - isReusable = true - useActivation = false - forbidPurgeWallet = false - allowSelectBlockchain = false - useBlock = false - useOneCommandAtTime = false - useCVC = false - allowSwapPIN = true - allowSwapPIN2 = true - forbidDefaultPIN = false - smartSecurityDelay = true - protectIssuerDataAgainstReplay = true - skipSecurityDelayIfValidatedByIssuer = true - skipCheckPIN2andCVCIfValidatedByIssuer = true - skipSecurityDelayIfValidatedByLinkedTerminal = true - restrictOverwriteIssuerDataEx = false - - // Settings mask - protocol encryption - protocolAllowUnencrypted = true - protocolAllowStaticEncryption = true - - useNDEF = true - useDynamicNDEF = true - disablePrecomputedNDEF = false - aar = "com.tangem.wallet" - aarCustom = "" - uri = "https://tangem.com" - - // Pins - PIN = "000000" - PIN2 = "000" - PIN3 = "" - CVC = "000" - pauseBeforePIN2 = 5000L - - count = 1050 - issuerName = "TANGEM" - issuerData = null - } - } - - fun makeSigningMethodMask(from: PersonalizationConfig): SigningMethodMask { - val signingMethodMaskBuilder = SigningMethodMaskBuilder() - if (from.SigningMethod0) { - signingMethodMaskBuilder.add(SigningMethod.SignHash) - } - if (from.SigningMethod1) { - signingMethodMaskBuilder.add(SigningMethod.SignRaw) - } - if (from.SigningMethod2) { - signingMethodMaskBuilder.add(SigningMethod.SignHashValidateByIssuer) - } - if (from.SigningMethod3) { - signingMethodMaskBuilder.add(SigningMethod.SignRawValidateByIssuer) - } - if (from.SigningMethod4) { - signingMethodMaskBuilder.add(SigningMethod.SignHashValidateByIssuerWriteIssuerData) - } - if (from.SigningMethod5) { - signingMethodMaskBuilder.add(SigningMethod.SignRawValidateByIssuerWriteIssuerData) - } - if (from.SigningMethod6) { - signingMethodMaskBuilder.add(SigningMethod.SignPos) - } - return signingMethodMaskBuilder.build() - } - } -} - -class CardData { - var date = "" - var batch = "" - var blockchain = "" - var token_symbol: String? = null - var token_contract_address: String? = null - var token_decimal: Long? = null - var product_note = false - var product_tag = false - var product_id_card = false - var product_id_issuer = false - - fun copyFrom(applyData: CardData) { - date = applyData.date - batch = applyData.batch - blockchain = applyData.blockchain - token_symbol = applyData.token_symbol - token_contract_address = applyData.token_contract_address - token_decimal = applyData.token_decimal - product_note = applyData.product_note - product_tag = applyData.product_tag - product_id_card = applyData.product_id_card - product_id_issuer = applyData.product_id_issuer - } - - companion object { - fun default(): CardData { - return CardData().apply { - date = "2020-02-17" - batch = "FFFF" - blockchain = "ETH" - token_symbol = "" - token_contract_address = "" - token_decimal = 0 - product_note = true - product_tag = false - product_id_card = false - product_id_issuer = false - } - } - } -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/PersonalizationJson.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/PersonalizationJson.kt deleted file mode 100644 index a024383090..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/dto/PersonalizationJson.kt +++ /dev/null @@ -1,148 +0,0 @@ -package com.tangem.devkit.ucase.variants.personalize.dto - -import com.google.gson.Gson -import com.google.gson.GsonBuilder -import com.tangem.commands.EllipticCurve -import com.tangem.commands.Product -import com.tangem.commands.ProductMaskBuilder -import com.tangem.commands.SigningMethodMask -import com.tangem.commands.personalization.entities.CardConfig -import com.tangem.commands.personalization.entities.NdefRecord -import java.util.* - -class PersonalizationJson { - - var issuerName = "" - var series = "" - var startNumber = 0L - var count = 0L - var PIN = "" - var PIN2 = "" - var PIN3 = "" - var hexCrExKey = "" - var CVC = "" - var pauseBeforePIN2 = 0L - var smartSecurityDelay = false - var curveID = "" - var SigningMethod = 0L - var MaxSignatures = 0L - var isReusable = false - var allowSwapPIN = false - var allowSwapPIN2 = false - var useActivation = false - var useCVC = false - var useNDEF = false - var useDynamicNDEF = false - var useOneCommandAtTime = false - var useBlock = false - var allowSelectBlockchain = false - var forbidPurgeWallet = false - var protocolAllowUnencrypted = false - var protocolAllowStaticEncryption = false - var protectIssuerDataAgainstReplay = false - var forbidDefaultPIN = false - var disablePrecomputedNDEF = false - var skipSecurityDelayIfValidatedByIssuer = false - var skipCheckPIN2andCVCIfValidatedByIssuer = false - var skipSecurityDelayIfValidatedByLinkedTerminal = false - var restrictOverwriteIssuerDataEx = false - var requireTerminalTxSignature = false - var requireTerminalCertSignature = false - var checkPIN3onCard = false - var createWallet = 0L - var issuerData = null - - var ndef = mutableListOf() - var cardData = CardData() - - var releaseVersion = false - var numberFormat = "" - - companion object { - const val CUSTOM = "--- CUSTOM ---" - - fun getJsonConverter(): Gson { - val builder = GsonBuilder().setPrettyPrinting() - return builder.create() - } - - fun clarifyJson(json: String): String { - val unsupportedQuotes = mutableListOf("“", "”", "«", "»") - var clearedJson = json - unsupportedQuotes.forEach { - if (clearedJson.contains(it)) clearedJson = clearedJson.replace(it, "\"") - } - // 160 is 00A0 symbol (No-Break Space) - return clearedJson.replace(160.toChar().toString(), "").trim() - } - } -} - -fun PersonalizationJson.toCardConfig(): CardConfig { - val isNote = cardData.product_note - val isTag = cardData.product_tag - val isIdCard = cardData.product_id_card - val isIdIssuer = cardData.product_id_issuer - - val productMaskBuilder = ProductMaskBuilder() - if (isNote) productMaskBuilder.add(Product.Note) - if (isTag) productMaskBuilder.add(Product.Tag) - if (isIdCard) productMaskBuilder.add(Product.IdCard) - if (isIdIssuer) productMaskBuilder.add(Product.IdIssuer) - val productMask = productMaskBuilder.build() - - val sdkCardData = com.tangem.commands.CardData( - blockchainName = this.cardData.blockchain, - batchId = this.cardData.batch, - productMask = productMask, - tokenSymbol = this.cardData.token_symbol, - tokenContractAddress = this.cardData.token_contract_address, - tokenDecimal = this.cardData.token_decimal?.toInt(), - issuerName = this.issuerName, - manufactureDateTime = Calendar.getInstance().time, - manufacturerSignature = null) - - return CardConfig( - this.issuerName, - "Tangem Test", - this.series, - this.startNumber, - this.count.toInt(), - this.PIN, - this.PIN2, - this.PIN3, - this.hexCrExKey, - this.CVC, - this.pauseBeforePIN2.toInt(), - this.smartSecurityDelay, - EllipticCurve.byName(this.curveID) ?: EllipticCurve.Secp256k1, - SigningMethodMask(this.SigningMethod.toInt()), - this.MaxSignatures.toInt(), - this.isReusable, - this.allowSwapPIN, - this.allowSwapPIN2, - this.useActivation, - this.useCVC, - this.useNDEF, - this.useDynamicNDEF, - this.useOneCommandAtTime, - this.useBlock, - this.allowSelectBlockchain, - this.forbidPurgeWallet, - this.protocolAllowUnencrypted, - this.protocolAllowStaticEncryption, - this.protectIssuerDataAgainstReplay, - this.forbidDefaultPIN, - this.disablePrecomputedNDEF, - this.skipSecurityDelayIfValidatedByIssuer, - this.skipCheckPIN2andCVCIfValidatedByIssuer, - this.skipSecurityDelayIfValidatedByLinkedTerminal, - this.restrictOverwriteIssuerDataEx, - this.requireTerminalTxSignature, - this.requireTerminalCertSignature, - this.checkPIN3onCard, - this.createWallet != 0L, - sdkCardData, - this.ndef - ) -} \ No newline at end of file diff --git a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/ui/PersonalizationFragment.kt b/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/ui/PersonalizationFragment.kt deleted file mode 100644 index 9e2d3ad01a..0000000000 --- a/tangem-devkit/src/main/java/com/tangem/devkit/ucase/variants/personalize/ui/PersonalizationFragment.kt +++ /dev/null @@ -1,271 +0,0 @@ -package com.tangem.devkit.ucase.variants.personalize.ui - -import android.content.DialogInterface -import android.os.Bundle -import android.view.* -import android.view.inputmethod.InputMethodManager -import android.widget.Button -import android.widget.EditText -import android.widget.LinearLayout -import android.widget.TextView -import androidx.core.content.ContextCompat.getSystemService -import androidx.lifecycle.Observer -import androidx.recyclerview.widget.DividerItemDecoration -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import androidx.transition.Fade -import com.google.android.material.textfield.TextInputLayout -import com.tangem.commands.Card -import com.tangem.devkit.R -import com.tangem.devkit._arch.structure.Id -import com.tangem.devkit._arch.structure.StringId -import com.tangem.devkit._arch.structure.abstraction.Item -import com.tangem.devkit._arch.structure.abstraction.SafeValueChanged -import com.tangem.devkit._arch.widget.WidgetBuilder -import com.tangem.devkit.commons.DialogController -import com.tangem.devkit.commons.view.MultiActionView -import com.tangem.devkit.commons.view.ViewAction -import com.tangem.devkit.extensions.copyToClipboard -import com.tangem.devkit.extensions.shareText -import com.tangem.devkit.extensions.view.beginDelayedTransition -import com.tangem.devkit.ucase.domain.paramsManager.ItemsManager -import com.tangem.devkit.ucase.domain.paramsManager.PayloadKey -import com.tangem.devkit.ucase.domain.paramsManager.managers.PersonalizationItemsManager -import com.tangem.devkit.ucase.resources.ActionType -import com.tangem.devkit.ucase.tunnel.ActionView -import com.tangem.devkit.ucase.tunnel.ItemError -import com.tangem.devkit.ucase.ui.BaseCardActionFragment -import com.tangem.devkit.ucase.variants.personalize.PersonalizationConfigStore -import com.tangem.devkit.ucase.variants.personalize.ui.presets.PersonalizationPresetManager -import com.tangem.devkit.ucase.variants.personalize.ui.presets.PersonalizationPresetView -import com.tangem.devkit.ucase.variants.personalize.ui.presets.RvPresetNamesAdapter -import com.tangem.devkit.ucase.variants.personalize.ui.widgets.PersonalizationItemBuilder -import com.tangem.devkit.ucase.variants.responses.ui.ResponseFragment -import ru.dev.gbixahue.eu4d.lib.android._android.views.inflate -import ru.dev.gbixahue.eu4d.lib.android.global.log.Log -import ru.dev.gbixahue.eu4d.lib.android.global.threading.post -import ru.dev.gbixahue.eu4d.lib.android.global.threading.postUI -import ru.dev.gbixahue.eu4d.lib.android.global.threading.postWork - - -/** -[REDACTED_AUTHOR] - */ -class PersonalizationFragment : BaseCardActionFragment(), PersonalizationPresetView { - - private lateinit var personalizationItemsManager: PersonalizationItemsManager - - override val itemsManager: ItemsManager by lazy { - personalizationItemsManager = PersonalizationItemsManager(PersonalizationConfigStore(requireContext())) - personalizationItemsManager - } - - override fun getLayoutId(): Int = R.layout.fg_base_action_layout - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - lifecycle.addObserver(itemsManager as PersonalizationItemsManager) - } - - override fun bindViews() { - super.bindViews() - swrLayout.isRefreshing = true - } - - override fun initViews() { - actionFab.setOnClickListener { actionVM.invokeMainAction() } - } - - override fun createWidgets(widgetCreatedCallback: () -> Unit) { - Log.d(this, "createWidgets") - val itemList = mutableListOf() - - val maxDelay = 500 - val timeStart = System.currentTimeMillis() - actionVM.ldItemList.observe(viewLifecycleOwner, Observer { list -> - Log.d(this, "ldBlockList size: ${list.size}") - itemList.addAll(list) - val llContainer = LinearLayout(requireContext()).apply { orientation = LinearLayout.VERTICAL } - postWork { - val builder = WidgetBuilder(PersonalizationItemBuilder()) - itemList.forEach { builder.build(it, llContainer) } - actionVM.attachToPayload(mutableMapOf( - PayloadKey.actionView to this as ActionView, - PayloadKey.itemList to itemList - )) - val timeEnd = System.currentTimeMillis() - val diff = timeEnd - timeStart - postUI(maxDelay - diff) { - contentContainer.beginDelayedTransition(Fade()) - contentContainer.addView(llContainer) - widgetCreatedCallback() - swrLayout.isRefreshing = false - swrLayout.isEnabled = false - } - } - }) - } - - override fun widgetsWasCreated() { - super.widgetsWasCreated() - - val footerContainer = contentContainer.inflate(R.layout.fg_personalization_footer) - - fun initShowHideBtn(parent: ViewGroup) { - val btn = parent.findViewById