add keycard installation

Signed-off-by: Dmitry Novotochinov <dmitry.novot@gmail.com>
This commit is contained in:
Dmitry Novotochinov 2018-12-04 16:41:34 +03:00
parent e40e495e11
commit 962c49e345
No known key found for this signature in database
GPG Key ID: 43D1DAF5AD39C927
47 changed files with 1435 additions and 376 deletions

View File

@ -219,7 +219,6 @@ configurations.all {
}
dependencies {
compile project(':react-native-nfc-manager')
implementation project(':react-native-background-timer')
implementation project(':react-native-svg')
implementation 'com.android.support:multidex:1.0.2'
@ -249,6 +248,7 @@ dependencies {
exclude group: "com.google.android.gms"
compile 'com.android.support:exifinterface:27.+'
}
implementation project(':react-native-status-keycard')
implementation 'com.google.firebase:firebase-core:16.0.3' //this decides your firebase SDK version
implementation 'com.google.firebase:firebase-messaging:17.1.0'
implementation project(':react-native-keychain')

View File

@ -4,7 +4,6 @@ import android.support.multidex.MultiDexApplication;
import com.aakashns.reactnativedialogs.ReactNativeDialogsPackage;
import org.devio.rn.splashscreen.SplashScreenReactPackage;
import com.facebook.react.ReactApplication;
import community.revteltech.nfc.NfcManagerPackage;
import io.invertase.firebase.RNFirebasePackage;
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage;
import io.invertase.firebase.notifications.RNFirebaseNotificationsPackage;
@ -23,6 +22,7 @@ import com.reactnative.ivpusic.imagepicker.PickerPackage;
import com.rnfs.RNFSPackage;
import fr.bamlab.rnimageresizer.ImageResizerPackage;
import im.status.ethereum.module.StatusPackage;
import im.status.ethereum.keycard.RNStatusKeycardPackage;
import io.realm.react.RealmReactPackage;
import me.alwx.HttpServer.HttpServerReactPackage;
import com.oblador.keychain.KeychainPackage;
@ -56,7 +56,6 @@ public class MainApplication extends MultiDexApplication implements ReactApplica
Function<String, String> callRPC = statusPackage.getCallRPC();
List<ReactPackage> packages = new ArrayList<ReactPackage>(Arrays.asList(
new MainReactPackage(),
new NfcManagerPackage(),
new RNFirebasePackage(),
new RNFirebaseMessagingPackage(),
new RNFirebaseNotificationsPackage(),
@ -66,6 +65,7 @@ public class MainApplication extends MultiDexApplication implements ReactApplica
new HttpServerReactPackage(),
new SplashScreenReactPackage(),
statusPackage,
new RNStatusKeycardPackage(),
new RealmReactPackage(),
new RNI18nPackage(),
new RNCameraPackage(),

View File

@ -26,6 +26,8 @@ include ':react-native-status'
project(':react-native-status').projectDir = new File(rootProject.projectDir, '../modules/react-native-status/android')
include ':react-native-camera'
project(':react-native-camera').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-camera/android')
include ':react-native-status-keycard'
project(':react-native-status-keycard').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-status-keycard/android')
include ':react-native-fs'
project(':react-native-fs').projectDir = new File(settingsDir, '../node_modules/react-native-fs/android')
include ':react-native-image-crop-picker'

View File

@ -10,6 +10,7 @@
"dismissKeyboard"
"react-native-splash-screen"
"react-native-status"
"react-native-status-keycard"
"react-native-camera"
"react-native-qrcode"
"identicon.js"
@ -37,7 +38,6 @@
"react-native/Libraries/vendor/emitter/EventEmitter"
"react-native-background-timer"
"react-native-fetch-polyfill"
"react-native-nfc-manager"
"text-encoding"
"js-sha3"
"react-navigation"]

View File

@ -18,8 +18,6 @@ target 'StatusIm' do
pod 'RNKeychain', :path => '../node_modules/react-native-keychain'
pod 'react-native-camera', path: '../node_modules/react-native-camera'
pod 'react-native-nfc-manager', :path => '../node_modules/react-native-nfc-manager'
target 'StatusImTests' do
inherit! :search_paths
# Pods for testing

View File

@ -66,8 +66,6 @@ PODS:
- React
- react-native-camera/RN (1.1.5):
- React
- react-native-nfc-manager (0.5.5):
- React
- React/Core (0.56.0):
- yoga (= 0.56.0.React)
- RNKeychain (3.0.0):
@ -80,7 +78,6 @@ DEPENDENCIES:
- React (from `../node_modules/react-native`)
- react-native-background-timer (from `../node_modules/react-native-background-timer`)
- react-native-camera (from `../node_modules/react-native-camera`)
- react-native-nfc-manager (from `../node_modules/react-native-nfc-manager`)
- RNKeychain (from `../node_modules/react-native-keychain`)
- yoga (from `../node_modules/react-native/ReactCommon/yoga`)
@ -103,8 +100,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-background-timer"
react-native-camera:
:path: "../node_modules/react-native-camera"
react-native-nfc-manager:
:path: "../node_modules/react-native-nfc-manager"
RNKeychain:
:path: "../node_modules/react-native-keychain"
yoga:
@ -123,10 +118,9 @@ SPEC CHECKSUMS:
React: 1fe0eb13d90b625d94c3b117c274dcfd2e760e11
react-native-background-timer: bb7a98c8e97fc7c290de2d423dd09ddb73dcbcbb
react-native-camera: 68ad5143d2d0636236d46c7de8d2a6455ca52a36
react-native-nfc-manager: a74ef58b29f0015ae9e70f120645b796668ba5c2
RNKeychain: 627c6095cef215dd3d9804a9a9cf45ab96aa3997
yoga: b1ce48b6cf950b98deae82838f5173ea7cf89e85
PODFILE CHECKSUM: b24b9e1dd90a715fd354083342dceb8f1a2f6d75
PODFILE CHECKSUM: 7636f960a0dbec2dd55b8b20e244befa3fdb4438
COCOAPODS: 1.5.2

View File

@ -49,13 +49,13 @@
"react-native-invertible-scroll-view": "1.1.0",
"react-native-keychain": "3.0.0",
"react-native-level-fs": "3.0.1",
"react-native-nfc-manager": "^0.5.5",
"react-native-os": "https://github.com/status-im/react-native-os.git#1.1.0-1",
"react-native-qrcode": "0.2.7",
"react-native-randombytes": "3.5.0",
"react-native-safe-area-view": "0.9.0",
"react-native-securerandom": "https://github.com/status-im/react-native-securerandom#0.1.1-1",
"react-native-splash-screen": "3.1.1",
"react-native-status-keycard": "github:status-im/react-native-status-keycard",
"react-native-svg": "6.5.2",
"react-native-tcp": "https://github.com/status-im/react-native-tcp.git#3.3.0-1",
"react-native-udp": "https://github.com/status-im/react-native-udp.git#2.3.1-1",

View File

@ -5949,11 +5949,6 @@ react-native-level-fs@3.0.1:
level-filesystem "^1.0.1"
levelup "^0.18.2"
react-native-nfc-manager@^0.5.5:
version "0.5.5"
resolved "https://registry.yarnpkg.com/react-native-nfc-manager/-/react-native-nfc-manager-0.5.5.tgz#5b60376bbc2287fc5e1a75c6c15e5511be788e7b"
integrity sha512-4gFuyDnNWXe81R7tTbc1AFlrz1LfBHp/S7daWL7gEsBFdeRegDmopecUJER511UR5d5Ymttw37LzTZUbnNKTlQ==
"react-native-os@https://github.com/status-im/react-native-os.git#1.1.0-1":
version "1.1.0"
resolved "https://github.com/status-im/react-native-os.git#1a6d0835f919cb075793ad7c602f2724eee4702d"
@ -6010,6 +6005,10 @@ react-native-splash-screen@3.1.1:
resolved "https://registry.yarnpkg.com/react-native-splash-screen/-/react-native-splash-screen-3.1.1.tgz#1a4e46c9fdce53ff52af2a2cb4181788c4e30b30"
integrity sha512-PU2YocOSGbLjL9Vgcq/cwMNuHHKNjjuPpa1IPMuWo+6EB/fSZ5VOmxSa7+eucQe3631s3NhGuk3eHKahU03a4Q==
"react-native-status-keycard@github:status-im/react-native-status-keycard":
version "1.0.0"
resolved "https://codeload.github.com/status-im/react-native-status-keycard/tar.gz/b6c7324a8fd69acba42127000189bf9d58f4b774"
react-native-svg@6.5.2:
version "6.5.2"
resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-6.5.2.tgz#1105896b8873b0856821b18daa0c6898cea6c00c"

View File

@ -17,8 +17,8 @@
(def desktop-config (js/require "react-native-desktop-config"))
(def react-native-firebase #js {})
(def nfc-manager #js {})
(def camera #js {:default #js {:constants {:Aspect "Portrait"}}})
(def status-keycard #js {:default #js {}})
(def dialogs #js {})
(def dismiss-keyboard #js {})
(def image-crop-picker #js {})

View File

@ -6,6 +6,7 @@
(def keychain (js/require "react-native-keychain"))
(def qr-code (js/require "react-native-qrcode"))
(def react-native (js/require "react-native"))
(def status-keycard (js/require "react-native-status-keycard"))
(def realm (js/require "realm"))
(def webview-bridge (js/require "react-native-webview-bridge"))
(def secure-random (.-generateSecureRandom (js/require "react-native-securerandom")))
@ -19,7 +20,6 @@
(def image-resizer (js/require "react-native-image-resizer"))
(def svg (js/require "react-native-svg"))
(def react-native-firebase (js/require "react-native-firebase"))
(def nfc-manager (js/require "react-native-nfc-manager"))
(def snoopy (js/require "rn-snoopy"))
(def snoopy-filter (js/require "rn-snoopy/stream/filter"))
(def snoopy-bars (js/require "rn-snoopy/stream/bars"))

5
resources/icons/link.svg Normal file
View File

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.5 5.75C4.08579 5.75 3.75 6.08579 3.75 6.5V11.5C3.75 11.9142 4.08579 12.25 4.5 12.25H9.5C9.91421 12.25 10.25 11.9142 10.25 11.5V8.70711C10.25 8.5745 10.3027 8.44732 10.3964 8.35355L11.3232 7.42678C11.4807 7.26929 11.75 7.38083 11.75 7.60355V11.5C11.75 12.7426 10.7426 13.75 9.5 13.75H4.5C3.25736 13.75 2.25 12.7426 2.25 11.5V6.5C2.25 5.25736 3.25736 4.25 4.5 4.25H8.39645C8.61917 4.25 8.73071 4.51929 8.57322 4.67678L7.64645 5.60355C7.55268 5.69732 7.4255 5.75 7.29289 5.75H4.5Z" fill="#4360DF"/>
<path d="M14.75 2C14.75 1.80811 14.6768 1.61621 14.5303 1.46973C14.3838 1.32324 14.1919 1.25 14 1.25H9C8.58569 1.25 8.25 1.58582 8.25 2C8.25 2.41418 8.58569 2.75 9 2.75H11.7066C11.8848 2.75 11.974 2.96543 11.848 3.09142L6.46973 8.46973C6.17676 8.76257 6.17676 9.23743 6.46973 9.53027C6.76245 9.82324 7.23755 9.82324 7.53027 9.53027L12.9086 4.15197C13.0346 4.02598 13.25 4.11521 13.25 4.29339V7C13.25 7.41418 13.5859 7.75 14 7.75C14.4141 7.75 14.75 7.41418 14.75 7V2Z" fill="#4360DF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -8,7 +8,6 @@
[status-im.constants :as constants]
[status-im.data-store.accounts :as accounts-store]
[status-im.i18n :as i18n]
[status-im.hardwallet.core :as hardwallet]
[status-im.native-module.core :as status]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.config :as config]
@ -62,7 +61,7 @@
[{:keys [signing-phrase
status
db] :as cofx}
{:keys [pubkey address mnemonic installation-id]} password seed-backed-up]
{:keys [pubkey address mnemonic installation-id keycard-instance-uid]} password seed-backed-up]
(let [normalized-address (utils.hex/normalize-hex address)
account {:public-key pubkey
:installation-id (or installation-id (get-in db [:accounts/new-installation-id]))
@ -75,6 +74,7 @@
:signing-phrase signing-phrase
:seed-backed-up? seed-backed-up
:mnemonic mnemonic
:keycard-instance-uid keycard-instance-uid
:settings (constants/default-account-settings)}]
(log/debug "account-created")
(when-not (string/blank? pubkey)
@ -128,12 +128,6 @@
(dissoc :password :password-confirm :name :error)))}
(navigation/navigate-to-cofx :create-account nil)))
(fx/defn navigate-to-authentication-method
[{:keys [db] :as cofx}]
(if (hardwallet/hardwallet-supported? db)
(navigation/navigate-to-cofx cofx :hardwallet-authentication-method nil)
(navigate-to-create-account-screen cofx)))
;;;; COFX
(re-frame/reg-cofx

View File

@ -213,3 +213,7 @@
{:type :bool :default false}))
(def v15 (update v14 :properties dissoc :email))
(def v16 (assoc-in v15
[:properties :keycard-instance-uid]
{:type :string :optional true}))

View File

@ -66,6 +66,11 @@
(def v17 v16)
(def v18 [network/v1
bootnode/v4
extension/v12
account/v16])
;; put schemas ordered by version
(def schemas [{:schema v1
:schemaVersion 1
@ -117,4 +122,7 @@
:migration migrations/v16}
{:schema v17
:schemaVersion 17
:migration migrations/v17}])
:migration migrations/v17}
{:schema v18
:schemaVersion 18
:migration migrations/v18}])

