[#10195] Separate keystore dir per multiacc

Having all keys related to specific multiacc in a separate dir will
simplify removing of the multiacc. Also it will allow adding of the same
account to different multiaccs.
This commit is contained in:
Roman Volosovskyi 2020-07-09 13:14:38 +03:00
parent e738cd0811
commit 920bc7d93e
No known key found for this signature in database
GPG Key ID: 0238A4B5ECEE70DE
14 changed files with 235 additions and 123 deletions

View File

@ -246,7 +246,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
return file.getAbsolutePath();
}
private String prepareDirAndUpdateConfig(final String jsonConfigString) {
private String prepareDirAndUpdateConfig(final String jsonConfigString, final String keyUID) {
Activity currentActivity = getCurrentActivity();
@ -303,7 +303,8 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
try {
final String updatedJsonConfigString = this.updateConfig(jsonConfigString, absRootDirPath, "/keystore");
final String multiaccountKeystoreDir = pathCombine("/keystore", keyUID);
final String updatedJsonConfigString = this.updateConfig(jsonConfigString, absRootDirPath, multiaccountKeystoreDir);
prettyPrintConfig(updatedJsonConfigString);
@ -317,41 +318,55 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
@ReactMethod
public void prepareDirAndUpdateConfig(final String config, final Callback callback) {
public void prepareDirAndUpdateConfig(final String keyUID, final String config, final Callback callback) {
Log.d(TAG, "prepareDirAndUpdateConfig");
String finalConfig = prepareDirAndUpdateConfig(config);
String finalConfig = prepareDirAndUpdateConfig(config, keyUID);
callback.invoke(finalConfig);
}
@ReactMethod
public void saveAccountAndLogin(final String multiaccountData, final String password, final String settings, final String config, final String accountsData) {
Log.d(TAG, "saveAccountAndLogin");
String finalConfig = prepareDirAndUpdateConfig(config);
String result = Statusgo.saveAccountAndLogin(multiaccountData, password, settings, finalConfig, accountsData);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "saveAccountAndLogin result: " + result);
Log.d(TAG, "Geth node started");
} else {
Log.e(TAG, "saveAccountAndLogin failed: " + result);
try {
Log.d(TAG, "saveAccountAndLogin");
String finalConfig = prepareDirAndUpdateConfig(config, this.getKeyUID(multiaccountData));
String result = Statusgo.saveAccountAndLogin(multiaccountData, password, settings, finalConfig, accountsData);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "saveAccountAndLogin result: " + result);
Log.d(TAG, "Geth node started");
} else {
Log.e(TAG, "saveAccountAndLogin failed: " + result);
}
} catch (JSONException e) {
Log.e(TAG, "JSON conversion failed: " + e.getMessage());
}
}
@ReactMethod
public void saveAccountAndLoginWithKeycard(final String multiaccountData, final String password, final String settings, final String config, final String accountsData, final String chatKey) {
Log.d(TAG, "saveAccountAndLoginWithKeycard");
String finalConfig = prepareDirAndUpdateConfig(config);
String result = Statusgo.saveAccountAndLoginWithKeycard(multiaccountData, password, settings, finalConfig, accountsData, chatKey);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "saveAccountAndLoginWithKeycard result: " + result);
Log.d(TAG, "Geth node started");
} else {
Log.e(TAG, "saveAccountAndLoginWithKeycard failed: " + result);
try {
Log.d(TAG, "saveAccountAndLoginWithKeycard");
String finalConfig = prepareDirAndUpdateConfig(config, this.getKeyUID(multiaccountData));
String result = Statusgo.saveAccountAndLoginWithKeycard(multiaccountData, password, settings, finalConfig, accountsData, chatKey);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "saveAccountAndLoginWithKeycard result: " + result);
Log.d(TAG, "Geth node started");
} else {
Log.e(TAG, "saveAccountAndLoginWithKeycard failed: " + result);
}
} catch (JSONException e) {
Log.e(TAG, "JSON conversion failed: " + e.getMessage());
}
}
private String getKeyUID(final String json) throws JSONException {
final JSONObject jsonObj = new JSONObject(json);
return jsonObj.getString("key-uid");
}
@ReactMethod
public void login(final String accountData, final String password) {
Log.d(TAG, "login");
this.migrateKeyStoreDir(accountData, password);
String result = Statusgo.login(accountData, password);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "Login result: " + result);
@ -416,23 +431,25 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
@ReactMethod
private void initKeystore() {
private void initKeystore(final String keyUID, final Callback callback) {
Log.d(TAG, "initKeystore");
Activity currentActivity = getCurrentActivity();
final String keydir = pathCombine(this.getNoBackupDirectory(), "/keystore");
if (!checkAvailability()) {
Log.e(TAG, "[initKeystore] Activity doesn't exist, cannot init keystore");
System.exit(0);
return;
}
final String commonKeydir = pathCombine(this.getNoBackupDirectory(), "/keystore");
final String keydir = pathCombine(commonKeydir, keyUID);
Runnable r = new Runnable() {
@Override
public void run() {
Statusgo.initKeystore(keydir);
callback.invoke(true);
}
};
@ -487,9 +504,27 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
StatusThreadPoolExecutor.getInstance().execute(r);
}
public void migrateKeyStoreDir(final String accountData, final String password) {
try {
final String commonKeydir = pathCombine(this.getNoBackupDirectory(), "/keystore");
final String keydir = pathCombine(commonKeydir, getKeyUID(accountData));
Log.d(TAG, "before migrateKeyStoreDir " + keydir);
File keydirFile = new File(keydir);
if(!keydirFile.exists() || keydirFile.list().length == 0) {
Log.d(TAG, "migrateKeyStoreDir");
Statusgo.migrateKeyStoreDir(accountData, password, commonKeydir, keydir);
Statusgo.initKeystore(keydir);
}
} catch (JSONException e) {
Log.e(TAG, "JSON conversion failed: " + e.getMessage());
}
}
@ReactMethod
public void loginWithKeycard(final String accountData, final String password, final String chatKey) {
Log.d(TAG, "loginWithKeycard");
this.migrateKeyStoreDir(accountData, password);
String result = Statusgo.loginWithKeycard(accountData, password, chatKey);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "LoginWithKeycard result: " + result);

View File

@ -110,7 +110,8 @@ RCT_EXPORT_METHOD(moveToInternalStorage:(RCTResponseSenderBlock)onResultCallback
////////////////////////////////////////////////////////////////////
#pragma mark - InitKeystore method
//////////////////////////////////////////////////////////////////// StopNode
RCT_EXPORT_METHOD(initKeystore) {
RCT_EXPORT_METHOD(initKeystore:(NSString *)keyUID
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"initKeystore() method called");
#endif
@ -119,12 +120,15 @@ RCT_EXPORT_METHOD(initKeystore) {
URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]
lastObject];
NSURL *keystoreDir = [rootUrl URLByAppendingPathComponent:@"keystore"];
NSURL *commonKeystoreDir = [rootUrl URLByAppendingPathComponent:@"keystore"];
NSURL *keystoreDir = [commonKeystoreDir URLByAppendingPathComponent:keyUID];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^(void)
{
NSString *res = StatusgoInitKeystore(keystoreDir.path);
NSLog(@"InitKeyStore result %@", res);
callback(@[]);
});
}
@ -306,8 +310,19 @@ RCT_EXPORT_METHOD(multiAccountDeriveAddresses:(NSString *)json
callback(@[result]);
}
-(NSString *) getKeyUID:(NSString *)jsonString {
NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:nil];
return [json valueForKey:@"key-uid"];
}
//////////////////////////////////////////////////////////////////// prepareDirAndUpdateConfig
-(NSString *) prepareDirAndUpdateConfig:(NSString *)config {
-(NSString *) prepareDirAndUpdateConfig:(NSString *)config
withKeyUID:(NSString *)keyUID {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
NSURL *rootUrl =[[fileManager
@ -354,7 +369,8 @@ RCT_EXPORT_METHOD(multiAccountDeriveAddresses:(NSString *)json
NSURL *absDataDirUrl = [NSURL fileURLWithPath:absDataDir];
NSURL *dataDirUrl = [NSURL fileURLWithPath:relativeDataDir];
NSURL *logUrl = [dataDirUrl URLByAppendingPathComponent:@"geth.log"];
[configJSON setValue:@"/keystore" forKey:@"KeyStoreDir"];
NSString *keystoreDir = [@"/keystore/" stringByAppendingString:keyUID];
[configJSON setValue:keystoreDir forKey:@"KeyStoreDir"];
[configJSON setValue:@"" forKey:@"LogDir"];
[configJSON setValue:logUrl.path forKey:@"LogFile"];
@ -380,15 +396,15 @@ RCT_EXPORT_METHOD(multiAccountDeriveAddresses:(NSString *)json
//////////////////////////////////////////////////////////////////// prepareDirAndUpdateConfig
RCT_EXPORT_METHOD(prepareDirAndUpdateConfig:(NSString *)config
RCT_EXPORT_METHOD(prepareDirAndUpdateConfig:(NSString *)keyUID
config:(NSString *)config
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"PrepareDirAndUpdateConfig() method called");
#endif
NSString *updatedConfig = [self prepareDirAndUpdateConfig:config];
NSString *updatedConfig = [self prepareDirAndUpdateConfig:config
withKeyUID:keyUID];
callback(@[updatedConfig]);
}
//////////////////////////////////////////////////////////////////// saveAccountAndLogin
@ -400,7 +416,9 @@ RCT_EXPORT_METHOD(saveAccountAndLogin:(NSString *)multiaccountData
#if DEBUG
NSLog(@"SaveAccountAndLogin() method called");
#endif
NSString *finalConfig = [self prepareDirAndUpdateConfig:config];
NSString *keyUID = [self getKeyUID:multiaccountData];
NSString *finalConfig = [self prepareDirAndUpdateConfig:config
withKeyUID:keyUID];
NSString *result = StatusgoSaveAccountAndLogin(multiaccountData, password, settings, finalConfig, accountsData);
NSLog(@"%@", result);
}
@ -415,17 +433,41 @@ RCT_EXPORT_METHOD(saveAccountAndLoginWithKeycard:(NSString *)multiaccountData
#if DEBUG
NSLog(@"SaveAccountAndLoginWithKeycard() method called");
#endif
NSString *finalConfig = [self prepareDirAndUpdateConfig:config];
NSString *keyUID = [self getKeyUID:multiaccountData];
NSString *finalConfig = [self prepareDirAndUpdateConfig:config
withKeyUID:keyUID];
NSString *result = StatusgoSaveAccountAndLoginWithKeycard(multiaccountData, password, settings, finalConfig, accountsData, chatKey);
NSLog(@"%@", result);
}
- (void) migrateKeystore:(NSString *)accountData
password:(NSString *)password {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *rootUrl =[[fileManager
URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]
lastObject];
NSString *keyUID = [self getKeyUID:accountData];
NSURL *oldKeystoreDir = [rootUrl URLByAppendingPathComponent:@"keystore"];
NSURL *multiaccountKeystoreDir = [oldKeystoreDir URLByAppendingPathComponent:keyUID];
NSArray *keys = [fileManager contentsOfDirectoryAtPath:multiaccountKeystoreDir.path error:nil];
if (keys.count == 0) {
NSString *migrationResult = StatusgoMigrateKeyStoreDir(accountData, password, oldKeystoreDir.path, multiaccountKeystoreDir.path);
NSLog(@"keystore migration result %@", migrationResult);
NSString *initKeystoreResult = StatusgoInitKeystore(multiaccountKeystoreDir.path);
NSLog(@"InitKeyStore result %@", initKeystoreResult);
}
}
//////////////////////////////////////////////////////////////////// login
RCT_EXPORT_METHOD(login:(NSString *)accountData
password:(NSString *)password) {
#if DEBUG
NSLog(@"Login() method called");
#endif
[self migrateKeystore:accountData password:password];
NSString *result = StatusgoLogin(accountData, password);
NSLog(@"%@", result);
}
@ -437,6 +479,8 @@ RCT_EXPORT_METHOD(loginWithKeycard:(NSString *)accountData
#if DEBUG
NSLog(@"LoginWithKeycard() method called");
#endif
[self migrateKeystore:accountData password:password];
NSString *result = StatusgoLoginWithKeycard(accountData, password, chatKey);
NSLog(@"%@", result);

View File

@ -334,7 +334,8 @@
:hardwallet/get-application-info {:pairing (get-pairing db key-uid)}
:hardwallet/login-with-keycard {:multiaccount-data multiaccount-data
:password encryption-public-key
:chat-key whisper-private-key}}
:chat-key whisper-private-key
:key-uid key-uid}}
(when save-keys?
(keychain/save-hardwallet-keys key-uid encryption-public-key whisper-private-key))
(clear-on-card-connected)

View File

@ -213,8 +213,9 @@
(catch on-failure))))
(defn save-multiaccount-and-login
[{:keys [multiaccount-data password settings node-config accounts-data chat-key]}]
[{:keys [key-uid multiaccount-data password settings node-config accounts-data chat-key]}]
(status/save-multiaccount-and-login-with-keycard
key-uid
(types/clj->json multiaccount-data)
password
(types/clj->json settings)

View File

@ -143,6 +143,7 @@
(log/debug "[simulated kk] generate-and-load-key response" response)
(status/multiaccount-store-derived
id
key-uid
[constants/path-wallet-root
constants/path-eip1581
constants/path-whisper
@ -197,9 +198,8 @@
path))
(defn export-key [{:keys [pin on-success on-failure]}]
(let [wallet-root-address (get-in
@re-frame.db/app-db
[:multiaccount :wallet-root-address])
(let [{:keys [key-uid wallet-root-address]}
(get @re-frame.db/app-db :multiaccount)
accounts (get @re-frame.db/app-db :multiaccount/accounts)
hashed-password (ethereum/sha3 pin)
path-num (inc (get-in @re-frame.db/app-db [:multiaccount :latest-derived-path]))
@ -220,6 +220,7 @@
(re-frame/dispatch [::new-account-error :account-error (i18n/label :t/account-exists-title)])
(status/multiaccount-store-derived
id
key-uid
[path]
hashed-password
(fn [result]
@ -293,16 +294,17 @@
(log/warn "sign-typed-data not implemented" args))
(defn save-multiaccount-and-login
[{:keys [multiaccount-data password settings node-config accounts-data]}]
[{:keys [key-uid multiaccount-data password settings node-config accounts-data]}]
(status/save-account-and-login
key-uid
(types/clj->json multiaccount-data)
password
(types/clj->json settings)
node-config
(types/clj->json accounts-data)))
(defn login [{:keys [multiaccount-data password]}]
(status/login multiaccount-data password))
(defn login [{:keys [key-uid multiaccount-data password]}]
(status/login key-uid multiaccount-data password))
(defn send-transaction-with-signature
[{:keys [transaction on-completed]}]

View File

@ -55,7 +55,6 @@
(fx/merge cofx
{:get-supported-biometric-auth nil
::init-theme nil
::init-keystore nil
::open-multiaccounts #(re-frame/dispatch [::initialize-multiaccounts % {:logout? false}])
:ui/listen-to-window-dimensions-change nil
::network/listen-to-network-info nil
@ -70,11 +69,6 @@
(fn [callback]
(status/open-accounts callback)))
(re-frame/reg-fx
::init-keystore
(fn []
(status/init-keystore)))
(re-frame/reg-fx
::init-theme
(fn []

View File

@ -71,6 +71,11 @@
(fx/defn create-multiaccount
[{:keys [db]}]
(let [{:keys [selected-id key-code]} (:intro-wizard db)
key-uid (some
(fn [{:keys [id key-uid]}]
(when (= id selected-id)
key-uid))
(get-in db [:intro-wizard :multiaccounts]))
hashed-password (ethereum/sha3 (security/safe-unmask-data key-code))
callback (fn [result]
(let [derived-data (normalize-derived-data-keys (types/json->clj result))
@ -84,7 +89,7 @@
(merge derived-whisper {:name name :photo-path photo-path}))]
(re-frame/dispatch [::store-multiaccount-success
key-code derived-data-extended]))))))]
{::store-multiaccount [selected-id hashed-password callback]}))
{::store-multiaccount [selected-id key-uid hashed-password callback]}))
(fx/defn prepare-intro-wizard
[{:keys [db] :as cofx}]
@ -230,8 +235,9 @@
{:hardwallet/save-multiaccount-and-login args})
(fx/defn save-account-and-login
[_ multiaccount-data password settings node-config accounts-data]
{::save-account-and-login [(types/clj->json multiaccount-data)
[_ key-uid multiaccount-data password settings node-config accounts-data]
{::save-account-and-login [key-uid
(types/clj->json multiaccount-data)
password
(types/clj->json settings)
node-config
@ -303,17 +309,20 @@
{:db db}
(if keycard-multiaccount?
(save-multiaccount-and-login-with-keycard
{:multiaccount-data multiaccount-data
{:key-uid key-uid
:multiaccount-data multiaccount-data
:password password
:settings settings
:node-config (node/get-new-config db)
:accounts-data accounts-data
:chat-key chat-key})
(save-account-and-login multiaccount-data
(ethereum/sha3 (security/safe-unmask-data password))
settings
(node/get-new-config db)
accounts-data))
(save-account-and-login
key-uid
multiaccount-data
(ethereum/sha3 (security/safe-unmask-data password))
settings
(node/get-new-config db)
accounts-data))
(when (:intro-wizard db)
(intro-step-forward {})))))
@ -401,9 +410,10 @@
(re-frame/reg-fx
::store-multiaccount
(fn [[id hashed-password callback]]
(fn [[id key-uid hashed-password callback]]
(status/multiaccount-store-derived
id
key-uid
[constants/path-wallet-root
constants/path-eip1581
constants/path-whisper
@ -413,9 +423,11 @@
(re-frame/reg-fx
::save-account-and-login
(fn [[multiaccount-data hashed-password settings config accounts-data]]
(status/save-account-and-login multiaccount-data
hashed-password
settings
config
accounts-data)))
(fn [[key-uid multiaccount-data hashed-password settings config accounts-data]]
(status/save-account-and-login
key-uid
multiaccount-data
hashed-password
settings
config
accounts-data)))

View File

@ -32,8 +32,8 @@
(re-frame/reg-fx
::login
(fn [[account-data hashed-password]]
(status/login account-data hashed-password)))
(fn [[key-uid account-data hashed-password]]
(status/login key-uid account-data hashed-password)))
(defn rpc->accounts [accounts]
(reduce (fn [acc {:keys [chat type wallet] :as account}]
@ -71,7 +71,8 @@
(assoc-in [:multiaccounts/login :processing] true)
(dissoc :intro-wizard)
(update :hardwallet dissoc :flow))
::login [(types/clj->json {:name name
::login [key-uid
(types/clj->json {:name name
:key-uid key-uid
:photo-path photo-path})
(ethereum/sha3 (security/safe-unmask-data password))]}))

View File

@ -18,7 +18,7 @@
efx (login.core/login cofx)]
(testing "Change multiaccount."
(is (= (::login.core/login efx)
["{\"name\":\"user\",\"key-uid\":\"key-uid\",\"photo-path\":\"photo\"}" (ethereum/sha3 "password")])))
["key-uid" "{\"name\":\"user\",\"key-uid\":\"key-uid\",\"photo-path\":\"photo\"}" (ethereum/sha3 "password")])))
(testing "start activity indicator"
(is (= (get-in efx [:db :multiaccounts/login :processing]) true))))))

View File

@ -80,11 +80,11 @@
[{:keys [db]}]
(let [password (get-in db [:intro-wizard :key-code])
{:keys [root-key]} (:intro-wizard db)
{:keys [id]} root-key
{:keys [id key-uid]} root-key
callback #(re-frame/dispatch [::store-multiaccount-success % password])
hashed-password (ethereum/sha3 (security/safe-unmask-data password))]
{:db (assoc-in db [:intro-wizard :processing?] true)
::multiaccounts.create/store-multiaccount [id hashed-password callback]}))
::multiaccounts.create/store-multiaccount [id key-uid hashed-password callback]}))
(fx/defn recover-multiaccount-with-checks
{:events [::sign-in-button-pressed]}

View File

@ -19,18 +19,19 @@
(.clearCookies ^js (status))
(.clearStorageAPIs ^js (status))))
(defn init-keystore []
(log/debug "[native-module] init-keystore")
(.initKeystore ^js (status)))
(defn init-keystore [key-uid callback]
(log/debug "[native-module] init-keystore" key-uid)
(.initKeystore ^js (status) key-uid callback))
(defn open-accounts [callback]
(log/debug "[native-module] open-accounts")
(.openAccounts ^js (status) #(callback (types/json->clj %))))
(defn prepare-dir-and-update-config
[config callback]
[key-uid config callback]
(log/debug "[native-module] prepare-dir-and-update-config")
(.prepareDirAndUpdateConfig ^js (status)
key-uid
config
#(callback (types/json->clj %))))
@ -44,26 +45,32 @@
(defn save-account-and-login
"NOTE: beware, the password has to be sha3 hashed"
[multiaccount-data hashed-password settings config accounts-data]
[key-uid multiaccount-data hashed-password settings config accounts-data]
(log/debug "[native-module] save-account-and-login"
"multiaccount-data" multiaccount-data)
(clear-web-data)
(.saveAccountAndLogin
^js (status) multiaccount-data hashed-password settings config accounts-data))
(init-keystore
key-uid
#(.saveAccountAndLogin
^js (status) multiaccount-data hashed-password settings config accounts-data)))
(defn save-multiaccount-and-login-with-keycard
"NOTE: chat-key is a whisper private key sent from keycard"
[multiaccount-data password settings config accounts-data chat-key]
[key-uid multiaccount-data password settings config accounts-data chat-key]
(log/debug "[native-module] save-account-and-login-with-keycard")
(.saveAccountAndLoginWithKeycard
^js (status) multiaccount-data password settings config accounts-data chat-key))
(init-keystore
key-uid
#(.saveAccountAndLoginWithKeycard
^js (status) multiaccount-data password settings config accounts-data chat-key)))
(defn login
"NOTE: beware, the password has to be sha3 hashed"
[account-data hashed-password]
[key-uid account-data hashed-password]
(log/debug "[native-module] login")
(clear-web-data)
(.login ^js (status) account-data hashed-password))
(init-keystore
key-uid
#(.login ^js (status) account-data hashed-password)))
(defn logout []
(log/debug "[native-module] logout")
@ -116,24 +123,28 @@
and chat accounts, you need to load the account again with
`multiaccount-load-account` before using `multiaccount-store-derived`
and the id of the account stored will have changed"
[account-id hashed-password callback]
[account-id key-uid hashed-password callback]
(log/debug "[native-module] multiaccount-store-account")
(when (status)
(.multiAccountStoreAccount ^js (status)
(types/clj->json {:accountID account-id
:password hashed-password})
callback)))
(init-keystore
key-uid
#(.multiAccountStoreAccount ^js (status)
(types/clj->json {:accountID account-id
:password hashed-password})
callback))))
(defn multiaccount-store-derived
"NOTE: beware, the password has to be sha3 hashed"
[account-id paths hashed-password callback]
(log/debug "[native-module] multiaccount-store-derived"
[account-id key-uid paths hashed-password callback]
(log/debug "[native-module] multiaccount-store-derived"
"account-id" account-id)
(.multiAccountStoreDerived ^js (status)
(types/clj->json {:accountID account-id
:paths paths
:password hashed-password})
callback))
(init-keystore
key-uid
#(.multiAccountStoreDerived ^js (status)
(types/clj->json {:accountID account-id
:paths paths
:password hashed-password})
callback)))
(defn multiaccount-generate-and-derive-addresses
"used to generate multiple multiaccounts for onboarding
@ -172,10 +183,12 @@
(.verify ^js (status) address hashed-password callback))
(defn login-with-keycard
[{:keys [multiaccount-data password chat-key]}]
[{:keys [key-uid multiaccount-data password chat-key]}]
(log/debug "[native-module] login-with-keycard")
(clear-web-data)
(.loginWithKeycard ^js (status) multiaccount-data password chat-key))
(init-keystore
key-uid
#(.loginWithKeycard ^js (status) multiaccount-data password chat-key)))
(defn set-soft-input-mode [mode]
(log/debug "[native-module] set-soft-input-mode")

View File

@ -165,11 +165,13 @@ app-db"
(fx/defn prepare-new-config
"Use this function to apply settings to the current account node config"
[{:keys [db]} {:keys [on-success]}]
{::prepare-new-config [(get-new-config db)
#(re-frame/dispatch
[::save-new-config % {:on-success on-success}])]})
(let [key-uid (get-in db [:multiaccount :key-uid])]
{::prepare-new-config [key-uid
(get-new-config db)
#(re-frame/dispatch
[::save-new-config % {:on-success on-success}])]}))
(re-frame/reg-fx
::prepare-new-config
(fn [[config callback]]
(status/prepare-dir-and-update-config config callback)))
(fn [[key-uid config callback]]
(status/prepare-dir-and-update-config key-uid config callback)))

