Compare commits

..
108 changed files with 1032 additions and 2197 deletions
@@ -92,11 +92,6 @@ public class EncryptionUtils extends ReactContextBaseJavaModule {
return Statusgo.hexToUtf8(str);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String serializeLegacyKey(final String publicKey) {
return Statusgo.serializeLegacyKey(publicKey);
}
@ReactMethod
public void setBlankPreviewFlag(final Boolean blankPreview) {
final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.reactContext);
@@ -94,10 +94,6 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(hexToUtf8:(NSString *)str) {
return StatusgoHexToUtf8(str);
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(serializeLegacyKey:(NSString *)str) {
return StatusgoSerializeLegacyKey(str);
}
RCT_EXPORT_METHOD(setBlankPreviewFlag:(BOOL *)newValue)
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
@@ -672,38 +672,6 @@ void _Sha3(const FunctionCallbackInfo<Value>& args) {
}
void _SerializeLegacyKey(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
if (args.Length() != 1) {
// Throw an Error that is passed back to JavaScript
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for SerializeLegacyKey")));
return;
}
// Check the argument types
if (!args[0]->IsString()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'str'")));
return;
}
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
char *arg0 = *arg0Obj;
// Call exported Go function, which returns a C string
char *c = SerializeLegacyKey(arg0);
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
args.GetReturnValue().Set(ret);
delete c;
}
void _ToChecksumAddress(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
@@ -2008,7 +1976,6 @@ void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "checkAddressChecksum", _CheckAddressChecksum);
NODE_SET_METHOD(exports, "isAddress", _IsAddress);
NODE_SET_METHOD(exports, "sha3", _Sha3);
NODE_SET_METHOD(exports, "serializeLegacyKey", _SerializeLegacyKey);
NODE_SET_METHOD(exports, "toChecksumAddress", _ToChecksumAddress);
NODE_SET_METHOD(exports, "logout", _Logout);
NODE_SET_METHOD(exports, "hashMessage", _HashMessage);
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

+37 -276
View File
@@ -1,277 +1,38 @@
(ns keycard.keycard
(:require
["react-native" :as rn]
["react-native-status-keycard" :default status-keycard]
[react-native.platform :as platform]
[taoensso.timbre :as log]
[utils.address :as address]))
(ns keycard.keycard)
(defonce event-emitter
(if platform/ios?
(new (.-NativeEventEmitter rn) status-keycard)
(.-DeviceEventEmitter rn)))
(defn start-nfc
[{:keys [on-success on-failure prompt-message]}]
(log/debug "start-nfc")
(.. status-keycard
(startNFC (str prompt-message))
(then on-success)
(catch on-failure)))
(defn stop-nfc
[{:keys [on-success on-failure error-message]}]
(log/debug "stop-nfc")
(.. status-keycard
(stopNFC (str error-message))
(then on-success)
(catch on-failure)))
(defn set-nfc-message
[{:keys [on-success on-failure status-message]}]
(log/debug "set-nfc-message")
(.. status-keycard
(setNFCMessage (str status-message))
(then on-success)
(catch on-failure)))
(defn check-nfc-support
[{:keys [on-success]}]
(.. status-keycard
nfcIsSupported
(then on-success)))
(defn check-nfc-enabled
[{:keys [on-success]}]
(.. status-keycard
nfcIsEnabled
(then on-success)))
(defn open-nfc-settings
[]
(.openNfcSettings status-keycard))
(defn remove-event-listeners
[]
(doseq [event ["keyCardOnConnected" "keyCardOnDisconnected" "keyCardOnNFCUserCancelled"
"keyCardOnNFCTimeout"]]
(.removeAllListeners ^js event-emitter event)))
(defn remove-event-listener
[^js event]
(when event
(.remove event)))
(defn on-card-connected
[callback]
(.addListener ^js event-emitter "keyCardOnConnected" callback))
(defn on-card-disconnected
[callback]
(.addListener ^js event-emitter "keyCardOnDisconnected" callback))
(defn on-nfc-user-cancelled
[callback]
(.addListener ^js event-emitter "keyCardOnNFCUserCancelled" callback))
(defn on-nfc-timeout
[callback]
(.addListener ^js event-emitter "keyCardOnNFCTimeout" callback))
(defn on-nfc-enabled
[callback]
(.addListener ^js event-emitter "keyCardOnNFCEnabled" callback))
(defn on-nfc-disabled
[callback]
(.addListener ^js event-emitter "keyCardOnNFCDisabled" callback))
(defn set-pairings
[pairings]
(.. status-keycard (setPairings (clj->js (or pairings {})))))
(defn get-application-info
[{:keys [on-success on-failure]}]
(.. status-keycard
(getApplicationInfo)
(then (fn [response]
(let [info (-> response
(js->clj :keywordize-keys true)
(update :key-uid address/normalized-hex))]
(on-success info))))
(catch on-failure)))
(defn factory-reset
[{:keys [on-success on-failure]}]
(.. status-keycard
(factoryReset)
(then (fn [response]
(let [info (-> response
(js->clj :keywordize-keys true)
(update :key-uid address/normalized-hex))]
(on-success info))))
(catch on-failure)))
(defn install-applet
[{:keys [on-success on-failure]}]
(.. status-keycard
installApplet
(then on-success)
(catch on-failure)))
(defn install-cash-applet
[{:keys [on-success on-failure]}]
(.. status-keycard
installCashApplet
(then on-success)
(catch on-failure)))
(defn init-card
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(init pin)
(then on-success)
(catch on-failure)))
(defn install-applet-and-init-card
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(installAppletAndInitCard pin)
(then on-success)
(catch on-failure)))
(defn pair
[{:keys [password on-success on-failure]}]
(when password
(.. status-keycard
(pair password)
(then on-success)
(catch on-failure))))
(defn generate-and-load-key
[{:keys [mnemonic pin on-success on-failure]}]
(.. status-keycard
(generateAndLoadKey mnemonic pin)
(then on-success)
(catch on-failure)))
(defn unblock-pin
[{:keys [puk new-pin on-success on-failure]}]
(when (and new-pin puk)
(.. status-keycard
(unblockPin puk new-pin)
(then on-success)
(catch on-failure))))
(defn verify-pin
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(verifyPin pin)
(then on-success)
(catch on-failure))))
(defn change-pin
[{:keys [current-pin new-pin on-success on-failure]}]
(when (and current-pin new-pin)
(.. status-keycard
(changePin current-pin new-pin)
(then on-success)
(catch on-failure))))
(defn change-puk
[{:keys [pin puk on-success on-failure]}]
(when (and pin puk)
(.. status-keycard
(changePUK pin puk)
(then on-success)
(catch on-failure))))
(defn change-pairing
[{:keys [pin pairing on-success on-failure]}]
(when (and pin pairing)
(.. status-keycard
(changePairingPassword pin pairing)
(then on-success)
(catch on-failure))))
(defn unpair
[{:keys [pin on-success on-failure]}]
(when pin
(.. status-keycard
(unpair pin)
(then on-success)
(catch on-failure))))
(defn delete
[{:keys [on-success on-failure]}]
(.. status-keycard
(delete)
(then on-success)
(catch on-failure)))
(defn remove-key
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(removeKey pin)
(then on-success)
(catch on-failure)))
(defn remove-key-with-unpair
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(removeKeyWithUnpair pin)
(then on-success)
(catch on-failure)))
(defn export-key
[{:keys [pin path on-success on-failure]}]
(.. status-keycard
(exportKeyWithPath pin path)
(then on-success)
(catch on-failure)))
(defn unpair-and-delete
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(unpairAndDelete pin)
(then on-success)
(catch on-failure))))
(defn import-keys
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(importKeys pin)
(then on-success)
(catch on-failure))))
(defn get-keys
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(getKeys pin)
(then on-success)
(catch on-failure))))
(defn sign
[{pin :pin path :path card-hash :hash on-success :on-success on-failure :on-failure}]
(when (and pin card-hash)
(if path
(.. status-keycard
(signWithPath pin path card-hash)
(then on-success)
(catch on-failure))
(.. status-keycard
(sign pin card-hash)
(then on-success)
(catch on-failure)))))
(defn sign-typed-data
[{card-hash :hash on-success :on-success on-failure :on-failure}]
(when card-hash
(.. status-keycard
(signPinless card-hash)
(then on-success)
(catch on-failure))))
(defprotocol Keycard
(start-nfc [this args])
(stop-nfc [this args])
(set-nfc-message [this args])
(check-nfc-support [this args])
(check-nfc-enabled [this args])
(open-nfc-settings [this])
(register-card-events [this args])
(set-pairings [this args])
(on-card-disconnected [this callback])
(on-card-connected [this callback])
(remove-event-listener [this event])
(remove-event-listeners [this])
(get-application-info [this args])
(factory-reset [this args])
(install-applet [this args])
(install-cash-applet [this args])
(init-card [this args])
(install-applet-and-init-card [this args])
(pair [this args])
(generate-and-load-key [this args])
(unblock-pin [this args])
(verify-pin [this args])
(change-pin [this args])
(change-puk [this args])
(change-pairing [this args])
(unpair [this args])
(delete [this args])
(remove-key [this args])
(remove-key-with-unpair [this args])
(export-key [this args])
(unpair-and-delete [this args])
(import-keys [this args])
(get-keys [this args])
(sign [this args])
(sign-typed-data [this args]))
+365
View File
@@ -0,0 +1,365 @@
(ns keycard.real-keycard
(:require
["react-native" :as rn]
["react-native-status-keycard" :default status-keycard]
[keycard.keycard :as keycard]
[react-native.platform :as platform]
[taoensso.timbre :as log]
[utils.address :as address]))
(defonce event-emitter
(if platform/ios?
(new (.-NativeEventEmitter rn) status-keycard)
(.-DeviceEventEmitter rn)))
(defonce active-listeners (atom []))
(defn start-nfc
[{:keys [on-success on-failure prompt-message]}]
(log/debug "start-nfc")
(.. status-keycard
(startNFC (str prompt-message))
(then on-success)
(catch on-failure)))
(defn stop-nfc
[{:keys [on-success on-failure error-message]}]
(log/debug "stop-nfc")
(.. status-keycard
(stopNFC (str error-message))
(then on-success)
(catch on-failure)))
(defn set-nfc-message
[{:keys [on-success on-failure status-message]}]
(log/debug "set-nfc-message")
(.. status-keycard
(setNFCMessage (str status-message))
(then on-success)
(catch on-failure)))
(defn check-nfc-support
[{:keys [on-success]}]
(.. status-keycard
nfcIsSupported
(then on-success)))
(defn check-nfc-enabled
[{:keys [on-success]}]
(.. status-keycard
nfcIsEnabled
(then on-success)))
(defn open-nfc-settings
[]
(.openNfcSettings status-keycard))
(defn remove-event-listeners
[]
(doseq [event ["keyCardOnConnected" "keyCardOnDisconnected" "keyCardOnNFCUserCancelled"
"keyCardOnNFCTimeout"]]
(.removeAllListeners ^js event-emitter event)))
(defn remove-event-listener
[^js event]
(.remove event))
(defn on-card-connected
[callback]
(.addListener ^js event-emitter "keyCardOnConnected" callback))
(defn on-card-disconnected
[callback]
(.addListener ^js event-emitter "keyCardOnDisconnected" callback))
(defn on-nfc-user-cancelled
[callback]
(.addListener ^js event-emitter "keyCardOnNFCUserCancelled" callback))
(defn on-nfc-timeout
[callback]
(.addListener ^js event-emitter "keyCardOnNFCTimeout" callback))
(defn on-nfc-enabled
[callback]
(.addListener ^js event-emitter "keyCardOnNFCEnabled" callback))
(defn on-nfc-disabled
[callback]
(.addListener ^js event-emitter "keyCardOnNFCDisabled" callback))
(defn set-pairings
[{:keys [pairings]}]
(.. status-keycard (setPairings (clj->js (or pairings {})))))
(defn register-card-events
[args]
(doseq [listener @active-listeners]
(remove-event-listener listener))
(reset! active-listeners
[(on-card-connected (:on-card-connected args))
(on-card-disconnected (:on-card-disconnected args))
(on-nfc-user-cancelled (:on-nfc-user-cancelled args))
(on-nfc-timeout (:on-nfc-timeout args))
(on-nfc-enabled (:on-nfc-enabled args))
(on-nfc-disabled (:on-nfc-disabled args))]))
(defn get-application-info
[{:keys [on-success on-failure]}]
(.. status-keycard
(getApplicationInfo)
(then (fn [response]
(let [info (-> response
(js->clj :keywordize-keys true)
(update :key-uid address/normalized-hex))]
(on-success info))))
(catch on-failure)))
(defn factory-reset
[{:keys [on-success on-failure]}]
(.. status-keycard
(factoryReset)
(then (fn [response]
(let [info (-> response
(js->clj :keywordize-keys true)
(update :key-uid address/normalized-hex))]
(on-success info))))
(catch on-failure)))
(defn install-applet
[{:keys [on-success on-failure]}]
(.. status-keycard
installApplet
(then on-success)
(catch on-failure)))
(defn install-cash-applet
[{:keys [on-success on-failure]}]
(.. status-keycard
installCashApplet
(then on-success)
(catch on-failure)))
(defn init-card
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(init pin)
(then on-success)
(catch on-failure)))
(defn install-applet-and-init-card
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(installAppletAndInitCard pin)
(then on-success)
(catch on-failure)))
(defn pair
[{:keys [password on-success on-failure]}]
(when password
(.. status-keycard
(pair password)
(then on-success)
(catch on-failure))))
(defn generate-and-load-key
[{:keys [mnemonic pin on-success on-failure]}]
(.. status-keycard
(generateAndLoadKey mnemonic pin)
(then on-success)
(catch on-failure)))
(defn unblock-pin
[{:keys [puk new-pin on-success on-failure]}]
(when (and new-pin puk)
(.. status-keycard
(unblockPin puk new-pin)
(then on-success)
(catch on-failure))))
(defn verify-pin
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(verifyPin pin)
(then on-success)
(catch on-failure))))
(defn change-pin
[{:keys [current-pin new-pin on-success on-failure]}]
(when (and current-pin new-pin)
(.. status-keycard
(changePin current-pin new-pin)
(then on-success)
(catch on-failure))))
(defn change-puk
[{:keys [pin puk on-success on-failure]}]
(when (and pin puk)
(.. status-keycard
(changePUK pin puk)
(then on-success)
(catch on-failure))))
(defn change-pairing
[{:keys [pin pairing on-success on-failure]}]
(when (and pin pairing)
(.. status-keycard
(changePairingPassword pin pairing)
(then on-success)
(catch on-failure))))
(defn unpair
[{:keys [pin on-success on-failure]}]
(when pin
(.. status-keycard
(unpair pin)
(then on-success)
(catch on-failure))))
(defn delete
[{:keys [on-success on-failure]}]
(.. status-keycard
(delete)
(then on-success)
(catch on-failure)))
(defn remove-key
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(removeKey pin)
(then on-success)
(catch on-failure)))
(defn remove-key-with-unpair
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(removeKeyWithUnpair pin)
(then on-success)
(catch on-failure)))
(defn export-key
[{:keys [pin path on-success on-failure]}]
(.. status-keycard
(exportKeyWithPath pin path)
(then on-success)
(catch on-failure)))
(defn unpair-and-delete
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(unpairAndDelete pin)
(then on-success)
(catch on-failure))))
(defn import-keys
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(importKeys pin)
(then on-success)
(catch on-failure))))
(defn get-keys
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(getKeys pin)
(then on-success)
(catch on-failure))))
(defn sign
[{pin :pin path :path card-hash :hash on-success :on-success on-failure :on-failure}]
(when (and pin card-hash)
(if path
(.. status-keycard
(signWithPath pin path card-hash)
(then on-success)
(catch on-failure))
(.. status-keycard
(sign pin card-hash)
(then on-success)
(catch on-failure)))))
(defn sign-typed-data
[{card-hash :hash on-success :on-success on-failure :on-failure}]
(when card-hash
(.. status-keycard
(signPinless card-hash)
(then on-success)
(catch on-failure))))
(defrecord RealKeycard []
keycard/Keycard
(keycard/start-nfc [_this args]
(start-nfc args))
(keycard/stop-nfc [_this args]
(stop-nfc args))
(keycard/set-nfc-message [_this args]
(set-nfc-message args))
(keycard/check-nfc-support [_this args]
(check-nfc-support args))
(keycard/check-nfc-enabled [_this args]
(check-nfc-enabled args))
(keycard/open-nfc-settings [_this]
(open-nfc-settings))
(keycard/register-card-events [_this args]
(register-card-events args))
(keycard/on-card-connected [_this callback]
(on-card-connected callback))
(keycard/on-card-disconnected [_this callback]
(on-card-disconnected callback))
(keycard/remove-event-listener [_this event]
(remove-event-listener event))
(keycard/remove-event-listeners [_this]
(remove-event-listeners))
(keycard/set-pairings [_this args]
(set-pairings args))
(keycard/get-application-info [_this args]
(get-application-info args))
(keycard/factory-reset [_this args]
(factory-reset args))
(keycard/install-applet [_this args]
(install-applet args))
(keycard/install-cash-applet [_this args]
(install-cash-applet args))
(keycard/init-card [_this args]
(init-card args))
(keycard/install-applet-and-init-card [_this args]
(install-applet-and-init-card args))
(keycard/pair [_this args]
(pair args))
(keycard/generate-and-load-key [_this args]
(generate-and-load-key args))
(keycard/unblock-pin [_this args]
(unblock-pin args))
(keycard/verify-pin [_this args]
(verify-pin args))
(keycard/change-pin [_this args]
(change-pin args))
(keycard/change-puk [_this args]
(change-puk args))
(keycard/change-pairing [_this args]
(change-pairing args))
(keycard/unpair [_this args]
(unpair args))
(keycard/delete [_this args]
(delete args))
(keycard/remove-key [_this args]
(remove-key args))
(keycard/remove-key-with-unpair [_this args]
(remove-key-with-unpair args))
(keycard/export-key [_this args]
(export-key args))
(keycard/unpair-and-delete [_this args]
(unpair-and-delete args))
(keycard/import-keys [_this args]
(import-keys args))
(keycard/get-keys [_this args]
(get-keys args))
(keycard/sign [_this args]
(sign args))
(keycard/sign-typed-data [_this args]
(sign-typed-data args)))
@@ -1,14 +1,12 @@
(ns legacy.status-im.ui.screens.peers-stats
(:require
[quo.foundations.colors :as colors]
[react-native.core :as rn]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn peers-stats
[]
(let [peers-count (rf/sub [:peer-stats/count])
theme (rf/sub [:theme])]
(let [peers-count (rf/sub [:peer-stats/count])]
(rn/use-mount
(fn []
(rf/dispatch [:peer-stats/get-count])))
@@ -20,5 +18,4 @@
{:style {:flex-direction :row
:margin-vertical 8
:justify-content :space-between}}
[rn/text {:style {:color (colors/theme-colors colors/neutral-100 colors/white theme)}}
(str (i18n/label :t/peers-count) ": " peers-count)]]]))
[rn/text (str (i18n/label :t/peers-count) ": " peers-count)]]]))
@@ -0,0 +1,58 @@
(ns legacy.status-im.utils.keychain.core
(:require
[oops.core :as oops]
[re-frame.core :as re-frame]
[react-native.keychain :as keychain]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(defn- whisper-key-name
[address]
(str address "-whisper"))
(re-frame/reg-fx
:keychain/get-keycard-keys
(fn [[key-uid callback]]
(keychain/get-credentials
key-uid
(fn [encryption-key-data]
(if encryption-key-data
(keychain/get-credentials
(whisper-key-name key-uid)
(fn [whisper-key-data]
(if whisper-key-data
(callback [(oops/oget encryption-key-data "password")
(oops/oget whisper-key-data "password")])
(callback nil))))
(callback nil))))))
(re-frame/reg-fx
:keychain/save-keycard-keys
(fn [[key-uid encryption-public-key whisper-private-key]]
(keychain/save-credentials
key-uid
key-uid
encryption-public-key
#(when-not %
(log/error
(str "Error while saving encryption-public-key"))))
(keychain/save-credentials
(whisper-key-name key-uid)
key-uid
whisper-private-key
#(when-not %
(log/error
(str "Error while saving whisper-private-key"))))))
(rf/defn get-keycard-keys
[_ key-uid]
{:keychain/get-keycard-keys
[key-uid
#(re-frame/dispatch
[:multiaccounts.login.callback/get-keycard-keys-success key-uid %])]})
(rf/defn save-keycard-keys
[_ key-uid encryption-public-key whisper-private-key]
{:keychain/save-keycard-keys [key-uid
encryption-public-key
whisper-private-key]})
+2 -5
View File
@@ -110,11 +110,8 @@
(def status-keycard
#js
{:default #js
{:nfcIsSupported (fn [] #js {:then identity})
:nfcIsEnabled (fn [] #js {:then identity})
:getApplicationInfo (fn [] #js {:then identity})
:getKeys (fn [] #js {:then identity})
:setPairings (fn [] #js {:then identity})}})
{:nfcIsSupported (fn [] #js {:then identity})
:nfcIsEnabled (fn [] #js {:then identity})}})
(def snoopy #js {:default #js {}})
(def snoopy-filter #js {:default #js {}})
+95 -5
View File
@@ -87,6 +87,31 @@
config
#(callback (types/json->clj %))))
(defn save-multiaccount-and-login-with-keycard
"NOTE: chat-key is a whisper private key sent from keycard"
[key-uid multiaccount-data password settings config accounts-data chat-key]
(log/debug "[native-module] save-account-and-login-with-keycard")
(init-keystore
key-uid
#(.saveAccountAndLoginWithKeycard
^js (account-manager)
multiaccount-data
password
settings
config
accounts-data
chat-key)))
(defn login-with-config
"NOTE: beware, the password has to be sha3 hashed"
[key-uid account-data hashed-password config]
(log/debug "[native-module] loginWithConfig")
(clear-web-data)
(let [config (if config (types/clj->json config) "")]
(init-keystore
key-uid
#(.loginWithConfig ^js (account-manager) account-data hashed-password config))))
(defn login-account
"NOTE: beware, the password has to be sha3 hashed"
[{:keys [keyUid] :as request}]
@@ -128,6 +153,19 @@
(clear-web-data)
(.logout ^js (account-manager)))
(defn multiaccount-load-account
"NOTE: beware, the password has to be sha3 hashed
this function is used after storing an account when you still want to
derive accounts from it, because saving an account flushes the loaded keys
from memory"
[address hashed-password callback]
(log/debug "[native-module] multiaccount-load-account")
(.multiAccountLoadAccount ^js (account-manager)
(types/clj->json {:address address
:password hashed-password})
callback))
(defn multiaccount-derive-addresses
"NOTE: this should be named derive-accounts
this only derive addresses, they still need to be stored
@@ -141,6 +179,38 @@
:paths paths})
callback)))
(defn multiaccount-store-account
"NOTE: beware, the password has to be sha3 hashed
this stores the account and flush keys in memory so
in order to also store derived accounts like initial wallet
and chat accounts, you need to load the account again with
`multiaccount-load-account` before using `multiaccount-store-derived`
and the id of the account stored will have changed"
[account-id key-uid hashed-password callback]
(log/debug "[native-module] multiaccount-store-account")
(when (status)
(init-keystore
key-uid
#(.multiAccountStoreAccount ^js (account-manager)
(types/clj->json {:accountID account-id
:password hashed-password})
callback))))
(defn multiaccount-store-derived
"NOTE: beware, the password has to be sha3 hashed"
[account-id key-uid paths hashed-password callback]
(log/debug "[native-module] multiaccount-store-derived"
"account-id"
account-id)
(init-keystore
key-uid
#(.multiAccountStoreDerived ^js (account-manager)
(types/clj->json {:accountID account-id
:paths paths
:password hashed-password})
callback)))
(defn multiaccount-generate-and-derive-addresses
"used to generate multiple multiaccounts for onboarding
NOTE: nothing is saved so you will need to use
@@ -164,12 +234,37 @@
:Bip39Passphrase password})
callback))
(defn multiaccount-import-private-key
[private-key callback]
(log/debug "[native-module] multiaccount-import-private-key")
(.multiAccountImportPrivateKey ^js (account-manager)
(types/clj->json {:privateKey private-key})
callback))
(defn verify
"NOTE: beware, the password has to be sha3 hashed"
[address hashed-password callback]
(log/debug "[native-module] verify")
(.verify ^js (account-manager) address hashed-password callback))
(defn verify-database-password
"NOTE: beware, the password has to be sha3 hashed"
[key-uid hashed-password callback]
(log/debug "[native-module] verify-database-password")
(.verifyDatabasePassword ^js (account-manager) key-uid hashed-password callback))
(defn login-with-keycard
[{:keys [key-uid multiaccount-data password chat-key node-config]}]
(log/debug "[native-module] login-with-keycard")
(clear-web-data)
(init-keystore
key-uid
#(.loginWithKeycard ^js (account-manager)
multiaccount-data
password
chat-key
(types/clj->json node-config))))
(defn set-soft-input-mode
[mode]
(log/debug "[native-module] set-soft-input-mode")
@@ -238,11 +333,6 @@
:key input-key})
(.deserializeAndCompressKey ^js (encryption) input-key callback))
(defn serialize-legacy-key
"Compresses an old format public key (0x04...) to the new one zQ..."
[public-key]
(.serializeLegacyKey ^js (encryption) public-key))
(defn compressed-key->public-key
"Provides compressed key to status-go and gets back the uncompressed public key via deserialization"
[public-key deserialization-key callback]
@@ -5,7 +5,6 @@
(defn- get-dimensions
[size]
(case size
:size-32 32
:size-24 24
:size-20 20
nil))
@@ -1,57 +0,0 @@
(ns quo.components.list-items.approval-info.component-spec
(:require [quo.components.list-items.approval-info.view :as approval-info]
[test-helpers.component :as h]))
(h/describe "List Items: Approval Info"
(h/test "should render correctly with basic props"
(h/render-with-theme-provider
[approval-info/view
{:type :spending-cap
:label "Spending Cap"
:avatar-props {:image "image"}}])
(h/is-truthy (h/get-by-label-text :approval-info)))
(h/test "should render correctly with label & description"
(h/render-with-theme-provider
[approval-info/view
{:type :spending-cap
:label "Spending Cap"
:description "Description"
:avatar-props {:image "image"}}])
(h/is-truthy (h/get-by-text "Spending Cap"))
(h/is-truthy (h/get-by-text "Description")))
(h/test "on-button-press event is called when button is pressed"
(let [on-button-press (h/mock-fn)]
(h/render-with-theme-provider
[approval-info/view
{:type :spending-cap
:label "Spending Cap"
:button-label "Edit"
:on-button-press on-button-press
:avatar-props {:image "image"}}])
(h/fire-event :press (h/get-by-text "Edit"))
(h/was-called on-button-press)))
(h/test "on-option-press event is called when option icon is pressed"
(let [on-option-press (h/mock-fn)]
(h/render-with-theme-provider
[approval-info/view
{:type :spending-cap
:label "Spending Cap"
:option-icon :i/options
:on-option-press on-option-press
:avatar-props {:image "image"}}])
(h/fire-event :press (h/get-by-label-text :icon))
(h/was-called on-option-press)))
(h/test "on-avatar-press event is called when avatar is pressed"
(let [on-avatar-press (h/mock-fn)]
(h/render-with-theme-provider
[approval-info/view
{:type :spending-cap
:label "Spending Cap"
:on-avatar-press on-avatar-press
:avatar-props {:image "image"}}])
(h/fire-event :press (h/get-by-label-text :token-avatar))
(h/was-called on-avatar-press))))
@@ -1,36 +0,0 @@
(ns quo.components.list-items.approval-info.style
(:require [quo.foundations.colors :as colors]))
(defn icon-description-color
[blur? theme]
(if blur?
colors/white-opa-40
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
(defn container
[description? blur? theme]
{:flex-direction :row
:padding-horizontal 12
:padding-vertical (if description? 8 12)
:border-radius 16
:gap 8
:align-items :center
:border-width 1
:border-color (if blur?
colors/white-opa-5
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
(def labels
{:flex 1
:justify-content :center
:padding-right 4})
(defn label
[blur? theme]
{:color (if blur?
colors/white
(colors/theme-colors colors/neutral-100 colors/white theme))})
(defn description
[blur? theme]
{:color (icon-description-color blur? theme)})
@@ -1,124 +0,0 @@
(ns quo.components.list-items.approval-info.view
(:require [clojure.string :as string]
[quo.components.avatars.account-avatar.view :as account-avatar]
[quo.components.avatars.collection-avatar.view :as collection-avatar]
[quo.components.avatars.community-avatar.view :as community-avatar]
[quo.components.avatars.dapp-avatar.view :as dapp-avatar]
[quo.components.avatars.icon-avatar :as icon-avatar]
[quo.components.avatars.token-avatar.view :as token-avatar]
[quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar]
[quo.components.buttons.button.view :as button]
[quo.components.icon :as icon]
[quo.components.list-items.approval-info.style :as style]
[quo.components.markdown.text :as text]
[quo.components.tags.tiny-tag.view :as tiny-tag]
[quo.foundations.colors :as colors]
quo.theme
[react-native.core :as rn]
[schema.core :as schema]))
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:type
[:enum :spending-cap :token-contract :account :spending-contract :network :date-signed
:collectible :address :community :collectible-contract]]
[:avatar-props :map]
[:label :string]
[:description {:optional true} [:maybe :string]]
[:button-label {:optional true} [:maybe :string]]
[:button-icon {:optional true} [:maybe :keyword]]
[:blur? {:optional true} [:maybe :boolean]]
[:unlimited-icon? {:optional true} [:maybe :boolean]]
[:option-icon {:optional true} [:maybe :keyword]]
[:tag-label {:optional true} [:maybe :string]]
[:on-button-press {:optional true} [:maybe fn?]]
[:on-avatar-press {:optional true} [:maybe fn?]]
[:on-option-press {:optional true} [:maybe fn?]]
[:container-style {:optional true} [:maybe :any]]]]]
:any])
(defn- avatar
[{:keys [type avatar-props blur? theme on-press]}]
[rn/pressable {:on-press on-press}
(case type
:account [account-avatar/view (assoc avatar-props :size 32)]
:collectible-contract [collection-avatar/view (assoc avatar-props :size :size-32)]
:spending-contract [dapp-avatar/view avatar-props]
:date-signed [icon-avatar/icon-avatar
(assoc avatar-props
:size :size-32
:opacity 10
:color (if blur?
colors/white
(colors/theme-colors colors/neutral-50
colors/neutral-40
theme)))]
:address [wallet-user-avatar/wallet-user-avatar
(assoc avatar-props
:size :size-32
:monospace? true
:lowercase? true
:neutral? true)]
:community [community-avatar/view avatar-props]
[token-avatar/view
(assoc avatar-props
:type
(if (= type :collectible) :collectible :asset))])])
(defn- view-internal
[{:keys [type avatar-props label description blur? unlimited-icon? container-style
on-option-press on-avatar-press on-button-press button-label button-icon tag-label
option-icon]}]
(let [theme (quo.theme/use-theme)
description? (not (string/blank? description))]
[rn/view
{:style (merge (style/container description? blur? theme) container-style)
:accessibility-label :approval-info}
[avatar
{:type type
:blur? blur?
:theme theme
:on-press on-avatar-press
:avatar-props avatar-props}]
[rn/view
{:style style/labels}
[rn/view
{:style {:flex-direction :row :align-items :center}}
[text/text
{:size :paragraph-1
:weight (if (= type :address) :monospace :semi-bold)
:style (style/label blur? theme)}
label]
(when unlimited-icon?
[icon/icon :i/alert
{:container-style {:margin-left 4}
:size 16
:color (style/icon-description-color blur? theme)}])]
(when description?
[text/text
{:size :paragraph-2
:weight (if (contains? #{:collectible-contract :spending-contract :account :token-contract}
type)
:monospace
:regular)
:style (style/description blur? theme)}
description])]
(when (= type :account) [tiny-tag/view {:label tag-label}])
(when (= type :spending-cap)
[button/button
{:type :outline
:size 24
:blur? blur?
:icon-left button-icon
:on-press on-button-press}
button-label])
(when option-icon
[rn/pressable {:on-press on-option-press}
[icon/icon option-icon
{:color (style/icon-description-color blur? theme)
:size 20}]])]))
(def view (schema/instrument #'view-internal ?schema))
@@ -1,43 +0,0 @@
(ns quo.components.pin-input.pin.view
(:require [quo.foundations.colors :as colors]
quo.theme
[react-native.core :as rn]))
(defn view
[{:keys [theme state blur?]}]
(let [app-theme (quo.theme/use-theme)
theme (or theme app-theme)]
[rn/view {:style {:width 36 :height 36 :align-items :center :justify-content :center}}
(case state
:active
[rn/view
{:style {:width 16
:height 16
:border-radius 8
:background-color (if blur?
colors/white-opa-20
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme))}}]
:filled
[rn/view
{:style {:width 16
:height 16
:border-radius 8
:background-color (if blur?
colors/white
(colors/theme-colors colors/neutral-100 colors/white theme))}}]
:error
[rn/view
{:style {:width 16
:height 16
:border-radius 8
:background-color (if blur?
colors/danger-60
(colors/theme-colors colors/danger-50 colors/danger-60 theme))}}]
[rn/view
{:style
{:width 12
:height 12
:border-radius 6
:background-color (if blur?
colors/white-opa-20
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme))}}])]))
-27
View File
@@ -1,27 +0,0 @@
(ns quo.components.pin-input.view
(:require [quo.components.markdown.text :as text]
[quo.components.pin-input.pin.view :as pin]
[quo.foundations.colors :as colors]
quo.theme
[react-native.core :as rn]))
(defn view
[{:keys [number-of-pins number-of-filled-pins error? info]
:or {number-of-pins 6 number-of-filled-pins 0}}]
(let [theme (quo.theme/use-theme)]
[rn/view {:style {:align-items :center}}
[rn/view {:style {:flex-direction :row}}
(for [i (range 1 (inc number-of-pins))]
^{:key i}
[pin/view
{:state (cond
error? :error
(<= i number-of-filled-pins) :filled
(= i (inc number-of-filled-pins)) :active)}])]
(when info
[text/text
{:style {:color (if error?
(colors/theme-colors colors/danger-50 colors/danger-60 theme)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}
:size :paragraph-2}
info])]))
@@ -159,19 +159,4 @@
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
(h/is-truthy (h/query-by-label-text :account-emoji)))
(h/test "edit icon is visible when subtitle type is editable"
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:card? true
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :editable
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
(h/is-truthy (h/query-by-label-text :edit-icon))))
(h/is-truthy (h/query-by-label-text :account-emoji))))
@@ -54,7 +54,6 @@
(def subtitle-container
{:flex-direction :row
:align-items :center
:margin-bottom 1})
(def right-container
@@ -63,7 +62,7 @@
(defn subtitle-icon-container
[subtitle-type]
{:margin-right (when-not (contains? #{:editable :default} subtitle-type) 4)
{:margin-right (when (not= :default subtitle-type) 4)
:justify-content :center})
(defn title
@@ -7,8 +7,7 @@
[quo.components.settings.data-item.style :as style]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[schema.core :as schema]))
[react-native.core :as rn]))
(defn- left-loading
[{:keys [size blur?]}]
@@ -41,17 +40,7 @@
{:weight :medium
:size :paragraph-2
:style (style/description blur? theme)}
subtitle]
(when (= subtitle-type :editable)
[icons/icon :i/edit
{:accessibility-label :edit-icon
:size 12
:container-style {:margin-left 2}
:color (if blur?
colors/neutral-40
(colors/theme-colors colors/neutral-50
colors/neutral-40
theme))}])]))
subtitle]]))
(defn- left-title
[{:keys [title blur?]}]
@@ -111,31 +100,7 @@
:color icon-color
:size 20}]])]))
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:blur? {:optional true} [:maybe :boolean]]
[:card? {:optional true} [:maybe :boolean]]
[:right-icon {:optional true} [:maybe :keyword]]
[:right-content {:optional true} [:maybe :map]]
[:status {:optional true} [:maybe [:enum :default :loading]]]
[:subtitle-type {:optional true} [:maybe [:enum :default :icon :network :account :editable]]]
[:size {:optional true} [:maybe [:enum :default :small :large]]]
[:title :string]
[:subtitle {:optional true} [:maybe :string]]
[:custom-subtitle {:optional true} [:maybe fn?]]
[:icon {:optional true} [:maybe :keyword]]
[:emoji {:optional true} [:maybe :string]]
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
[:network-image {:optional true} [:maybe :schema.common/image-source]]
[:on-press {:optional true} [:maybe fn?]]
[:container-style {:optional true} [:maybe :map]]]]]
:any])
(defn view-internal
(defn view
[{:keys [blur? card? right-icon right-content status size on-press container-style]
:as props}]
(let [theme (quo.theme/use-theme)
@@ -158,5 +123,3 @@
{:right-icon right-icon
:right-content right-content
:icon-color icon-color}])]))
(def view (schema/instrument #'view-internal ?schema))
@@ -5,9 +5,8 @@
[:catn
[:props
[:map
[:type [:enum :status-account :saved-account :account :user :token]]
[:type [:enum :status-account :saved-account :account :user]]
[:account-props {:optional true} [:maybe :map]]
[:token-props {:optional true} [:maybe :map]]
[:networks? {:optional true} [:maybe :boolean]]
[:values {:optional true} [:maybe :map]]]]]
:any])
@@ -4,7 +4,6 @@
[quo.components.avatars.user-avatar.view :as user-avatar]
[quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar]
[quo.components.markdown.text :as text]
[quo.components.utilities.token.view :as token]
[quo.components.wallet.summary-info.schema :as summary-info-schema]
[quo.components.wallet.summary-info.style :as style]
[quo.foundations.colors :as colors]
@@ -59,14 +58,13 @@
:theme theme}])]))
(defn- view-internal
[{:keys [type account-props token-props networks? values]}]
[{:keys [type account-props networks? values]}]
(let [theme (quo.theme/use-theme)]
[rn/view
{:style (style/container networks? theme)}
[rn/view
{:style style/info-container}
(case type
:token [token/view (select-keys token-props #{:token :size})]
:status-account [account-avatar/view account-props]
:saved-account [wallet-user-avatar/wallet-user-avatar (assoc account-props :size :size-32)]
:account [wallet-user-avatar/wallet-user-avatar
@@ -75,8 +73,7 @@
:neutral? true)]
[user-avatar/user-avatar account-props])
[rn/view {:style {:margin-left 8}}
(when (not= type :account)
[text/text {:weight :semi-bold} (or (:name account-props) (:label token-props))])
(when (not= type :account) [text/text {:weight :semi-bold} (:name account-props)])
[rn/view
{:style {:flex-direction :row
:align-items :center}}
@@ -94,7 +91,7 @@
:weight (when (= type :account) :semi-bold)
:style {:color (when (not= type :account)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}}
(or (:address account-props) (:address token-props))]]]]
(:address account-props)]]]]
(when networks?
[:<>
[rn/view
-6
View File
@@ -86,7 +86,6 @@
quo.components.list-items.account-list-card.view
quo.components.list-items.account.view
quo.components.list-items.address.view
quo.components.list-items.approval-info.view
quo.components.list-items.channel.view
quo.components.list-items.community.view
quo.components.list-items.dapp.view
@@ -121,7 +120,6 @@
quo.components.overlay.view
quo.components.password.password-tips.view
quo.components.password.tips.view
quo.components.pin-input.view
quo.components.profile.collectible-list-item.view
quo.components.profile.collectible.view
quo.components.profile.expanded-collectible.view
@@ -322,9 +320,6 @@
(def keyboard-key quo.components.numbered-keyboard.keyboard-key.view/view)
(def numbered-keyboard quo.components.numbered-keyboard.numbered-keyboard.view/view)
;;;; PIN input
(def pin-input quo.components.pin-input.view/view)
;;;; Links
(def internal-link-card quo.components.links.internal-link-card.view/view)
(def link-preview quo.components.links.link-preview.view/view)
@@ -335,7 +330,6 @@
(def account-item quo.components.list-items.account.view/view)
(def account-list-card quo.components.list-items.account-list-card.view/view)
(def address quo.components.list-items.address.view/view)
(def approval-info quo.components.list-items.approval-info.view/view)
(def channel quo.components.list-items.channel.view/view)
(def community-list quo.components.list-items.community.view/view)
(def dapp quo.components.list-items.dapp.view/view)
-1
View File
@@ -55,7 +55,6 @@
quo.components.links.url-preview.component-spec
quo.components.list-items.account.component-spec
quo.components.list-items.address.component-spec
quo.components.list-items.approval-info.component-spec
quo.components.list-items.channel.component-spec
quo.components.list-items.community.component-spec
quo.components.list-items.dapp.component-spec
+15 -71
View File
@@ -1,91 +1,35 @@
(ns react-native.wallet-connect
(:require
["@walletconnect/core" :as wc-core]
["@walletconnect/utils" :as wc-utils]
["@walletconnect/web3wallet$default" :as Web3Wallet]
[cljs-bean.core :as bean]
[oops.core :as oops]))
["@walletconnect/core" :refer [Core]]
["@walletconnect/utils" :refer
[buildApprovedNamespaces getSdkError parseUri]]
["@walletconnect/web3wallet" :refer [Web3Wallet]]))
(defn- wallet-connect-core
[project-id]
(new ^js wc-core/Core (clj->js {:projectId project-id})))
(Core. #js {:projectId project-id}))
(defn init
[project-id metadata]
(let [core (wallet-connect-core project-id)]
(oops/ocall Web3Wallet
"init"
(bean/->js {:core core
:metadata metadata}))))
(Web3Wallet.init
(clj->js {:core core
:metadata metadata}))))
(defn build-approved-namespaces
[proposal supported-namespaces]
(oops/ocall wc-utils
"buildApprovedNamespaces"
(bean/->js {:proposal proposal
:supportedNamespaces supported-namespaces})))
(buildApprovedNamespaces
(clj->js {:proposal proposal
:supportedNamespaces supported-namespaces})))
;; Get an error from this list:
;; https://github.com/WalletConnect/walletconnect-monorepo/blob/c6e9529418a0c81d4efcc6ac4e61f242a50b56c5/packages/utils/src/errors.ts
(defn get-sdk-error
[error-key]
(oops/ocall wc-utils "getSdkError" error-key))
(getSdkError error-key))
(defn parse-uri
[uri]
(-> (oops/ocall wc-utils "parseUri" uri)
(bean/->clj)))
(defn respond-session-request
[{:keys [web3-wallet topic id result error]}]
(oops/ocall web3-wallet
"respondSessionRequest"
(bean/->js {:topic topic
:response
(merge {:id id
:jsonrpc "2.0"}
(when result
{:result result})
(when error
{:error error}))})))
(defn reject-session
[{:keys [web3-wallet id reason]}]
(.rejectSession web3-wallet
(clj->js {:id id
:reason reason})))
(defn approve-session
[{:keys [web3-wallet id approved-namespaces]}]
(oops/ocall web3-wallet
"approveSession"
(bean/->js {:id id
:namespaces approved-namespaces})))
(defn get-active-sessions
[web3-wallet]
(oops/ocall web3-wallet "getActiveSessions"))
(defn core-pairing-disconnnect
[web3-wallet topic]
(oops/ocall web3-wallet
"core.pairing.disconnect"
(bean/->js {:topic topic})))
(defn core-pairing-pair
[web3-wallet url]
(oops/ocall web3-wallet
"core.pairing.pair"
(bean/->js {:uri url})))
(defn get-pairings
[web3-wallet]
(oops/ocall web3-wallet "core.pairing.getPairings"))
(defn register-handler
[{:keys [web3-wallet event handler]}]
(oops/ocall web3-wallet
"on"
event
#(-> (bean/->clj %)
handler)))
(-> uri
parseUri
(js->clj :keywordize-keys true)))
+3 -5
View File
@@ -63,10 +63,8 @@
(defn view
[{:keys [hide? insets]}
{:keys [content selected-item padding-bottom-override border-radius on-close shell?
gradient-cover? customization-color hide-handle? blur-radius
hide-on-background-press?]
:or {border-radius 12
hide-on-background-press? true}}]
gradient-cover? customization-color hide-handle? blur-radius]
:or {border-radius 12}}]
(let [theme (quo.theme/use-theme)
{window-height :height} (rn/get-window)
[sheet-height set-sheet-height] (rn/use-state 0)
@@ -121,7 +119,7 @@
:on-layout handle-layout-height}
;; backdrop
[rn/pressable
{:on-press #(when hide-on-background-press? (rf/dispatch [:hide-bottom-sheet]))
{:on-press #(rf/dispatch [:hide-bottom-sheet])
:style {:flex 1}}
[reanimated/view
{:style (reanimated/apply-animations-to-style
+14 -39
View File
@@ -144,10 +144,6 @@
(fn [_ [opts]]
{:keychain/save-password-and-auth-method opts}))
(defn- whisper-key-name
[address]
(str address "-whisper"))
;; NOTE: migrating the plaintext password in the keychain
;; with the hashed one. Added due to the sync onboarding
;; flow, where the password arrives already hashed.
@@ -155,38 +151,17 @@
:keychain/password-hash-migration
(fn [{:keys [key-uid callback]
:or {callback identity}}]
(keychain/get-credentials
(whisper-key-name key-uid)
(fn [whisper-key-data]
(if whisper-key-data
(callback) ;; we don't need to migrate keycard password
(-> (get-password-migration! key-uid identity)
(.then (fn [migrated?]
(if migrated?
(callback)
(-> (get-user-password! key-uid identity)
(.then security/hash-masked-password)
(.then #(save-user-password! key-uid %))
(.then #(save-password-migration! key-uid))
(.then callback)))))
(.catch (fn [err]
(log/error "Failed to migrate the keychain password"
{:error err
:key-uid key-uid
:event :keychain/password-hash-migration})))))))))
(re-frame/reg-fx
:keychain/get-keycard-keys
(fn [[key-uid callback]]
(keychain/get-credentials
key-uid
(fn [encryption-key-data]
(if encryption-key-data
(keychain/get-credentials
(whisper-key-name key-uid)
(fn [whisper-key-data]
(if whisper-key-data
(callback [(oops/oget encryption-key-data "password")
(oops/oget whisper-key-data "password")])
(callback nil))))
(callback nil))))))
(-> (get-password-migration! key-uid identity)
(.then (fn [migrated?]
(if migrated?
(callback)
(-> (get-user-password! key-uid identity)
(.then security/hash-masked-password)
(.then #(save-user-password! key-uid %))
(.then #(save-password-migration! key-uid))
(.then callback)))))
(.catch (fn [err]
(log/error "Failed to migrate the keychain password"
{:error err
:key-uid key-uid
:event :keychain/password-hash-migration}))))))
+1 -3
View File
@@ -25,9 +25,7 @@
:invite-friends (js/require "../resources/images/ui2/invite-friends.png")
:transaction-progress (js/require "../resources/images/ui2/transaction-progress.png")
:welcome-illustration (js/require "../resources/images/ui2/welcome_illustration.png")
:notifications (js/require "../resources/images/ui2/notifications.png")
:nfc-prompt (js/require "../resources/images/ui2/nfc-prompt.png")
:nfc-success (js/require "../resources/images/ui2/nfc-success.png")})
:notifications (js/require "../resources/images/ui2/notifications.png")})
(def ui-themed
{:angry-man
@@ -10,14 +10,11 @@
(defn authorize
[{:keys [db]} [args]]
(let [key-uid (get-in db [:profile/profile :key-uid])
keycard? (get-in db [:profile/profile :keycard-pairing])]
(let [key-uid (get-in db [:profile/profile :key-uid])]
{:fx [[:effects.biometric/check-if-available
{:key-uid key-uid
:on-success #(rf/dispatch [:standard-auth/authorize-with-biometric args])
:on-fail (if keycard?
#(rf/dispatch [:standard-auth/authorize-with-keycard args])
#(rf/dispatch [:standard-auth/authorize-with-password args]))}]]}))
:on-fail #(rf/dispatch [:standard-auth/authorize-with-password args])}]]}))
(schema/=> authorize events-schema/?authorize)
(rf/reg-event-fx :standard-auth/authorize authorize)
@@ -48,11 +45,8 @@
(defn on-biometric-success
[{:keys [db]} [on-auth-success]]
(let [key-uid (get-in db [:profile/profile :key-uid])
keycard? (get-in db [:profile/profile :keycard-pairing])]
{:fx [(if keycard?
[:keychain/get-keycard-keys [key-uid on-auth-success]]
[:keychain/get-user-password [key-uid on-auth-success]])
(let [key-uid (get-in db [:profile/profile :key-uid])]
{:fx [[:keychain/get-user-password [key-uid on-auth-success]]
[:dispatch [:standard-auth/set-success true]]
[:dispatch [:standard-auth/reset-login-password]]]}))
-4
View File
@@ -126,7 +126,6 @@
(def ^:const profile-pictures-visibility-none 3)
(def ^:const min-password-length 6)
(def ^:const pincode-length 6)
(def ^:const new-password-min-length 10)
(def ^:const max-group-chat-participants 20)
(def ^:const max-group-chat-name-length 24)
@@ -566,6 +565,3 @@
(def ^:const default-slippage 0.5)
(def ^:const max-recommended-slippage 5)
(def ^:const max-slippage-decimal-places 2)
(def ^:const swap-default-provider
{:name "Paraswap"
:terms-and-conditions-url "https://files.paraswap.io/tos_v4.pdf"})
@@ -18,7 +18,7 @@
(defn do-init-permission-addresses
[{:keys [db]} [community-id revealed-accounts]]
(let [wallet-accounts (utils/sorted-operable-non-watch-only-accounts db)
(let [wallet-accounts (utils/sorted-non-watch-only-accounts db)
addresses-to-reveal (if (seq revealed-accounts)
(set (keys revealed-accounts))
;; Reveal all addresses as fallback.
@@ -62,7 +62,7 @@
status-go will default to all available."
[{:keys [db]} [{:keys [community-id password on-success addresses airdrop-address]}]]
(let [pub-key (get-in db [:profile/profile :public-key])
wallet-accounts (utils/sorted-operable-non-watch-only-accounts db)
wallet-accounts (utils/sorted-non-watch-only-accounts db)
addresses-to-reveal (if (seq addresses)
(set addresses)
(get-in db [:communities/all-addresses-to-reveal community-id]))
@@ -9,25 +9,17 @@
(def wallet-accounts
{"0xA" {:address "0xA"
:watch-only? true
:operable? true
:position 2
:color :red
:emoji "🦇"}
"0xB" {:address "0xB"
:operable? true
:position 0
:color :blue
:emoji "🐈"}
"0xC" {:address "0xC"
:operable? true
:position 1
:color :orange
:emoji "🛏️"}
"0xD" {:address "0xD"
:operable? false
:position 3
:color :flamingo
:emoji "🦩"}})
"0xB" {:address "0xB"
:position 0
:color :blue
:emoji "🐈"}
"0xC" {:address "0xC"
:position 1
:color :orange
:emoji "🛏️"}})
(def permissioned-accounts
[{:address "0xB"
@@ -22,7 +22,7 @@
airdrop-account (rf/sub [:communities/airdrop-account id])
revealed-accounts (rf/sub [:communities/accounts-to-reveal id])
revealed-accounts-count (count revealed-accounts)
wallet-accounts-count (count (rf/sub [:wallet/operable-accounts-without-watched-accounts]))
wallet-accounts-count (count (rf/sub [:wallet/accounts-without-watched-accounts]))
addresses-shared-text (if (= revealed-accounts-count wallet-accounts-count)
(i18n/label :t/all-addresses)
(i18n/label-pluralize
@@ -120,7 +120,7 @@
(defn set-permissioned-accounts
[{:keys [db]} [community-id addresses-to-reveal]]
(let [addresses-to-reveal (set addresses-to-reveal)
wallet-accounts (utils/sorted-operable-non-watch-only-accounts db)
wallet-accounts (utils/sorted-non-watch-only-accounts db)
current-airdrop-address (get-in db [:communities/all-airdrop-addresses community-id])
new-airdrop-address (if (contains? addresses-to-reveal current-airdrop-address)
current-airdrop-address
@@ -142,7 +142,7 @@
[{:keys [db]} [community-id new-value]]
(let [current-addresses (get-in db [:communities/all-addresses-to-reveal community-id])
addresses-to-reveal (if new-value
(->> (utils/sorted-operable-non-watch-only-accounts db)
(->> (utils/sorted-non-watch-only-accounts db)
(map :address)
set)
current-addresses)]
@@ -33,15 +33,9 @@
(let [cofx
{:db {:communities/all-addresses-to-reveal {community-id #{"0xA" "0xB" "0xC"}}
:communities/all-airdrop-addresses {community-id "0xB"}
:wallet {:accounts {"0xB" {:address "0xB"
:operable? true
:position 0}
"0xA" {:address "0xA"
:operable? true
:position 1}
"0xC" {:address "0xC"
:operable? true
:position 2}}}}}
:wallet {:accounts {"0xB" {:address "0xB" :position 0}
"0xA" {:address "0xA" :position 1}
"0xC" {:address "0xC" :position 2}}}}}
addresses-to-reveal ["0xA" "0xC"]]
(is (match?
{:db {:communities/all-addresses-to-reveal
@@ -58,9 +52,9 @@
(testing "sets flag from false -> true will mark all addresses to be revealed"
(let [cofx {:db
{:wallet
{:accounts {"0xB" {:address "0xB" :operable? true :position 0}
"0xA" {:address "0xA" :operable? true :position 1}
"0xC" {:address "0xC" :operable? true :position 2}}}
{:accounts {"0xB" {:address "0xB" :position 0}
"0xA" {:address "0xA" :position 1}
"0xC" {:address "0xC" :position 2}}}
:communities/all-addresses-to-reveal {community-id #{"0xA"}}
:communities/selected-share-all-addresses {community-id false}}}
addresses-to-reveal #{"0xA" "0xB" "0xC"}]
@@ -260,7 +260,7 @@
can-edit-addresses? (rf/sub [:communities/can-edit-shared-addresses? id])
wallet-accounts (rf/sub [:wallet/operable-accounts-without-watched-accounts])
wallet-accounts (rf/sub [:wallet/accounts-without-watched-accounts])
unmodified-addresses-to-reveal (rf/sub [:communities/addresses-to-reveal id])
[addresses-to-reveal set-addresses-to-reveal] (rn/use-state unmodified-addresses-to-reveal)
@@ -154,7 +154,7 @@
(defn update-previous-permission-addresses
[{:keys [db]} [community-id]]
(when community-id
(let [accounts (utils/sorted-operable-non-watch-only-accounts db)
(let [accounts (utils/sorted-non-watch-only-accounts db)
selected-permission-addresses (get-in db
[:communities community-id
:selected-permission-addresses])
@@ -198,7 +198,7 @@
[{:keys [db]} [community-id]]
(let [share-all-addresses? (get-in db [:communities community-id :share-all-addresses?])
next-share-all-addresses? (not share-all-addresses?)
accounts (utils/sorted-operable-non-watch-only-accounts db)
accounts (utils/sorted-non-watch-only-accounts db)
addresses (set (map :address accounts))]
{:db (update-in db
[:communities community-id]
@@ -51,7 +51,7 @@
(rf/reg-event-fx :communities/check-permissions-to-join-community-with-all-addresses
(fn [{:keys [db]} [community-id]]
(let [accounts (utils/sorted-operable-non-watch-only-accounts db)
(let [accounts (utils/sorted-non-watch-only-accounts db)
addresses (set (map :address accounts))]
{:db (assoc-in db [:communities/permissions-check community-id :checking?] true)
:json-rpc/call [{:method "wakuext_checkPermissionsToJoinCommunity"
@@ -12,10 +12,9 @@
constants/community-token-permission-become-member :t/member
fallback-to)))
(defn sorted-operable-non-watch-only-accounts
(defn sorted-non-watch-only-accounts
[db]
(->> (get-in db [:wallet :accounts])
(vals)
(remove :watch-only?)
(filter :operable?)
(sort-by :position)))
-111
View File
@@ -1,111 +0,0 @@
(ns status-im.contexts.keycard.effects
(:require [keycard.keycard :as keycard]
[native-module.core :as native-module]
[react-native.async-storage :as async-storage]
[react-native.platform :as platform]
[status-im.contexts.profile.config :as profile.config]
[taoensso.timbre :as log]
[utils.re-frame :as rf]
[utils.transforms :as transforms]))
(defonce ^:private active-listeners (atom []))
(defn register-card-events
[]
(doseq [listener @active-listeners]
(keycard/remove-event-listener listener))
(reset! active-listeners
[(keycard/on-card-connected #(rf/dispatch [:keycard/on-card-connected]))
(keycard/on-card-disconnected #(rf/dispatch [:keycard/on-card-disconnected]))
(when platform/ios?
(keycard/on-nfc-user-cancelled #(rf/dispatch [:keycard.ios/on-nfc-user-cancelled])))
(when platform/ios?
(keycard/on-nfc-timeout #(rf/dispatch [:keycard.ios/on-nfc-timeout])))
(keycard/on-nfc-enabled #(rf/dispatch [:keycard/on-check-nfc-enabled-success true]))
(keycard/on-nfc-disabled #(rf/dispatch [:keycard/on-check-nfc-enabled-success false]))]))
(rf/reg-fx :effects.keycard/register-card-events register-card-events)
(defn check-nfc-enabled
[]
(log/debug "[keycard] check-nfc-enabled")
(keycard/check-nfc-enabled
{:on-success
(fn [response]
(log/debug "[keycard response] check-nfc-enabled")
(rf/dispatch [:keycard/on-check-nfc-enabled-success response]))}))
(rf/reg-fx :effects.keycard/check-nfc-enabled check-nfc-enabled)
(rf/reg-fx
:effects.keycard.ios/start-nfc
(fn [args]
(log/debug "fx start-nfc")
(keycard/start-nfc args)))
(rf/reg-fx
:effects.keycard.ios/stop-nfc
(fn [args]
(log/debug "fx stop-nfc")
(keycard/stop-nfc args)))
(defn- error-object->map
[^js object]
{:code (.-code object)
:error (.-message object)})
(defn get-application-info
[{:keys [on-success on-failure] :as args}]
(log/debug "[keycard] get-application-info")
(keycard/get-application-info
(assoc
args
:on-success
(fn [response]
(log/debug "[keycard response succ] get-application-info")
(when on-success
(on-success response)))
:on-failure
(fn [response]
(log/error "[keycard response fail] get-application-info")
(when on-failure
(on-failure (error-object->map response)))))))
(rf/reg-fx :effects.keycard/get-application-info get-application-info)
(defn get-keys
[{:keys [on-success on-failure] :as args}]
(log/debug "[keycard] get-keys")
(keycard/get-keys
(assoc
args
:on-success
(fn [response]
(log/debug "[keycard response succ] get-keys")
(when on-success
(on-success (transforms/js->clj response))))
:on-failure
(fn [response]
(log/warn "[keycard response fail] get-keys"
(error-object->map response))
(when on-failure
(on-failure (error-object->map response)))))))
(rf/reg-fx :effects.keycard/get-keys get-keys)
(defn login
[{:keys [key-uid password whisper-private-key]}]
(native-module/login-account
(assoc (profile.config/login)
:keyUid key-uid
:password password
:keycardWhisperPrivateKey whisper-private-key)))
(rf/reg-fx :effects.keycard/login-with-keycard login)
(defn retrieve-pairings
[]
(async-storage/get-item
"status-keycard-pairings"
#(rf/dispatch [:keycard/on-retrieve-pairings-success %])))
(rf/reg-fx :effects.keycard/retrieve-pairings retrieve-pairings)
(defn set-pairing-to-keycard
[pairings]
(keycard/set-pairings pairings))
(rf/reg-fx :effects.keycard/set-pairing-to-keycard set-pairing-to-keycard)
@@ -1,57 +0,0 @@
(ns status-im.contexts.keycard.events
(:require [re-frame.core :as rf]
status-im.contexts.keycard.login.events
status-im.contexts.keycard.pin.events
status-im.contexts.keycard.sheet.events
[taoensso.timbre :as log]))
(rf/reg-event-fx :keycard/on-check-nfc-enabled-success
(fn [{:keys [db]} [nfc-enabled?]]
{:db (assoc-in db [:keycard :nfc-enabled?] nfc-enabled?)}))
(rf/reg-event-fx :keycard.ios/on-nfc-user-cancelled
(fn [{:keys [db]}]
(log/debug "[keycard] nfc user cancelled")
{:db (assoc-in db [:keycard :pin :status] nil)
:fx [(when-let [on-nfc-cancelled-event-vector (get-in db [:keycard :on-nfc-cancelled-event-vector])]
[:dispatch on-nfc-cancelled-event-vector])]}))
(rf/reg-event-fx :keycard/on-card-connected
(fn [{:keys [db]} _]
(log/debug "[keycard] card globally connected")
{:db (assoc-in db [:keycard :card-connected?] true)
:fx [(when-let [event (get-in db [:keycard :on-card-connected-event-vector])]
[:dispatch event])]}))
(rf/reg-event-fx :keycard/on-card-disconnected
(fn [{:keys [db]} _]
(log/debug "[keycard] card disconnected")
{:db (assoc-in db [:keycard :card-connected?] false)
:fx [(when-let [event (get-in db [:keycard :on-card-disconnected-event-vector])]
[:dispatch event])]}))
(rf/reg-event-fx :keycard.ios/start-nfc
(fn [_]
{:effects.keycard.ios/start-nfc nil}))
(rf/reg-event-fx :keycard.ios/on-nfc-timeout
(fn [{:keys [db]} _]
(log/debug "[keycard] nfc timeout")
{:db (assoc-in db [:keycard :card-connected?] false)
:fx [[:dispatch-later [{:ms 500 :dispatch [:keycard.ios/start-nfc]}]]]}))
(rf/reg-event-fx :keycard/get-application-info
(fn [_ [{:keys [on-success on-failure]}]]
(log/debug "[keycard] get-application-info")
{:effects.keycard/get-application-info {:on-success on-success
:on-failure on-failure}}))
(rf/reg-event-fx :keycard/on-retrieve-pairings-success
(fn [{:keys [db]} [pairings]]
{:db (assoc-in db [:keycard :pairings] pairings)
:fx [[:effects.keycard/set-pairing-to-keycard pairings]]}))
(rf/reg-event-fx :keycard.ios/on-start-nfc-success
(fn [{:keys [db]} [{:keys [on-cancel-event-vector]}]]
(log/debug "[keycard] nfc started success")
{:db (assoc-in db [:keycard :on-nfc-cancelled-event-vector] on-cancel-event-vector)}))
@@ -1,87 +0,0 @@
(ns status-im.contexts.keycard.login.events
(:require [status-im.contexts.keycard.utils :as keycard.utils]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(rf/reg-event-fx :keycard.login/on-get-keys-error
(fn [{:keys [db]} [error]]
(log/debug "[keycard] get keys error: " error)
(let [tag-was-lost? (keycard.utils/tag-lost? (:error error))
pin-retries-count (keycard.utils/pin-retries (:error error))]
(if tag-was-lost?
{:db (assoc-in db [:keycard :pin :status] nil)}
(if (nil? pin-retries-count)
{:effects.utils/show-popup {:title "wrong-keycard"}}
{:db (-> db
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries-count)
(update-in [:keycard :pin] assoc :status :error))
:fx [[:dispatch [:keycard/hide-connection-sheet]]
(when (zero? pin-retries-count)
[:effects.utils/show-popup {:title "frozen-keycard"}])]})))))
(rf/reg-event-fx :keycard.login/on-get-keys-success
(fn [{:keys [db]} [data]]
(let [{:keys [key-uid encryption-public-key
whisper-private-key]} data
key-uid (str "0x" key-uid)
profile (get-in db [:profile/profiles-overview key-uid])]
{:db
(-> db
(dissoc :keycard)
(update :profile/login assoc
:password encryption-public-key
:key-uid key-uid
:name (:name profile)))
:fx [[:dispatch [:keycard/hide-connection-sheet]]
[:effects.keycard/login-with-keycard
{:password encryption-public-key
:whisper-private-key whisper-private-key
:key-uid key-uid}]]})))
(rf/reg-event-fx :keycard.login/on-get-keys-from-keychain-success
(fn [{:keys [db]} [key-uid [encryption-public-key whisper-private-key]]]
(when (and encryption-public-key whisper-private-key)
(let [profile (get-in db [:profile/profiles-overview key-uid])]
{:db
(-> db
(dissoc :keycard)
(update :profile/login assoc
:password encryption-public-key
:key-uid key-uid
:name (:name profile)))
:fx [[:dispatch [:keycard/hide-connection-sheet]]
[:effects.keycard/login-with-keycard
{:password encryption-public-key
:whisper-private-key whisper-private-key
:key-uid key-uid}]]}))))
(rf/reg-event-fx :keycard.login/on-get-application-info-success
(fn [{:keys [db]} [application-info]]
(let [profile (get-in db [:profile/profiles-overview (get-in db [:profile/login :key-uid])])
pin (get-in db [:keycard :pin :text])
error (keycard.utils/validate-application-info profile application-info)]
(if error
{:effects.utils/show-popup {:title (str error)}}
{:db (-> db
(assoc-in [:keycard :application-info] application-info)
(assoc-in [:keycard :pin :status] :verifying))
:effects.keycard/get-keys {:pin pin
:on-success #(rf/dispatch [:keycard.login/on-get-keys-success %])
:on-failure #(rf/dispatch [:keycard.login/on-get-keys-error %])}}))))
(rf/reg-event-fx :keycard.login/cancel-reading-card
(fn [{:keys [db]}]
{:db (assoc-in db [:keycard :on-card-connected-event-vector] nil)}))
(rf/reg-event-fx :keycard/read-card-and-login
(fn [{:keys [db]}]
(let [connected? (get-in db [:keycard :card-connected?])
event-vector [:keycard/get-application-info
{:on-success #(rf/dispatch [:keycard.login/on-get-application-info-success %])}]]
(log/debug "[keycard] proceed-to-login")
{:db (assoc-in db [:keycard :on-card-connected-event-vector] event-vector)
:fx [[:dispatch
[:keycard/show-connection-sheet
{:on-cancel-event-vector [:keycard.login/cancel-reading-card]}]]
(when connected?
[:dispatch event-vector])]})))
@@ -1,21 +0,0 @@
(ns status-im.contexts.keycard.pin.events
(:require [utils.re-frame :as rf]))
(rf/reg-event-fx :keycard.pin/delete-pressed
(fn [{:keys [db]}]
(let [pin (get-in db [:keycard :pin :text])]
(when (and pin (pos? (count pin)))
{:db (-> db
(assoc-in [:keycard :pin :text] (.slice pin 0 -1))
(assoc-in [:keycard :pin :status] nil))}))))
(rf/reg-event-fx :keycard.pin/number-pressed
(fn [{:keys [db]} [number max-numbers on-complete-event]]
(let [pin (get-in db [:keycard :pin :text])
new-pin (str pin number)]
(when (<= (count new-pin) max-numbers)
{:db (-> db
(assoc-in [:keycard :pin :text] new-pin)
(assoc-in [:keycard :pin :status] nil))
:fx [(when (= (dec max-numbers) (count pin))
[:dispatch [on-complete-event]])]}))))
@@ -1,26 +0,0 @@
(ns status-im.contexts.keycard.pin.view
(:require [quo.core :as quo]
[react-native.core :as rn]
[status-im.constants :as constants]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn auth
[callback-event-key]
(let [{:keys [text status]} (rf/sub [:keycard/pin])
pin-retry-counter (rf/sub [:keycard/pin-retry-counter])
error? (= status :error)]
[rn/view {:padding-bottom 12 :flex 1}
[rn/view {:flex 1 :justify-content :center :align-items :center :padding 34}
[quo/pin-input
{:blur? false
:number-of-pins constants/pincode-length
:number-of-filled-pins (count text)
:error? error?
:info (when error?
(i18n/label :t/pin-retries-left {:number pin-retry-counter}))}]]
[quo/numbered-keyboard
{:delete-key? true
:on-delete #(rf/dispatch [:keycard.pin/delete-pressed])
:on-press #(rf/dispatch [:keycard.pin/number-pressed % constants/pincode-length
callback-event-key])}]]))
@@ -1,30 +0,0 @@
(ns status-im.contexts.keycard.sheet.events
(:require [re-frame.core :as rf]
[react-native.platform :as platform]
[taoensso.timbre :as log]))
(rf/reg-event-fx :keycard/show-connection-sheet-component
(fn [{:keys [db]} [{:keys [on-cancel-event-vector]}]]
{:db (assoc-in db [:keycard :connection-sheet-opts] {:on-close #(rf/dispatch on-cancel-event-vector)})
:fx [[:dismiss-keyboard true]
[:show-nfc-sheet nil]]}))
(rf/reg-event-fx :keycard/show-connection-sheet
(fn [_ [args]]
(if platform/android?
{:dispatch [:keycard/show-connection-sheet-component args]}
{:effects.keycard.ios/start-nfc
{:on-success
(fn []
(log/debug "nfc started successfully. next: show-connection-sheet")
(rf/dispatch [:keycard.ios/on-start-nfc-success args]))
:on-failure
(fn []
(log/debug "nfc failed star starting. not calling show-connection-sheet"))}})))
(rf/reg-event-fx :keycard/hide-connection-sheet
(fn [{:keys [db]}]
(if platform/android?
{:db (assoc-in db [:keycard :connection-sheet-opts] nil)
:fx [[:hide-nfc-sheet nil]]}
{:effects.keycard.ios/stop-nfc nil})))
@@ -1,36 +0,0 @@
(ns status-im.contexts.keycard.sheet.view
(:require [quo.foundations.colors :as colors]
quo.theme
[react-native.core :as rn]
[status-im.common.resources :as resources]
[utils.re-frame :as rf]))
(defn connect-keycard
[]
(let [connected? (rf/sub [:keycard/connected?])
{:keys [on-close]} (rf/sub [:keycard/connection-sheet-opts])
theme (quo.theme/use-theme)]
[rn/view {:flex 1}
[rn/view {:flex 1}]
[rn/view
{:style {:align-items :center
:padding-horizontal 36
:padding-vertical 30
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)}}
[rn/text {:style {:font-size 26 :color "#9F9FA5" :margin-bottom 36}}
"Ready to Scan"]
[rn/image
{:source (resources/get-image :nfc-prompt)}]
[rn/text {:style {:font-size 16 :color :white :margin-vertical 36}}
(if connected?
"Connected. Dont move your card."
"Hold your phone near a Status Keycard")]
[rn/pressable
{:on-press (fn []
(when on-close (on-close))
(rf/dispatch [:keycard/hide-connection-sheet]))
:style {:flex-direction :row}}
[rn/view
{:style {:background-color "#8E8E93" :flex 1 :align-items :center :padding 18 :border-radius 10}}
[rn/text {:style {:color :white :font-size 16}}
"Cancel"]]]]]))
-45
View File
@@ -1,45 +0,0 @@
(ns status-im.contexts.keycard.utils
(:require [taoensso.timbre :as log]))
(def pin-mismatch-error #"Unexpected error SW, 0x63C(\d+)|wrongPIN\(retryCounter: (\d+)\)")
(defn pin-retries
[error]
(when-let [matched-error (re-matches pin-mismatch-error error)]
(js/parseInt (second (filter some? matched-error)))))
(defn tag-lost?
[error]
(or
(= error "Tag was lost.")
(= error "NFCError:100")
(re-matches #".*NFCError:100.*" error)))
(defn validate-application-info
[profile {:keys [key-uid paired? pin-retry-counter puk-retry-counter] :as application-info}]
(let [profile-mismatch? (or (nil? profile) (not= (:key-uid profile) key-uid))]
(log/debug "[keycard] login-with-keycard"
"empty application info" (empty? application-info)
"no key-uid" (empty? key-uid)
"profile-mismatch?" profile-mismatch?
"no pairing" paired?)
(cond
(empty? application-info)
:not-keycard
(empty? (:key-uid application-info))
:keycard-blank
profile-mismatch?
:keycard-wrong
(not paired?)
:keycard-unpaired
(and (zero? pin-retry-counter)
(or (nil? puk-retry-counter)
(pos? puk-retry-counter)))
nil
:else
nil)))
@@ -1,80 +0,0 @@
(ns status-im.contexts.preview.quo.list-items.approval-info
(:require
[quo.core :as quo]
[quo.foundations.resources :as resources]
[react-native.core :as rn]
[status-im.common.resources :as common.resources]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
[{:type :select
:key :type
:options [{:key :spending-cap}
{:key :token-contract}
{:key :account}
{:key :spending-contract}
{:key :network}
{:key :date-signed}
{:key :collectible}
{:key :collectible-contract}
{:key :address}
{:key :community}]}
{:type :text
:key :label}
{:type :text
:key :description}
{:type :boolean
:key :blur?}
{:type :boolean
:key :unlimited-icon?}
{:type :text
:key :button-label}
{:type :text
:key :tag-label}
{:type :select
:key :option-icon
:options [{:key nil
:value "None"}
{:key :i/options}
{:key :i/chevron-right}]}])
(defn- get-avatar-props
[type]
(case type
:collectible {:image (common.resources/get-mock-image :collectible2)}
:account {:customization-color :orange
:emoji "😇"}
:collectible-contract {:image (common.resources/get-mock-image :bored-ape)}
:spending-contract {:network-image (resources/get-network :ethereum)
:image (resources/get-dapp :coingecko)}
:date-signed {:icon :i/signature}
:address {:customization-color :blue
:full-name "0 x"}
:community {:image (common.resources/get-mock-image :status-logo)
:size :size-32}
{:image (common.resources/get-mock-image :status-logo)}))
(defn view
[]
(let [[state set-state] (rn/use-state {:type :spending-cap
:label "Label"
:description "Description"
:blur? false
:unlimited-icon? false
:button-label "Edit"
:tag-label "31,283.77 EUR"
:option-icon :i/options})]
[preview/preview-container
{:state state
:set-state set-state
:blur? (:blur? state)
:show-blur-background? true
:blur-dark-only? true
:descriptor descriptor}
[quo/approval-info
(assoc state
:button-icon :i/edit
:on-button-press #(js/alert "Button Pressed")
:on-avatar-press #(js/alert "Token Pressed")
:avatar-props (get-avatar-props (:type state))
:on-option-press #(js/alert "Option Pressed"))]]))
@@ -105,7 +105,6 @@
[status-im.contexts.preview.quo.list-items.account-list-card :as
account-list-card]
[status-im.contexts.preview.quo.list-items.address :as address]
[status-im.contexts.preview.quo.list-items.approval-info :as approval-info]
[status-im.contexts.preview.quo.list-items.channel :as channel]
[status-im.contexts.preview.quo.list-items.dapp :as dapp]
[status-im.contexts.preview.quo.list-items.missing-keypair :as missing-keypair]
@@ -145,7 +144,6 @@
small-option-card]
[status-im.contexts.preview.quo.password.password-tips :as password-tips]
[status-im.contexts.preview.quo.password.tips :as tips]
[status-im.contexts.preview.quo.pin-input.pin-input :as pin-input]
[status-im.contexts.preview.quo.profile.collectible :as collectible]
[status-im.contexts.preview.quo.profile.collectible-list-item :as collectible-list-item]
[status-im.contexts.preview.quo.profile.expanded-collectible :as expanded-collectible]
@@ -371,8 +369,6 @@
:component keyboard-key/view}
{:name :numbered-keyboard
:component numbered-keyboard/view}]
:pin-input [{:name :pin-input
:component pin-input/view}]
:links [{:name :internal-link-card
:options {:insets {:top true}}
:component internal-link-card/view}
@@ -391,8 +387,6 @@
:component account-list-card/view}
{:name :address
:component address/view}
{:name :approval-info
:component approval-info/view}
{:name :channel
:component channel/view}
{:name :community-list
@@ -1,27 +0,0 @@
(ns status-im.contexts.preview.quo.pin-input.pin-input
(:require [quo.core :as quo]
[react-native.core :as rn]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
[{:key :blur? :type :boolean}
{:type :number
:key :number-of-pins}
{:type :number
:key :number-of-filled-pins}
{:type :boolean
:key :error?}
{:type :text
:key :info}])
(defn view
[]
(let [[state set-state] (rn/use-state {:blur? false
:number-of-pins 6
:number-of-filled-pins 0})]
[preview/preview-container
{:state state
:set-state set-state
:descriptor descriptor}
[rn/view {:style {:padding-vertical 40 :align-items :center :justify-content :center}}
[quo/pin-input state]]]))
@@ -47,8 +47,7 @@
:options [{:key :default}
{:key :icon}
{:key :network}
{:key :account}
{:key :editable}]}
{:key :account}]}
{:type :select
:key :status
:options [{:key :default}
@@ -186,13 +186,9 @@
(rf/reg-event-fx
:profile.login/biometric-success
(fn [{:keys [db]}]
(let [key-uid (get-in db [:profile/login :key-uid])
keycard? (get-in db [:profile/profiles-overview key-uid :keycard-pairing])]
(if keycard?
{:keychain/get-keycard-keys
[key-uid #(rf/dispatch [:keycard.login/on-get-keys-from-keychain-success key-uid %])]}
{:keychain/get-user-password
[key-uid #(rf/dispatch [:profile.login/get-user-password-success %])]}))))
(let [key-uid (get-in db [:profile/login :key-uid])]
{:keychain/get-user-password [key-uid
#(rf/dispatch [:profile.login/get-user-password-success %])]})))
(rf/reg-event-fx
:profile.login/biometric-auth-fail
@@ -10,7 +10,6 @@
[status-im.common.standard-authentication.core :as standard-authentication]
[status-im.config :as config]
[status-im.constants :as constants]
[status-im.contexts.keycard.pin.view :as keycard.pin]
[status-im.contexts.onboarding.common.background.view :as background]
[status-im.contexts.profile.profiles.style :as style]
[taoensso.timbre :as log]
@@ -141,7 +140,7 @@
[:profile/profile-selected key-uid])
(rf/dispatch
[:profile.login/login-with-biometric-if-available key-uid])
(set-hide-profiles))}]))
(when-not keycard-pairing (set-hide-profiles)))}]))
(defn- profiles-section
[{:keys [hide-profiles]}]
@@ -190,8 +189,8 @@
[:profile.login/biometric-success])
:on-fail #(rf/dispatch
[:profile.login/biometric-auth-fail
%])}]))]
%])}]))
]
[standard-authentication/password-input
{:shell? true
:blur? true
@@ -200,7 +199,7 @@
(defn login-section
[{:keys [show-profiles]}]
(let [processing (rf/sub [:profile/login-processing])
{:keys [key-uid name keycard-pairing
{:keys [key-uid name
customization-color]} (rf/sub [:profile/login-profile])
sign-in-enabled? (rf/sub [:sign-in-enabled?])
profile-picture (rf/sub [:profile/login-profiles-picture key-uid])
@@ -229,7 +228,7 @@
:disabled? processing
:accessibility-label :show-profiles}
:i/multi-profile]]
[(if keycard-pairing rn/view rn/scroll-view)
[rn/scroll-view
{:keyboard-should-persist-taps :always
:style {:flex 1}}
[quo/profile-card
@@ -237,20 +236,17 @@
:customization-color (or customization-color :primary)
:profile-picture profile-picture
:card-style style/login-profile-card}]
(if keycard-pairing
[keycard.pin/auth :keycard/read-card-and-login]
[password-input])]
(when-not keycard-pairing
[quo/button
{:size 40
:type :primary
:customization-color (or customization-color :primary)
:accessibility-label :login-button
:icon-left :i/unlocked
:disabled? (or (not sign-in-enabled?) processing)
:on-press login-multiaccount
:container-style {:margin-bottom (+ (safe-area/get-bottom) 12)}}
(i18n/label :t/log-in)])]))
[password-input]]
[quo/button
{:size 40
:type :primary
:customization-color (or customization-color :primary)
:accessibility-label :login-button
:icon-left :i/unlocked
:disabled? (or (not sign-in-enabled?) processing)
:on-press login-multiaccount
:container-style {:margin-bottom (+ (safe-area/get-bottom) 12)}}
(i18n/label :t/log-in)]]))
(defn view
[]
@@ -15,19 +15,13 @@
[{:keys [name full-address chain-short-names address] :as opts}]
(let [[_ splitted-address] (network-utils/split-network-full-address address)
open-send-flow (rn/use-callback
(fn []
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:pop-to-root :shell-stack])
(js/setTimeout #(rf/dispatch [:wallet/select-send-address
{:address full-address
:recipient
{:label
(utils/get-shortened-address
splitted-address)
:recipient-type :saved-address}
:stack-id :wallet-select-address
:start-flow? true}])
400))
#(rf/dispatch [:wallet/select-send-address
{:address full-address
:recipient {:label (utils/get-shortened-address
splitted-address)
:recipient-type :saved-address}
:stack-id :wallet-select-address
:start-flow? true}])
[full-address])
open-eth-chain-explorer (rn/use-callback
#(rf/dispatch [:wallet/navigate-to-chain-explorer
@@ -83,7 +83,7 @@
{:style style/about-tab
:content-container-style {:padding-bottom (+ constants/floating-shell-button-height 8)}}
[quo/data-item
{:subtitle-type :default
{:description :default
:right-icon :i/options
:card? true
:status :default
@@ -7,7 +7,6 @@
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
[status-im.contexts.wallet.sheets.buy-token.view :as buy-token]
[status-im.feature-flags :as ff]
[status-im.setup.hot-reload :as hot-reload]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -29,15 +28,14 @@
{:keys [name color formatted-balance
watch-only?]} (rf/sub [:wallet/current-viewing-account])
customization-color (rf/sub [:profile/customization-color])]
(hot-reload/use-safe-unmount (fn []
(rf/dispatch [:wallet/close-account-page])
(rf/dispatch [:wallet/clean-current-viewing-account])))
(rn/use-unmount #(rf/dispatch [:wallet/clean-send-data]))
(rn/use-mount
#(rf/dispatch [:wallet/fetch-activities-for-current-account]))
[rn/view {:style {:flex 1}}
[account-switcher/view
{:type :wallet-networks
:on-press #(rf/dispatch [:pop-to-root :shell-stack])}]
:on-press (fn []
(rf/dispatch [:wallet/close-account-page]))}]
[quo/account-overview
{:container-style style/account-overview
:current-value formatted-balance
@@ -8,7 +8,6 @@
[status-im.common.floating-button-page.view :as floating-button-page]
[status-im.contexts.wallet.add-account.create-account.import-private-key.style :as style]
[status-im.contexts.wallet.common.validation :as v]
[status-im.setup.hot-reload :as hot-reload]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -113,7 +112,7 @@
public-address (rf/sub [:wallet/public-address])
[flow-state set-flow-state] (rn/use-state nil)
error? (= :invalid-private-key flow-state)]
(hot-reload/use-safe-unmount on-unmount)
(rn/use-unmount on-unmount)
[rn/view {:flex 1}
[floating-button-page/view
{:customization-color customization-color
@@ -15,7 +15,6 @@
[status-im.contexts.wallet.common.utils :as common.utils]
[status-im.contexts.wallet.sheets.account-origin.view :as account-origin]
[status-im.feature-flags :as ff]
[status-im.setup.hot-reload :as hot-reload]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.responsiveness :as responsiveness]
@@ -314,7 +313,7 @@
error (or @account-name-error @emoji-and-color-error?)]
(rn/use-mount #(check-emoji-and-color-error @emoji @account-color))
(hot-reload/use-safe-unmount #(rf/dispatch [:wallet/clear-create-account]))
(rn/use-unmount #(rf/dispatch [:wallet/clear-create-account]))
(if keypair-name
[add-new-keypair-variant
@@ -9,7 +9,6 @@
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.common.utils.networks :as network-utils]
[status-im.setup.hot-reload :as hot-reload]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -53,7 +52,7 @@
bridge-to-title (i18n/label :t/bridge-to
{:name (string/upper-case (str token-symbol))})]
(hot-reload/use-safe-unmount #(rf/dispatch [:wallet/clean-bridge-to-selection]))
(rn/use-unmount #(rf/dispatch [:wallet/clean-bridge-to-selection]))
[rn/view
[account-switcher/view
@@ -3,13 +3,12 @@
[react-native.core :as rn]
[status-im.contexts.wallet.bridge.input-amount.style :as style]
[status-im.contexts.wallet.send.input-amount.view :as input-amount]
[status-im.setup.hot-reload :as hot-reload]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn view
[]
(hot-reload/use-safe-unmount #(rf/dispatch [:wallet/clean-routes-calculation]))
(rn/use-unmount #(rf/dispatch [:wallet/clean-routes-calculation]))
[rn/view {:style style/bridge-send-wrapper}
[input-amount/view
{:current-screen-id :screen/wallet.bridge-input-amount
@@ -21,4 +20,5 @@
:stack-id :screen/wallet.bridge-input-amount}]))
:on-navigate-back (fn []
(rf/dispatch [:wallet/clean-disabled-from-networks])
(rf/dispatch [:wallet/clean-send-amount]))}]])
(rf/dispatch [:wallet/clean-send-amount])
(rf/dispatch [:navigate-back]))}]])
@@ -23,7 +23,6 @@
(defn add-keys-to-account
[account]
(-> account
(assoc :operable? (not= (:operable account) :no))
(assoc :watch-only? (= (:type account) :watch))
(assoc :default-account? (:wallet account))))
@@ -68,7 +67,7 @@
:color :colorId})
(update :prodPreferredChainIds chain-ids-set->string)
(update :testPreferredChainIds chain-ids-set->string)
(dissoc :watch-only? :default-account? :operable? :tokens :collectibles)))
(dissoc :watch-only? :default-account? :tokens :collectibles)))
(defn- rpc->balances-per-chain
[token]
@@ -32,7 +32,6 @@
:watch-only? false
:prod-preferred-chain-ids #{1 42161}
:created-at 1716548742000
:operable? true
:operable :fully
:removed false})
@@ -172,10 +171,9 @@
{:key-uid "0x123"
:address "1x123"})
"1x456" (merge account
{:key-uid "0x456"
:address "1x456"
:operable? false
:operable :no})}
{:key-uid "0x456"
:address "1x456"
:operable :no})}
:updated-keypairs-by-id {"0x123" {:key-uid "0x123"
:type :seed
:lowest-operability :fully
@@ -186,10 +184,9 @@
:type :key
:lowest-operability :no
:accounts [(merge account
{:key-uid "0x456"
:address "1x456"
:operable? false
:operable :no})]}}})
{:key-uid "0x456"
:address "1x456"
:operable :no})]}}})
(sut/reconcile-keypairs [raw-keypair-seed-phrase
raw-keypair-private-key]))))
(testing "reconcile-keypairs represents removed key pairs and accounts"
+26 -29
View File
@@ -66,15 +66,13 @@
(rf/reg-event-fx :wallet/clean-current-viewing-account
(fn [{:keys [db]}]
(let [just-completed-transaction? (get-in db [:wallet :ui :send :just-completed-transaction?])]
(when-not just-completed-transaction?
{:db (update db :wallet dissoc :current-viewing-account-address)}))))
{:db (update db :wallet dissoc :current-viewing-account-address)}))
(rf/reg-event-fx :wallet/close-account-page
(fn [{:keys [db]}]
(let [just-completed-transaction? (get-in db [:wallet :ui :send :just-completed-transaction?])]
(when-not just-completed-transaction?
{:fx [[:dispatch [:wallet/clear-account-tab]]]}))))
(fn [_]
{:fx [[:dispatch [:wallet/clean-current-viewing-account]]
[:dispatch [:wallet/clear-account-tab]]
[:dispatch [:pop-to-root :shell-stack]]]}))
(defn log-rpc-error
[_ [{:keys [event params]} error]]
@@ -89,13 +87,6 @@
[:dispatch [:wallet/request-collectibles-for-all-accounts {:new-request? true}]]
[:dispatch [:wallet/check-recent-history-for-all-accounts]]])
(rf/reg-event-fx
:wallet/fetch-assets-for-address
(fn [_ [address]]
{:fx [[:dispatch [:wallet/get-wallet-token-for-account address]]
[:dispatch [:wallet/request-new-collectibles-for-account-from-signal address]]
[:dispatch [:wallet/check-recent-history-for-account address]]]}))
(rf/reg-event-fx
:wallet/get-accounts-success
(fn [{:keys [db]} [accounts]]
@@ -121,7 +112,9 @@
(rf/reg-event-fx :wallet/process-account-from-signal
(fn [{:keys [db]} [{:keys [address] :as account}]]
{:db (assoc-in db [:wallet :accounts address] (data-store/rpc->account account))
:fx [[:dispatch [:wallet/fetch-assets-for-address address]]]}))
:fx [[:dispatch [:wallet/get-wallet-token-for-account address]]
[:dispatch [:wallet/request-new-collectibles-for-account-from-signal address]]
[:dispatch [:wallet/check-recent-history-for-account address]]]}))
(rf/reg-event-fx
:wallet/save-account
@@ -582,17 +575,18 @@
updated-account-addresses (set (map :address updated-accounts))
new-account-addresses (clojure.set/difference updated-account-addresses
existing-account-addresses)]
(cond-> {:db (update-in db
[:wallet :accounts]
(fn [existing-accounts]
(merge-with merge
(apply dissoc existing-accounts removed-account-addresses)
(utils.collection/index-by :address updated-accounts))))}
(seq new-account-addresses)
(assoc :fx
(mapv (fn [address] [:dispatch [:wallet/fetch-assets-for-address address]])
new-account-addresses)))))
{:db (update-in db
[:wallet :accounts]
(fn [existing-accounts]
(merge-with merge
(apply dissoc existing-accounts removed-account-addresses)
(utils.collection/index-by :address updated-accounts))))
:fx (mapcat (fn [address]
[[:dispatch [:wallet/get-wallet-token-for-account address]]
[:dispatch
[:wallet/request-new-collectibles-for-account-from-signal address]]
[:dispatch [:wallet/check-recent-history-for-account address]]])
new-account-addresses)}))
(rf/reg-event-fx :wallet/reconcile-watch-only-accounts reconcile-watch-only-accounts)
@@ -627,10 +621,13 @@
(into removed-account-addresses
old-account-addresses))
updated-accounts-by-address)))}
(seq new-account-addresses)
(assoc :fx
(mapv (fn [address] [:dispatch [:wallet/fetch-assets-for-address address]])
new-account-addresses)))))
(mapcat (fn [address]
[[:dispatch [:wallet/get-wallet-token-for-account address]]
[:dispatch
[:wallet/request-new-collectibles-for-account-from-signal address]]
[:dispatch [:wallet/check-recent-history-for-account address]]])
new-account-addresses)))))
(rf/reg-event-fx :wallet/reconcile-keypairs reconcile-keypairs)
+16 -7
View File
@@ -40,7 +40,6 @@
:color :purple
:wallet true
:default-account? true
:operable? true
:name "Ethereum account"
:type :generated
:chat false
@@ -146,7 +145,10 @@
(h/deftest-event :wallet/process-account-from-signal
[event-id dispatch]
(let [expected-effects {:db {:wallet {:accounts {address account}}}
:fx [[:dispatch [:wallet/fetch-assets-for-address address]]]}]
:fx [[:dispatch [:wallet/get-wallet-token-for-account address]]
[:dispatch
[:wallet/request-new-collectibles-for-account-from-signal address]]
[:dispatch [:wallet/check-recent-history-for-account address]]]}]
(reset! rf-db/app-db {:wallet {:accounts {}}})
(is (match? expected-effects (dispatch [event-id raw-account])))))
@@ -167,7 +169,9 @@
:type :seed
:lowest-operability :fully
:accounts [account]}}}}
:fx [[:dispatch [:wallet/fetch-assets-for-address address]]]})
:fx [[:dispatch [:wallet/get-wallet-token-for-account address]]
[:dispatch [:wallet/request-new-collectibles-for-account-from-signal address]]
[:dispatch [:wallet/check-recent-history-for-account address]]]})
(dispatch [event-id
[{:key-uid keypair-key-uid
:type "seed"
@@ -288,7 +292,6 @@
(assoc raw-account
:address "1x001"
:chat true)]}]]))))))
(h/deftest-event :wallet/reconcile-watch-only-accounts
[event-id dispatch]
(testing "event adds new watch-only accounts"
@@ -300,7 +303,10 @@
vector? matchers/equals
map? matchers/equals]
{:db {:wallet {:accounts {(:address account) account}}}
:fx [[:dispatch [:wallet/fetch-assets-for-address address]]]})
:fx [[:dispatch [:wallet/get-wallet-token-for-account address]]
[:dispatch
[:wallet/request-new-collectibles-for-account-from-signal address]]
[:dispatch [:wallet/check-recent-history-for-account address]]]})
(dispatch [event-id [raw-account]]))))
(testing "event removes watch-only accounts that are marked as removed"
(reset! rf-db/app-db {:wallet {:accounts {(:address account) account}}})
@@ -310,7 +316,8 @@
[set? matchers/set-equals
vector? matchers/equals
map? matchers/equals]
{:db {:wallet {:accounts {}}}})
{:db {:wallet {:accounts {}}}
:fx []})
(dispatch [event-id [(assoc raw-account :removed true)]]))))
(testing "event updates existing watch-only accounts"
(reset! rf-db/app-db {:wallet
@@ -321,8 +328,10 @@
[set? matchers/set-equals
vector? matchers/equals
map? matchers/equals]
{:db {:wallet {:accounts {address (assoc account :name "Test")}}}})
{:db {:wallet {:accounts {address (assoc account :name "Test")}}}
:fx []})
(dispatch [event-id
[(assoc raw-account
:address address
:name "Test")]])))))
(cljs.test/run-tests)
+3 -11
View File
@@ -487,18 +487,10 @@
transaction-details (send-utils/map-multitransaction-by-ids transaction-batch-id
transaction-hashes)]
{:db (-> db
(assoc-in [:wallet :ui :send :just-completed-transaction?] true)
(assoc-in [:wallet :transactions] transaction-details)
(assoc-in [:wallet :ui :send :transaction-ids] transaction-ids))
:fx [[:dispatch
[:wallet/end-transaction-flow]]
[:dispatch-later
[{:ms 2000
:dispatch [:wallet/clean-just-completed-transaction]}]]]})))
(rf/reg-event-fx :wallet/clean-just-completed-transaction
(fn [{:keys [db]}]
{:db (update-in db [:wallet :ui :send] dissoc :just-completed-transaction?)}))
[:wallet/end-transaction-flow]]]})))
(rf/reg-event-fx :wallet/clean-up-transaction-flow
(fn [_]
@@ -667,8 +659,8 @@
{:json-rpc/call [{:method "wallet_createMultiTransaction"
:params request-params
:on-success (fn [result]
(rf/dispatch [:wallet/add-authorized-transaction result])
(rf/dispatch [:hide-bottom-sheet]))
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:wallet/add-authorized-transaction result]))
:on-error (fn [error]
(log/error "failed to send transaction"
{:event :wallet/send-transaction
@@ -6,7 +6,6 @@
[status-im.common.floating-button-page.view :as floating-button-page]
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
[status-im.contexts.wallet.send.from.style :as style]
[status-im.setup.hot-reload :as hot-reload]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -19,7 +18,9 @@
(defn- on-close
[]
(rf/dispatch [:wallet/clean-current-viewing-account]))
(rf/dispatch [:wallet/clean-current-viewing-account])
(rf/dispatch [:wallet/clean-send-data])
(rf/dispatch [:navigate-back]))
(defn- render-fn
[item _ _ {:keys [network-details]}]
@@ -35,11 +36,10 @@
[]
(let [accounts (rf/sub [:wallet/accounts-with-current-asset])
network-details (rf/sub [:wallet/network-details])]
(hot-reload/use-safe-unmount on-close)
[floating-button-page/view
{:footer-container-padding 0
:header [account-switcher/view
{:on-press #(rf/dispatch [:navigate-back])
{:on-press on-close
:margin-top (safe-area/get-top)
:switcher-type :select-account}]}
@@ -16,7 +16,6 @@
[status-im.contexts.wallet.sheets.buy-token.view :as buy-token]
[status-im.contexts.wallet.sheets.unpreferred-networks-alert.view :as unpreferred-networks-alert]
[status-im.feature-flags :as ff]
[status-im.setup.hot-reload :as hot-reload]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.money :as money]
@@ -323,7 +322,6 @@
(let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!))
app-keyboard-listener (.addEventListener rn/app-state "change" dismiss-keyboard-fn)]
#(.remove app-keyboard-listener))))
(hot-reload/use-safe-unmount on-navigate-back)
(rn/use-effect
(fn []
(set-input-state #(controlled-input/set-upper-limit % current-limit)))
@@ -348,7 +346,7 @@
(when (controlled-input/input-error input-state) "-error"))}
[account-switcher/view
{:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back])
:on-press on-navigate-back
:switcher-type :select-account}]
[quo/token-input
{:container-style style/input-container
@@ -17,7 +17,6 @@
[status-im.contexts.wallet.send.select-address.style :as style]
[status-im.contexts.wallet.send.select-address.tabs.view :as tabs]
[status-im.feature-flags :as ff]
[status-im.setup.hot-reload :as hot-reload]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -177,7 +176,8 @@
(rf/dispatch [:wallet/clean-selected-collectible])
(rf/dispatch [:wallet/clean-send-address])
(rf/dispatch [:wallet/clean-disabled-from-networks])
(rf/dispatch [:wallet/select-address-tab nil]))
(rf/dispatch [:wallet/select-address-tab nil])
(rf/dispatch [:navigate-back]))
on-change-tab #(rf/dispatch [:wallet/select-address-tab %])
input-value (reagent/atom "")
input-focused? (reagent/atom false)]
@@ -185,13 +185,12 @@
(let [selected-tab (or (rf/sub [:wallet/send-tab]) (:id (first tabs-data)))
valid-ens-or-address? (boolean (rf/sub [:wallet/valid-ens-or-address?]))
searching-address? (rf/sub [:wallet/searching-address?])]
(hot-reload/use-safe-unmount on-close)
[floating-button-page/view
{:content-container-style {:flex 1}
:footer-container-padding 0
:keyboard-should-persist-taps true
:header [account-switcher/view
{:on-press #(rf/dispatch [:navigate-back])
{:on-press on-close
:margin-top (safe-area/get-top)
:switcher-type :select-account}]
:footer (when-not (string/blank? @input-value)
@@ -7,7 +7,6 @@
[status-im.contexts.wallet.common.asset-list.view :as asset-list]
[status-im.contexts.wallet.common.collectibles-tab.view :as collectibles-tab]
[status-im.contexts.wallet.send.select-asset.style :as style]
[status-im.setup.hot-reload :as hot-reload]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -67,9 +66,9 @@
(rf/dispatch [:wallet/clean-selected-token])
(rf/dispatch [:wallet/clean-selected-collectible])
(rf/dispatch [:navigate-back]))]
(hot-reload/use-safe-unmount (fn []
(rf/dispatch [:wallet/clean-selected-token])
(rf/dispatch [:wallet/clean-selected-collectible])))
(rn/use-unmount (fn []
(rf/dispatch [:wallet/clean-selected-token])
(rf/dispatch [:wallet/clean-selected-collectible])))
[rn/safe-area-view {:style style/container}
[account-switcher/view
{:icon-name :i/arrow-left
@@ -13,4 +13,5 @@
:on-navigate-back (fn []
(rf/dispatch [:wallet/clean-disabled-from-networks])
(rf/dispatch [:wallet/clean-from-locked-amounts])
(rf/dispatch [:wallet/clean-send-amount]))}])
(rf/dispatch [:wallet/clean-send-amount])
(rf/dispatch [:navigate-back]))}])
@@ -108,8 +108,9 @@
[]
(let [options-height (reagent/atom 0)]
(fn []
(let [theme (quo.theme/use-theme)
accounts (rf/sub [:wallet/operable-accounts-without-current-viewing-account])
(let [theme (quo.theme/use-theme)
accounts (rf/sub
[:wallet/fully-or-partially-operable-accounts-without-current-viewing-account])
show-account-selector? (pos? (count accounts))]
[:<>
(when show-account-selector?
@@ -20,7 +20,7 @@
(defn view
[]
(let [selected-account-address (rf/sub [:wallet/current-viewing-account-address])
accounts (rf/sub [:wallet/operable-accounts-without-watched-accounts])]
accounts (rf/sub [:wallet/fully-or-partially-operable-accounts-without-watched-accounts])]
[:<>
[quo/drawer-top {:title (i18n/label :t/select-account)}]
[gesture/flat-list
@@ -42,23 +42,3 @@
(rf/reg-event-fx :wallet.swap/set-max-slippage
(fn [{:keys [db]} [max-slippage]]
{:db (assoc-in db [:wallet :ui :swap :max-slippage] (utils.number/parse-float max-slippage))}))
(rf/reg-event-fx :wallet.swap/select-asset-to-receive
(fn [{:keys [db]} [{:keys [token]}]]
{:db (assoc-in db [:wallet :ui :swap :asset-to-receive] token)}))
(rf/reg-event-fx :wallet.swap/set-pay-amount
(fn [{:keys [db]} [amount]]
{:db (assoc-in db [:wallet :ui :swap :pay-amount] amount)}))
(rf/reg-event-fx :wallet.swap/set-swap-proposal
(fn [{:keys [db]} [swap-proposal]]
{:db (assoc-in db [:wallet :ui :swap :swap-proposal] swap-proposal)}))
(rf/reg-event-fx :wallet.swap/set-provider
(fn [{:keys [db]}]
{:db (assoc-in db [:wallet :ui :swap :providers] [constants/swap-default-provider])}))
(rf/reg-event-fx :wallet.swap/recalculate-fees
(fn [{:keys [db]} [loading-fees?]]
{:db (assoc-in db [:wallet :ui :swap :loading-fees?] loading-fees?)}))
@@ -18,20 +18,6 @@
:value search-text
:on-change-text on-change-text}]])
(def dummy-swap-proposal
{:from {:chain-id 1
:native-currency-symbol "ETH"}
:to {:chain-id 1
:native-currency-symbol "ETH"}
:gas-amount "23487"
:gas-fees {:base-fee "32.325296406"
:max-priority-fee-per-gas "0.011000001"
:eip1559-enabled true}
:estimated-time 3
:receive-amount 99.98
:receive-token {:symbol "SNT"
:address "0x432492384728934239789"}})
(defn- assets-view
[search-text on-change-text]
(let [on-token-press (fn [token]
@@ -40,11 +26,7 @@
{:token token
:network (when (= (count token-networks) 1)
(first token-networks))
:stack-id :screen/wallet.swap-select-asset-to-pay}])
(rf/dispatch [:wallet.swap/select-asset-to-receive {:token token}])
(rf/dispatch [:wallet.swap/set-pay-amount 100])
(rf/dispatch [:wallet.swap/set-swap-proposal dummy-swap-proposal])
(rf/dispatch [:wallet.swap/set-provider])))]
:stack-id :screen/wallet.swap-select-asset-to-pay}])))]
[:<>
[search-input search-text on-change-text]
[asset-list/view
@@ -58,6 +40,8 @@
on-close (fn []
(rf/dispatch [:wallet.swap/clean-asset-to-pay])
(rf/dispatch [:navigate-back]))]
(rn/use-unmount (fn []
(rf/dispatch [:wallet.swap/clean-asset-to-pay])))
[rn/safe-area-view {:style style/container}
[account-switcher/view
{:on-press on-close
@@ -1,39 +0,0 @@
(ns status-im.contexts.wallet.swap.swap-confirmation.style
(:require [quo.foundations.colors :as colors]))
(def detail-item
{:flex 1
:height 36
:background-color :transparent})
(def content-container
{:padding-top 12
:padding-horizontal 20
:padding-bottom 32})
(def title-container
{:margin-right 4})
(def title-line-with-margin-top
{:flex-direction :row
:margin-top 4})
(def details-container
{:flex-direction :row
:justify-content :space-between
:height 52
:padding-top 7
:margin-bottom 8})
(def summary-section-container
{:padding-horizontal 20
:padding-bottom 16})
(defn section-label
[theme]
{:margin-bottom 8
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
(def providers-container
{:align-items :center
:margin-top 12})
@@ -1,192 +0,0 @@
(ns status-im.contexts.wallet.swap.swap-confirmation.view
(:require
[quo.core :as quo]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[status-im.common.floating-button-page.view :as floating-button-page]
[status-im.common.standard-authentication.core :as standard-auth]
[status-im.contexts.wallet.swap.swap-confirmation.style :as style]
[utils.address :as address-utils]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- on-close-action
[]
(rf/dispatch [:navigate-back]))
(defn- swap-title
[{:keys [pay-token-symbol pay-amount receive-token-symbol receive-amount account]}]
[rn/view {:style style/content-container}
[rn/view {:style {:flex-direction :row}}
[quo/text
{:size :heading-1
:weight :semi-bold
:style style/title-container
:accessibility-label :title-label}
(i18n/label :t/swap)]
[quo/summary-tag
{:token pay-token-symbol
:label (str pay-amount " " pay-token-symbol)
:type :token}]]
[rn/view {:style style/title-line-with-margin-top}
[quo/text
{:size :heading-1
:weight :semi-bold
:style style/title-container
:accessibility-label :title-label}
(i18n/label :t/to)]
[quo/summary-tag
{:token receive-token-symbol
:label (str receive-amount " " receive-token-symbol)
:type :token}]]
[rn/view {:style style/title-line-with-margin-top}
[quo/text
{:size :heading-1
:weight :semi-bold
:style style/title-container
:accessibility-label :send-label}
(i18n/label :t/in)]
[quo/summary-tag
{:label (:name account)
:type :account
:emoji (:emoji account)
:customization-color (:color account)}]]])
(defn- summary-section
[{:keys [theme label title-accessibility-label amount token-symbol token-address network]}]
(let [network-values {(if (= network :mainnet) :ethereum network)
{:amount amount :token-symbol token-symbol}}]
[rn/view {:style style/summary-section-container}
[quo/text
{:size :paragraph-2
:weight :medium
:style (style/section-label theme)
:accessibility-label title-accessibility-label}
label]
[quo/summary-info
{:type :token
:networks? true
:values network-values
:token-props {:token token-symbol
:label (str amount " " token-symbol)
:address (address-utils/get-shortened-compressed-key token-address)
:size 32}}]]))
(defn- data-item
[{:keys [title subtitle loading?]}]
[quo/data-item
{:container-style style/detail-item
:blur? false
:card? false
:status (if loading? :loading :default)
:size :small
:title title
:subtitle subtitle}])
(defn- transaction-details
[{:keys [estimated-time-min max-fees max-slippage loading-fees?]}]
[rn/view {:style style/details-container}
[:<>
[data-item
{:title (i18n/label :t/est-time)
:subtitle (i18n/label :t/time-in-mins {:minutes (str estimated-time-min)})}]
[data-item
{:title (i18n/label :t/max-fees)
:subtitle max-fees
:loading? loading-fees?}]
[data-item
{:title (i18n/label :t/max-slippage)
:subtitle (str max-slippage "%")}]]])
(defn footer
[{:keys [estimated-time-min native-currency-symbol max-slippage theme account-color provider
loading-fees?]}]
(let [native-token (when native-currency-symbol
(rf/sub [:wallet/token-by-symbol
native-currency-symbol]))
fee-formatted (rf/sub [:wallet/wallet-send-fee-fiat-formatted
native-token])]
[:<>
[transaction-details
{:estimated-time-min estimated-time-min
:max-fees fee-formatted
:max-slippage max-slippage
:loading-fees? loading-fees?
:theme theme}]
[standard-auth/slide-button
{:size :size-48
:track-text (i18n/label :t/slide-to-swap)
:container-style {:z-index 2}
:customization-color account-color
:disabled? loading-fees?
:auth-button-label (i18n/label :t/confirm)}]
[rn/view {:style style/providers-container}
[quo/text
{:size :paragraph-2
:style {:color (colors/theme-colors colors/neutral-80-opa-40
colors/white-opa-70
theme)}}
(i18n/label :t/swaps-powered-by {:provider (:name provider)})]]]))
(defn view
[]
(let [theme (quo.theme/use-theme)
swap-transaction-data (rf/sub [:wallet/swap])
{:keys [asset-to-pay max-slippage network
pay-amount providers swap-proposal
loading-fees?]} swap-transaction-data
receive-amount (:receive-amount swap-proposal)
receive-token (:receive-token swap-proposal)
receive-token-symbol (:symbol receive-token)
receive-token-address (:address receive-token)
estimated-time-min (:estimated-time swap-proposal)
pay-token-symbol (:symbol asset-to-pay)
pay-token-address (:address asset-to-pay)
native-currency-symbol (get-in swap-proposal [:from :native-currency-symbol])
account (rf/sub [:wallet/current-viewing-account])
account-color (:color account)
provider (first providers)]
[rn/view {:style {:flex 1}}
[floating-button-page/view
{:footer-container-padding 0
:header [quo/page-nav
{:icon-name :i/arrow-left
:on-press on-close-action
:margin-top (safe-area/get-top)
:background :blur
:accessibility-label :top-bar}]
:footer [footer
{:estimated-time-min estimated-time-min
:native-currency-symbol native-currency-symbol
:max-slippage max-slippage
:account-color account-color
:provider provider
:loading-fees? loading-fees?
:theme theme}]
:gradient-cover? true
:customization-color account-color}
[rn/view
[swap-title
{:pay-token-symbol pay-token-symbol
:pay-amount pay-amount
:receive-token-symbol receive-token-symbol
:receive-amount receive-amount
:account account}]
[summary-section
{:title-accessibility-label :summary-section-pay
:label (i18n/label :t/pay)
:token-symbol pay-token-symbol
:amount pay-amount
:token-address pay-token-address
:network (:network-name network)
:theme theme}]
[summary-section
{:title-accessibility-label :summary-section-receive
:label (i18n/label :t/receive)
:token-symbol receive-token-symbol
:amount receive-amount
:token-address receive-token-address
:network (:network-name network)
:theme theme}]]]]))
@@ -12,8 +12,4 @@
[quo/button
{:on-press #(rf/dispatch [:show-bottom-sheet
{:content slippage-settings/view}])}
(str "Edit Slippage: " max-slippage "%")]
[quo/button
{:on-press #(rf/dispatch [:navigate-to-within-stack
[:screen/wallet.swap-confirmation :screen/wallet.swap-propasal]])}
"Swap confirmation"]]))
(str "Edit Slippage: " max-slippage "%")]]))
@@ -29,15 +29,18 @@
(rf/reg-fx
:effects.wallet-connect/register-event-listener
(fn [[web3-wallet wc-event handler]]
(wallet-connect/register-handler
{:web3-wallet web3-wallet
:event wc-event
:handler handler})))
(.on web3-wallet
wc-event
(fn [js-proposal]
(-> js-proposal
(js->clj :keywordize-keys true)
handler)))))
(rf/reg-fx
:effects.wallet-connect/fetch-pairings
(fn [{:keys [web3-wallet on-success on-fail]}]
(-> (wallet-connect/get-pairings web3-wallet)
(-> (.. web3-wallet -core -pairing)
(.getPairings)
(promesa/then on-success)
(promesa/catch on-fail))))
@@ -45,21 +48,23 @@
:effects.wallet-connect/pair
(fn [{:keys [web3-wallet url on-success on-fail]}]
(when web3-wallet
(-> (wallet-connect/core-pairing-pair web3-wallet url)
(-> (.. web3-wallet -core -pairing)
(.pair (clj->js {:uri url}))
(promesa/then on-success)
(promesa/catch on-fail)))))
(rf/reg-fx
:effects.wallet-connect/disconnect
(fn [{:keys [web3-wallet topic on-success on-fail]}]
(-> (wallet-connect/core-pairing-disconnnect web3-wallet topic)
(-> (.. web3-wallet -core -pairing)
(.disconnect (clj->js {:topic topic}))
(promesa/then on-success)
(promesa/catch on-fail))))
(rf/reg-fx
:effects.wallet-connect/fetch-active-sessions
(fn [{:keys [web3-wallet on-success on-fail]}]
(-> (wallet-connect/get-active-sessions web3-wallet)
(-> (.getActiveSessions web3-wallet)
(promesa/then on-success)
(promesa/catch on-fail))))
@@ -70,10 +75,9 @@
approved-namespaces (wallet-connect/build-approved-namespaces
params
supported-namespaces)]
(-> (wallet-connect/approve-session
{:web3-wallet web3-wallet
:id id
:approved-namespaces approved-namespaces})
(-> (.approveSession web3-wallet
(clj->js {:id id
:namespaces approved-namespaces}))
(promesa/then on-success)
(promesa/catch on-fail)))))
@@ -115,14 +119,17 @@
(rf/reg-fx
:effects.wallet-connect/respond-session-request
(fn [{:keys [web3-wallet topic id result error on-success on-error]}]
(-> (wallet-connect/respond-session-request
{:web3-wallet web3-wallet
:topic topic
:id id
:result result
:error error})
(promesa/then on-success)
(promesa/catch on-error))))
(->
(.respondSessionRequest web3-wallet
(clj->js {:topic topic
:response (merge {:id id
:jsonrpc "2.0"}
(when result
{:result result})
(when error
{:error error}))}))
(promesa/then on-success)
(promesa/catch on-error))))
(rf/reg-fx
:effects.wallet-connect/reject-session-proposal
@@ -130,9 +137,8 @@
(let [{:keys [id]} proposal
reason (wallet-connect/get-sdk-error
constants/wallet-connect-user-rejected-error-key)]
(-> (wallet-connect/reject-session
{:web3-wallet web3-wallet
:id id
:reason reason})
(-> (.rejectSession web3-wallet
(clj->js {:id id
:reason reason}))
(promesa/then on-success)
(promesa/catch on-error)))))
@@ -183,7 +183,7 @@
(fn [_ [scanned-text]]
(let [parsed-uri (wallet-connect/parse-uri scanned-text)
version (:version parsed-uri)
valid-wc-uri? (wc-utils/valid-wc-uri? parsed-uri)
valid-wc-uri? (wc-utils/valid-uri? parsed-uri)
expired? (-> parsed-uri
:expiryTimestamp
wc-utils/timestamp-expired?)
+6 -1
View File
@@ -41,5 +41,10 @@
:visibility-status-updates {}
:stickers/packs-pending #{}
:settings/change-password {}
:keycard {}
:keycard {:nfc-enabled? false
:pin {:original []
:confirmation []
:current []
:puk []
:enter-step :original}}
:theme :light})
-5
View File
@@ -25,8 +25,6 @@
status-im.contexts.communities.overview.events
status-im.contexts.communities.sharing.events
status-im.contexts.contact.blocking.events
status-im.contexts.keycard.effects
status-im.contexts.keycard.events
status-im.contexts.onboarding.common.overlay.events
status-im.contexts.onboarding.events
status-im.contexts.profile.events
@@ -59,9 +57,6 @@
:theme/init-theme nil
:network/listen-to-network-info nil
:effects.biometric/get-supported-type nil
:effects.keycard/register-card-events nil
:effects.keycard/check-nfc-enabled nil
:effects.keycard/retrieve-pairings nil
;;app starting flow continues in get-profiles-overview
:profile/get-profiles-overview #(rf/dispatch [:profile/get-profiles-overview-success %])
:effects.font/get-font-file-for-initials-avatar
+4 -12
View File
@@ -81,22 +81,14 @@
(fn [] views/bottom-sheet))
;;;; Alert Banner
(navigation/register-component
"alert-banner"
(fn [] (gesture/gesture-handler-root-hoc views/alert-banner #js {:flex 0}))
(fn [] views/alert-banner))
;;;; NFC sheet
;;;; LEGACY (should be removed in status 2.0)
(navigation/register-component
"nfc-sheet"
(fn [] (gesture/gesture-handler-root-hoc views/nfc-sheet-comp))
(fn [] views/nfc-sheet-comp)))
;;;; LEGACY (should be removed in status 2.0)
(navigation/register-component
"popover"
(fn [] (gesture/gesture-handler-root-hoc views/popover-comp))
(fn [] views/popover-comp))
"popover"
(fn [] (gesture/gesture-handler-root-hoc views/popover-comp))
(fn [] views/popover-comp)))
+56 -7
View File
@@ -230,7 +230,6 @@
(fn [] (navigation/dissmiss-overlay "bottom-sheet")))
;;;; Alert Banner
(rf/reg-fx :show-alert-banner
(fn [[view-id theme]]
(show-overlay "alert-banner"
@@ -246,17 +245,67 @@
(reset! state/alert-banner-shown? false)
(reload-status-nav-color-fx [view-id theme])))
;;;; NFC sheet
;;;; Merge options
(rf/reg-fx :show-nfc-sheet
(fn [] (show-overlay "nfc-sheet")))
(rf/reg-fx :hide-nfc-sheet
(fn [] (navigation/dissmiss-overlay "nfc-sheet")))
(rf/reg-fx :merge-options
(fn [{:keys [id options]}]
(navigation/merge-options id options)))
;;;; Legacy (should be removed in status 2.0)
(defn- get-screen-component
[component]
(let [{:keys [options]} (get views/screens component)]
{:component {:id component
:name component
:options (merge (options/statusbar-and-navbar-options (:theme options) nil nil)
options)}}))
(rf/reg-fx :set-stack-root-fx
(fn [[stack component]]
;; We don't have bottom tabs as separate stacks anymore,. So the old way of pushing screens in
;; specific tabs will not work. Disabled set-stack-root for :shell-stack as it is not working
;; and currently only being used for browser and some rare keycard flows after login
(when-not (= @state/root-id :shell-stack)
(log/debug :set-stack-root-fx stack component)
(navigation/set-stack-root
(name stack)
(if (vector? component)
(mapv get-screen-component component)
(get-screen-component component))))))
(rf/reg-fx :show-popover
(fn [] (show-overlay "popover")))
(rf/reg-fx :hide-popover
(fn [] (navigation/dissmiss-overlay "popover")))
(rf/reg-fx :show-visibility-status-popover
(fn [] (show-overlay "visibility-status-popover")))
(rf/reg-fx :hide-visibility-status-popover
(fn [] (navigation/dissmiss-overlay "visibility-status-popover")))
(rf/reg-fx :show-wallet-connect-sheet
(fn [] (show-overlay "wallet-connect-sheet")))
(rf/reg-fx :hide-wallet-connect-sheet
(fn [] (navigation/dissmiss-overlay "wallet-connect-sheet")))
(rf/reg-fx :show-wallet-connect-success-sheet
(fn [] (show-overlay "wallet-connect-success-sheet")))
(rf/reg-fx :hide-wallet-connect-success-sheet
(fn [] (navigation/dissmiss-overlay "wallet-connect-success-sheet")))
(rf/reg-fx :show-wallet-connect-app-management-sheet
(fn [] (show-overlay "wallet-connect-app-management-sheet")))
(rf/reg-fx :hide-wallet-connect-app-management-sheet
(fn [] (navigation/dissmiss-overlay "wallet-connect-app-management-sheet")))
(rf/reg-fx :show-signing-sheet
(fn [] (show-overlay "signing-sheet")))
(rf/reg-fx :hide-signing-sheet
(fn [] (navigation/dissmiss-overlay "signing-sheet")))
+5
View File
@@ -74,6 +74,11 @@
[{:keys [db]} root-id]
{:set-root [root-id (:theme db)]})
(rf/defn set-stack-root
{:events [:set-stack-root]}
[_ stack root]
{:set-stack-root-fx [stack root]})
(rf/defn change-tab
{:events [:navigate-change-tab]}
[{:keys [db]} stack-id]
-5
View File
@@ -118,7 +118,6 @@
[status-im.contexts.wallet.send.transaction-confirmation.view :as wallet-transaction-confirmation]
[status-im.contexts.wallet.send.transaction-progress.view :as wallet-transaction-progress]
[status-im.contexts.wallet.swap.select-asset-to-pay.view :as wallet-swap-select-asset-to-pay]
[status-im.contexts.wallet.swap.swap-confirmation.view :as wallet-swap-confirmation]
[status-im.contexts.wallet.swap.swap-proposal.view :as wallet-swap-propasal]
[status-im.contexts.wallet.wallet-connect.modals.send-transaction.view :as
wallet-connect-send-transaction]
@@ -522,10 +521,6 @@
:options {:insets {:top? true}}
:component wallet-swap-propasal/view}
{:name :screen/wallet.swap-confirmation
:options {:modalPresentationStyle :overCurrentContext}
:component wallet-swap-confirmation/view}
{:name :scan-profile-qr-code
:options (merge
options/dark-screen
-12
View File
@@ -11,7 +11,6 @@
[status-im.common.bottom-sheet-screen.view :as bottom-sheet-screen]
[status-im.common.bottom-sheet.view :as bottom-sheet]
[status-im.common.toasts.view :as toasts]
[status-im.contexts.keycard.sheet.view :as keycard.sheet]
[status-im.navigation.screens :as screens]
[status-im.setup.hot-reload :as reloader]
[utils.re-frame :as rf]))
@@ -122,17 +121,6 @@
[alert-banner/view]])
functional-compiler))
(def nfc-sheet-comp
(reagent/reactify-component
(fn []
(let [app-theme (rf/sub [:theme])]
^{:key (str "nfc-sheet-" @reloader/cnt)}
[quo.theme/provider app-theme
[rn/keyboard-avoiding-view
{:style {:position :relative :flex 1}}
[keycard.sheet/connect-keycard]]]))
functional-compiler))
;; LEGACY (should be removed in status 2.0)
(def popover-comp
+3 -15
View File
@@ -5,8 +5,7 @@
[re-frame.core :as re-frame]
[status-im.constants :as constants]
[status-im.contexts.chat.events :as chat.events]
[status-im.contexts.profile.utils :as profile.utils]
[status-im.subs.contact.utils :as contact.utils]))
[status-im.contexts.profile.utils :as profile.utils]))
(def memo-chats-stack-items (atom nil))
@@ -260,19 +259,8 @@
:chats/photo-path
:<- [:contacts/contacts]
:<- [:profile/profile-with-image]
:<- [:mediaserver/port]
:<- [:initials-avatar-font-file]
:<- [:theme]
(fn [[contacts {:keys [public-key] :as multiaccount} port font-file theme] [_ id]]
(let [contact (or (when (= id public-key) multiaccount)
(get contacts id)
(contact.utils/replace-contact-image-uri
{:contact {:public-key id
:customization-color constants/profile-default-color}
:port port
:public-key id
:font-file font-file
:theme theme}))]
(fn [[contacts {:keys [public-key] :as multiaccount}] [_ id]]
(let [contact (or (when (= id public-key) multiaccount) (get contacts id))]
(profile.utils/photo contact))))
(re-frame/reg-sub
@@ -53,7 +53,7 @@
(re-frame/reg-sub :communities/accounts-to-reveal
(fn [[_ community-id]]
[(re-frame/subscribe [:wallet/operable-accounts-without-watched-accounts])
[(re-frame/subscribe [:wallet/accounts-without-watched-accounts])
(re-frame/subscribe [:communities/addresses-to-reveal community-id])])
(fn [[accounts addresses] _]
(filter #(contains? addresses (:address %))
@@ -61,7 +61,7 @@
(re-frame/reg-sub :communities/airdrop-account
(fn [[_ community-id]]
[(re-frame/subscribe [:wallet/operable-accounts-without-watched-accounts])
[(re-frame/subscribe [:wallet/accounts-without-watched-accounts])
(re-frame/subscribe [:communities/airdrop-address community-id])])
(fn [[accounts airdrop-address] _]
(->> accounts
@@ -24,10 +24,10 @@
(h/deftest-sub :communities/airdrop-account
[sub-name]
(let [airdrop-account {:address "0xA" :operable? true :position 1}]
(let [airdrop-account {:address "0xA" :position 1}]
(reset! rf-db/app-db
{:communities/all-airdrop-addresses {community-id "0xA"}
:wallet {:accounts {"0xB" {:address "0xB" :operable? true :position 0}
:wallet {:accounts {"0xB" {:address "0xB" :position 0}
"0xA" airdrop-account}}})
(is (match? airdrop-account (rf/sub [sub-name community-id])))))
@@ -36,11 +36,9 @@
[sub-name]
(reset! rf-db/app-db
{:communities/all-addresses-to-reveal {community-id #{"0xC" "0xB"}}
:wallet {:accounts {"0xB" {:address "0xB" :operable? true :position 0}
"0xA" {:address "0xA" :operable? true :position 1}
"0xC" {:address "0xC"
:operable? true
:position 2}}}})
:wallet {:accounts {"0xB" {:address "0xB" :position 0}
"0xA" {:address "0xA" :position 1}
"0xC" {:address "0xC" :position 2}}}})
(is (match? [{:address "0xB" :position 0}
{:address "0xC" :position 2}]
+49 -18
View File
@@ -5,10 +5,10 @@
[legacy.status-im.ui.screens.profile.visibility-status.utils :as visibility-status-utils]
[quo.theme]
[re-frame.core :as re-frame]
[status-im.common.pixel-ratio :as pixel-ratio]
[status-im.constants :as constants]
[status-im.contexts.profile.utils :as profile.utils]
[status-im.subs.chat.utils :as chat.utils]
[status-im.subs.contact.utils :as contact.utils]
[utils.address :as address]
[utils.collection]
[utils.i18n :as i18n]))
@@ -37,6 +37,50 @@
(fn [multiaccount]
(get multiaccount :profile-pictures-visibility)))
(defn- replace-contact-image-uri
[contact port public-key font-file theme]
(let [{:keys [images ens-name customization-color]} contact
images
(reduce (fn [acc image]
(let [image-name (:type image)
clock (:clock image)
options {:port port
:ratio pixel-ratio/ratio
:public-key
public-key
:image-name
image-name
; We pass the clock so that we reload the
; image if the image is updated
:clock
clock
:theme
theme
:override-ring?
(when ens-name false)}]
(assoc-in acc
[(keyword image-name) :config]
{:type :contact
:options options})))
images
(vals images))
images (if (seq images)
images
{:thumbnail
{:config {:type :initials
:options {:port port
:ratio pixel-ratio/ratio
:public-key public-key
:override-ring? (when ens-name false)
:uppercase-ratio (:uppercase-ratio
constants/initials-avatar-font-conf)
:customization-color customization-color
:theme theme
:font-file font-file}}}})]
(assoc contact :images images)))
(defn- enrich-contact
([contact] (enrich-contact contact nil nil))
([{:keys [public-key] :as contact} setting own-public-key]
@@ -59,12 +103,7 @@
(defn- reduce-contacts-image-uri
[contacts port font-file theme]
(reduce-kv (fn [acc public-key contact]
(let [contact (contact.utils/replace-contact-image-uri
{:contact contact
:port port
:public-key public-key
:font-file font-file
:theme theme})]
(let [contact (replace-contact-image-uri contact port public-key font-file theme)]
(assoc acc public-key contact)))
{}
contacts))
@@ -191,12 +230,7 @@
[_ contact-identity ens-name port font-file theme]
(let [contact (enrich-contact
(public-key-and-ens-name->new-contact contact-identity ens-name))]
(contact.utils/replace-contact-image-uri
{:contact contact
:port port
:public-key contact-identity
:font-file font-file
:theme theme})))
(replace-contact-image-uri contact port contact-identity font-file theme)))
(re-frame/reg-sub
:contacts/current-contact
@@ -216,10 +250,7 @@
:contacts/contact-by-identity
:<- [:contacts/contacts]
(fn [contacts [_ contact-identity]]
(get
contacts
contact-identity
(contact.utils/build-contact-from-public-key contact-identity))))
(get contacts contact-identity {:public-key contact-identity})))
(re-frame/reg-sub
:contacts/contact-two-names-by-identity
@@ -257,7 +288,7 @@
(assoc public-key current-contact))]
(->> members
(map #(or (get all-contacts %)
(contact.utils/build-contact-from-public-key %)))
{:public-key %}))
(sort-by (comp string/lower-case
(fn [{:keys [primary-name name alias public-key]}]
(or primary-name
-54
View File
@@ -1,54 +0,0 @@
(ns status-im.subs.contact.utils
(:require
[native-module.core :as native-module]
[status-im.common.pixel-ratio :as pixel-ratio]
[status-im.constants :as constants]
[utils.address :as address]))
(defn replace-contact-image-uri
[{:keys [contact port public-key font-file theme]}]
(let [{:keys [images ens-name customization-color]} contact
images
(reduce (fn [acc image]
(let [image-name (:type image)
clock (:clock image)
options {:port port
:ratio pixel-ratio/ratio
:public-key public-key
:image-name image-name
; We pass the clock so that we reload the
; image if the image is updated
:clock clock
:theme theme
:override-ring? (when ens-name false)}]
(assoc-in acc
[(keyword image-name) :config]
{:type :contact
:options options})))
images
(vals images))
images (if (seq images)
images
{:thumbnail
{:config {:type :initials
:options {:port port
:ratio pixel-ratio/ratio
:public-key public-key
:override-ring? (when ens-name false)
:uppercase-ratio (:uppercase-ratio
constants/initials-avatar-font-conf)
:customization-color customization-color
:theme theme
:font-file font-file}}}})]
(assoc contact :images images)))
(defn build-contact-from-public-key
[public-key]
(when public-key
(let [compressed-key (native-module/serialize-legacy-key public-key)]
{:public-key public-key
:compressed-key compressed-key
:primary-name (address/get-shortened-compressed-key (or compressed-key public-key))})))
-38
View File
@@ -1,38 +0,0 @@
(ns status-im.subs.keycard
(:require [utils.re-frame :as rf]))
(rf/reg-sub
:keycard/keycard-profile?
(fn [db]
(not (nil? (get-in db [:profile/profile :keycard-pairing])))))
(rf/reg-sub
:keycard/nfc-enabled?
:<- [:keycard]
(fn [keycard]
(:nfc-enabled? keycard)))
(rf/reg-sub
:keycard/connected?
:<- [:keycard]
(fn [keycard]
(:card-connected? keycard)))
(rf/reg-sub
:keycard/pin
:<- [:keycard]
(fn [keycard]
(:pin keycard)))
(rf/reg-sub
:keycard/pin-retry-counter
:<- [:keycard]
(fn [keycard]
(get-in keycard [:application-info :pin-retry-counter])))
(rf/reg-sub
:keycard/connection-sheet-opts
:<- [:keycard]
(fn [keycard]
(:connection-sheet-opts keycard)))
-4
View File
@@ -9,7 +9,6 @@
status-im.subs.community.account-selection
status-im.subs.contact
status-im.subs.general
status-im.subs.keycard
status-im.subs.messages
status-im.subs.onboarding
status-im.subs.pairing
@@ -187,6 +186,3 @@
;; centralized-metrics
(reg-root-key-sub :centralized-metrics/enabled? :centralized-metrics/enabled?)
(reg-root-key-sub :centralized-metrics/user-confirmed? :centralized-metrics/user-confirmed?)
;;keycard
(reg-root-key-sub :keycard :keycard)
@@ -38,11 +38,11 @@
(fn [saved-addresses]
(->> saved-addresses
vals
(group-by (comp string/upper-case first :name))
(sort-by :name)
(group-by #(string/upper-case (first (:name %))))
(map (fn [[k v]]
{:title k
:data (sort-by (comp string/lower-case :name) v)}))
(sort-by :title))))
:data v})))))
(rf/reg-sub
:wallet/saved-addresses-addresses
@@ -62,7 +62,7 @@
(fn [saved-addresses [_ query]]
(->> saved-addresses
vals
(sort-by (comp string/lower-case :name))
(sort-by :name)
(filter
(fn [{:keys [name address ens chain-short-names]}]
(let [lowercase-query (string/lower-case (string/trim query))]
-5
View File
@@ -25,11 +25,6 @@
:<- [:wallet/wallet-send]
:-> :transaction-ids)
(rf/reg-sub
:wallet/just-completed-transaction
:<- [:wallet/wallet-send]
:-> :just-completed-transaction?)
(rf/reg-sub
:wallet/wallet-send-amount
:<- [:wallet/wallet-send]
-1
View File
@@ -52,7 +52,6 @@
fiat-value)]
{:crypto (str crypto-formatted " " token-symbol)
:fiat fiat-formatted})))
(rf/reg-sub
:wallet/swap-max-slippage
:<- [:wallet/swap]
+9 -7
View File
@@ -454,23 +454,25 @@
(fn [accounts]
(remove :watch-only? accounts)))
(defn- keep-operable-accounts
(defn- keep-fully-or-partially-operable-accounts
[accounts]
(filter :operable? accounts))
(filter (fn fully-or-partially-operable? [{:keys [operable]}]
(#{:fully :partially} operable))
accounts))
(rf/reg-sub
:wallet/operable-accounts-without-current-viewing-account
:wallet/fully-or-partially-operable-accounts-without-current-viewing-account
:<- [:wallet/accounts-without-current-viewing-account]
keep-operable-accounts)
keep-fully-or-partially-operable-accounts)
(rf/reg-sub
:wallet/operable-accounts-without-watched-accounts
:wallet/fully-or-partially-operable-accounts-without-watched-accounts
:<- [:wallet/accounts-without-watched-accounts]
keep-operable-accounts)
keep-fully-or-partially-operable-accounts)
(rf/reg-sub
:wallet/accounts-with-current-asset
:<- [:wallet/operable-accounts-without-watched-accounts]
:<- [:wallet/fully-or-partially-operable-accounts-without-watched-accounts]
:<- [:wallet/wallet-send-token-symbol]
:<- [:wallet/wallet-send-token]
(fn [[accounts token-symbol token]]
+91 -105
View File
@@ -16,12 +16,10 @@
{:0x1 {:tokens [{:symbol "ETH"} {:symbol "SNT"}]
:network-preferences-names #{}
:customization-color nil
:operable? true
:operable :fully}
:0x2 {:tokens [{:symbol "SNT"}]
:network-preferences-names #{}
:customization-color nil
:operable? true
:operable :partially}})
(def tokens-0x1
@@ -108,7 +106,6 @@
:name "Account One"
:type :generated
:watch-only? false
:operable? true
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :blue
@@ -130,7 +127,6 @@
:name "Account Two"
:type :generated
:watch-only? false
:operable? true
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :purple
@@ -152,7 +148,6 @@
:name "Watched Account 1"
:type :watch
:watch-only? true
:operable? true
:chat false
:test-preferred-chain-ids #{0}
:color :magenta
@@ -224,7 +219,7 @@
(assoc-in [:wallet :accounts] accounts)
(assoc-in [:wallet :networks] network-data)))
(is
(match?
(=
(list {:path "m/44'/60'/0'/0/0"
:emoji "😃"
:key-uid "0x2f5ea39"
@@ -233,7 +228,6 @@
:name "Account One"
:type :generated
:watch-only? false
:operable? true
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :blue
@@ -256,7 +250,6 @@
:name "Account Two"
:type :generated
:watch-only? false
:operable? true
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :purple
@@ -279,7 +272,6 @@
:name "Watched Account 1"
:type :watch
:watch-only? true
:operable? true
:chat false
:test-preferred-chain-ids #{0}
:color :magenta
@@ -315,30 +307,29 @@
(let [result (rf/sub [sub-name])]
(is
(match? {:path "m/44'/60'/0'/0/0"
:emoji "😃"
:key-uid "0x2f5ea39"
:address "0x1"
:wallet false
:name "Account One"
:type :generated
:watch-only? false
:operable? true
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :blue
:hidden false
:prod-preferred-chain-ids #{1 10 42161}
:network-preferences-names #{:mainnet :arbitrum :optimism}
:position 0
:clock 1698945829328
:created-at 1698928839000
:operable :fully
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false
:tokens tokens-0x1}
(dissoc result :balance :formatted-balance)))
(= {:path "m/44'/60'/0'/0/0"
:emoji "😃"
:key-uid "0x2f5ea39"
:address "0x1"
:wallet false
:name "Account One"
:type :generated
:watch-only? false
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :blue
:hidden false
:prod-preferred-chain-ids #{1 10 42161}
:network-preferences-names #{:mainnet :arbitrum :optimism}
:position 0
:clock 1698945829328
:created-at 1698928839000
:operable :fully
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false
:tokens tokens-0x1}
(dissoc result :balance :formatted-balance)))
(is (money/equal-to (:balance result) (money/bignumber 3250)))
(is (match? (:formatted-balance result) "$3250.00")))))
@@ -376,55 +367,52 @@
(assoc-in [:wallet :current-viewing-account-address] "0x2")
(assoc-in [:wallet :networks] network-data)))
(is
(match?
(list
{:path "m/44'/60'/0'/0/0"
:emoji "😃"
:key-uid "0x2f5ea39"
:address "0x1"
:wallet false
:name "Account One"
:type :generated
:watch-only? false
:operable? true
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :blue
:hidden false
:prod-preferred-chain-ids #{1 10 42161}
:network-preferences-names #{:mainnet :arbitrum :optimism}
:position 0
:clock 1698945829328
:created-at 1698928839000
:operable :fully
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false
:tokens tokens-0x1}
{:path ""
:emoji "🎉"
:key-uid "0x2f5ea39"
:address "0x3"
:wallet false
:name "Watched Account 1"
:type :watch
:watch-only? true
:operable? true
:chat false
:test-preferred-chain-ids #{0}
:color :magenta
:hidden false
:prod-preferred-chain-ids #{0}
:network-preferences-names #{}
:position 2
:clock 1698945829328
:created-at 1698928839000
:operable :fully
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x"
:removed false
:tokens tokens-0x3})
(rf/sub [sub-name])))))
(= (list
{:path "m/44'/60'/0'/0/0"
:emoji "😃"
:key-uid "0x2f5ea39"
:address "0x1"
:wallet false
:name "Account One"
:type :generated
:watch-only? false
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :blue
:hidden false
:prod-preferred-chain-ids #{1 10 42161}
:network-preferences-names #{:mainnet :arbitrum :optimism}
:position 0
:clock 1698945829328
:created-at 1698928839000
:operable :fully
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false
:tokens tokens-0x1}
{:path ""
:emoji "🎉"
:key-uid "0x2f5ea39"
:address "0x3"
:wallet false
:name "Watched Account 1"
:type :watch
:watch-only? true
:chat false
:test-preferred-chain-ids #{0}
:color :magenta
:hidden false
:prod-preferred-chain-ids #{0}
:network-preferences-names #{}
:position 2
:clock 1698945829328
:created-at 1698928839000
:operable :fully
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x"
:removed false
:tokens tokens-0x3})
(rf/sub [sub-name])))))
(h/deftest-sub :wallet/accounts-without-watched-accounts
[sub-name]
@@ -434,7 +422,7 @@
(assoc-in [:wallet :accounts] accounts)
(assoc-in [:wallet :networks] network-data)))
(is
(match?
(=
(list
{:path "m/44'/60'/0'/0/0"
:emoji "😃"
@@ -444,7 +432,6 @@
:name "Account One"
:type :generated
:watch-only? false
:operable? true
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :blue
@@ -468,7 +455,6 @@
:name "Account Two"
:type :generated
:watch-only? false
:operable? true
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :purple
@@ -498,7 +484,6 @@
[{:tokens [{:symbol "ETH"} {:symbol "SNT"}]
:network-preferences-names #{}
:customization-color nil
:operable? true
:operable :fully}]))))
(testing "returns the accounts list with the current asset using token"
@@ -511,7 +496,6 @@
[{:tokens [{:symbol "ETH"} {:symbol "SNT"}]
:network-preferences-names #{}
:customization-color nil
:operable? true
:operable :fully}]))))
(testing
@@ -592,19 +576,19 @@
(assoc-in [:wallet :accounts] accounts)
(assoc-in [:wallet :networks] network-data)))
(is
(match? [(-> accounts
(get "0x1")
(assoc :customization-color :blue)
(assoc :network-preferences-names #{:mainnet :arbitrum :optimism}))
(-> accounts
(get "0x2")
(assoc :customization-color :purple)
(assoc :network-preferences-names #{:mainnet :arbitrum :optimism}))
(-> accounts
(get "0x3")
(assoc :customization-color :magenta)
(assoc :network-preferences-names #{}))]
(rf/sub [sub-name])))))
(= [(-> accounts
(get "0x1")
(assoc :customization-color :blue)
(assoc :network-preferences-names #{:mainnet :arbitrum :optimism}))
(-> accounts
(get "0x2")
(assoc :customization-color :purple)
(assoc :network-preferences-names #{:mainnet :arbitrum :optimism}))
(-> accounts
(get "0x3")
(assoc :customization-color :magenta)
(assoc :network-preferences-names #{}))]
(rf/sub [sub-name])))))
(h/deftest-sub :wallet/watch-only-accounts
[sub-name]
@@ -614,10 +598,10 @@
(assoc-in [:wallet :accounts] accounts)
(assoc-in [:wallet :networks] network-data)))
(is
(match? [(-> accounts
(get "0x3")
(assoc :network-preferences-names #{}))]
(rf/sub [sub-name])))))
(= [(-> accounts
(get "0x3")
(assoc :network-preferences-names #{}))]
(rf/sub [sub-name])))))
(def chat-account
{:path "m/43'/60'/1581'/0'/0"
@@ -827,7 +811,9 @@
(testing "returns local suggestions:"
(swap! rf-db/app-db
#(assoc-in % [:wallet :ui :search-address :local-suggestions] local-suggestions))
(is (match? local-suggestions (rf/sub [sub-name])))))
(is
(= local-suggestions
(rf/sub [sub-name])))))
(h/deftest-sub :wallet/valid-ens-or-address?
[sub-name]

Some files were not shown because too many files have changed in this diff Show More