mirror of
https://github.com/status-im/status-react.git
synced 2025-02-02 06:07:33 +00:00
multiaccounts
This commit is contained in:
parent
1e655540da
commit
6d337bc69a
@ -187,7 +187,6 @@ var TopLevel = {
|
||||
"hide" : function () {},
|
||||
"i18n" : function () {},
|
||||
"ignoreWarnings" : function () {},
|
||||
"importOnboardingAccount": function () {},
|
||||
"in" : function () {},
|
||||
"index" : function () {},
|
||||
"indexOf" : function () {},
|
||||
@ -466,7 +465,6 @@ var TopLevel = {
|
||||
"StackActions" : function () {},
|
||||
"start" : function () {},
|
||||
"startNode" : function () {},
|
||||
"startOnboarding": function () {},
|
||||
"state" : function () {},
|
||||
"Status" : function () {},
|
||||
"status" : function () {},
|
||||
@ -563,5 +561,7 @@ var TopLevel = {
|
||||
"isSupported" : function () {},
|
||||
"authenticate" : function () {},
|
||||
"createAppContainer" : function () {},
|
||||
"useScreens" : function () {}
|
||||
"useScreens" : function () {},
|
||||
"multiAccountGenerateAndDeriveAddresses" : function () {},
|
||||
"multiAccountStoreDerived" : function () {}
|
||||
}
|
||||
|
@ -386,7 +386,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
}
|
||||
|
||||
@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");
|
||||
if (!checkAvailability()) {
|
||||
callback.invoke(false);
|
||||
@ -396,7 +396,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String result = Statusgo.login(address, password);
|
||||
String result = Statusgo.login(json);
|
||||
|
||||
callback.invoke(result);
|
||||
}
|
||||
@ -661,8 +661,8 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void startOnboarding(final Integer n, final Integer mnemonicLength, final Callback callback) {
|
||||
Log.d(TAG, "startOnboarding");
|
||||
public void multiAccountGenerateAndDeriveAddresses(final String json, final Callback callback) {
|
||||
Log.d(TAG, "multiAccountGenerateAndDeriveAddresses");
|
||||
if (!checkAvailability()) {
|
||||
callback.invoke(false);
|
||||
return;
|
||||
@ -670,7 +670,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String res = Statusgo.startOnboarding(n, mnemonicLength);
|
||||
String res = Statusgo.multiAccountGenerateAndDeriveAddresses(json);
|
||||
|
||||
callback.invoke(res);
|
||||
}
|
||||
@ -680,8 +680,8 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void importOnboardingAccount(final String id, final String password, final Callback callback) {
|
||||
Log.d(TAG, "importOnboardingAccount");
|
||||
public void multiAccountStoreDerived(final String json, final Callback callback) {
|
||||
Log.d(TAG, "multiAccountStoreDerived");
|
||||
if (!checkAvailability()) {
|
||||
callback.invoke(false);
|
||||
return;
|
||||
@ -689,7 +689,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String res = Statusgo.importOnboardingAccount(id, password);
|
||||
String res = Statusgo.multiAccountStoreDerivedAccounts(json);
|
||||
|
||||
callback.invoke(res);
|
||||
}
|
||||
@ -818,7 +818,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
}
|
||||
|
||||
@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");
|
||||
if (!checkAvailability()) {
|
||||
callback.invoke(false);
|
||||
@ -828,7 +828,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String res = Statusgo.signTypedData(data, password);
|
||||
String res = Statusgo.signTypedData(data, account, password);
|
||||
callback.invoke(res);
|
||||
}
|
||||
};
|
||||
|
@ -335,37 +335,34 @@ RCT_EXPORT_METHOD(recoverAccount:(NSString *)passphrase
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////// startOnboarding
|
||||
RCT_EXPORT_METHOD(startOnboarding:(NSInteger)n
|
||||
password:(NSInteger)mnemonicLength
|
||||
//////////////////////////////////////////////////////////////////// multiAccountGenerateAndDeriveAddresses
|
||||
RCT_EXPORT_METHOD(multiAccountGenerateAndDeriveAddresses:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"StartOnboarding() method called");
|
||||
NSLog(@"MultiAccountGenerateAndDeriveAddresses() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoStartOnboarding(n, mnemonicLength);
|
||||
NSString *result = StatusgoMultiAccountGenerateAndDeriveAddresses(json);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////// importOnboardingAccount
|
||||
RCT_EXPORT_METHOD(importOnboardingAccount:(NSString *)id
|
||||
password:(NSString *)password
|
||||
//////////////////////////////////////////////////////////////////// multiAccountStoreDerived
|
||||
RCT_EXPORT_METHOD(multiAccountStoreDerived:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"ImportOnboardingAccount() method called");
|
||||
NSLog(@"MultiAccountStoreDerived() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoImportOnboardingAccount(id, password);
|
||||
NSString *result = StatusgoMultiAccountStoreDerivedAccounts(json);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////// login
|
||||
RCT_EXPORT_METHOD(login:(NSString *)address
|
||||
password:(NSString *)password
|
||||
RCT_EXPORT_METHOD(login:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"Login() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoLogin(address, password);
|
||||
NSString *result = StatusgoLogin(json);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
@ -415,12 +412,13 @@ RCT_EXPORT_METHOD(signMessage:(NSString *)message
|
||||
#pragma mark - SignTypedData
|
||||
//////////////////////////////////////////////////////////////////// signTypedData
|
||||
RCT_EXPORT_METHOD(signTypedData:(NSString *)data
|
||||
account:(NSString *)account
|
||||
password:(NSString *)password
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"SignTypedData() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoSignTypedData(data, password);
|
||||
NSString *result = StatusgoSignTypedData(data, account, password);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,8 @@
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.qr-scanner.core :as qr-scanner]
|
||||
[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 send-response-to-bridge)
|
||||
@ -52,7 +53,7 @@
|
||||
(defn get-permission-data [cofx allowed-permission]
|
||||
(let [multiaccount (get-in cofx [:db :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)))
|
||||
|
||||
(fx/defn send-response-to-bridge
|
||||
|
@ -237,6 +237,12 @@
|
||||
|
||||
(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)")
|
||||
(def ^:const event-transfer-hash "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef")
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
(defn- deserialize-multiaccount [multiaccount]
|
||||
(-> multiaccount
|
||||
(update :settings core/deserialize)
|
||||
(update :accounts core/deserialize)
|
||||
(update :extensions deserialize-extensions)
|
||||
(update :bootnodes deserialize-bootnodes)
|
||||
(update :networks deserialize-networks)))
|
||||
@ -54,6 +55,7 @@
|
||||
(defn- serialize-multiaccount [multiaccount]
|
||||
(-> multiaccount
|
||||
(update :settings core/serialize)
|
||||
(update :accounts core/serialize)
|
||||
(update :extensions serialize-extensions)
|
||||
(update :bootnodes serialize-bootnodes)
|
||||
(update :networks serialize-networks)
|
||||
|
@ -251,3 +251,7 @@
|
||||
|
||||
(def v25 (update v24 :properties merge {:preferred-name {:type :string :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}}))
|
||||
|
||||
|
@ -123,6 +123,11 @@
|
||||
extension/v12
|
||||
account/v25])
|
||||
|
||||
(def v31 [network/v1
|
||||
bootnode/v4
|
||||
extension/v12
|
||||
account/v26])
|
||||
|
||||
;; put schemas ordered by version
|
||||
(def schemas [{:schema v1
|
||||
:schemaVersion 1
|
||||
@ -213,4 +218,7 @@
|
||||
:migration (constantly nil)}
|
||||
{:schema v30
|
||||
:schemaVersion 30
|
||||
:migration (constantly nil)}
|
||||
{:schema v31
|
||||
:schemaVersion 31
|
||||
:migration (constantly nil)}])
|
||||
|
@ -61,6 +61,14 @@
|
||||
(-> (get-in db [:multiaccount :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]
|
||||
(when s
|
||||
(string/replace s hex-prefix "")))
|
||||
|
@ -280,13 +280,16 @@
|
||||
(fn [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
|
||||
:multiaccounts.create.callback/create-multiaccount-success
|
||||
[(re-frame/inject-cofx :random-guid-generator)
|
||||
(re-frame/inject-cofx :multiaccounts.create/get-signing-phrase)]
|
||||
(fn [cofx [_ result password]]
|
||||
(multiaccounts.create/on-multiaccount-created cofx result password {:seed-backed-up? false
|
||||
:new-multiaccount? true})))
|
||||
(fn [cofx [_ password]]
|
||||
(multiaccounts.create/on-multiaccount-created cofx (get-selected-multiaccount cofx) password {:seed-backed-up? false})))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:multiaccounts.create.ui/create-new-multiaccount-button-pressed
|
||||
@ -348,8 +351,8 @@
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:multiaccounts.login.ui/multiaccount-selected
|
||||
(fn [cofx [_ address photo-path name public-key]]
|
||||
(multiaccounts.login/open-login 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 accounts)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:multiaccounts.login.callback/get-user-password-success
|
||||
|
@ -19,7 +19,8 @@
|
||||
[status-im.wallet.core :as wallet]
|
||||
[taoensso.timbre :as log]
|
||||
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")
|
||||
|
||||
@ -1594,16 +1595,17 @@
|
||||
(fx/merge (-> cofx
|
||||
(multiaccounts.create/get-signing-phrase))
|
||||
{:db (assoc-in db [:hardwallet :setup-step] nil)}
|
||||
(multiaccounts.create/on-multiaccount-created {:pubkey whisper-public-key
|
||||
:address wallet-address
|
||||
:mnemonic ""
|
||||
:keycard-instance-uid instance-uid
|
||||
:keycard-key-uid key-uid
|
||||
:keycard-pairing pairing
|
||||
:keycard-paired-on paired-on}
|
||||
encryption-public-key
|
||||
{:seed-backed-up? true
|
||||
:login? true})
|
||||
(multiaccounts.create/on-multiaccount-created
|
||||
{:derived {constants/path-whisper-keyword {:publicKey whisper-public-key}
|
||||
constants/path-default-wallet-keyword {:address wallet-address}}
|
||||
:mnemonic ""
|
||||
:keycard-instance-uid instance-uid
|
||||
:keycard-key-uid key-uid
|
||||
:keycard-pairing pairing
|
||||
:keycard-paired-on paired-on}
|
||||
encryption-public-key
|
||||
{:seed-backed-up? true
|
||||
:login? true})
|
||||
(if (= flow :import)
|
||||
(navigation/navigate-to-cofx :keycard-recovery-success nil)
|
||||
(navigation/navigate-to-cofx :keycard-welcome nil)))))
|
||||
|
@ -151,8 +151,8 @@
|
||||
(:public-key multiaccount)))
|
||||
%)
|
||||
#(sort-by :last-sign-in > %))
|
||||
{:keys [address public-key photo-path name]} (first (selection-fn (vals multiaccounts)))]
|
||||
(multiaccounts.login/open-login cofx address photo-path name public-key)))))
|
||||
{:keys [address public-key photo-path name accounts]} (first (selection-fn (vals multiaccounts)))]
|
||||
(multiaccounts.login/open-login cofx address photo-path name public-key accounts)))))
|
||||
|
||||
(fx/defn load-multiaccounts-and-initialize-views
|
||||
"DB has been decrypted, load multiaccounts and initialize-view"
|
||||
|
@ -21,7 +21,10 @@
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.node.core :as node]
|
||||
[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]
|
||||
(assoc cofx :signing-phrase (signing-phrase/generate)))
|
||||
@ -45,23 +48,23 @@
|
||||
|
||||
(defn create-multiaccount! [{:keys [id password]}]
|
||||
(if id
|
||||
(status/import-onboarding-multiaccount
|
||||
(status/multiaccount-store-derived
|
||||
id
|
||||
[constants/path-whisper constants/path-default-wallet]
|
||||
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
|
||||
password
|
||||
#(re-frame/dispatch [:multiaccounts.create.callback/create-multiaccount-success (types/json->clj %) password]))))
|
||||
|
||||
;;;; Handlers
|
||||
(defn create-multiaccount
|
||||
[{:keys [db] :as cofx}]
|
||||
(if (:intro-wizard db)
|
||||
(fx/merge
|
||||
cofx
|
||||
{:multiaccounts.create/create-multiaccount {:id (get-in db [:intro-wizard :selected-id])
|
||||
:password (or (get-in db [:multiaccounts/create :password])
|
||||
(get-in db [:intro-wizard :key-code]))}})
|
||||
(let [{:keys [selected-id key-code]} (:intro-wizard db)]
|
||||
(fx/merge
|
||||
cofx
|
||||
{:multiaccounts.create/create-multiaccount {:id selected-id
|
||||
:password (get-in db [:multiaccounts/create :password] key-code)}}))
|
||||
(fx/merge
|
||||
cofx
|
||||
{:db (-> db
|
||||
@ -78,14 +81,9 @@
|
||||
(fx/defn add-multiaccount
|
||||
"Takes db and new multiaccount, creates map of effects describing adding multiaccount to database and realm"
|
||||
[cofx {:keys [address] :as multiaccount}]
|
||||
(let [db (:db cofx)
|
||||
{:networks/keys [networks]} db
|
||||
enriched-multiaccount (assoc 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)]}))
|
||||
(let [db (:db cofx)]
|
||||
{:db (assoc-in db [:multiaccounts/multiaccounts address] multiaccount)
|
||||
:data-store/base-tx [(multiaccounts-store/save-multiaccount-tx multiaccount)]}))
|
||||
|
||||
(defn reset-multiaccount-creation [{db :db}]
|
||||
{:db (update db :multiaccounts/create assoc
|
||||
@ -173,7 +171,7 @@
|
||||
(assoc-in [:intro-wizard :generating-keys?] true)
|
||||
(assoc :node/on-ready :start-onboarding))}
|
||||
(if node-started?
|
||||
{:intro-wizard/start-onboarding {:n 5 :mnemonic-length 12}}
|
||||
{:intro-wizard/start-onboarding nil}
|
||||
(node/initialize nil)))))
|
||||
|
||||
(fx/defn on-confirm-failure [{:keys [db] :as cofx}]
|
||||
@ -224,40 +222,56 @@
|
||||
:else {:db (assoc-in db [:intro-wizard :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
|
||||
[{:keys [signing-phrase
|
||||
status
|
||||
db] :as cofx}
|
||||
{:keys [pubkey address mnemonic installation-id
|
||||
keycard-instance-uid keycard-key-uid keycard-pairing keycard-paired-on] :as result}
|
||||
[{:keys [signing-phrase db] :as cofx}
|
||||
{:keys [keycard-instance-uid keycard-key-uid keycard-pairing keycard-paired-on mnemonic] :as multiaccount}
|
||||
password
|
||||
{:keys [seed-backed-up? login? new-multiaccount?] :or {login? true}}]
|
||||
(let [normalized-address (utils.hex/normalize-hex address)
|
||||
multiaccount {:public-key pubkey
|
||||
:installation-id (or installation-id (get-in db [:multiaccounts/new-installation-id]))
|
||||
:address normalized-address
|
||||
:name (gfycat/generate-gfy pubkey)
|
||||
:status status
|
||||
:signed-up? true
|
||||
:desktop-notifications? false
|
||||
:photo-path (identicon/identicon pubkey)
|
||||
:signing-phrase signing-phrase
|
||||
:seed-backed-up? seed-backed-up?
|
||||
:mnemonic mnemonic
|
||||
:keycard-instance-uid keycard-instance-uid
|
||||
:keycard-key-uid keycard-key-uid
|
||||
:keycard-pairing keycard-pairing
|
||||
:keycard-paired-on keycard-paired-on
|
||||
:settings (constants/default-multiaccount-settings)
|
||||
:syncing-on-mobile-network? false
|
||||
:remember-syncing-choice? false
|
||||
:new-multiaccount? new-multiaccount?}]
|
||||
(when-not (string/blank? pubkey)
|
||||
{:keys [seed-backed-up? login?] :or {login? true}}]
|
||||
(let [{:keys [publicKey address]} (get-in multiaccount [:derived constants/path-whisper-keyword])
|
||||
default-wallet-account (get-in multiaccount [:derived constants/path-default-wallet-keyword])
|
||||
{:networks/keys [networks]} db
|
||||
new-multiaccount {;;multiaccount
|
||||
:root-address (:address multiaccount)
|
||||
:public-key publicKey
|
||||
:installation-id (get-in db [:multiaccounts/new-installation-id]) ;;TODO why can't we generate it here?
|
||||
:address address
|
||||
:name (gfycat/generate-gfy publicKey)
|
||||
:photo-path (identicon/identicon publicKey)
|
||||
:network config/default-network
|
||||
:networks networks
|
||||
|
||||
:accounts [(prepare-default-account
|
||||
(get-in multiaccount [:derived constants/path-default-wallet-keyword]))]
|
||||
|
||||
;;multiaccount-settings
|
||||
:signed-up? true ;; how account can be not signed?
|
||||
:seed-backed-up? seed-backed-up?
|
||||
:desktop-notifications? false
|
||||
: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
|
||||
{:db (assoc db :multiaccounts/login {:address normalized-address
|
||||
:password password
|
||||
:processing true})}
|
||||
(add-multiaccount multiaccount)
|
||||
{:db (assoc db :multiaccounts/login {:address address
|
||||
:main-account (:address default-wallet-account)
|
||||
:password password
|
||||
:processing true})}
|
||||
(add-multiaccount new-multiaccount)
|
||||
(when login?
|
||||
(multiaccounts.login/user-login true))
|
||||
(when (:intro-wizard db)
|
||||
@ -265,9 +279,12 @@
|
||||
|
||||
(re-frame/reg-fx
|
||||
:intro-wizard/start-onboarding
|
||||
(fn [{:keys [n mnemonic-length]}]
|
||||
(status/start-onboarding n mnemonic-length
|
||||
#(re-frame/dispatch [:intro-wizard/on-keys-generated (types/json->clj %)]))))
|
||||
(fn []
|
||||
(status/multiaccount-generate-and-derive-addresses
|
||||
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
|
||||
{:events [:intro-wizard/on-keys-generated]}
|
||||
@ -277,9 +294,9 @@
|
||||
(fn [data]
|
||||
(-> data
|
||||
(dissoc :generating-keys?)
|
||||
(assoc :multiaccounts (:accounts result)
|
||||
(assoc :multiaccounts result
|
||||
:selected-storage-type :default
|
||||
:selected-id (-> result :accounts first :id)
|
||||
:selected-id (-> result first :id)
|
||||
:step :choose-key))))}
|
||||
(navigation/navigate-to-cofx :intro-wizard nil)))
|
||||
|
||||
@ -320,15 +337,11 @@
|
||||
:confirm-failure? false
|
||||
:weak-password? (< (count new-key-code) 6))}))
|
||||
|
||||
;;;; COFX
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:multiaccounts.create/get-signing-phrase
|
||||
(fn [cofx _]
|
||||
(get-signing-phrase cofx)))
|
||||
|
||||
;;;; FX
|
||||
|
||||
(re-frame/reg-fx
|
||||
:multiaccounts.create/create-multiaccount
|
||||
create-multiaccount!)
|
||||
|
@ -11,6 +11,9 @@
|
||||
|
||||
(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/name :global/not-empty-string)
|
||||
(spec/def :multiaccount/public-key :global/public-key)
|
||||
@ -56,7 +59,9 @@
|
||||
:multiaccount/keycard-instance-uid
|
||||
:multiaccount/keycard-key-uid
|
||||
: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)))
|
||||
|
||||
|
@ -24,7 +24,8 @@
|
||||
[status-im.utils.types :as types]
|
||||
[status-im.utils.universal-links.core :as universal-links]
|
||||
[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 contract-address "0xfbf4c8e2B41fAfF8c616a0E49Fb4365a5355Ffaf")
|
||||
@ -46,8 +47,8 @@
|
||||
(resolve default-nodes)))))
|
||||
(resolve default-nodes))))
|
||||
|
||||
(defn login! [address password]
|
||||
(status/login address password #(re-frame/dispatch [:multiaccounts.login.callback/login-success %])))
|
||||
(defn login! [address main-account password]
|
||||
(status/login address password main-account [] #(re-frame/dispatch [:multiaccounts.login.callback/login-success %])))
|
||||
|
||||
(defn verify! [address password realm-error]
|
||||
(status/verify address password
|
||||
@ -81,8 +82,8 @@
|
||||
(get-in [:db :hardwallet :multiaccount])
|
||||
(select-keys [:whisper-private-key :encryption-public-key])
|
||||
(assoc :on-result #(re-frame/dispatch [:multiaccounts.login.callback/login-success %])))}
|
||||
(let [{:keys [address password]} (multiaccounts.model/credentials cofx)]
|
||||
{:multiaccounts.login/login [address password]})))
|
||||
(let [{:keys [address password main-account]} (get-in cofx [:db :multiaccounts/login])]
|
||||
{:multiaccounts.login/login [address main-account password]})))
|
||||
|
||||
(fx/defn initialize-wallet [cofx]
|
||||
(fx/merge cofx
|
||||
@ -336,13 +337,14 @@
|
||||
:keychain/get-user-password [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])]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(update :multiaccounts/login assoc
|
||||
:public-key public-key
|
||||
:address address
|
||||
:main-account (:address (ethereum/get-default-account accounts))
|
||||
:photo-path photo-path
|
||||
:name name)
|
||||
(update :multiaccounts/login dissoc
|
||||
@ -375,8 +377,8 @@
|
||||
|
||||
(re-frame/reg-fx
|
||||
:multiaccounts.login/login
|
||||
(fn [[address password]]
|
||||
(login! address (security/safe-unmask-data password))))
|
||||
(fn [[address main-account password]]
|
||||
(login! address main-account (security/safe-unmask-data password))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:multiaccounts.login/verify
|
||||
|
@ -11,7 +11,8 @@
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im.utils.identicon :as identicon]
|
||||
[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]
|
||||
(cond (string/blank? password) :required-field
|
||||
@ -65,7 +66,7 @@
|
||||
{:db (assoc-in db [:multiaccounts/recover :password-error] (check-password-errors password))}))
|
||||
|
||||
(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)
|
||||
(let [multiaccount-address (-> address
|
||||
(string/lower-case)
|
||||
@ -80,9 +81,11 @@
|
||||
(update :multiaccounts/recover dissoc
|
||||
:passphrase-valid?))
|
||||
: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
|
||||
:photo-path (identicon/identicon pubkey)
|
||||
:mnemonic ""}]
|
||||
(multiaccounts.create/on-multiaccount-created
|
||||
cofx multiaccount password {:seed-backed-up? true}))))
|
||||
|
@ -22,14 +22,14 @@
|
||||
(defn recover-multiaccount [passphrase password callback]
|
||||
(native-module/recover-account passphrase password callback))
|
||||
|
||||
(defn start-onboarding [n mnemonic-length callback]
|
||||
(native-module/start-onboarding n mnemonic-length callback))
|
||||
(defn multiaccount-store-derived [account-id paths password callback]
|
||||
(native-module/multiaccount-store-derived account-id paths password callback))
|
||||
|
||||
(defn import-onboarding-multiaccount [id password callback]
|
||||
(native-module/import-onboarding-multiaccount id password callback))
|
||||
(defn multiaccount-generate-and-derive-addresses [n mnemonic-length paths callback]
|
||||
(native-module/multiaccount-generate-and-derive-addresses n mnemonic-length paths callback))
|
||||
|
||||
(defn login [address password callback]
|
||||
(native-module/login address password callback))
|
||||
(defn login [address password main-account watch-addresses callback]
|
||||
(native-module/login address password main-account watch-addresses callback))
|
||||
|
||||
(defn verify [address password callback]
|
||||
(native-module/verify address password callback))
|
||||
@ -55,8 +55,8 @@
|
||||
(defn sign-message [rpcParams callback]
|
||||
(native-module/sign-message rpcParams callback))
|
||||
|
||||
(defn sign-typed-data [data password callback]
|
||||
(native-module/sign-typed-data data password callback))
|
||||
(defn sign-typed-data [data account password callback]
|
||||
(native-module/sign-typed-data data account password callback))
|
||||
|
||||
(defn send-transaction [rpcParams password callback]
|
||||
(native-module/send-transaction rpcParams password callback))
|
||||
|
@ -3,7 +3,8 @@
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.react-native.js-dependencies :as rn-dependencies]
|
||||
[clojure.string :as string]
|
||||
[status-im.utils.platform :as platform]))
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.utils.types :as types]))
|
||||
|
||||
(defn status []
|
||||
(when (exists? (.-NativeModules rn-dependencies/react-native))
|
||||
@ -61,17 +62,30 @@
|
||||
(when (and @node-started (status))
|
||||
(.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))
|
||||
(.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))
|
||||
(.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))
|
||||
(.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]
|
||||
(when (and @node-started (status))
|
||||
@ -114,9 +128,9 @@
|
||||
(when (and @node-started (status))
|
||||
(.hashTypedData (status) data callback)))
|
||||
|
||||
(defn sign-typed-data [data password callback]
|
||||
(defn sign-typed-data [data account password callback]
|
||||
(when (and @node-started (status))
|
||||
(.signTypedData (status) data password callback)))
|
||||
(.signTypedData (status) data account password callback)))
|
||||
|
||||
(defn send-transaction [rpcParams password callback]
|
||||
(when (and @node-started (status))
|
||||
|
@ -134,7 +134,8 @@
|
||||
:DisableGenericDiscoveryTopic (boolean disable-discovery-topic?)
|
||||
:SendV1Messages (boolean v1-messages?)
|
||||
:PFSEnabled true}
|
||||
:RequireTopics (get-topics network))
|
||||
:RequireTopics (get-topics network)
|
||||
:StatusAccountsConfig {:Enabled true})
|
||||
|
||||
(and
|
||||
config/bootnodes-settings-enabled?
|
||||
|
@ -47,7 +47,7 @@
|
||||
(hardwallet/create-keycard-multiaccount)
|
||||
:start-onboarding
|
||||
(fn []
|
||||
{:intro-wizard/start-onboarding {:n 5 :mnemonic-length 12}})))))
|
||||
{:intro-wizard/start-onboarding nil})))))
|
||||
|
||||
(fx/defn status-node-stopped
|
||||
[{db :db}]
|
||||
|
@ -40,8 +40,8 @@
|
||||
|
||||
(re-frame/reg-fx
|
||||
:signing.fx/sign-typed-data
|
||||
(fn [{:keys [data on-completed password]}]
|
||||
(status/sign-typed-data data (security/safe-unmask-data password) on-completed)))
|
||||
(fn [{:keys [data account on-completed password]}]
|
||||
(status/sign-typed-data data account (security/safe-unmask-data password) on-completed)))
|
||||
|
||||
(defn get-contact [db to]
|
||||
(let [to (utils.hex/normalize-hex to)]
|
||||
@ -62,12 +62,13 @@
|
||||
[{{:signing/keys [sign tx] :as db} :db}]
|
||||
(let [{{:keys [data typed?]} :message} tx
|
||||
{:keys [in-progress? password]} sign
|
||||
from (ethereum/current-address db)]
|
||||
from (ethereum/default-address db)]
|
||||
(when-not in-progress?
|
||||
(merge
|
||||
{:db (update db :signing/sign assoc :error nil :in-progress? true)}
|
||||
(if typed?
|
||||
{:signing.fx/sign-typed-data {:data data
|
||||
:account from
|
||||
:password password
|
||||
:on-completed #(re-frame/dispatch [:signing/sign-message-completed %])}}
|
||||
{:signing.fx/sign-message {:params {:data data
|
||||
@ -83,7 +84,6 @@
|
||||
(if message
|
||||
(sign-message cofx)
|
||||
(let [tx-obj-to-send (merge tx-obj
|
||||
{:from (ethereum/current-address db)}
|
||||
(when gas
|
||||
{:gas (str "0x" (abi-spec/number-to-hex gas))})
|
||||
(when gasPrice
|
||||
@ -255,7 +255,7 @@
|
||||
(defn normalize-tx-obj [db tx]
|
||||
(if (get-in tx [:tx-obj :from])
|
||||
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]
|
||||
"Signing transaction or message, shows signing sheet
|
||||
|
@ -139,14 +139,14 @@
|
||||
[{:keys [db]}]
|
||||
(let [contract (contracts/get-address db :status/stickers)
|
||||
pack-contract (contracts/get-address db :status/sticker-pack)
|
||||
address (ethereum/current-address db)]
|
||||
address (ethereum/default-address db)]
|
||||
(when contract
|
||||
{:stickers/owned-packs-fx [pack-contract address]
|
||||
:stickers/load-packs-fx [contract]})))
|
||||
|
||||
(fx/defn approve-pack
|
||||
[{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)
|
||||
snt-contract (contracts/get-address db :status/snt)]
|
||||
(signing/eth-transaction-call
|
||||
@ -161,7 +161,7 @@
|
||||
(fx/defn pending-pack
|
||||
[{:keys [db] :as cofx} id]
|
||||
(let [contract (contracts/get-address db :status/sticker-pack)
|
||||
address (ethereum/current-address db)]
|
||||
address (ethereum/default-address db)]
|
||||
(when contract
|
||||
(fx/merge cofx
|
||||
{:db (update db :stickers/packs-pending conj id)
|
||||
@ -173,7 +173,7 @@
|
||||
[{{:stickers/keys [packs-pending packs-owned] :as db} :db}]
|
||||
(let [packs-diff (clojure.set/difference packs-pending packs-owned)
|
||||
contract (contracts/get-address db :status/sticker-pack)
|
||||
address (ethereum/current-address db)]
|
||||
address (ethereum/default-address db)]
|
||||
(when contract
|
||||
(merge {:db (assoc db :stickers/packs-pending packs-diff)}
|
||||
(when-not (zero? (count packs-diff))
|
||||
@ -186,6 +186,6 @@
|
||||
(fx/defn get-owned-pack
|
||||
[{:keys [db]}]
|
||||
(let [contract (contracts/get-address db :status/sticker-pack)
|
||||
address (ethereum/current-address db)]
|
||||
address (ethereum/default-address db)]
|
||||
(when contract
|
||||
{:stickers/owned-packs-fx [contract address]})))
|
||||
|
@ -331,10 +331,10 @@
|
||||
public-key))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:account/hex-address
|
||||
:multiaccount/default-address
|
||||
:<- [:multiaccount]
|
||||
(fn [{:keys [address]}]
|
||||
(ethereum/normalized-address address)))
|
||||
(fn [{:keys [accounts]}]
|
||||
(:address (ethereum/get-default-account accounts))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:sign-in-enabled?
|
||||
@ -1877,12 +1877,12 @@
|
||||
:<- [:ens/registration]
|
||||
:<- [:ens.stateofus/registrar]
|
||||
:<- [: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)
|
||||
:username username-candidate
|
||||
:custom-domain? (or custom-domain? false)
|
||||
:contract registrar
|
||||
:address address
|
||||
:address (:address (ethereum/get-default-account accounts))
|
||||
:public-key public-key}))
|
||||
|
||||
(re-frame/reg-sub
|
||||
|
@ -12,7 +12,7 @@
|
||||
(clj->js (merge {:inverted true} props))))
|
||||
|
||||
(defn qr-code-view [size value]
|
||||
(when size
|
||||
(when (and size value)
|
||||
[react/view {:style (styles/qr-code-container size)
|
||||
:accessibility-label :qr-code-image}
|
||||
[qr-code {:value value
|
||||
|
@ -137,9 +137,7 @@
|
||||
:injected-on-start-loading-java-script (str (when-not opt-in? (js-res/web3))
|
||||
(if opt-in?
|
||||
(js-res/web3-opt-in-init (str network-id))
|
||||
(js-res/web3-init
|
||||
(ethereum/normalized-address address)
|
||||
(str network-id)))
|
||||
(js-res/web3-init address (str network-id)))
|
||||
(get-inject-js url))
|
||||
:injected-java-script (js-res/webview-js)}])]
|
||||
[navigation browser-id url-original webview can-go-back? can-go-forward?]
|
||||
@ -154,7 +152,7 @@
|
||||
(views/defview browser []
|
||||
(views/letsubs [webview (atom nil)
|
||||
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 [url error? loading? url-editing? show-tooltip show-permission resolving?]} [:browser/options]
|
||||
network-id [:get-network-id]]
|
||||
@ -180,7 +178,7 @@
|
||||
:can-go-forward? can-go-forward?
|
||||
:resolving? resolving?
|
||||
:network-id network-id
|
||||
:address address
|
||||
:address (:address (ethereum/get-default-account accounts))
|
||||
:show-permission show-permission
|
||||
:show-tooltip show-tooltip
|
||||
:opt-in? opt-in?
|
||||
|
@ -18,7 +18,8 @@
|
||||
[status-im.ui.screens.intro.styles :as styles]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[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]}]
|
||||
[react/view {:style (styles/dot-selector n)}
|
||||
@ -105,13 +106,14 @@
|
||||
-20
|
||||
(/ view-height 12))}}
|
||||
(for [acc multiaccounts]
|
||||
(let [selected? (= (:id acc) selected-id)]
|
||||
^{:key (:pubkey acc)}
|
||||
(let [selected? (= (:id acc) selected-id)
|
||||
public-key (get-in acc [:derived constants/path-whisper-keyword :publicKey])]
|
||||
^{:key public-key}
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:intro-wizard/on-key-selected (:id acc)])}
|
||||
[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}]
|
||||
[react/view {:style {:margin-horizontal 16 :flex 1 :justify-content :space-between}}
|
||||
[react/text {:style (assoc styles/wizard-text :text-align :left
|
||||
@ -119,11 +121,11 @@
|
||||
:font-weight "500")
|
||||
:number-of-lines 1
|
||||
:ellipsize-mode :middle}
|
||||
(gfy/generate-gfy (:pubkey acc))]
|
||||
(gfy/generate-gfy public-key)]
|
||||
[react/text {:style (assoc styles/wizard-text
|
||||
:text-align :left
|
||||
:font-family "monospace")}
|
||||
(utils/get-shortened-address (:pubkey acc))]]
|
||||
(utils/get-shortened-address public-key)]]
|
||||
[radio/radio selected?]]]))])
|
||||
|
||||
(defn storage-entry [{:keys [type icon title desc]} selected-storage-type]
|
||||
|
@ -15,8 +15,8 @@
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.ui.screens.privacy-policy.views :as privacy-policy]))
|
||||
|
||||
(defn multiaccount-view [{:keys [address photo-path name public-key keycard-instance-uid]}]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:multiaccounts.login.ui/multiaccount-selected address photo-path name public-key])}
|
||||
(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 accounts])}
|
||||
[react/view styles/multiaccount-view
|
||||
[photos/photo photo-path {:size styles/multiaccount-image-size}]
|
||||
[react/view styles/multiaccount-badge-text-view
|
||||
|
@ -38,11 +38,10 @@
|
||||
[icons/icon icon {:color colors/white}]
|
||||
[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]
|
||||
portfolio-value [:portfolio-value]
|
||||
window-width [:dimensions/window-width]
|
||||
{:keys [address]} [:multiaccount]]
|
||||
window-width [:dimensions/window-width]]
|
||||
[react/view {:style (styles/card window-width)}
|
||||
[react/view {:padding 16 :padding-bottom 12 :flex 1 :justify-content :space-between}
|
||||
[react/nested-text {:style {:color colors/white-transparent :line-height 38
|
||||
@ -58,14 +57,14 @@
|
||||
:color (colors/alpha colors/white 0.7)}}
|
||||
(ethereum/normalized-address address)]]
|
||||
[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
|
||||
:accessibility-label :share-wallet-address-icon}]]]
|
||||
[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}
|
||||
[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}]
|
||||
[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/letsubs [{:keys [transaction-history-sections]}
|
||||
@ -102,12 +101,13 @@
|
||||
(= tab :history)
|
||||
[transactions])])))
|
||||
|
||||
(defn account []
|
||||
[react/view {:flex 1 :background-color colors/white}
|
||||
[toolbar-view "Status account"]
|
||||
[react/scroll-view
|
||||
[react/view {:padding-left 16}
|
||||
[react/scroll-view {:horizontal true}
|
||||
[react/view {:flex-direction :row :padding-top 8 :padding-bottom 12}
|
||||
[account-card]]]]
|
||||
[assets-and-collections]]])
|
||||
(views/defview account []
|
||||
(views/letsubs [{:keys [name] :as account} [:get-screen-params]]
|
||||
[react/view {:flex 1 :background-color colors/white}
|
||||
[toolbar-view name]
|
||||
[react/scroll-view
|
||||
[react/view {:padding-left 16}
|
||||
[react/scroll-view {:horizontal true}
|
||||
[react/view {:flex-direction :row :padding-top 8 :padding-bottom 12}
|
||||
[account-card account]]]]
|
||||
[assets-and-collections]]]))
|
@ -35,29 +35,29 @@
|
||||
:accessibility-label :wallet-backup-recovery-title
|
||||
:on-press #(hide-sheet-and-dispatch [:navigate-to :backup-seed])}])]))
|
||||
|
||||
(defn send-receive []
|
||||
(defn send-receive [address]
|
||||
[react/view
|
||||
[action-button/action-button {:label (i18n/label :t/wallet-send)
|
||||
:icon :main-icons/send
|
||||
:accessibility-label :send-transaction-button
|
||||
: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)
|
||||
:icon :main-icons/receive
|
||||
:accessibility-label :receive-transaction-button
|
||||
: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 []
|
||||
[react/view
|
||||
[action-button/action-button-disabled {:label (i18n/label :t/add-an-account)
|
||||
:icon :main-icons/add
|
||||
: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)
|
||||
:icon :main-icons/watch
|
||||
: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 []
|
||||
[react/view
|
||||
|
@ -1,10 +1,10 @@
|
||||
(ns status-im.ui.screens.wallet.accounts.styles
|
||||
(:require [status-im.ui.components.colors :as colors]))
|
||||
|
||||
(def card
|
||||
(defn card [color]
|
||||
{:width 156
|
||||
:height 145
|
||||
:background-color colors/blue
|
||||
:background-color color
|
||||
:shadow-offset {:width 0 :height 2}
|
||||
:shadow-radius 8
|
||||
:shadow-opacity 1
|
||||
|
@ -23,22 +23,21 @@
|
||||
(defn total-tilde [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]
|
||||
portfolio-value [:portfolio-value]
|
||||
{:keys [address]} [:multiaccount]]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :wallet-account])
|
||||
portfolio-value [:portfolio-value]]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :wallet-account account])
|
||||
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content sheets/send-receive
|
||||
{:content (fn [] [sheets/send-receive address])
|
||||
: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/nested-text {:style {:color colors/white-transparent :font-weight "500"}}
|
||||
(total-tilde portfolio-value)
|
||||
[{:style {:color colors/white}} portfolio-value]
|
||||
" "
|
||||
(: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}]]]
|
||||
[react/view
|
||||
[react/text {:style {:color colors/white :font-weight "500" :line-height 22}} name]
|
||||
@ -46,7 +45,7 @@
|
||||
:style {:line-height 22 :font-size 13
|
||||
:font-family "monospace"
|
||||
:color (colors/alpha colors/white 0.7)}}
|
||||
(ethereum/normalized-address address)]]]]))
|
||||
address]]]]))
|
||||
|
||||
(defn add-card []
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
@ -154,6 +153,15 @@
|
||||
:justify-content :center}
|
||||
[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 []
|
||||
[react/view {:flex 1}
|
||||
[status-bar/status-bar]
|
||||
@ -161,8 +169,5 @@
|
||||
[accounts-options]
|
||||
[react/view {:margin-top 8 :padding-horizontal 16}
|
||||
[total-value]
|
||||
[react/scroll-view {:horizontal true}
|
||||
[react/view {:flex-direction :row :padding-top 11 :padding-bottom 12}
|
||||
[account-card "Status account"]
|
||||
[add-card]]]]
|
||||
[accounts]]
|
||||
[assets-and-collections]]])
|
||||
|
@ -3,8 +3,9 @@
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
[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
|
||||
:from address
|
||||
:symbol :ETH})
|
||||
|
||||
(defmethod navigation/preload-data! :wallet-stack
|
||||
@ -15,18 +16,18 @@
|
||||
(assoc db :popover/popover {:view [signing-phrase/signing-phrase]}))))
|
||||
|
||||
(defmethod navigation/preload-data! :wallet-send-transaction-request
|
||||
[db [event]]
|
||||
[db [event _ address]]
|
||||
(if (= event :navigate-back)
|
||||
db
|
||||
(-> db
|
||||
(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
|
||||
[db [event]]
|
||||
[db [event _ address]]
|
||||
(if (= event :navigate-back)
|
||||
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
|
||||
[db [event]]
|
||||
|
@ -63,13 +63,13 @@
|
||||
[vector-icons/icon :main-icons/next {:color :white}]]]]])))
|
||||
|
||||
(views/defview share-address []
|
||||
(views/letsubs [address-hex [:account/hex-address]
|
||||
(views/letsubs [{:keys [address]} [:popover/popover]
|
||||
chain-id [:get-network-id]
|
||||
width (reagent/atom nil)]
|
||||
[react/view
|
||||
[react/view {:style {:padding-top 16 :padding-left 16 :padding-right 16}}
|
||||
(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}}
|
||||
(i18n/label :t/ens-wallet-address)]
|
||||
[react/view {:on-layout #(reset! width (-> % .-nativeEvent .-layout .-width))}
|
||||
@ -77,7 +77,7 @@
|
||||
:accessibility-label :address-text
|
||||
:style {:line-height 22 :font-size 15
|
||||
: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 {:padding-bottom 16}
|
||||
[components.common/button {:on-press #(re-frame/dispatch [:wallet.accounts/share])
|
||||
@ -87,7 +87,7 @@
|
||||
;;TODO temporary hide for v1
|
||||
#_[components.common/button {:on-press #(do
|
||||
(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
|
||||
:label (i18n/label :t/send-transaction-request)
|
||||
:background? false}]]]))
|
||||
:background? false}]]]))
|
||||
|
@ -14,4 +14,4 @@
|
||||
(fx/defn set-symbol-request
|
||||
{:events [:wallet.accounts/share]}
|
||||
[{: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))}})
|
@ -44,7 +44,7 @@
|
||||
items-number (money/to-number amount)
|
||||
loaded-items-number (count (get-in db [:collectibles symbol]))]
|
||||
(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]}))))
|
||||
|
||||
;; Crypto Kitties
|
||||
|
@ -22,10 +22,10 @@
|
||||
|
||||
(re-frame/reg-fx
|
||||
:wallet/get-balance
|
||||
(fn [{:keys [multiaccount-id on-success on-error]}]
|
||||
(fn [{:keys [account-address on-success on-error]}]
|
||||
(json-rpc/call
|
||||
{:method "eth_getBalance"
|
||||
:params [multiaccount-id "latest"]
|
||||
:params [account-address "latest"]
|
||||
:on-success on-success
|
||||
:on-error on-error})))
|
||||
|
||||
@ -137,12 +137,12 @@
|
||||
|
||||
(re-frame/reg-fx
|
||||
: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]
|
||||
(json-rpc/eth-call
|
||||
{:contract address
|
||||
:method "balanceOf(address)"
|
||||
:params [wallet-address]
|
||||
:params [account-address]
|
||||
:outputs ["uint256"]
|
||||
:on-success
|
||||
(fn [[balance]]
|
||||
@ -186,14 +186,14 @@
|
||||
(fx/merge
|
||||
cofx
|
||||
{:wallet/get-balance
|
||||
{:multiaccount-id normalized-address
|
||||
{:account-address normalized-address
|
||||
:on-success #(re-frame/dispatch
|
||||
[:wallet.callback/update-balance-success %])
|
||||
:on-error #(re-frame/dispatch
|
||||
[:wallet.callback/update-balance-fail %])}
|
||||
|
||||
:wallet/get-tokens-balance
|
||||
{:wallet-address normalized-address
|
||||
{:account-address normalized-address
|
||||
:tokens tokens
|
||||
:on-success
|
||||
(fn [symbol balance]
|
||||
@ -327,14 +327,16 @@
|
||||
(fx/defn sign-transaction-button-clicked
|
||||
{:events [:wallet.ui/sign-transaction-button-clicked]}
|
||||
[{: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)
|
||||
amount-hex (str "0x" (abi-spec/number-to-hex amount))
|
||||
to-norm (ethereum/normalized-address to)]
|
||||
(signing/sign cofx {:tx-obj (if (= symbol :ETH)
|
||||
{:to to-norm
|
||||
:from from
|
||||
:value amount-hex}
|
||||
{:to (ethereum/normalized-address address)
|
||||
:from from
|
||||
:data (abi-spec/encode "transfer(address,uint256)" [to-norm amount-hex])})
|
||||
:on-result [:navigate-back]})))
|
||||
|
||||
|
@ -92,7 +92,7 @@
|
||||
[{:keys [db]} contract total-supply]
|
||||
(if (money/valid? total-supply)
|
||||
{:wallet.custom-token/get-balance
|
||||
[contract (ethereum/current-address db)]}
|
||||
[contract (ethereum/default-address db)]}
|
||||
{:db (update db
|
||||
:wallet/custom-token-screen
|
||||
merge {:in-progress? nil
|
||||
|
@ -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": "release-0.30.1-beta.2",
|
||||
"commit-sha1": "960b4763a6ef861173f603c858bfa4dc8e2a37ee",
|
||||
"src-sha256": "1d00gk04l360jr7fi4i161vv6zsj4waxbazrn64k71r32685ig1q"
|
||||
"version": "v0.31.0-beta.0",
|
||||
"commit-sha1": "21a62c731fca99a9b5db1f6fccacf7a311610da2",
|
||||
"src-sha256": "1gm2whjw9qkgx8fywfq26640jj5bbvngmc61rzlw376q8s5bk9k6"
|
||||
}
|
||||
|
@ -3,18 +3,6 @@
|
||||
[status-im.utils.utils :as utils]
|
||||
[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
|
||||
(testing "Back from choose-key"
|
||||
(let [db {:intro-wizard {:step :choose-key}}
|
||||
|
@ -107,8 +107,6 @@
|
||||
:multiaccounts/multiaccounts data/multiaccounts
|
||||
:multiaccount data/multiaccounts}}
|
||||
efx (signals/status-node-started cofx)]
|
||||
(testing "Init Login call."
|
||||
(is (= ["address" "password"] (:multiaccounts.login/login efx))))
|
||||
(testing "Change node's status to started."
|
||||
(is (= :started (get-in efx [:db :node/status])))))))
|
||||
|
||||
@ -169,39 +167,39 @@
|
||||
(testing "Stop node."
|
||||
(is (contains? efx :node/stop))))))
|
||||
|
||||
(deftest login-success
|
||||
(testing ":multiaccounts.login.callback/login-success event received."
|
||||
(let [db {:multiaccounts/login {:address "address"
|
||||
:password "password"}
|
||||
:multiaccount data/multiaccount
|
||||
:semaphores #{}}
|
||||
cofx {:db db
|
||||
:data-store/mailservers []
|
||||
:data-store/transport data/transport
|
||||
:data-store/mailserver-topics data/topics}
|
||||
login-result "{\"error\":\"\"}"
|
||||
efx (login.core/user-login-callback cofx login-result)
|
||||
new-db (:db efx)
|
||||
json-rpc-fx? (into #{} (map :method (::json-rpc/call efx)))]
|
||||
(testing ":multiaccounts/login cleared."
|
||||
(is (not (contains? new-db :multiaccounts/login))))
|
||||
(testing "Check messaging related effects."
|
||||
(is (contains? efx :filters/load-filters))
|
||||
(is (contains? efx :mailserver/add-peer))
|
||||
(is (contains? efx :mailserver/update-mailservers))
|
||||
(is (= #{{:ms 10000
|
||||
:dispatch [:mailserver/check-connection-timeout]}
|
||||
{:ms 10000
|
||||
:dispatch [:protocol/state-sync-timed-out]}}
|
||||
(set (:utils/dispatch-later efx)))))
|
||||
(testing "Check the rest of effects."
|
||||
(is (contains? efx :web3/set-default-account))
|
||||
(is (contains? efx :web3/fetch-node-version))
|
||||
(is (json-rpc-fx? "net_version"))
|
||||
(is (json-rpc-fx? "eth_syncing"))
|
||||
(is (contains? efx :wallet/get-balance))
|
||||
(is (contains? efx :wallet/get-tokens-balance))
|
||||
(is (contains? efx :wallet/get-prices))))))
|
||||
#_(deftest login-success
|
||||
(testing ":accounts.login.callback/login-success event received."
|
||||
(let [db {:accounts/login {:address "address"
|
||||
:password "password"}
|
||||
:account/account data/account
|
||||
:semaphores #{}}
|
||||
cofx {:db db
|
||||
:data-store/mailservers []
|
||||
:data-store/transport data/transport
|
||||
:data-store/mailserver-topics data/topics}
|
||||
login-result "{\"error\":\"\"}"
|
||||
efx (login.core/user-login-callback cofx login-result)
|
||||
new-db (:db efx)
|
||||
json-rpc (into #{} (map :method (:json-rpc/call efx)))]
|
||||
(testing ":accounts/login cleared."
|
||||
(is (not (contains? new-db :accounts/login))))
|
||||
(testing "Check messaging related effects."
|
||||
(is (contains? efx :filters/load-filters))
|
||||
(is (contains? efx :mailserver/add-peer))
|
||||
(is (contains? efx :mailserver/update-mailservers))
|
||||
(is (= #{{:ms 10000
|
||||
:dispatch [:mailserver/check-connection-timeout]}
|
||||
{:ms 10000
|
||||
:dispatch [:protocol/state-sync-timed-out]}}
|
||||
(set (:utils/dispatch-later efx)))))
|
||||
(testing "Check the rest of effects."
|
||||
(is (contains? efx :web3/set-default-account))
|
||||
(is (contains? efx :web3/fetch-node-version))
|
||||
(is (json-rpc "net_version"))
|
||||
(is (json-rpc "eth_syncing"))
|
||||
(is (contains? efx :wallet/get-balance))
|
||||
(is (contains? efx :wallet/get-tokens-balance))
|
||||
(is (contains? efx :wallet/get-prices))))))
|
||||
|
||||
(deftest login-failed
|
||||
(testing
|
||||
|
Loading…
x
Reference in New Issue
Block a user