enable Keycard on iOS

Signed-off-by: Andrea Franz <andrea@gravityblast.com>
This commit is contained in:
Andrea Franz 2020-11-25 10:30:00 +01:00
parent f9c3747768
commit 505171cf87
No known key found for this signature in database
GPG Key ID: 4F0D2F2D9DE7F29D
38 changed files with 634 additions and 268 deletions

9
ios/Bridge.swift Normal file
View File

@ -0,0 +1,9 @@
//
// Bridge.swift
// StatusIm
//
// Created by Andrea Franz on 02/12/2020.
// Copyright © 2020 Status. All rights reserved.
//
import Foundation

View File

@ -19,6 +19,10 @@ abstract_target 'Status' do
pod 'Permission-Microphone', :path => "#{permissions_path}/Microphone.podspec"
pod 'Permission-Camera', :path => "#{permissions_path}/Camera.podspec"
pod "react-native-status-keycard", path: "../node_modules/react-native-status-keycard"
pod "Keycard", git: "https://github.com/status-im/Keycard.swift.git"
pod 'secp256k1', git: "https://github.com/status-im/secp256k1.swift.git", submodules: true
target 'StatusIm' do
target 'StatusImTests' do
inherit! :complete
@ -37,3 +41,4 @@ abstract_target 'Status' do
use_native_modules!
end

View File

@ -2,8 +2,9 @@ PODS:
- boost-for-react-native (1.63.0)
- BVLinearGradient (2.5.6):
- React
- CocoaAsyncSocket (7.6.4)
- CocoaAsyncSocket (7.6.5)
- CocoaLibEvent (1.0.0)
- CryptoSwift (1.3.8)
- DoubleConversion (1.1.6)
- FBLazyVector (0.63.4)
- FBReactNativeSpec (0.63.4):
@ -69,6 +70,18 @@ PODS:
- DoubleConversion
- glog
- glog (0.3.5)
- Keycard (3.0.4):
- CryptoSwift
- secp256k1
- libwebp (1.1.0):
- libwebp/demux (= 1.1.0)
- libwebp/mux (= 1.1.0)
- libwebp/webp (= 1.1.0)
- libwebp/demux (1.1.0):
- libwebp/webp
- libwebp/mux (1.1.0):
- libwebp/demux
- libwebp/webp (1.1.0)
- OpenSSL-Universal (1.0.2.20):
- OpenSSL-Universal/Static (= 1.0.2.20)
- OpenSSL-Universal/Static (1.0.2.20)
@ -266,6 +279,9 @@ PODS:
- React
- react-native-splash-screen (3.2.0):
- React
- react-native-status-keycard (2.5.30):
- Keycard
- React
- react-native-webview (10.9.2):
- React-Core
- React-RCTActionSheet (0.63.4):
@ -369,13 +385,20 @@ PODS:
- React
- RNSVG (9.13.6):
- React
- SDWebImage (5.10.2):
- SDWebImage/Core (= 5.10.2)
- SDWebImage/Core (5.10.2)
- SDWebImageWebPCoder (0.6.1):
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.7)
- secp256k1 (0.1.6)
- SQLCipher (3.4.2):
- SQLCipher/standard (= 3.4.2)
- SQLCipher/common (3.4.2)
- SQLCipher/standard (3.4.2):
- SQLCipher/common
- SSZipArchive (2.2.3)
- TOCropViewController (2.5.5)
- TOCropViewController (2.6.0)
- TouchID (4.4.1):
- React
- Yoga (1.14.0)
@ -408,6 +431,7 @@ DEPENDENCIES:
- FlipperKit/SKIOSNetworkPlugin (~> 0.54.0)
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- Keycard (from `https://github.com/status-im/Keycard.swift.git`)
- Permission-Camera (from `../node_modules/react-native-permissions/ios/Camera.podspec`)
- Permission-Microphone (from `../node_modules/react-native-permissions/ios/Microphone.podspec`)
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
@ -433,6 +457,7 @@ DEPENDENCIES:
- react-native-shake (from `../node_modules/react-native-shake`)
- "react-native-slider (from `../node_modules/@react-native-community/slider`)"
- react-native-splash-screen (from `../node_modules/react-native-splash-screen`)
- react-native-status-keycard (from `../node_modules/react-native-status-keycard`)
- react-native-webview (from `../node_modules/react-native-webview`)
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
@ -461,6 +486,7 @@ DEPENDENCIES:
- RNReanimated (from `../node_modules/react-native-reanimated`)
- RNScreens (from `../node_modules/react-native-screens`)
- RNSVG (from `../node_modules/react-native-svg`)
- secp256k1 (from `https://github.com/status-im/secp256k1.swift.git`)
- SQLCipher (~> 3.0)
- SSZipArchive
- TouchID (from `../node_modules/react-native-touch-id`)
@ -471,6 +497,7 @@ SPEC REPOS:
- boost-for-react-native
- CocoaAsyncSocket
- CocoaLibEvent
- CryptoSwift
- Flipper
- Flipper-DoubleConversion
- Flipper-Folly
@ -497,6 +524,8 @@ EXTERNAL SOURCES:
:podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec"
glog:
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
Keycard:
:git: https://github.com/status-im/Keycard.swift.git
Permission-Camera:
:path: "../node_modules/react-native-permissions/ios/Camera.podspec"
Permission-Microphone:
@ -543,6 +572,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/@react-native-community/slider"
react-native-splash-screen:
:path: "../node_modules/react-native-splash-screen"
react-native-status-keycard:
:path: "../node_modules/react-native-status-keycard"
react-native-webview:
:path: "../node_modules/react-native-webview"
React-RCTActionSheet:
@ -599,16 +630,29 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-screens"
RNSVG:
:path: "../node_modules/react-native-svg"
secp256k1:
:git: https://github.com/status-im/secp256k1.swift.git
:submodules: true
TouchID:
:path: "../node_modules/react-native-touch-id"
Yoga:
:path: "../node_modules/react-native/ReactCommon/yoga"
CHECKOUT OPTIONS:
Keycard:
:commit: 36e260cfafc2755a47f1e5f542858ceb0c6c37df
:git: https://github.com/status-im/Keycard.swift.git
secp256k1:
:commit: 46a1fa30d9b8babeae85ff519050f42394ab5fcc
:git: https://github.com/status-im/secp256k1.swift.git
:submodules: true
SPEC CHECKSUMS:
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
CocoaAsyncSocket: 694058e7c0ed05a9e217d1b3c7ded962f4180845
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f
CryptoSwift: 01b0f0cba1d5c212e5a335ff6c054fb75a204f00
DoubleConversion: cde416483dac037923206447da6e1454df403714
FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
@ -621,6 +665,8 @@ SPEC CHECKSUMS:
FlipperKit: ab353d41aea8aae2ea6daaf813e67496642f3d7d
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
glog: cee4319f395bad5865ef3f32466c2e0ae677432c
Keycard: dd96182888da0aacf4de821b641103143bbb26cc
libwebp: 946cb3063cea9236285f7e9a8505d806d30e07f3
OpenSSL-Universal: ff34003318d5e1163e9529b08470708e389ffcdd
Permission-Camera: afad27bf90337684d4a86f3825112d648c8c4d3b
Permission-Microphone: 0ffabc3fe1c75cfb260525ee3f529383c9f4368c
@ -645,6 +691,7 @@ SPEC CHECKSUMS:
react-native-shake: de052eaa3eadc4a326b8ddd7ac80c06e8d84528c
react-native-slider: 12bd76d3d568c9c5500825db54123d44b48e4ad4
react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
react-native-status-keycard: a001766cf8f27de56406ac712a52a982f1f28744
react-native-webview: 4e96d493f9f90ba4f03b28933f30b2964df07e39
React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336
React-RCTAnimation: 1bde3ecc0c104c55df246eda516e0deb03c4e49b
@ -673,13 +720,16 @@ SPEC CHECKSUMS:
RNReanimated: 89f5e0a04d1dd52fbf27e7e7030d8f80a646a3fc
RNScreens: b748efec66e095134c7166ca333b628cd7e6f3e2
RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f
SDWebImage: b969dcfc02c40a5da71eac0b03b8f1a0c794a86f
SDWebImageWebPCoder: d0dac55073088d24b2ac1b191a71a8f8d0adac21
secp256k1: f61d67e6fdcb85fd727acf1bf35ace6036db540c
SQLCipher: f9fcf29b2e59ced7defc2a2bdd0ebe79b40d4990
SSZipArchive: 62d4947b08730e4cda640473b0066d209ff033c9
TOCropViewController: da59f531f8ac8a94ef6d6c0fc34009350f9e8bfe
TOCropViewController: 3105367e808b7d3d886a74ff59bf4804e7d3ab38
TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4
Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: 8752b77562edc2969e7016627fa83c23a152cf3c
PODFILE CHECKSUM: 5d4b89aa09f8d53bc530d173622952e85d5d7662
COCOAPODS: 1.10.0
COCOAPODS: 1.10.1

