Skip to content

Commit

Permalink
[#20035] feat: import missing key pair by scanning QR code
Browse files Browse the repository at this point in the history
  • Loading branch information
mohsen-ghafouri committed May 22, 2024
1 parent 9de8613 commit 6932af2
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,16 @@ class NetworkManager(private val reactContext: ReactApplicationContext) : ReactC
callback)
}

@ReactMethod
fun inputConnectionStringForImportingKeypairsKeystores(connectionString: String, configJSON: String, callback: Callback) {
val jsonConfig = JSONObject(configJSON)
val receiverConfig = jsonConfig.getJSONObject("receiverConfig")
val keyStorePath = utils.pathCombine(utils.getNoBackupDirectory(), "/keystore")
receiverConfig.put("keystorePath", keyStorePath)

utils.executeRunnableStatusGoMethod(
{ Statusgo.inputConnectionStringForImportingKeypairsKeystores(connectionString, jsonConfig.toString()) },
callback
)
}
}
19 changes: 19 additions & 0 deletions modules/react-native-status/ios/RCTStatus/NetworkManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,23 @@ @implementation NetworkManager
callback(@[result]);
}

RCT_EXPORT_METHOD(inputConnectionStringForImportingKeypairsKeystores:(NSString *)cs
configJSON:(NSString *)configJSON
callback:(RCTResponseSenderBlock)callback) {

NSData *configData = [configJSON dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSMutableDictionary *configDict = [NSJSONSerialization JSONObjectWithData:configData options:NSJSONReadingMutableContainers error:&error];
NSMutableDictionary *receiverConfig = configDict[@"receiverConfig"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *rootUrl =[[fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *multiaccountKeystoreDir = [rootUrl URLByAppendingPathComponent:@"keystore"];
NSString *keystoreDir = multiaccountKeystoreDir.path;

[receiverConfig setValue:keystoreDir forKey:@"keystorePath"];
NSString *modifiedConfigJSON = [Utils jsonStringWithPrettyPrint:NO fromDictionary:configDict];
NSString *result = StatusgoInputConnectionStringForImportingKeypairsKeystores(cs, modifiedConfigJSON);
callback(@[result]);
}

@end
12 changes: 12 additions & 0 deletions src/native_module/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -609,3 +609,15 @@
{:fn :get-connection-string-for-exporting-keypairs-keystores
:config-json config-json})
(.getConnectionStringForExportingKeypairsKeystores ^js (network) config-json callback))

(defn input-connection-string-for-importing-keypairs-keystores
"Provides connection string to status-go for the purpose of importing keypairs and keystores on the receiver side"
[connection-string config-json callback]
(log/info "[native-module] Sending Import Keypairs Connection String"
{:fn :input-connection-string-for-importing-keypairs-keystores
:config-json config-json
:connection-string connection-string})
(.inputConnectionStringForImportingKeypairsKeystores ^js (network)
connection-string
config-json
callback))
8 changes: 7 additions & 1 deletion src/quo/components/wallet/missing_keypairs/style.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@
{:top 1})

(def title-info-container
{:padding-left 8})
{:padding-left 8
:flex 1})

(def title-row
{:display :flex
:flex-direction :row
:justify-content :space-between})

(def title-container
{:align-items :flex-start
Expand Down
25 changes: 19 additions & 6 deletions src/quo/components/wallet/missing_keypairs/view.cljs
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
(ns quo.components.wallet.missing-keypairs.view
(:require
[quo.components.buttons.button.view :as button]
[quo.components.icon :as icon]
[quo.components.list-items.missing-keypair.view :as missing-keypair]
[quo.components.markdown.text :as text]
[quo.components.wallet.missing-keypairs.style :as style]
[quo.foundations.colors :as colors]
[quo.theme]
[react-native.core :as rn]
[utils.i18n :as i18n]))
[utils.i18n :as i18n]
[utils.re-frame :as rf]))

(defn open-import-scan
[]
(rf/dispatch [:open-modal :screen/settings.scan-key-pair-qr]))

