parent
4cdbfb6cc6
commit
389a730eff
|
@ -75,4 +75,17 @@ class NetworkManager(private val reactContext: ReactApplicationContext) : ReactC
|
|||
utils.executeRunnableStatusGoMethod({ Statusgo.recover(rpcParams) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun getConnectionStringForExportingKeypairsKeystores(configJSON: String, callback: Callback) {
|
||||
val jsonConfig = JSONObject(configJSON)
|
||||
val senderConfig = jsonConfig.getJSONObject("senderConfig")
|
||||
val keyUID = senderConfig.getString("loggedInKeyUid")
|
||||
val keyStorePath = utils.getKeyStorePath(keyUID)
|
||||
senderConfig.put("keystorePath", keyStorePath)
|
||||
|
||||
utils.executeRunnableStatusGoMethod(
|
||||
{ Statusgo.getConnectionStringForExportingKeypairsKeystores(jsonConfig.toString()) },
|
||||
callback)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -106,4 +106,22 @@ RCT_EXPORT_METHOD(recover:(NSString *)message
|
|||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getConnectionStringForExportingKeypairsKeystores:(NSString *)configJSON
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
|
||||
NSData *configData = [configJSON dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSError *error;
|
||||
NSMutableDictionary *configDict = [NSJSONSerialization JSONObjectWithData:configData options:NSJSONReadingMutableContainers error:&error];
|
||||
NSMutableDictionary *senderConfig = configDict[@"senderConfig"];
|
||||
NSString *keyUID = senderConfig[@"loggedInKeyUid"];
|
||||
NSURL *multiaccountKeystoreDir = [Utils getKeyStoreDirForKeyUID:keyUID];
|
||||
NSString *keystoreDir = multiaccountKeystoreDir.path;
|
||||
|
||||
[senderConfig setValue:keystoreDir forKey:@"keystorePath"];
|
||||
NSString *modifiedConfigJSON = [Utils jsonStringWithPrettyPrint:NO fromDictionary:configDict];
|
||||
|
||||
NSString *result = StatusgoGetConnectionStringForExportingKeypairsKeystores(modifiedConfigJSON);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -601,3 +601,11 @@
|
|||
(.createAccountFromMnemonicAndDeriveAccountsForPaths ^js (account-manager)
|
||||
(types/clj->json mnemonic)
|
||||
#(callback (types/json->clj %))))
|
||||
|
||||
(defn get-connection-string-for-exporting-keypairs-keystores
|
||||
"Generates connection string form status-go for the purpose of exporting keypairs and keystores on sender side"
|
||||
[config-json callback]
|
||||
(log/info "[native-module] Fetching Export Keypairs Connection String"
|
||||
{:fn :get-connection-string-for-exporting-keypairs-keystores
|
||||
:config-json config-json})
|
||||
(.getConnectionStringForExportingKeypairsKeystores ^js (network) config-json callback))
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
(ns status-im.contexts.settings.wallet.events
|
||||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[status-im.contexts.syncing.utils :as sync-utils]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/rename-keypair-success
|
||||
|
@ -30,3 +34,22 @@
|
|||
:on-error #(log/info "failed to rename keypair " %)}]]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/rename-keypair rename-keypair)
|
||||
|
||||
(defn get-key-pair-export-connection
|
||||
[{:keys [db]} [{:keys [sha3-pwd keypair-key-uid callback]}]]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])
|
||||
config-map (transforms/clj->json {:senderConfig {:loggedInKeyUid key-uid
|
||||
:keystorePath ""
|
||||
:keypairsToExport [keypair-key-uid]
|
||||
:password (security/safe-unmask-data
|
||||
sha3-pwd)}
|
||||
:serverConfig {:timeout 0}})
|
||||
handle-connection (fn [response]
|
||||
(when (sync-utils/valid-connection-string? response)
|
||||
(callback response)
|
||||
(rf/dispatch [:hide-bottom-sheet])))]
|
||||
(native-module/get-connection-string-for-exporting-keypairs-keystores
|
||||
config-map
|
||||
handle-connection)))
|
||||
|
||||
(rf/reg-event-fx :wallet/get-key-pair-export-connection get-key-pair-export-connection)
|
||||
|
|
|
@ -7,13 +7,23 @@
|
|||
[data]
|
||||
(rf/dispatch [:open-modal :screen/settings.rename-keypair data]))
|
||||
|
||||
(defn on-show-qr
|
||||
[data]
|
||||
(rf/dispatch [:open-modal :screen/settings.encrypted-key-pair-qr data]))
|
||||
|
||||
(defn view
|
||||
[props data]
|
||||
(let [has-paired-device (rf/sub [:pairing/has-paired-devices])]
|
||||
[:<>
|
||||
[quo/drawer-top props]
|
||||
[quo/action-drawer
|
||||
[(when (= (:type props) :keypair)
|
||||
[(when has-paired-device
|
||||
[{:icon :i/qr-code
|
||||
:accessibility-label :show-key-pr-qr
|
||||
:label (i18n/label :t/show-encrypted-qr-of-key-pairs)
|
||||
:on-press #(on-show-qr data)}])
|
||||
(when (= (:type props) :keypair)
|
||||
[{:icon :i/edit
|
||||
:accessibility-label :rename-key-pair
|
||||
:label (i18n/label :t/rename-key-pair)
|
||||
:on-press #(on-rename-request data)}])]]])
|
||||
:on-press #(on-rename-request data)}])]]]))
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.countdown.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.hooks :as hooks]
|
||||
[utils.datetime :as datetime]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(def code-valid-for-ms 120000)
|
||||
(def one-min-ms 60000)
|
||||
|
||||
(defn current-ms
|
||||
[]
|
||||
(* 1000 (js/Math.ceil (/ (datetime/timestamp) 1000))))
|
||||
|
||||
(defn view
|
||||
[on-clear]
|
||||
(let [[valid-for-ms set-valid-for-ms] (rn/use-state code-valid-for-ms)
|
||||
[timestamp set-timestamp] (rn/use-state current-ms)
|
||||
clock (rn/use-callback (fn []
|
||||
(let [remaining (- code-valid-for-ms
|
||||
(- (current-ms)
|
||||
timestamp))]
|
||||
(when (pos? remaining)
|
||||
(set-valid-for-ms remaining))
|
||||
(when (zero? remaining)
|
||||
(set-timestamp (current-ms))
|
||||
(set-valid-for-ms code-valid-for-ms)
|
||||
(on-clear))))
|
||||
[code-valid-for-ms])]
|
||||
(hooks/use-interval clock on-clear 1000)
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style {:color (if (< valid-for-ms one-min-ms)
|
||||
colors/danger-60
|
||||
colors/white-opa-40)}}
|
||||
(i18n/label :t/valid-for-time {:valid-for (datetime/ms-to-duration valid-for-ms)})]))
|
|
@ -0,0 +1,46 @@
|
|||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.safe-area :as safe-area]))
|
||||
|
||||
(defn container-main
|
||||
[]
|
||||
{:background-color colors/neutral-95
|
||||
:padding-top (safe-area/get-top)
|
||||
:flex 1})
|
||||
|
||||
(def page-container
|
||||
{:margin-top 14
|
||||
:margin-horizontal 20})
|
||||
|
||||
(def title-container
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :space-between})
|
||||
|
||||
(def standard-auth
|
||||
{:margin-top 12
|
||||
:flex 1})
|
||||
|
||||
(def qr-container
|
||||
{:margin-top 12
|
||||
:background-color colors/white-opa-5
|
||||
:border-radius 20
|
||||
:flex 1
|
||||
:padding 12})
|
||||
|
||||
(def sub-text-container
|
||||
{:margin-bottom 8
|
||||
:justify-content :space-between
|
||||
:align-items :center
|
||||
:flex-direction :row})
|
||||
|
||||
(def valid-cs-container
|
||||
{:flex 1
|
||||
:margin 12})
|
||||
|
||||
(def warning-text
|
||||
{:margin-horizontal 16
|
||||
:margin-top 20
|
||||
:text-align :center
|
||||
:color colors/white-opa-70})
|
|
@ -0,0 +1,98 @@
|
|||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.clipboard :as clipboard]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.qr-codes.view :as qr-codes]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.common.standard-authentication.core :as standard-auth]
|
||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.countdown.view :as countdown]
|
||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.style :as style]
|
||||
[status-im.contexts.syncing.utils :as sync-utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn navigate-back [] (rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{:keys [key-uid]} (rf/sub [:get-screen-params])
|
||||
{:keys [customization-color]} (rf/sub [:profile/profile-with-image])
|
||||
[code set-code] (rn/use-state nil)
|
||||
valid-connection-string? (rn/use-memo #(sync-utils/valid-connection-string? code) [code])
|
||||
validate-and-set-code (rn/use-callback (fn [connection-string]
|
||||
(when (sync-utils/valid-connection-string?
|
||||
connection-string)
|
||||
(set-code connection-string))))
|
||||
cleanup-clock (rn/use-callback #(set-code nil))
|
||||
on-auth-success (rn/use-callback (fn [entered-password]
|
||||
(rf/dispatch
|
||||
[:wallet/get-key-pair-export-connection
|
||||
{:sha3-pwd entered-password
|
||||
:keypair-key-uid key-uid
|
||||
:callback validate-and-set-code}]))
|
||||
[key-uid])]
|
||||
[rn/view {:style (style/container-main)}
|
||||
[rn/scroll-view
|
||||
[quo/page-nav
|
||||
{:type :no-title
|
||||
:icon-name :i/close
|
||||
:background :blur
|
||||
:on-press navigate-back}]
|
||||
[rn/view {:style style/page-container}
|
||||
[rn/view {:style style/title-container}
|
||||
[quo/text
|
||||
{:size :heading-1
|
||||
:weight :semi-bold
|
||||
:style {:color colors/white}}
|
||||
(i18n/label :t/encrypted-key-pairs)]]
|
||||
[rn/view {:style style/qr-container}
|
||||
(if valid-connection-string?
|
||||
[qr-codes/qr-code {:url code}]
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
[rn/image
|
||||
{:source (resources/get-image :qr-code)
|
||||
:style {:width "100%"
|
||||
:background-color colors/white-opa-70
|
||||
:border-radius 12
|
||||
:aspect-ratio 1}}]])
|
||||
(when valid-connection-string?
|
||||
[rn/view {:style style/valid-cs-container}
|
||||
[rn/view {:style style/sub-text-container}
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style {:color colors/white-opa-40}}
|
||||
(i18n/label :t/encrypted-key-pairs-code)]
|
||||
[countdown/view cleanup-clock]]
|
||||
[quo/input
|
||||
{:default-value code
|
||||
:type :password
|
||||
:default-shown? true
|
||||
:editable false}]
|
||||
[quo/button
|
||||
{:on-press (fn []
|
||||
(clipboard/set-string code)
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:text (i18n/label
|
||||
:t/sharing-copied-to-clipboard)}]))
|
||||
:type :grey
|
||||
:container-style {:margin-top 12}
|
||||
:icon-left :i/copy}
|
||||
(i18n/label :t/copy-qr)]])
|
||||
(when-not valid-connection-string?
|
||||
[rn/view {:style style/standard-auth}
|
||||
[standard-auth/slide-button
|
||||
{:blur? true
|
||||
:size :size-40
|
||||
:track-text (i18n/label :t/slide-to-reveal-qr-code)
|
||||
:customization-color customization-color
|
||||
:on-auth-success on-auth-success
|
||||
:auth-button-label (i18n/label :t/reveal-qr-code)
|
||||
:auth-button-icon-left :i/reveal}]])]]
|
||||
(when-not valid-connection-string?
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/warning-text}
|
||||
(i18n/label :t/make-sure-no-camera-warning)])]]))
|
|
@ -57,6 +57,8 @@
|
|||
[status-im.contexts.profile.settings.screens.password.change-password.view :as change-password]
|
||||
[status-im.contexts.profile.settings.screens.password.view :as settings-password]
|
||||
[status-im.contexts.profile.settings.view :as settings]
|
||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.view :as
|
||||
encrypted-key-pair-qr]
|
||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.rename.view :as keypair-rename]
|
||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.view :as keypairs-and-accounts]
|
||||
[status-im.contexts.settings.wallet.network-settings.view :as network-settings]
|
||||
|
@ -509,6 +511,10 @@
|
|||
:options (assoc options/dark-screen :sheet? true)
|
||||
:component keypair-rename/view}
|
||||
|
||||
{:name :screen/settings.encrypted-key-pair-qr
|
||||
:options options/transparent-screen-options
|
||||
:component encrypted-key-pair-qr/view}
|
||||
|
||||
{:name :screen/settings.saved-addresses
|
||||
:options options/transparent-modal-screen-options
|
||||
:component saved-addresses-settings/view}
|
||||
|
|
|
@ -28,3 +28,9 @@
|
|||
:<- [:syncing]
|
||||
(fn [syncing]
|
||||
(:pairing-status syncing)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:pairing/has-paired-devices
|
||||
:<- [:pairing/enabled-installations]
|
||||
(fn [installations]
|
||||
(> (count installations) 1)))
|
||||
|
|
|
@ -524,6 +524,8 @@
|
|||
"enable": "Enable",
|
||||
"enable-notifications-sub-title": "Receive notifications about your new messages or wallet transactions",
|
||||
"encrypt-with-password": "Encrypt with password",
|
||||
"encrypted-key-pairs": "Encrypted key pairs",
|
||||
"encrypted-key-pairs-code": "Encrypted key pairs code",
|
||||
"ending-not-allowed": "{{ending}} ending is not allowed",
|
||||
"ends-with-space": "Cannot end with space",
|
||||
"ens-10-SNT": "10 SNT",
|
||||
|
@ -939,6 +941,7 @@
|
|||
"main-wallet": "Main Wallet",
|
||||
"make-admin": "Make admin",
|
||||
"make-moderator": "Make moderator",
|
||||
"make-sure-no-camera-warning": "Make sure no camera or person can see this screen before revealing",
|
||||
"manage-keys-and-storage": "Manage keys and storage",
|
||||
"mark-as-read": "Mark as read",
|
||||
"mark-all-read": "Mark all read",
|
||||
|
@ -1272,6 +1275,7 @@
|
|||
"reset-card-description": "This operation will reset card to initial state. It will erase all card data including private keys. Operation is not reversible.",
|
||||
"retry": "Retry",
|
||||
"reveal-sync-code": "Reveal sync code",
|
||||
"reveal-qr-code": "Reveal QR code",
|
||||
"revoke-access": "Revoke access",
|
||||
"save": "Save",
|
||||
"save-address": "Save address",
|
||||
|
@ -1337,6 +1341,7 @@
|
|||
"show-more": "Show more",
|
||||
"show-qr": "Show QR code",
|
||||
"show-transaction-data": "Show transaction data",
|
||||
"show-encrypted-qr-of-key-pairs": "Show encrypted QR of key pairs on device",
|
||||
"sign-and-send": "Sign and send",
|
||||
"sign-in": "Sign in",
|
||||
"sign-message": "Sign Message",
|
||||
|
@ -1970,6 +1975,7 @@
|
|||
"slide-to-request-to-join": "Slide to request to join",
|
||||
"slide-to-reveal-code": "Slide to reveal code",
|
||||
"slide-to-create-account": "Slide to create account",
|
||||
"slide-to-reveal-qr-code": "Slide to reveal QR code",
|
||||
"minimum-received": "Minimum received",
|
||||
"powered-by-paraswap": "Powered by Paraswap",
|
||||
"priority": "Priority",
|
||||
|
|
Loading…
Reference in New Issue