From e11385e35093f6f312bf0a037dc63fe829f3fc2b Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Mon, 4 Nov 2019 11:51:56 +0200 Subject: [PATCH] Add web3.keycard.signTypedData Signed-off-by: Vitaliy Vlasov --- .../app/src/main/res/drawable-hdpi/nfc.png | Bin 0 -> 1315 bytes .../app/src/main/res/drawable-mdpi/nfc.png | Bin 0 -> 940 bytes .../app/src/main/res/drawable-xhdpi/nfc.png | Bin 0 -> 1713 bytes .../app/src/main/res/drawable-xxhdpi/nfc.png | Bin 0 -> 2531 bytes .../app/src/main/res/drawable-xxxhdpi/nfc.png | Bin 0 -> 3272 bytes externs.js | 2 + .../nfc.imageset/Contents.json | 23 ++++ .../Images.xcassets/nfc.imageset/nfc-1.png | Bin 0 -> 1713 bytes .../Images.xcassets/nfc.imageset/nfc-2.png | Bin 0 -> 2531 bytes .../Images.xcassets/nfc.imageset/nfc.png | Bin 0 -> 940 bytes src/status_im/browser/core.cljs | 10 +- src/status_im/constants.cljs | 6 +- src/status_im/hardwallet/card.cljs | 37 +++++ src/status_im/hardwallet/common.cljs | 2 +- src/status_im/hardwallet/fx.cljs | 4 + src/status_im/hardwallet/keycard.cljs | 4 +- src/status_im/hardwallet/real_keycard.cljs | 20 ++- src/status_im/hardwallet/sign.cljs | 60 ++++++++ .../hardwallet/simulated_keycard.cljs | 2 + src/status_im/signing/core.cljs | 46 +++++-- src/status_im/signing/keycard.cljs | 17 +-- src/status_im/subs.cljs | 16 ++- src/status_im/ui/screens/popover/views.cljs | 8 +- src/status_im/ui/screens/signing/styles.cljs | 19 +++ src/status_im/ui/screens/signing/views.cljs | 128 ++++++++++++++++-- translations/en.json | 9 ++ 26 files changed, 369 insertions(+), 44 deletions(-) create mode 100644 android/app/src/main/res/drawable-hdpi/nfc.png create mode 100644 android/app/src/main/res/drawable-mdpi/nfc.png create mode 100644 android/app/src/main/res/drawable-xhdpi/nfc.png create mode 100644 android/app/src/main/res/drawable-xxhdpi/nfc.png create mode 100644 android/app/src/main/res/drawable-xxxhdpi/nfc.png create mode 100644 ios/StatusIm/Images.xcassets/nfc.imageset/Contents.json create mode 100644 ios/StatusIm/Images.xcassets/nfc.imageset/nfc-1.png create mode 100644 ios/StatusIm/Images.xcassets/nfc.imageset/nfc-2.png create mode 100644 ios/StatusIm/Images.xcassets/nfc.imageset/nfc.png diff --git a/android/app/src/main/res/drawable-hdpi/nfc.png b/android/app/src/main/res/drawable-hdpi/nfc.png new file mode 100644 index 0000000000000000000000000000000000000000..57429ac2c517ed0b359d4ac3e8b1f51ac9c8e931 GIT binary patch literal 1315 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 Hu0mjfm0}+X literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xxhdpi/nfc.png b/android/app/src/main/res/drawable-xxhdpi/nfc.png new file mode 100644 index 0000000000000000000000000000000000000000..36535b29a651cebecefb586e332a488f06a2c3e3 GIT binary patch literal 2531 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xxxhdpi/nfc.png b/android/app/src/main/res/drawable-xxxhdpi/nfc.png new file mode 100644 index 0000000000000000000000000000000000000000..5dad02d58b8141bac130d8ee0268408a39a77a7b GIT binary patch literal 3272 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 Hu0mjfm0}+X literal 0 HcmV?d00001 diff --git a/ios/StatusIm/Images.xcassets/nfc.imageset/nfc-2.png b/ios/StatusIm/Images.xcassets/nfc.imageset/nfc-2.png new file mode 100644 index 0000000000000000000000000000000000000000..36535b29a651cebecefb586e332a488f06a2c3e3 GIT binary patch literal 2531 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 literal 0 HcmV?d00001 diff --git a/ios/StatusIm/Images.xcassets/nfc.imageset/nfc.png b/ios/StatusIm/Images.xcassets/nfc.imageset/nfc.png new file mode 100644 index 0000000000000000000000000000000000000000..685858afa1fb03d95a43222f4c0e6742e296c29b GIT binary patch literal 940 zcmV;d15^BoP)QEvAPHI!Q(J(111&&e^Cc7NtazqS6CBy;M^ zh^m1sBh*Ij7V9xS%LrP+L6Xx2FWJ!Xb=sX)omwME;)V&OZIU3ELp9g%gg?=eNI$tv z@DouRRdvU&G``d0LK@S^51gH}xKMq-STfhScRU4h5K38ztAhxr#+YN0H zqYI)O-fDOHyTjt-Yb-%TvvfBN&G(c1K^QLr>&}^!P{fWQWTA!RO$rnmnz}SG;dvY; zd90vwgId18_9P@DnKvrX%l#xS;IZNptlTb-(1S*9M8Tf|H9W-iabPNAv|d?q#z+Z; zGbDcOsoPkOxyzB&lZJ?FHFkw+7R=aHAZ9!P%vrZb{{(+8JVf}5(Em%@T;Ti`Bhj-i zZ(LBwQqBE!9Re`|$GK+c&S2fC|`>l`z=I$3cg=Uiq2NA&CjNwK&b6kDzN( zqIi4_YarFe3m)QEh;-ON7^WY*>BV36Vcone-9Y3^J~5jS_AM(=&?}ppHG&|2nT1nwb3lnBs9oCMEXq1bfTbm^rBp+>~qEfPI{5xV0DoV!Il0EVET zpgkgLKbN<(4Pv(UWl03po4P@H5-M77vtvsp)1Wd~gTl;bMmAiH@q()WIW=Rj^l4IM zY;MtR9pZyBy)b2CBe&V?>(qyA--Wc&7LWvwwDq}5B3H($Gds2!D&^XMEkz@0TWzEb zB8I7BN6D(6d>cZGpq$i9o=qdJiTKG1pJ;M0xIcjwU{Zy#3j=-5wb3AA$&B#h3ZGIZ z&;kUMq}|Hy=IALSU#8;^psNn3;=t#LMN2;?uv(kqetW{il>rZc6@CHw*FfPR1?y7) O0000map response)])))}))) + +(defn install-cash-applet [] + (log/info "[keycard] install-cash-applet") + (keycard/install-cash-applet + card + {:on-success + (fn [response] + (log/info "[keycard response succ] install-cash-applet" + (js->clj response :keywordize-keys true)) + (re-frame/dispatch + [:hardwallet.callback/on-install-applet-success response])) + :on-failure + (fn [response] + (log/info "[keycard response fail] install-cash-applet" + (error-object->map response)) + (re-frame/dispatch + [:hardwallet.callback/on-install-applet-error + (error-object->map response)]))})) + +(defn sign-typed-data + [{:keys [hash] :as args}] + (log/info "[keycard] sign-typed-data" args) + (keycard/sign-typed-data + card + {:hash hash + :on-success + (fn [response] + (log/info "[keycard response succ] sign-typed-data" (js->clj response :keywordize-keys true)) + (re-frame/dispatch [:hardwallet.callback/on-sign-success + response])) + :on-failure + (fn [response] + (log/info "[keycard response fail] sign-typed-data" + (error-object->map response)) + (re-frame/dispatch + [:hardwallet.callback/on-sign-error + (error-object->map response)]))})) diff --git a/src/status_im/hardwallet/common.cljs b/src/status_im/hardwallet/common.cljs index dd1dcf893f9..9d41859853b 100644 --- a/src/status_im/hardwallet/common.cljs +++ b/src/status_im/hardwallet/common.cljs @@ -411,7 +411,7 @@ [{:keys [db] :as cofx} error] (log/debug "[hardwallet] application info error " error) (let [on-card-read (get-in db [:hardwallet :on-card-read]) - on-card-connected (get-in db [:hardwallet :on-card-conncted]) + on-card-connected (get-in db [:hardwallet :on-card-connected]) login? (= on-card-read :hardwallet/login-with-keycard) tag-was-lost? (tag-lost? (:error error))] (when-not tag-was-lost? diff --git a/src/status_im/hardwallet/fx.cljs b/src/status_im/hardwallet/fx.cljs index 4258b14e213..390a10123fb 100644 --- a/src/status_im/hardwallet/fx.cljs +++ b/src/status_im/hardwallet/fx.cljs @@ -94,6 +94,10 @@ :hardwallet/sign card/sign) +(re-frame/reg-fx + :hardwallet/sign-typed-data + card/sign-typed-data) + (re-frame/reg-fx :hardwallet/login-with-keycard status/login-with-keycard) diff --git a/src/status_im/hardwallet/keycard.cljs b/src/status_im/hardwallet/keycard.cljs index d54eccddbba..95763aa219b 100644 --- a/src/status_im/hardwallet/keycard.cljs +++ b/src/status_im/hardwallet/keycard.cljs @@ -11,6 +11,7 @@ (remove-event-listeners [this]) (get-application-info [this args]) (install-applet [this args]) + (install-cash-applet [this args]) (init-card [this args]) (install-applet-and-init-card [this args]) (pair [this args]) @@ -26,4 +27,5 @@ (export-key [this args]) (unpair-and-delete [this args]) (get-keys [this args]) - (sign [this args])) + (sign [this args]) + (sign-typed-data [this args])) diff --git a/src/status_im/hardwallet/real_keycard.cljs b/src/status_im/hardwallet/real_keycard.cljs index 2ccd367cbbb..53f09ff09c0 100644 --- a/src/status_im/hardwallet/real_keycard.cljs +++ b/src/status_im/hardwallet/real_keycard.cljs @@ -59,6 +59,12 @@ (then on-success) (catch on-failure))) +(defn install-cash-applet [{:keys [on-success on-failure]}] + (.. status-keycard + installCashApplet + (then on-success) + (catch on-failure))) + (defn init-card [{:keys [pin on-success on-failure]}] (.. status-keycard (init pin) @@ -178,6 +184,14 @@ (then on-success) (catch on-failure)))) +(defn sign-typed-data + [{:keys [hash on-success on-failure]}] + (when hash + (.. status-keycard + (signPinless hash) + (then on-success) + (catch on-failure)))) + (defrecord RealKeycard [] keycard/Keycard (keycard/check-nfc-support [this args] @@ -200,6 +214,8 @@ (get-application-info args)) (keycard/install-applet [this args] (install-applet args)) + (keycard/install-cash-applet [this args] + (install-cash-applet args)) (keycard/init-card [this args] (init-card args)) (keycard/install-applet-and-init-card [this args] @@ -231,4 +247,6 @@ (keycard/get-keys [this args] (get-keys args)) (keycard/sign [this args] - (sign args))) + (sign args)) + (keycard/sign-typed-data [this args] + (sign-typed-data args))) diff --git a/src/status_im/hardwallet/sign.cljs b/src/status_im/hardwallet/sign.cljs index d5dc8e3be57..6c7477de207 100644 --- a/src/status_im/hardwallet/sign.cljs +++ b/src/status_im/hardwallet/sign.cljs @@ -2,7 +2,10 @@ (:require [clojure.string :as string] [re-frame.core :as re-frame] [status-im.ethereum.core :as ethereum] + [status-im.ethereum.json-rpc :as json-rpc] + [status-im.hardwallet.card :as card] [status-im.utils.fx :as fx] + [status-im.utils.money :as money] [status-im.utils.types :as types] [taoensso.timbre :as log] [status-im.hardwallet.common :as common])) @@ -74,6 +77,63 @@ (common/get-application-info (common/get-pairing db) nil) (common/hide-connection-sheet))) +(def sign-typed-data-listener (atom nil)) + +(fx/defn sign-typed-data + {:events [:hardwallet/sign-typed-data]} + [{:keys [db] :as cofx}] + (let [card-connected? (get-in db [:hardwallet :card-connected?]) + hash (get-in db [:hardwallet :hash])] + (if card-connected? + (do + (when @sign-typed-data-listener + (card/remove-event-listener @sign-typed-data-listener)) + {:db (-> db + (assoc-in [:hardwallet :card-read-in-progress?] true) + (assoc-in [:signing/sign :keycard-step] :signing)) + :hardwallet/sign-typed-data {:hash (ethereum/naked-address hash)}}) + (do + (reset! sign-typed-data-listener + (card/on-card-connected #(re-frame/dispatch [:hardwallet/sign-typed-data]))) + (fx/merge cofx + (common/set-on-card-connected :hardwallet/sign-typed-data) + {:db (assoc-in db [:signing/sign :keycard-step] :signing)}))))) + +(fx/defn fetch-currency-symbol-on-success + {:events [:hardwallet/fetch-currency-symbol-on-success]} + [{:keys [db] :as cofx} currency] + {:db (assoc-in db [:signing/sign :formatted-data :message :formatted-currency] currency)}) + +(fx/defn fetch-currency-decimals-on-success + {:events [:hardwallet/fetch-currency-decimals-on-success]} + [{:keys [db] :as cofx} decimals] + {:db (update-in db [:signing/sign :formatted-data :message] + #(assoc % :formatted-amount (.dividedBy (money/bignumber (:amount %)) + (money/bignumber (money/from-decimal decimals)))))}) + +(fx/defn store-hash-and-sign-typed + {:events [:hardwallet/store-hash-and-sign-typed]} + [{:keys [db] :as cofx} result] + (let [{:keys [result error]} (types/json->clj result) + message (get-in db [:signing/sign :formatted-data :message]) + currency-contract (:currency message)] + (when-not (or (:receiver message) (:code message)) + (json-rpc/eth-call {:contract currency-contract + :method "decimals()" + :outputs ["uint8"] + :on-success (fn [[decimals]] + (re-frame/dispatch [:hardwallet/fetch-currency-decimals-on-success decimals]))}) + + (json-rpc/eth-call {:contract currency-contract + :method "symbol()" + :outputs ["string"] + :on-success (fn [[currency]] + (re-frame/dispatch [:hardwallet/fetch-currency-symbol-on-success currency]))})) + + (fx/merge cofx + {:db (assoc-in db [:hardwallet :hash] result)} + sign-typed-data))) + (fx/defn prepare-to-sign {:events [:hardwallet/prepare-to-sign]} [{:keys [db] :as cofx}] diff --git a/src/status_im/hardwallet/simulated_keycard.cljs b/src/status_im/hardwallet/simulated_keycard.cljs index 02428c60d7a..e4961f5274d 100644 --- a/src/status_im/hardwallet/simulated_keycard.cljs +++ b/src/status_im/hardwallet/simulated_keycard.cljs @@ -60,6 +60,7 @@ (later #(on-success (get @state :application-info)))) (defn install-applet [args]) +(defn install-cash-applet [args]) (def kk1-password "6d9ZHjn94kFP4bPm") @@ -121,6 +122,7 @@ (defn unpair-and-delete [args]) (defn get-keys [args]) (defn sign [args]) +(defn sign-typed-data [args]) (defrecord SimulatedKeycard [] keycard/Keycard diff --git a/src/status_im/signing/core.cljs b/src/status_im/signing/core.cljs index 8b6edad268f..cdddcf44960 100644 --- a/src/status_im/signing/core.cljs +++ b/src/status_im/signing/core.cljs @@ -10,6 +10,7 @@ [status-im.ethereum.eip55 :as eip55] [status-im.ethereum.tokens :as tokens] [status-im.i18n :as i18n] + [status-im.signing.keycard :as signing.keycard] [status-im.native-module.core :as status] [status-im.utils.fx :as fx] [status-im.hardwallet.common :as hardwallet.common] @@ -179,17 +180,26 @@ (fx/defn show-sign [{:keys [db] :as cofx}] (let [{:signing/keys [queue]} db - {{:keys [gas gasPrice] :as tx-obj} :tx-obj {:keys [data typed?] :as message} :message :as tx} (last queue) + {{:keys [gas gasPrice] :as tx-obj} :tx-obj {:keys [data typed? pinless?] :as message} :message :as tx} (last queue) keycard-multiaccount? (boolean (get-in db [:multiaccount :keycard-pairing])) wallet-set-up-passed? (get-in db [:multiaccount :wallet-set-up-passed?]) updated-db (if wallet-set-up-passed? db (assoc db :popover/popover {:view :signing-phrase}))] (if message - {:db (assoc updated-db - :signing/in-progress? true - :signing/queue (drop-last queue) - :signing/tx tx - :signing/sign {:type (if keycard-multiaccount? :keycard :password) - :formatted-data (if typed? (types/json->clj data) (ethereum/hex-to-utf8 data))})} + (fx/merge + cofx + {:db (assoc updated-db + :signing/in-progress? true + :signing/queue (drop-last queue) + :signing/tx tx + :signing/sign {:type (cond pinless? :pinless + keycard-multiaccount? :keycard + :else :password) + :formatted-data (if typed? (types/json->clj data) (ethereum/hex-to-utf8 data)) + :keycard-step (when pinless? :connect)})} + (when pinless? + (signing.keycard/hash-message {:data data + :typed? true + :on-completed #(re-frame/dispatch [:hardwallet/store-hash-and-sign-typed %])}))) (fx/merge cofx {:db (assoc updated-db @@ -295,18 +305,28 @@ (when on-error {:dispatch (conj on-error message)}))))) +(fx/defn dissoc-signing-db-entries-and-check-queue + {:events [:signing/dissoc-entries-and-check-queue]} + [{:keys [db] :as cofx}] + (fx/merge cofx + {:db (dissoc db :signing/tx :signing/in-progress? :signing/sign)} + check-queue)) + (fx/defn sign-message-completed {:events [:signing/sign-message-completed]} [{:keys [db] :as cofx} result] (let [{:keys [result error]} (types/json->clj result) on-result (get-in db [:signing/tx :on-result])] (if error - {:db (update db :signing/sign assoc - :error (if (= 5 (:code error)) (i18n/label :t/wrong-password) (:message error)) - :in-progress? false)} + {:db (-> db + (assoc-in [:signing/sign :error] (if (= 5 (:code error)) (i18n/label :t/wrong-password) (:message error))) + (assoc :signing/in-progress? false))} (fx/merge cofx - {:db (dissoc db :signing/tx :signing/in-progress? :signing/sign)} - (check-queue) + (when-not (= (-> db :signing/sign :type) :pinless) + (dissoc-signing-db-entries-and-check-queue)) + #(when (= (-> db :signing/sign :type) :pinless) + {:dispatch-later [{:ms 3000 + :dispatch [:signing/dissoc-entries-and-check-queue]}]}) #(when on-result {:dispatch (conj on-result result)}))))) @@ -314,7 +334,7 @@ {:events [:signing/transaction-completed] :interceptors [(re-frame/inject-cofx :random-id-generator)]} [cofx response tx-obj hashed-password] - (let [cofx-in-progress-false (assoc-in cofx [:db :signing/sign :in-progress?] false) + (let [cofx-in-progress-false (assoc-in cofx [:db :signing/in-progress?] false) {:keys [result error]} (types/json->clj response)] (log/debug "transaction-completed" error tx-obj) (if error diff --git a/src/status_im/signing/keycard.cljs b/src/status_im/signing/keycard.cljs index 1833b1e794e..7f3d46abb0e 100644 --- a/src/status_im/signing/keycard.cljs +++ b/src/status_im/signing/keycard.cljs @@ -79,11 +79,12 @@ {:events [:signing.ui/sign-with-keycard-pressed]} [{:keys [db] :as cofx}] (let [message (get-in db [:signing/tx :message])] - (fx/merge cofx - {:db (-> db - (assoc-in [:hardwallet :pin :enter-step] :sign) - (assoc-in [:signing/sign :keycard-step] :pin) - (assoc-in [:signing/sign :type] :keycard))} - (if message - (hash-message message) - (hash-transaction))))) + (fx/merge + cofx + {:db (-> db + (assoc-in [:hardwallet :pin :enter-step] :sign) + (assoc-in [:signing/sign :type] :keycard) + (assoc-in [:signing/sign :keycard-step] :pin))} + (if message + (hash-message message nil) + (hash-transaction))))) diff --git a/src/status_im/subs.cljs b/src/status_im/subs.cljs index 3903b8ccad8..48ca624fb0c 100644 --- a/src/status_im/subs.cljs +++ b/src/status_im/subs.cljs @@ -177,7 +177,6 @@ ;;signing (reg-root-key-sub :signing/tx :signing/tx) -(reg-root-key-sub :signing/sign :signing/sign) (reg-root-key-sub :signing/edit-fee :signing/edit-fee) ;;intro-wizard @@ -2069,6 +2068,21 @@ (fn [{:keys [signing-phrase]}] signing-phrase)) +(re-frame/reg-sub + :signing/sign + (fn [db] + (let [sign (:signing/sign db)] + (if (= :pinless (:type sign)) + (let [message (get-in sign [:formatted-data :message])] + (if (and (:amount message) (:currency message)) + (assoc sign :fiat-amount + (money/fiat-amount-value (:amount message) + (:currency message) + :USD (:prices db)) + :fiat-currency "USD") + sign)) + sign)))) + (defn- too-precise-amount? "Checks if number has any extra digit beyond the allowed number of decimals. It does so by checking the number against its rounded value." diff --git a/src/status_im/ui/screens/popover/views.cljs b/src/status_im/ui/screens/popover/views.cljs index b556c587b45..adf77ac663c 100644 --- a/src/status_im/ui/screens/popover/views.cljs +++ b/src/status_im/ui/screens/popover/views.cljs @@ -10,8 +10,9 @@ [status-im.ui.screens.profile.user.views :as profile.user] [status-im.ui.screens.multiaccounts.recover.views :as multiaccounts.recover] [status-im.react-native.js-dependencies :as js-dependencies] - [status-im.ui.screens.biometric.views :as biometric] - [status-im.ui.components.colors :as colors])) + [status-im.ui.components.colors :as colors] + [status-im.ui.screens.signing.views :as signing] + [status-im.ui.screens.biometric.views :as biometric])) (defn hide-panel-anim [bottom-anim-value alpha-value window-height] @@ -133,6 +134,9 @@ (= :disable-password-saving view) [biometric/disable-password-saving-popover] + (= :transaction-data view) + [signing/transaction-data] + :else [view])]]]]])))}))) diff --git a/src/status_im/ui/screens/signing/styles.cljs b/src/status_im/ui/screens/signing/styles.cljs index b2521280100..f96077a5777 100644 --- a/src/status_im/ui/screens/signing/styles.cljs +++ b/src/status_im/ui/screens/signing/styles.cljs @@ -58,3 +58,22 @@ :color (if disabled? colors/black colors/white) :padding-horizontal 16 :padding-vertical 10}) + +(defn sheet-title [small-screen?] + {:font-weight "500" + :font-size (if small-screen? 16 19) + :margin-top 16}) + +(defn sheet-subtitle [small-screen?] + {:font-size (if small-screen? 16 19) + :text-align :center + :margin-bottom 12 + :color colors/gray}) + +(defn sheet-icon [bg-color] + {:height 64 + :width 64 + :border-radius 32 + :justify-content :center + :align-items :center + :background-color bg-color}) diff --git a/src/status_im/ui/screens/signing/views.cljs b/src/status_im/ui/screens/signing/views.cljs index d2fff83f2bc..d90bf1d09c1 100644 --- a/src/status_im/ui/screens/signing/views.cljs +++ b/src/status_im/ui/screens/signing/views.cljs @@ -133,6 +133,105 @@ [react/view {:align-items :center :margin-top 16 :margin-bottom 40} [sign-with-keycard-button nil nil]])]) +(defn signature-request [{:keys [error formatted-data + fiat-amount fiat-currency + keycard-step + in-progress? enabled?] :as sign} small-screen?] + (let [message (:message formatted-data) + title (case keycard-step + :connect :t/looking-for-cards + :signing :t/processing + :error :t/lost-connection + :success :t/success) + subtitle (case keycard-step + :connect :t/hold-card + :signing :t/try-keeping-the-card-still + :error :t/tap-card-again + :success :t/transaction-signed)] + [react/view (assoc styles/message :padding-vertical 16 :align-items :center) + [react/view {:style {:align-self :flex-start :padding-left 16 :margin-bottom 24}} + [react/text {:style {:font-size (if small-screen? 15 17) :font-weight "700"}} + (i18n/label :t/confirmation-request)]] + (when (and (:formatted-amount message) (:formatted-currency message)) + [react/view {:style {:margin-bottom 24 :align-self :stretch}} + [react/nested-text {:style {:font-weight "500" :font-size (if small-screen? 34 44) + :text-align :center}} + (str (:formatted-amount message) " ") + [{:style {:color colors/gray}} (:formatted-currency message)]] + [react/text {:style {:font-size 19 :text-align :center + :margin-bottom 16}} + (str fiat-amount " " fiat-currency)] + [separator]]) + [react/view {:style (styles/sheet-icon (case keycard-step + (:connect :signing) colors/blue-transparent-10 + :error colors/red-transparent-10 + :success colors/green-transparent-10))} + (case keycard-step + :connect + [icons/icon :main-icons/nfc {:color colors/blue :width 27 :height 21}] + :signing + [react/activity-indicator {:animating true :color colors/blue}] + :error + [icons/icon :main-icons/close {:color colors/red}] + :success + [icons/icon :main-icons/check {:color colors/green}])] + [react/text {:style (styles/sheet-title small-screen?)} (i18n/label title)] + [react/text {:style (styles/sheet-subtitle small-screen?)} (i18n/label subtitle)] + [button/button {:type :main + :disabled? (= keycard-step :success) + :text-style {:font-size (if small-screen? 18 20)} + :style {:align-self :stretch} + :container-style {:height (if small-screen? 52 64)} + :label (i18n/label :t/show-transaction-data) + :on-press #(re-frame/dispatch [:show-popover {:view :transaction-data}])}] + [button/button {:type :main + :theme :red + :disabled? (= keycard-step :success) + :container-style {:margin-top 8 + :height 64 :margin-bottom 16} + :style {:align-self :stretch} + :text-style {:font-size 20} + :label (i18n/label :t/decline) + :on-press #(re-frame/dispatch [:signing.ui/cancel-is-pressed])}]])) + +(defn- transaction-data-item [{:keys [label data]}] + [react/view + [react/text {:style {:font-size 17 + :line-height 20 + :margin-bottom 8 + :color colors/gray}} + label] + [react/text {:style {:font-size 17 + :line-height 20 + :margin-bottom 24}} + data]]) + +(views/defview transaction-data [] + (views/letsubs + [{:keys [formatted-data]} [:signing/sign]] + [react/view {:style {:flex 1}} + [react/view {:style {:margin-horizontal 24 + :margin-top 24}} + [react/text {:style {:font-size 17 + :font-weight "700"}} + (i18n/label :t/transaction-data)]] + [react/scroll-view {:style {:flex 1 + :margin-horizontal 8 + :padding-horizontal 16 + :padding-vertical 10 + :margin-vertical 14}} + [transaction-data-item {:label "Label" + :data formatted-data}]] + [separator] + [react/view {:style {:margin-horizontal 8 + :margin-vertical 16}} + [button/button {:type :main + :text-style {:font-size 20} + :style {:margin-horizontal 0} + :container-style {:height 64} + :label (i18n/label :t/close) + :on-press #(re-frame/dispatch [:hide-popover])}]]])) + (views/defview password-view [{:keys [type error in-progress? enabled?] :as sign}] (views/letsubs [phrase [:signing/phrase]] (case type @@ -160,19 +259,22 @@ [react/view]))) (views/defview message-sheet [] - (views/letsubs [{:keys [formatted-data type] :as sign} [:signing/sign]] - [react/view styles/message - [react/view styles/message-header - [react/text {:style {:typography :title-bold}} (i18n/label :t/signing-a-message)] - [react/touchable-highlight {:on-press #(re-frame/dispatch [:signing.ui/cancel-is-pressed])} - [react/view {:padding 6} - [react/text {:style {:color colors/blue}} (i18n/label :t/cancel)]]]] - [separator] - [react/view {:padding-top 16 :flex 1} - [react/view styles/message-border - [react/scroll-view - [react/text (or formatted-data "")]]] - [password-view sign]]])) + (views/letsubs [{:keys [formatted-data type] :as sign} [:signing/sign] + small-screen? [:dimensions/small-screen?]] + (if (= type :pinless) + [signature-request sign small-screen?] + [react/view styles/message + [react/view styles/message-header + [react/text {:style {:typography :title-bold}} (i18n/label :t/signing-a-message)] + [react/touchable-highlight {:on-press #(re-frame/dispatch [:signing.ui/cancel-is-pressed])} + [react/view {:padding 6} + [react/text {:style {:color colors/blue}} (i18n/label :t/cancel)]]]] + [separator] + [react/view {:padding-top 16 :flex 1} + [react/view styles/message-border + [react/scroll-view + [react/text (or formatted-data "")]]] + [password-view sign]]]))) (defn amount-item [prices wallet-currency amount amount-error display-symbol fee-display-symbol prices-loading?] (let [converted-value (* amount (get-in prices [(keyword display-symbol) (keyword (:code wallet-currency)) :price]))] diff --git a/translations/en.json b/translations/en.json index be89ca681b9..7bbacaffe03 100644 --- a/translations/en.json +++ b/translations/en.json @@ -135,6 +135,7 @@ "clear-history-confirmation": "Clear history?", "clear-history-confirmation-content": "Are you sure you want to clear this chat history?", "clear-history-title": "Clear history?", + "close": "Close", "close-app-button": "Confirm", "close-app-content": "The app will stop and close. When you reopen it, the selected network will be used", "close-app-title": "Warning!", @@ -142,6 +143,7 @@ "complete-hardwallet-setup": "This card is now an essential part your multiaccount security. Transactions can't be sent without it.", "completed": "Completed", "confirm": "Confirm", + "confirmation-request": "Confirmation request", "confirmations": "Confirmations", "confirmations-helper-text": "When the transaction has 12 confirmations you can consider it settled.", "connect": "Connect", @@ -593,6 +595,8 @@ "logout-app-content": "The account will be logged out. When you unlock it again, the selected network will be used", "logout-are-you-sure": "Are you sure you want\nto log out?", "logout-title": "Log out?", + "looking-for-cards": "Looking for cards...", + "lost-connection": "Lost connection", "mailserver-address": "Mailserver address", "mailserver-automatic": "Automatic selection", "mailserver-connection-error": "Could not connect to mailserver", @@ -875,6 +879,7 @@ "show-less": "Show less", "show-more": "Show more", "show-qr": "Show QR code", + "show-transaction-data": "Show transaction data", "sign-and-send": "Sign and send", "sign-in": "Unlock", "sign-message": "Sign Message", @@ -916,6 +921,7 @@ "sync-synced": "In sync", "syncing-devices": "Syncing...", "tag-was-lost": "Tag was lost", + "tap-card-again": "Tap the card to the back of your phone again", "test-networks": "Test networks", "text-input-disabled": "Please wait a moment...", "this-device": "This device", @@ -934,6 +940,7 @@ "token-details": "Token details", "topic-name-error": "Use only lowercase letters (a to z), numbers & dashes (-). Do not use chat keys", "transaction": "Transaction", + "transaction-data": "Transaction data", "transaction-declined": "Transaction declined", "transaction-description": "Consider it complete after 12 confirmations on the network.", "transaction-details": "Transaction details", @@ -941,6 +948,7 @@ "transaction-history": "Transaction history", "transaction-request": "Transaction Request", "transaction-sent": "Transaction sent", + "transaction-signed": "The transaction has been successfully signed", "transactions": "Transactions", "transactions-filter-select-all": "Select all", "transactions-filter-title": "Filter history", @@ -978,6 +986,7 @@ "tribute-to-talk-tribute-received2": " are now contacts and can securely chat with each other.", "tribute-to-talk-you-require-snt": "You require SNT for new people to start a chat.", "try-again": "Try again", + "try-keeping-the-card-still": "Try keeping the card still", "turn-nfc-on": "Turn NFC on to continue", "turn-nfc-description": "NFC is disabled on yor device. You can enable it in settings", "keycard-init-title": "Looking for cards...",