(defn title-view
[{:keys [keypairs blur?]}]
Expand All @@ -22,11 +28,18 @@
:color colors/warning-60}]]
[rn/view
{:style style/title-info-container}
[text/text
{:weight :medium
:style {:color colors/warning-60}}
(i18n/label :t/amount-missing-keypairs
{:amount (str (count keypairs))})]
[rn/view {:style style/title-row}
[text/text
{:weight :medium
:style {:color colors/warning-60}}
(i18n/label :t/amount-missing-keypairs
{:amount (str (count keypairs))})]
[button/button
{:type :outline
:background :blur
:size 24
:on-press open-import-scan}
(i18n/label :t/import)]]
[text/text
{:size :paragraph-2
:style (style/subtitle blur? theme)}
Expand Down
31 changes: 31 additions & 0 deletions src/status_im/contexts/settings/wallet/events.cljs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
(ns status-im.contexts.settings.wallet.events
(:require
[native-module.core :as native-module]
[status-im.contexts.syncing.events :as syncing-events]
[status-im.contexts.syncing.utils :as sync-utils]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
Expand Down Expand Up @@ -53,3 +54,33 @@
handle-connection)))

(rf/reg-event-fx :wallet/get-key-pair-export-connection get-key-pair-export-connection)


(defn- input-connection-string-callback
[res]
(log/info "[local-pairing] input-connection-string-for-bootstrapping callback"
{:response res
:event :syncing/input-connection-string-for-bootstrapping})
(let [error (when (syncing-events/extract-error res)
(str "generic-error: " res))]
(when (some? error)
(rf/dispatch [:toasts/upsert
{:type :negative
:text error}]))))

(defn connection-string-for-key-pair-import
[{:keys [db]} [connection-string]]
(let [key-uid (get-in db [:profile/profile :key-uid])
config-map (.stringify js/JSON
(clj->js
{:receiverConfig
{:loggedInKeyUid key-uid
:keystorePath ""
:password ""
:keypairsToImport []}}))]
(native-module/input-connection-string-for-importing-keypairs-keystores
connection-string
config-map
input-connection-string-callback)))

(rf/reg-event-fx :wallet/connection-string-for-key-pair-import connection-string-for-key-pair-import)
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.scan-qr.view
(:require
[status-im.common.scan-qr-code.view :as scan-qr-code]
[status-im.contexts.communities.events]
[status-im.contexts.syncing.utils :as sync-utils]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))

(def invalid-qr-toast
{:type :negative
:theme :dark
:text (i18n/label :t/invalid-qr)})

(defn show-invalid-qr-toast
[]
(debounce/debounce-and-dispatch
[:toasts/upsert invalid-qr-toast]
300))

(defn on-qr-code-scanned
[scanned-text]
(if (sync-utils/valid-connection-string? scanned-text)
(rf/dispatch [:wallet/connection-string-for-key-pair-import scanned-text])
(show-invalid-qr-toast)))

(defn view
[]
[scan-qr-code/view
{:title (i18n/label :t/scan-key-pairs-qr-code)
:subtitle (i18n/label :t/find-it-in-setting)
:share-button? false
:on-success-scan on-qr-code-scanned}])
2 changes: 1 addition & 1 deletion src/status_im/contexts/syncing/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
:VerifyTransactionChainID config/verify-transaction-chain-id}}
log-config)))

(defn- extract-error
(defn extract-error
[json-str]
(-> json-str
transforms/json->clj
Expand Down
5 changes: 5 additions & 0 deletions src/status_im/navigation/screens.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
[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.scan-qr.view :as scan-key-pair-qr]
[status-im.contexts.settings.wallet.keypairs-and-accounts.view :as keypairs-and-accounts]
[status-im.contexts.settings.wallet.network-settings.view :as network-settings]
[status-im.contexts.settings.wallet.saved-addresses.view :as saved-addresses-settings]
Expand Down Expand Up @@ -523,6 +524,10 @@
:options options/transparent-modal-screen-options
:component keypairs-and-accounts/view}

{:name :screen/settings.scan-key-pair-qr
:options options/transparent-modal-screen-options
:component scan-key-pair-qr/view}

{:name :screen/settings.network-settings
:options options/transparent-modal-screen-options
:component network-settings/view}
Expand Down
2 changes: 2 additions & 0 deletions translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1289,6 +1289,7 @@
"scan-qr": "Scan QR",
"scan-qr-code": "Scan QR code",
"scan-with-status-app": "Scan with the Status app on another device",
"scan-key-pairs-qr-code": "Scan key pairs QR code",
"invalid-qr": "Oops! This QR doesn’t work with Status",
"search": "Search",
"search-discover-communities": "Search communities or categories",
Expand Down Expand Up @@ -2206,6 +2207,7 @@
"create-new-profile": "Create new profile",
"add-existing-status-profile": "Add existing Status profile",
"find-sync-code": "Find sync code",
"find-it-in-setting": "Find it in Settings on your other synced device",
"sign-in-by-syncing": "Sign in by syncing",
"synchronise-your-data-across-your-devices": "Synchronise your data across your devices",
"scan-sync-qr-code": "Scan QR code",
Expand Down

0 comments on commit 6932af2

Please sign in to comment.