multiaccounts

This commit is contained in:
Andrey Shovkoplyas 2019-07-19 16:11:10 +02:00
parent 1e655540da
commit 6d337bc69a
No known key found for this signature in database
GPG Key ID: EAAB7C8622D860A4
40 changed files with 334 additions and 270 deletions

View File

@ -187,7 +187,6 @@ var TopLevel = {
"hide" : function () {}, "hide" : function () {},
"i18n" : function () {}, "i18n" : function () {},
"ignoreWarnings" : function () {}, "ignoreWarnings" : function () {},
"importOnboardingAccount": function () {},
"in" : function () {}, "in" : function () {},
"index" : function () {}, "index" : function () {},
"indexOf" : function () {}, "indexOf" : function () {},
@ -466,7 +465,6 @@ var TopLevel = {
"StackActions" : function () {}, "StackActions" : function () {},
"start" : function () {}, "start" : function () {},
"startNode" : function () {}, "startNode" : function () {},
"startOnboarding": function () {},
"state" : function () {}, "state" : function () {},
"Status" : function () {}, "Status" : function () {},
"status" : function () {}, "status" : function () {},
@ -563,5 +561,7 @@ var TopLevel = {
"isSupported" : function () {}, "isSupported" : function () {},
"authenticate" : function () {}, "authenticate" : function () {},
"createAppContainer" : function () {}, "createAppContainer" : function () {},
"useScreens" : function () {} "useScreens" : function () {},
"multiAccountGenerateAndDeriveAddresses" : function () {},
"multiAccountStoreDerived" : function () {}
} }

View File

@ -386,7 +386,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
} }
@ReactMethod @ReactMethod
public void login(final String address, final String password, final Callback callback) { public void login(final String json, final Callback callback) {
Log.d(TAG, "login"); Log.d(TAG, "login");
if (!checkAvailability()) { if (!checkAvailability()) {
callback.invoke(false); callback.invoke(false);
@ -396,7 +396,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
Runnable r = new Runnable() { Runnable r = new Runnable() {
@Override @Override
public void run() { public void run() {
String result = Statusgo.login(address, password); String result = Statusgo.login(json);
callback.invoke(result); callback.invoke(result);
} }
@ -661,8 +661,8 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
} }
@ReactMethod @ReactMethod
public void startOnboarding(final Integer n, final Integer mnemonicLength, final Callback callback) { public void multiAccountGenerateAndDeriveAddresses(final String json, final Callback callback) {
Log.d(TAG, "startOnboarding"); Log.d(TAG, "multiAccountGenerateAndDeriveAddresses");
if (!checkAvailability()) { if (!checkAvailability()) {
callback.invoke(false); callback.invoke(false);
return; return;
@ -670,7 +670,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
Runnable r = new Runnable() { Runnable r = new Runnable() {
@Override @Override
public void run() { public void run() {
String res = Statusgo.startOnboarding(n, mnemonicLength); String res = Statusgo.multiAccountGenerateAndDeriveAddresses(json);
callback.invoke(res); callback.invoke(res);
} }
@ -680,8 +680,8 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
} }
@ReactMethod @ReactMethod
public void importOnboardingAccount(final String id, final String password, final Callback callback) { public void multiAccountStoreDerived(final String json, final Callback callback) {
Log.d(TAG, "importOnboardingAccount"); Log.d(TAG, "multiAccountStoreDerived");
if (!checkAvailability()) { if (!checkAvailability()) {
callback.invoke(false); callback.invoke(false);
return; return;
@ -689,7 +689,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
Runnable r = new Runnable() { Runnable r = new Runnable() {
@Override @Override
public void run() { public void run() {
String res = Statusgo.importOnboardingAccount(id, password); String res = Statusgo.multiAccountStoreDerivedAccounts(json);
callback.invoke(res); callback.invoke(res);
} }
@ -818,7 +818,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
} }
@ReactMethod @ReactMethod
public void signTypedData(final String data, final String password, final Callback callback) { public void signTypedData(final String data, final String account, final String password, final Callback callback) {
Log.d(TAG, "signTypedData"); Log.d(TAG, "signTypedData");
if (!checkAvailability()) { if (!checkAvailability()) {
callback.invoke(false); callback.invoke(false);
@ -828,7 +828,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
Runnable r = new Runnable() { Runnable r = new Runnable() {
@Override @Override
public void run() { public void run() {
String res = Statusgo.signTypedData(data, password); String res = Statusgo.signTypedData(data, account, password);
callback.invoke(res); callback.invoke(res);
} }
}; };

View File

@ -335,37 +335,34 @@ RCT_EXPORT_METHOD(recoverAccount:(NSString *)passphrase
callback(@[result]); callback(@[result]);
} }
//////////////////////////////////////////////////////////////////// startOnboarding //////////////////////////////////////////////////////////////////// multiAccountGenerateAndDeriveAddresses
RCT_EXPORT_METHOD(startOnboarding:(NSInteger)n RCT_EXPORT_METHOD(multiAccountGenerateAndDeriveAddresses:(NSString *)json
password:(NSInteger)mnemonicLength
callback:(RCTResponseSenderBlock)callback) { callback:(RCTResponseSenderBlock)callback) {
#if DEBUG #if DEBUG
NSLog(@"StartOnboarding() method called"); NSLog(@"MultiAccountGenerateAndDeriveAddresses() method called");
#endif #endif
NSString *result = StatusgoStartOnboarding(n, mnemonicLength); NSString *result = StatusgoMultiAccountGenerateAndDeriveAddresses(json);
callback(@[result]); callback(@[result]);
} }
//////////////////////////////////////////////////////////////////// importOnboardingAccount //////////////////////////////////////////////////////////////////// multiAccountStoreDerived
RCT_EXPORT_METHOD(importOnboardingAccount:(NSString *)id RCT_EXPORT_METHOD(multiAccountStoreDerived:(NSString *)json
password:(NSString *)password
callback:(RCTResponseSenderBlock)callback) { callback:(RCTResponseSenderBlock)callback) {
#if DEBUG #if DEBUG
NSLog(@"ImportOnboardingAccount() method called"); NSLog(@"MultiAccountStoreDerived() method called");
#endif #endif
NSString *result = StatusgoImportOnboardingAccount(id, password); NSString *result = StatusgoMultiAccountStoreDerivedAccounts(json);
callback(@[result]); callback(@[result]);
} }
//////////////////////////////////////////////////////////////////// login //////////////////////////////////////////////////////////////////// login
RCT_EXPORT_METHOD(login:(NSString *)address RCT_EXPORT_METHOD(login:(NSString *)json
password:(NSString *)password
callback:(RCTResponseSenderBlock)callback) { callback:(RCTResponseSenderBlock)callback) {
#if DEBUG #if DEBUG
NSLog(@"Login() method called"); NSLog(@"Login() method called");
#endif #endif
NSString *result = StatusgoLogin(address, password); NSString *result = StatusgoLogin(json);
callback(@[result]); callback(@[result]);
} }
@ -415,12 +412,13 @@ RCT_EXPORT_METHOD(signMessage:(NSString *)message
#pragma mark - SignTypedData #pragma mark - SignTypedData
//////////////////////////////////////////////////////////////////// signTypedData //////////////////////////////////////////////////////////////////// signTypedData
RCT_EXPORT_METHOD(signTypedData:(NSString *)data RCT_EXPORT_METHOD(signTypedData:(NSString *)data
account:(NSString *)account
password:(NSString *)password password:(NSString *)password
callback:(RCTResponseSenderBlock)callback) { callback:(RCTResponseSenderBlock)callback) {
#if DEBUG #if DEBUG
NSLog(@"SignTypedData() method called"); NSLog(@"SignTypedData() method called");
#endif #endif
NSString *result = StatusgoSignTypedData(data, password); NSString *result = StatusgoSignTypedData(data, account, password);
callback(@[result]); callback(@[result]);
} }

View File

@ -6,7 +6,8 @@
[status-im.i18n :as i18n] [status-im.i18n :as i18n]
[status-im.qr-scanner.core :as qr-scanner] [status-im.qr-scanner.core :as qr-scanner]
[status-im.ui.screens.navigation :as navigation] [status-im.ui.screens.navigation :as navigation]
[status-im.utils.fx :as fx])) [status-im.utils.fx :as fx]
[status-im.ethereum.core :as ethereum]))
(declare process-next-permission) (declare process-next-permission)
(declare send-response-to-bridge) (declare send-response-to-bridge)
@ -52,7 +53,7 @@
(defn get-permission-data [cofx allowed-permission] (defn get-permission-data [cofx allowed-permission]
(let [multiaccount (get-in cofx [:db :multiaccount])] (let [multiaccount (get-in cofx [:db :multiaccount])]
(get {constants/dapp-permission-contact-code (:public-key multiaccount) (get {constants/dapp-permission-contact-code (:public-key multiaccount)
constants/dapp-permission-web3 [(ethereum/normalized-address (:address multiaccount))]} constants/dapp-permission-web3 [(:address (ethereum/get-default-account (:accounts multiaccount)))]}
allowed-permission))) allowed-permission)))
(fx/defn send-response-to-bridge (fx/defn send-response-to-bridge

View File

@ -237,6 +237,12 @@
(def ^:const status-create-address "status_createaddress") (def ^:const status-create-address "status_createaddress")
(def ^:const path-default-wallet "m/44'/60'/0'/0/0")
(def ^:const path-whisper "m/43'/60'/1581'/0'/0")
(def ^:const path-default-wallet-keyword (keyword path-default-wallet))
(def ^:const path-whisper-keyword (keyword path-whisper))
;; (ethereum/sha3 "Transfer(address,address,uint256)") ;; (ethereum/sha3 "Transfer(address,address,uint256)")
(def ^:const event-transfer-hash "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") (def ^:const event-transfer-hash "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef")

View File

@ -34,6 +34,7 @@
(defn- deserialize-multiaccount [multiaccount] (defn- deserialize-multiaccount [multiaccount]
(-> multiaccount (-> multiaccount
(update :settings core/deserialize) (update :settings core/deserialize)
(update :accounts core/deserialize)
(update :extensions deserialize-extensions) (update :extensions deserialize-extensions)
(update :bootnodes deserialize-bootnodes) (update :bootnodes deserialize-bootnodes)
(update :networks deserialize-networks))) (update :networks deserialize-networks)))
@ -54,6 +55,7 @@
(defn- serialize-multiaccount [multiaccount] (defn- serialize-multiaccount [multiaccount]
(-> multiaccount (-> multiaccount
(update :settings core/serialize) (update :settings core/serialize)
(update :accounts core/serialize)
(update :extensions serialize-extensions) (update :extensions serialize-extensions)
(update :bootnodes serialize-bootnodes) (update :bootnodes serialize-bootnodes)
(update :networks serialize-networks) (update :networks serialize-networks)

View File

@ -251,3 +251,7 @@
(def v25 (update v24 :properties merge {:preferred-name {:type :string :optional true} (def v25 (update v24 :properties merge {:preferred-name {:type :string :optional true}
:show-name? {:type :bool :optional true}})) :show-name? {:type :bool :optional true}}))
(def v26 (update v25 :properties merge {:root-address {:type :string :optional true}
:accounts {:type :string :optional true}}))

View File

@ -123,6 +123,11 @@
extension/v12 extension/v12
account/v25]) account/v25])
(def v31 [network/v1
bootnode/v4
extension/v12
account/v26])
;; put schemas ordered by version ;; put schemas ordered by version
(def schemas [{:schema v1 (def schemas [{:schema v1
:schemaVersion 1 :schemaVersion 1
@ -213,4 +218,7 @@
:migration (constantly nil)} :migration (constantly nil)}
{:schema v30 {:schema v30
:schemaVersion 30 :schemaVersion 30
:migration (constantly nil)}
{:schema v31
:schemaVersion 31
:migration (constantly nil)}]) :migration (constantly nil)}])

View File

@ -61,6 +61,14 @@
(-> (get-in db [:multiaccount :address]) (-> (get-in db [:multiaccount :address])
normalized-address)) normalized-address))
(defn get-default-account [accounts]
(some #(when (:default? %) %) accounts))
(defn default-address [db]
(-> (get-in db [:multiaccount :accounts])
get-default-account
:address))
(defn naked-address [s] (defn naked-address [s]
(when s (when s
(string/replace s hex-prefix ""))) (string/replace s hex-prefix "")))

View File

@ -280,13 +280,16 @@
(fn [cofx [_ input-key text]] (fn [cofx [_ input-key text]]
(multiaccounts.create/multiaccount-set-input-text cofx input-key text))) (multiaccounts.create/multiaccount-set-input-text cofx input-key text)))
(defn get-selected-multiaccount [{:keys [db]}]
(let [{:keys [selected-id multiaccounts]} (:intro-wizard db)]
(some #(when (= selected-id (:id %)) %) multiaccounts)))
(handlers/register-handler-fx (handlers/register-handler-fx
:multiaccounts.create.callback/create-multiaccount-success :multiaccounts.create.callback/create-multiaccount-success
[(re-frame/inject-cofx :random-guid-generator) [(re-frame/inject-cofx :random-guid-generator)
(re-frame/inject-cofx :multiaccounts.create/get-signing-phrase)] (re-frame/inject-cofx :multiaccounts.create/get-signing-phrase)]
(fn [cofx [_ result password]] (fn [cofx [_ password]]
(multiaccounts.create/on-multiaccount-created cofx result password {:seed-backed-up? false (multiaccounts.create/on-multiaccount-created cofx (get-selected-multiaccount cofx) password {:seed-backed-up? false})))
:new-multiaccount? true})))
(handlers/register-handler-fx (handlers/register-handler-fx
:multiaccounts.create.ui/create-new-multiaccount-button-pressed :multiaccounts.create.ui/create-new-multiaccount-button-pressed
@ -348,8 +351,8 @@
(handlers/register-handler-fx (handlers/register-handler-fx
:multiaccounts.login.ui/multiaccount-selected :multiaccounts.login.ui/multiaccount-selected
(fn [cofx [_ address photo-path name public-key]] (fn [cofx [_ address photo-path name public-key accounts]]
(multiaccounts.login/open-login cofx address photo-path name public-key))) (multiaccounts.login/open-login cofx address photo-path name public-key accounts)))
(handlers/register-handler-fx (handlers/register-handler-fx
:multiaccounts.login.callback/get-user-password-success :multiaccounts.login.callback/get-user-password-success

View File

@ -19,7 +19,8 @@
[status-im.wallet.core :as wallet] [status-im.wallet.core :as wallet]
[taoensso.timbre :as log] [taoensso.timbre :as log]
status-im.hardwallet.fx status-im.hardwallet.fx
[status-im.ui.components.react :as react])) [status-im.ui.components.react :as react]
[status-im.constants :as constants]))
(def default-pin "000000") (def default-pin "000000")
@ -1594,16 +1595,17 @@
(fx/merge (-> cofx (fx/merge (-> cofx
(multiaccounts.create/get-signing-phrase)) (multiaccounts.create/get-signing-phrase))
{:db (assoc-in db [:hardwallet :setup-step] nil)} {:db (assoc-in db [:hardwallet :setup-step] nil)}
(multiaccounts.create/on-multiaccount-created {:pubkey whisper-public-key (multiaccounts.create/on-multiaccount-created
:address wallet-address {:derived {constants/path-whisper-keyword {:publicKey whisper-public-key}
:mnemonic "" constants/path-default-wallet-keyword {:address wallet-address}}
:keycard-instance-uid instance-uid :mnemonic ""
:keycard-key-uid key-uid :keycard-instance-uid instance-uid
:keycard-pairing pairing :keycard-key-uid key-uid
:keycard-paired-on paired-on} :keycard-pairing pairing
encryption-public-key :keycard-paired-on paired-on}
{:seed-backed-up? true encryption-public-key
:login? true}) {:seed-backed-up? true
:login? true})
(if (= flow :import) (if (= flow :import)
(navigation/navigate-to-cofx :keycard-recovery-success nil) (navigation/navigate-to-cofx :keycard-recovery-success nil)
(navigation/navigate-to-cofx :keycard-welcome nil))))) (navigation/navigate-to-cofx :keycard-welcome nil)))))

View File

@ -151,8 +151,8 @@
(:public-key multiaccount))) (:public-key multiaccount)))
%) %)
#(sort-by :last-sign-in > %)) #(sort-by :last-sign-in > %))
{:keys [address public-key photo-path name]} (first (selection-fn (vals multiaccounts)))] {:keys [address public-key photo-path name accounts]} (first (selection-fn (vals multiaccounts)))]
(multiaccounts.login/open-login cofx address photo-path name public-key))))) (multiaccounts.login/open-login cofx address photo-path name public-key accounts)))))
(fx/defn load-multiaccounts-and-initialize-views (fx/defn load-multiaccounts-and-initialize-views
"DB has been decrypted, load multiaccounts and initialize-view" "DB has been decrypted, load multiaccounts and initialize-view"

View File

@ -21,7 +21,10 @@
[status-im.utils.fx :as fx] [status-im.utils.fx :as fx]
[status-im.node.core :as node] [status-im.node.core :as node]
[status-im.ui.screens.mobile-network-settings.events :as mobile-network] [status-im.ui.screens.mobile-network-settings.events :as mobile-network]
[status-im.utils.platform :as platform])) [status-im.utils.platform :as platform]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.ui.components.colors :as colors]
[status-im.ethereum.core :as ethereum]))
(defn get-signing-phrase [cofx] (defn get-signing-phrase [cofx]
(assoc cofx :signing-phrase (signing-phrase/generate))) (assoc cofx :signing-phrase (signing-phrase/generate)))
@ -45,23 +48,23 @@
(defn create-multiaccount! [{:keys [id password]}] (defn create-multiaccount! [{:keys [id password]}]
(if id (if id
(status/import-onboarding-multiaccount (status/multiaccount-store-derived
id id
[constants/path-whisper constants/path-default-wallet]
password password
#(re-frame/dispatch [:multiaccounts.create.callback/create-multiaccount-success (types/json->clj %) password])) #(re-frame/dispatch [:multiaccounts.create.callback/create-multiaccount-success password]))
(status/create-multiaccount (status/create-multiaccount
password password
#(re-frame/dispatch [:multiaccounts.create.callback/create-multiaccount-success (types/json->clj %) password])))) #(re-frame/dispatch [:multiaccounts.create.callback/create-multiaccount-success (types/json->clj %) password]))))
;;;; Handlers
(defn create-multiaccount (defn create-multiaccount
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(if (:intro-wizard db) (if (:intro-wizard db)
(fx/merge (let [{:keys [selected-id key-code]} (:intro-wizard db)]
cofx (fx/merge
{:multiaccounts.create/create-multiaccount {:id (get-in db [:intro-wizard :selected-id]) cofx
:password (or (get-in db [:multiaccounts/create :password]) {:multiaccounts.create/create-multiaccount {:id selected-id
(get-in db [:intro-wizard :key-code]))}}) :password (get-in db [:multiaccounts/create :password] key-code)}}))
(fx/merge (fx/merge
cofx cofx
{:db (-> db {:db (-> db
@ -78,14 +81,9 @@
(fx/defn add-multiaccount (fx/defn add-multiaccount
"Takes db and new multiaccount, creates map of effects describing adding multiaccount to database and realm" "Takes db and new multiaccount, creates map of effects describing adding multiaccount to database and realm"
[cofx {:keys [address] :as multiaccount}] [cofx {:keys [address] :as multiaccount}]
(let [db (:db cofx) (let [db (:db cofx)]
{:networks/keys [networks]} db {:db (assoc-in db [:multiaccounts/multiaccounts address] multiaccount)
enriched-multiaccount (assoc multiaccount :data-store/base-tx [(multiaccounts-store/save-multiaccount-tx multiaccount)]}))
:network config/default-network
:networks networks
:address address)]
{:db (assoc-in db [:multiaccounts/multiaccounts address] enriched-multiaccount)
:data-store/base-tx [(multiaccounts-store/save-multiaccount-tx enriched-multiaccount)]}))
(defn reset-multiaccount-creation [{db :db}] (defn reset-multiaccount-creation [{db :db}]
{:db (update db :multiaccounts/create assoc {:db (update db :multiaccounts/create assoc
@ -173,7 +171,7 @@
(assoc-in [:intro-wizard :generating-keys?] true) (assoc-in [:intro-wizard :generating-keys?] true)
(assoc :node/on-ready :start-onboarding))} (assoc :node/on-ready :start-onboarding))}
(if node-started? (if node-started?
{:intro-wizard/start-onboarding {:n 5 :mnemonic-length 12}} {:intro-wizard/start-onboarding nil}
(node/initialize nil))))) (node/initialize nil)))))
(fx/defn on-confirm-failure [{:keys [db] :as cofx}] (fx/defn on-confirm-failure [{:keys [db] :as cofx}]
@ -224,40 +222,56 @@
:else {:db (assoc-in db [:intro-wizard :step] :else {:db (assoc-in db [:intro-wizard :step]
(inc-step step))}))) (inc-step step))})))
(defn prepare-default-account [{:keys [publicKey address]}]
{:public-key publicKey
:address address
:color colors/blue
:default? true
:name "Status account"})
(fx/defn on-multiaccount-created (fx/defn on-multiaccount-created
[{:keys [signing-phrase [{:keys [signing-phrase db] :as cofx}
status {:keys [keycard-instance-uid keycard-key-uid keycard-pairing keycard-paired-on mnemonic] :as multiaccount}
db] :as cofx}
{:keys [pubkey address mnemonic installation-id
keycard-instance-uid keycard-key-uid keycard-pairing keycard-paired-on] :as result}
password password
{:keys [seed-backed-up? login? new-multiaccount?] :or {login? true}}] {:keys [seed-backed-up? login?] :or {login? true}}]
(let [normalized-address (utils.hex/normalize-hex address) (let [{:keys [publicKey address]} (get-in multiaccount [:derived constants/path-whisper-keyword])
multiaccount {:public-key pubkey default-wallet-account (get-in multiaccount [:derived constants/path-default-wallet-keyword])
:installation-id (or installation-id (get-in db [:multiaccounts/new-installation-id])) {:networks/keys [networks]} db
:address normalized-address new-multiaccount {;;multiaccount
:name (gfycat/generate-gfy pubkey) :root-address (:address multiaccount)
:status status :public-key publicKey
:signed-up? true :installation-id (get-in db [:multiaccounts/new-installation-id]) ;;TODO why can't we generate it here?
:desktop-notifications? false :address address
:photo-path (identicon/identicon pubkey) :name (gfycat/generate-gfy publicKey)
:signing-phrase signing-phrase :photo-path (identicon/identicon publicKey)
:seed-backed-up? seed-backed-up? :network config/default-network
:mnemonic mnemonic :networks networks
:keycard-instance-uid keycard-instance-uid
:keycard-key-uid keycard-key-uid :accounts [(prepare-default-account
:keycard-pairing keycard-pairing (get-in multiaccount [:derived constants/path-default-wallet-keyword]))]
:keycard-paired-on keycard-paired-on
:settings (constants/default-multiaccount-settings) ;;multiaccount-settings
:syncing-on-mobile-network? false :signed-up? true ;; how account can be not signed?
:remember-syncing-choice? false :seed-backed-up? seed-backed-up?
:new-multiaccount? new-multiaccount?}] :desktop-notifications? false
(when-not (string/blank? pubkey) :signing-phrase signing-phrase
:mnemonic mnemonic
:settings (constants/default-multiaccount-settings)
:syncing-on-mobile-network? false
:remember-syncing-choice? false
;;keycard
:keycard-instance-uid keycard-instance-uid
:keycard-key-uid keycard-key-uid
:keycard-pairing keycard-pairing
:keycard-paired-on keycard-paired-on}]
(when-not (string/blank? publicKey)
(fx/merge cofx (fx/merge cofx
{:db (assoc db :multiaccounts/login {:address normalized-address {:db (assoc db :multiaccounts/login {:address address
:password password :main-account (:address default-wallet-account)
:processing true})} :password password
(add-multiaccount multiaccount) :processing true})}
(add-multiaccount new-multiaccount)
(when login? (when login?
(multiaccounts.login/user-login true)) (multiaccounts.login/user-login true))
(when (:intro-wizard db) (when (:intro-wizard db)
@ -265,9 +279,12 @@
(re-frame/reg-fx (re-frame/reg-fx
:intro-wizard/start-onboarding :intro-wizard/start-onboarding
(fn [{:keys [n mnemonic-length]}] (fn []
(status/start-onboarding n mnemonic-length (status/multiaccount-generate-and-derive-addresses
#(re-frame/dispatch [:intro-wizard/on-keys-generated (types/json->clj %)])))) 5
12
[constants/path-whisper constants/path-default-wallet]
#(re-frame/dispatch [:intro-wizard/on-keys-generated (types/json->clj %)]))))
(fx/defn on-keys-generated (fx/defn on-keys-generated
{:events [:intro-wizard/on-keys-generated]} {:events [:intro-wizard/on-keys-generated]}
@ -277,9 +294,9 @@
(fn [data] (fn [data]
(-> data (-> data
(dissoc :generating-keys?) (dissoc :generating-keys?)
(assoc :multiaccounts (:accounts result) (assoc :multiaccounts result
:selected-storage-type :default :selected-storage-type :default
:selected-id (-> result :accounts first :id) :selected-id (-> result first :id)
:step :choose-key))))} :step :choose-key))))}
(navigation/navigate-to-cofx :intro-wizard nil))) (navigation/navigate-to-cofx :intro-wizard nil)))
@ -320,15 +337,11 @@
:confirm-failure? false :confirm-failure? false
:weak-password? (< (count new-key-code) 6))})) :weak-password? (< (count new-key-code) 6))}))
;;;; COFX
(re-frame/reg-cofx (re-frame/reg-cofx
:multiaccounts.create/get-signing-phrase :multiaccounts.create/get-signing-phrase
(fn [cofx _] (fn [cofx _]
(get-signing-phrase cofx))) (get-signing-phrase cofx)))
;;;; FX
(re-frame/reg-fx (re-frame/reg-fx
:multiaccounts.create/create-multiaccount :multiaccounts.create/create-multiaccount
create-multiaccount!) create-multiaccount!)

View File

@ -11,6 +11,9 @@
(spec/def ::password (spec/and :global/not-empty-string valid-length?)) (spec/def ::password (spec/and :global/not-empty-string valid-length?))
(spec/def :multiaccount/root-address (spec/nilable string?))
(spec/def :multiaccount/accounts (spec/nilable vector?))
(spec/def :multiaccount/address :global/address) (spec/def :multiaccount/address :global/address)
(spec/def :multiaccount/name :global/not-empty-string) (spec/def :multiaccount/name :global/not-empty-string)
(spec/def :multiaccount/public-key :global/public-key) (spec/def :multiaccount/public-key :global/public-key)
@ -56,7 +59,9 @@
:multiaccount/keycard-instance-uid :multiaccount/keycard-instance-uid
:multiaccount/keycard-key-uid :multiaccount/keycard-key-uid
:multiaccount/keycard-pairing :multiaccount/keycard-pairing
:multiaccount/keycard-paired-on])) :multiaccount/keycard-paired-on
:multiaccount/root-address
:multiaccount/accounts]))
(spec/def :multiaccounts/multiaccounts (spec/nilable (spec/map-of :multiaccount/address :multiaccounts/multiaccount))) (spec/def :multiaccounts/multiaccounts (spec/nilable (spec/map-of :multiaccount/address :multiaccounts/multiaccount)))

View File

@ -24,7 +24,8 @@
[status-im.utils.types :as types] [status-im.utils.types :as types]
[status-im.utils.universal-links.core :as universal-links] [status-im.utils.universal-links.core :as universal-links]
[status-im.wallet.core :as wallet] [status-im.wallet.core :as wallet]
[taoensso.timbre :as log])) [taoensso.timbre :as log]
[status-im.ethereum.core :as ethereum]))
(def rpc-endpoint "https://goerli.infura.io/v3/f315575765b14720b32382a61a89341a") (def rpc-endpoint "https://goerli.infura.io/v3/f315575765b14720b32382a61a89341a")
(def contract-address "0xfbf4c8e2B41fAfF8c616a0E49Fb4365a5355Ffaf") (def contract-address "0xfbf4c8e2B41fAfF8c616a0E49Fb4365a5355Ffaf")
@ -46,8 +47,8 @@
(resolve default-nodes))))) (resolve default-nodes)))))
(resolve default-nodes)))) (resolve default-nodes))))
(defn login! [address password] (defn login! [address main-account password]
(status/login address password #(re-frame/dispatch [:multiaccounts.login.callback/login-success %]))) (status/login address password main-account [] #(re-frame/dispatch [:multiaccounts.login.callback/login-success %])))
(defn verify! [address password realm-error] (defn verify! [address password realm-error]
(status/verify address password (status/verify address password
@ -81,8 +82,8 @@
(get-in [:db :hardwallet :multiaccount]) (get-in [:db :hardwallet :multiaccount])
(select-keys [:whisper-private-key :encryption-public-key]) (select-keys [:whisper-private-key :encryption-public-key])
(assoc :on-result #(re-frame/dispatch [:multiaccounts.login.callback/login-success %])))} (assoc :on-result #(re-frame/dispatch [:multiaccounts.login.callback/login-success %])))}
(let [{:keys [address password]} (multiaccounts.model/credentials cofx)] (let [{:keys [address password main-account]} (get-in cofx [:db :multiaccounts/login])]
{:multiaccounts.login/login [address password]}))) {:multiaccounts.login/login [address main-account password]})))
(fx/defn initialize-wallet [cofx] (fx/defn initialize-wallet [cofx]
(fx/merge cofx (fx/merge cofx
@ -336,13 +337,14 @@
:keychain/get-user-password [address :keychain/get-user-password [address
#(re-frame/dispatch [:multiaccounts.login.callback/get-user-password-success % address])]}) #(re-frame/dispatch [:multiaccounts.login.callback/get-user-password-success % address])]})
(fx/defn open-login [{:keys [db] :as cofx} address photo-path name public-key] (fx/defn open-login [{:keys [db] :as cofx} address photo-path name public-key accounts]
(let [keycard-multiaccount? (get-in db [:multiaccounts/multiaccounts address :keycard-instance-uid])] (let [keycard-multiaccount? (get-in db [:multiaccounts/multiaccounts address :keycard-instance-uid])]
(fx/merge cofx (fx/merge cofx
{:db (-> db {:db (-> db
(update :multiaccounts/login assoc (update :multiaccounts/login assoc
:public-key public-key :public-key public-key
:address address :address address
:main-account (:address (ethereum/get-default-account accounts))
:photo-path photo-path :photo-path photo-path
:name name) :name name)
(update :multiaccounts/login dissoc (update :multiaccounts/login dissoc
@ -375,8 +377,8 @@
(re-frame/reg-fx (re-frame/reg-fx
:multiaccounts.login/login :multiaccounts.login/login
(fn [[address password]] (fn [[address main-account password]]
(login! address (security/safe-unmask-data password)))) (login! address main-account (security/safe-unmask-data password))))
(re-frame/reg-fx (re-frame/reg-fx
:multiaccounts.login/verify :multiaccounts.login/verify

View File

@ -11,7 +11,8 @@
[status-im.utils.fx :as fx] [status-im.utils.fx :as fx]
[status-im.utils.identicon :as identicon] [status-im.utils.identicon :as identicon]
[status-im.utils.security :as security] [status-im.utils.security :as security]
[status-im.utils.types :as types])) [status-im.utils.types :as types]
[status-im.constants :as constants]))
(defn check-password-errors [password] (defn check-password-errors [password]
(cond (string/blank? password) :required-field (cond (string/blank? password) :required-field
@ -65,7 +66,7 @@
{:db (assoc-in db [:multiaccounts/recover :password-error] (check-password-errors password))})) {:db (assoc-in db [:multiaccounts/recover :password-error] (check-password-errors password))}))
(fx/defn validate-recover-result (fx/defn validate-recover-result
[{:keys [db] :as cofx} {:keys [error pubkey address]} password] [{:keys [db] :as cofx} {:keys [error pubkey address walletAddress walletPubKey chatAddress chatPubKey]} password]
(if (empty? error) (if (empty? error)
(let [multiaccount-address (-> address (let [multiaccount-address (-> address
(string/lower-case) (string/lower-case)
@ -80,9 +81,11 @@
(update :multiaccounts/recover dissoc (update :multiaccounts/recover dissoc
:passphrase-valid?)) :passphrase-valid?))
:node/stop nil} :node/stop nil}
(let [multiaccount {:pubkey pubkey (let [multiaccount {:derived {constants/path-whisper-keyword {:publicKey chatPubKey
:address chatAddress}
constants/path-default-wallet-keyword {:publicKey walletPubKey
:address walletAddress}}
:address address :address address
:photo-path (identicon/identicon pubkey)
:mnemonic ""}] :mnemonic ""}]
(multiaccounts.create/on-multiaccount-created (multiaccounts.create/on-multiaccount-created
cofx multiaccount password {:seed-backed-up? true})))) cofx multiaccount password {:seed-backed-up? true}))))

View File

@ -22,14 +22,14 @@
(defn recover-multiaccount [passphrase password callback] (defn recover-multiaccount [passphrase password callback]
(native-module/recover-account passphrase password callback)) (native-module/recover-account passphrase password callback))
(defn start-onboarding [n mnemonic-length callback] (defn multiaccount-store-derived [account-id paths password callback]
(native-module/start-onboarding n mnemonic-length callback)) (native-module/multiaccount-store-derived account-id paths password callback))
(defn import-onboarding-multiaccount [id password callback] (defn multiaccount-generate-and-derive-addresses [n mnemonic-length paths callback]
(native-module/import-onboarding-multiaccount id password callback)) (native-module/multiaccount-generate-and-derive-addresses n mnemonic-length paths callback))
(defn login [address password callback] (defn login [address password main-account watch-addresses callback]
(native-module/login address password callback)) (native-module/login address password main-account watch-addresses callback))
(defn verify [address password callback] (defn verify [address password callback]
(native-module/verify address password callback)) (native-module/verify address password callback))
@ -55,8 +55,8 @@
(defn sign-message [rpcParams callback] (defn sign-message [rpcParams callback]
(native-module/sign-message rpcParams callback)) (native-module/sign-message rpcParams callback))
(defn sign-typed-data [data password callback] (defn sign-typed-data [data account password callback]
(native-module/sign-typed-data data password callback)) (native-module/sign-typed-data data account password callback))
(defn send-transaction [rpcParams password callback] (defn send-transaction [rpcParams password callback]
(native-module/send-transaction rpcParams password callback)) (native-module/send-transaction rpcParams password callback))

View File

@ -3,7 +3,8 @@
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[status-im.react-native.js-dependencies :as rn-dependencies] [status-im.react-native.js-dependencies :as rn-dependencies]
[clojure.string :as string] [clojure.string :as string]
[status-im.utils.platform :as platform])) [status-im.utils.platform :as platform]
[status-im.utils.types :as types]))
(defn status [] (defn status []
(when (exists? (.-NativeModules rn-dependencies/react-native)) (when (exists? (.-NativeModules rn-dependencies/react-native))
@ -61,17 +62,30 @@
(when (and @node-started (status)) (when (and @node-started (status))
(.recoverAccount (status) passphrase password on-result))) (.recoverAccount (status) passphrase password on-result)))
(defn start-onboarding [n mnemonic-length on-result] (defn multiaccount-generate-and-derive-addresses [n mnemonic-length paths on-result]
(when (and @node-started (status)) (when (and @node-started (status))
(.startOnboarding (status) n mnemonic-length on-result))) (.multiAccountGenerateAndDeriveAddresses (status)
(types/clj->json {:n n
:mnemonicPhraseLength mnemonic-length
:bip39Passphrase ""
:paths paths})
on-result)))
(defn import-onboarding-multiaccount [id password on-result] (defn multiaccount-store-derived [account-id paths password on-result]
(when (and @node-started (status)) (when (and @node-started (status))
(.importOnboardingAccount (status) id password on-result))) (.multiAccountStoreDerived (status)
(types/clj->json {:accountID account-id
:paths paths
:password password})
(defn login [address password on-result] on-result)))
(defn login [address password main-account watch-addresses on-result]
(when (and @node-started (status)) (when (and @node-started (status))
(.login (status) address password on-result))) (.login (status)
(types/clj->json {:chatAddress address :password password
:mainAccount main-account :watch-addresses watch-addresses})
on-result)))
(defn verify [address password on-result] (defn verify [address password on-result]
(when (and @node-started (status)) (when (and @node-started (status))
@ -114,9 +128,9 @@
(when (and @node-started (status)) (when (and @node-started (status))
(.hashTypedData (status) data callback))) (.hashTypedData (status) data callback)))
(defn sign-typed-data [data password callback] (defn sign-typed-data [data account password callback]
(when (and @node-started (status)) (when (and @node-started (status))
(.signTypedData (status) data password callback))) (.signTypedData (status) data account password callback)))
(defn send-transaction [rpcParams password callback] (defn send-transaction [rpcParams password callback]
(when (and @node-started (status)) (when (and @node-started (status))

View File

@ -134,7 +134,8 @@
:DisableGenericDiscoveryTopic (boolean disable-discovery-topic?) :DisableGenericDiscoveryTopic (boolean disable-discovery-topic?)
:SendV1Messages (boolean v1-messages?) :SendV1Messages (boolean v1-messages?)
:PFSEnabled true} :PFSEnabled true}
:RequireTopics (get-topics network)) :RequireTopics (get-topics network)
:StatusAccountsConfig {:Enabled true})
(and (and
config/bootnodes-settings-enabled? config/bootnodes-settings-enabled?

View File

@ -47,7 +47,7 @@
(hardwallet/create-keycard-multiaccount) (hardwallet/create-keycard-multiaccount)
:start-onboarding :start-onboarding
(fn [] (fn []
{:intro-wizard/start-onboarding {:n 5 :mnemonic-length 12}}))))) {:intro-wizard/start-onboarding nil})))))
(fx/defn status-node-stopped (fx/defn status-node-stopped
[{db :db}] [{db :db}]

View File

@ -40,8 +40,8 @@
(re-frame/reg-fx (re-frame/reg-fx
:signing.fx/sign-typed-data :signing.fx/sign-typed-data
(fn [{:keys [data on-completed password]}] (fn [{:keys [data account on-completed password]}]
(status/sign-typed-data data (security/safe-unmask-data password) on-completed))) (status/sign-typed-data data account (security/safe-unmask-data password) on-completed)))
(defn get-contact [db to] (defn get-contact [db to]
(let [to (utils.hex/normalize-hex to)] (let [to (utils.hex/normalize-hex to)]
@ -62,12 +62,13 @@
[{{:signing/keys [sign tx] :as db} :db}] [{{:signing/keys [sign tx] :as db} :db}]
(let [{{:keys [data typed?]} :message} tx (let [{{:keys [data typed?]} :message} tx
{:keys [in-progress? password]} sign {:keys [in-progress? password]} sign
from (ethereum/current-address db)] from (ethereum/default-address db)]
(when-not in-progress? (when-not in-progress?
(merge (merge
{:db (update db :signing/sign assoc :error nil :in-progress? true)} {:db (update db :signing/sign assoc :error nil :in-progress? true)}
(if typed? (if typed?
{:signing.fx/sign-typed-data {:data data {:signing.fx/sign-typed-data {:data data
:account from
:password password :password password
:on-completed #(re-frame/dispatch [:signing/sign-message-completed %])}} :on-completed #(re-frame/dispatch [:signing/sign-message-completed %])}}
{:signing.fx/sign-message {:params {:data data {:signing.fx/sign-message {:params {:data data
@ -83,7 +84,6 @@
(if message (if message
(sign-message cofx) (sign-message cofx)
(let [tx-obj-to-send (merge tx-obj (let [tx-obj-to-send (merge tx-obj
{:from (ethereum/current-address db)}
(when gas (when gas
{:gas (str "0x" (abi-spec/number-to-hex gas))}) {:gas (str "0x" (abi-spec/number-to-hex gas))})
(when gasPrice (when gasPrice
@ -255,7 +255,7 @@
(defn normalize-tx-obj [db tx] (defn normalize-tx-obj [db tx]
(if (get-in tx [:tx-obj :from]) (if (get-in tx [:tx-obj :from])
tx tx
(assoc-in tx [:tx-obj :from] (ethereum/current-address db)))) (assoc-in tx [:tx-obj :from] (ethereum/default-address db))))
(fx/defn sign [{:keys [db] :as cofx} tx] (fx/defn sign [{:keys [db] :as cofx} tx]
"Signing transaction or message, shows signing sheet "Signing transaction or message, shows signing sheet

View File

@ -139,14 +139,14 @@
[{:keys [db]}] [{:keys [db]}]
(let [contract (contracts/get-address db :status/stickers) (let [contract (contracts/get-address db :status/stickers)
pack-contract (contracts/get-address db :status/sticker-pack) pack-contract (contracts/get-address db :status/sticker-pack)
address (ethereum/current-address db)] address (ethereum/default-address db)]
(when contract (when contract
{:stickers/owned-packs-fx [pack-contract address] {:stickers/owned-packs-fx [pack-contract address]
:stickers/load-packs-fx [contract]}))) :stickers/load-packs-fx [contract]})))
(fx/defn approve-pack (fx/defn approve-pack
[{db :db :as cofx} pack-id price] [{db :db :as cofx} pack-id price]
(let [address (ethereum/current-address db) (let [address (ethereum/default-address db)
sticker-market-contract (contracts/get-address db :status/sticker-market) sticker-market-contract (contracts/get-address db :status/sticker-market)
snt-contract (contracts/get-address db :status/snt)] snt-contract (contracts/get-address db :status/snt)]
(signing/eth-transaction-call (signing/eth-transaction-call
@ -161,7 +161,7 @@
(fx/defn pending-pack (fx/defn pending-pack
[{:keys [db] :as cofx} id] [{:keys [db] :as cofx} id]
(let [contract (contracts/get-address db :status/sticker-pack) (let [contract (contracts/get-address db :status/sticker-pack)
address (ethereum/current-address db)] address (ethereum/default-address db)]
(when contract (when contract
(fx/merge cofx (fx/merge cofx
{:db (update db :stickers/packs-pending conj id) {:db (update db :stickers/packs-pending conj id)
@ -173,7 +173,7 @@
[{{:stickers/keys [packs-pending packs-owned] :as db} :db}] [{{:stickers/keys [packs-pending packs-owned] :as db} :db}]
(let [packs-diff (clojure.set/difference packs-pending packs-owned) (let [packs-diff (clojure.set/difference packs-pending packs-owned)
contract (contracts/get-address db :status/sticker-pack) contract (contracts/get-address db :status/sticker-pack)
address (ethereum/current-address db)] address (ethereum/default-address db)]
(when contract (when contract
(merge {:db (assoc db :stickers/packs-pending packs-diff)} (merge {:db (assoc db :stickers/packs-pending packs-diff)}
(when-not (zero? (count packs-diff)) (when-not (zero? (count packs-diff))
@ -186,6 +186,6 @@
(fx/defn get-owned-pack (fx/defn get-owned-pack
[{:keys [db]}] [{:keys [db]}]
(let [contract (contracts/get-address db :status/sticker-pack) (let [contract (contracts/get-address db :status/sticker-pack)
address (ethereum/current-address db)] address (ethereum/default-address db)]
(when contract (when contract
{:stickers/owned-packs-fx [contract address]}))) {:stickers/owned-packs-fx [contract address]})))

View File

@ -331,10 +331,10 @@
public-key)) public-key))
(re-frame/reg-sub (re-frame/reg-sub
:account/hex-address :multiaccount/default-address
:<- [:multiaccount] :<- [:multiaccount]
(fn [{:keys [address]}] (fn [{:keys [accounts]}]
(ethereum/normalized-address address))) (:address (ethereum/get-default-account accounts))))
(re-frame/reg-sub (re-frame/reg-sub
:sign-in-enabled? :sign-in-enabled?
@ -1877,12 +1877,12 @@
:<- [:ens/registration] :<- [:ens/registration]
:<- [:ens.stateofus/registrar] :<- [:ens.stateofus/registrar]
:<- [:multiaccount] :<- [:multiaccount]
(fn [[{:keys [custom-domain? username-candidate] :as ens} registrar {:keys [address public-key]}] _] (fn [[{:keys [custom-domain? username-candidate] :as ens} registrar {:keys [accounts public-key]}] _]
{:state (or (get-in ens [:states username-candidate]) :initial) {:state (or (get-in ens [:states username-candidate]) :initial)
:username username-candidate :username username-candidate
:custom-domain? (or custom-domain? false) :custom-domain? (or custom-domain? false)
:contract registrar :contract registrar
:address address :address (:address (ethereum/get-default-account accounts))
:public-key public-key})) :public-key public-key}))
(re-frame/reg-sub (re-frame/reg-sub

View File

@ -12,7 +12,7 @@
(clj->js (merge {:inverted true} props)))) (clj->js (merge {:inverted true} props))))
(defn qr-code-view [size value] (defn qr-code-view [size value]
(when size (when (and size value)
[react/view {:style (styles/qr-code-container size) [react/view {:style (styles/qr-code-container size)
:accessibility-label :qr-code-image} :accessibility-label :qr-code-image}
[qr-code {:value value [qr-code {:value value

View File

@ -137,9 +137,7 @@
:injected-on-start-loading-java-script (str (when-not opt-in? (js-res/web3)) :injected-on-start-loading-java-script (str (when-not opt-in? (js-res/web3))
(if opt-in? (if opt-in?
(js-res/web3-opt-in-init (str network-id)) (js-res/web3-opt-in-init (str network-id))
(js-res/web3-init (js-res/web3-init address (str network-id)))
(ethereum/normalized-address address)
(str network-id)))
(get-inject-js url)) (get-inject-js url))
:injected-java-script (js-res/webview-js)}])] :injected-java-script (js-res/webview-js)}])]
[navigation browser-id url-original webview can-go-back? can-go-forward?] [navigation browser-id url-original webview can-go-back? can-go-forward?]
@ -154,7 +152,7 @@
(views/defview browser [] (views/defview browser []
(views/letsubs [webview (atom nil) (views/letsubs [webview (atom nil)
window-width [:dimensions/window-width] window-width [:dimensions/window-width]
{:keys [address settings]} [:multiaccount] {:keys [accounts settings]} [:multiaccount]
{:keys [browser-id dapp? name unsafe?] :as browser} [:get-current-browser] {:keys [browser-id dapp? name unsafe?] :as browser} [:get-current-browser]
{:keys [url error? loading? url-editing? show-tooltip show-permission resolving?]} [:browser/options] {:keys [url error? loading? url-editing? show-tooltip show-permission resolving?]} [:browser/options]
network-id [:get-network-id]] network-id [:get-network-id]]
@ -180,7 +178,7 @@
:can-go-forward? can-go-forward? :can-go-forward? can-go-forward?
:resolving? resolving? :resolving? resolving?
:network-id network-id :network-id network-id
:address address :address (:address (ethereum/get-default-account accounts))
:show-permission show-permission :show-permission show-permission
:show-tooltip show-tooltip :show-tooltip show-tooltip
:opt-in? opt-in? :opt-in? opt-in?

View File

@ -18,7 +18,8 @@
[status-im.ui.screens.intro.styles :as styles] [status-im.ui.screens.intro.styles :as styles]
[status-im.ui.components.toolbar.view :as toolbar] [status-im.ui.components.toolbar.view :as toolbar]
[status-im.i18n :as i18n] [status-im.i18n :as i18n]
[status-im.ui.components.status-bar.view :as status-bar])) [status-im.ui.components.status-bar.view :as status-bar]
[status-im.constants :as constants]))
(defn dots-selector [{:keys [on-press n selected color]}] (defn dots-selector [{:keys [on-press n selected color]}]
[react/view {:style (styles/dot-selector n)} [react/view {:style (styles/dot-selector n)}
@ -105,13 +106,14 @@
-20 -20
(/ view-height 12))}} (/ view-height 12))}}
(for [acc multiaccounts] (for [acc multiaccounts]
(let [selected? (= (:id acc) selected-id)] (let [selected? (= (:id acc) selected-id)
^{:key (:pubkey acc)} public-key (get-in acc [:derived constants/path-whisper-keyword :publicKey])]
^{:key public-key}
[react/touchable-highlight [react/touchable-highlight
{:on-press #(re-frame/dispatch [:intro-wizard/on-key-selected (:id acc)])} {:on-press #(re-frame/dispatch [:intro-wizard/on-key-selected (:id acc)])}
[react/view {:style (styles/list-item selected?)} [react/view {:style (styles/list-item selected?)}
[react/image {:source {:uri (identicon/identicon (:pubkey acc))} [react/image {:source {:uri (identicon/identicon public-key)}
:style styles/multiaccount-image}] :style styles/multiaccount-image}]
[react/view {:style {:margin-horizontal 16 :flex 1 :justify-content :space-between}} [react/view {:style {:margin-horizontal 16 :flex 1 :justify-content :space-between}}
[react/text {:style (assoc styles/wizard-text :text-align :left [react/text {:style (assoc styles/wizard-text :text-align :left
@ -119,11 +121,11 @@
:font-weight "500") :font-weight "500")
:number-of-lines 1 :number-of-lines 1
:ellipsize-mode :middle} :ellipsize-mode :middle}
(gfy/generate-gfy (:pubkey acc))] (gfy/generate-gfy public-key)]
[react/text {:style (assoc styles/wizard-text [react/text {:style (assoc styles/wizard-text
:text-align :left :text-align :left
:font-family "monospace")} :font-family "monospace")}
(utils/get-shortened-address (:pubkey acc))]] (utils/get-shortened-address public-key)]]
[radio/radio selected?]]]))]) [radio/radio selected?]]]))])
(defn storage-entry [{:keys [type icon title desc]} selected-storage-type] (defn storage-entry [{:keys [type icon title desc]} selected-storage-type]

View File

@ -15,8 +15,8 @@
[status-im.ui.components.toolbar.view :as toolbar] [status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.screens.privacy-policy.views :as privacy-policy])) [status-im.ui.screens.privacy-policy.views :as privacy-policy]))
(defn multiaccount-view [{:keys [address photo-path name public-key keycard-instance-uid]}] (defn multiaccount-view [{:keys [address photo-path name public-key keycard-instance-uid accounts]}]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:multiaccounts.login.ui/multiaccount-selected address photo-path name public-key])} [react/touchable-highlight {:on-press #(re-frame/dispatch [:multiaccounts.login.ui/multiaccount-selected address photo-path name public-key accounts])}
[react/view styles/multiaccount-view [react/view styles/multiaccount-view
[photos/photo photo-path {:size styles/multiaccount-image-size}] [photos/photo photo-path {:size styles/multiaccount-image-size}]
[react/view styles/multiaccount-badge-text-view [react/view styles/multiaccount-badge-text-view

View File

@ -38,11 +38,10 @@
[icons/icon icon {:color colors/white}] [icons/icon icon {:color colors/white}]
[react/text {:style {:margin-left 8 :color colors/white}} label]]]]) [react/text {:style {:margin-left 8 :color colors/white}} label]]]])
(views/defview account-card [] (views/defview account-card [{:keys [address]}]
(views/letsubs [currency [:wallet/currency] (views/letsubs [currency [:wallet/currency]
portfolio-value [:portfolio-value] portfolio-value [:portfolio-value]
window-width [:dimensions/window-width] window-width [:dimensions/window-width]]
{:keys [address]} [:multiaccount]]
[react/view {:style (styles/card window-width)} [react/view {:style (styles/card window-width)}
[react/view {:padding 16 :padding-bottom 12 :flex 1 :justify-content :space-between} [react/view {:padding 16 :padding-bottom 12 :flex 1 :justify-content :space-between}
[react/nested-text {:style {:color colors/white-transparent :line-height 38 [react/nested-text {:style {:color colors/white-transparent :line-height 38
@ -58,14 +57,14 @@
:color (colors/alpha colors/white 0.7)}} :color (colors/alpha colors/white 0.7)}}
(ethereum/normalized-address address)]] (ethereum/normalized-address address)]]
[react/view {:position :absolute :top 12 :right 12} [react/view {:position :absolute :top 12 :right 12}
[react/touchable-highlight {:on-press #(re-frame/dispatch [:show-popover {:view :share-account}])} [react/touchable-highlight {:on-press #(re-frame/dispatch [:show-popover {:view :share-account :address address}])}
[icons/icon :main-icons/share {:color colors/white [icons/icon :main-icons/share {:color colors/white
:accessibility-label :share-wallet-address-icon}]]] :accessibility-label :share-wallet-address-icon}]]]
[react/view {:height 52 :background-color (colors/alpha colors/black 0.2) [react/view {:height 52 :background-color (colors/alpha colors/black 0.2)
:border-bottom-right-radius 8 :border-bottom-left-radius 8 :flex-direction :row} :border-bottom-right-radius 8 :border-bottom-left-radius 8 :flex-direction :row}
[button (i18n/label :t/wallet-send) :main-icons/send #(re-frame/dispatch [:navigate-to :wallet-send-transaction])] [button (i18n/label :t/wallet-send) :main-icons/send #(re-frame/dispatch [:navigate-to :wallet-send-transaction address])]
[react/view {:style styles/divider}] [react/view {:style styles/divider}]
[button (i18n/label :t/receive) :main-icons/receive #(re-frame/dispatch [:show-popover {:view :share-account}])]]])) [button (i18n/label :t/receive) :main-icons/receive #(re-frame/dispatch [:show-popover {:view :share-account :address address}])]]]))
(views/defview transactions [] (views/defview transactions []
(views/letsubs [{:keys [transaction-history-sections]} (views/letsubs [{:keys [transaction-history-sections]}
@ -102,12 +101,13 @@
(= tab :history) (= tab :history)
[transactions])]))) [transactions])])))
(defn account [] (views/defview account []
[react/view {:flex 1 :background-color colors/white} (views/letsubs [{:keys [name] :as account} [:get-screen-params]]
[toolbar-view "Status account"] [react/view {:flex 1 :background-color colors/white}
[react/scroll-view [toolbar-view name]
[react/view {:padding-left 16} [react/scroll-view
[react/scroll-view {:horizontal true} [react/view {:padding-left 16}
[react/view {:flex-direction :row :padding-top 8 :padding-bottom 12} [react/scroll-view {:horizontal true}
[account-card]]]] [react/view {:flex-direction :row :padding-top 8 :padding-bottom 12}
[assets-and-collections]]]) [account-card account]]]]
[assets-and-collections]]]))

View File

@ -35,29 +35,29 @@
:accessibility-label :wallet-backup-recovery-title :accessibility-label :wallet-backup-recovery-title
:on-press #(hide-sheet-and-dispatch [:navigate-to :backup-seed])}])])) :on-press #(hide-sheet-and-dispatch [:navigate-to :backup-seed])}])]))
(defn send-receive [] (defn send-receive [address]
[react/view [react/view
[action-button/action-button {:label (i18n/label :t/wallet-send) [action-button/action-button {:label (i18n/label :t/wallet-send)
:icon :main-icons/send :icon :main-icons/send
:accessibility-label :send-transaction-button :accessibility-label :send-transaction-button
:icon-opts {:color :blue} :icon-opts {:color :blue}
:on-press #(hide-sheet-and-dispatch [:navigate-to :wallet-send-transaction])}] :on-press #(hide-sheet-and-dispatch [:navigate-to :wallet-send-transaction address])}]
[action-button/action-button {:label (i18n/label :t/receive) [action-button/action-button {:label (i18n/label :t/receive)
:icon :main-icons/receive :icon :main-icons/receive
:accessibility-label :receive-transaction-button :accessibility-label :receive-transaction-button
:icon-opts {:color :blue} :icon-opts {:color :blue}
:on-press #(hide-sheet-and-dispatch [:show-popover {:view :share-account}])}]]) :on-press #(hide-sheet-and-dispatch [:show-popover {:view :share-account :address address}])}]])
(defn add-account [] (defn add-account []
[react/view [react/view
[action-button/action-button-disabled {:label (i18n/label :t/add-an-account) [action-button/action-button-disabled {:label (i18n/label :t/add-an-account)
:icon :main-icons/add :icon :main-icons/add
:icon-opts {:color :blue} :icon-opts {:color :blue}
:on-press #(hide-sheet-and-dispatch [:navigate-to :wallet-send-transaction])}] :on-press #(hide-sheet-and-dispatch [:navigate-to])}]
[action-button/action-button-disabled {:label (i18n/label :t/add-a-watch-account) [action-button/action-button-disabled {:label (i18n/label :t/add-a-watch-account)
:icon :main-icons/watch :icon :main-icons/watch
:icon-opts {:color :blue} :icon-opts {:color :blue}
:on-press #(hide-sheet-and-dispatch [:navigate-to :wallet-request-transaction])}]]) :on-press #(hide-sheet-and-dispatch [:navigate-to])}]])
(defn account-settings [] (defn account-settings []
[react/view [react/view

View File

@ -1,10 +1,10 @@
(ns status-im.ui.screens.wallet.accounts.styles (ns status-im.ui.screens.wallet.accounts.styles
(:require [status-im.ui.components.colors :as colors])) (:require [status-im.ui.components.colors :as colors]))
(def card (defn card [color]
{:width 156 {:width 156
:height 145 :height 145
:background-color colors/blue :background-color color
:shadow-offset {:width 0 :height 2} :shadow-offset {:width 0 :height 2}
:shadow-radius 8 :shadow-radius 8
:shadow-opacity 1 :shadow-opacity 1

View File

@ -23,22 +23,21 @@
(defn total-tilde [value] (defn total-tilde [value]
(when (and (not= "0" value) (not= "..." value)) "~")) (when (and (not= "0" value) (not= "..." value)) "~"))
(views/defview account-card [name] (views/defview account-card [{:keys [name color address] :as account}]
(views/letsubs [currency [:wallet/currency] (views/letsubs [currency [:wallet/currency]
portfolio-value [:portfolio-value] portfolio-value [:portfolio-value]]
{:keys [address]} [:multiaccount]] [react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :wallet-account account])
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :wallet-account])
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet :on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet
{:content sheets/send-receive {:content (fn [] [sheets/send-receive address])
:content-height 130}])} :content-height 130}])}
[react/view {:style styles/card} [react/view {:style (styles/card color)}
[react/view {:flex-direction :row :align-items :center :justify-content :space-between} [react/view {:flex-direction :row :align-items :center :justify-content :space-between}
[react/nested-text {:style {:color colors/white-transparent :font-weight "500"}} [react/nested-text {:style {:color colors/white-transparent :font-weight "500"}}
(total-tilde portfolio-value) (total-tilde portfolio-value)
[{:style {:color colors/white}} portfolio-value] [{:style {:color colors/white}} portfolio-value]
" " " "
(:code currency)] (:code currency)]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:show-popover {:view :share-account}])} [react/touchable-highlight {:on-press #(re-frame/dispatch [:show-popover {:view :share-account :address address}])}
[icons/icon :main-icons/share {:color colors/white}]]] [icons/icon :main-icons/share {:color colors/white}]]]
[react/view [react/view
[react/text {:style {:color colors/white :font-weight "500" :line-height 22}} name] [react/text {:style {:color colors/white :font-weight "500" :line-height 22}} name]
@ -46,7 +45,7 @@
:style {:line-height 22 :font-size 13 :style {:line-height 22 :font-size 13
:font-family "monospace" :font-family "monospace"
:color (colors/alpha colors/white 0.7)}} :color (colors/alpha colors/white 0.7)}}
(ethereum/normalized-address address)]]]])) address]]]]))
(defn add-card [] (defn add-card []
[react/touchable-highlight {:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet [react/touchable-highlight {:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet
@ -154,6 +153,15 @@
:justify-content :center} :justify-content :center}
[icons/icon :main-icons/more {:accessibility-label :accounts-more-options}]]]])) [icons/icon :main-icons/more {:accessibility-label :accounts-more-options}]]]]))
(views/defview accounts []
(views/letsubs [{:keys [accounts]} [:multiaccount]]
[react/scroll-view {:horizontal true}
[react/view {:flex-direction :row :padding-top 11 :padding-bottom 12}
(for [account accounts]
^{:key account}
[account-card account])
[add-card]]]))
(defn accounts-overview [] (defn accounts-overview []
[react/view {:flex 1} [react/view {:flex 1}
[status-bar/status-bar] [status-bar/status-bar]
@ -161,8 +169,5 @@
[accounts-options] [accounts-options]
[react/view {:margin-top 8 :padding-horizontal 16} [react/view {:margin-top 8 :padding-horizontal 16}
[total-value] [total-value]
[react/scroll-view {:horizontal true} [accounts]]
[react/view {:flex-direction :row :padding-top 11 :padding-bottom 12}
[account-card "Status account"]
[add-card]]]]
[assets-and-collections]]]) [assets-and-collections]]])

View File

@ -3,8 +3,9 @@
[status-im.ui.screens.navigation :as navigation] [status-im.ui.screens.navigation :as navigation]
[status-im.ui.screens.wallet.signing-phrase.views :as signing-phrase])) [status-im.ui.screens.wallet.signing-phrase.views :as signing-phrase]))
(def transaction-send-default (defn transaction-send-default [address]
{:method constants/web3-send-transaction {:method constants/web3-send-transaction
:from address
:symbol :ETH}) :symbol :ETH})
(defmethod navigation/preload-data! :wallet-stack (defmethod navigation/preload-data! :wallet-stack
@ -15,18 +16,18 @@
(assoc db :popover/popover {:view [signing-phrase/signing-phrase]})))) (assoc db :popover/popover {:view [signing-phrase/signing-phrase]}))))
(defmethod navigation/preload-data! :wallet-send-transaction-request (defmethod navigation/preload-data! :wallet-send-transaction-request
[db [event]] [db [event _ address]]
(if (= event :navigate-back) (if (= event :navigate-back)
db db
(-> db (-> db
(assoc-in [:wallet :request-transaction] {:symbol :ETH}) (assoc-in [:wallet :request-transaction] {:symbol :ETH})
(assoc-in [:wallet :send-transaction] transaction-send-default)))) (assoc-in [:wallet :send-transaction] (transaction-send-default address)))))
(defmethod navigation/preload-data! :wallet-send-transaction (defmethod navigation/preload-data! :wallet-send-transaction
[db [event]] [db [event _ address]]
(if (= event :navigate-back) (if (= event :navigate-back)
db db
(assoc-in db [:wallet :send-transaction] transaction-send-default))) (assoc-in db [:wallet :send-transaction] (transaction-send-default address))))
(defmethod navigation/preload-data! :wallet-add-custom-token (defmethod navigation/preload-data! :wallet-add-custom-token
[db [event]] [db [event]]

View File

@ -63,13 +63,13 @@
[vector-icons/icon :main-icons/next {:color :white}]]]]]))) [vector-icons/icon :main-icons/next {:color :white}]]]]])))
(views/defview share-address [] (views/defview share-address []
(views/letsubs [address-hex [:account/hex-address] (views/letsubs [{:keys [address]} [:popover/popover]
chain-id [:get-network-id] chain-id [:get-network-id]
width (reagent/atom nil)] width (reagent/atom nil)]
[react/view [react/view
[react/view {:style {:padding-top 16 :padding-left 16 :padding-right 16}} [react/view {:style {:padding-top 16 :padding-left 16 :padding-right 16}}
(when @width (when @width
[qr-code-viewer/qr-code-view (- @width 32) (eip681/generate-uri address-hex {:chain-id chain-id})]) [qr-code-viewer/qr-code-view (- @width 32) (eip681/generate-uri address {:chain-id chain-id})])
[react/text {:style {:font-size 13 :color colors/gray :margin-top 12 :margin-bottom 4}} [react/text {:style {:font-size 13 :color colors/gray :margin-top 12 :margin-bottom 4}}
(i18n/label :t/ens-wallet-address)] (i18n/label :t/ens-wallet-address)]
[react/view {:on-layout #(reset! width (-> % .-nativeEvent .-layout .-width))} [react/view {:on-layout #(reset! width (-> % .-nativeEvent .-layout .-width))}
@ -77,7 +77,7 @@
:accessibility-label :address-text :accessibility-label :address-text
:style {:line-height 22 :font-size 15 :style {:line-height 22 :font-size 15
:font-family "monospace"}} :font-family "monospace"}}
(eip55/address->checksum address-hex)]]] (eip55/address->checksum address)]]]
[react/view {:height 1 :background-color colors/gray-lighter :margin-top 8}] [react/view {:height 1 :background-color colors/gray-lighter :margin-top 8}]
[react/view {:padding-bottom 16} [react/view {:padding-bottom 16}
[components.common/button {:on-press #(re-frame/dispatch [:wallet.accounts/share]) [components.common/button {:on-press #(re-frame/dispatch [:wallet.accounts/share])
@ -87,7 +87,7 @@
;;TODO temporary hide for v1 ;;TODO temporary hide for v1
#_[components.common/button {:on-press #(do #_[components.common/button {:on-press #(do
(re-frame/dispatch [:hide-popover]) (re-frame/dispatch [:hide-popover])
(re-frame/dispatch [:navigate-to :wallet-send-transaction-request])) (re-frame/dispatch [:navigate-to :wallet-send-transaction-request address]))
:accessibility-label :sent-transaction-request-button :accessibility-label :sent-transaction-request-button
:label (i18n/label :t/send-transaction-request) :label (i18n/label :t/send-transaction-request)
:background? false}]]])) :background? false}]]]))

View File

@ -14,4 +14,4 @@
(fx/defn set-symbol-request (fx/defn set-symbol-request
{:events [:wallet.accounts/share]} {:events [:wallet.accounts/share]}
[{:keys [db]}] [{:keys [db]}]
{:list.selection/open-share {:message (eip55/address->checksum (ethereum/current-address db))}}) {:list.selection/open-share {:message (eip55/address->checksum (ethereum/default-address db))}})

View File

@ -44,7 +44,7 @@
items-number (money/to-number amount) items-number (money/to-number amount)
loaded-items-number (count (get-in db [:collectibles symbol]))] loaded-items-number (count (get-in db [:collectibles symbol]))]
(merge (when (not= items-number loaded-items-number) (merge (when (not= items-number loaded-items-number)
(load-collectibles-fx all-tokens symbol items-number (ethereum/current-address db) chain-id)) (load-collectibles-fx all-tokens symbol items-number (ethereum/default-address db) chain-id))
{:dispatch [:navigate-to :collectibles-list collectible]})))) {:dispatch [:navigate-to :collectibles-list collectible]}))))
;; Crypto Kitties ;; Crypto Kitties

View File

@ -22,10 +22,10 @@
(re-frame/reg-fx (re-frame/reg-fx
:wallet/get-balance :wallet/get-balance
(fn [{:keys [multiaccount-id on-success on-error]}] (fn [{:keys [account-address on-success on-error]}]
(json-rpc/call (json-rpc/call
{:method "eth_getBalance" {:method "eth_getBalance"
:params [multiaccount-id "latest"] :params [account-address "latest"]
:on-success on-success :on-success on-success
:on-error on-error}))) :on-error on-error})))
@ -137,12 +137,12 @@
(re-frame/reg-fx (re-frame/reg-fx
:wallet/get-tokens-balance :wallet/get-tokens-balance
(fn [{:keys [wallet-address tokens on-success on-error]}] (fn [{:keys [account-address tokens on-success on-error]}]
(doseq [{:keys [address symbol]} tokens] (doseq [{:keys [address symbol]} tokens]
(json-rpc/eth-call (json-rpc/eth-call
{:contract address {:contract address
:method "balanceOf(address)" :method "balanceOf(address)"
:params [wallet-address] :params [account-address]
:outputs ["uint256"] :outputs ["uint256"]
:on-success :on-success
(fn [[balance]] (fn [[balance]]
@ -186,14 +186,14 @@
(fx/merge (fx/merge
cofx cofx
{:wallet/get-balance {:wallet/get-balance
{:multiaccount-id normalized-address {:account-address normalized-address
:on-success #(re-frame/dispatch :on-success #(re-frame/dispatch
[:wallet.callback/update-balance-success %]) [:wallet.callback/update-balance-success %])
:on-error #(re-frame/dispatch :on-error #(re-frame/dispatch
[:wallet.callback/update-balance-fail %])} [:wallet.callback/update-balance-fail %])}
:wallet/get-tokens-balance :wallet/get-tokens-balance
{:wallet-address normalized-address {:account-address normalized-address
:tokens tokens :tokens tokens
:on-success :on-success
(fn [symbol balance] (fn [symbol balance]
@ -327,14 +327,16 @@
(fx/defn sign-transaction-button-clicked (fx/defn sign-transaction-button-clicked
{:events [:wallet.ui/sign-transaction-button-clicked]} {:events [:wallet.ui/sign-transaction-button-clicked]}
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
(let [{:keys [to symbol amount]} (get-in cofx [:db :wallet :send-transaction]) (let [{:keys [to symbol amount from]} (get-in cofx [:db :wallet :send-transaction])
{:keys [symbol address]} (tokens/asset-for (:wallet/all-tokens db) (keyword (:chain db)) symbol) {:keys [symbol address]} (tokens/asset-for (:wallet/all-tokens db) (keyword (:chain db)) symbol)
amount-hex (str "0x" (abi-spec/number-to-hex amount)) amount-hex (str "0x" (abi-spec/number-to-hex amount))
to-norm (ethereum/normalized-address to)] to-norm (ethereum/normalized-address to)]
(signing/sign cofx {:tx-obj (if (= symbol :ETH) (signing/sign cofx {:tx-obj (if (= symbol :ETH)
{:to to-norm {:to to-norm
:from from
:value amount-hex} :value amount-hex}
{:to (ethereum/normalized-address address) {:to (ethereum/normalized-address address)
:from from
:data (abi-spec/encode "transfer(address,uint256)" [to-norm amount-hex])}) :data (abi-spec/encode "transfer(address,uint256)" [to-norm amount-hex])})
:on-result [:navigate-back]}))) :on-result [:navigate-back]})))

View File

@ -92,7 +92,7 @@
[{:keys [db]} contract total-supply] [{:keys [db]} contract total-supply]
(if (money/valid? total-supply) (if (money/valid? total-supply)
{:wallet.custom-token/get-balance {:wallet.custom-token/get-balance
[contract (ethereum/current-address db)]} [contract (ethereum/default-address db)]}
{:db (update db {:db (update db
:wallet/custom-token-screen :wallet/custom-token-screen
merge {:in-progress? nil merge {:in-progress? nil

View File

@ -2,7 +2,7 @@
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead", "_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
"owner": "status-im", "owner": "status-im",
"repo": "status-go", "repo": "status-go",
"version": "release-0.30.1-beta.2", "version": "v0.31.0-beta.0",
"commit-sha1": "960b4763a6ef861173f603c858bfa4dc8e2a37ee", "commit-sha1": "21a62c731fca99a9b5db1f6fccacf7a311610da2",
"src-sha256": "1d00gk04l360jr7fi4i161vv6zsj4waxbazrn64k71r32685ig1q" "src-sha256": "1gm2whjw9qkgx8fywfq26640jj5bbvngmc61rzlw376q8s5bk9k6"
} }

View File

@ -3,18 +3,6 @@
[status-im.utils.utils :as utils] [status-im.utils.utils :as utils]
[status-im.multiaccounts.create.core :as models])) [status-im.multiaccounts.create.core :as models]))
(deftest on-multiaccount-created
(let [result (models/on-multiaccount-created {:random-guid-generator (constantly "")
:signing-phrase ""
:db {}}
{:pubkey "04de2e21f1642ebee03b9aa4bf1936066124cc89967eaf269544c9b90c539fd5c980166a897d06dd4d3732b38116239f63c89395a8d73eac72881fab802010cb56"
:address "7e92236392a850980d00d0cd2a4b92886bd7fe7b"
:mnemonic "hello world"}
"password"
true)]
(is (= (keys result)
[:db :multiaccounts.login/clear-web-data :data-store/change-multiaccount :data-store/base-tx]))))
(deftest intro-step-back (deftest intro-step-back
(testing "Back from choose-key" (testing "Back from choose-key"
(let [db {:intro-wizard {:step :choose-key}} (let [db {:intro-wizard {:step :choose-key}}

View File

@ -107,8 +107,6 @@
:multiaccounts/multiaccounts data/multiaccounts :multiaccounts/multiaccounts data/multiaccounts
:multiaccount data/multiaccounts}} :multiaccount data/multiaccounts}}
efx (signals/status-node-started cofx)] efx (signals/status-node-started cofx)]
(testing "Init Login call."
(is (= ["address" "password"] (:multiaccounts.login/login efx))))
(testing "Change node's status to started." (testing "Change node's status to started."
(is (= :started (get-in efx [:db :node/status]))))))) (is (= :started (get-in efx [:db :node/status])))))))
@ -169,39 +167,39 @@
(testing "Stop node." (testing "Stop node."
(is (contains? efx :node/stop)))))) (is (contains? efx :node/stop))))))
(deftest login-success #_(deftest login-success
(testing ":multiaccounts.login.callback/login-success event received." (testing ":accounts.login.callback/login-success event received."
(let [db {:multiaccounts/login {:address "address" (let [db {:accounts/login {:address "address"
:password "password"} :password "password"}
:multiaccount data/multiaccount :account/account data/account
:semaphores #{}} :semaphores #{}}
cofx {:db db cofx {:db db
:data-store/mailservers [] :data-store/mailservers []
:data-store/transport data/transport :data-store/transport data/transport
:data-store/mailserver-topics data/topics} :data-store/mailserver-topics data/topics}
login-result "{\"error\":\"\"}" login-result "{\"error\":\"\"}"
efx (login.core/user-login-callback cofx login-result) efx (login.core/user-login-callback cofx login-result)
new-db (:db efx) new-db (:db efx)
json-rpc-fx? (into #{} (map :method (::json-rpc/call efx)))] json-rpc (into #{} (map :method (:json-rpc/call efx)))]
(testing ":multiaccounts/login cleared." (testing ":accounts/login cleared."
(is (not (contains? new-db :multiaccounts/login)))) (is (not (contains? new-db :accounts/login))))
(testing "Check messaging related effects." (testing "Check messaging related effects."
(is (contains? efx :filters/load-filters)) (is (contains? efx :filters/load-filters))
(is (contains? efx :mailserver/add-peer)) (is (contains? efx :mailserver/add-peer))
(is (contains? efx :mailserver/update-mailservers)) (is (contains? efx :mailserver/update-mailservers))
(is (= #{{:ms 10000 (is (= #{{:ms 10000
:dispatch [:mailserver/check-connection-timeout]} :dispatch [:mailserver/check-connection-timeout]}
{:ms 10000 {:ms 10000
:dispatch [:protocol/state-sync-timed-out]}} :dispatch [:protocol/state-sync-timed-out]}}
(set (:utils/dispatch-later efx))))) (set (:utils/dispatch-later efx)))))
(testing "Check the rest of effects." (testing "Check the rest of effects."
(is (contains? efx :web3/set-default-account)) (is (contains? efx :web3/set-default-account))
(is (contains? efx :web3/fetch-node-version)) (is (contains? efx :web3/fetch-node-version))
(is (json-rpc-fx? "net_version")) (is (json-rpc "net_version"))
(is (json-rpc-fx? "eth_syncing")) (is (json-rpc "eth_syncing"))
(is (contains? efx :wallet/get-balance)) (is (contains? efx :wallet/get-balance))
(is (contains? efx :wallet/get-tokens-balance)) (is (contains? efx :wallet/get-tokens-balance))
(is (contains? efx :wallet/get-prices)))))) (is (contains? efx :wallet/get-prices))))))
(deftest login-failed (deftest login-failed
(testing (testing