View File

@ -127,3 +127,6 @@
(contains? % :BQX) (conj :ETHOS)))
updated (serialize new-settings)]
(aset account "settings" updated)))))
(defn v18 [old-realm new-realm]
(log/debug "migrating base database v18: " old-realm new-realm))

View File

@ -196,7 +196,7 @@
(handlers/register-handler-fx
:accounts.create.ui/create-new-account-button-pressed
(fn [cofx _]
(accounts.create/navigate-to-authentication-method cofx)))
(hardwallet/navigate-to-authentication-method cofx)))
;; accounts recover module
@ -825,6 +825,26 @@
;; hardwallet module
(handlers/register-handler-fx
:hardwallet.ui/get-application-info
(fn [_ _]
{:hardwallet/get-application-info nil}))
(handlers/register-handler-fx
:hardwallet.callback/on-register-card-events
(fn [cofx [_ listeners]]
(hardwallet/on-register-card-events cofx listeners)))
(handlers/register-handler-fx
:hardwallet.callback/on-get-application-info-success
(fn [cofx [_ info]]
(hardwallet/on-get-application-info-success cofx info)))
(handlers/register-handler-fx
:hardwallet.callback/on-get-application-info-error
(fn [cofx [_ error]]
(hardwallet/on-get-application-info-error cofx error)))
(handlers/register-handler-fx
:hardwallet.callback/check-nfc-support-success
(fn [cofx [_ supported?]]
@ -835,6 +855,59 @@
(fn [cofx [_ enabled?]]
(hardwallet/set-nfc-enabled cofx enabled?)))
(handlers/register-handler-fx
:hardwallet.callback/on-card-connected
(fn [cofx [_ data]]
(hardwallet/on-card-connected cofx data)))
(handlers/register-handler-fx
:hardwallet.callback/on-card-disconnected
(fn [cofx [_ data]]
(hardwallet/on-card-disconnected cofx data)))
(handlers/register-handler-fx
:hardwallet.callback/on-install-applet-and-init-card-success
(fn [cofx [_ secrets]]
(hardwallet/on-install-applet-and-init-card-success cofx secrets)))
(handlers/register-handler-fx
:hardwallet.callback/on-install-applet-and-init-card-error
(fn [cofx [_ error]]
(hardwallet/on-install-applet-and-init-card-error cofx error)))
(handlers/register-handler-fx
:hardwallet.callback/on-pairing-success
(fn [cofx [_ pairing]]
(hardwallet/on-pairing-success cofx pairing)))
(handlers/register-handler-fx
:hardwallet.callback/on-pairing-error
(fn [cofx [_ error]]
(hardwallet/on-pairing-error cofx error)))
(handlers/register-handler-fx
:hardwallet.callback/on-generate-mnemonic-success
(fn [cofx [_ mnemonic]]
(hardwallet/on-generate-mnemonic-success cofx mnemonic)))
(handlers/register-handler-fx
:hardwallet.callback/on-generate-mnemonic-error
(fn [cofx [_ error]]
(hardwallet/on-generate-mnemonic-error cofx error)))
(handlers/register-handler-fx
:hardwallet.callback/on-generate-and-load-key-success
[(re-frame/inject-cofx :random-guid-generator)
(re-frame/inject-cofx :accounts.create/get-signing-phrase)
(re-frame/inject-cofx :accounts.create/get-status)]
(fn [cofx [_ data]]
(hardwallet/on-generate-and-load-key-success cofx data)))
(handlers/register-handler-fx
:hardwallet.callback/on-generate-and-load-key-error
(fn [cofx [_ error]]
(hardwallet/on-generate-and-load-key-error cofx error)))
(handlers/register-handler-fx
:hardwallet.ui/status-hardwallet-option-pressed
(fn [cofx _]
@ -850,11 +923,6 @@
(fn [_ _]
{:hardwallet/open-nfc-settings nil}))
(handlers/register-handler-fx
:hardwallet.ui/connect-info-button-pressed
(fn [cofx _]
(browser/open-url cofx "https://hardwallet.status.im")))
(handlers/register-handler-fx
:hardwallet.ui/hold-card-button-pressed
(fn [{:keys [db] :as cofx} _]
@ -864,8 +932,23 @@
(handlers/register-handler-fx
:hardwallet.ui/begin-setup-button-pressed
(fn [{:keys [db]} _]
{:db (assoc-in db [:hardwallet :setup-step] :preparing)}))
(fn [_ _]
{:ui/show-confirmation {:title ""
:content (i18n/label :t/begin-keycard-setup-confirmation-text)
:confirm-button-text (i18n/label :t/yes)
:cancel-button-text (i18n/label :t/no)
:on-accept #(re-frame/dispatch [:hardwallet.ui/begin-setup-confirm-button-pressed])
:on-cancel #()}}))
(handlers/register-handler-fx
:hardwallet.ui/begin-setup-confirm-button-pressed
(fn [cofx _]
(hardwallet/load-preparing-screen cofx)))
(handlers/register-handler-fx
:hardwallet/install-applet-and-init-card
(fn [cofx _]
(hardwallet/install-applet-and-init-card cofx)))
(handlers/register-handler-fx
:hardwallet.ui/pair-card-button-pressed
@ -882,14 +965,34 @@
(fn [{:keys [db]} _]))
(handlers/register-handler-fx
:hardwallet.ui/no-pairing-slots-help-button-pressed
:hardwallet.ui/recovery-phrase-next-button-pressed
(fn [cofx _]
(browser/open-url "https://hardwallet.status.im" cofx)))
(hardwallet/recovery-phrase-start-confirmation cofx)))
(handlers/register-handler-fx
:hardwallet.ui/card-already-linked-help-button-pressed
:hardwallet.ui/recovery-phrase-confirm-word-next-button-pressed
(fn [cofx _]
(browser/open-url "https://hardwallet.status.im" cofx)))
(hardwallet/recovery-phrase-confirm-word cofx)))
(handlers/register-handler-fx
:hardwallet.ui/recovery-phrase-confirm-word-back-button-pressed
(fn [{:keys [db]} _]
{:db (assoc-in db [:hardwallet :setup-step] :recovery-phrase)}))
(handlers/register-handler-fx
:hardwallet.ui/recovery-phrase-confirm-word-input-changed
(fn [{:keys [db]} [_ input]]
{:db (assoc-in db [:hardwallet :recovery-phrase :input-word] input)}))
(handlers/register-handler-fx
:hardwallet.ui/recovery-phrase-confirm-pressed
(fn [cofx _]
(hardwallet/load-loading-keys-screen cofx)))
(handlers/register-handler-fx
:hardwallet.ui/recovery-phrase-cancel-pressed
(fn [{:keys [db]} _]
{:db (assoc-in db [:hardwallet :setup-step] :recovery-phrase)}))
(handlers/register-handler-fx
:hardwallet/connection-error
@ -917,13 +1020,18 @@
(handlers/register-handler-fx
:hardwallet.ui/secret-keys-dialog-confirm-pressed
(fn [{:keys [db]} _]
{:db (assoc-in db [:hardwallet :setup-step] :complete)}))
(fn [cofx _]
(hardwallet/load-pairing-screen cofx)))
(handlers/register-handler-fx
:hardwallet/pair
(fn [cofx _]
(hardwallet/pair cofx)))
(handlers/register-handler-fx
:hardwallet.ui/success-button-pressed
(fn [cofx _]
(navigation/navigate-to-cofx cofx :home nil)))
(hardwallet/success-button-pressed cofx)))
(handlers/register-handler-fx
:hardwallet.ui/pin-numpad-button-pressed
@ -936,10 +1044,32 @@
(when-not (empty? (get-in db [:hardwallet :pin step]))
{:db (update-in db [:hardwallet :pin step] pop)})))
(handlers/register-handler-fx
:hardwallet.ui/card-ready-next-button-pressed
(fn [cofx _]
(hardwallet/load-generating-mnemonic-screen cofx)))
(handlers/register-handler-fx
:hardwallet/generate-mnemonic
(fn [cofx _]
(hardwallet/generate-mnemonic cofx)))
(handlers/register-handler-fx
:hardwallet/generate-and-load-key
(fn [cofx _]
(hardwallet/generate-and-load-key cofx)))
(handlers/register-handler-fx
:hardwallet.ui/create-pin-button-pressed
(fn [{:keys [db]} _]
{:db (update-in db [:hardwallet :setup-step] :pin)}))
{:db (-> db
(assoc-in [:hardwallet :setup-step] :pin)
(assoc-in [:hardwallet :pin :enter-step] :original))}))
(handlers/register-handler-fx
:hardwallet.ui/error-button-pressed
(fn [cofx _]
(hardwallet/error-button-pressed cofx)))
;; browser module

View File