View File

@ -40,6 +40,9 @@
57C854A7993C47A3B1AECD32 /* Inter-MediumItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = C6B1215047604CD59A4C74D6 /* Inter-MediumItalic.otf */; };
68E19BBDF749E72ED1F9DEF5 /* libPods-Status-StatusIm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 132CE3B093884B0FB239A0AB /* libPods-Status-StatusIm.a */; };
6C137817D5298C82BC79177C /* libPods-Status-StatusImPR.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D4CB5416994C913628B8754 /* libPods-Status-StatusImPR.a */; };
65F6941925780A4F00A45E76 /* Bridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F6941825780A4F00A45E76 /* Bridge.swift */; };
65F6941A25780A4F00A45E76 /* Bridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F6941825780A4F00A45E76 /* Bridge.swift */; };
65F6941B25780A4F00A45E76 /* Bridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F6941825780A4F00A45E76 /* Bridge.swift */; };
70ADBB5ECF934DCF8A0E4919 /* Inter-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 1426DF592BA248FC81D955CB /* Inter-Regular.otf */; };
74B758FC20D7C00B003343C3 /* launch-image-universal.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 74B758FB20D7C00B003343C3 /* launch-image-universal.storyboard */; };
8391E8E0E93C41A98AAA6631 /* Inter-SemiBoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = A4F2BBE8D4DD4140A6CCAC39 /* Inter-SemiBoldItalic.otf */; };
@ -124,6 +127,11 @@
4C16DE0B1F89508700AA10DB /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
4E586E1B0E544F64AA9F5BD1 /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
5D4CB5416994C913628B8754 /* libPods-Status-StatusImPR.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusImPR.a"; sourceTree = BUILT_PRODUCTS_DIR; };
5E9C2936B3890356C5BE1078 /* Pods-StatusIm-StatusImTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StatusIm-StatusImTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-StatusIm-StatusImTests/Pods-StatusIm-StatusImTests.debug.xcconfig"; sourceTree = "<group>"; };
65F693BD2578002500A45E76 /* CoreNFC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreNFC.framework; path = System/Library/Frameworks/CoreNFC.framework; sourceTree = SDKROOT; };
65F693BF2578003600A45E76 /* CoreNFC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreNFC.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk/System/iOSSupport/System/Library/Frameworks/CoreNFC.framework; sourceTree = DEVELOPER_DIR; };
65F6941725780A4E00A45E76 /* StatusImTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "StatusImTests-Bridging-Header.h"; sourceTree = "<group>"; };
65F6941825780A4F00A45E76 /* Bridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bridge.swift; sourceTree = "<group>"; };
69291A6222A63434694EA2A6 /* Pods-Status-StatusImPR.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusImPR.release.xcconfig"; path = "Pods/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR.release.xcconfig"; sourceTree = "<group>"; };
693A62DB37BC4CD5A30E5C96 /* Inter-SemiBold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-SemiBold.otf"; path = "../resources/fonts/Inter-SemiBold.otf"; sourceTree = "<group>"; };
74B758FB20D7C00B003343C3 /* launch-image-universal.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "launch-image-universal.storyboard"; sourceTree = "<group>"; };
@ -279,6 +287,7 @@
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
65F6941825780A4F00A45E76 /* Bridge.swift */,
3AAD2AB624A3A5F10075D594 /* StatusImPR */,
13B07FAE1A68108700A75B9A /* StatusIm */,
832341AE1AAA6A7D00B99B32 /* Libraries */,
@ -287,6 +296,7 @@
A97BA941B2FB44B4B66EE6D3 /* Frameworks */,
1E7837547A9A40E18AD63CF3 /* Resources */,
5C1C8762251D6EF495FB2384 /* Pods */,
65F6941725780A4E00A45E76 /* StatusImTests-Bridging-Header.h */,
);
indentWidth = 2;
sourceTree = "<group>";
@ -314,6 +324,8 @@
A97BA941B2FB44B4B66EE6D3 /* Frameworks */ = {
isa = PBXGroup;
children = (
65F693BD2578002500A45E76 /* CoreNFC.framework */,
65F693BF2578003600A45E76 /* CoreNFC.framework */,
3A8F8EA924A4D31600BF206D /* GameKit.framework */,
4C16DE0B1F89508700AA10DB /* JavaScriptCore.framework */,
B24FC7FE1DE7195F00D694FF /* MessageUI.framework */,
@ -724,6 +736,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
65F6941A25780A4F00A45E76 /* Bridge.swift in Sources */,
00E356F31AD99517003FC87E /* StatusImTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -732,6 +745,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
65F6941925780A4F00A45E76 /* Bridge.swift in Sources */,
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
3A2626CF245C3F2200D5F94B /* Dummy.swift in Sources */,
13B07FC11A68108700A75B9A /* main.m in Sources */,
@ -742,6 +756,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
65F6941B25780A4F00A45E76 /* Bridge.swift in Sources */,
3AAD2ABC24A3A60E0075D594 /* AppDelegate.m in Sources */,
3AAD2ABD24A3A60E0075D594 /* Dummy.swift in Sources */,
3AAD2ABE24A3A60E0075D594 /* main.m in Sources */,
@ -766,6 +781,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_ID_SUFFIX = .debug;
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
DEVELOPMENT_TEAM = DTX7Z4U3YA;
FRAMEWORK_SEARCH_PATHS = (
@ -777,13 +793,16 @@
"$(inherited)",
);
INFOPLIST_FILE = StatusImTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = im.status.ethereum;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "StatusImTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StatusIm.app/StatusIm";
};
name = Debug;
@ -795,6 +814,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_ID_SUFFIX = "";
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Distribution";
COPY_PHASE_STRIP = NO;
DEVELOPMENT_TEAM = DTX7Z4U3YA;
@ -803,13 +823,15 @@
"$(inherited)",
);
INFOPLIST_FILE = StatusImTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = im.status.ethereum;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "StatusImTests-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StatusIm.app/StatusIm";
};
name = Release;
@ -1137,7 +1159,7 @@
"$(SRCROOT)/../node_modules/react-native-image-resizer/ios/RCTImageResizer",
"$(SRCROOT)/../node_modules/react-native-splash-screen/ios/**",
);
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LIBRARY_SEARCH_PATHS = (
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
"\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"",
@ -1211,7 +1233,7 @@
"$(SRCROOT)/../node_modules/react-native-image-resizer/ios/RCTImageResizer",
"$(SRCROOT)/../node_modules/react-native-splash-screen/ios/**",
);
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LIBRARY_SEARCH_PATHS = (
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
"\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"",

View File

@ -127,5 +127,12 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
<string>A00000080400010101</string>
<string>A00000080400010301</string>
</array>
<key>NFCReaderUsageDescription</key>
<string>Enable Keycard</string>
</dict>
</plist>

View File

@ -2,6 +2,11 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>NDEF</string>
<string>TAG</string>
</array>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.associated-domains</key>

View File

@ -133,5 +133,12 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
<string>A00000080400010101</string>
<string>A00000080400010301</string>
</array>
<key>NFCReaderUsageDescription</key>
<string>Enable Keycard</string>
</dict>
</plist>

View File

@ -2,6 +2,11 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>NDEF</string>
<string>TAG</string>
</array>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.associated-domains</key>

View File

@ -0,0 +1,4 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//

View File

@ -20,5 +20,12 @@
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
<string>A00000080400010101</string>
<string>A00000080400010301</string>
</array>
<key>NFCReaderUsageDescription</key>
<string>Enable Keycard</string>
</dict>
</plist>

View File

@ -301,6 +301,37 @@ RCT_EXPORT_METHOD(hashTransaction:(NSString *)txArgsJSON
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// hashMessage
RCT_EXPORT_METHOD(hashMessage:(NSString *)message
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"hashMessage() method called");
#endif
NSString *result = StatusgoHashMessage(message);
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// hashTypedData
RCT_EXPORT_METHOD(hashTypedData:(NSString *)data
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"hashTypedData() method called");
#endif
NSString *result = StatusgoHashTypedData(data);
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// sendTransactionWithSignature
RCT_EXPORT_METHOD(sendTransactionWithSignature:(NSString *)txArgsJSON
signature:(NSString *)signature
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"sendTransactionWithSignature() method called");
#endif
NSString *result = StatusgoSendTransactionWithSignature(txArgsJSON, signature);
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// multiAccountImportMnemonic
RCT_EXPORT_METHOD(multiAccountImportMnemonic:(NSString *)json
callback:(RCTResponseSenderBlock)callback) {

View File

@ -4,6 +4,7 @@
"private": true,
"scripts": {
"start": "react-native start",
"ios": "react-native run-ios",
"app:compile:android": "shadow-cljs compile android",
"app:watch": "shadow-cljs watch android",
"app:packager": "react-native start --host 0.0.0.0 --port 8081",
@ -60,7 +61,7 @@
"react-native-screens": "^2.10.1",
"react-native-shake": "^3.3.1",
"react-native-splash-screen": "^3.2.0",
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#v2.5.28",
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#v2.5.30",
"react-native-svg": "^9.8.4",
"react-native-touch-id": "^4.4.1",
"react-native-webview": "git+https://github.com/status-im/react-native-webview.git#v10.9.2",

View File

@ -31,6 +31,7 @@
disable-drag? :disableDrag?
show-handle? :showHandle?
visible? :visible?
transparent :transparent
backdrop-dismiss? :backdropDismiss?
back-button-cancel :backButtonCancel
children :children
@ -189,6 +190,7 @@
(when back-button-cancel
(close-sheet)))}
[rn/view {:style styles/container
:opacity (if transparent 0 1)
:pointer-events :box-none}
[gesture-handler/tap-gesture-handler (merge {:enabled backdrop-dismiss?}
tap-gesture-handler)

View File

@ -1,61 +1,57 @@
(ns status-im.keycard.card
(:require [re-frame.core :as re-frame]
[status-im.keycard.ios-keycard :as ios-keycard]
[status-im.keycard.keycard :as keycard]
[status-im.keycard.real-keycard :as real-keycard]
[status-im.keycard.simulated-keycard :as simulated-keycard]
[status-im.utils.config :as config]
[status-im.utils.platform :as platform]
[taoensso.timbre :as log]))
(defonce card (if config/keycard-test-menu-enabled?
(simulated-keycard/SimulatedKeycard.)
(if platform/android?
(real-keycard/RealKeycard.)
(ios-keycard/IOSKeycard.))))
(real-keycard/RealKeycard.)))
(defn check-nfc-support []
(log/info "[keycard] check-nfc-support")
(log/debug "[keycard] check-nfc-support")
(keycard/check-nfc-support
card
{:on-success
(fn [response]
(log/info "[keycard response] check-nfc-support")
(log/debug "[keycard response] check-nfc-support")
(re-frame/dispatch
[:keycard.callback/check-nfc-support-success response]))}))
(defn check-nfc-enabled []
(log/info "[keycard] check-nfc-enabled")
(log/debug "[keycard] check-nfc-enabled")
(keycard/check-nfc-enabled
card
{:on-success
(fn [response]
(log/info "[keycard response] check-nfc-enabled")
(log/debug "[keycard response] check-nfc-enabled")
(re-frame/dispatch
[:keycard.callback/check-nfc-enabled-success response]))}))
(defn open-nfc-settings []
(log/info "[keycard] open-nfc-settings")
(log/debug "[keycard] open-nfc-settings")
(keycard/open-nfc-settings card))
(defn remove-event-listener [event]
(log/info "[keycard] remove-event-listener")
(log/debug "[keycard] remove-event-listener")
(keycard/remove-event-listener card event))
(defn on-card-disconnected [callback]
(log/info "[keycard] on-card-disconnected")
(log/debug "[keycard] on-card-disconnected")
(keycard/on-card-disconnected card callback))
(defn on-card-connected [callback]
(log/info "[keycard] on-card-connected")
(log/debug "[keycard] on-card-connected")
(keycard/on-card-connected card callback))
(defn remove-event-listeners []
(log/info "[keycard] remove-event-listeners")
(log/debug "[keycard] remove-event-listeners")
(keycard/remove-event-listeners card))
(defn register-card-events []
(log/info "[keycard] register-card-events")
(log/debug "[keycard] register-card-events")
(keycard/register-card-events
card
{:on-card-connected
@ -64,6 +60,12 @@
:on-card-disconnected
#(re-frame/dispatch [:keycard.callback/on-card-disconnected])
:on-nfc-user-cancelled
#(re-frame/dispatch [:keycard.callback/on-nfc-user-cancelled])
:on-nfc-timeout
#(re-frame/dispatch [:keycard.callback/on-nfc-timeout])
:on-nfc-enabled
#(re-frame/dispatch [:keycard.callback/check-nfc-enabled-success true])
@ -75,188 +77,188 @@
:error (.-message object)})
(defn get-application-info [{:keys [on-success] :as args}]
(log/info "[keycard] get-application-info")
(log/debug "[keycard] get-application-info")
(keycard/get-application-info
card
(merge
args
{:on-success
(fn [response]
(log/info "[keycard response succ] get-application-info")
(log/debug "[keycard response succ] get-application-info")
(re-frame/dispatch
[:keycard.callback/on-get-application-info-success
response on-success]))
:on-failure
(fn [response]
(log/info "[keycard response fail] get-application-info")
(log/debug "[keycard response fail] get-application-info")
(re-frame/dispatch
[:keycard.callback/on-get-application-info-error
(error-object->map response)]))})))
(defn install-applet []
(log/info "[keycard] install-applet")
(log/debug "[keycard] install-applet")
(keycard/install-applet
card
{:on-success
(fn [response]
(log/info "[keycard response succ] install-applet")
(log/debug "[keycard response succ] install-applet")
(re-frame/dispatch
[:keycard.callback/on-install-applet-success response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] install-applet")
(log/debug "[keycard response fail] install-applet")
(re-frame/dispatch
[:keycard.callback/on-install-applet-error
(error-object->map response)]))}))
(defn init-card [pin]
(log/info "[keycard] init-card")
(log/debug "[keycard] init-card")
(keycard/init-card
card
{:pin pin
:on-success
(fn [response]
(log/info "[keycard response succ] init-card")
(log/debug "[keycard response succ] init-card")
(re-frame/dispatch
[:keycard.callback/on-init-card-success response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] init-card")
(log/debug "[keycard response fail] init-card")
(re-frame/dispatch
[:keycard.callback/on-init-card-error
(error-object->map response)]))}))
(defn install-applet-and-init-card [pin]
(log/info "[keycard] install-applet-and-init-card")
(log/debug "[keycard] install-applet-and-init-card")
(keycard/install-applet-and-init-card
card
{:pin pin
:on-success
(fn [response]
(log/info "[keycard response succ] install-applet-and-init-card")
(log/debug "[keycard response succ] install-applet-and-init-card")
#(re-frame/dispatch
[:keycard.callback/on-install-applet-and-init-card-success
response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] install-applet-and-init-card")
(log/debug "[keycard response fail] install-applet-and-init-card")
(re-frame/dispatch
[:keycard.callback/on-install-applet-and-init-card-error
(error-object->map response)]))}))
(defn pair [args]
(log/info "[keycard] pair")
(log/debug "[keycard] pair")
(keycard/pair
card
(merge
args
{:on-success
(fn [response]
(log/info "[keycard response succ] pair")
(log/debug "[keycard response succ] pair")
(re-frame/dispatch
[:keycard.callback/on-pair-success response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] pair")
(log/debug "[keycard response fail] pair")
(re-frame/dispatch
[:keycard.callback/on-pair-error (error-object->map response)]))})))
(defn generate-and-load-key [args]
(log/info "[keycard] generate-and-load-key")
(log/debug "[keycard] generate-and-load-key")
(keycard/generate-and-load-key
card
(merge
args
{:on-success
(fn [response]
(log/info "[keycard response succ] generate-and-load-key")
(log/debug "[keycard response succ] generate-and-load-key")
(re-frame/dispatch
[:keycard.callback/on-generate-and-load-key-success response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] generate-and-load-key")
(log/debug "[keycard response fail] generate-and-load-key")
(re-frame/dispatch
[:keycard.callback/on-generate-and-load-key-error
(error-object->map response)]))})))
(defn unblock-pin [args]
(log/info "[keycard] unblock-pin")
(log/debug "[keycard] unblock-pin")
(keycard/unblock-pin
card
(merge
args
{:on-success
(fn [response]
(log/info "[keycard response succ] unblock-pin")
(log/debug "[keycard response succ] unblock-pin")
(re-frame/dispatch
[:keycard.callback/on-unblock-pin-success response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] unblock-pin")
(log/debug "[keycard response fail] unblock-pin")
(re-frame/dispatch [:keycard.callback/on-unblock-pin-error
(error-object->map response)]))})))
(defn verify-pin [args]
(log/info "[keycard] verify-pin")
(log/debug "[keycard] verify-pin")
(keycard/verify-pin
card
(merge
args
{:on-success
(fn [response]
(log/info "[keycard response succ] verify-pin")
(log/debug "[keycard response succ] verify-pin")
(re-frame/dispatch [:keycard.callback/on-verify-pin-success
response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] verify-pin")
(log/debug "[keycard response fail] verify-pin")
(re-frame/dispatch
[:keycard.callback/on-verify-pin-error
(error-object->map response)]))})))
(defn change-pin [args]
(log/info "[keycard] change-pin")
(log/debug "[keycard] change-pin")
(keycard/change-pin
card
(merge
args
{:on-success
(fn [response]
(log/info "[keycard response succ] change-pin")
(log/debug "[keycard response succ] change-pin")
(re-frame/dispatch
[:keycard.callback/on-change-pin-success response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] change-pin")
(log/debug "[keycard response fail] change-pin")
(re-frame/dispatch
[:keycard.callback/on-change-pin-error
(error-object->map response)]))})))
(defn unpair [args]
(log/info "[keycard] unpair")
(log/debug "[keycard] unpair")
(keycard/unpair
card
(merge
args
{:on-success
(fn [response]
(log/info "[keycard response succ] unpair")
(log/debug "[keycard response succ] unpair")
(re-frame/dispatch
[:keycard.callback/on-unpair-success response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] unpair")
(log/debug "[keycard response fail] unpair")
(re-frame/dispatch
[:keycard.callback/on-unpair-error
(error-object->map response)]))})))
(defn delete []
(log/info "[keycard] delete")
(log/debug "[keycard] delete")
(keycard/delete
card
{:on-success
(fn [response]
(log/info "[keycard response succ] delete")
(log/debug "[keycard response succ] delete")
(re-frame/dispatch
[:keycard.callback/on-delete-success response]))
:on-failure
@ -267,107 +269,107 @@
(error-object->map response)]))}))
(defn remove-key [args]
(log/info "[keycard] remove-key")
(log/debug "[keycard] remove-key")
(keycard/remove-key
card
(merge
args
{:on-success
(fn [response]
(log/info "[keycard response succ] remove-key")
(log/debug "[keycard response succ] remove-key")
(re-frame/dispatch [:keycard.callback/on-remove-key-success
response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] remove-key")
(log/debug "[keycard response fail] remove-key")
(re-frame/dispatch [:keycard.callback/on-remove-key-error
(error-object->map response)]))})))
(defn remove-key-with-unpair [args]
(log/info "[keycard] remove-key-with-unpair")
(log/debug "[keycard] remove-key-with-unpair")
(keycard/remove-key-with-unpair
card
(merge
args
{:on-success
(fn [response]
(log/info "[keycard response succ] remove-key-with-unpair")
(log/debug "[keycard response succ] remove-key-with-unpair")
(re-frame/dispatch [:keycard.callback/on-remove-key-success
response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] remove-key-with-unpair")
(log/debug "[keycard response fail] remove-key-with-unpair")
(re-frame/dispatch [:keycard.callback/on-remove-key-error
(error-object->map response)]))})))
(defn export-key [args]
(log/info "[keycard] export-key")
(log/debug "[keycard] export-key")
(keycard/export-key
card
(merge
args
{:on-success
(fn [response]
(log/info "[keycard response succ] export-key")
(log/debug "[keycard response succ] export-key")
(re-frame/dispatch [:keycard.callback/on-export-key-success
response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] export-key")
(log/debug "[keycard response fail] export-key")
(re-frame/dispatch [:keycard.callback/on-export-key-error
(error-object->map response)]))})))
(defn unpair-and-delete [args]
(log/info "[keycard] unpair-and-delete")
(log/debug "[keycard] unpair-and-delete")
(keycard/unpair-and-delete
card
(merge
args
{:on-success
(fn [response]
(log/info "[keycard response succ] unpair-and-delete")
(log/debug "[keycard response succ] unpair-and-delete")
(re-frame/dispatch [:keycard.callback/on-delete-success
response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] unpair-and-delete")
(log/debug "[keycard response fail] unpair-and-delete")
(re-frame/dispatch [:keycard.callback/on-delete-error
(error-object->map response)]))})))
(defn get-keys [{:keys [on-success] :as args}]
(log/info "[keycard] get-keys")
(log/debug "[keycard] get-keys")
(keycard/get-keys
card
(merge
args
{:on-success
(fn [response]
(log/info "[keycard response succ] get-keys")
(log/debug "[keycard response succ] get-keys")
(re-frame/dispatch
[(or on-success :keycard.callback/on-get-keys-success)
response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] get-keys"
(log/debug "[keycard response fail] get-keys"
(error-object->map response))
(re-frame/dispatch [:keycard.callback/on-get-keys-error
(error-object->map response)]))})))
(defn sign [{:keys [on-success on-failure] :as args}]
(log/info "[keycard] sign")
(log/debug "[keycard] sign")
(keycard/sign
card
(merge
args
{:on-success
(fn [response]
(log/info "[keycard response succ] sign")
(log/debug "[keycard response succ] sign")
(if on-success
(on-success response)
(re-frame/dispatch [:keycard.callback/on-sign-success response])))
:on-failure
(fn [response]
(log/info "[keycard response fail] sign")
(log/debug "[keycard response fail] sign")
(if on-failure
(on-failure response)
(re-frame/dispatch
@ -375,35 +377,35 @@
(error-object->map response)])))})))
(defn install-cash-applet []
(log/info "[keycard] install-cash-applet")
(log/debug "[keycard] install-cash-applet")
(keycard/install-cash-applet
card
{:on-success
(fn [response]
(log/info "[keycard response succ] install-cash-applet")
(log/debug "[keycard response succ] install-cash-applet")
(re-frame/dispatch
[:keycard.callback/on-install-applet-success response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] install-cash-applet")
(log/debug "[keycard response fail] install-cash-applet")
(re-frame/dispatch
[:keycard.callback/on-install-applet-error
(error-object->map response)]))}))
(defn sign-typed-data
[{:keys [hash]}]
(log/info "[keycard] sign-typed-data")
(log/debug "[keycard] sign-typed-data")
(keycard/sign-typed-data
card
{:hash hash
:on-success
(fn [response]
(log/info "[keycard response succ] sign-typed-data")
(log/debug "[keycard response succ] sign-typed-data")
(re-frame/dispatch [:keycard.callback/on-sign-success
response]))
:on-failure
(fn [response]
(log/info "[keycard response fail] sign-typed-data")
(log/debug "[keycard response fail] sign-typed-data")
(re-frame/dispatch
[:keycard.callback/on-sign-error
(error-object->map response)]))}))
@ -416,3 +418,12 @@
(defn send-transaction-with-signature [args]
(keycard/send-transaction-with-signature card args))
(defn start-nfc [args]
(keycard/start-nfc card args))
(defn stop-nfc [args]
(keycard/stop-nfc card args))
(defn set-nfc-message [args]
(keycard/set-nfc-message card args))

View File

@ -96,23 +96,27 @@
{:events [:keycard.callback/on-change-pin-error]}
[{:keys [db] :as cofx} error]
(log/debug "[keycard] change pin error" error)
(let [tag-was-lost? (= "Tag was lost." (:error error))
pairing (common/get-pairing db)]
(let [tag-was-lost? (common/tag-lost? (:error error))
pairing (common/get-pairing db)
pin-retries (common/pin-retries (:error error))]
(fx/merge cofx
(if tag-was-lost?
(fx/merge cofx
{:db (assoc-in db [:keycard :pin :status] nil)}
(common/set-on-card-connected :keycard/change-pin))
(if (re-matches common/pin-mismatch-error (:error error))
(if-not (nil? pin-retries)
(fx/merge cofx
{:db (update-in db [:keycard :pin] merge {:status :error
{:db (-> db
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries)
(update-in [:keycard :pin] assoc
:status :error
:enter-step :current
:puk []
:current []
:original []
:confirmation []
:sign []
:error-label :t/pin-mismatch})}
(navigation/navigate-to-cofx :enter-pin-settings nil)
(common/get-application-info pairing nil))
:error-label :t/pin-mismatch))}
(when (zero? pin-retries) (common/frozen-keycard-popup))
(navigation/navigate-to-cofx :enter-pin-settings nil))
(common/show-wrong-keycard-alert true))))))

View File

@ -10,11 +10,15 @@
[status-im.utils.keychain.core :as keychain]
[status-im.utils.types :as types]
[taoensso.timbre :as log]
[status-im.bottom-sheet.core :as bottom-sheet]))
[status-im.bottom-sheet.core :as bottom-sheet]
[status-im.utils.platform :as platform]))
(def default-pin "000000")
(def pin-mismatch-error #"Unexpected error SW, 0x63C\d+")
(def pin-mismatch-error #"Unexpected error SW, 0x63C(\d+)|wrongPIN\(retryCounter: (\d+)\)")
(defn pin-retries [error]
(when-let [matched-error (re-matches pin-mismatch-error error)] (js/parseInt (second (filter some? matched-error)))))
(fx/defn dispatch-event
[_ event]
@ -51,7 +55,10 @@
:no-pairing-slots))
(defn tag-lost? [error]
(= error "Tag was lost."))
(or
(= error "Tag was lost.")
(= error "NFCError:100")
(re-matches #".*NFCError:100.*" error)))
(defn find-multiaccount-by-keycard-instance-uid
[db keycard-instance-uid]
@ -168,7 +175,7 @@
:on-connect ::on-card-connected
:on-disconnect ::on-card-disconnected})))
(fx/defn show-connection-sheet
(fx/defn show-connection-sheet-component
[{:keys [db] :as cofx} {:keys [on-card-connected on-card-read handler]
{:keys [on-cancel]
:or {on-cancel [::cancel-sheet-confirm]}}
@ -182,7 +189,8 @@
cofx
{:dismiss-keyboard true}
(bottom-sheet/show-bottom-sheet
{:view {:show-handle? false
{:view {:transparent platform/ios?
:show-handle? false
:backdrop-dismiss? false
:disable-drag? true
:back-button-cancel false
@ -195,7 +203,21 @@
(when connected?
handler))))
(fx/defn hide-connection-sheet
(fx/defn show-connection-sheet
[{:keys [db] :as cofx} args]
(let [nfc-running? (get-in db [:keycard :nfc-running?])]
(log/debug "show connection; already running?" nfc-running?)
(if nfc-running?
(show-connection-sheet-component cofx args)
{:keycard/start-nfc-and-show-connection-sheet args})))
(fx/defn on-nfc-ready-for-sheet
{:events [:keycard.callback/show-connection-sheet]}
[cofx args]
(log/debug "on-nfc-ready-for-sheet")
(show-connection-sheet-component cofx args))
(fx/defn hide-connection-sheet-component
[{:keys [db] :as cofx}]
(fx/merge cofx
{:db (assoc-in db [:keycard :card-read-in-progress?] false)}
@ -203,6 +225,17 @@
(restore-on-card-read)
(bottom-sheet/hide-bottom-sheet)))
(fx/defn hide-connection-sheet
[cofx]
(log/debug "hide-connection-sheet")
{:keycard/stop-nfc-and-hide-connection-sheet nil})
(fx/defn on-nfc-ready-to-close-sheet
{:events [:keycard.callback/hide-connection-sheet]}
[cofx]
(log/debug "on-nfc-ready-to-close-sheet")
(hide-connection-sheet-component cofx))
(fx/defn clear-pin
[{:keys [db] :as cofx}]
(fx/merge
@ -286,7 +319,8 @@
(defn- tag-lost-exception? [code error]
(or
(= code "android.nfc.TagLostException")
(= error "Tag was lost.")))
(= error "Tag was lost.")
(= error "NFCError:100")))
(fx/defn process-error [{:keys [db]} code error]
(when-not (tag-lost-exception? code error)
@ -342,28 +376,37 @@
(clear-on-card-read)
(hide-connection-sheet))))
(fx/defn frozen-keycard-popup
[{:keys [db] :as cofx}]
(if (:multiaccounts/login db)
(fx/merge
cofx
{:db (assoc-in db [:keycard :pin :status] :frozen-card)}
hide-connection-sheet)
{:db (assoc db :popover/popover {:view :frozen-card})}))
(fx/defn on-get-keys-error
{:events [:keycard.callback/on-get-keys-error]}
[{:keys [db] :as cofx} error]
(log/debug "[keycard] get keys error: " error)
(let [tag-was-lost? (tag-lost? (:error error))
key-uid (get-in db [:keycard :application-info :key-uid])
flow (get-in db [:keycard :flow])]
flow (get-in db [:keycard :flow])
pin-retries-count (pin-retries (:error error))]
(if tag-was-lost?
{:db (assoc-in db [:keycard :pin :status] nil)}
(if (re-matches pin-mismatch-error (:error error))
(if-not (nil? pin-retries-count)
(fx/merge
cofx
{:keycard/get-application-info
{:pairing (get-pairing db key-uid)}
:db
(update-in db [:keycard :pin] merge
{:status :error
{:db (-> db
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries-count)
(update-in [:keycard :pin] assoc
:status :error
:login []
:import-multiaccount []
:error-label :t/pin-mismatch})}
:error-label :t/pin-mismatch))}
(hide-connection-sheet)
(when (zero? pin-retries-count) (frozen-keycard-popup))
(when (= flow :import)
(navigation/navigate-to-cofx :keycard-recovery-pin nil)))
(show-wrong-keycard-alert true)))))
@ -384,15 +427,6 @@
{:keycard/get-application-info {:pairing pairing'
:on-success on-card-read}}))
(fx/defn frozen-keycard-popup
[{:keys [db] :as cofx}]
(if (:multiaccounts/login db)
(fx/merge
cofx
{:db (assoc-in db [:keycard :pin :status] :frozen-card)}
hide-connection-sheet)
{:db (assoc db :popover/popover {:view :frozen-card})}))
(fx/defn on-get-application-info-success
{:events [:keycard.callback/on-get-application-info-success]}
[{:keys [db] :as cofx} info on-success]
@ -426,7 +460,6 @@
hide-connection-sheet)
(when on-success'
(dispatch-event cofx on-success')))))))
(fx/defn on-get-application-info-error
{:events [:keycard.callback/on-get-application-info-error]}
[{:keys [db] :as cofx} error]

View File

@ -5,7 +5,7 @@
(deftest test-show-connection-sheet
(testing "the card is not connected yet"
(let [db {:keycard {:card-connected? false}}
res (common/show-connection-sheet
res (common/show-connection-sheet-component
{:db db}
{:on-card-connected :do-something
:handler (fn [{:keys [db]}]
@ -16,7 +16,7 @@
(is (true? (get-in res [:db :bottom-sheet/show?])))))
(testing "the card is connected before the interaction"
(let [db {:keycard {:card-connected? true}}
res (common/show-connection-sheet
res (common/show-connection-sheet-component
{:db db}
{:on-card-connected :do-something
:handler (fn [{:keys [db]}]
@ -30,13 +30,13 @@
(is
(thrown?
js/Error
(common/show-connection-sheet
(common/show-connection-sheet-component
{:db {}}
{:handler (fn [_])}))))
(testing "handler is not specified"
(is
(thrown?
js/Error
(common/show-connection-sheet
(common/show-connection-sheet-component
{:db {}}
{:on-card-connected :do-something})))))

View File

@ -135,18 +135,19 @@
(let [pairing (common/get-pairing db)
reset-pin (get-in db [:keycard :pin :reset])]
(fx/merge cofx
{:keycard/get-application-info
{:pairing pairing}
:db
(update-in db [:keycard :pin] merge
{:status :after-unblocking
{:db
(-> db
(update-in [:keycard :application-info] assoc
:puk-retry-counter 5
:pin-retry-counter 3)
(update-in [:keycard :pin] assoc
:status :after-unblocking
:enter-step :login
:login reset-pin
:confirmation []
:puk []
:puk-restore? true
:error-label nil})}
:error-label nil))}
(common/hide-connection-sheet)
(common/clear-on-card-connected)
(common/clear-on-card-read))))
@ -155,19 +156,20 @@
{:events [:keycard.callback/on-unblock-pin-error]}
[{:keys [db] :as cofx} error]
(let [pairing (common/get-pairing db)
tag-was-lost? (common/tag-lost? (:error error))]
tag-was-lost? (common/tag-lost? (:error error))
puk-retries (common/pin-retries (:error error))]
(log/debug "[keycard] unblock pin error" error)
(when-not tag-was-lost?
(fx/merge cofx
{:keycard/get-application-info
{:pairing pairing}
:db
(update-in db [:keycard :pin] merge
{:status :error
{:db
(-> db
(assoc-in [:keycard :application-info :puk-retry-counter] puk-retries)
(update-in [:keycard :pin] merge
{:status (if (zero? puk-retries) :blocked-card :error)
:error-label :t/puk-mismatch
:enter-step :puk
:puk []})}
:puk []}))}
(common/hide-connection-sheet)))))
(fx/defn clear-on-verify-handlers
@ -188,8 +190,9 @@
(common/clear-on-card-read)
;; TODO(Ferossgp): Each pin input should handle this event on it's own,
;; now for simplicity do not hide bottom sheet when generating key
;; but should be refactored.
(when-not (= on-verified :keycard/generate-and-load-key)
;; and exporting key but should be refactored.
(when-not (contains? #{:keycard/generate-and-load-key
:wallet.accounts/generate-new-keycard-account} on-verified)
(common/hide-connection-sheet))
(when-not (contains? #{:keycard/unpair
:keycard/generate-and-load-key
@ -207,28 +210,30 @@
(let [tag-was-lost? (common/tag-lost? (:error error))
setup? (boolean (get-in db [:keycard :setup-step]))
on-verified-failure (get-in db [:keycard :pin :on-verified-failure])
exporting? (get-in db [:keycard :on-export-success])]
exporting? (get-in db [:keycard :on-export-success])
pin-retries (common/pin-retries (:error error))]
(log/debug "[keycard] verify pin error" error)
(when-not tag-was-lost?
(if (re-matches common/pin-mismatch-error (:error error))
(if-not (nil? pin-retries)
(fx/merge cofx
{:db (update-in db [:keycard :pin]
merge
{:status :error
{:db (-> db
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries)
(update-in [:keycard :pin] assoc
:status :error
:enter-step :current
:puk []
:current []
:original []
:confirmation []
:sign []
:error-label :t/pin-mismatch})}
:error-label :t/pin-mismatch))}
(common/hide-connection-sheet)
(when (and (not setup?)
(not on-verified-failure))
(if exporting?
(navigation/navigate-back)
(navigation/navigate-to-cofx :enter-pin-settings nil)))
(common/get-application-info (common/get-pairing db) nil)
(when (zero? pin-retries) (common/frozen-keycard-popup))
(when on-verified-failure
(fn [_] {:utils/dispatch-later
[{:dispatch [on-verified-failure]
@ -414,7 +419,7 @@
(assoc-in [:keycard :setup-step] next-step)
(assoc-in [:keycard :secrets :pairing] pairing)
(assoc-in [:keycard :secrets :paired-on] paired-on))}
(common/hide-connection-sheet)
(when-not (and (= flow :recovery) (= next-step :card-ready)) (common/hide-connection-sheet))
(when multiaccount
(set-multiaccount-pairing multiaccount pairing paired-on))
(when (= flow :login)
@ -525,6 +530,21 @@
(log/debug "[keycard] card disconnected")
{:db (assoc-in db [:keycard :card-connected?] false)})
(fx/defn on-nfc-user-cancelled
{:events [:keycard.callback/on-nfc-user-cancelled]}
[{:keys [db]} _]
(log/debug "[keycard] nfc user cancelled")
{:dispatch [:signing.ui/cancel-is-pressed]})
(fx/defn on-nfc-timeout
{:events [:keycard.callback/on-nfc-timeout]}
[{:keys [db]} _]
(log/debug "[keycard] nfc timeout")
{:db (-> db
(assoc-in [:keycard :nfc-running?] false)
(assoc-in [:keycard :card-connected?] false))
:keycard/start-nfc nil})
(fx/defn on-register-card-events
{:events [:keycard.callback/on-register-card-events]}
[{:keys [db]} listeners]
@ -553,3 +573,39 @@
[{:keys [db]} step]
(when-not (empty? (get-in db [:keycard :pin step]))
{:db (update-in db [:keycard :pin step] pop)}))
(fx/defn start-nfc
{:events [:keycard.ui/start-nfc]}
[cofx]
{:keycard/start-nfc nil})
(fx/defn stop-nfc
{:events [:keycard.ui/stop-nfc]}
[cofx]
{:keycard/stop-nfc nil
:keycard.callback/on-card-disconnected nil})
(fx/defn start-nfc-success
{:events [:keycard.callback/start-nfc-success]}
[{:keys [db]} _]
(log/debug "[keycard] nfc started success")
{:db (assoc-in db [:keycard :nfc-running?] true)})
(fx/defn start-nfc-failure
{:events [:keycard.callback/start-nfc-failure]}
[{:keys [db]} _]
(log/debug "[keycard] nfc failed starting")) ;; leave current value on :nfc-running
(fx/defn stop-nfc-success
{:events [:keycard.callback/stop-nfc-success]}
[{:keys [db]} _]
(log/debug "[keycard] nfc stopped success")
(log/debug "[keycard] setting card-connected? and nfc-running? to false")
{:db (-> db
(assoc-in [:keycard :nfc-running?] false)
(assoc-in [:keycard :card-connected?] false))})
(fx/defn stop-nfc-failure
{:events [:keycard.callback/stop-nfc-failure]}
[{:keys [db]} _]
(log/debug "[keycard] nfc failed stopping")) ;; leave current value on :nfc-running

View File

@ -8,15 +8,19 @@
{:events [:keycard.callback/on-export-key-error]}
[{:keys [db] :as cofx} error]
(log/debug "[keycard] export key error" error)
(let [tag-was-lost? (common/tag-lost? (:error error))]
(let [tag-was-lost? (common/tag-lost? (:error error))
pin-retries (common/pin-retries (:error error))]
(cond tag-was-lost?
(fx/merge cofx
{:db (assoc-in db [:keycard :pin :status] nil)}
(common/set-on-card-connected :wallet.accounts/generate-new-keycard-account))
(re-matches common/pin-mismatch-error (:error error))
(not (nil? pin-retries))
(fx/merge cofx
{:db (update-in db [:keycard :pin] merge {:status :error
{:db (-> db
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries)
(update-in [:keycard :pin] assoc
:status :error
:enter-step :export-key
:puk []
:current []
@ -24,10 +28,9 @@
:confirmation []
:sign []
:export-key []
:error-label :t/pin-mismatch})}
:error-label :t/pin-mismatch))}
(common/hide-connection-sheet)
(common/get-application-info (common/get-pairing db) nil))
(when (zero? pin-retries) (common/frozen-keycard-popup)))
:else
(fx/merge cofx
(common/show-wrong-keycard-alert true)

View File

@ -3,10 +3,58 @@
[status-im.utils.types :as types]
[status-im.keycard.card :as card]
[status-im.native-module.core :as status]
[status-im.utils.platform :as platform]
["react-native" :refer (BackHandler)]
[taoensso.timbre :as log]
["@react-native-community/async-storage" :default AsyncStorage]))
(re-frame/reg-fx
:keycard/start-nfc
(fn []
(log/debug "fx start-nfc")
(card/start-nfc
{:on-success #(re-frame/dispatch [:keycard.callback/start-nfc-success])
:on-failure #(re-frame/dispatch [:keycard.callback/start-nfc-failure])})))
(re-frame/reg-fx
:keycard/stop-nfc
(fn []
(log/debug "fx stop-nfc")
(card/stop-nfc
{:on-success #(re-frame/dispatch [:keycard.callback/stop-nfc-success])
:on-failure #(re-frame/dispatch [:keycard.callback/stop-nfc-failure])})))
(re-frame/reg-fx
:keycard/set-nfc-message
card/set-nfc-message)
(re-frame/reg-fx
:keycard/start-nfc-and-show-connection-sheet
(fn [args]
(log/debug "fx start-nfc-and-show-connection-sheet")
(card/start-nfc
{:on-success
(fn []
(log/debug "nfc started successfully. next: show-connection-sheet")
(re-frame/dispatch [:keycard.callback/start-nfc-success])
(re-frame/dispatch [:keycard.callback/show-connection-sheet args]))
:on-failure
(fn []
(log/debug "nfc failed star starting. not calling show-connection-sheet")
(re-frame/dispatch [:keycard.callback/start-nfc-failure]))})))
(re-frame/reg-fx
:keycard/stop-nfc-and-hide-connection-sheet
(fn []
(log/debug "fx stop-nfc-and-hide-connection-sheet")
(card/stop-nfc
{:on-success
(fn []
(re-frame/dispatch [:keycard.callback/stop-nfc-success])
(re-frame/dispatch [:keycard.callback/hide-connection-sheet]))
:on-failure
(fn []
(re-frame/dispatch [:keycard.callback/stop-nfc-failure]))})))
(re-frame/reg-fx
:keycard/get-application-info
card/get-application-info)
@ -112,11 +160,10 @@
(re-frame/reg-fx
:keycard/retrieve-pairings
(fn []
(when platform/android?
(.. AsyncStorage
(getItem "status-keycard-pairings")
(then #(re-frame/dispatch [:keycard.callback/on-retrieve-pairings-success
(types/deserialize %)]))))))
(types/deserialize %)])))))
;; TODO: Should act differently on different views
(re-frame/reg-fx

View File

@ -1,6 +1,9 @@
(ns status-im.keycard.keycard)
(defprotocol Keycard
(start-nfc [this args])
(stop-nfc [this args])
(set-nfc-message [this args])
(check-nfc-support [this args])
(check-nfc-enabled [this args])
(open-nfc-settings [this])

View File

@ -123,7 +123,7 @@
(and (zero? pin-retry-counter)
(or (nil? puk-retry-counter)
(= 5 puk-retry-counter)))
(pos? puk-retry-counter)))
nil #_(frozen-keycard-popup cofx)
:else

View File

@ -5,11 +5,36 @@
[status-im.native-module.core :as status]
[status-im.ethereum.core :as ethereum]
[status-im.keycard.keycard :as keycard]
[taoensso.timbre :as log]))
[taoensso.timbre :as log]
[status-im.utils.platform :as platform]))
(defonce event-emitter (if platform/ios?
(new (.-NativeEventEmitter rn) status-keycard)
(.-DeviceEventEmitter rn)))
(defonce event-emitter (.-DeviceEventEmitter rn))
(defonce active-listeners (atom []))
(defn start-nfc [{:keys [on-success on-failure prompt-message]}]
(log/debug "start-nfc")
(.. status-keycard
(startNFC (str prompt-message))
(then on-success)
(catch on-failure)))
(defn stop-nfc [{:keys [on-success on-failure error-message]}]
(log/debug "stop-nfc")
(.. status-keycard
(stopNFC (str error-message))
(then on-success)
(catch on-failure)))
(defn set-nfc-message [{:keys [on-success on-failure status-message]}]
(log/debug "set-nfc-message")
(.. status-keycard
(setNFCMessage (str status-message))
(then on-success)
(catch on-failure)))
(defn check-nfc-support [{:keys [on-success]}]
(.. status-keycard
nfcIsSupported
@ -24,7 +49,7 @@
(.openNfcSettings status-keycard))
(defn remove-event-listeners []
(doseq [event ["keyCardOnConnected" "keyCardOnDisconnected"]]
(doseq [event ["keyCardOnConnected" "keyCardOnDisconnected", "keyCardOnNFCUserCancelled", "keyCardOnNFCTimeout"]]
(.removeAllListeners ^js event-emitter event)))
(defn remove-event-listener
@ -39,6 +64,14 @@
[callback]
(.addListener ^js event-emitter "keyCardOnDisconnected" callback))
(defn on-nfc-user-cancelled
[callback]
(.addListener ^js event-emitter "keyCardOnNFCUserCancelled" callback))
(defn on-nfc-timeout
[callback]
(.addListener ^js event-emitter "keyCardOnNFCTimeout" callback))
(defn on-nfc-enabled
[callback]
(.addListener ^js event-emitter "keyCardOnNFCEnabled" callback))
@ -54,6 +87,8 @@
(reset! active-listeners
[(on-card-connected (:on-card-connected args))
(on-card-disconnected (:on-card-disconnected args))
(on-nfc-user-cancelled (:on-nfc-user-cancelled args))
(on-nfc-timeout (:on-nfc-timeout args))
(on-nfc-enabled (:on-nfc-enabled args))
(on-nfc-disabled (:on-nfc-disabled args))]))
@ -226,6 +261,12 @@
(defrecord RealKeycard []
keycard/Keycard
(keycard/start-nfc [this args]
(start-nfc args))
(keycard/stop-nfc [this args]
(stop-nfc args))
(keycard/set-nfc-message [this args]
(set-nfc-message args))
(keycard/check-nfc-support [this args]
(check-nfc-support args))
(keycard/check-nfc-enabled [this args]

View File

@ -215,6 +215,7 @@
(update :instance-uid #(get-in db [:keycard :multiaccount :instance-uid] %))))
(assoc-in [:keycard :multiaccount-wallet-address] (:wallet-address account-data))
(assoc-in [:keycard :multiaccount-whisper-public-key] (:whisper-public-key account-data))
(assoc-in [:keycard :pin :status] nil)
(assoc-in [:keycard :application-info :key-uid]
(ethereum/normalized-hex (:key-uid account-data)))
(update :keycard dissoc :recovery-phrase)
@ -246,6 +247,7 @@
(fx/merge cofx
{:db (-> db
(assoc-in [:keycard :multiaccount :instance-uid] instance-uid)
(assoc-in [:keycard :pin :status] :verifying)
(assoc-in [:keycard :secrets] {:pairing pairing'
:paired-on (utils.datetime/timestamp)}))
:keycard/get-keys {:pairing pairing'

View File

@ -198,20 +198,20 @@
[{:keys [db] :as cofx} error]
(log/debug "[keycard] sign error: " error)
(let [tag-was-lost? (common/tag-lost? (:error error))
pin-retries (get-in db [:keycard :application-info :pin-retry-counter])]
pin-retries (common/pin-retries (:error error))]
(when-not tag-was-lost?
(if (re-matches common/pin-mismatch-error (:error error))
(if (not (nil? pin-retries))
(fx/merge cofx
{:db (-> db
(assoc-in [:keycard :application-info :pin-retry-counter] (dec pin-retries))
(update-in [:keycard :pin] merge {:status :error
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries)
(update-in [:keycard :pin] assoc
:status :error
:sign []
:error-label :t/pin-mismatch})
:error-label :t/pin-mismatch)
(assoc-in [:signing/sign :keycard-step] :pin))}
(common/hide-connection-sheet)
(common/get-application-info (common/get-pairing db) nil)
(when (zero? (dec pin-retries))
(common/frozen-keycard-popup)))
(when (zero? pin-retries) (common/frozen-keycard-popup)))
(fx/merge cofx
(common/hide-connection-sheet)
(common/show-wrong-keycard-alert true))))))

View File

@ -14,6 +14,7 @@
(def initial-state
{:card-connected? false
:nfc-started? false
:application-info {:initialized? false}})
(defonce state (atom initial-state))
@ -68,6 +69,16 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn start-nfc [{:keys [on-success]}]
(when (get @state :card-connected?) (connect-card))
(later #(on-success true)))
(defn stop-nfc [{:keys [on-success]}]
(later #(on-success true)))
(defn set-nfc-message [{:keys [on-success]}]
(later #(on-success true)))
(defn check-nfc-support [{:keys [on-success]}]
(later #(on-success true)))
@ -87,18 +98,22 @@
id))
(defn register-card-events [args]
(log/debug "register-card-events")
(on-card-connected (:on-card-connected args))
(on-card-disconnected (:on-card-disconnected args)))
(defn remove-event-listener [id]
(log/debug "remove-event-listener")
(swap! state update :on-card-connected dissoc id)
(swap! state update :on-card-disconnected dissoc id))
(defn remove-event-listeners []
(log/debug "remove-event-listeners")
(swap! state dissoc :on-card-connected)
(swap! state dissoc :on-card-disconnected))
(defn get-application-info [{:keys [on-success]}]
(log/debug "get-application-info")
(later #(on-success (get @state :application-info))))
(defn install-applet [_])
@ -390,6 +405,15 @@
(defrecord SimulatedKeycard []
keycard/Keycard
(keycard/start-nfc [this args]
(log/debug "simulated card start-nfc")
(start-nfc args))
(keycard/stop-nfc [this args]
(log/debug "simulated card stop-nfc")
(stop-nfc args))
(keycard/set-nfc-message [this args]
(log/debug "simulated card set-nfc-message")
(set-nfc-message args))
(keycard/check-nfc-support [this args]
(log/debug "simulated card check-nfc-support")
(check-nfc-support args))

View File

@ -14,7 +14,6 @@
[status-im.navigation :as navigation]
[status-im.utils.config :as config]
[status-im.utils.fx :as fx]
[status-im.utils.platform :as platform]
[status-im.utils.security :as security]
[status-im.utils.signing-phrase.core :as signing-phrase]
[status-im.utils.types :as types]
@ -30,17 +29,14 @@
(defn decrement-step [step]
(let [inverted (map-invert step-kw-to-num)]
(if (and (= step :create-code)
(or (not platform/android?)
(not (nfc/nfc-supported?))))
(not (nfc/nfc-supported?)))
:choose-key
(inverted (dec (step-kw-to-num step))))))
(defn inc-step [step]
(let [inverted (map-invert step-kw-to-num)]
(if (and (= step :choose-key)
(or (not (or platform/android?
config/keycard-test-menu-enabled?))
(not (nfc/nfc-supported?))))
(not (nfc/nfc-supported?)))
:create-code
(inverted (inc (step-kw-to-num step))))))

View File

@ -14,11 +14,9 @@
[status-im.utils.fx :as fx]
[status-im.utils.security :as security]
[status-im.utils.types :as types]
[status-im.utils.platform :as platform]
[status-im.utils.utils :as utils]
[status-im.bottom-sheet.core :as bottom-sheet]
[taoensso.timbre :as log]
[status-im.utils.config :as config]))
[taoensso.timbre :as log]))
(defn existing-account?
[multiaccounts key-uid]
@ -234,9 +232,7 @@
assoc :step :select-key-storage
:forward-action :multiaccounts.recover/select-storage-next-pressed
:selected-storage-type :default)}
(if (and (or platform/android?
config/keycard-test-menu-enabled?)
(nfc/nfc-supported?))
(if (nfc/nfc-supported?)
(navigation/navigate-to-cofx :recover-multiaccount-select-storage nil)
(select-storage-next-pressed))))

View File

@ -9,6 +9,7 @@
[status-im.ethereum.tokens :as tokens]
[status-im.keycard.common :as keycard.common]
[status-im.i18n.i18n :as i18n]
[status-im.keycard.card :as keycard.card]
[status-im.native-module.core :as status]
[status-im.signing.keycard :as signing.keycard]
[status-im.utils.fx :as fx]
@ -203,6 +204,8 @@
:formatted-data (if typed? (types/json->clj data) (ethereum/hex->text data))
:keycard-step (when pinless? :connect)})}
(when pinless?
(keycard.card/start-nfc {:on-success #(re-frame/dispatch [:keycard.callback/start-nfc-success])
:on-failure #(re-frame/dispatch [:keycard.callback/start-nfc-failure])})
(signing.keycard/hash-message {:data data
:typed? true
:on-completed #(re-frame/dispatch [:keycard/store-hash-and-sign-typed %])})))

View File

@ -12,11 +12,9 @@
[status-im.ui.components.react :as react]
[status-im.ui.components.topbar :as topbar]
[status-im.ui.screens.intro.styles :as styles]
[status-im.utils.config :as config]
[status-im.ui.components.toolbar :as toolbar]
[status-im.utils.gfycat.core :as gfy]
[status-im.utils.identicon :as identicon]
[status-im.utils.platform :as platform]
[status-im.utils.security :as security]
[status-im.utils.debounce :refer [dispatch-and-chill]]
[quo.core :as quo]
@ -103,10 +101,7 @@
{:accessibility-label (keyword (str "select-storage-" type))
:on-press #(re-frame/dispatch
[:intro-wizard/on-key-storage-selected
(if (or platform/android?
config/keycard-test-menu-enabled?)
type
:default)])}
type])}
[react/view (assoc (styles/list-item selected?)
:align-items :flex-start
:padding-top 16

View File

@ -135,7 +135,8 @@
(i18n/label :t/keycard-free-pairing-slots {:n free-pairing-slots})]])]
[react/view
[react/view {:padding 16
:justify-content :center}
:justify-content :center
:margin-bottom 100}
[quo/text-input
{:on-change-text #(re-frame/dispatch [:keycard.onboarding.pair.ui/input-changed %])
:auto-focus true

View File

@ -13,6 +13,7 @@
[status-im.ui.screens.chat.photos :as photos]
[status-im.ui.screens.keycard.pin.views :as pin.views]
[status-im.ui.screens.keycard.styles :as styles]
[status-im.ui.screens.intro.styles :as intro-styles]
[status-im.constants :as constants]
[status-im.keycard.login :as keycard.login]
[status-im.ui.screens.keycard.frozen-card.view :as frozen-card.view])
@ -200,10 +201,9 @@
[react/text (i18n/label :t/keycard-can-use-with-new-passcode)]]
(when-not hide-login-actions?
[react/view
{:style {:width 160
{:style {:width 260
:margin-bottom 15}}
[react/view {:flex-direction :row
:height 52}
[react/view intro-styles/buttons-container
[quo/button {:on-press #(re-frame/dispatch
[::keycard.login/login-after-reset])}
(i18n/label :t/open)]]])])

View File

@ -103,7 +103,7 @@
(defview seed-phrase []
(letsubs
[{:keys [seed-word-count seed-shape-invalid?]} [:multiaccounts/key-storage]]
[react/keyboard-avoiding-view {:flex 1}
[react/keyboard-avoiding-view {:style {:display :flex :flex 1 :flex-direction :column}}
[local-topbar (i18n/label :t/enter-seed-phrase)]
[multiaccounts.views/seed-phrase-input
{:on-change-event [::multiaccounts.key-storage/seed-phrase-input-changed]
@ -114,6 +114,7 @@
:margin-bottom 8
:text-align :center}}
(i18n/label :t/multiaccounts-recover-enter-phrase-text)]
[react/keyboard-avoiding-view {:style {:flex 1}}
[toolbar/toolbar {:show-border? true
:right [quo/button
{:type :secondary
@ -121,7 +122,7 @@
(nil? seed-shape-invalid?))
:on-press #(re-frame/dispatch [::multiaccounts.key-storage/choose-storage-pressed])
:after :main-icons/next}
(i18n/label :t/choose-storage)]}]]))
(i18n/label :t/choose-storage)]}]]]))
(defn keycard-subtitle []
[react/view

View File

@ -10,7 +10,6 @@
[status-im.utils.security]
[status-im.ui.components.colors :as colors]
[quo.core :as quo]
[status-im.utils.platform :as platform]
[status-im.react-native.resources :as resources]
[status-im.ui.components.icons.icons :as icons]))
@ -52,7 +51,6 @@
;; Show manage storage link when on login screen, only on android devices
;; and the selected account is not paired with keycard
(when (and (= view-id :login)
platform/android?
(not acc-to-login-keycard-pairing))
[quo/list-item
{:theme :accent
@ -67,8 +65,6 @@
:accessibility-label :enter-seed-phrase-button
:icon :main-icons/text
:on-press #(hide-sheet-and-dispatch [::multiaccounts.recover/enter-phrase-pressed])}]
(when (or platform/android?
config/keycard-test-menu-enabled?)
[quo/list-item
{:theme :accent
:title (i18n/label :t/recover-with-keycard)
@ -83,7 +79,7 @@
:height 40}
[react/image {:source (resources/get-image :keycard-logo-blue)
:style {:width 24 :height 24}}]]
:on-press #(hide-sheet-and-dispatch [::keycard/recover-with-keycard-pressed])}])
:on-press #(hide-sheet-and-dispatch [::keycard/recover-with-keycard-pressed])}]
(when config/database-management-enabled?
[quo/list-item {:theme :accent
:on-press #(hide-sheet-and-dispatch [:multiaccounts.login.ui/import-db-submitted])

View File

@ -11,7 +11,6 @@
[status-im.ui.components.qr-code-viewer.views :as qr-code-viewer]
[status-im.ui.components.react :as react]
[status-im.ui.screens.profile.user.styles :as styles]
[status-im.utils.platform :as platform]
[status-im.utils.config :as config]
[status-im.utils.gfycat.core :as gfy]
[status-im.utils.universal-links.utils :as universal-links]
@ -128,9 +127,7 @@
:accessibility-label :sync-settings-button
:chevron true
:on-press #(re-frame/dispatch [:navigate-to :sync-settings])}]
(when (and (or platform/android?
config/keycard-test-menu-enabled?)
keycard-pairing)
(when keycard-pairing
[quo/list-item
{:icon :main-icons/keycard
:title (i18n/label :t/keycard)

View File

@ -16,6 +16,7 @@
[status-im.ui.screens.signing.sheets :as sheets]
[status-im.ethereum.tokens :as tokens]
[status-im.utils.types :as types]
[status-im.utils.platform :as platform]
[clojure.string :as string]
[quo.core :as quo]
[quo.gesture-handler :as gh]
@ -107,8 +108,9 @@
enter-step [:keycard/pin-enter-step]
status [:keycard/pin-status]
retry-counter [:keycard/retry-counter]]
(let [enter-step (or enter-step :sign)]
[react/view
(let [enter-step (or enter-step :sign)
margin-bottom (if platform/ios? 40 0)]
[react/view {:margin-bottom margin-bottom}
[pin.views/pin-view
{:pin pin
:retry-counter retry-counter

View File

@ -124,7 +124,7 @@
[topbar/topbar
{:navigation :none
:right-accessories
[{:label :t/cancel
[{:label (i18n/label :t/cancel)
:on-press #(re-frame/dispatch [:keycard/new-account-pin-sheet-hide])}]}]
[pin.views/pin-view
{:pin pin

View File

@ -6751,9 +6751,9 @@ react-native-splash-screen@^3.2.0:
resolved "https://registry.yarnpkg.com/react-native-splash-screen/-/react-native-splash-screen-3.2.0.tgz#d47ec8557b1ba988ee3ea98d01463081b60fff45"
integrity sha512-Ls9qiNZzW/OLFoI25wfjjAcrf2DZ975hn2vr6U9gyuxi2nooVbzQeFoQS5vQcbCt9QX5NY8ASEEAtlLdIa6KVg==
"react-native-status-keycard@git+https://github.com/status-im/react-native-status-keycard.git#v2.5.28":
version "2.5.28"
resolved "git+https://github.com/status-im/react-native-status-keycard.git#6d95a0d85dd1062d2565eec89d589ecb0a56282f"
"react-native-status-keycard@git+https://github.com/status-im/react-native-status-keycard.git#v2.5.30":
version "2.5.30"
resolved "git+https://github.com/status-im/react-native-status-keycard.git#958adb1e72dea1db989b4bf4663efe04ed8b2c0c"
react-native-svg@^9.8.4:
version "9.13.6"