diff --git a/CHANGELOG b/CHANGELOG
index a54546074..5c3555098 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,343 +1,49 @@
-* ae82aca0 - (HEAD -> release/3.9.0, tag: develop-280, tag: 1.0(36), origin/develop, develop) Merge pull request #336 from tangem/IOS-5602_add_privacy_manifest
+* 5ba5f600 - (HEAD -> release/3.10.0, tag: develop-290, origin/develop, develop) Merge pull request #351 from tangem/IOS-6522_fix_alert_message
|\
-| * 0d6ff58d - IOS-5602 Add PrivacyInfo for UserDefaults
+| * 89e12add - IOS-6522 Fix alert message
|/
-* 1dd026ba - (tag: develop-279) Merge pull request #335 from tangem/IOS-5376_open_read_wallets
+* d3f79b59 - (tag: develop-289, tag: 39) Merge pull request #349 from tangem/IOS-6620_update_privacy_manifest
|\
-| * 09bb944c - Merge branch 'develop' into IOS-5376_open_read_wallets
-| |\
-| |/
-|/|
-* | 32ba6584 - (tag: develop-278) Merge pull request #334 from tangem/IOS-4876_refactor_backup_flow
-|\ \
-| * \ ef8710d7 - Merge branch 'develop' into IOS-4876_refactor_backup_flow
-| |\ \
-| |/ /
-|/| |
-* | | 342eacba - (tag: develop-277) Merge pull request #333 from tangem/feature/IOS-5453-add-spm-support
-|\ \ \
-| * \ \ b65de7a2 - Merge branch 'develop' into feature/IOS-5453-add-spm-support
-| |\ \ \
-| |/ / /
-|/| | |
-| * | | fdbe938f - IOS-5453: Fix some typos and warnings
-| * | | fb0d4be7 - IOS-5453: Fix compilation error
-| * | | 669291bf - IOS-5453: Update example project
-| * | | 4a694280 - IOS-5453: Improve file path for localization resources
-| * | | 6cb5c5ed - IOS-5453: Fix example project file inconsistency
-| * | | 935d62c3 - IOS-5453: Fix bundle resources in the main target
-| * | | 2027d357 - IOS-5453: Fix bundle resources in unit tests when SPM is used
-| * | | 80591906 - IOS-5453: Add package manifest
-| * | | 0150cf71 - IOS-5453: Fix compilation errors due to transitive imports
-| * | | 73647881 - IOS-5453: Remove unused codegen-related C file
-| * | | 4a87c4bd - IOS-5453: Fix project file inconsistency
-| * | | 1931371b - IOS-5453: Update example project
-| * | | d31fc7fc - IOS-5453: Fix C flags
-| * | | d5a78744 - IOS-5453: Fix compilation error due to script sandboxing
-| * | | bdf9e6b5 - IOS-5453: Add refs to gemfiles and podfiles
-| * | | 818ed79f - IOS-5453: Clean-up podspec file a bit
-| * | | dd8e7d70 - IOS-5453: Bring back iOS 11.0 as a minimum deployment target
-| * | | 0f57689d - IOS-5453: Update project using Xcode 15.1.0
-| * | | 7763841e - IOS-5453: Update ruby deps and fix their versions
-| | * | 0c6fdb44 - IOS-4876 Refine code
-| | * | 238d24c7 - IOS-4876 Split certificate loading
-| |/ /
-|/| |
-| | * 570e25d4 - IOS-5376 Open read command
-| | * a7c4549b - IOS-5376 Make read wallets list public
-| |/
-|/|
-* | d7f37dfe - (tag: develop-276) Merge pull request #332 from tangem/IOS-5256_update_timeout_loc
-|\ \
-| |/
-|/|
-| * 58ef4753 - IOS-5256 Update timeout error locaization
-|/
-* 57b2b20f - (tag: develop-275) Merge pull request #331 from tangem/IOS-5346_rename_header
-|\
-| * 2f20128c - IOS-5346 Rename secp256k1 header
-|/
-* 4399166e - (tag: develop-274) Merge pull request #329 from tangem/IOS-4025_refactor_prefligh_filtering
-|\
-| * f25eaeb6 - (tag: IOS-4025_4) IOS-4025 Fix error handling
-| * 02ae031b - (tag: IOS-4025_3) IOS-4025 Filter old cards too
-| * dcc8a752 - (tag: IOS-4025_2) IOS-4025 Old xcode compile issue
-| * abc70173 - IOS-4025 Rename file
-| * 9d151508 - IOS-4025 Rename
-| * 3e318d4c - IOS-4025 Merge branch 'IOS-4025_refactor_prefligh_filtering' of github.com:Tangem/tangem-sdk-ios into IOS-4025_refactor_prefligh_filtering
-| |\
-| | * 3520c4d6 - Merge branch 'develop' into IOS-4025_refactor_prefligh_filtering
-| | |\
-| |_|/
-|/| |
-* | | dddb7efe - (tag: develop-273) Merge pull request #330 from tangem/IOS-4905_decrese_interval
-|\ \ \
-| * | | ffd6daaa - (tag: develop-272_test1) IOS-4905 Decrease interval
-|/ / /
-| | * 3cd562c3 - Update TangemSdk/TangemSdk/TangemSdk.swift
-| | * 6e542e0d - Update TangemSdk/TangemSdk/TangemSdk.swift
-| * | d58e90da - IOS-4025 Reset environment on preflight error
-| |/
-| * 25719685 - (tag: IOS-4025_1) IOS-4025 Refactoring
-| * c028c2be - IOS-4025 PublicKeyId -> PublicKeyID
-| * 0e3fe8c1 - (tag: filtering_test) IOS-4025 Code polishing
-| * 715e4603 - IOS-4025 Refactor preflight filtering
-|/
-* 169b69b2 - (tag: develop-272) Merge pull request #328 from tangem/IOS-5072_nfc_device_list
-|\
-| * 8dfcc2f4 - IOS-5072 Update bad NFC device list
-|/
-* 18af3a9c - (tag: develop-271) Merge pull request #327 from tangem/IOS-4927_fix_tests
-|\
-| * 1836e085 - IOS-4927 Try to make tests locale independent
-|/
-* d73f7aec - (tag: develop-270) Merge pull request #323 from tangem/IOS-4687-improve-derivation-path-validation
-|\
-| * 076d92fa - IOS-4687 Merge remote-tracking branch 'origin/develop' into IOS-4687-improve-derivation-path-validation
-| |\
-| |/
-|/|
-* | ac27e96b - (tag: develop-269) Merge pull request #325 from tangem/IOS-4905_workaround_session_issue
-|\ \
-| * \ c5755d09 - Merge branch 'develop' into IOS-4905_workaround_session_issue
-| |\ \
-| |/ /
-|/| |
-* | | c8c18a94 - (tag: develop-268) Merge pull request #326 from tangem/IOS-4799_open_sdk_backup
-|\ \ \
-| * | | bcadae91 - IOS-4799 beautify
-| * | | 8bbc0935 - IOS-4799 Open config for changes
-|/ / /
-| * | 29bee07d - IOS-4905 re-indent and fix comment
-| * | 5b2671a3 - IOS-4905 Rename var
-| * | 81dc1c12 - IOS-4905 Change to major ver
-| * | f29f355d - IOS-4905 Check for device
-| * | 7fa353dc - IOS-4905 Fix build
-| * | 224050ce - IOS-4905 Fix iOS 17.0.3 reconnection issues
-|/ /
-* | 80fd1791 - (tag: develop-267) Merge pull request #324 from tangem/IOS-4741-app-change-ui-alert-controller-tint
-|\ \
-| * | 0bb86f5b - IOS-4741 Added the ability to set the tint of the UIAlertController popups
-|/ /
-| * a3b3cf6d - IOS-4687 m' -- must not be valid master node
-| * 8c8b8add - IOS-4687 Refactoring
-| * d6e7b05e - IOS-4687 Considering leading quotes invalid -- `/m/'3/0`
-| * 28573e2b - IOS-4687 Consider `m'` as valid derivation path level
-| * 4ece8c54 - IOS-4687 Added a test for a quote after the 'm' symbol
-| * 3bae301d - IOS-4687 Improved derivation path validation
-|/
-* d765cc63 - (tag: develop-266) Merge pull request #322 from tangem/IOS-4541-screen-presented-multiple-times
-|\
-| * 930443ff - IOS-4541 Ensure that ViewController only presented once
-|/
-* af1f9978 - (tag: develop-265) Merge pull request #321 from tangem/tureck1y-patch-1
-|\
-| * 48b0654e - Update CODEOWNERS
-|/
-* 71687fa0 - (tag: develop-264) Merge pull request #320 from tangem/IOS-4286
-|\
-| * 8ae6785e - IOS-4286 Rename method
-| * dcf47dc9 - IOS-4286 Add lib fraemwork for fix tests
-| * 4b2a0b85 - IOS-4286 Refactor public modify
-| * 3c7d1145 - (tag: develop-263-fix) IOS-4286 Make public BLSUtils
-| * 627c6830 - IOS-4286 Set implementation library bls into bls utils
-|/
-* 56abd16d - (tag: develop-263) Merge pull request #319 from tangem/IOS-4280-fix-bls-link-signature-min-target
-|\
-| * 67db51bf - Merge branch 'develop' into IOS-4280-fix-bls-link-signature-min-target
-| |\
-| |/
-|/|
-* | e71775cf - (tag: develop-262) Merge pull request #318 from tangem/IOS-3767_sign_hashes_chunking
-|\ \
-| * | e385dd4a - IOS-3767 Add more docs
-| * | d63de832 - IOS-3767 Clamp from 1 to max chunk size
-| * | 0ed6b8a9 - IOS-3767 Add explanation
-| * | 9f6138f6 - IOS-3767 Refactor chunking
-|/ /
-| * 3e914f44 - IOS-4280 fix library bls-signatures
-|/
-* 49ebe543 - (tag: develop-261) Merge pull request #317 from tangem/IOS-4169-add-bls-signature-lib
-|\
-| * de9edefa - IOS-4169 Link bls framework for example dev
-| * cbc037ee - IOS-4169 Fix named errors
-| * f7ac0302 - Add valid xcfraemwork for bls-signature
-| * 14e5bfc8 - Merge branch 'develop' into IOS-4169-add-bls-signature-lib
-| |\
-| |/
-|/|
-* | 006c5aec - (tag: develop-260) Merge pull request #316 from tangem/IOS-42131_fix_card_deserialization
-|\ \
-| * | 4f3b1612 - IOS-42131 Return bip0340
-|/ /
-* | 8762d4ce - (tag: develop-259) Merge pull request #315 from tangem/IOS-4136_update_fw
-|\ \
-| * | 958ba0a0 - IOS-4136 Bump up to 6.33
-|/ /
-* | e2b8b02d - (tag: develop-258) Merge pull request #313 from tangem/IOS-4136_compatible_ed
-|\ \
-| * | 6579315f - IOS-4136 Ad verification tests into demo
-| * | 0196f153 - IOS-4136 Make auto tests
-| * | efba46ca - IOS-4136 Return Ikarus back to standart
-| * | 67f35308 - Merge branch 'develop' into IOS-4136_compatible_ed
-| |\ \
-| |/ /
-|/| |
-* | | a726dd6a - (tag: develop-257) Merge pull request #314 from tangem/save_secp256k1_version
-|\ \ \
-| * | | 882832e7 - Create secp256k1version.txt
-|/ / /
-| * | b55689a7 - IOS-4136 improve search
-| * | 8f2d5408 - IOS-4136 Rename curve
-| * | 64f72be7 - IOS-4136 Update tests with snippets
-| * | ee0a3fba - IOS-4136 Add tests
-| * | af316ae9 - IOS-4136 Fix deserialization
-| * | 75f38872 - IOS-4136 Add tests
-| * | 4909ac14 - IOS-4136 Move pkSize into constants
-| * | ef2b8dbd - IOS-4136 add derivation precheck for ed25519slip0010
-| * | aa26c144 - IOS-4136 Add ed25519 full support
-|/ /
-| * f2a75f9f - (tag: develop-bls-signature) IOS-4169 add bls-signature tag
-|/
-* 4618a206 - (tag: develop-256) Merge pull request #310 from tangem/IOS-3934-card-sdk-example-app-unusable-layout-on-small-phones
-|\
-| * d6da4afe - IOS-3934 Merge remote-tracking branch 'origin/develop' into IOS-3934-card-sdk-example-app-unusable-layout-on-small-phones
-| |\
-| |/
-|/|
-* | 21473465 - (tag: develop-255) Merge pull request #311 from tangem/IOS-4047_wrong_card_type_text
-|\ \
-| * | 333cf52a - IOS-4047 Change localization for the wrongCardType error
-|/ /
-| * 6a53dcea - IOS-3934 lowered the priority of the scan log text view
-| * 1f399662 - IOS-3934 Improved example application layout on small phones
-|/
-* c5b5a978 - (tag: develop-254) Merge pull request #309 from tangem/IOS-2914-Add-Secp256k1UnmarshalSignature
-|\
-| * bdaaa5bd - IOS-2914 Add `Secp256k1Signature.Extended`
-|/
-* 40446415 - (tag: develop-253) Merge pull request #308 from tangem/IOS-3943-additional-sdk-wording-changes
-|\
-| * d2192b70 - IOS-3943 Updated the wordings following Andrey Lazutkin review
-| * 286db29b - IOS-3943 Removed error_old_firmware
-| * a3ce7609 - IOS-3943 Removed error_no_remaining_signatures
-| * 5c382cb0 - IOS-3943 Removed error_not_activated
-|/
-* 4eb47ac0 - (tag: develop-252) Merge pull request #307 from tangem/IOS-3747_reset_backup_isactive
-|\
-| * 8cce90ee - IOS-3747 Check for backupStatus before reset
-|/
-* cd77b050 - (tag: develop-251) Merge pull request #306 from tangem/IOS-3906-replace-ок-with-ok
-|\
-| * 523a1aef - IOS-3906 Changed russian OK text
-|/
-* 90f99894 - (tag: develop-250) Merge pull request #305 from tangem/IOS-3506_remove_unowned
-|\
-| * 7a0be59d - IOS-3506 Revert yaml
-| * a0c7bd33 - IOS-3506 Revert yaml
-| * 0ca4e214 - IOS-3506 Fix old swift issues
-| * 5463cc3b - IOS-3506 Update yaml
-| * 07251f07 - IOS-3506 add token
-| * 396beb2f - IOS-3506 use self-hosted runner
-| * ba0f1b5d - IOS-3506 Fix old swift warnings
-| * 104151a2 - IOS-3506 Remove unowned everywhere
-| * aec5fc50 - IOS-3506 Remove unowned from CardSession
+| * 22f5bcd5 - IOS-6620 Remove unsupported devices
+| * 35c8b3d1 - IOS-6620 Add Privacy Manifest into example
+| * 9cde2028 - IOS-6620 Update privacy manifest
|/
-* 68441ef9 - (tag: develop-249) Merge pull request #304 from tangem/IOS-3747_fix_backup_islinked
+* 7a1ff80a - (tag: develop-288) Merge pull request #347 from tangem/IOS-5193_refactor_extension
|\
-| * 1b67a51f - IOS-3747 Remove excess precheck before reset
-| * fca362ea - IOS-3747 Fix BackupStatus.isActive checks
+| * 9cab3b95 - IOS-5193 Refactor extensions
|/
-* 37568512 - (tag: develop-248, tag: 32) Merge pull request #303 from tangem/IOS-3796_fix_ecdh_2
+* b2b15a41 - (tag: develop-287) Merge pull request #346 from tangem/IOS-5193_add_convenience_method
|\
-| * a7cacbc3 - IOS-3796 Refactor code
+| * 5a77a2f3 - IOS-5193 Add convenience method
|/
-* 8416d9d0 - (tag: develop-247) Merge pull request #302 from tangem/IOS-3796_fix_ecdh
+* 151522de - (tag: develop-286) Merge pull request #344 from tangem/feature/IOS-6296_backup_errors_update
|\
-| * 8a5af363 - IOS-3796 Calculate x-only for ECDH
+| * 36fc8529 - Show separate messages for backupFailedAlreadyCreated and noActiveBackup errors
|/
-* fd4fe32f - (tag: develop-246) Merge pull request #301 from tangem/IOS-3776_empy_backed_up
+* 24d07f57 - (tag: develop-285, tag: 37) Merge pull request #343 from tangem/IOS-6210_add_logs_backup
|\
-| * 96788435 - IOS-3776 Add doc
-| * 77dee215 - IOS-3776 Handle empty backedup wallet
-|/
-* f7f0421e - (tag: develop-245, tag: 31) Merge pull request #300 from tangem/IOS-3607_bls_import
-|\
-| * 1586af3c - IOS-3607 Code polishing
-| * 9ddab0e9 - IOS-3607 Complete BLS importing
-| * 824f042d - IOS-3607 BLS WIP
-|/
-* 2d838018 - (tag: develop-244) Merge pull request #297 from tangem/IOS-3606_import_schnorr
-|\
-| * 3faf9ba8 - Merge branch 'develop' into IOS-3606_import_schnorr
-| |\
-| |/
-|/|
-* | 7c52d621 - (tag: develop-243) Merge pull request #298 from tangem/IOS-3688-card-sdk-clean-up-platform-specific-strings
-|\ \
-| * \ 2bd5a6d6 - IOS-3688 Merge remote-tracking branch 'origin/develop' into IOS-3688-card-sdk-clean-up-platform-specific-strings
-| |\ \
-| |/ /
-|/| |
-| * | 4816cb9e - IOS-3688 Too much info
-| * | 30c94029 - IOS-3688 Added a few missing strings
-| | * 9099e659 - IOS-3606 Remove excess case
-| | * 7cfbc879 - IOS-3606 Add ability to import schnorr keys
-| |/
-|/|
-* | 7b2267c9 - (tag: develop-242) Update CODEOWNERS
-* | 6e8537e2 - (tag: develop-241) Merge pull request #296 from tangem/IOS-3605_update_secp256k1_schnorr
-|\ \
-| * \ 1dcf4ae6 - Merge branch 'develop' into IOS-3605_update_secp256k1_schnorr
-| |\ \
-| |/ /
-|/| |
-* | | 0a3cc9fe - (tag: develop-240) Merge pull request #295 from tangem/IOS-3335-missing-l10n
-|\ \ \
-| |_|/
-|/| |
-| * | 578124bd - IOS-3335 Added chinese l10n
-|/ /
-| * aa71aab9 - IOS-3605 Fix verification
-| * 4d6bdbe5 - IOS-3605 Update secp256k1 with schnorr
+| * d2fb40ea - IOS-6210 Add backup logs
|/
-* b102d4c2 - (tag: develop-239) Merge pull request #294 from tangem/IOS-3673_finalize_backup_master
+* 68fcf888 - (tag: develop-284) Merge pull request #341 from tangem/IOS-5986_skip_derivation_errors
|\
-| * 92e76ac3 - Merge branch 'develop' into IOS-3673_finalize_backup_master
+| * a205aca6 - Merge branch 'develop' into IOS-5986_skip_derivation_errors
| |\
| |/
|/|
-* | 7fcba436 - (tag: develop-238) Merge pull request #293 from tangem/IOS-3672-derivation-path-m-0-000000-is-considered-valid-and-is-equal-to-m-0-0
+* | 94c1a699 - (tag: develop-283) Merge pull request #342 from tangem/feature/IOS-6085-seed-make-words-count-public
|\ \
-| * | 9cb0e346 - IOS-3672 Normalizing derivation path when parsing from a string
+| * | 63546fbf - IOS-6085: Make EntropyLength words count public
|/ /
-| * fd8b3979 - Merge branch 'develop' into IOS-3673_finalize_backup_master
-| |\
-| |/
-|/|
-* | a4e4633e - (tag: develop-237) Merge pull request #292 from tangem/IOS-3666_return_cardId
-|\ \
-| * | 659e8c47 - IOS-3666 Return cardId in backupFailedNotEmptyWallets
-|/ /
-| * b5a7b204 - IOS-3673 Add FinalizeReadBackupDataCommand
-|/
-* 0ffb4796 - (tag: develop-236) Merge pull request #291 from tangem/IOS-3531_open_derivatio_other_curves
-|\
-| * 3eeef45d - IOS-3531 Open derivation for all supported curves
+| * 25e83ac5 - IOS-5986 Ignore only concrete errors
+| * 2ffb346e - IOS-5986 Skip derivation errors
|/
-* f6df2e7e - (tag: develop-235) Merge pull request #287 from tangem/IOS-3603_update_attest_card
+* 7ddce67f - (tag: develop-282) Merge pull request #338 from tangem/IOS-5674_fix_reader
|\
-| * 0b7f5556 - IOS-3603 Rename to linkedCardPublicKeys
-| * bb217c27 - IOS-3603 refactor handler
-| * 67bfd91f - IOS-3603 Handle full attestation via JSONRPC
-| * dffe73ac - Merge branch 'develop' into IOS-3603_update_attest_card
+| * b6fadf9e - Merge branch 'develop' into IOS-5674_fix_reader
| |\
| |/
|/|
-* | 2c3c8cad - (tag: develop-234) Merge pull request #290 from tangem/master
+* | 5d860b54 - (tag: develop-281, origin/release/0.0.2) Merge pull request #339 from tangem/master
/
-* 4585e781 - IOS-3603 Add attestation to demo
-* 8b40b85c - IOS-3603 Complete attestation
-* 9650868b - IOS-3603 Fix tests
-* f19f2b4c - IOS-3603 Add linked cards attestation
-* 29cd98e4 - IOS-3603 Bump v6 fw
\ No newline at end of file
+* 1517748d - IOS-5674 Refactor code
+* 5c1a6ed1 - (origin/release/0.0.3, origin/release/0.0.1) IOS-5674 Fix reader
\ No newline at end of file
diff --git a/Example/PrivacyInfo.xcprivacy b/Example/PrivacyInfo.xcprivacy
new file mode 100644
index 000000000..e08a130bc
--- /dev/null
+++ b/Example/PrivacyInfo.xcprivacy
@@ -0,0 +1,14 @@
+
+
+
+
+ NSPrivacyTracking
+
+ NSPrivacyTrackingDomains
+
+ NSPrivacyCollectedDataTypes
+
+ NSPrivacyAccessedAPITypes
+
+
+
diff --git a/Example/TangemSdkExample.xcodeproj/project.pbxproj b/Example/TangemSdkExample.xcodeproj/project.pbxproj
index c4d8b9016..14202b819 100644
--- a/Example/TangemSdkExample.xcodeproj/project.pbxproj
+++ b/Example/TangemSdkExample.xcodeproj/project.pbxproj
@@ -47,6 +47,8 @@
DC23EDA02912DD520023E626 /* ResetToFactorySettingsTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC23ED9E2912DD0D0023E626 /* ResetToFactorySettingsTask.swift */; };
DC28E0F22877F84B00AE7A84 /* DebugLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC28E0F12877F84B00AE7A84 /* DebugLogger.swift */; };
DC28E0F32877F9BA00AE7A84 /* DebugLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC28E0F12877F84B00AE7A84 /* DebugLogger.swift */; };
+ DC4512802BD17F8F00DE6F94 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = DC45127F2BD17F8F00DE6F94 /* PrivacyInfo.xcprivacy */; };
+ DC4512822BD17F9D00DE6F94 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = DC45127F2BD17F8F00DE6F94 /* PrivacyInfo.xcprivacy */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -99,6 +101,7 @@
B6B9589B2B2FCA9900E7B74E /* Podfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Podfile; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
DC23ED9E2912DD0D0023E626 /* ResetToFactorySettingsTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetToFactorySettingsTask.swift; sourceTree = ""; };
DC28E0F12877F84B00AE7A84 /* DebugLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugLogger.swift; sourceTree = ""; };
+ DC45127F2BD17F8F00DE6F94 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; };
E53EB3E423F2C7C90079CC11 /* TangemSdkExampleDevelopmentUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TangemSdkExampleDevelopmentUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
E53EB3E623F2C7C90079CC11 /* TangemSdkExampleDevelopmentUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TangemSdkExampleDevelopmentUITests.swift; sourceTree = ""; };
E53EB3EE23F2CD860079CC11 /* RobotApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RobotApi.swift; sourceTree = ""; };
@@ -162,6 +165,7 @@
5D78C1AD234F435B008D7478 = {
isa = PBXGroup;
children = (
+ DC45127F2BD17F8F00DE6F94 /* PrivacyInfo.xcprivacy */,
B6B9589A2B2FCA9900E7B74E /* Gemfile */,
B6B9589B2B2FCA9900E7B74E /* Podfile */,
5D78C1B8234F435B008D7478 /* TangemSdkExample */,
@@ -301,7 +305,7 @@
};
};
};
- buildConfigurationList = 5D78C1B1234F435B008D7478 /* Build configuration list for PBXProject "TangemSdkExample" */;
+ buildConfigurationList = 5D78C1B1234F435B008D7478 /* Build configuration list for PBXProject "TangemSDKExample" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
@@ -329,6 +333,7 @@
B6B9589C2B2FCA9900E7B74E /* Gemfile in Resources */,
5D78C1C6234F435C008D7478 /* LaunchScreen.storyboard in Resources */,
B6B9589D2B2FCA9900E7B74E /* Podfile in Resources */,
+ DC4512822BD17F9D00DE6F94 /* PrivacyInfo.xcprivacy in Resources */,
5D78C1C3234F435C008D7478 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -337,6 +342,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ DC4512802BD17F8F00DE6F94 /* PrivacyInfo.xcprivacy in Resources */,
5DBC25BF235F053F005F0C79 /* LaunchScreen.storyboard in Resources */,
5DBC25C0235F053F005F0C79 /* Assets.xcassets in Resources */,
);
@@ -641,6 +647,10 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.tangem.TangemSDKExample;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
+ SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
};
@@ -661,6 +671,10 @@
);
PRODUCT_BUNDLE_IDENTIFIER = com.tangem.TangemSDKExample;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
+ SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
};
@@ -709,7 +723,7 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
- 5D78C1B1234F435B008D7478 /* Build configuration list for PBXProject "TangemSdkExample" */ = {
+ 5D78C1B1234F435B008D7478 /* Build configuration list for PBXProject "TangemSDKExample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
5D78C1C8234F435C008D7478 /* Debug */,
diff --git a/TangemSdk.podspec b/TangemSdk.podspec
index 331c49d5e..bc12fb0f1 100644
--- a/TangemSdk.podspec
+++ b/TangemSdk.podspec
@@ -8,7 +8,7 @@
Pod::Spec.new do |s|
s.name = 'TangemSdk'
- s.version = '3.9.0'
+ s.version = '3.10.0'
s.summary = 'Use TangemSdk for Tangem cards integration'
s.description = <<-DESC
Tangem is a Swiss-based secure hardware wallet manufacturer that enables blockchain-based assets to be kept in custody within smart physical banknotes and accessed via NFC technology. Tangem’s mission is to make digital assets accessible, affordable and convenient for consumers.
diff --git a/TangemSdk/TangemSdk.xcodeproj/project.pbxproj b/TangemSdk/TangemSdk.xcodeproj/project.pbxproj
index 8d806149f..d9b6cc37a 100644
--- a/TangemSdk/TangemSdk.xcodeproj/project.pbxproj
+++ b/TangemSdk/TangemSdk.xcodeproj/project.pbxproj
@@ -2448,6 +2448,10 @@
PRODUCT_BUNDLE_IDENTIFIER = com.tangem.tangemSdk.example;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
+ SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_INCLUDE_PATHS = "$(SRCROOT)/TangemSdk/";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
@@ -2497,6 +2501,10 @@
PRODUCT_BUNDLE_IDENTIFIER = com.tangem.tangemSdk.example;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
+ SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_INCLUDE_PATHS = "$(SRCROOT)/TangemSdk/";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
diff --git a/TangemSdk/TangemSdk/Common/Core/CardSession.swift b/TangemSdk/TangemSdk/Common/Core/CardSession.swift
index 68e4afa75..68e57ab48 100644
--- a/TangemSdk/TangemSdk/Common/Core/CardSession.swift
+++ b/TangemSdk/TangemSdk/Common/Core/CardSession.swift
@@ -246,7 +246,7 @@ public class CardSession {
/// - Parameter error: The error to show
public func stop(error: Error, completion: (() -> Void)?) {
Log.session("Stop session")
- reader.stopSession(with: error.localizedDescription)
+ reader.stopSession(with: error)
sessionDidStop(completion: completion)
}
@@ -321,7 +321,6 @@ public class CardSession {
.sink(receiveCompletion: {[weak self] readerCompletion in
self?.sendSubscription = []
if case let .failure(error) = readerCompletion {
- Log.error(error)
completion(.failure(error))
}
}, receiveValue: {[weak self] responseApdu in
diff --git a/TangemSdk/TangemSdk/Common/Core/TangemSdkError.swift b/TangemSdk/TangemSdk/Common/Core/TangemSdkError.swift
index 304c1b381..a8acfaa13 100644
--- a/TangemSdk/TangemSdk/Common/Core/TangemSdkError.swift
+++ b/TangemSdk/TangemSdk/Common/Core/TangemSdkError.swift
@@ -511,9 +511,12 @@ public enum TangemSdkError: Error, LocalizedError, Encodable {
case .backupFailedNotEmptyWallets: return "error_backup_not_empty_wallets".localized
case .backupFailedWrongIssuer, .backupFailedHDWalletSettings, .backupFailedNotEnoughCurves,
.backupFailedNotEnoughWallets, .backupFailedFirmware, .backupNotAllowed,
- .backupFailedIncompatibleBatch, .backupFailedIncompatibleFirmware, .backupFailedKeysImportSettings,
- .backupFailedAlreadyCreated:
+ .backupFailedIncompatibleBatch, .backupFailedIncompatibleFirmware, .backupFailedKeysImportSettings:
return "error_backup_wrong_card".localized("\(self.code)")
+ case .backupFailedAlreadyCreated:
+ return "error_backup_failed_already_created".localized
+ case .noActiveBackup:
+ return "error_no_active_backup".localized
case .resetPinWrongCard:
return "error_reset_wrong_card".localized("\(self.code)")
case .oldCard: return "error_old_card".localized
diff --git a/TangemSdk/TangemSdk/Common/Extensions/TangemSdk+Combine.swift b/TangemSdk/TangemSdk/Common/Extensions/TangemSdk+Combine.swift
index 459acb12d..f63d67861 100644
--- a/TangemSdk/TangemSdk/Common/Extensions/TangemSdk+Combine.swift
+++ b/TangemSdk/TangemSdk/Common/Extensions/TangemSdk+Combine.swift
@@ -81,7 +81,7 @@ extension NFCTagReaderSession {
}
@available(iOS 13.0, *)
-extension TangemSdk {
+public extension TangemSdk {
/// Combine wrapper for `startSession` method.
/// - Parameters:
/// - runnable: A custom task, adopting `CardSessionRunnable` protocol
@@ -89,12 +89,28 @@ extension TangemSdk {
/// - initialMessage: A custom description that shows at the beginning of the NFC session. If nil, default message will be used
/// - accessCode: Access code that will be used for a card session initialization. If nil, Tangem SDK will handle it automatically.
/// - Returns: `AnyPublisher`
- public func startSessionPublisher(with runnable: T,
- cardId: String? = nil,
- initialMessage: Message? = nil,
- accessCode: String? = nil) -> AnyPublisher {
+ func startSessionPublisher(with runnable: T,
+ cardId: String?,
+ initialMessage: Message? = nil,
+ accessCode: String? = nil) -> AnyPublisher {
return Deferred { Future() {
self.startSession(with: runnable, cardId: cardId, initialMessage: initialMessage, accessCode: accessCode, completion: $0)
}}.eraseToAnyPublisher()
}
+
+ /// Combine wrapper for `startSession` method.
+ /// - Parameters:
+ /// - runnable: A custom task, adopting `CardSessionRunnable` protocol
+ /// - filter: Filters card to be read. Optional.
+ /// - initialMessage: A custom description that shows at the beginning of the NFC session. If nil, default message will be used
+ /// - accessCode: Access code that will be used for a card session initialization. If nil, Tangem SDK will handle it automatically.
+ /// - Returns: `AnyPublisher`
+ func startSessionPublisher(with runnable: T,
+ filter: SessionFilter?,
+ initialMessage: Message? = nil,
+ accessCode: String? = nil) -> AnyPublisher {
+ return Deferred { Future() {
+ self.startSession(with: runnable, filter: filter, initialMessage: initialMessage, accessCode: accessCode, completion: $0)
+ }}.eraseToAnyPublisher()
+ }
}
diff --git a/TangemSdk/TangemSdk/Common/Localization/Resources/de.lproj/Localizable.strings b/TangemSdk/TangemSdk/Common/Localization/Resources/de.lproj/Localizable.strings
index e58df6d8e..5af26c609 100644
--- a/TangemSdk/TangemSdk/Common/Localization/Resources/de.lproj/Localizable.strings
+++ b/TangemSdk/TangemSdk/Common/Localization/Resources/de.lproj/Localizable.strings
@@ -19,10 +19,12 @@
"common_warning" = "Warning";
"error_already_created" = "Ein Wallet ist bereits erstellt worden";
"error_backup_card_already_added" = "This card has already been added to the list";
+"error_backup_failed_already_created" = "This card cannot be used as a backup because it already contains a wallet. Ensure that no funds are stored on the card by scanning it in the app. Then, reset it to factory settings.";
"error_backup_not_empty_wallets" = "This card already has a wallet. If you want to proceed you have to reset it to factory settings first.";
"error_backup_wrong_card" = "This card can't be used as a backup card. Error code: %@.";
"error_card_verification_failed" = "Die Kartenverifizierung ist fehlgeschlagen";
"error_file_not_found" = "File not found";
+"error_no_active_backup" = "The selected card cannot be used to reset the card access code, because there is no backup on it. Please contact support team.";
"error_old_card" = "Tangem cards issued before September 2019 cannot sign data using an iPhone due to iOS restrictions";
"error_pin_cannot_be_changed_format" = "%@ cannot be changed";
"error_pin_cannot_be_default_format" = "%@ cannot be changed to this value. Please, enter another one.";
diff --git a/TangemSdk/TangemSdk/Common/Localization/Resources/en.lproj/Localizable.strings b/TangemSdk/TangemSdk/Common/Localization/Resources/en.lproj/Localizable.strings
index 8672a793b..0b1c9e7a2 100644
--- a/TangemSdk/TangemSdk/Common/Localization/Resources/en.lproj/Localizable.strings
+++ b/TangemSdk/TangemSdk/Common/Localization/Resources/en.lproj/Localizable.strings
@@ -19,10 +19,12 @@
"common_warning" = "Warning";
"error_already_created" = "A wallet has already been created";
"error_backup_card_already_added" = "This card has already been added to the list";
+"error_backup_failed_already_created" = "This card cannot be used as a backup because it already contains a wallet. Ensure that no funds are stored on the card by scanning it in the app. Then, reset it to factory settings.";
"error_backup_not_empty_wallets" = "This card already has a wallet. If you want to proceed you have to reset it to factory settings first.";
"error_backup_wrong_card" = "This card can't be used as a backup card. Error code: %@.";
"error_card_verification_failed" = "Card verification failed";
"error_file_not_found" = "File not found";
+"error_no_active_backup" = "The selected card cannot be used to reset the card access code, because there is no backup on it. Please contact support team.";
"error_old_card" = "Tangem cards issued before September 2019 cannot sign data using an iPhone due to iOS restrictions";
"error_pin_cannot_be_changed_format" = "%@ cannot be changed";
"error_pin_cannot_be_default_format" = "%@ cannot be changed to this value. Please, enter another one.";
diff --git a/TangemSdk/TangemSdk/Common/Localization/Resources/fr.lproj/Localizable.strings b/TangemSdk/TangemSdk/Common/Localization/Resources/fr.lproj/Localizable.strings
index 6963eabd4..005fe1b9a 100644
--- a/TangemSdk/TangemSdk/Common/Localization/Resources/fr.lproj/Localizable.strings
+++ b/TangemSdk/TangemSdk/Common/Localization/Resources/fr.lproj/Localizable.strings
@@ -19,10 +19,12 @@
"common_warning" = "Warning";
"error_already_created" = "Le portefeuille a déjà été créé";
"error_backup_card_already_added" = "This card has already been added to the list";
+"error_backup_failed_already_created" = "This card cannot be used as a backup because it already contains a wallet. Ensure that no funds are stored on the card by scanning it in the app. Then, reset it to factory settings.";
"error_backup_not_empty_wallets" = "This card already has a wallet. If you want to proceed you have to reset it to factory settings first.";
"error_backup_wrong_card" = "This card can't be used as a backup card. Error code: %@.";
"error_card_verification_failed" = "Erreur de validation de la carte";
"error_file_not_found" = "File not found";
+"error_no_active_backup" = "The selected card cannot be used to reset the card access code, because there is no backup on it. Please contact support team.";
"error_old_card" = "Tangem cards issued before September 2019 cannot sign data using an iPhone due to iOS restrictions";
"error_pin_cannot_be_changed_format" = "%@ cannot be changed";
"error_pin_cannot_be_default_format" = "%@ cannot be changed to this value. Please, enter another one.";
diff --git a/TangemSdk/TangemSdk/Common/Localization/Resources/it.lproj/Localizable.strings b/TangemSdk/TangemSdk/Common/Localization/Resources/it.lproj/Localizable.strings
index 5185362e1..29e633762 100644
--- a/TangemSdk/TangemSdk/Common/Localization/Resources/it.lproj/Localizable.strings
+++ b/TangemSdk/TangemSdk/Common/Localization/Resources/it.lproj/Localizable.strings
@@ -19,10 +19,12 @@
"common_warning" = "Warning";
"error_already_created" = "Portafoglio già creato";
"error_backup_card_already_added" = "This card has already been added to the list";
+"error_backup_failed_already_created" = "This card cannot be used as a backup because it already contains a wallet. Ensure that no funds are stored on the card by scanning it in the app. Then, reset it to factory settings.";
"error_backup_not_empty_wallets" = "This card already has a wallet. If you want to proceed you have to reset it to factory settings first.";
"error_backup_wrong_card" = "This card can't be used as a backup card. Error code: %@.";
"error_card_verification_failed" = "Non è stata eseguita la verifica della carta";
"error_file_not_found" = "File not found";
+"error_no_active_backup" = "The selected card cannot be used to reset the card access code, because there is no backup on it. Please contact support team.";
"error_old_card" = "Tangem cards issued before September 2019 cannot sign data using an iPhone due to iOS restrictions";
"error_pin_cannot_be_changed_format" = "%@ cannot be changed";
"error_pin_cannot_be_default_format" = "%@ cannot be changed to this value. Please, enter another one.";
diff --git a/TangemSdk/TangemSdk/Common/Localization/Resources/ru.lproj/Localizable.strings b/TangemSdk/TangemSdk/Common/Localization/Resources/ru.lproj/Localizable.strings
index 183b057a8..c847c6a8f 100644
--- a/TangemSdk/TangemSdk/Common/Localization/Resources/ru.lproj/Localizable.strings
+++ b/TangemSdk/TangemSdk/Common/Localization/Resources/ru.lproj/Localizable.strings
@@ -19,10 +19,12 @@
"common_warning" = "Предупреждение";
"error_already_created" = "Кошелек уже создан";
"error_backup_card_already_added" = "Эта карта уже добавлена в список";
+"error_backup_failed_already_created" = "Резервное копирование не возможно, на выбранной карте уже создан кошелек. Пожалуйста, убедитесь, что на этой карте нет средств, отсканировав её в приложении, и затем сбросьте её до заводских настроек.";
"error_backup_not_empty_wallets" = "На этой карте уже создан кошелёк. Если вы хотите продолжить, сбросьте карту к заводским настройкам.";
"error_backup_wrong_card" = "Эту карту нельзя использовать для резервного копирования. Код ошибки: %@.";
"error_card_verification_failed" = "Ошибка проверки карты";
"error_file_not_found" = "Файл не найден";
+"error_no_active_backup" = "Выбранная карта не может использоваться для сброса кода доступа карты, т.к. на ней нет резервного копирования. Обратитесь, пожалуйста, в поддержку.";
"error_old_card" = "Карты Tangem, выпущенные до сентября 2019 года, не могут подписывать данные с помощью iPhone из-за ограничений iOS.";
"error_pin_cannot_be_changed_format" = "%@ не может быть изменен";
"error_pin_cannot_be_default_format" = "%@ нельзя изменить на это значение. Пожалуйста, введите другое";
diff --git a/TangemSdk/TangemSdk/Common/Localization/Resources/zh-Hant.lproj/Localizable.strings b/TangemSdk/TangemSdk/Common/Localization/Resources/zh-Hant.lproj/Localizable.strings
index af18a5cba..a5d0b3514 100644
--- a/TangemSdk/TangemSdk/Common/Localization/Resources/zh-Hant.lproj/Localizable.strings
+++ b/TangemSdk/TangemSdk/Common/Localization/Resources/zh-Hant.lproj/Localizable.strings
@@ -19,10 +19,12 @@
"common_warning" = "警告";
"error_already_created" = "已創建錢包";
"error_backup_card_already_added" = "此卡已添加到列表中";
+"error_backup_failed_already_created" = "This card cannot be used as a backup because it already contains a wallet. Ensure that no funds are stored on the card by scanning it in the app. Then, reset it to factory settings.";
"error_backup_not_empty_wallets" = "這張卡已經有錢包了。如果要繼續,您必須先將其重置為出廠設置";
"error_backup_wrong_card" = "此卡不能作為備用卡使用。錯誤代碼:%@。";
"error_card_verification_failed" = "卡驗證失敗";
"error_file_not_found" = "文件未找到";
+"error_no_active_backup" = "The selected card cannot be used to reset the card access code, because there is no backup on it. Please contact support team.";
"error_old_card" = "由於 iOS 限制,2019 年 9 月之前發行的 Tangem 卡無法使用 iPhone 簽署數據";
"error_pin_cannot_be_changed_format" = "%@ 無法更改";
"error_pin_cannot_be_default_format" = "%@ 不能更改為此值。 請輸入另一個";
diff --git a/TangemSdk/TangemSdk/Common/NFC/CardReader.swift b/TangemSdk/TangemSdk/Common/NFC/CardReader.swift
index 68bf42aec..2cf157e73 100644
--- a/TangemSdk/TangemSdk/Common/NFC/CardReader.swift
+++ b/TangemSdk/TangemSdk/Common/NFC/CardReader.swift
@@ -40,6 +40,7 @@ public protocol CardReader: AnyObject {
func resumeSession()
func stopSession(with errorMessage: String?)
func pauseSession(with errorMessage: String?)
+ func stopSession(with error: Error)
func sendPublisher(apdu: CommandApdu) -> AnyPublisher
func restartPolling(silent: Bool)
}
diff --git a/TangemSdk/TangemSdk/Common/NFC/NFCReader.swift b/TangemSdk/TangemSdk/Common/NFC/NFCReader.swift
index bb354ad14..cedf26244 100644
--- a/TangemSdk/TangemSdk/Common/NFC/NFCReader.swift
+++ b/TangemSdk/TangemSdk/Common/NFC/NFCReader.swift
@@ -76,8 +76,12 @@ final class NFCReader: NSObject {
private var sendRetryCount = Constants.retryCount
private var startRetryCount = Constants.startRetryCount
private let pollingOption: NFCTagReaderSession.PollingOption
- private var sessionDidBecomeActiveTimestamp: Date = .init()
-
+ private var sessionDidBecomeActiveTS: Date = .init()
+ private var firstConnectionTS: Date? = nil
+ private var tagConnectionTS: Date? = nil
+ private var isBeingStopped = false
+ private var stoppedError: TangemSdkError? = nil
+
/// Starting from iOS 17 is no longer possible to invoke restart polling after 20 seconds from first connection on some devices
private lazy var shouldReduceRestartPolling: Bool = {
if #available(iOS 17, *), NFCUtils.isBrokenRestartPollingDevice {
@@ -87,8 +91,6 @@ final class NFCReader: NSObject {
return false
}()
- private var firstConnectionTimestamp: Date? = nil
-
private lazy var nfcUtils: NFCUtils = .init()
init(pollingOption: NFCTagReaderSession.PollingOption = [.iso14443]) {
@@ -108,6 +110,11 @@ extension NFCReader: CardReader {
var alertMessage: String {
get { return _alertMessage ?? "" }
set {
+ if isBeingStopped {
+ Log.nfc("Session is being stopped. Skip alert message.")
+ return
+ }
+
readerSession?.alertMessage = newValue
_alertMessage = newValue
}
@@ -122,6 +129,11 @@ extension NFCReader: CardReader {
invalidatedWithError = nil
cancelled = false
connectedTag = nil
+ isBeingStopped = false
+ stoppedError = nil
+ tagConnectionTS = nil
+ firstConnectionTS = nil
+ sessionDidBecomeActiveTS = Date()
let alertMessage = message ?? "view_delegate_scan_description".localized
_alertMessage = alertMessage
@@ -140,7 +152,7 @@ extension NFCReader: CardReader {
.filter{[weak self] _ in
guard let self else { return false }
- let distanceToSessionActive = self.sessionDidBecomeActiveTimestamp.distance(to: Date())
+ let distanceToSessionActive = self.sessionDidBecomeActiveTS.distance(to: Date())
if !self.isSessionReady || distanceToSessionActive < 1 {
Log.nfc("Filter out cancelled event")
return false
@@ -207,16 +219,17 @@ extension NFCReader: CardReader {
.dropFirst()
.sink {[weak self] isSilent in
guard let self, let session = self.readerSession,
- session.isReady else {
+ session.isReady,
+ !self.isBeingStopped else {
return
}
- if self.shouldReduceRestartPolling, let firstConnectionTimestamp = self.firstConnectionTimestamp {
- let interval = Date().timeIntervalSince(firstConnectionTimestamp)
+ if self.shouldReduceRestartPolling, let firstConnectionTS = self.firstConnectionTS {
+ let interval = Date().timeIntervalSince(firstConnectionTS)
Log.nfc("Restart polling interval is: \(interval)")
// 20 is too much because of time inaccuracy
- if interval >= 18 {
+ if interval >= 16 {
Log.nfc("Ignore restart polling")
return
}
@@ -247,6 +260,15 @@ extension NFCReader: CardReader {
}
func stopSession(with errorMessage: String? = nil) {
+ guard (readerSession?.isReady == true) else {
+ return
+ }
+
+ if isBeingStopped {
+ return
+ }
+
+ isBeingStopped = true
Log.nfc("Stop reader session invoked")
stopTimers()
if let errorMessage = errorMessage {
@@ -256,6 +278,11 @@ extension NFCReader: CardReader {
}
}
+ func stopSession(with error: Error) {
+ stoppedError = error.toTangemSdkError()
+ stopSession(with: error.localizedDescription)
+ }
+
func restartPolling(silent: Bool) {
restartPollingPublisher.send(silent)
}
@@ -264,6 +291,13 @@ extension NFCReader: CardReader {
/// - Parameter apdu: serialized apdu
/// - Parameter completion: result with ResponseApdu or NFCError otherwise
func sendPublisher(apdu: CommandApdu) -> AnyPublisher {
+ if isBeingStopped {
+ Log.nfc("Session is being stopped. Skip sending.")
+ return Empty(completeImmediately: false)
+ .setFailureType(to: TangemSdkError.self)
+ .eraseToAnyPublisher()
+ }
+
Log.nfc("Send publisher invoked")
return Just(())
@@ -289,7 +323,7 @@ extension NFCReader: CardReader {
return Fail(error: TangemSdkError.unsupportedCommand).eraseToAnyPublisher()
} //todo: handle tag lost
- let requestTimestamp = Date()
+ let requestTS = Date()
Log.apdu("SEND --> \(apdu)")
return iso7816tag
.sendCommandPublisher(cApdu: apdu)
@@ -307,8 +341,8 @@ extension NFCReader: CardReader {
.eraseToAnyPublisher()
}
- let distance = requestTimestamp.distance(to: Date())
- let isDistanceTooLong = distance > Constants.timestampTolerance
+ let distance = requestTS.distance(to: Date())
+ let isDistanceTooLong = distance > Constants.requestToleranceTS
if isDistanceTooLong || self.sendRetryCount <= 0 { //retry to fix old device issues
Log.nfc("Invoke restart polling on error")
self.sendRetryCount = Constants.retryCount
@@ -337,7 +371,7 @@ extension NFCReader: CardReader {
}
private func start() {
- firstConnectionTimestamp = nil
+ firstConnectionTS = nil
readerSession?.invalidate() //Important! We must keep invalidate/begin in balance after start retries
readerSession = NFCTagReaderSession(pollingOption: self.pollingOption, delegate: self, queue: queue)!
readerSession!.alertMessage = _alertMessage!
@@ -371,12 +405,11 @@ extension NFCReader: CardReader {
.TimerPublisher(interval: Constants.tagTimeout, tolerance: 0, runLoop: RunLoop.main, mode: .common)
.autoconnect()
.receive(on: queue)
- .filter {[weak self] _ in self?.idleTimerCancellable != nil }
.sink {[weak self] _ in
guard let self else { return }
Log.nfc("Stop by tag timer")
- self.stopSession(with: TangemSdkError.nfcTimeout.localizedDescription)
+ self.stopSession(with: TangemSdkError.nfcTimeout)
self.tagTimerCancellable = nil
}
}
@@ -390,7 +423,7 @@ extension NFCReader: CardReader {
guard let self else { return }
Log.nfc("Stop by session timer")
- self.stopSession(with: TangemSdkError.nfcTimeout.localizedDescription)
+ self.stopSession(with: TangemSdkError.nfcTimeout)
self.sessionTimerCancellable = nil
}
}
@@ -400,6 +433,7 @@ extension NFCReader: CardReader {
.TimerPublisher(interval: Constants.idleTimeout, runLoop: RunLoop.main, mode: .common)
.autoconnect()
.receive(on: queue)
+ .filter { [weak self] _ in !(self?.isBeingStopped ?? true) }
.sink {[weak self] _ in
guard let self else { return }
@@ -470,36 +504,49 @@ extension NFCReader: CardReader {
@available(iOS 13.0, *)
extension NFCReader: NFCTagReaderSessionDelegate {
func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) {
- sessionDidBecomeActiveTimestamp = Date()
+ sessionDidBecomeActiveTS = Date()
isSessionReady = true
}
func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) {
- Log.nfc("NFC Session did invalidate with: \(error.localizedDescription)")
+ Log.nfc("NFC Session did invalidate with NFC error: \(error.localizedDescription)")
if nfcStuckTimerCancellable == nil { //handle stuck retries ios14
- invalidatedWithError = TangemSdkError.parse(error as! NFCReaderError)
+ invalidatedWithError = stoppedError ?? TangemSdkError.parse(error as! NFCReaderError)
+ }
+
+ isBeingStopped = false
+
+ if let tagConnectionTS {
+ let currentTS = Date()
+ Log.nfc("Session time is: \(currentTS.timeIntervalSince(sessionDidBecomeActiveTS))")
+ Log.nfc("Tag time is: \(currentTS.timeIntervalSince(tagConnectionTS))")
}
}
func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
Log.nfc("NFC tag detected: \(tags)")
- if firstConnectionTimestamp == nil {
- firstConnectionTimestamp = Date()
- }
-
let nfcTag = tags.first!
sessionConnectCancellable = session.connectPublisher(tag: nfcTag)
.receive(on: queue)
.sink {[weak self] completion in
+ guard let self else { return }
+
switch completion {
case .failure:
- self?.restartPolling(silent: false)
+ self.restartPolling(silent: false)
case .finished:
break
}
- self?.sessionConnectCancellable = nil
+ self.sessionConnectCancellable = nil
+
+ self.tagConnectionTS = Date()
+
+ if self.firstConnectionTS == nil {
+ self.firstConnectionTS = self.tagConnectionTS
+ }
+
} receiveValue: {[weak self] _ in
self?.tagDidConnect(nfcTag)
}
@@ -516,7 +563,7 @@ extension NFCReader {
static let nfcStuckTimeout = 1.0
static let retryCount = 20
static let startRetryCount = 5
- static let timestampTolerance = 1.0
+ static let requestToleranceTS = 1.0
static let searchTagTimeout = 1.0
}
}
diff --git a/TangemSdk/TangemSdk/Common/Network/NetworkService.swift b/TangemSdk/TangemSdk/Common/Network/NetworkService.swift
index 53897ed8a..0aec5aad8 100644
--- a/TangemSdk/TangemSdk/Common/Network/NetworkService.swift
+++ b/TangemSdk/TangemSdk/Common/Network/NetworkService.swift
@@ -70,7 +70,6 @@ public class NetworkService {
private func requestDataPublisher(request: URLRequest, configuration: URLSessionConfiguration) -> AnyPublisher {
Log.network("request to: \(request)")
- Log.network("request to: \(String(describing: request.allHTTPHeaderFields))")
return URLSession(configuration: configuration)
.dataTaskPublisher(for: request)
diff --git a/TangemSdk/TangemSdk/Crypto/BIP39/EntropyLength.swift b/TangemSdk/TangemSdk/Crypto/BIP39/EntropyLength.swift
index 734d49c0f..a8ebd478b 100644
--- a/TangemSdk/TangemSdk/Crypto/BIP39/EntropyLength.swift
+++ b/TangemSdk/TangemSdk/Crypto/BIP39/EntropyLength.swift
@@ -15,7 +15,7 @@ public enum EntropyLength: Int, CaseIterable {
case bits224 = 224
case bits256 = 256
- var wordCount: Int {
+ public var wordCount: Int {
switch self {
case .bits128: return 12
case .bits160: return 15
diff --git a/TangemSdk/TangemSdk/Operations/Backup/BackupService.swift b/TangemSdk/TangemSdk/Operations/Backup/BackupService.swift
index 55b4986ea..81eeebdaf 100644
--- a/TangemSdk/TangemSdk/Operations/Backup/BackupService.swift
+++ b/TangemSdk/TangemSdk/Operations/Backup/BackupService.swift
@@ -492,16 +492,30 @@ class BackupRepo {
var data: BackupServiceData = .init() {
didSet {
- try? save()
+ do {
+ try save()
+ } catch {
+ Log.debug(error)
+ }
+
+ Log.debug("BackupRepo updated")
}
}
init () {
- try? fetch()
+ do {
+ try fetch()
+ } catch {
+ Log.debug(error)
+ }
}
func reset() {
- try? storage.delete(.backupData)
+ do {
+ try storage.delete(.backupData)
+ } catch {
+ Log.debug(error)
+ }
data = .init()
}
diff --git a/TangemSdk/TangemSdk/Operations/Derivation/DeriveWalletPublicKeysTask.swift b/TangemSdk/TangemSdk/Operations/Derivation/DeriveWalletPublicKeysTask.swift
index 7168b1cac..76f2b963e 100644
--- a/TangemSdk/TangemSdk/Operations/Derivation/DeriveWalletPublicKeysTask.swift
+++ b/TangemSdk/TangemSdk/Operations/Derivation/DeriveWalletPublicKeysTask.swift
@@ -39,14 +39,22 @@ public class DeriveWalletPublicKeysTask: CardSessionRunnable {
let path = derivationPaths[index]
let task = DeriveWalletPublicKeyTask(walletPublicKey: walletPublicKey, derivationPath: path)
task.run(in: session) { result in
+ var keys = keys
+
switch result {
case .success(let key):
- var keys = keys
keys[path] = key
- self.runDerivation(at: index + 1, keys: keys, in: session, completion: completion)
case .failure(let error):
- completion(.failure(error))
+ switch error {
+ case .nonHardenedDerivationNotSupported, .walletNotFound, .unsupportedCurve:
+ Log.error(error)
+ default:
+ completion(.failure(error))
+ return
+ }
}
+
+ self.runDerivation(at: index + 1, keys: keys, in: session, completion: completion)
}
}
}
diff --git a/TangemSdk/TangemSdk/PrivacyInfo.xcprivacy b/TangemSdk/TangemSdk/PrivacyInfo.xcprivacy
index 79bc9e285..5704beda8 100644
--- a/TangemSdk/TangemSdk/PrivacyInfo.xcprivacy
+++ b/TangemSdk/TangemSdk/PrivacyInfo.xcprivacy
@@ -2,6 +2,12 @@
+ NSPrivacyTracking
+
+ NSPrivacyTrackingDomains
+
+ NSPrivacyCollectedDataTypes
+
NSPrivacyAccessedAPITypes
diff --git a/VERSION b/VERSION
index a5c4c7633..30291cba2 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.9.0
+3.10.0