@ -0,0 +1,92 @@
(ns status-im.hardwallet.card
(:require [re-frame.core :as re-frame]
[status-im.react-native.js-dependencies :as js-dependencies]
[status-im.utils.config :as config]
[status-im.utils.platform :as platform]
[taoensso.timbre :as log]))
(defonce keycard (.-default js-dependencies/status-keycard))
(defonce event-emitter (.-DeviceEventEmitter js-dependencies/react-native))
(defn- error-object->map [object]
{:code (.-code object)
:error (.-message object)})
(defn check-nfc-support []
(when config/hardwallet-enabled?
(.. keycard
nfcIsSupported
(then #(re-frame/dispatch [:hardwallet.callback/check-nfc-support-success %])))))
(defn check-nfc-enabled []
(when platform/android?
(.. keycard
nfcIsEnabled
(then #(re-frame/dispatch [:hardwallet.callback/check-nfc-enabled-success %])))))
(defn open-nfc-settings []
(when platform/android?
(.openNfcSettings keycard)))
(defn remove-event-listeners []
(doseq [event ["keyCardOnConnected" "keyCardOnDisconnected"]]
(.removeAllListeners event-emitter event)))
(defn register-card-events []
(when (and config/hardwallet-enabled?)
(remove-event-listeners)
(re-frame/dispatch [:hardwallet.callback/on-register-card-events
{:on-card-connected
(.addListener event-emitter
"keyCardOnConnected"
#(re-frame/dispatch [:hardwallet.callback/on-card-connected %]))
:on-card-disconnected
(.addListener event-emitter
"keyCardOnDisconnected"
#(re-frame/dispatch [:hardwallet.callback/on-card-disconnected %]))}])))
(defn get-application-info []
(.. keycard
getApplicationInfo
(then #(re-frame/dispatch [:hardwallet.callback/on-get-application-info-success %]))
(catch #(re-frame/dispatch [:hardwallet.callback/on-get-application-info-error (error-object->map %)]))))
(defn start []
(when config/hardwallet-enabled?
(.. keycard
start
(then #(log/debug "[hardwallet] module started"))
(catch #(log/debug "[hardwallet] module not started " %)))))
(defn install-applet-and-init-card []
(when config/hardwallet-enabled?
(.. keycard
installAppletAndInitCard
(then #(re-frame/dispatch [:hardwallet.callback/on-install-applet-and-init-card-success %]))
(catch #(re-frame/dispatch [:hardwallet.callback/on-install-applet-and-init-card-error (error-object->map %)])))))
(defn pair
[{:keys [password]}]
(when password
(.. keycard
(pair password)
(then #(re-frame/dispatch [:hardwallet.callback/on-pairing-success %]))
(catch #(re-frame/dispatch [:hardwallet.callback/on-pairing-error (error-object->map %)])))))
(defn generate-mnemonic
[{:keys [pairing]}]
(when pairing
(.. keycard
(generateMnemonic pairing)
(then #(re-frame/dispatch [:hardwallet.callback/on-generate-mnemonic-success %]))
(catch #(re-frame/dispatch [:hardwallet.callback/on-generate-mnemonic-error (error-object->map %)])))))
(defn generate-and-load-key
[{:keys [mnemonic pairing pin]}]
(when pairing
(.. keycard
(generateAndLoadKey mnemonic pairing pin)
(then #(re-frame/dispatch [:hardwallet.callback/on-generate-and-load-key-success %]))
(catch #(re-frame/dispatch [:hardwallet.callback/on-generate-and-load-key-error (error-object->map %)])))))

View File

@ -1,24 +1,44 @@
(ns status-im.hardwallet.core
(:require [re-frame.core :as re-frame]
[status-im.react-native.js-dependencies :as js-dependencies]
status-im.hardwallet.fx
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.config :as config]
[status-im.utils.fx :as fx]
[status-im.utils.platform :as platform]))
[status-im.utils.platform :as platform]
[taoensso.timbre :as log]
[status-im.i18n :as i18n]
[status-im.accounts.create.core :as accounts.create]
[status-im.accounts.login.core :as accounts.login]))
(defn check-nfc-support []
(when config/hardwallet-enabled?
(.. js-dependencies/nfc-manager
-default
isSupported
(then #(re-frame/dispatch [:hardwallet.callback/check-nfc-support-success %])))))
(defn hardwallet-supported? [{:keys [db]}]
(and config/hardwallet-enabled?
platform/android?
(get-in db [:hardwallet :nfc-supported?])))
(defn check-nfc-enabled []
(when platform/android?
(.. js-dependencies/nfc-manager
-default
isEnabled
(then #(re-frame/dispatch [:hardwallet.callback/check-nfc-enabled-success %])))))
(fx/defn navigate-to-authentication-method
[cofx]
(if (hardwallet-supported? cofx)
(navigation/navigate-to-cofx cofx :hardwallet-authentication-method nil)
(accounts.create/navigate-to-create-account-screen cofx)))
(fx/defn on-register-card-events
[{:keys [db]} listeners]
{:db (update-in db [:hardwallet :listeners] merge listeners)})
(fx/defn on-get-application-info-success
[{:keys [db]} info]
(let [info' (js->clj info :keywordize-keys true)]
{:db (-> db
(assoc-in [:hardwallet :application-info] info')
(assoc-in [:hardwallet :application-info :applet-installed?] true)
(assoc-in [:hardwallet :application-info-error] nil))}))
(fx/defn on-get-application-info-error
[{:keys [db]} error]
(log/debug "[hardwallet] application info error " error)
{:db (-> db
(assoc-in [:hardwallet :application-info-error] error)
(assoc-in [:hardwallet :application-info :applet-installed?] false))})
(fx/defn set-nfc-support
[{:keys [db]} supported?]
@ -28,21 +48,31 @@
[{:keys [db]} enabled?]
{:db (assoc-in db [:hardwallet :nfc-enabled?] enabled?)})
(defn open-nfc-settings []
(when platform/android?
(.. js-dependencies/nfc-manager
-default
goToNfcSetting)))
(fx/defn navigate-to-connect-screen [cofx]
(fx/defn navigate-to-connect-screen [{:keys [db] :as cofx}]
(fx/merge cofx
{:hardwallet/check-nfc-enabled nil}
{:hardwallet/check-nfc-enabled nil
:hardwallet/register-card-events nil
:db (assoc-in db [:hardwallet :setup-step] :begin)}
(navigation/navigate-to-cofx :hardwallet-connect nil)))
(defn hardwallet-supported? [db]
(and config/hardwallet-enabled?
platform/android?
(get-in db [:hardwallet :nfc-supported?])))
(fx/defn success-button-pressed [cofx]
;; login not implemented yet
)
(fx/defn error-button-pressed [{:keys [db] :as cofx}]
(let [return-to-step (get-in db [:hardwallet :return-to-step] :begin)]
(fx/merge cofx
{:db (assoc-in db [:hardwallet :setup-step] return-to-step)}
(when-not return-to-step
(navigation/navigate-to-cofx :hardwallet-connect nil)))))
(fx/defn load-pairing-screen [{:keys [db]}]
{:db (assoc-in db [:hardwallet :setup-step] :pairing)
:dispatch [:hardwallet/pair]})
(fx/defn pair [cofx]
(let [{:keys [password]} (get-in cofx [:db :hardwallet :secrets])]
{:hardwallet/pair {:password password}}))
(fx/defn return-back-from-nfc-settings [{:keys [db]}]
(when (= :hardwallet-connect (:view-id db))
@ -81,14 +111,184 @@
(get-in db' [:hardwallet :pin :confirmation])))
(pin-mismatch))))
(re-frame/reg-fx
:hardwallet/check-nfc-support
check-nfc-support)
(fx/defn load-loading-keys-screen
[{:keys [db]}]
{:db (assoc-in db [:hardwallet :setup-step] :loading-keys)
:dispatch [:hardwallet/generate-and-load-key]})
(re-frame/reg-fx
:hardwallet/check-nfc-enabled
check-nfc-enabled)
(fx/defn load-generating-mnemonic-screen
[{:keys [db]}]
{:db (assoc-in db [:hardwallet :setup-step] :generating-mnemonic)
:dispatch [:hardwallet/generate-mnemonic]})
(re-frame/reg-fx
:hardwallet/open-nfc-settings
open-nfc-settings)
(fx/defn generate-mnemonic
[cofx]
(let [{:keys [pairing]} (get-in cofx [:db :hardwallet :secrets])]
{:hardwallet/generate-mnemonic {:pairing pairing}}))
(fx/defn on-card-connected
[{:keys [db] :as cofx} data]
(log/debug "[hardwallet] card connected " data)
(let [return-to-step (get-in db [:hardwallet :return-to-step])
setup-running? (get-in db [:hardwallet :setup-step])]
(fx/merge cofx
{:db (cond-> db
return-to-step (assoc-in [:hardwallet :setup-step] return-to-step)
true (assoc-in [:hardwallet :card-connected?] true)
true (assoc-in [:hardwallet :return-to-step] nil))
:hardwallet/get-application-info nil}
(when setup-running?
(navigation/navigate-to-cofx :hardwallet-setup nil)))))
(fx/defn on-card-disconnected
[{:keys [db] :as cofx} _]
(log/debug "[hardwallet] card disconnected ")
(let [setup-running? (get-in db [:hardwallet :setup-step])]
(fx/merge cofx
{:db (assoc-in db [:hardwallet :card-connected?] false)}
(when setup-running?
(navigation/navigate-to-cofx :hardwallet-connect nil)))))
(fx/defn load-preparing-screen
[{:keys [db]}]
{:db (assoc-in db [:hardwallet :setup-step] :preparing)
:dispatch [:hardwallet/install-applet-and-init-card]})
(fx/defn install-applet-and-init-card
[{:keys [db]}]
{:hardwallet/install-applet-and-init-card nil})
(fx/defn on-install-applet-and-init-card-success
[{:keys [db]} secrets]
(let [secrets' (js->clj secrets :keywordize-keys true)]
{:db (-> db
(assoc-in [:hardwallet :setup-step] :secret-keys)
(assoc-in [:hardwallet :secrets] secrets'))}))
(defn- tag-lost-exception? [code]
(= code "android.nfc.TagLostException"))
(fx/defn process-error [{:keys [db] :as cofx} code]
(if (tag-lost-exception? code)
(navigation/navigate-to-cofx cofx :hardwallet-connect nil)
{:db (assoc-in db [:hardwallet :setup-step] :error)}))
(fx/defn on-install-applet-and-init-card-error
[{:keys [db] :as cofx} {:keys [code error]}]
(log/debug "[hardwallet] install applet and init card error: " error)
(fx/merge cofx
{:db (-> db
(assoc-in [:hardwallet :return-to-step] :begin)
(assoc-in [:hardwallet :setup-error] error))}
(process-error code)))
(fx/defn on-pairing-success
[{:keys [db]} pairing]
{:db (-> db
(assoc-in [:hardwallet :setup-step] :card-ready)
(assoc-in [:hardwallet :secrets :pairing] pairing))})
(fx/defn on-pairing-error
[{:keys [db] :as cofx} {:keys [error code]}]
(log/debug "[hardwallet] pairing error: " error)
(fx/merge cofx
{:db (-> db
(assoc-in [:hardwallet :return-to-step] :secret-keys)
(assoc-in [:hardwallet :setup-error] error))}
(process-error code)))
(fx/defn on-generate-mnemonic-success
[{:keys [db]} mnemonic]
{:db (-> db
(assoc-in [:hardwallet :setup-step] :recovery-phrase)
(assoc-in [:hardwallet :secrets :mnemonic] mnemonic))})
(fx/defn on-generate-mnemonic-error
[{:keys [db] :as cofx} {:keys [error code]}]
(log/debug "[hardwallet] generate mnemonic error: " error)
(fx/merge cofx
{:db (-> db
(assoc-in [:hardwallet :return-to-step] :card-ready)
(assoc-in [:hardwallet :setup-error] error))}
(process-error code)))
(fx/defn recovery-phrase-start-confirmation [{:keys [db]}]
(let [mnemonic (get-in db [:hardwallet :secrets :mnemonic])
[word1 word2] (shuffle (map-indexed vector (clojure.string/split mnemonic #" ")))
word1 (zipmap [:idx :word] word1)
word2 (zipmap [:idx :word] word2)]
{:db (-> db
(assoc-in [:hardwallet :setup-step] :recovery-phrase-confirm-word1)
(assoc-in [:hardwallet :recovery-phrase :step] :word1)
(assoc-in [:hardwallet :recovery-phrase :confirm-error] nil)
(assoc-in [:hardwallet :recovery-phrase :input-word] nil)
(assoc-in [:hardwallet :recovery-phrase :word1] word1)
(assoc-in [:hardwallet :recovery-phrase :word2] word2))}))
(defn- show-recover-confirmation []
{:ui/show-confirmation {:title (i18n/label :t/are-you-sure?)
:content (i18n/label :t/are-you-sure-description)
:confirm-button-text (clojure.string/upper-case (i18n/label :t/yes))
:cancel-button-text (i18n/label :t/see-it-again)
:on-accept #(re-frame/dispatch [:hardwallet.ui/recovery-phrase-confirm-pressed])
:on-cancel #(re-frame/dispatch [:hardwallet.ui/recovery-phrase-cancel-pressed])}})
(defn- recovery-phrase-next-word [db]
{:db (-> db
(assoc-in [:hardwallet :recovery-phrase :step] :word2)
(assoc-in [:hardwallet :recovery-phrase :confirm-error] nil)
(assoc-in [:hardwallet :recovery-phrase :input-word] nil)
(assoc-in [:hardwallet :setup-step] :recovery-phrase-confirm-word2))})
(fx/defn recovery-phrase-confirm-word
[{:keys [db]}]
(let [step (get-in db [:hardwallet :recovery-phrase :step])
input-word (get-in db [:hardwallet :recovery-phrase :input-word])
{:keys [word]} (get-in db [:hardwallet :recovery-phrase step])]
(if (= word input-word)
(if (= step :word1)
(recovery-phrase-next-word db)
(show-recover-confirmation))
{:db (assoc-in db [:hardwallet :recovery-phrase :confirm-error] (i18n/label :t/wrong-word))})))
(fx/defn generate-and-load-key
[{:keys [db] :as cofx}]
(let [{:keys [mnemonic pairing pin]} (get-in db [:hardwallet :secrets])]
(fx/merge cofx
{:hardwallet/generate-and-load-key {:mnemonic mnemonic
:pairing pairing
:pin pin}})))
(fx/defn on-generate-and-load-key-success
[{:keys [db] :as cofx} data]
(let [{:keys [whisper-public-key
whisper-private-key
whisper-address
wallet-address
encryption-public-key]} (js->clj data :keywordize-keys true)
whisper-public-key' (str "0x" whisper-public-key)
keycard-instance-uid (get-in db [:hardwallet :application-info :instance-uid])]
(fx/merge cofx
{:db (-> db
(assoc-in [:hardwallet :whisper-public-key] whisper-public-key')
(assoc-in [:hardwallet :whisper-private-key] whisper-private-key)
(assoc-in [:hardwallet :whisper-address] whisper-address)
(assoc-in [:hardwallet :wallet-address] wallet-address)
(assoc-in [:hardwallet :encryption-public-key] encryption-public-key)
(assoc-in [:hardwallet :setup-step] nil))}
(accounts.create/on-account-created {:pubkey whisper-public-key'
:address wallet-address
:mnemonic ""
:keycard-instance-uid keycard-instance-uid}
encryption-public-key
true)
(navigation/navigate-to-cofx :hardwallet-success nil))))
(fx/defn on-generate-and-load-key-error
[{:keys [db] :as cofx} {:keys [error code]}]
(log/debug "[hardwallet] generate and load key error: " error)
(fx/merge cofx
{:db (-> db
(assoc-in [:hardwallet :return-to-step] :recovery-phrase)
(assoc-in [:hardwallet :setup-error] error))}
(process-error code)))

View File

@ -0,0 +1,48 @@
(ns status-im.hardwallet.fx
(:require [re-frame.core :as re-frame]
[status-im.hardwallet.card :as card]
[status-im.react-native.js-dependencies :as js-dependencies]))
(re-frame/reg-fx
:hardwallet/get-application-info
card/get-application-info)
(re-frame/reg-fx
:hardwallet/check-nfc-support
card/check-nfc-support)
(re-frame/reg-fx
:hardwallet/check-nfc-enabled
card/check-nfc-enabled)
(re-frame/reg-fx
:hardwallet/open-nfc-settings
card/open-nfc-settings)
(re-frame/reg-fx
:hardwallet/start-module
card/start)
(re-frame/reg-fx
:hardwallet/install-applet-and-init-card
card/install-applet-and-init-card)
(re-frame/reg-fx
:hardwallet/register-card-events
card/register-card-events)
(re-frame/reg-fx
:hardwallet/remove-event-listeners
card/remove-event-listeners)
(re-frame/reg-fx
:hardwallet/pair
card/pair)
(re-frame/reg-fx
:hardwallet/generate-mnemonic
card/generate-mnemonic)
(re-frame/reg-fx
:hardwallet/generate-and-load-key
card/generate-and-load-key)

View File

@ -79,7 +79,9 @@
:network/listen-to-network-status nil
:network/listen-to-connection-status nil
:hardwallet/check-nfc-support nil
:hardwallet/check-nfc-enabled nil}
:hardwallet/check-nfc-enabled nil
:hardwallet/start-module nil
:hardwallet/register-card-events nil}
(initialize-keychain)))
(fx/defn initialize-app-db
@ -88,7 +90,7 @@
initial-props desktop/desktop
network-status network peers-count peers-summary device-UUID]
:node/keys [status]
:or {network (get app-db :network)}} :db}]
:or {network (get app-db :network)}} :db}]
{:db (assoc app-db
:contacts/contacts {}
:initial-props initial-props
@ -99,9 +101,9 @@
:status-module-initialized? (or platform/ios? js/goog.DEBUG status-module-initialized?)
:node/status status
:network network
:hardwallet hardwallet
:device-UUID device-UUID
:view-id view-id
:hardwallet (select-keys hardwallet [:nfc-enabled? :nfc-supported?]))})
:view-id view-id)})
(fx/defn initialize-app
[cofx encryption-key]
@ -157,7 +159,7 @@
(let [{:universal-links/keys [url]
:keys [accounts/accounts accounts/create networks/networks network
network-status peers-count peers-summary view-id navigation-stack
desktop/desktop
desktop/desktop hardwallet
status-module-initialized? device-UUID semaphores accounts/login]
:node/keys [status on-ready]
:or {network (get app-db :network)}} db
@ -184,6 +186,7 @@
:peers-count peers-count
:device-UUID device-UUID
:semaphores semaphores
:hardwallet hardwallet
:web3 web3)
(= view-id :create-account)
(assoc-in [:accounts/create :step] :enter-name))}))
@ -205,6 +208,10 @@
(= (get-in cofx [:db :view-id])
:create-account))
(defn finishing-hardwallet-setup? [cofx]
(= (get-in cofx [:db :view-id])
:hardwallet-success))
(fx/defn initialize-account [cofx address]
(fx/merge cofx
{:notifications/get-fcm-token nil}
@ -218,7 +225,8 @@
(browser/initialize-dapp-permissions)
(extensions.registry/initialize)
(accounts.update/update-sign-in-time)
#(when-not (creating-account? %)
#(when-not (or (creating-account? %)
(finishing-hardwallet-setup? %))
(login-only-events % address))))
(re-frame/reg-fx

View File

@ -57,13 +57,17 @@
:console (js/require "./resources/images/contacts/console.png")})
(def ui
{:empty-hashtags (js/require "./resources/images/ui/empty-hashtags.png")
:empty-recent (js/require "./resources/images/ui/empty-recent.png")
:analytics-image (js/require "./resources/images/ui/analytics-image.png")
:welcome-image (js/require "./resources/images/ui/welcome-image.png")
:lock {:image (js/require "./resources/images/ui/lock.png")
:width 993
:height 933}
:wallet-welcome (js/require "./resources/images/ui/wallet-welcome.png")
:hardwallet-card (js/require "./resources/images/ui/hardwallet-card.png")
:phone-nfc (js/require "./resources/images/ui/phone-nfc.png")})
{:empty-hashtags (js/require "./resources/images/ui/empty-hashtags.png")
:empty-recent (js/require "./resources/images/ui/empty-recent.png")
:analytics-image (js/require "./resources/images/ui/analytics-image.png")
:welcome-image (js/require "./resources/images/ui/welcome-image.png")
:lock {:image (js/require "./resources/images/ui/lock.png")
:width 993
:height 933}
:wallet-welcome (js/require "./resources/images/ui/wallet-welcome.png")
:hardwallet-card (js/require "./resources/images/ui/hardwallet-card.png")
:secret-keys (js/require "./resources/images/ui/secret-keys.png")
:keycard-lock (js/require "./resources/images/ui/keycard-lock.png")
:hold-card-animation (js/require "./resources/images/ui/hold-card-animation.png")
:phone-nfc-on (js/require "./resources/images/ui/phone-nfc-on.png")
:phone-nfc-off (js/require "./resources/images/ui/phone-nfc-off.png")})

View File

@ -40,6 +40,7 @@
;; GREEN
(def green "#44d058") ;; icon for successful inboud transaction
(def green-transparent-10 (alpha green 0.1)) ;; icon for successful inboud transaction
(def chat-colors ["#fa6565"
"#7cda00"

View File

@ -68,11 +68,15 @@
[react/view {:style (styles/logo-container size shadow?)}
[icons/icon :icons/logo (styles/logo icon-size)]]))
(defn bottom-button [{:keys [label disabled? on-press forward?]}]
(defn bottom-button [{:keys [label disabled? on-press forward? back? uppercase?]
:or {uppercase? true}}]
[react/touchable-highlight {:on-press on-press :disabled disabled?}
[react/view (styles/bottom-button disabled?)
(when back?
[icons/icon :icons/back {:color colors/blue
:container-style {:align-self :baseline}}])
[react/text {:style styles/bottom-button-label
:uppercase? true}
:uppercase? uppercase?}
(or label (i18n/label :t/next))]
(when forward?
[icons/icon :icons/forward {:color colors/blue}])]])

View File

@ -96,6 +96,7 @@
:icons/dots (js/require "./resources/icons/dots.svg")
:icons/warning (js/require "./resources/icons/warning.svg")
:icons/info (js/require "./resources/icons/info.svg")
:icons/link (js/require "./resources/icons/link.svg")
:icons/hardwallet (js/require "./resources/icons/hardwallet.svg")
:icons/password (js/require "./resources/icons/password.svg")
:icons/nfc (js/require "./resources/icons/nfc.svg")
@ -175,6 +176,7 @@
:icons/warning (components.svg/slurp-svg "./resources/icons/warning.svg")
:icons/settings (components.svg/slurp-svg "./resources/icons/settings.svg")
:icons/info (components.svg/slurp-svg "./resources/icons/info.svg")
:icons/link (components.svg/slurp-svg "./resources/icons/link.svg")
:icons/hardwallet (components.svg/slurp-svg "./resources/icons/hardwallet.svg")
:icons/password (components.svg/slurp-svg "./resources/icons/password.svg")
:icons/nfc (components.svg/slurp-svg "./resources/icons/nfc.svg")

View File

@ -188,7 +188,7 @@
(spec/def ::semaphores set?)
(spec/def ::hardwallet map?)
(spec/def ::hardwallet (spec/nilable map?))
(spec/def ::db (spec/keys :opt [:contacts/contacts
:contacts/dapps

View File

@ -5,6 +5,18 @@
{:flex 1
:background-color colors/white})
(def lock-image-container
{:background-color colors/blue-light
:width 160
:height 160
:border-radius 80
:align-items :center
:justify-content :center})
(def lock-image
{:width 160
:height 160})
(def choose-authentication-method
{:flex-direction :column
:flex 1
@ -13,6 +25,7 @@
(def choose-authentication-method-text
{:color colors/black
:margin-top 51
:padding-horizontal 60
:text-align :center
:font-weight :bold

View File

@ -8,7 +8,8 @@
[status-im.ui.components.common.common :as common]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.i18n :as i18n]
[status-im.ui.components.colors :as colors]))
[status-im.ui.components.colors :as colors]
[status-im.react-native.resources :as resources]))
(defn authentication-method-row [{:keys [title on-press icon]}]
[react/touchable-highlight {:on-press on-press}
@ -30,11 +31,14 @@
nil]
[common/separator]
[react/view styles/choose-authentication-method
[react/view styles/lock-image-container
[react/image {:source (:keycard-lock resources/ui)
:style styles/lock-image}]]
[react/text {:style styles/choose-authentication-method-text
:number-of-lines 3}
(i18n/label :t/choose-authentication-method)]]
[react/view styles/authentication-methods
[authentication-method-row {:title (i18n/label :t/status-hardwallet-capitalized)
[authentication-method-row {:title (i18n/label :t/keycard)
:icon :icons/hardwallet
:on-press #(re-frame/dispatch [:hardwallet.ui/status-hardwallet-option-pressed])}]
[authentication-method-row {:title (i18n/label :t/password)

View File

@ -6,10 +6,81 @@
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.react :as react]
[status-im.i18n :as i18n]
[status-im.ui.components.colors :as colors]))
[status-im.ui.components.colors :as colors]
[re-frame.core :as re-frame]))
(defn maintain-card []
(let [animation-value (animation/create-value 0)
(defview application-info [visible?]
(letsubs [info [:hardwallet-application-info]
error [:hardwallet-application-info-error]]
[react/modal {:visible @visible?
:transparent false
:on-request-close #()}
[react/view {:padding 20
:justify-content :center}
[react/text {:style {:font-size 18
:font-weight :bold}}
"Application info"]
[react/view {:margin-top 20}
(if-not error
(for [[k v] info]
^{:key k} [react/text {:style {:font-size 15}}
(str k " " v)])
[react/text {:style {:font-size 15}}
"Applet is not installed"])]
[react/touchable-highlight
{:on-press #(reset! visible? false)}
[react/view {:align-items :center
:text-style :underline
:margin-top 48}
[react/text {:style {:font-size 18}}
"Close window"]]]]]))
(def step-name
{:preparing {:label :t/initialization
:number 1
:next-step :secret-keys}
:secret-keys {:label :t/puk-and-pair-codes
:number 2
:next-step :pairing}
:pairing {:label :t/pairing
:number 3
:next-step :recovery-phrase}
:card-ready {:label :t/pairing
:number 3
:next-step :recovery-phrase}
:generating-mnemonic {:label :t/recovery-phrase
:number 4}
:recovery-phrase-confirm-word1 {:label :t/recovery-phrase
:number 4}
:recovery-phrase-confirm-word2 {:label :t/recovery-phrase
:number 4}
:loading-keys {:label :t/recovery-phrase
:number 4}
:recovery-phrase {:label :t/recovery-phrase
:number 4}})
(defn- setup-steps [step]
(let [current-step (step-name step)
{current-label :label current-number :number second-step :next-step} current-step
{second-label :label second-number :number third-step :next-step} (step-name second-step)
{third-label :label third-number :number} (step-name third-step)]
(if current-label
[react/view styles/setup-steps-container
[react/text {:style styles/maintain-card-current-step-text}
(str current-number ". " (i18n/label current-label))]
(when second-label
[react/text {:style styles/maintain-card-second-step-text}
(str second-number ". " (i18n/label second-label))])
(when third-label
[react/text {:style styles/maintain-card-third-step-text}
(str third-number ". " (i18n/label third-label))])]
[react/text {:style styles/maintain-card-text
:number-of-lines 2}
(i18n/label :t/maintain-card-to-phone-contact)])))
(defn maintain-card [step]
(let [modal-visible? (reagent/atom false)
animation-value (animation/create-value 0)
;TODO(dmitryn): make animation smoother
interpolate-fn (fn [output-range]
(animation/interpolate animation-value
@ -24,21 +95,24 @@
(animation/anim-loop)
(animation/start)))
:display-name "maintain-card"
:reagent-render (fn [] [react/view styles/maintain-card-container
[react/view styles/hardwallet-icon-container
[vector-icons/icon :icons/hardwallet {:color colors/blue}]
[vector-icons/icon :icons/indicator-small {:color colors/blue
:container-style (styles/hardwallet-icon-indicator-small-container
(interpolate-fn [0 0.5 1 0.5 0]))}]
[vector-icons/icon :icons/indicator-middle {:color colors/blue
:container-style (styles/hardwallet-icon-indicator-middle-container
(interpolate-fn [1 0.4 0 0.4 0.8]))}]
[vector-icons/icon :icons/indicator-big {:color colors/blue
:container-style (styles/hardwallet-icon-indicator-big-container
(interpolate-fn [0.5 0.8 0.5 0.8 0.4]))}]]
[react/text {:style styles/maintain-card-text
:number-of-lines 2}
(i18n/label :t/maintain-card-to-phone-contact)]])})))
:reagent-render (fn [step] [react/view styles/maintain-card-container
[react/touchable-highlight
{:on-press #(do
(re-frame/dispatch [:hardwallet.ui/get-application-info])
(reset! modal-visible? true))}
[react/view styles/hardwallet-icon-container
[vector-icons/icon :icons/hardwallet {:color colors/blue}]
[vector-icons/icon :icons/indicator-small {:color colors/blue
:container-style (styles/hardwallet-icon-indicator-small-container
(interpolate-fn [0 0.5 1 0.5 0]))}]
[vector-icons/icon :icons/indicator-middle {:color colors/blue
:container-style (styles/hardwallet-icon-indicator-middle-container
(interpolate-fn [1 0.4 0 0.4 0.8]))}]
[vector-icons/icon :icons/indicator-big {:color colors/blue
:container-style (styles/hardwallet-icon-indicator-big-container
(interpolate-fn [0.5 0.8 0.5 0.8 0.4]))}]]]
[setup-steps step]
[application-info modal-visible?]])})))
(defn wizard-step [step-number]
(when step-number

View File

@ -11,24 +11,12 @@
:align-items :center
:justify-content :space-between})
(def hardwallet-card-image-container
{:margin-top 120})
(def hardwallet-card-image
{:width 255
:height 160})
(def hardwallet-card-image-small
{:width 44
:height 28
:position :absolute
:left 58
:top 13
:z-index 1
:margin-right 20})
(def status-hardwallet-text-container
{:margin-top 30})
(def turn-nfc-text-container
{:margin-top 55})
(def status-hardwallet-text
{:font-size 22
@ -52,44 +40,37 @@
:border-radius 10
:margin-bottom 20})
(def nfc-enabled-container
{:flex-direction :row
:justify-content :space-between
:align-items :center})
(def phone-nfc-on-image
{:width 401
:height 250})
(def phone-nfc-image
{:width 54
:height 72
:z-index 2
:margin-left 20
:margin-top 8
:align-items :baseline})
(def phone-nfc-off-image
{:width 301
:height 180})
(def hold-card-text
{:width 186
:text-align :center
:font-size 14
:color colors/blue
:line-height 20
:text-transform :uppercase
:margin-right 40})
{:width 186
:text-align :center
:font-size 14
:line-height 20
:margin-right 40})
(def nfc-enabled-container
{:flex-direction :column
:justify-content :space-between
:align-items :center
:margin-top 50})
(def nfc-disabled-container
{:flex-direction :row
{:flex-direction :column
:justify-content :space-between
:align-items :center})
:align-items :center
:margin-top 120})
(def nfc-icon
{:margin-left 52
:margin-top 22})
(def nfc-disabled-actions-container
{:flex-direction :column
:align-items :center
:justify-content :space-between
:margin-right 100
:margin-top 20})
(def turn-nfc-text
{:text-transform :uppercase
:line-height 20
@ -97,5 +78,25 @@
:color colors/gray})
(def go-to-settings-text
{:color colors/gray})
{:text-align :center
:padding-top 9
:color colors/gray})
(def bottom-container
{:height 52
:justify-content :center
:border-top-width 1
:border-color colors/gray-light})
(def product-info-container
{:flex-direction :row
:align-items :center
:justify-content :center})
(def product-info-text
{:text-align :center
:font-size 15
:color colors/blue})
(def external-link-icon
{:margin-left 5})

View File

@ -11,53 +11,47 @@
[status-im.i18n :as i18n]
[status-im.ui.components.colors :as colors]))
(defn nfc-enabled []
[react/view styles/nfc-enabled-container
[react/view
[react/image {:source (:hold-card-animation resources/ui)
:style styles/phone-nfc-on-image}]]
[react/view styles/turn-nfc-text-container
[react/text {:style styles/status-hardwallet-text
:number-of-lines 2}
(i18n/label :t/hold-card)]]])
(defn nfc-disabled []
[react/view styles/nfc-disabled-container
[react/view
[react/image {:source (:phone-nfc-off resources/ui)
:style styles/phone-nfc-off-image}]]
[react/view styles/turn-nfc-text-container
[react/text {:style styles/status-hardwallet-text
:on-press #(re-frame/dispatch [:hardwallet.ui/go-to-settings-button-pressed])}
(i18n/label :t/turn-nfc-on)]
[react/text {:style styles/go-to-settings-text
:on-press #(re-frame/dispatch [:hardwallet.ui/go-to-settings-button-pressed])}
(i18n/label :t/go-to-settings)]]])
(defview hardwallet-connect []
(letsubs [nfc-enabled? [:hardwallet/nfc-enabled?]]
[react/view styles/container
[status-bar/status-bar]
[react/view components.styles/flex
[react/view {:flex 1
:flex-direction :column
:justify-content :space-between}
[toolbar/toolbar {}
toolbar/default-nav-back
nil
[toolbar/actions [{:icon :icons/info
:icon-opts {:color :black
:accessibility-label :hardwallet-connect-info-button}
:handler #(re-frame/dispatch [:hardwallet.ui/connect-info-button-pressed])}]]]
nil]
[react/view styles/hardwallet-connect
[react/view styles/hardwallet-card-image-container
[react/image {:source (:hardwallet-card resources/ui)
:style styles/hardwallet-card-image}]]
[react/view styles/status-hardwallet-text-container
[react/text {:style styles/status-hardwallet-text}
(i18n/label :t/status-hardwallet)]
[react/text {:style styles/status-hardwallet-text}
(i18n/label :t/secure-your-assets)]
[react/text {:style styles/link-card-text
:number-of-lines 2}
(i18n/label :t/link-card)]]
[react/view (styles/bottom-action-container nfc-enabled?)
(if nfc-enabled?
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:hardwallet.ui/hold-card-button-pressed])}
[react/view styles/nfc-enabled-container
[react/image {:source (:phone-nfc resources/ui)
:style styles/phone-nfc-image}]
[react/image {:source (:hardwallet-card resources/ui)
:style styles/hardwallet-card-image-small}]
[react/text {:style styles/hold-card-text
:number-of-lines 2
:font :medium
:uppercase? true}
(i18n/label :t/hold-card)]]]
[react/view styles/nfc-disabled-container
[vector-icons/icon :icons/nfc {:color colors/gray
:container-style styles/nfc-icon}]
[react/view styles/nfc-disabled-actions-container
[react/text {:style styles/turn-nfc-text
:font :medium
:on-press #(re-frame/dispatch [:hardwallet.ui/go-to-settings-button-pressed])
:uppercase? true}
(i18n/label :t/turn-nfc-on)]
[react/text {:style styles/go-to-settings-text
:on-press #(re-frame/dispatch [:hardwallet.ui/go-to-settings-button-pressed])}
(i18n/label :t/go-to-settings)]]])]]]]))
(if nfc-enabled?
[nfc-enabled]
[nfc-disabled])]
[react/view styles/bottom-container
[react/touchable-highlight {:on-press #(.openURL react/linking "https://hardwallet.status.im")}
[react/view styles/product-info-container
[react/text {:style styles/product-info-text}
(i18n/label :t/product-information)]
[vector-icons/icon :icons/link {:color colors/blue
:container-style styles/external-link-icon}]]]]]]))

View File

@ -14,7 +14,7 @@
(re-frame/reg-sub
:hardwallet/pin-enter-step
(fn [db]
(get-in db [:hardwallet :pin :enter-step])))
(get-in db [:hardwallet :pin :enter-step] :original)))
(re-frame/reg-sub
:hardwallet/pin-status

View File

@ -60,7 +60,7 @@
(let [enabled? (not= status :validating)]
[react/view styles/pin-container
[react/view styles/center-container
[components/wizard-step 4]
;[components/wizard-step 4]
[react/text {:style styles/center-title-text
:font :bold}
(i18n/label title)]

View File

@ -23,15 +23,38 @@
:height 60
:border-radius 10
:border-width 1
:border-color colors/blue
:border-style :dashed})
:border-color colors/blue-light})
(def maintain-card-text
{:padding-horizontal 20
:font-size 12
:width 232
{:font-size 12
:padding-horizontal 30
:color colors/blue})
(def setup-steps-container
{:flex-direction :row
:align-items :baseline
:flex 1
:width "95%"
:background-color :white
:padding-left 20
:margin-right 20})
(def maintain-card-current-step-text
{:font-size 12
:color colors/blue})
(def maintain-card-second-step-text
{:font-size 12
:padding-left 8
;:background-color :red
:color colors/gray})
(def maintain-card-third-step-text
{:font-size 12
;:background-color :yellow
:padding-left 8
:color colors/gray})
(def hardwallet-icon-container
{:margin-left 20
:flex-direction :row
@ -49,7 +72,7 @@
{:opacity opacity})
(def hardwallet-card-image-container
{:margin-top 81
{:margin-top 47
:flex 1
:align-items :center})
@ -68,6 +91,10 @@
:flex-direction :column
:align-items :center})
(def card-blank-container
{:flex 1
:flex-direction :column})
(def enter-pair-code-container
{:flex 1
:flex-direction :column
@ -83,9 +110,17 @@
:text-align :center})
(def center-title-text
{:font-size 22
:text-align :center
:color colors/black})
{:font-size 22
:font-weight :bold
:text-align :center
:color colors/black})
(def bottom-container
{:height 60
:justify-content :center
:align-items :center
:border-top-width 1
:border-color colors/gray-light})
(def bottom-button-container
{:background-color colors/gray-background
@ -95,20 +130,36 @@
:width 160
:height 44
:border-radius 10
:margin-bottom 40})
:margin-bottom 14})
(def begin-button-container
{:background-color colors/gray-background
:align-items :center
:justify-content :center
:flex-direction :row
:width 160
:height 42
:border-radius 10
:margin-bottom 1})
(def bottom-button-text
{:font-size 14
{:font-size 15
:color colors/blue
:line-height 20
:text-transform :uppercase})
:line-height 20})
(def next-button-container
{:flex-direction :row
:justify-content :space-between
:align-items :center
:width "100%"
:height 52
:border-top-width 1
:border-color colors/gray-light})
(def back-and-next-buttons-container
{:flex-direction :row
:align-self :flex-end
:width "100%"
:margin-vertical 15
:margin-right 21})
:justify-content :space-between
:margin-vertical 15})
;; prepare step
@ -133,6 +184,27 @@
(def estimated-time-text
(assoc generating-codes-for-pairing-text :padding-top 25))
(def recovery-phrase-inner-container
{:align-self :center})
(def check-recovery-phrase-text
{:font-size 22
:font-weight :bold
:text-align :center
:color colors/gray})
(def recovery-phrase-word-n-text
{:font-size 22
:font-weight :bold
:text-align :center
:color colors/black})
(def recovery-phrase-description
{:padding 16})
(def recovery-phrase-description-text
{:color colors/black})
(def waiting-indicator-container
{:height 200})
@ -142,58 +214,86 @@
{:flex 1
:flex-direction :column
:justify-content :space-between
:margin-top 40})
:margin-top 30})
(def secret-keys-inner-container
{:flex-direction :column
:align-items :center})
{:flex-direction :column
:justify-content :space-between
:align-items :center})
(def secret-keys-title-container
{:width 292})
{:width 292
:margin-vertical 25})
(def secret-keys-title-text
{:font-size 22
:text-align :center
:color colors/black})
{:font-size 22
:font-weight :bold
:text-align :center
:color colors/black})
(def secret-keys-image-container
{:width 120
:height 120})
(def puk-code-title-text
{:font-size 17
:padding-top 32
:font-weight :bold
:padding-top 12
:color colors/black})
(def secret-code-explanation-container
{:margin-top 5
:margin-bottom 15})
(def puk-code-explanation-text
{:font-size 15
:width 292
:text-align :center
:padding-top 5
:color colors/gray})
{:font-size 15
:padding-horizontal 32
:text-align :center
:padding-top 5
:padding-bottom 10
:color colors/gray})
(def puk-code-numbers-container
{:justify-content :center
:flex-direction :row})
(def puk-code-numbers-border-container
{:border-bottom-width 2
:width 302
:text-align :center
;:justify-content :center
;:align-items :center
;:flex-direction :column
;:padding-bottom 10
:border-color colors/gray-lighter})
(defstyle puk-code-numbers-inner-container
{:width "85%"
:android {:margin-horizontal 16}
:height 64
:margin-top 20
:height 94
;:margin-top 10
:align-items :center
:justify-content :center
:border-width 1
:border-color colors/gray-light
:justify-content :space-between
:flex-direction :column
:border-width 2
:border-color colors/gray-lighter
:border-radius 10})
(def puk-code-text
{:font-size 17
:text-align :center
:color colors/green})
{:font-size 17
:font-weight :bold
:padding-bottom 10
:text-align :center
:color colors/green})
;; card ready
(def card-ready-container secret-keys-container)
(def card-ready-inner-container
{:align-self :center})
{:align-self :center
:flex 1
:justify-content :space-between})
;; enter pair code
@ -214,3 +314,43 @@
{:font-size 15
:padding-top 5
:color colors/gray})
(def card-is-empty-text
{:color colors/black
:font-size 17
:font-weight :bold
:margin-bottom 20})
(def card-is-empty-prepare-text
{:margin-top 25
:padding-horizontal 40})
(def remaining-steps-container
{:margin-top 55
:margin-left 16
:flex 1
:width "90%"
:flex-direction :column})
(def remaining-steps-text
{:color colors/gray
:font-size 15})
(def remaining-step-row
{:flex-direction :row
:margin-top 15})
(def remaining-step-row-text
{:border-width 1
:border-radius 16
:border-color colors/gray-light
:align-items :center
:justify-content :center
:width 32
:height 32})
(def remaining-step-row-text2
{:align-items :center
:justify-content :center
:margin-left 11})

View File

@ -10,3 +10,50 @@
:hardwallet-pair-code
(fn [db]
(get-in db [:hardwallet :pair-code])))
(re-frame/reg-sub
:hardwallet-recovery-phrase-word
(fn [db]
(get-in db [:hardwallet
:recovery-phrase
(get-in db [:hardwallet :recovery-phrase :step])])))
(re-frame/reg-sub
:hardwallet-recovery-phrase-input-word
(fn [db]
(get-in db [:hardwallet :recovery-phrase :input-word])))
(re-frame/reg-sub
:hardwallet-recovery-phrase-confirm-error
(fn [db]
(get-in db [:hardwallet :recovery-phrase :confirm-error])))
(re-frame/reg-sub
:hardwallet-recovery-phrase-step
(fn [db]
(get-in db [:hardwallet :recovery-phrase :step])))
(re-frame/reg-sub
:hardwallet-secrets
(fn [db]
(get-in db [:hardwallet :secrets])))
(re-frame/reg-sub
:hardwallet-setup-error
(fn [db]
(get-in db [:hardwallet :setup-error])))
(re-frame/reg-sub
:hardwallet-mnemonic
(fn [db]
(get-in db [:hardwallet :secrets :mnemonic])))
(re-frame/reg-sub
:hardwallet-application-info
(fn [db]
(get-in db [:hardwallet :application-info])))
(re-frame/reg-sub
:hardwallet-application-info-error
(fn [db]
(get-in db [:hardwallet :application-info-error])))

View File

@ -2,6 +2,7 @@
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.ui.screens.profile.seed.views :as seed.views]
[status-im.ui.screens.hardwallet.components :as components]
[status-im.ui.screens.hardwallet.pin.views :as pin.views]
[status-im.ui.components.animation :as animation]
@ -13,58 +14,149 @@
[status-im.ui.components.styles :as components.styles]
[status-im.ui.components.text-input.view :as text-input]
[status-im.i18n :as i18n]
[status-im.ui.components.colors :as colors]))
[status-im.utils.utils :as utils]
[status-im.ui.components.colors :as colors]
[status-im.ui.screens.hardwallet.setup.styles :as styles]))
(defn secret-keys []
[react/view styles/secret-keys-container
[react/view styles/secret-keys-inner-container
[react/view styles/secret-keys-title-container
[components/wizard-step 2]
[react/text {:style styles/secret-keys-title-text
:number-of-lines 2
:font :bold}
(i18n/label :t/write-down-and-store-securely)]]
[react/text {:style styles/puk-code-title-text
:font :bold}
(i18n/label :t/puk-code)]
[react/text {:style styles/puk-code-explanation-text}
(i18n/label :t/puk-code-explanation)]
[react/view styles/puk-code-numbers-container
[react/view styles/puk-code-numbers-inner-container
[react/text {:style styles/puk-code-text
:font :bold}
"1234 5678 9123"]]]
[react/text {:style styles/puk-code-title-text
:font :bold}
(i18n/label :t/pair-code)]
[react/text {:style styles/puk-code-explanation-text
:number-of-lines 2}
(i18n/label :t/pair-code-explanation)]
[react/view styles/puk-code-numbers-container
[react/view styles/puk-code-numbers-inner-container
[react/text {:style styles/puk-code-text
:font :bold}
"a12k52kh0x"]]]]
[react/view styles/next-button-container
[react/view components.styles/flex]
[components.common/bottom-button
{:on-press #(re-frame/dispatch [:hardwallet.ui/secret-keys-next-button-pressed])
:forward? true}]]])
(defview secret-keys []
(letsubs [secrets [:hardwallet-secrets]]
[react/view styles/secret-keys-container
[react/scroll-view
[react/view styles/secret-keys-inner-container
[react/view
[react/image {:source (:secret-keys resources/ui)
:style styles/secret-keys-image-container}]]
[react/view styles/secret-keys-title-container
[react/text {:style styles/secret-keys-title-text
:number-of-lines 2}
(i18n/label :t/write-down-and-store-securely)]]
[react/view styles/puk-code-numbers-container
[react/view styles/puk-code-numbers-inner-container
[react/text {:style styles/puk-code-title-text}
(i18n/label :t/pin-code)]
[react/view styles/puk-code-numbers-border-container]
[react/text {:style styles/puk-code-text}
(:pin secrets)]]]
[react/view styles/secret-code-explanation-container
[react/text {:style styles/puk-code-explanation-text}
(i18n/label :t/pin-code-description)]]
[react/view styles/puk-code-numbers-container
[react/view styles/puk-code-numbers-inner-container
[react/text {:style styles/puk-code-title-text}
(i18n/label :t/puk-code)]
[react/view styles/puk-code-numbers-border-container]
[react/text {:style styles/puk-code-text}
(:puk secrets)]]]
[react/view styles/secret-code-explanation-container
[react/text {:style styles/puk-code-explanation-text}
(i18n/label :t/puk-code-explanation)]]
[react/view styles/puk-code-numbers-container
[react/view styles/puk-code-numbers-inner-container
[react/text {:style styles/puk-code-title-text}
(i18n/label :t/pair-code)]
[react/view styles/puk-code-numbers-border-container]
[react/text {:style styles/puk-code-text}
(:password secrets)]]]
[react/view styles/secret-code-explanation-container
[react/text {:style styles/puk-code-explanation-text
:number-of-lines 2}
(i18n/label :t/pair-code-explanation)]]]
[react/view styles/next-button-container
[react/view components.styles/flex]
[react/view {:margin-right 20}
[components.common/bottom-button
{:on-press #(re-frame/dispatch [:hardwallet.ui/secret-keys-next-button-pressed])
:uppercase? false
:forward? true}]]]]]))
(defn card-ready []
[react/view styles/card-ready-container
[react/view styles/card-ready-inner-container
[components/wizard-step 3]
[react/text {:style styles/center-title-text
:number-of-lines 2
:font :bold}
(i18n/label :t/card-is-ready)]]
[react/view styles/next-button-container
[react/view components.styles/flex]
[components.common/bottom-button
{:on-press #(re-frame/dispatch [:hardwallet.ui/create-pin-button-pressed])
:label (i18n/label :t/create-pin)
:forward? true}]]])
[react/view (assoc styles/center-container :margin-top 68)
[react/text {:style styles/center-title-text}
(i18n/label :t/card-is-paired)]
[react/text {:style styles/estimated-time-text}
(i18n/label :t/next-step-generating-mnemonic)]]
[react/view]
[react/view styles/next-button-container
[react/view components.styles/flex]
[react/view {:margin-right 20}
[components.common/bottom-button
{:on-press #(re-frame/dispatch [:hardwallet.ui/card-ready-next-button-pressed])
:forward? true}]]]]])
(defview recovery-phrase []
(letsubs [mnemonic [:hardwallet-mnemonic]]
(let [mnemonic-vec (vec (map-indexed vector (clojure.string/split mnemonic #" ")))]
[react/view styles/card-ready-container
[react/view styles/recovery-phrase-inner-container
[react/view styles/center-container
[react/text {:style styles/center-title-text
:number-of-lines 2
:font :bold}
(i18n/label :t/your-recovery-phrase)]
[react/view {:style {:margin-top 17
:margin-bottom 16
:margin-horizontal 16
:flex-direction :row
:border-radius 8
:background-color colors/white
:border-width 1
:border-color colors/gray-lighter}}
[seed.views/six-words (subvec mnemonic-vec 0 6)]
[react/view {:style {:width 1
:background-color colors/gray-lighter}}]
[seed.views/six-words (subvec mnemonic-vec 6 12)]]
[react/view styles/recovery-phrase-description
[react/text {:style styles/recovery-phrase-description-text}
(i18n/label :t/your-recovery-phrase-description)]]]]
[react/view styles/next-button-container
[react/view components.styles/flex]
[react/view {:margin-right 20}
[components.common/bottom-button
{:on-press #(re-frame/dispatch [:hardwallet.ui/recovery-phrase-next-button-pressed])
:label (i18n/label :t/next)
:uppercase? false
:forward? true}]]]])))
(defview confirm-word-input [error ref step]
{:component-will-update #(.clear @ref)}
[text-input/text-input-with-label
{:on-change-text #(re-frame/dispatch [:hardwallet.ui/recovery-phrase-confirm-word-input-changed %])
:auto-focus true
:ref (partial reset! ref)
:on-submit-editing #(re-frame/dispatch [:hardwallet.ui/recovery-phrase-confirm-word-next-button-pressed])
:error error
:placeholder (i18n/label :t/enter-word)}])
(defview recovery-phrase-confirm-word [step]
^{:key (str step)}
(letsubs [width [:dimensions/window-width]
word [:hardwallet-recovery-phrase-word]
input-word [:hardwallet-recovery-phrase-input-word]
error [:hardwallet-recovery-phrase-confirm-error]
ref (reagent/atom nil)]
(let [{:keys [word idx]} word]
[react/view styles/enter-pair-code-container
[react/view styles/enter-pair-code-title-container
[react/view
[react/text {:style styles/check-recovery-phrase-text}
(i18n/label :t/check-your-recovery-phrase)]
[react/text {:style styles/recovery-phrase-word-n-text}
(i18n/label :t/word-n {:number (inc idx)})]]
[react/view (styles/enter-pair-code-input-container width)
[confirm-word-input error ref step]]]
[react/view styles/back-and-next-buttons-container
[components.common/bottom-button
{:on-press #(re-frame/dispatch [:hardwallet.ui/recovery-phrase-confirm-word-back-button-pressed])
:back? true
:uppercase? false
:label (i18n/label :t/back)}]
[components.common/bottom-button
{:on-press #(re-frame/dispatch [:hardwallet.ui/recovery-phrase-confirm-word-next-button-pressed])
:disabled? (empty? input-word)
:uppercase? false
:forward? true}]]])))
(defview enter-pair-code []
(letsubs [pair-code [:hardwallet-pair-code]
@ -84,13 +176,15 @@
:placeholder ""}]]]
[react/view styles/next-button-container
[react/view components.styles/flex]
[components.common/bottom-button
{:on-press #(re-frame/dispatch [:hardwallet.ui/pair-code-next-button-pressed])
:disabled? (empty? pair-code)
:forward? true}]]]))
[react/view {:margin-right 20}
[components.common/bottom-button
{:on-press #(re-frame/dispatch [:hardwallet.ui/pair-code-next-button-pressed])
:disabled? (empty? pair-code)
:uppercase? false
:forward? true}]]]]))
(defn- card-with-button-view
[{:keys [text-label button-label button-container-style on-press-event]}]
[{:keys [text-label button-label button-container-style on-press]}]
"Generic view with centered card image and button at the bottom.
Used by 'Prepare', 'Pair', 'No slots', 'Card is linked' screens"
[react/view styles/card-with-button-view-container
@ -101,41 +195,86 @@
[react/text {:style styles/center-text}
(i18n/label text-label)]]]
[react/touchable-highlight
{:on-press #(re-frame/dispatch [on-press-event])}
{:on-press on-press}
[react/view (merge styles/bottom-button-container button-container-style)
[react/text {:style styles/bottom-button-text
:font :medium
:uppercase? true}
[react/text {:style styles/bottom-button-text}
(i18n/label button-label)]]]])
(defn begin []
[card-with-button-view {:text-label :t/card-is-empty
:button-label :t/begin-set-up
:on-press-event :hardwallet.ui/begin-setup-button-pressed}])
[react/view styles/card-blank-container
[react/scroll-view
[react/view styles/hardwallet-card-image-container
[react/text {:style styles/card-is-empty-text}
(i18n/label :t/card-is-blank)]
[react/view {:margin-top 15}
[react/image {:source (:hardwallet-card resources/ui)
:style styles/hardwallet-card-image}]]
[react/view styles/card-is-empty-prepare-text
[react/text {:style styles/center-text}
(i18n/label :t/card-setup-prepare-text)]]]
[react/view styles/remaining-steps-container
[react/text {:style styles/remaining-steps-text}
(i18n/label :t/remaining-steps)]
[react/view {:margin-bottom 25}
(for [[number text] [["1" (i18n/label :t/initialization-of-the-card)]
["2" (i18n/label :t/puk-and-pairing-codes-displayed)]
["3" (i18n/label :t/device-pairing)]
["4" (i18n/label :t/recovery-phrase)]]]
^{:key number} [react/view styles/remaining-step-row
[react/view styles/remaining-step-row-text
[react/text {:style {:color colors/black}}
number]]
[react/view styles/remaining-step-row-text2
[react/text {:style {:color colors/black}}
text]]])]]
[react/view styles/bottom-container
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:hardwallet.ui/begin-setup-button-pressed])}
[react/view styles/begin-button-container
[react/text {:style styles/bottom-button-text}
(i18n/label :t/begin-set-up)]]]]]])
(defn pair []
[card-with-button-view {:text-label :t/pair-card-question
:button-label :t/pair-card
:on-press-event :hardwallet.ui/pair-card-button-pressed}])
:on-press-event #(re-frame/dispatch [:hardwallet.ui/pair-card-button-pressed])}])
(defn no-slots []
[card-with-button-view {:text-label :t/no-pairing-slots-available
:button-label :t/help
:button-container-style {:background-color colors/white}
:on-press-event :hardwallet.ui/no-pairing-slots-help-button-pressed}])
:on-press-event (.openURL react/linking "https://hardwallet.status.im")}])
(defn card-already-linked []
[card-with-button-view {:text-label :t/card-already-linked
:button-label :t/help
:button-container-style {:background-color colors/white}
:on-press-event :hardwallet.ui/card-already-linked-help-button-pressed}])
:on-press-event (.openURL react/linking "https://hardwallet.status.im")}])
(defview error []
(letsubs [error [:hardwallet-setup-error]]
[react/view styles/card-with-button-view-container
[react/view styles/hardwallet-card-image-container
[react/image {:source (:hardwallet-card resources/ui)
:style styles/hardwallet-card-image}]
[react/view styles/center-text-container
[react/text {:style styles/center-text}
(i18n/label :t/something-went-wrong)]
[react/text {:style styles/center-text}
(str (:code error) "\n" (:error error))]]]
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:hardwallet.ui/error-button-pressed])}
[react/view styles/bottom-button-container
[react/text {:style styles/bottom-button-text
:font :medium
:uppercase? false}
(i18n/label :t/try-again)]]]]))
(defn- loading-view [{:keys [title-label text-label estimated-time-seconds step-number]}]
"Generic view with waiting time estimate and loading indicator.
Used by 'Prepare', 'Pairing', 'Completing' screens"
[react/view styles/loading-view-container
[react/view styles/center-container
[components/wizard-step step-number]
[react/text {:style styles/center-title-text
:font :bold}
(i18n/label title-label)]
@ -144,26 +283,64 @@
:number-of-lines 2}
(i18n/label text-label)])
[react/text {:style styles/estimated-time-text}
(str
(i18n/label :t/estimated-time)
" ~"
estimated-time-seconds
" "
(i18n/label-pluralize estimated-time-seconds
:t/datetime-second))]]
(i18n/label :t/this-will-take-few-seconds)]]
[react/view styles/waiting-indicator-container
[react/activity-indicator {:animating true
:size :large}]]])
(defn preparing []
[loading-view {:title-label :t/preparing-card
:text-label :t/generating-codes-for-pairing
:estimated-time-seconds 20
:step-number 1}])
(defn- preparing []
[react/view styles/loading-view-container
[react/view styles/center-container
[react/text {:style styles/center-title-text
:font :bold}
(i18n/label :t/preparing-card)]
[react/text {:style styles/generating-codes-for-pairing-text
:number-of-lines 2}
(i18n/label :t/generating-codes-for-pairing)]
[react/text {:style styles/estimated-time-text}
(i18n/label :t/taking-long-hold-phone-connected)]]
[react/view styles/waiting-indicator-container
[react/activity-indicator {:animating true
:size :large}]]])
(defn pairing []
[loading-view {:title-label :t/pairing-card
:estimated-time-seconds 30}])
(defn- generating-mnemonic []
[react/view styles/loading-view-container
[react/view styles/center-container
[react/text {:style styles/center-title-text
:font :bold}
(i18n/label :t/generating-mnemonic)]
[react/text {:style styles/estimated-time-text}
(i18n/label :t/this-will-take-few-seconds)]]
[react/view styles/waiting-indicator-container
[react/activity-indicator {:animating true
:size :large}]]])
(defn- loading-keys []
[react/view styles/loading-view-container
[react/view styles/center-container
[react/text {:style styles/center-title-text
:font :bold}
(i18n/label :t/finishing-card-setup)]
[react/text {:style styles/generating-codes-for-pairing-text
:number-of-lines 2}
(i18n/label :t/finishing-card-setup-steps)]
[react/text {:style styles/estimated-time-text}
(i18n/label :t/this-will-take-few-seconds)]]
[react/view styles/waiting-indicator-container
[react/activity-indicator {:animating true
:size :large}]]])
(defn- pairing []
[react/view styles/loading-view-container
[react/view styles/center-container
[react/text {:style styles/center-title-text
:font :bold}
(i18n/label :t/pairing-card)]
[react/text {:style styles/estimated-time-text}
(i18n/label :t/this-will-take-few-seconds)]]
[react/view styles/waiting-indicator-container
[react/activity-indicator {:animating true
:size :large}]]])
(defn complete []
[loading-view {:title-label :t/completing-card-setup
@ -178,11 +355,17 @@
:card-ready [card-ready]
:complete [complete]
:pair [pair]
:generating-mnemonic [generating-mnemonic]
:loading-keys [loading-keys]
:enter-pair-code [enter-pair-code]
:no-slots [no-slots]
:card-already-linked [card-already-linked]
:pairing [pairing]
:pin [pin.views/main]
:recovery-phrase [recovery-phrase]
:recovery-phrase-confirm-word1 [recovery-phrase-confirm-word step]
:recovery-phrase-confirm-word2 [recovery-phrase-confirm-word step]
:error [error]
[begin]))
(defview hardwallet-setup []
@ -190,5 +373,5 @@
[react/keyboard-avoiding-view components.styles/flex
[react/view styles/container
[react/view styles/inner-container
[components/maintain-card]
[components/maintain-card step]
[content step]]]]))