View File

@ -57,7 +57,7 @@
"/" (last (string/split path "/")))
path))
(defn derive-and-store-account [path hashed-password type accounts]
(defn derive-and-store-account [key-uid path hashed-password type accounts]
(fn [value]
(let [{:keys [id error]} (types/json->clj value)]
(if error
@ -71,6 +71,7 @@
(re-frame/dispatch [::new-account-error :account-error (i18n/label :t/account-exists-title)])
(status/multiaccount-store-derived
id
key-uid
[path]
hashed-password
(fn [result]
@ -87,7 +88,7 @@
(def pass-error "cannot retrieve a valid key for a given account: could not decrypt key with given password")
(defn store-account [path hashed-password type]
(defn store-account [key-uid path hashed-password type]
(fn [value]
(let [{:keys [id error]} (types/json->clj value)]
(if error
@ -96,6 +97,7 @@
error])
(status/multiaccount-store-account
id
key-uid
hashed-password
(account-stored path type))))))
@ -108,38 +110,40 @@
(re-frame/reg-fx
::generate-account
(fn [{:keys [derivation-info hashed-password accounts]}]
(fn [{:keys [derivation-info hashed-password accounts key-uid]}]
(let [{:keys [address path]} derivation-info]
(status/multiaccount-load-account
address
hashed-password
(derive-and-store-account path hashed-password :generated accounts)))))
(derive-and-store-account key-uid path hashed-password :generated accounts)))))
(re-frame/reg-fx
::import-account-seed
(fn [{:keys [passphrase hashed-password accounts]}]
(fn [{:keys [passphrase hashed-password accounts key-uid]}]
(status/multiaccount-import-mnemonic
(mnemonic/sanitize-passphrase (security/unmask passphrase))
""
(derive-and-store-account constants/path-default-wallet hashed-password :seed accounts))))
(derive-and-store-account key-uid constants/path-default-wallet hashed-password :seed accounts))))
(re-frame/reg-fx
::import-account-private-key
(fn [{:keys [private-key hashed-password]}]
(fn [{:keys [private-key hashed-password key-uid]}]
(status/multiaccount-import-private-key
(string/trim (security/unmask private-key))
(store-account constants/path-default-wallet hashed-password :key))))
(store-account key-uid constants/path-default-wallet hashed-password :key))))
(fx/defn generate-new-account
[{:keys [db]} hashed-password]
(let [wallet-root-address (get-in db [:multiaccount :wallet-root-address])
path-num (inc (get-in db [:multiaccount :latest-derived-path]))
accounts (:multiaccount/accounts db)]
(let [{:keys [key-uid wallet-root-address]}
(get db :multiaccount)
path-num (inc (get-in db [:multiaccount :latest-derived-path]))
accounts (:multiaccount/accounts db)]
{:db (assoc-in db [:add-account :step] :generating)
::generate-account {:derivation-info {:path (str "m/" path-num)
:address wallet-root-address}
:hashed-password hashed-password
:accounts accounts}}))
:accounts accounts
:key-uid key-uid}}))
(fx/defn import-new-account-seed
[{:keys [db]} passphrase hashed-password]
@ -150,21 +154,24 @@
(fx/defn new-account-seed-validated
{:events [:wallet.accounts/seed-validated]}
[cofx phrase-warnings passphrase hashed-password]
(let [error (:error (types/json->clj phrase-warnings))]
[{:keys [db] :as cofx} phrase-warnings passphrase hashed-password]
(let [error (:error (types/json->clj phrase-warnings))
{:keys [key-uid]} (:multiaccount db)]
(if-not (string/blank? error)
(new-account-error cofx :account-error error)
(let [{:keys [db]} cofx
accounts (:multiaccount/accounts db)]
(let [accounts (:multiaccount/accounts db)]
{::import-account-seed {:passphrase passphrase
:hashed-password hashed-password
:accounts accounts}}))))
:accounts accounts
:key-uid key-uid}}))))
(fx/defn import-new-account-private-key
[{:keys [db]} private-key hashed-password]
{:db (assoc-in db [:add-account :step] :generating)
::import-account-private-key {:private-key private-key
:hashed-password hashed-password}})
(let [{:keys [key-uid]} (:multiaccount db)]
{:db (assoc-in db [:add-account :step] :generating)
::import-account-private-key {:private-key private-key
:hashed-password hashed-password
:key-uid key-uid}}))
(fx/defn save-new-account
[{:keys [db] :as cofx}]

View File

@ -2,7 +2,7 @@
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
"owner": "status-im",
"repo": "status-go",
"version": "v0.54.1",
"commit-sha1": "20f45a7c1caa25a30853480ac47177b534536f26",
"src-sha256": "1hsjsv00dlbjp4nqnifymldr8v20arzv07l9l27jarq9dk00wbia"
"version": "v0.55.1",
"commit-sha1": "6d5a93287b2c1b4d4d5d1178a3ecec870bf18b9e",
"src-sha256": "1wly0km9bxxv1wwj6jchqh4d4x2m86fxrdqixjzldy70vl6qbyqa"
}