View File

@ -17,22 +17,25 @@
:align-items :center
:justify-content :center})
(def hardwallet-card-image
{:width 255
:height 160})
(def icon-check-container
{:width 64
:height 64
:bottom -40
:position :absolute
{:width 160
:height 160
:align-items :center
:justify-content :center
:background-color colors/green
:background-color colors/green-transparent-10
:border-radius 100})
(def icon-check-inner-container
{:width 80
:height 80
:align-items :center
:justify-content :center
:background-color colors/white
:border-radius 50})
(def complete-text-container
{:margin-top 40})
{:flex-direction :column
:align-items :center})
(def complete-text
{:font-size 22
@ -43,9 +46,11 @@
(def complete-information-text
{:text-align :center
:font-size 15
:line-height 22
:color colors/gray
:margin-bottom 21
:padding-horizontal 80
:padding-vertical 10})
:padding-top 20})
(def bottom-action-container
{:background-color colors/gray-background
@ -58,7 +63,11 @@
:margin-bottom 40})
(def bottom-action-text
{:font-size 14
{:font-size 15
:color colors/blue
:line-height 20
:text-transform :uppercase})
(def waiting-indicator-container
{:height 20
:margin-bottom 70})

View File

@ -1,36 +1,46 @@
(ns status-im.ui.screens.hardwallet.success.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [re-frame.core :as re-frame]
[status-im.react-native.resources :as resources]
[status-im.ui.screens.hardwallet.success.styles :as styles]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.react :as react]
[status-im.ui.components.styles :as components.styles]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.i18n :as i18n]
[status-im.ui.components.colors :as colors]))
[status-im.ui.components.colors :as colors]
[reagent.core :as reagent]))
(defn- activity-indicator [show?]
[react/view styles/waiting-indicator-container
(when @show?
[react/view
[react/text {:style {:padding-bottom 20}}
(i18n/label :t/sign-in-to-status)]
[react/activity-indicator {:animating true
:size :large}]])])
(defn hardwallet-success []
[react/view styles/container
[status-bar/status-bar]
[react/view components.styles/flex
[react/view styles/inner-container
[react/view styles/hardwallet-card-image-container
[react/image {:source (:hardwallet-card resources/ui)
:style styles/hardwallet-card-image}]
[react/view styles/icon-check-container
[vector-icons/icon :icons/check {:color :white
:width 30
:height 30}]]]
[react/view styles/complete-text-container
[react/text {:style styles/complete-text}
(i18n/label :t/complete-exclamation)]
[react/text {:style styles/complete-information-text
:number-of-lines 3}
(i18n/label :t/complete-hardwallet-setup)]]
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:hardwallet.ui/success-button-pressed])}
[react/view styles/bottom-action-container
[react/text {:style styles/bottom-action-text
:font :medium
:uppercase? true}
(i18n/label :t/okay)]]]]]])
(let [processing? (reagent/atom false)]
[react/view styles/container
[status-bar/status-bar]
[react/view components.styles/flex
[react/view styles/inner-container
[react/view styles/hardwallet-card-image-container
[react/view styles/icon-check-container
[react/view styles/icon-check-inner-container
[vector-icons/icon :icons/check {:color colors/green
:width 30
:height 30}]]]]
[react/view styles/complete-text-container
[activity-indicator processing?]
[react/text {:style styles/complete-text}
(i18n/label :t/complete-exclamation)]
[react/text {:style styles/complete-information-text}
(i18n/label :t/complete-hardwallet-setup)]
[react/touchable-highlight
{:on-press #(do
(reset! processing? true)
(re-frame/dispatch [:hardwallet.ui/success-button-pressed]))}
[react/view styles/bottom-action-container
[react/text {:style styles/bottom-action-text}
(i18n/label :t/okay)]]]]]]]))

View File

@ -15,7 +15,6 @@
(def nfc #js {})
(def orientation #js {})
(def qr-code #js {})
(def nfc-manager #js {:default #js {}})
(def react-native
#js {:NativeModules #js {}
:Animated #js {:View #js {}
@ -28,6 +27,7 @@
(def vector-icons #js {:default #js {}})
(def webview-bridge #js {:default #js {}})
(def svg #js {:default #js {}})
(def status-keycard #js {:default #js {}})
(defrecord Notification [])
(def react-native-firebase #js {:default #js {:notifications #js {:Notification Notification}}})

View File

@ -0,0 +1,35 @@
(ns status-im.test.accounts.create.core
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.accounts.create.core :as models]))
(deftest on-account-created
(let [result (models/on-account-created {:random-guid-generator (constantly "")
:signing-phrase ""
:status ""
:db {}}
{:pubkey "04de2e21f1642ebee03b9aa4bf1936066124cc89967eaf269544c9b90c539fd5c980166a897d06dd4d3732b38116239f63c89395a8d73eac72881fab802010cb56"
:address "7e92236392a850980d00d0cd2a4b92886bd7fe7b"
:mnemonic "hello world"}
"password"
true)]
(is (= (:db result)
{:accounts/login {:address "7e92236392a850980d00d0cd2a4b92886bd7fe7b", :password "password", :processing true},
:accounts/accounts {"7e92236392a850980d00d0cd2a4b92886bd7fe7b"
{:address "7e92236392a850980d00d0cd2a4b92886bd7fe7b", :mnemonic "hello world", :signing-phrase "",
:signed-up? true, :name "Dark Woozy Alligatorsnappingturtle", :desktop-notifications? false,
:settings {:wallet {:visible-tokens {:testnet #{:STT :HND},
:mainnet #{:SNT},
:rinkeby #{:MOKSHA :KDO}, :xdai #{}, :poa #{}}}},
:networks nil,
:photo-path "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAADAFBMVEX////YjowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRS2MAAABAHRSTlP//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmfXxgAABnNJREFUeNoBaAaX+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoRUBAbwwC1cAAAAASUVORK5CYII=",
:status "",
:seed-backed-up? true,
:network "mainnet_rpc",
:public-key "04de2e21f1642ebee03b9aa4bf1936066124cc89967eaf269544c9b90c539fd5c980166a897d06dd4d3732b38116239f63c89395a8d73eac72881fab802010cb56",
:installation-id ""}},
:network "mainnet_rpc",
:node/status :starting}))
(is (= (keys result)
[:db
:node/start
:data-store/base-tx]))))

View File

@ -24,10 +24,10 @@
6
:original))))
(testing "confirmation entered"
(is (= {:db {:hardwallet {:pin {:original [1 2 3 4 5 6]
:confirmation [1 2 3 4 5 6]
:enter-step :confirmation
:status :validating}}}}
(is (= {:db {:hardwallet {:pin {:original [1 2 3 4 5 6]
:confirmation [1 2 3 4 5 6]
:enter-step :confirmation
:status :validating}}}}
(hardwallet/process-pin-input {:db {:hardwallet {:pin {:original [1 2 3 4 5 6]
:confirmation [1 2 3 4 5]
:enter-step :confirmation}}}}
@ -44,3 +44,28 @@
:enter-step :confirmation}}}}
7
:confirmation)))))
(deftest on-generate-and-load-key-success
(is (= (select-keys
(get-in
(hardwallet/on-generate-and-load-key-success
{:random-guid-generator (constantly "")
:signing-phrase ""
:status ""
:db {}}
#js {"whisper-private-key" "f342f3ef17ce86abfa92b912b3a108a4546cfc687fd8e0f02fedf87a60ee4c0f"
"whisper-public-key" "04de2e21f1642ebee03b9aa4bf1936066124cc89967eaf269544c9b90c539fd5c980166a897d06dd4d3732b38116239f63c89395a8d73eac72881fab802010cb56"
"encryption-public-key" "04f2a432677a1b7c4f1bb22078135821d1d10fce23422297b5c808a545f2b61cdba38ee7394762172fc6ff5e9e28db7535e555efe2812905ffd4e0c25e82a98ae8"
"whisper-address" "87df2285f90b71221fab6267b7cb37532fedbb1f"
"wallet-address" "7e92236392a850980d00d0cd2a4b92886bd7fe7b"})
[:db :hardwallet])
[:whisper-private-key
:whisper-public-key
:encryption-public-key
:wallet-address
:whisper-address]))
{:whisper-private-key "f342f3ef17ce86abfa92b912b3a108a4546cfc687fd8e0f02fedf87a60ee4c0f"
:whisper-public-key "0x04de2e21f1642ebee03b9aa4bf1936066124cc89967eaf269544c9b90c539fd5c980166a897d06dd4d3732b38116239f63c89395a8d73eac72881fab802010cb56"
:encryption-public-key "04f2a432677a1b7c4f1bb22078135821d1d10fce23422297b5c808a545f2b61cdba38ee7394762172fc6ff5e9e28db7535e555efe2812905ffd4e0c25e82a98ae8"
:whisper-address "87df2285f90b71221fab6267b7cb37532fedbb1f"
:wallet-address "7e92236392a850980d00d0cd2a4b92886bd7fe7b"}))

View File

@ -452,6 +452,7 @@
"currency-display-name-thb": "Thailand Baht",
"transactions-filter-type": "Type",
"next": "Next",
"back": "Back",
"recent": "Recent statuses",
"wallet-send-token": "Send {{symbol}}",
"bootnodes-enabled": "Bootnodes enabled",
@ -751,31 +752,52 @@
"send-command-payment": "Send a payment",
"request-command-payment": "Request a payment",
"choose-authentication-method": "Choose an authentication method to protect your account",
"keycard": "Keycard",
"status-hardwallet-capitalized": "Status Hardwallet",
"status-hardwallet": "Status hardwallet",
"secure-your-assets": "secure your assets",
"link-card": "Link the card and use it to confirm your identity on the platform.",
"hold-card": "hold card to the back of your phone",
"turn-nfc-on": "turn nfc on",
"go-to-settings": "Go to Settings",
"hold-card": "Hold card to the back\n of your phone",
"turn-nfc-on": "Turn NFC on to continue",
"go-to-settings": "Go to Settings...",
"card-is-empty": "Card is empty",
"begin-set-up": "begin set up",
"card-is-blank": "This card is blank",
"card-setup-prepare-text": "The whole process will take a few minutes.",
"card-is-paired": "Card is paired",
"begin-set-up": "Begin setup",
"maintain-card-to-phone-contact": "Maintain card-to-phone contact during process.",
"preparing-card": "Preparing card",
"generating-codes-for-pairing": "Generating codes for pairing with your Status account.",
"generating-codes-for-pairing": "> Downloading product software to card\n > Generating unlocking & pairing codes",
"estimated-time": "Estimated time",
"cant-read-card": "Can't read card",
"cant-read-card-error-explanation": "Card must stay in contact with phone during setup so it can connect to the NFC reader",
"write-down-and-store-securely": "Write these down and store them securely",
"write-down-and-store-securely": "Write codes down\n & store them securely",
"puk-code": "PUK code",
"puk-code-explanation": "Unlocks card if you lose access",
"puk-code-explanation": "If you forget your PIN or enter it incorrectly 3 times, you'll need this code to unlock your card.",
"pair-code": "Pair code",
"pair-code-explanation": "Pairs card to a different device with the same Status account on it",
"secret-keys-confirmation-title": "Did you write them down?",
"secret-keys-confirmation-text": "Record these now because you won't see this screen again",
"secret-keys-confirmation-confirm": "GOT IT",
"secret-keys-confirmation-cancel": "SEE IT AGAIN",
"see-it-again": "SEE IT AGAIN",
"completing-card-setup": "Completing card setup",
"generating-mnemonic": "Generating mnemonic phrase",
"next-step-generating-mnemonic": "Next step is generating mnemonic phrase for your card",
"this-will-take-few-seconds": "This will take a few seconds",
"finishing-card-setup": "Finishing card setup",
"finishing-card-setup-steps": "> Loading keys to the card\n> Generating account",
"product-information": "Product Information",
"remaining-steps": "Remaining steps",
"initialization-of-the-card": "Initialization of the card",
"puk-and-pairing-codes-displayed": "PUK and pairing codes displayed",
"begin-keycard-setup-confirmation-text": "Setup will erase your card including the keys already stored on your card. Would you like to continue?",
"device-pairing": "Device pairing",
"something-went-wrong": "Something went wrong",
"try-again": "Try again",
"taking-long-hold-phone-connected": "This will take a few seconds.\n Hold card connected to the phone.",
"pin-code": "PIN code",
"pin-code-description": "Unlocks the card",
"create-pin": "Create a PIN",
"create-pin-description": "You'll need your card + this PIN to log in and to confirm transactions",
"repeat-pin": "Repeate your PIN",
@ -788,6 +810,12 @@
"card-already-linked": "Card is already linked to another account",
"help": "help",
"pairing-card": "Pairing card",
"complete-exclamation": "Complete!",
"complete-hardwallet-setup": "This card is now an essential part your account security. Transactions can't be sent without it.",
"okay": "Okay",
"initialization": "Initialization",
"puk-and-pair-codes": "PUK and pair codes",
"pairing": "Pairing",
"view-my-wallet": "View my wallet",
"share-my-profile": "Share my profile",
"share-chat": "Share chat",