Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
52d7d60751 | ||
|
|
37c25b9351 | ||
|
|
c917454b7d | ||
|
|
25d51aa929 | ||
|
|
5bb3cdc19e | ||
|
|
756e892acb | ||
|
|
0dcf4e7b14 |
-10
@@ -35,11 +35,6 @@ class LogManager(private val reactContext: ReactApplicationContext) : ReactConte
|
||||
return File(pubDirectory, gethLogFileName)
|
||||
}
|
||||
|
||||
private fun getPreLoginLogFile(): File {
|
||||
val pubDirectory = utils.getPublicStorageDirectory()
|
||||
return File(pubDirectory, preLoginLogFileName)
|
||||
}
|
||||
|
||||
fun prepareLogsFile(context: Context): File? {
|
||||
val logFile = getGethLogFile()
|
||||
|
||||
@@ -161,7 +156,6 @@ class LogManager(private val reactContext: ReactApplicationContext) : ReactConte
|
||||
val statusLogFile = File(logsTempDir, statusLogFileName)
|
||||
val gethLogFile = getGethLogFile()
|
||||
val requestLogFile = getRequestLogFile()
|
||||
val preLoginLogFile = getPreLoginLogFile()
|
||||
|
||||
try {
|
||||
if (zipFile.exists() || zipFile.createNewFile()) {
|
||||
@@ -181,9 +175,6 @@ class LogManager(private val reactContext: ReactApplicationContext) : ReactConte
|
||||
if (requestLogFile.exists()) {
|
||||
filesToZip.add(requestLogFile)
|
||||
}
|
||||
if (preLoginLogFile.exists()) {
|
||||
filesToZip.add(preLoginLogFile)
|
||||
}
|
||||
val zipped = zip(filesToZip.toTypedArray(), zipFile, errorList)
|
||||
if (zipped && zipFile.exists()) {
|
||||
zipFile.setReadable(true, false)
|
||||
@@ -214,7 +205,6 @@ class LogManager(private val reactContext: ReactApplicationContext) : ReactConte
|
||||
private const val gethLogFileName = "geth.log"
|
||||
private const val statusLogFileName = "Status.log"
|
||||
private const val requestsLogFileName = "api.log"
|
||||
private const val preLoginLogFileName = "pre_login.log"
|
||||
private const val logsZipFileName = "Status-debug-logs.zip"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ RCT_EXPORT_METHOD(sendLogs:(NSString *)dbJson
|
||||
|
||||
NSURL *mainGethLogsFile = [rootUrl URLByAppendingPathComponent:@"geth.log"];
|
||||
NSURL *mainLogsFile = [logsFolderName URLByAppendingPathComponent:@"geth.log"];
|
||||
NSURL *preLoginLogFile = [rootUrl URLByAppendingPathComponent:@"pre_login.log"];
|
||||
|
||||
NSURL *requestsLogFile = [rootUrl URLByAppendingPathComponent:@"api.log"];
|
||||
|
||||
@@ -47,10 +46,6 @@ RCT_EXPORT_METHOD(sendLogs:(NSString *)dbJson
|
||||
if ([fileManager fileExistsAtPath:requestsLogFile.path]) {
|
||||
[fileManager copyItemAtPath:requestsLogFile.path toPath:[logsFolderName URLByAppendingPathComponent:@"api.log"].path error:nil];
|
||||
}
|
||||
|
||||
if ([fileManager fileExistsAtPath:preLoginLogFile.path]) {
|
||||
[fileManager copyItemAtPath:preLoginLogFile.path toPath:[logsFolderName URLByAppendingPathComponent:@"pre_login.log"].path error:nil];
|
||||
}
|
||||
|
||||
[SSZipArchive createZipFileAtPath:zipFile.path withContentsOfDirectory:logsFolderName.path];
|
||||
[fileManager removeItemAtPath:logsFolderName.path error:nil];
|
||||
|
||||
@@ -6,7 +6,6 @@ readonly FOOJAY_FALLBACK="0.5.0"
|
||||
readonly KOTLIN_FALLBACK="1.8.0"
|
||||
readonly TOOLS_FALLBACK="3.5.4"
|
||||
readonly HERMES_FALLBACK="0.73.5"
|
||||
readonly GRADLE_LINT_FALLBACK="31.1.1"
|
||||
|
||||
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
|
||||
cd "${GIT_ROOT}"
|
||||
@@ -26,28 +25,16 @@ get_version() {
|
||||
echo "$version"
|
||||
}
|
||||
|
||||
# https://github.com/googlesamples/android-custom-lint-rules/blob/be672cd747ecf13844918e1afccadb935f856a72/docs/api-guide/example.md.html#L112-L129
|
||||
get_gradle_lint_version() {
|
||||
gradlePluginVersion=$(get_version "./nix/pkgs/aapt2/default.nix" "version =" $GRADLE_LINT_FALLBACK)
|
||||
major=$(echo "$gradlePluginVersion" | grep -o "^[0-9]*")
|
||||
# lintVersion = gradlePluginVersion + 23.0.0
|
||||
major=$((major + 23))
|
||||
minor=$(echo "$gradlePluginVersion" | grep -o "\.[0-9]*\." | grep -o "[0-9]*")
|
||||
patch=$(echo "$gradlePluginVersion" | grep -o "[0-9]*$")
|
||||
|
||||
echo "$major.$minor.$patch"
|
||||
}
|
||||
|
||||
foojay_version=$(get_version "./node_modules/@react-native/gradle-plugin/settings.gradle.kts" "foojay.*version" "$FOOJAY_FALLBACK")
|
||||
kotlin_version=$(get_version "./node_modules/@react-native/gradle-plugin/gradle/libs.versions.toml" "kotlin =" "$KOTLIN_FALLBACK")
|
||||
tools_version=$(get_version "./patches/BlurView-build.gradle.patch" "gradle:" "$TOOLS_FALLBACK")
|
||||
hermes_version=$(get_version "./node_modules/react-native/ReactAndroid/gradle.properties" "VERSION_NAME" "$HERMES_FALLBACK")
|
||||
lint_version=$(get_gradle_lint_version)
|
||||
|
||||
|
||||
cat << EOF
|
||||
org.gradle.toolchains.foojay-resolver-convention:org.gradle.toolchains.foojay-resolver-convention.gradle.plugin:$foojay_version
|
||||
org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:$kotlin_version
|
||||
com.android.tools.build:gradle:$tools_version
|
||||
com.facebook.react:hermes-android:$hermes_version
|
||||
com.android.tools.lint:lint-gradle:$lint_version
|
||||
com.android.tools.lint:lint-gradle:31.1.1
|
||||
EOF
|
||||
|
||||
@@ -10,7 +10,6 @@ let
|
||||
|
||||
pname = "aapt2";
|
||||
# Warning: This must be the same as gradlePluginVersion android/gradle.properties
|
||||
# also referenced in nix/deps/gradle/deps_hack.sh
|
||||
version = "8.1.1-10154469";
|
||||
|
||||
pkgPath = "com/android/tools/build/aapt2";
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
(ns status-im.app.events
|
||||
(:require
|
||||
[status-im.app.use-case :as uc]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
|
||||
(def navigation-effects-tree
|
||||
{:uc-view-saved-addresses
|
||||
{:on-start [[:dispatch [:open-modal :screen/settings.saved-addresses]]]
|
||||
:uc-add-saved-address {:on-start [[:dispatch [:open-modal :screen/settings.add-address-to-save]]]
|
||||
:on-finish [[:dispatch [:navigate-back]]]}
|
||||
:on-finish [[:dispatch [:navigate-back]]]}})
|
||||
|
||||
|
||||
(def db-path-use-case-stack [:app :use-cases-stack])
|
||||
|
||||
(defn use-cases
|
||||
[db]
|
||||
(get-in db db-path-use-case-stack '()))
|
||||
|
||||
(defn current-use-case
|
||||
[db]
|
||||
(-> db
|
||||
use-cases
|
||||
first))
|
||||
|
||||
(defn- navigation-effects-for-key
|
||||
[db last-key]
|
||||
(let [path (-> db
|
||||
use-cases
|
||||
reverse
|
||||
vec
|
||||
(conj last-key))]
|
||||
(tap> {:in :navigation-effects-for-key
|
||||
:use-cases (use-cases db)})
|
||||
(get-in navigation-effects-tree path)))
|
||||
|
||||
(defn start-use-case-navigation-effects
|
||||
[db]
|
||||
(navigation-effects-for-key db :on-start))
|
||||
|
||||
(defn finish-use-case-navigation-effects
|
||||
[db]
|
||||
(navigation-effects-for-key db :on-finish))
|
||||
|
||||
|
||||
(rf/reg-event-fx :app/start-use-case
|
||||
(fn [{:keys [db]} [use-case-id]]
|
||||
(let [new-db (update-in db db-path-use-case-stack conj use-case-id)]
|
||||
#_(tap> {:in :app/start-use-case
|
||||
:effects (start-use-case-navigation-effects new-db)})
|
||||
{:db new-db
|
||||
:fx (start-use-case-navigation-effects new-db)})))
|
||||
|
||||
(rf/reg-event-fx :app/finish-use-case
|
||||
(fn [{:keys [db]} [use-case-to-finish]]
|
||||
(let [new-db (update-in db db-path-use-case-stack rest)]
|
||||
(if (= (current-use-case db) use-case-to-finish)
|
||||
{:db new-db
|
||||
:fx (finish-use-case-navigation-effects db)}
|
||||
;; TODO: kozieiev: replace with effect
|
||||
(log/error "Attempt to finish use case that is not current:" use-case-to-finish)))))
|
||||
|
||||
(rf/reg-event-fx :app/clear-use-cases-stack
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc-in db db-path-use-case-stack '())}))
|
||||
|
||||
(comment
|
||||
(rf/dispatch [:app/start-use-case :uc-save-address])
|
||||
(rf/dispatch [:app/start-use-case :uc-edit-address])
|
||||
(rf/dispatch [:app/finish-use-case :uc-edit-address])
|
||||
(rf/dispatch [:app/finish-use-case :uc-save-address])
|
||||
|
||||
|
||||
(rf/dispatch [:app/clear-use-cases-stack])
|
||||
|
||||
(rf/sub [:app/use-case-active? :uc-edit-address])
|
||||
(rf/sub [:app/use-case-active? :uc-save-address])
|
||||
(rf/sub [:app/current-use-case])
|
||||
(rf/dispatch [:navigate-back])
|
||||
|
||||
(start-use-case-navigation-effects {:app {:use-cases-stack
|
||||
'(:uc-view-saved-addresses :uc-add-saved-address)}})
|
||||
(finish-use-case-navigation-effects {:app {:use-cases-stack
|
||||
'(:uc-view-saved-addresses :uc-add-saved-address)}})
|
||||
|
||||
(use-cases {:app {:use-cases-stack
|
||||
'(:uc-view-saved-addresses :uc-add-saved-address)}})
|
||||
|
||||
(-> {:app {:use-cases-stack '(:uc-view-saved-addresses :uc-add-saved-address)}}
|
||||
use-cases
|
||||
reverse
|
||||
vec
|
||||
(conj :on-exit))
|
||||
|
||||
|
||||
)
|
||||
|
||||
#_(rf/reg-event-fx
|
||||
:app/notify-user
|
||||
(fn [{:keys [db]} [{:keys [text type] :as message}]]
|
||||
(let [notification-id (-> db
|
||||
(get-in [:app :last-user-notification :id] 0)
|
||||
inc)]
|
||||
{;; whenever we need to publish notification we override the old and increment id
|
||||
:db (assoc-in db
|
||||
[:app :last-user-notification]
|
||||
(merge message
|
||||
{:id notification-id}))
|
||||
;; TODO: toasts are part of ui layer and they shouldn't be published here. Instead some part
|
||||
;; of ui should keep track of last user notification and generate toast
|
||||
:fx [#_[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type type
|
||||
:text text}]]]})))
|
||||
|
||||
#_(comment
|
||||
(rf/dispatch [:app/notify-user
|
||||
{:type :positive
|
||||
:text "This is a good news"}])
|
||||
(rf/dispatch [:app/notify-user
|
||||
{:type :negative
|
||||
:text "This is a bad news"}])
|
||||
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:text "This is a test notification3"}])
|
||||
)
|
||||
@@ -0,0 +1,97 @@
|
||||
(ns status-im.app.use-case)
|
||||
|
||||
(defmulti initial-state
|
||||
(fn [use-case-id]
|
||||
use-case-id))
|
||||
|
||||
(defmethod initial-state :default
|
||||
[_]
|
||||
{:use-case-id :default})
|
||||
|
||||
(defn start
|
||||
[use-case-id state-update]
|
||||
(merge (initial-state use-case-id)
|
||||
state-update))
|
||||
|
||||
(defn make-step
|
||||
[current-state state-update]
|
||||
(merge current-state state-update))
|
||||
|
||||
(defn finish
|
||||
[use-case-id state-update]
|
||||
(merge (initial-state use-case-id)
|
||||
state-update))
|
||||
|
||||
|
||||
;; -----------------------------------------------------
|
||||
|
||||
(defmethod initial-state :uc-view-saved-addresses
|
||||
[_]
|
||||
{:use-case-id :uc-view-saved-addresses})
|
||||
|
||||
(defmethod initial-state :uc-add-saved-address
|
||||
[_]
|
||||
{:use-case-id :uc-add-saved-address
|
||||
:address nil
|
||||
:ens nil
|
||||
:ens? false
|
||||
:name nil
|
||||
:customization-color nil})
|
||||
|
||||
;; -----------------------------------------------------
|
||||
|
||||
(defmulti navigation-start
|
||||
(fn [use-case-data]
|
||||
(:use-case-id use-case-data)))
|
||||
|
||||
(defmulti navigation-step
|
||||
(fn [use-case-data]
|
||||
(:use-case-id use-case-data)))
|
||||
|
||||
(defmethod navigation-step :default
|
||||
[]
|
||||
nil)
|
||||
|
||||
(defmulti navigation-finish
|
||||
(fn [use-case-data]
|
||||
(:use-case-id use-case-data)))
|
||||
|
||||
;; -----------------------------------------------------
|
||||
|
||||
(defmethod navigation-start :uc-view-saved-addresses
|
||||
[_]
|
||||
[[:dispatch [:open-modal :screen/settings.saved-addresses]]])
|
||||
|
||||
(defmethod navigation-finish :uc-view-saved-addresses
|
||||
[_]
|
||||
[[:dispatch [:navigate-back]]])
|
||||
|
||||
;; -----------------------------------------------------
|
||||
|
||||
(defmethod navigation-start :uc-add-saved-address
|
||||
[_]
|
||||
[[:dispatch [:open-modal :screen/settings.add-address-to-save]]])
|
||||
|
||||
(defmethod navigation-step :uc-add-saved-address
|
||||
[{:keys [address ens ens?] :as use-case-state}]
|
||||
[[:dispatch [:open-modal :screen/settings.add-address-to-save]]])
|
||||
|
||||
(defmethod navigation-finish :uc-add-saved-address
|
||||
[_]
|
||||
[[:dispatch [:navigate-back]]])
|
||||
|
||||
;; -----------------------------------------------------
|
||||
(comment
|
||||
(initial-state :uc-add-saved-address)
|
||||
(initial-state :uc-view-saved-addresses)
|
||||
(initial-state :unknown)
|
||||
|
||||
(navigation-start {:use-case-id :uc-add-saved-address})
|
||||
(navigation-finish {:use-case-id :uc-add-saved-address})
|
||||
(navigation-start {:use-case-id :uc-add-saved-address})
|
||||
|
||||
(-> :uc-add-saved-address
|
||||
initial-state
|
||||
(make-step {:address "0xasdfas"})))
|
||||
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
|
||||
(defn outmost-transparent-container
|
||||
[]
|
||||
{:elevation 2
|
||||
:pointer-events :box-none
|
||||
:padding-top (+ (safe-area/get-top) 6)
|
||||
:flex-direction :column
|
||||
:justify-content :center
|
||||
:align-items :center})
|
||||
{:elevation 2
|
||||
:pointer-events :box-none
|
||||
:padding-top (+ (safe-area/get-top) 6)
|
||||
:flex-direction :column
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:background-color :yellow})
|
||||
|
||||
(def each-toast-container
|
||||
{:width "100%"
|
||||
|
||||
@@ -443,10 +443,7 @@
|
||||
(def ^:const wallet-account-name-max-length 20)
|
||||
|
||||
|
||||
(def ^:const gas-rate-low 0)
|
||||
(def ^:const gas-rate-medium 1)
|
||||
(def ^:const gas-rate-high 2)
|
||||
(def ^:const gas-rate-custom 3)
|
||||
(def ^:const send-type-transfer 0)
|
||||
(def ^:const send-type-bridge 5)
|
||||
(def ^:const send-type-erc-721-transfer 6)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
[status-im.contexts.chat.messenger.messages.pin.events :as messages.pin]
|
||||
[status-im.contexts.communities.events :as communities]
|
||||
[status-im.contexts.shell.activity-center.events :as activity-center]
|
||||
[status-im.contexts.wallet.data-store :as wallet.data-store]
|
||||
[status-im.infra.transform :as infra.transform]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -220,10 +220,10 @@
|
||||
current-visibility-status-clj)))
|
||||
|
||||
(seq saved-addresses-js)
|
||||
(let [saved-addresses (-> saved-addresses-js types/js->clj wallet.data-store/rpc->saved-addresses)]
|
||||
(let [saved-addresses (-> saved-addresses-js types/js->clj infra.transform/rpc->saved-addresses)]
|
||||
(js-delete response-js "savedAddresses")
|
||||
(rf/merge cofx
|
||||
{:fx [[:dispatch [:wallet/reconcile-saved-addresses saved-addresses]]]}
|
||||
{:fx [[:dispatch [:domain/reconcile-saved-addresses saved-addresses]]]}
|
||||
(process-next response-js sync-handler)))
|
||||
|
||||
(seq ens-username-details-js)
|
||||
|
||||
@@ -27,7 +27,5 @@
|
||||
:callback
|
||||
(fn [{:keys [error]}]
|
||||
(if (string/blank? error)
|
||||
(do
|
||||
(rf/dispatch [:biometric/disable])
|
||||
(rf/dispatch [:navigate-to :screen/keycard.migrate.success]))
|
||||
(rf/dispatch [:navigate-to :screen/keycard.migrate.success])
|
||||
(rf/dispatch [:navigate-to :screen/keycard.migrate.fail])))}]]})))
|
||||
|
||||
+8
-6
@@ -15,7 +15,8 @@
|
||||
|
||||
(defn- navigate-back
|
||||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
(rf/dispatch [:app/finish-use-case :uc-add-saved-address])
|
||||
#_(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn- validate-input
|
||||
[account-addresses saved-addresses user-input]
|
||||
@@ -164,15 +165,16 @@
|
||||
on-press-continue (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch
|
||||
[:wallet/set-address-to-save
|
||||
[:open-modal :screen/settings.save-address
|
||||
{:address address
|
||||
:ens (when ens-name? address-or-ens)
|
||||
:ens? ens-name?}])
|
||||
(rf/dispatch
|
||||
[:open-modal :screen/settings.save-address]))
|
||||
:ens? ens-name?}]))
|
||||
[address ens-name? address-or-ens])]
|
||||
(rn/use-unmount #(rf/dispatch [:wallet/clean-scanned-address]))
|
||||
(rn/use-mount #(rf/dispatch [:wallet/clear-address-to-save]))
|
||||
#_(rn/use-effect (fn []
|
||||
(when (rf/sub [:app/use-case-active? :uc-add-saved-addresses])
|
||||
(rf/dispatch [:navigate-back])))
|
||||
[(rf/sub [:app/use-case-active? :uc-add-saved-addresses])])
|
||||
[quo/overlay {:type :shell}
|
||||
[floating-button-page/view
|
||||
{:footer-container-padding 0
|
||||
|
||||
@@ -5,164 +5,97 @@
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn save-address
|
||||
[{:keys [db]}
|
||||
[{:keys [address name customization-color on-success on-error ens]}]]
|
||||
(let [test-networks-enabled? (boolean (get-in db [:profile/profile :test-networks-enabled?]))
|
||||
address-to-save {:address address
|
||||
:name name
|
||||
:colorId customization-color
|
||||
:ens ens
|
||||
:isTest test-networks-enabled?}]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_upsertSavedAddress"
|
||||
:params [address-to-save]
|
||||
:on-success on-success
|
||||
:on-error on-error}]]]}))
|
||||
(rf/reg-event-fx :app/save-address
|
||||
(fn [{:keys [db]}
|
||||
[{:keys [address name customization-color ens edit?]}]]
|
||||
(let [on-success (if edit?
|
||||
[:wallet/edit-saved-address-success]
|
||||
[:wallet/add-saved-address-success])
|
||||
test-networks-enabled? (boolean (get-in db [:profile/profile :test-networks-enabled?]))
|
||||
address-to-save {:address address
|
||||
:name name
|
||||
:colorId customization-color
|
||||
:ens ens
|
||||
:isTest test-networks-enabled?}]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_upsertSavedAddress"
|
||||
:params [address-to-save]
|
||||
:on-success on-success
|
||||
:on-error [:wallet/add-saved-address-failed]}]]]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/save-address save-address)
|
||||
(rf/reg-event-fx :wallet/delete-saved-address-success
|
||||
(fn [{:keys [db]} [{:keys [address test-networks-enabled? toast-message]}]]
|
||||
(let [db-key (if test-networks-enabled? :test :prod)
|
||||
saved-address (get-in db [:wallet :saved-addresses db-key address])]
|
||||
{:fx [[:dispatch [:domain/reconcile-saved-addresses [(assoc saved-address :removed? true)]]]
|
||||
[:dispatch [:hide-bottom-sheet]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text toast-message}]}]]})))
|
||||
|
||||
(defn- update-saved-addresses
|
||||
[saved-addresses-db new-saved-addresses]
|
||||
(reduce
|
||||
(fn [acc {:keys [address removed? test?] :as saved-address}]
|
||||
(let [db-key (if test? :test :prod)]
|
||||
(if removed?
|
||||
(update acc db-key dissoc address)
|
||||
(assoc-in acc [db-key address] saved-address))))
|
||||
(or saved-addresses-db
|
||||
{:test {}
|
||||
:prod {}})
|
||||
new-saved-addresses))
|
||||
(rf/reg-event-fx :wallet/delete-saved-address-failed
|
||||
(fn [_ [error]]
|
||||
{:fx [[:dispatch [:hide-bottom-sheet]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :negative
|
||||
:theme :dark
|
||||
:text error}]}]]}))
|
||||
|
||||
(defn reconcile-saved-addresses
|
||||
[{:keys [db]} [saved-addresses]]
|
||||
{:db (update-in db [:wallet :saved-addresses] update-saved-addresses saved-addresses)})
|
||||
(rf/reg-event-fx :wallet/delete-saved-address
|
||||
(fn [{:keys [db]} [{:keys [address toast-message]}]]
|
||||
(let [test-networks-enabled? (boolean (get-in db [:profile/profile :test-networks-enabled?]))]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_deleteSavedAddress"
|
||||
:params [address test-networks-enabled?]
|
||||
:on-success [:wallet/delete-saved-address-success
|
||||
{:address address
|
||||
:test-networks-enabled? test-networks-enabled?
|
||||
:toast-message toast-message}]
|
||||
:on-error [:wallet/delete-saved-address-failed]}]]]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/reconcile-saved-addresses reconcile-saved-addresses)
|
||||
(rf/reg-event-fx :wallet/add-saved-address-success
|
||||
(fn [_]
|
||||
{:fx [[:dispatch [:infra/get-saved-addresses]]
|
||||
[:dispatch [:dismiss-modal :screen/settings.add-address-to-save]]
|
||||
[:dispatch [:dismiss-modal :screen/settings.save-address]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text (i18n/label :t/address-saved)}]}]]}))
|
||||
|
||||
(defn get-saved-addresses-success
|
||||
[_ [raw-saved-addresses]]
|
||||
(let [saved-addresses (data-store/rpc->saved-addresses raw-saved-addresses)]
|
||||
{:fx [[:dispatch [:wallet/reconcile-saved-addresses saved-addresses]]]}))
|
||||
(rf/reg-event-fx :wallet/edit-saved-address-success
|
||||
(fn [_]
|
||||
{:fx [[:dispatch [:infra/get-saved-addresses]]
|
||||
[:dispatch [:dismiss-modal :screen/settings.edit-saved-address]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text (i18n/label :t/address-edited)}]}]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/get-saved-addresses-success get-saved-addresses-success)
|
||||
|
||||
(defn saved-addresses-rpc-error
|
||||
[_ [action error]]
|
||||
(log/warn (str "[wallet] [saved-addresses] Failed to " action)
|
||||
{:error error}))
|
||||
|
||||
(rf/reg-event-fx :wallet/saved-addresses-rpc-error saved-addresses-rpc-error)
|
||||
|
||||
(defn get-saved-addresses
|
||||
[_]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_getSavedAddresses"
|
||||
:on-success [:wallet/get-saved-addresses-success]
|
||||
:on-error [:wallet/saved-addresses-rpc-error :get-saved-addresses]}]]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/get-saved-addresses get-saved-addresses)
|
||||
|
||||
(defn delete-saved-address-success
|
||||
[{:keys [db]} [{:keys [address test-networks-enabled? toast-message]}]]
|
||||
(let [db-key (if test-networks-enabled? :test :prod)
|
||||
saved-address (get-in db [:wallet :saved-addresses db-key address])]
|
||||
{:fx [[:dispatch [:wallet/reconcile-saved-addresses [(assoc saved-address :removed? true)]]]
|
||||
[:dispatch [:hide-bottom-sheet]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text toast-message}]}]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/delete-saved-address-success delete-saved-address-success)
|
||||
|
||||
(defn delete-saved-address-failed
|
||||
[_ [error]]
|
||||
{:fx [[:dispatch [:hide-bottom-sheet]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :negative
|
||||
:theme :dark
|
||||
:text error}]}]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/delete-saved-address-failed delete-saved-address-failed)
|
||||
|
||||
(defn delete-saved-address
|
||||
[{:keys [db]} [{:keys [address toast-message]}]]
|
||||
(let [test-networks-enabled? (boolean (get-in db [:profile/profile :test-networks-enabled?]))]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_deleteSavedAddress"
|
||||
:params [address test-networks-enabled?]
|
||||
:on-success [:wallet/delete-saved-address-success
|
||||
{:address address
|
||||
:test-networks-enabled? test-networks-enabled?
|
||||
:toast-message toast-message}]
|
||||
:on-error [:wallet/delete-saved-address-failed]}]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/delete-saved-address delete-saved-address)
|
||||
|
||||
(defn add-saved-address-success
|
||||
[_ [toast-message]]
|
||||
{:fx [[:dispatch [:wallet/get-saved-addresses]]
|
||||
[:dispatch [:dismiss-modal :screen/settings.add-address-to-save]]
|
||||
[:dispatch [:dismiss-modal :screen/settings.save-address]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text toast-message}]}]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/add-saved-address-success add-saved-address-success)
|
||||
|
||||
(defn edit-saved-address-success
|
||||
[_]
|
||||
{:fx [[:dispatch [:wallet/get-saved-addresses]]
|
||||
[:dispatch [:dismiss-modal :screen/settings.edit-saved-address]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text (i18n/label :t/address-edited)}]}]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/edit-saved-address-success edit-saved-address-success)
|
||||
|
||||
(defn add-saved-address-failed
|
||||
[_ [error]]
|
||||
{:fx [[:dispatch [:wallet/saved-addresses-rpc-error :add-save-address error]]
|
||||
[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type :negative
|
||||
:theme :dark
|
||||
:text error}]]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/add-saved-address-failed add-saved-address-failed)
|
||||
|
||||
(defn set-address-to-save
|
||||
[{:keys [db]} [args]]
|
||||
{:db (assoc-in db [:wallet :ui :saved-address] args)})
|
||||
|
||||
(rf/reg-event-fx :wallet/set-address-to-save set-address-to-save)
|
||||
|
||||
(defn clear-address-to-save
|
||||
[{:keys [db]}]
|
||||
{:db (update-in db [:wallet :ui] dissoc :saved-address)})
|
||||
|
||||
(rf/reg-event-fx :wallet/clear-address-to-save clear-address-to-save)
|
||||
|
||||
(defn check-remaining-capacity-for-saved-addresses
|
||||
[{:keys [db]} [{:keys [on-success on-error]}]]
|
||||
(let [test-networks-enabled? (boolean (get-in db [:profile/profile :test-networks-enabled?]))]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_remainingCapacityForSavedAddresses"
|
||||
:params [test-networks-enabled?]
|
||||
:on-success on-success
|
||||
:on-error on-error}]]]}))
|
||||
(rf/reg-event-fx :wallet/add-saved-address-failed
|
||||
(fn [_ [error]]
|
||||
{:fx [[:dispatch [:infra/saved-addresses-rpc-error :add-save-address error]]
|
||||
[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type :negative
|
||||
:theme :dark
|
||||
:text error}]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/check-remaining-capacity-for-saved-addresses
|
||||
check-remaining-capacity-for-saved-addresses)
|
||||
(fn [{:keys [db]} [{:keys [on-success on-error]}]]
|
||||
(let [test-networks-enabled? (boolean (get-in db [:profile/profile :test-networks-enabled?]))]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_remainingCapacityForSavedAddresses"
|
||||
:params [test-networks-enabled?]
|
||||
:on-success on-success
|
||||
:on-error on-error}]]]})))
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
result-fx (:fx effects)
|
||||
expected-fx [[:json-rpc/call
|
||||
[{:method "wakuext_getSavedAddresses"
|
||||
:on-success [:wallet/get-saved-addresses-success]
|
||||
:on-success [:infra/convert-saved-addresses]
|
||||
:on-error [:wallet/saved-addresses-rpc-error :get-saved-addresses]}]]]]
|
||||
(is (match? expected-fx result-fx)))))
|
||||
|
||||
@@ -56,10 +56,10 @@
|
||||
(deftest get-saved-addresses-success-test
|
||||
(let [cofx {:db {}}
|
||||
raw-saved-addresses [saved-address-rpc-1]
|
||||
effects (events/get-saved-addresses-success cofx [raw-saved-addresses])
|
||||
effects (events/convert-saved-addresses cofx [raw-saved-addresses])
|
||||
saved-addresses (data-store/rpc->saved-addresses raw-saved-addresses)
|
||||
result-fx (:fx effects)
|
||||
expected-fx [[:dispatch [:wallet/reconcile-saved-addresses saved-addresses]]]]
|
||||
expected-fx [[:dispatch [:domain/reconcile-saved-addresses saved-addresses]]]]
|
||||
(is (match? expected-fx result-fx))))
|
||||
|
||||
(deftest reconcile-saved-addresses-test
|
||||
@@ -220,7 +220,7 @@
|
||||
toast-message "Address saved"
|
||||
effects (events/add-saved-address-success cofx [toast-message])
|
||||
result-fx (:fx effects)
|
||||
expected-fx [[:dispatch [:wallet/get-saved-addresses]]
|
||||
expected-fx [[:dispatch [:infra/get-saved-addresses]]
|
||||
[:dispatch [:dismiss-modal :screen/settings.add-address-to-save]]
|
||||
[:dispatch [:dismiss-modal :screen/settings.save-address]]
|
||||
[:dispatch-later
|
||||
@@ -238,7 +238,7 @@
|
||||
toast-message "Address edited"
|
||||
effects (events/edit-saved-address-success cofx)
|
||||
result-fx (:fx effects)
|
||||
expected-fx [[:dispatch [:wallet/get-saved-addresses]]
|
||||
expected-fx [[:dispatch [:infra/get-saved-addresses]]
|
||||
[:dispatch [:dismiss-modal :screen/settings.edit-saved-address]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
|
||||
@@ -17,50 +17,42 @@
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{:keys [edit?]} (rf/sub [:get-screen-params])
|
||||
{:keys [address name customization-color ens ens?]}
|
||||
(rf/sub [:wallet/saved-address])
|
||||
(let [{:keys [address name customization-color ens
|
||||
ens? edit?]} (rf/sub [:get-screen-params])
|
||||
[address-label set-address-label] (rn/use-state (or name ""))
|
||||
[address-color set-address-color] (rn/use-state (or customization-color
|
||||
(rand-nth colors/account-colors)))
|
||||
placeholder (i18n/label :t/address-name)
|
||||
address-text (rn/use-callback
|
||||
(fn []
|
||||
[quo/address-text
|
||||
{:full-address? true
|
||||
:address address
|
||||
:format :long}])
|
||||
[address])
|
||||
on-press-save (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:wallet/save-address
|
||||
{:on-success
|
||||
(if edit?
|
||||
[:wallet/edit-saved-address-success]
|
||||
[:wallet/add-saved-address-success
|
||||
(i18n/label :t/address-saved)])
|
||||
:on-error
|
||||
[:wallet/add-saved-address-failed]
|
||||
:name address-label
|
||||
:ens (when ens? ens)
|
||||
:address address
|
||||
:customization-color address-color}]))
|
||||
[address address-label
|
||||
address-color])
|
||||
data-item-props (rn/use-memo
|
||||
#(cond-> {:status :default
|
||||
:size :default
|
||||
:subtitle-type :default
|
||||
:label :none
|
||||
:blur? true
|
||||
:card? true
|
||||
:title (i18n/label :t/address)
|
||||
:subtitle ens
|
||||
:custom-subtitle address-text
|
||||
:container-style style/data-item}
|
||||
ens?
|
||||
(dissoc :custom-subtitle))
|
||||
[ens ens? address-text])]
|
||||
placeholder (i18n/label :t/address-name)
|
||||
address-text (rn/use-callback
|
||||
(fn []
|
||||
[quo/address-text
|
||||
{:full-address? true
|
||||
:address address
|
||||
:format :long}])
|
||||
[address])
|
||||
on-press-save (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:app/save-address
|
||||
{:edit? edit?
|
||||
:name address-label
|
||||
:ens (when ens? ens)
|
||||
:address address
|
||||
:customization-color address-color}]))
|
||||
[address address-label
|
||||
address-color])
|
||||
data-item-props (rn/use-memo
|
||||
#(cond-> {:status :default
|
||||
:size :default
|
||||
:subtitle-type :default
|
||||
:blur? true
|
||||
:card? true
|
||||
:title (i18n/label :t/address)
|
||||
:subtitle ens
|
||||
:custom-subtitle address-text
|
||||
:container-style style/data-item}
|
||||
ens?
|
||||
(dissoc :custom-subtitle))
|
||||
[ens ens? address-text])]
|
||||
[quo/overlay {:type :shell}
|
||||
[floating-button-page/view
|
||||
{:footer-container-padding (if edit? (+ (safe-area/get-bottom) 12) 0)
|
||||
|
||||
+9
-8
@@ -9,7 +9,7 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[{:keys [name address customization-color] :as opts}]
|
||||
[{:keys [name address customization-color] :as address-details}]
|
||||
(let [open-send-flow (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:wallet/init-send-flow-for-address
|
||||
@@ -62,19 +62,20 @@
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:content (fn []
|
||||
[remove-address/view opts])}])
|
||||
[opts])
|
||||
[remove-address/view address-details])}])
|
||||
[address-details])
|
||||
open-show-address-qr (rn/use-callback
|
||||
#(rf/dispatch [:open-modal
|
||||
:screen/settings.share-saved-address opts])
|
||||
[opts])
|
||||
:screen/settings.share-saved-address
|
||||
address-details])
|
||||
[address-details])
|
||||
open-edit-saved-address (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:wallet/set-address-to-save opts])
|
||||
(rf/dispatch [:open-modal
|
||||
:screen/settings.edit-saved-address
|
||||
{:edit? true}]))
|
||||
[opts])]
|
||||
(merge {:edit? true}
|
||||
address-details)]))
|
||||
[address-details])]
|
||||
[quo/action-drawer
|
||||
[[{:icon :i/arrow-up
|
||||
:label (i18n/label :t/send-to-user {:user name})
|
||||
|
||||
@@ -99,12 +99,15 @@
|
||||
|
||||
(defn- navigate-back
|
||||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
(rf/dispatch [:app/finish-use-case :uc-view-saved-addresses])
|
||||
#_(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn- add-address-to-save
|
||||
[]
|
||||
(rf/dispatch [:wallet/check-remaining-capacity-for-saved-addresses
|
||||
{:on-success #(rf/dispatch [:open-modal :screen/settings.add-address-to-save])
|
||||
{:on-success (fn []
|
||||
(rf/dispatch [:app/start-use-case :uc-add-saved-address])
|
||||
#_(rf/dispatch [:open-modal :screen/settings.add-address-to-save]))
|
||||
:on-error #(rf/dispatch [:toasts/upsert
|
||||
{:type :negative
|
||||
:theme :dark
|
||||
@@ -151,6 +154,10 @@
|
||||
:on-clear on-clear-input
|
||||
:customization-color customization-color}))
|
||||
[has-saved-addresses? customization-color search-text])]
|
||||
#_(rn/use-effect (fn []
|
||||
(when (rf/sub [:app/use-case-active? :uc-view-saved-addresses])
|
||||
(rf/dispatch [:navigate-back])))
|
||||
[(rf/sub [:app/use-case-active? :uc-view-saved-addresses])])
|
||||
[quo/overlay
|
||||
{:type :shell
|
||||
:top-inset? true}
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
|
||||
(defn open-saved-addresses-settings-modal
|
||||
[]
|
||||
(rf/dispatch [:open-modal :screen/settings.saved-addresses]))
|
||||
(rf/dispatch [:app/start-use-case :uc-view-saved-addresses])
|
||||
#_(rf/dispatch [:open-modal :screen/settings.saved-addresses]))
|
||||
|
||||
(defn open-keypairs-and-accounts-settings-modal
|
||||
[]
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
[clojure.string :as string]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.collectible.utils :as collectible-utils]
|
||||
[status-im.contexts.wallet.send.transaction-settings.core :as transaction-settings]
|
||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||
[utils.collection :as utils.collection]
|
||||
[utils.money :as money]
|
||||
@@ -163,25 +162,7 @@
|
||||
(->> (map rpc->keypair keypairs)
|
||||
(sort-by #(if (= (:type %) :profile) 0 1))))
|
||||
|
||||
(defn- add-keys-to-saved-address
|
||||
[saved-address]
|
||||
(assoc saved-address :ens? (not (string/blank? (:ens saved-address)))))
|
||||
|
||||
(defn rpc->saved-address
|
||||
[saved-address]
|
||||
(-> saved-address
|
||||
(set/rename-keys {:chainShortNames :chain-short-names
|
||||
:isTest :test?
|
||||
:createdAt :created-at
|
||||
:colorId :customization-color
|
||||
:mixedcaseAddress :mixedcase-address
|
||||
:removed :removed?})
|
||||
(update :customization-color (comp keyword string/lower-case))
|
||||
add-keys-to-saved-address))
|
||||
|
||||
(defn rpc->saved-addresses
|
||||
[saved-addresses]
|
||||
(map rpc->saved-address saved-addresses))
|
||||
|
||||
(defn reconcile-keypairs
|
||||
[keypairs]
|
||||
@@ -230,8 +211,7 @@
|
||||
|
||||
(defn new->old-route-path
|
||||
[new-path]
|
||||
(let [to-bignumber (fn [k] (-> new-path k money/bignumber))
|
||||
suggested-levels-for-max-fees-per-gas (:suggested-levels-for-max-fees-per-gas new-path)]
|
||||
(let [to-bignumber (fn [k] (-> new-path k money/bignumber))]
|
||||
{:approval-fee (to-bignumber :approval-fee)
|
||||
:approval-l-1-fee (to-bignumber :approval-l-1-fee)
|
||||
:bonder-fees (to-bignumber :tx-bonder-fees)
|
||||
@@ -240,34 +220,35 @@
|
||||
:amount-in-locked (:amount-in-locked new-path)
|
||||
:amount-in (:amount-in new-path)
|
||||
:max-amount-in (:max-amount-in new-path)
|
||||
:gas-fees {:gas-price "0"
|
||||
:base-fee (send-utils/convert-to-gwei (:tx-base-fee
|
||||
new-path)
|
||||
precision)
|
||||
:gas-fees {:gas-price "0"
|
||||
:base-fee (send-utils/convert-to-gwei (:tx-base-fee
|
||||
new-path)
|
||||
precision)
|
||||
:max-priority-fee-per-gas (send-utils/convert-to-gwei (:tx-priority-fee
|
||||
new-path)
|
||||
precision)
|
||||
:l-1-gas-fee (send-utils/convert-to-gwei (:tx-l-1-fee
|
||||
new-path)
|
||||
precision)
|
||||
:eip-1559-enabled true
|
||||
:tx-max-fees-per-gas (send-utils/convert-to-gwei
|
||||
(:tx-max-fees-per-gas
|
||||
new-path)
|
||||
precision)
|
||||
:suggested-gas-fees-for-setting
|
||||
{:tx-fee-mode/normal (send-utils/convert-to-gwei
|
||||
(:low
|
||||
suggested-levels-for-max-fees-per-gas)
|
||||
precision)
|
||||
:tx-fee-mode/fast (send-utils/convert-to-gwei
|
||||
(:medium
|
||||
suggested-levels-for-max-fees-per-gas)
|
||||
precision)
|
||||
:tx-fee-mode/urgent (send-utils/convert-to-gwei
|
||||
(:high
|
||||
suggested-levels-for-max-fees-per-gas)
|
||||
precision)}}
|
||||
:max-fee-per-gas-low (send-utils/convert-to-gwei
|
||||
(get-in
|
||||
new-path
|
||||
[:suggested-levels-for-max-fees-per-gas
|
||||
:low])
|
||||
precision)
|
||||
:max-fee-per-gas-medium (send-utils/convert-to-gwei
|
||||
(get-in
|
||||
new-path
|
||||
[:suggested-levels-for-max-fees-per-gas
|
||||
:medium])
|
||||
precision)
|
||||
:max-fee-per-gas-high (send-utils/convert-to-gwei
|
||||
(get-in
|
||||
new-path
|
||||
[:suggested-levels-for-max-fees-per-gas
|
||||
:high])
|
||||
precision)
|
||||
:l-1-gas-fee (send-utils/convert-to-gwei (:tx-l-1-fee
|
||||
new-path)
|
||||
precision)
|
||||
:eip-1559-enabled true}
|
||||
:bridge-name (:processor-name new-path)
|
||||
:amount-out (:amount-out new-path)
|
||||
:approval-contract-address (:approval-contract-address new-path)
|
||||
@@ -276,10 +257,7 @@
|
||||
:to (:to-chain new-path)
|
||||
:approval-amount-required (:approval-amount-required new-path)
|
||||
;; :cost () ;; tbd not used on desktop
|
||||
:gas-amount (:tx-gas-amount new-path)
|
||||
:router-input-params-uuid (:router-input-params-uuid new-path)
|
||||
:tx-fee-mode (transaction-settings/gas-rate->tx-fee-mode (:tx-gas-fee-mode
|
||||
new-path))}))
|
||||
:gas-amount (:tx-gas-amount new-path)}))
|
||||
|
||||
(defn tokens-never-loaded?
|
||||
[db]
|
||||
|
||||
@@ -435,16 +435,14 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet/start-bridge
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc-in db [:wallet :ui :send :tx-type] :tx/bridge)
|
||||
:fx [[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:start-flow? true
|
||||
:flow-id :wallet-bridge-flow}]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/set-send-tx-type
|
||||
(fn [{:keys [db]} [type]]
|
||||
{:db (assoc-in db [:wallet :ui :send :tx-type] type)}))
|
||||
(let [view-id (:view-id db)]
|
||||
(cond-> {:db (assoc-in db [:wallet :ui :send :tx-type] :tx/bridge)}
|
||||
(= view-id :screen/wallet.accounts)
|
||||
(assoc :fx
|
||||
[[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:start-flow? true
|
||||
:flow-id :wallet-bridge-flow}]]])))))
|
||||
|
||||
(rf/reg-event-fx :wallet/select-bridge-network
|
||||
(fn [{:keys [db]} [{:keys [network-chain-id stack-id]}]]
|
||||
@@ -579,7 +577,7 @@
|
||||
[:dispatch [:wallet/get-ethereum-chains]]
|
||||
[:dispatch [:wallet/get-accounts]]
|
||||
[:dispatch [:wallet/get-keypairs]]
|
||||
[:dispatch [:wallet/get-saved-addresses]]
|
||||
[:dispatch [:infra/get-saved-addresses]]
|
||||
(when (ff/enabled? ::ff/wallet.wallet-connect)
|
||||
[:dispatch-later [{:ms 500 :dispatch [:wallet-connect/init]}]])]}))
|
||||
|
||||
|
||||
@@ -91,16 +91,12 @@
|
||||
{:content buy-token/view}]))
|
||||
on-bridge-press (rn/use-callback
|
||||
(fn []
|
||||
;; For a single account, it starts the bridge flow immediately. For
|
||||
;; multiple accounts, it sets the transaction type and starts the
|
||||
;; bridge flow after account selection.
|
||||
(rf/dispatch [:wallet/clean-send-data])
|
||||
(when-not multiple-accounts?
|
||||
(rf/dispatch [:wallet/switch-current-viewing-account
|
||||
first-account-address])
|
||||
(rf/dispatch [:wallet/start-bridge]))
|
||||
first-account-address]))
|
||||
(rf/dispatch [:wallet/start-bridge])
|
||||
(when multiple-accounts?
|
||||
(rf/dispatch [:wallet/set-send-tx-type :tx/bridge])
|
||||
(rf/dispatch [:open-modal :screen/wallet.select-from])))
|
||||
[multiple-accounts? first-account-address])
|
||||
on-swap-press (rn/use-callback
|
||||
|
||||
@@ -6,12 +6,10 @@
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.contexts.wallet.data-store :as data-store]
|
||||
[status-im.contexts.wallet.send.transaction-settings.core :as transaction-settings]
|
||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||
[status-im.contexts.wallet.sheets.network-selection.view :as network-selection]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.money :as utils.money]
|
||||
[utils.number]
|
||||
[utils.re-frame :as rf]
|
||||
@@ -386,100 +384,16 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet/set-token-amount-to-send
|
||||
(fn [{:keys [db]} [{:keys [amount stack-id start-flow?]}]]
|
||||
{:db (assoc-in db [:wallet :ui :send :amount] amount)
|
||||
:fx [[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
:start-flow? start-flow?
|
||||
:flow-id :wallet-send-flow}]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet.send/auth-slider-completed
|
||||
(fn [{:keys [db]}]
|
||||
(let [last-request-uuid (get-in db [:wallet :ui :send :last-request-uuid])]
|
||||
{:db (update-in db [:wallet :ui :send] dissoc :transaction-for-signing)
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :amount] amount)
|
||||
(update-in [:wallet :ui :send] dissoc :transaction-for-signing))
|
||||
:fx [[:dispatch [:wallet/build-transactions-from-route {:request-uuid last-request-uuid}]]
|
||||
[:dispatch
|
||||
[:wallet.send/set-sign-transactions-callback-fx
|
||||
[:dispatch
|
||||
[:wallet/prepare-signatures-for-transactions :send]]]]]})))
|
||||
|
||||
(defn log-transaction-signature-error
|
||||
[error]
|
||||
(log/error
|
||||
"failed to prepare signatures for transactions"
|
||||
{:event :wallet/prepare-signatures-for-transactions
|
||||
:error error})
|
||||
(rf/dispatch
|
||||
[:toasts/upsert
|
||||
{:id :prepare-signatures-for-transactions-error
|
||||
:type :negative
|
||||
:text (:message error)}]))
|
||||
|
||||
(defn- send-transactions-with-signatures
|
||||
[tx-type signatures]
|
||||
(rf/dispatch
|
||||
[:wallet/send-router-transactions-with-signatures tx-type
|
||||
signatures]))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/send-router-transactions-with-signatures
|
||||
(fn [{:keys [db]} [tx-type signatures]]
|
||||
(let [transaction-for-signing (get-in db [:wallet :ui tx-type :transaction-for-signing])
|
||||
signatures-map (reduce (fn [acc {:keys [message signature]}]
|
||||
(assoc acc
|
||||
message
|
||||
(send-utils/signature-rsv signature)))
|
||||
{}
|
||||
signatures)]
|
||||
{:json-rpc/call [{:method "wallet_sendRouterTransactionsWithSignatures"
|
||||
:params [{:uuid (get-in transaction-for-signing [:sendDetails :uuid])
|
||||
:signatures signatures-map}]
|
||||
:on-success (fn []
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to send router transactions with signatures"
|
||||
{:event :wallet/send-router-transactions-with-signatures
|
||||
:error error})
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :send-router-transactions-with-signatures-error
|
||||
:type :negative
|
||||
:text (:message error)}]))}]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/prepare-signatures-for-transactions
|
||||
(fn [{:keys [db]} [tx-type]]
|
||||
(let [transaction-for-signing (get-in db
|
||||
[:wallet :ui tx-type :transaction-for-signing])
|
||||
signing-details (:signingDetails transaction-for-signing)
|
||||
{:keys [hashes address signOnKeycard]} signing-details
|
||||
send-tx-fn (partial send-transactions-with-signatures tx-type)]
|
||||
(if signOnKeycard
|
||||
{:fx [[:dispatch
|
||||
[:standard-auth/authorize-with-keycard
|
||||
{:on-complete (fn [pin]
|
||||
(rf/dispatch [:keycard/connect-and-sign-hashes
|
||||
{:keycard-pin pin
|
||||
:address address
|
||||
:hashes hashes
|
||||
:on-success send-tx-fn
|
||||
:on-failure log-transaction-signature-error}]))}]]]}
|
||||
{:fx [[:dispatch
|
||||
[:standard-auth/authorize
|
||||
{:on-auth-success (fn [sha3-pwd]
|
||||
(rf/dispatch [:wallet/standard-auth-autorization-success hashes
|
||||
address sha3-pwd send-tx-fn]))
|
||||
:auth-button-label (i18n/label :t/confirm)}]]]}))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/standard-auth-autorization-success
|
||||
(fn [_ [hashes address sha3-pwd send-tx-fn]]
|
||||
{:fx [[:effects.wallet/sign-transaction-hashes
|
||||
{:hashes hashes
|
||||
:address address
|
||||
:password (security/safe-unmask-data sha3-pwd)
|
||||
:on-success send-tx-fn
|
||||
:on-error log-transaction-signature-error}]]}))
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
:start-flow? start-flow?
|
||||
:flow-id :wallet-send-flow}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/build-transaction-for-collectible-route
|
||||
@@ -495,14 +409,16 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet/set-token-amount-to-bridge
|
||||
(fn [{:keys [db]} [{:keys [amount stack-id start-flow?]}]]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :amount] amount)
|
||||
(update-in [:wallet :ui :send] dissoc :transaction-for-signing))
|
||||
:fx [[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
:start-flow? start-flow?
|
||||
:flow-id :wallet-bridge-flow}]]]}))
|
||||
(let [last-request-uuid (get-in db [:wallet :ui :send :last-request-uuid])]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :amount] amount)
|
||||
(update-in [:wallet :ui :send] dissoc :transaction-for-signing))
|
||||
:fx [[:dispatch [:wallet/build-transactions-from-route {:request-uuid last-request-uuid}]]
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
:start-flow? start-flow?
|
||||
:flow-id :wallet-bridge-flow}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/clean-bridge-to-selection
|
||||
@@ -664,10 +580,7 @@
|
||||
:wallet/handle-suggested-routes
|
||||
(fn [{:keys [db]} [data]]
|
||||
(let [{send :send swap? :swap} (-> db :wallet :ui)
|
||||
skip-processing-routes? (:skip-processing-suggested-routes? send)
|
||||
clean-user-tx-settings? (get-in db
|
||||
[:wallet :ui :send :custom-tx-settings
|
||||
:delete-on-routes-update?])]
|
||||
skip-processing-routes? (:skip-processing-suggested-routes? send)]
|
||||
(when (or swap? (not skip-processing-routes?))
|
||||
(let [{error-code :code
|
||||
:as error} (:ErrorResponse data)
|
||||
@@ -678,16 +591,13 @@
|
||||
(log/error "failed to get suggested routes (async)"
|
||||
{:event :wallet/handle-suggested-routes
|
||||
:error error-message}))
|
||||
(merge
|
||||
(when clean-user-tx-settings?
|
||||
{:db (update-in db [:wallet :ui :send] dissoc :custom-tx-settings)})
|
||||
{:fx [[:dispatch
|
||||
(cond
|
||||
(and failure? swap?) [:wallet/swap-proposal-error error]
|
||||
failure? [:wallet/suggested-routes-error error-message]
|
||||
swap? [:wallet/swap-proposal-success (fix-routes data)]
|
||||
:else [:wallet/suggested-routes-success (fix-routes data)
|
||||
enough-assets?])]]}))))))
|
||||
{:fx [[:dispatch
|
||||
(cond
|
||||
(and failure? swap?) [:wallet/swap-proposal-error error]
|
||||
failure? [:wallet/suggested-routes-error error-message]
|
||||
swap? [:wallet/swap-proposal-success (fix-routes data)]
|
||||
:else [:wallet/suggested-routes-success (fix-routes data)
|
||||
enough-assets?])]]})))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/transaction-success
|
||||
@@ -759,6 +669,66 @@
|
||||
:type :negative
|
||||
:text (:message error)}]))}]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/prepare-signatures-for-transactions
|
||||
(fn [{:keys [db]} [type sha3-pwd]]
|
||||
(let [{:keys [hashes address signOnKeycard]} (get-in db
|
||||
[:wallet :ui type :transaction-for-signing
|
||||
:signingDetails])
|
||||
on-success (fn [signatures]
|
||||
(rf/dispatch
|
||||
[:wallet/send-router-transactions-with-signatures type
|
||||
signatures]))
|
||||
on-error (fn [error]
|
||||
(log/error
|
||||
"failed to prepare signatures for transactions"
|
||||
{:event :wallet/prepare-signatures-for-transactions
|
||||
:error error})
|
||||
(rf/dispatch
|
||||
[:toasts/upsert
|
||||
{:id :prepare-signatures-for-transactions-error
|
||||
:type :negative
|
||||
:text (:message error)}]))]
|
||||
(if signOnKeycard
|
||||
{:fx [[:dispatch
|
||||
[:standard-auth/authorize-with-keycard
|
||||
{:on-complete #(rf/dispatch [:keycard/connect-and-sign-hashes
|
||||
{:keycard-pin %
|
||||
:address address
|
||||
:hashes hashes
|
||||
:on-success on-success
|
||||
:on-failure on-error}])}]]]}
|
||||
{:fx [[:effects.wallet/sign-transaction-hashes
|
||||
{:hashes hashes
|
||||
:address address
|
||||
:password (security/safe-unmask-data sha3-pwd)
|
||||
:on-success on-success
|
||||
:on-error on-error}]]}))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/send-router-transactions-with-signatures
|
||||
(fn [{:keys [db]} [type signatures]]
|
||||
(let [transaction-for-signing (get-in db [:wallet :ui type :transaction-for-signing])
|
||||
signatures-map (reduce (fn [acc {:keys [message signature]}]
|
||||
(assoc acc
|
||||
message
|
||||
(send-utils/signature-rsv signature)))
|
||||
{}
|
||||
signatures)]
|
||||
{:json-rpc/call [{:method "wallet_sendRouterTransactionsWithSignatures"
|
||||
:params [{:uuid (get-in transaction-for-signing [:sendDetails :uuid])
|
||||
:signatures signatures-map}]
|
||||
:on-success (fn []
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to send router transactions with signatures"
|
||||
{:event :wallet/send-router-transactions-with-signatures
|
||||
:error error})
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :send-router-transactions-with-signatures-error
|
||||
:type :negative
|
||||
:text (:message error)}]))}]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/select-from-account
|
||||
(fn [{db :db} [{:keys [address stack-id network-details network start-flow?] :as params}]]
|
||||
@@ -847,69 +817,35 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet/init-tx-settings
|
||||
(fn [{db :db}]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :custom-tx-settings]
|
||||
{:max-base-fee {:low 5
|
||||
:current 8.2
|
||||
:high 9}
|
||||
:priority-fee {:low 0.6
|
||||
:high 5.1
|
||||
:current 1.1}
|
||||
:max-gas-amount {:low 30000
|
||||
:current 31000}
|
||||
:nonce {:last-transaction 21
|
||||
:current 22}}))}))
|
||||
{:db (assoc-in db
|
||||
[:wallet :ui :send :tx-settings]
|
||||
{:max-base-fee {:low 5
|
||||
:current 8.2
|
||||
:high 9}
|
||||
:priority-fee {:low 0.6
|
||||
:high 5.1
|
||||
:current 1.1}
|
||||
:max-gas-amount {:low 30000
|
||||
:current 31000}
|
||||
:nonce {:last-transaction 21
|
||||
:current 22}})}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/set-max-base-fee
|
||||
(fn [{db :db} [value]]
|
||||
{:db (assoc-in db [:wallet :ui :send :custom-tx-settings :max-base-fee :current] value)}))
|
||||
{:db (assoc-in db [:wallet :ui :send :tx-settings :max-base-fee :current] value)}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/set-priority-fee
|
||||
(fn [{db :db} [value]]
|
||||
{:db (assoc-in db [:wallet :ui :send :custom-tx-settings :priority-fee :current] value)}))
|
||||
{:db (assoc-in db [:wallet :ui :send :tx-settings :priority-fee :current] value)}))
|
||||
(rf/reg-event-fx
|
||||
|
||||
:wallet/set-max-gas-amount
|
||||
(fn [{db :db} [value]]
|
||||
{:db (assoc-in db [:wallet :ui :send :custom-tx-settings :max-gas-amount :current] value)}))
|
||||
{:db (assoc-in db [:wallet :ui :send :tx-settings :max-gas-amount :current] value)}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/set-nonce
|
||||
(fn [{db :db} [value]]
|
||||
{:db (assoc-in db [:wallet :ui :send :tx-settings :nonce :current] value)}))
|
||||
|
||||
(rf/reg-event-fx :wallet/quick-fee-mode-confirmed
|
||||
(fn [{db :db} [fee-mode]]
|
||||
(let [gas-rate (transaction-settings/tx-fee-mode->gas-rate fee-mode)
|
||||
route (first (get-in db [:wallet :ui :send :route]))
|
||||
path-tx-identity (send-utils/path-identity route)
|
||||
params [path-tx-identity gas-rate]]
|
||||
{:db (assoc-in db [:wallet :ui :send :custom-tx-settings :tx-fee-mode] fee-mode)
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "wallet_setFeeMode"
|
||||
:params params
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to set quick transaction settings"
|
||||
{:event :wallet/quick-fee-mode-confirmed
|
||||
:error (:message error)
|
||||
:params params}))}]]
|
||||
[:dispatch [:wallet/mark-user-tx-settings-for-deletion]]]})))
|
||||
|
||||
|
||||
;; There is a delay between the moment when user selected
|
||||
;; custom settings and the moment when new route arrived
|
||||
;; with those settings applied. During this delay
|
||||
;; we should keep user settings for ui. After new route
|
||||
;; arrived we should clean the settings.
|
||||
(rf/reg-event-fx :wallet/mark-user-tx-settings-for-deletion
|
||||
(fn [{db :db}]
|
||||
{:db (assoc-in db [:wallet :ui :send :custom-tx-settings :delete-on-routes-update?] true)}))
|
||||
|
||||
|
||||
(rf/reg-event-fx :wallet.send/set-sign-transactions-callback-fx
|
||||
(fn [{:keys [db]} [callback-fx]]
|
||||
{:db (assoc-in db
|
||||
[:wallet :ui :send :sign-transactions-callback-fx]
|
||||
callback-fx)}))
|
||||
|
||||
@@ -72,6 +72,11 @@
|
||||
|
||||
:else (rf/dispatch [:wallet/stop-and-clean-suggested-routes])))
|
||||
|
||||
(defn- get-fee-formatted
|
||||
[route]
|
||||
(when-let [native-currency-symbol (-> route first :from :native-currency-symbol)]
|
||||
(rf/sub [:wallet/wallet-send-fee-fiat-formatted native-currency-symbol])))
|
||||
|
||||
(defn- insufficient-asset-amount?
|
||||
[{:keys [token-symbol owned-eth-token input-state limit-exceeded? enough-assets?]}]
|
||||
(let [eth-selected? (= token-symbol (string/upper-case constants/mainnet-short-name))
|
||||
@@ -167,7 +172,7 @@
|
||||
(empty? route)
|
||||
(not valid-input?))
|
||||
fee-formatted (when (or (not confirm-disabled?) not-enough-asset?)
|
||||
(rf/sub [:wallet/wallet-send-fee-fiat-formatted]))
|
||||
(get-fee-formatted route))
|
||||
handle-on-confirm (fn [amount]
|
||||
(rf/dispatch [:wallet/set-token-amount-to-send
|
||||
{:amount amount
|
||||
|
||||
@@ -5,10 +5,9 @@
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.biometric.utils :as biometric]
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.common.standard-authentication.core :as standard-auth]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.send.transaction-confirmation.style :as style]
|
||||
[status-im.contexts.wallet.send.transaction-settings.view :as transaction-settings]
|
||||
@@ -169,9 +168,10 @@
|
||||
:subtitle subtitle}])
|
||||
|
||||
(defn- transaction-details
|
||||
[{:keys [estimated-time-min max-fees to-network
|
||||
transaction-type route-loaded?]}]
|
||||
(let [loading-suggested-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
|
||||
[{:keys [estimated-time-min max-fees to-network route
|
||||
transaction-type]}]
|
||||
(let [route-loaded? (and route (seq route))
|
||||
loading-suggested-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
|
||||
amount (rf/sub [:wallet/send-total-amount-formatted])]
|
||||
[rn/view
|
||||
{:style (style/details-container
|
||||
@@ -182,17 +182,18 @@
|
||||
[rn/activity-indicator {:style {:flex 1}}]
|
||||
route-loaded?
|
||||
[:<>
|
||||
[quo/button
|
||||
{:icon-only? true
|
||||
:type :outline
|
||||
:size 32
|
||||
:inner-style {:opacity 1}
|
||||
:accessibility-label :advanced-button
|
||||
:container-style {:margin-right 8}
|
||||
:on-press #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content transaction-settings/settings-sheet}])}
|
||||
:i/advanced]
|
||||
(when (ff/enabled? ::ff/wallet.transaction-params)
|
||||
[quo/button
|
||||
{:icon-only? true
|
||||
:type :outline
|
||||
:size 32
|
||||
:inner-style {:opacity 1}
|
||||
:accessibility-label :advanced-button
|
||||
:container-style {:margin-right 8}
|
||||
:on-press #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content transaction-settings/settings-sheet}])}
|
||||
:i/advanced])
|
||||
[data-item
|
||||
{:title (i18n/label :t/est-time)
|
||||
:subtitle (i18n/label :t/time-in-mins {:minutes (str estimated-time-min)})}]
|
||||
@@ -224,7 +225,11 @@
|
||||
estimated-time-min (reduce + (map :estimated-time route))
|
||||
token-symbol (or token-display-name
|
||||
(-> send-transaction-data :token :symbol))
|
||||
fee-formatted (rf/sub [:wallet/wallet-send-fee-fiat-formatted])
|
||||
first-route (first route)
|
||||
native-currency-symbol (get-in first-route
|
||||
[:from :native-currency-symbol])
|
||||
fee-formatted (rf/sub [:wallet/wallet-send-fee-fiat-formatted
|
||||
native-currency-symbol])
|
||||
account (rf/sub [:wallet/current-viewing-account])
|
||||
account-color (:color account)
|
||||
bridge-to-network (when bridge-to-chain-id
|
||||
@@ -232,6 +237,7 @@
|
||||
bridge-to-chain-id]))
|
||||
loading-suggested-routes? (rf/sub
|
||||
[:wallet/wallet-send-loading-suggested-routes?])
|
||||
transaction-for-signing (rf/sub [:wallet/wallet-send-transaction-for-signing])
|
||||
from-account-props {:customization-color account-color
|
||||
:size 32
|
||||
:emoji (:emoji account)
|
||||
@@ -243,9 +249,20 @@
|
||||
user-props {:full-name to-address
|
||||
:address (utils/get-shortened-address
|
||||
to-address)}
|
||||
biometric-auth? (= (rf/sub [:auth-method]) constants/auth-method-biometric)
|
||||
biometric-type (rf/sub [:biometrics/supported-type])]
|
||||
sign-on-keycard? (get-in transaction-for-signing
|
||||
[:signingDetails :signOnKeycard])]
|
||||
(hot-reload/use-safe-unmount #(rf/dispatch [:wallet/clean-route-data-for-collectible-tx]))
|
||||
;; In token send flow we already have transaction built when
|
||||
;; we reach confirmation screen. But in send collectible flow
|
||||
;; routes request happens at the same time with navigation to
|
||||
;; confirmation screen. So we need to build the transaction as soon
|
||||
;; as route is available.
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(when (and (send-utils/tx-type-collectible? transaction-type)
|
||||
first-route)
|
||||
(rf/dispatch [:wallet/build-transaction-for-collectible-route])))
|
||||
[first-route])
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
(when (ff/enabled? ::ff/wallet.transaction-params)
|
||||
@@ -266,21 +283,27 @@
|
||||
:to-network bridge-to-network
|
||||
:theme theme
|
||||
:route route
|
||||
:transaction-type transaction-type
|
||||
:route-loaded? (and route (seq route))}]
|
||||
:transaction-type transaction-type}]
|
||||
(when (and (not loading-suggested-routes?) route (seq route))
|
||||
[quo/slide-button
|
||||
{:size :size-48
|
||||
:track-text (if (= transaction-type :tx/bridge)
|
||||
(i18n/label :t/slide-to-bridge)
|
||||
(i18n/label :t/slide-to-send))
|
||||
:container-style {:z-index 2}
|
||||
[standard-auth/slide-button
|
||||
{:size :size-48
|
||||
:track-text (if (= transaction-type :tx/bridge)
|
||||
(i18n/label :t/slide-to-bridge)
|
||||
(i18n/label :t/slide-to-send))
|
||||
:container-style {:z-index 2}
|
||||
:disabled? (not transaction-for-signing)
|
||||
:customization-color account-color
|
||||
:track-icon (if biometric-auth?
|
||||
(biometric/get-icon-by-type biometric-type)
|
||||
:password)
|
||||
:on-complete #(rf/dispatch
|
||||
[:wallet.send/auth-slider-completed])}])]
|
||||
:auth-button-label (i18n/label :t/confirm)
|
||||
:on-complete (when sign-on-keycard?
|
||||
#(rf/dispatch
|
||||
[:wallet/prepare-signatures-for-transactions
|
||||
:send
|
||||
""]))
|
||||
:on-auth-success
|
||||
(fn [psw]
|
||||
(rf/dispatch
|
||||
[:wallet/prepare-signatures-for-transactions :send
|
||||
psw]))}])]
|
||||
:gradient-cover? true
|
||||
:customization-color (:color account)}
|
||||
[rn/view
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
(fn []
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(rf/dispatch [:wallet/get-saved-addresses])))
|
||||
(rf/dispatch [:infra/get-saved-addresses])))
|
||||
(let [transaction-details (rf/sub [:wallet/send-transaction-progress])]
|
||||
[floating-button-page/view
|
||||
{:footer-container-padding 0
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
(ns status-im.contexts.wallet.send.transaction-settings.core
|
||||
(:require
|
||||
[status-im.constants :as constants]))
|
||||
|
||||
(def default-transaction-setting :tx-fee-mode/fast)
|
||||
|
||||
(defn tx-fee-mode->gas-rate
|
||||
[tx-fee-mode]
|
||||
(case tx-fee-mode
|
||||
:tx-fee-mode/normal constants/gas-rate-low
|
||||
:tx-fee-mode/fast constants/gas-rate-medium
|
||||
:tx-fee-mode/urgent constants/gas-rate-high
|
||||
:tx-fee-mode/custom constants/gas-rate-custom
|
||||
constants/gas-rate-medium))
|
||||
|
||||
(defn gas-rate->tx-fee-mode
|
||||
[gas-rate]
|
||||
(condp = gas-rate
|
||||
constants/gas-rate-low :tx-fee-mode/normal
|
||||
constants/gas-rate-medium :tx-fee-mode/fast
|
||||
constants/gas-rate-high :tx-fee-mode/urgent
|
||||
constants/gas-rate-custom :tx-fee-mode/custom
|
||||
:tx-fee-mode/fast))
|
||||
@@ -5,7 +5,6 @@
|
||||
[react-native.platform :as platform]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.controlled-input.utils :as controlled-input]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -15,8 +14,7 @@
|
||||
(let [max-base-fee (:current (rf/sub [:wallet/tx-settings-max-base-fee]))
|
||||
priority-fee (:current (rf/sub [:wallet/tx-settings-priority-fee]))
|
||||
max-gas-amount (:current (rf/sub [:wallet/tx-settings-max-gas-amount]))
|
||||
nonce (:current (rf/sub [:wallet/tx-settings-nonce]))
|
||||
account-color (rf/sub [:wallet/current-viewing-account-color])]
|
||||
nonce (:current (rf/sub [:wallet/tx-settings-nonce]))]
|
||||
[rn/view
|
||||
[quo/drawer-top
|
||||
{:title (i18n/label :t/custom)}]
|
||||
@@ -64,90 +62,64 @@
|
||||
:preview-size :size-32}]}]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-props {:on-press #(rf/dispatch [:hide-bottom-sheet])
|
||||
:customization-color account-color}
|
||||
:button-one-props {:on-press #(rf/dispatch [:hide-bottom-sheet])}
|
||||
:button-one-label (i18n/label :t/confirm)}]]))
|
||||
|
||||
(defn settings-sheet
|
||||
[]
|
||||
(let [current-transaction-setting (rf/sub [:wallet/tx-fee-mode])
|
||||
account-color (rf/sub [:wallet/current-viewing-account-color])
|
||||
[transaction-setting set-transaction-setting] (rn/use-state current-transaction-setting)
|
||||
set-normal #(set-transaction-setting :tx-fee-mode/normal)
|
||||
set-fast #(set-transaction-setting :tx-fee-mode/fast)
|
||||
set-urgent #(set-transaction-setting :tx-fee-mode/urgent)]
|
||||
[_]
|
||||
(let [[selected-id set-selected-id] (rn/use-state :normal)]
|
||||
[rn/view
|
||||
[quo/drawer-top
|
||||
{:title (i18n/label :t/transaction-settings)}]
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:data [{:title (str (i18n/label :t/normal) "~60s")
|
||||
:image-props "🍿"
|
||||
:description-props {:text (rf/sub [:wallet/wallet-send-transaction-setting-fiat-formatted
|
||||
:tx-fee-mode/normal])}
|
||||
:image :emoji
|
||||
:description :text
|
||||
:action :selector
|
||||
:action-props {:type :radio
|
||||
:checked? (= :tx-fee-mode/normal transaction-setting)
|
||||
:customization-color account-color
|
||||
;; there is an UI isssue in quo/category, it has :on-press event
|
||||
;; and child radio button has own :on-change. If they are not set
|
||||
;; to the same action then we are getting inconsistent behaviour
|
||||
;; when user can click on settings item but cant on radio itself.
|
||||
;; So duplication is to prevent that until general fix is applied
|
||||
;; to quo/category
|
||||
:on-change set-normal}
|
||||
:on-press set-normal
|
||||
:label :text
|
||||
:preview-size :size-32}
|
||||
{:title (str (i18n/label :t/fast) "~40s")
|
||||
:image-props "🚗"
|
||||
:description-props {:text (rf/sub [:wallet/wallet-send-transaction-setting-fiat-formatted
|
||||
:tx-fee-mode/fast])}
|
||||
:image :emoji
|
||||
:description :text
|
||||
:action :selector
|
||||
:action-props {:type :radio
|
||||
:checked? (= :tx-fee-mode/fast transaction-setting)
|
||||
:on-change set-fast
|
||||
:customization-color account-color}
|
||||
:on-press set-fast
|
||||
:label :text
|
||||
:preview-size :size-32}
|
||||
{:title (str (i18n/label :t/urgent) "~15s")
|
||||
:image-props "🚀"
|
||||
:description-props {:text (rf/sub [:wallet/wallet-send-transaction-setting-fiat-formatted
|
||||
:tx-fee-mode/urgent])}
|
||||
:image :emoji
|
||||
:description :text
|
||||
:action :selector
|
||||
:action-props {:type :radio
|
||||
:checked? (= :tx-fee-mode/urgent transaction-setting)
|
||||
:customization-color account-color
|
||||
:on-change set-urgent}
|
||||
:on-press set-urgent
|
||||
:label :text
|
||||
:preview-size :size-32}
|
||||
(when (ff/enabled? ::ff/wallet.transaction-params)
|
||||
{:title (i18n/label :t/custom)
|
||||
:image-props :i/edit
|
||||
:description-props {:text "Set your own fees and nonce"}
|
||||
:image :icon
|
||||
:description :text
|
||||
:action :arrow
|
||||
:on-press #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content custom-settings-sheet}])
|
||||
:label :text
|
||||
:preview-size :size-32})]}]
|
||||
:data [{:title (str (i18n/label :t/normal) "~60s")
|
||||
:image-props "🍿"
|
||||
:description-props {:text "€1.45"}
|
||||
:image :emoji
|
||||
:description :text
|
||||
:action :selector
|
||||
:action-props {:type :radio
|
||||
:checked? (= :normal selected-id)}
|
||||
:on-press #(set-selected-id :normal)
|
||||
:label :text
|
||||
:preview-size :size-32}
|
||||
{:title (str (i18n/label :t/fast) "~40s")
|
||||
:image-props "🚗"
|
||||
:description-props {:text "€1.65"}
|
||||
:image :emoji
|
||||
:description :text
|
||||
:action :selector
|
||||
:action-props {:type :radio
|
||||
:checked? (= :fast selected-id)}
|
||||
:on-press #(set-selected-id :fast)
|
||||
:label :text
|
||||
:preview-size :size-32}
|
||||
{:title (str (i18n/label :t/urgent) "~15s")
|
||||
:image-props "🚀"
|
||||
:description-props {:text "€1.85"}
|
||||
:image :emoji
|
||||
:description :text
|
||||
:action :selector
|
||||
:action-props {:type :radio
|
||||
:checked? (= :urgent selected-id)}
|
||||
:on-press #(set-selected-id :urgent)
|
||||
:label :text
|
||||
:preview-size :size-32}
|
||||
{:title (i18n/label :t/custom)
|
||||
:image-props :i/edit
|
||||
:description-props {:text "Set your own fees and nonce"}
|
||||
:image :icon
|
||||
:description :text
|
||||
:action :arrow
|
||||
:on-press #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content custom-settings-sheet}])
|
||||
:label :text
|
||||
:preview-size :size-32}]}]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-props {:on-press (fn []
|
||||
(rf/dispatch [:wallet/quick-fee-mode-confirmed
|
||||
transaction-setting])
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
:customization-color account-color}
|
||||
:button-one-props {:on-press #(rf/dispatch [:hide-bottom-sheet])}
|
||||
:button-one-label (i18n/label :t/confirm)}]]))
|
||||
|
||||
(defn- hint
|
||||
|
||||
@@ -25,42 +25,21 @@
|
||||
transaction-hashes))
|
||||
|
||||
(defn calculate-gas-fee
|
||||
[{:keys [gas-amount gas-price l1-gas-fee]}]
|
||||
(let [total-gas-fee-wei (money/mul (money/->wei :gwei gas-price) gas-amount)
|
||||
l1-fee-wei (money/->wei :gwei l1-gas-fee)]
|
||||
[data]
|
||||
(let [gas-amount (money/bignumber (get data :gas-amount))
|
||||
gas-fees (get data :gas-fees)
|
||||
eip1559-enabled? (get gas-fees :eip-1559-enabled)
|
||||
optimal-price-gwei (money/bignumber (if eip1559-enabled?
|
||||
(get gas-fees :max-fee-per-gas-medium)
|
||||
(get gas-fees :gas-price)))
|
||||
total-gas-fee-wei (money/mul (money/->wei :gwei optimal-price-gwei) gas-amount)
|
||||
l1-fee-wei (money/->wei :gwei (get gas-fees :l-1-gas-fee))]
|
||||
(money/add total-gas-fee-wei l1-fee-wei)))
|
||||
|
||||
(defn path-gas-fee
|
||||
[path]
|
||||
(let [gas-amount (money/bignumber (get path :gas-amount))
|
||||
gas-fees (get path :gas-fees)
|
||||
eip1559-enabled? (get gas-fees :eip-1559-enabled)
|
||||
gas-price (money/bignumber (if eip1559-enabled?
|
||||
(get gas-fees :tx-max-fees-per-gas)
|
||||
(get gas-fees :gas-price)))
|
||||
l1-gas-fee (get gas-fees :l-1-gas-fee)]
|
||||
(calculate-gas-fee {:gas-amount gas-amount
|
||||
:gas-price gas-price
|
||||
:l1-gas-fee l1-gas-fee})))
|
||||
|
||||
(defn path-gas-fee-for-custom-gas-price
|
||||
[route gas-price]
|
||||
(let [gas-amount (money/bignumber (get route :gas-amount))
|
||||
gas-fees (get route :gas-fees)
|
||||
l1-gas-fee (get gas-fees :l-1-gas-fee)]
|
||||
(calculate-gas-fee {:gas-amount gas-amount
|
||||
:gas-price (money/bignumber gas-price)
|
||||
:l1-gas-fee l1-gas-fee})))
|
||||
|
||||
(defn full-route-gas-fee
|
||||
(defn calculate-full-route-gas-fee
|
||||
"Sums all the routes fees in wei and then convert the total value to ether"
|
||||
[route]
|
||||
(money/wei->ether (reduce money/add (map path-gas-fee route))))
|
||||
|
||||
(defn full-route-gas-fee-for-custom-gas-price
|
||||
"Sums all the routes fees in wei and then convert the total value to ether"
|
||||
[route gas-price]
|
||||
(money/wei->ether (reduce money/add (map #(path-gas-fee-for-custom-gas-price % gas-price) route))))
|
||||
(money/wei->ether (reduce money/add (map calculate-gas-fee route))))
|
||||
|
||||
(defn- path-amount-in
|
||||
[path]
|
||||
@@ -245,11 +224,3 @@
|
||||
{:r (subs signature 0 64)
|
||||
:s (subs signature 64 128)
|
||||
:v (subs signature 128 130)})
|
||||
|
||||
(defn path-identity
|
||||
[path]
|
||||
{:routerInputParamsUuid (:router-input-params-uuid path)
|
||||
:pathName (:bridge-name path)
|
||||
:chainID (get-in path [:from :chain-id])
|
||||
:isApprovalTx (:approval-required path)
|
||||
:communityID nil})
|
||||
|
||||
@@ -178,21 +178,21 @@
|
||||
(deftest calculate-gas-fee-test
|
||||
(testing "EIP-1559 transaction without L1 fee"
|
||||
(let [data {:gas-amount "23487"
|
||||
:gas-fees {:tx-max-fees-per-gas "2.259274911"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "0"}}
|
||||
:gas-fees {:max-fee-per-gas-medium "2.259274911"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "0"}}
|
||||
expected-result (money/bignumber "53063589834657")] ; This is in Wei
|
||||
(is (money/equal-to (utils/path-gas-fee data)
|
||||
(is (money/equal-to (utils/calculate-gas-fee data)
|
||||
expected-result))))
|
||||
|
||||
(testing "EIP-1559 transaction with L1 fee of 60,000 Gwei"
|
||||
(let [data {:gas-amount "23487"
|
||||
:gas-fees {:tx-max-fees-per-gas "2.259274911"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "60000"}}
|
||||
:gas-fees {:max-fee-per-gas-medium "2.259274911"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "60000"}}
|
||||
expected-result (money/bignumber "113063589834657")] ; Added 60,000 Gwei in Wei to the
|
||||
; previous result
|
||||
(is (money/equal-to (utils/path-gas-fee data)
|
||||
(is (money/equal-to (utils/calculate-gas-fee data)
|
||||
expected-result))))
|
||||
|
||||
(testing "Non-EIP-1559 transaction with specified gas price"
|
||||
@@ -202,48 +202,48 @@
|
||||
:l-1-gas-fee "0"}}
|
||||
expected-result (money/bignumber "67471600217343")] ; This is in Wei, for the specified
|
||||
; gas amount and price
|
||||
(is (money/equal-to (utils/path-gas-fee data)
|
||||
(is (money/equal-to (utils/calculate-gas-fee data)
|
||||
expected-result)))))
|
||||
|
||||
(deftest calculate-full-route-gas-fee-test
|
||||
(testing "Route with a single EIP-1559 transaction, no L1 fees"
|
||||
(let [route [{:gas-amount "23487"
|
||||
:gas-fees {:tx-max-fees-per-gas "2.259274911"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "0"}}]
|
||||
:gas-fees {:max-fee-per-gas-medium "2.259274911"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "0"}}]
|
||||
expected-result (money/bignumber "0.000053063589834657")] ; The Wei amount for the
|
||||
; transaction, converted to
|
||||
; Ether
|
||||
(is (money/equal-to (utils/full-route-gas-fee route)
|
||||
(is (money/equal-to (utils/calculate-full-route-gas-fee route)
|
||||
expected-result))))
|
||||
|
||||
(testing "Route with two EIP-1559 transactions, no L1 fees"
|
||||
(let [route [{:gas-amount "23487"
|
||||
:gas-fees {:tx-max-fees-per-gas "2.259274911"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "0"}}
|
||||
:gas-fees {:max-fee-per-gas-medium "2.259274911"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "0"}}
|
||||
{:gas-amount "23487"
|
||||
:gas-fees {:tx-max-fees-per-gas "2.259274911"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "0"}}]
|
||||
:gas-fees {:max-fee-per-gas-medium "2.259274911"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "0"}}]
|
||||
expected-result (money/bignumber "0.000106127179669314")] ; Sum of both transactions' Wei
|
||||
; amounts, converted to Ether
|
||||
(is (money/equal-to (utils/full-route-gas-fee route)
|
||||
(is (money/equal-to (utils/calculate-full-route-gas-fee route)
|
||||
expected-result))))
|
||||
|
||||
(testing "Route with two EIP-1559 transactions, one with L1 fee of 60,000 Gwei"
|
||||
(let [route [{:gas-amount "23487"
|
||||
:gas-fees {:tx-max-fees-per-gas "2.259274911"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "0"}}
|
||||
:gas-fees {:max-fee-per-gas-medium "2.259274911"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "0"}}
|
||||
{:gas-amount "23487"
|
||||
:gas-fees {:tx-max-fees-per-gas "2.259274911"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "60000"}}]
|
||||
:gas-fees {:max-fee-per-gas-medium "2.259274911"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "60000"}}]
|
||||
expected-result (money/bignumber "0.000166127179669314")] ; Added 60,000 Gwei in Wei to
|
||||
; the previous total and
|
||||
; converted to Ether
|
||||
(is (money/equal-to (utils/full-route-gas-fee route)
|
||||
(is (money/equal-to (utils/calculate-full-route-gas-fee route)
|
||||
expected-result)))))
|
||||
|
||||
(deftest token-available-networks-for-suggested-routes-test
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
[quo.foundations.resources :as resources]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.biometric.utils :as biometric]
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.common.standard-authentication.core :as standard-auth]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.external-links :as external-links]
|
||||
[status-im.contexts.wallet.swap.set-spending-cap.style :as style]
|
||||
@@ -217,21 +216,25 @@
|
||||
|
||||
(defn- slide-button
|
||||
[]
|
||||
(let [loading-swap-proposal? (rf/sub [:wallet/swap-loading-swap-proposal?])
|
||||
swap-proposal (rf/sub [:wallet/swap-proposal-without-fees])
|
||||
account (rf/sub [:wallet/current-viewing-account])
|
||||
biometric-auth? (= (rf/sub [:auth-method]) constants/auth-method-biometric)
|
||||
biometric-type (rf/sub [:biometrics/supported-type])]
|
||||
[quo/slide-button
|
||||
(let [loading-swap-proposal? (rf/sub [:wallet/swap-loading-swap-proposal?])
|
||||
swap-proposal (rf/sub [:wallet/swap-proposal-without-fees])
|
||||
account (rf/sub [:wallet/current-viewing-account])
|
||||
transaction-for-signing (rf/sub [:wallet/swap-transaction-for-signing])
|
||||
sign-on-keycard? (get-in transaction-for-signing
|
||||
[:signingDetails :signOnKeycard])
|
||||
on-auth-success (rn/use-callback
|
||||
#(rf/dispatch [:wallet/prepare-signatures-for-transactions :swap %]))
|
||||
on-complete (rn/use-callback
|
||||
#(rf/dispatch [:wallet/prepare-signatures-for-transactions :swap ""]))]
|
||||
[standard-auth/slide-button
|
||||
{:size :size-48
|
||||
:track-text (i18n/label :t/slide-to-sign)
|
||||
:container-style {:z-index 2}
|
||||
:customization-color (:color account)
|
||||
:track-icon (if biometric-auth?
|
||||
(biometric/get-icon-by-type biometric-type)
|
||||
:password)
|
||||
:disabled? (or loading-swap-proposal? (not swap-proposal))
|
||||
:on-complete #(rf/dispatch [:wallet/prepare-signatures-for-transactions :swap])}]))
|
||||
:on-complete (when sign-on-keycard? on-complete)
|
||||
:on-auth-success on-auth-success
|
||||
:auth-button-label (i18n/label :t/confirm)}]))
|
||||
|
||||
(defn- footer
|
||||
[]
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.biometric.utils :as biometric]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.common.standard-authentication.core :as standard-auth]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||
@@ -167,21 +167,26 @@
|
||||
transaction-for-signing (rf/sub [:wallet/swap-transaction-for-signing])
|
||||
swap-proposal (rf/sub [:wallet/swap-proposal-without-fees])
|
||||
account (rf/sub [:wallet/current-viewing-account])
|
||||
biometric-auth? (= (rf/sub [:auth-method]) constants/auth-method-biometric)
|
||||
biometric-type (rf/sub [:biometrics/supported-type])
|
||||
account-color (:color account)]
|
||||
[quo/slide-button
|
||||
account-color (:color account)
|
||||
sign-on-keycard? (get-in transaction-for-signing
|
||||
[:signingDetails :signOnKeycard])]
|
||||
[standard-auth/slide-button
|
||||
{:size :size-48
|
||||
:track-text (i18n/label :t/slide-to-swap)
|
||||
:container-style {:z-index 2}
|
||||
:customization-color account-color
|
||||
:track-icon (if biometric-auth?
|
||||
(biometric/get-icon-by-type biometric-type)
|
||||
:password)
|
||||
:disabled? (or loading-swap-proposal?
|
||||
(not swap-proposal)
|
||||
(not transaction-for-signing))
|
||||
:on-complete #(rf/dispatch [:wallet/prepare-signatures-for-transactions :swap])}]))
|
||||
:auth-button-label (i18n/label :t/confirm)
|
||||
:on-complete (when sign-on-keycard?
|
||||
#(rf/dispatch
|
||||
[:wallet/prepare-signatures-for-transactions
|
||||
:swap
|
||||
""]))
|
||||
:on-auth-success (fn [data]
|
||||
(rf/dispatch [:wallet/stop-get-swap-proposal])
|
||||
(rf/dispatch [:wallet/prepare-signatures-for-transactions :swap data]))}]))
|
||||
|
||||
(defn footer
|
||||
[]
|
||||
|
||||
@@ -41,4 +41,6 @@
|
||||
:stickers/packs-pending #{}
|
||||
:settings/change-password {}
|
||||
:keycard {}
|
||||
:theme :dark})
|
||||
:theme :dark
|
||||
:app {:use-cases-stack '()
|
||||
:last-user-notification {}}})
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
(ns status-im.domain.events
|
||||
(:require
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- update-saved-addresses
|
||||
[saved-addresses-db new-saved-addresses]
|
||||
(reduce
|
||||
(fn [acc {:keys [address removed? test?] :as saved-address}]
|
||||
(let [db-key (if test? :test :prod)]
|
||||
(if removed?
|
||||
(update acc db-key dissoc address)
|
||||
(assoc-in acc [db-key address] saved-address))))
|
||||
(or saved-addresses-db
|
||||
{:test {}
|
||||
:prod {}})
|
||||
new-saved-addresses))
|
||||
|
||||
(rf/reg-event-fx :domain/reconcile-saved-addresses
|
||||
(fn [{:keys [db]} [saved-addresses]]
|
||||
{:db (update-in db [:wallet :saved-addresses] update-saved-addresses saved-addresses)}))
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns status-im.events
|
||||
(:require
|
||||
status-im.app.events
|
||||
status-im.common.alert-banner.events
|
||||
status-im.common.alert.effects
|
||||
status-im.common.async-storage.effects
|
||||
@@ -55,6 +56,8 @@
|
||||
status-im.contexts.wallet.swap.events
|
||||
status-im.contexts.wallet.wallet-connect.events.core
|
||||
[status-im.db :as db]
|
||||
status-im.domain.events
|
||||
status-im.infra.events
|
||||
status-im.navigation.effects
|
||||
status-im.navigation.events
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
(ns status-im.infra.events
|
||||
(:require
|
||||
[status-im.infra.transform :as transform]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/reg-event-fx :infra/convert-saved-addresses
|
||||
(fn [_ [raw-saved-addresses]]
|
||||
(let [saved-addresses (transform/rpc->saved-addresses raw-saved-addresses)]
|
||||
{:fx [[:dispatch [:domain/reconcile-saved-addresses saved-addresses]]]})))
|
||||
|
||||
|
||||
(rf/reg-event-fx :infra/get-saved-addresses
|
||||
(fn [_]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_getSavedAddresses"
|
||||
:on-success [:infra/convert-saved-addresses]
|
||||
:on-error [:infra/saved-addresses-rpc-error :get-saved-addresses]}]]]}))
|
||||
|
||||
(rf/reg-event-fx :infra/saved-addresses-rpc-error
|
||||
(fn [_ [action error]]
|
||||
(log/warn (str "[wallet] [saved-addresses] Failed to " action)
|
||||
{:error error})))
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
(ns status-im.infra.transform
|
||||
(:require
|
||||
[camel-snake-kebab.extras :as cske]
|
||||
[clojure.set :as set]
|
||||
[clojure.string :as string]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.collectible.utils :as collectible-utils]
|
||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||
[utils.collection :as utils.collection]
|
||||
[utils.money :as money]
|
||||
[utils.number :as utils.number]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(defn- add-keys-to-saved-address
|
||||
[saved-address]
|
||||
(assoc saved-address :ens? (not (string/blank? (:ens saved-address)))))
|
||||
|
||||
(defn rpc->saved-address
|
||||
[saved-address]
|
||||
(-> saved-address
|
||||
(set/rename-keys {:chainShortNames :chain-short-names
|
||||
:isTest :test?
|
||||
:createdAt :created-at
|
||||
:colorId :customization-color
|
||||
:mixedcaseAddress :mixedcase-address
|
||||
:removed :removed?})
|
||||
(update :customization-color (comp keyword string/lower-case))
|
||||
add-keys-to-saved-address))
|
||||
|
||||
(defn rpc->saved-addresses
|
||||
[saved-addresses]
|
||||
(map rpc->saved-address saved-addresses))
|
||||
@@ -0,0 +1,26 @@
|
||||
(ns status-im.subs.app
|
||||
(:require
|
||||
[re-frame.core :as rf]))
|
||||
|
||||
(rf/reg-sub
|
||||
:app/last-user-notification
|
||||
:<- [:app]
|
||||
:-> :last-user-notification)
|
||||
|
||||
|
||||
(rf/reg-sub
|
||||
:app/use-cases
|
||||
:<- [:app]
|
||||
:-> :use-cases-stack)
|
||||
|
||||
(rf/reg-sub
|
||||
:app/current-use-case
|
||||
:<- [:app/use-cases]
|
||||
(fn [use-cases]
|
||||
(first use-cases)))
|
||||
|
||||
(rf/reg-sub
|
||||
:app/use-case-active?
|
||||
:<- [:app/use-cases]
|
||||
(fn [use-cases [_sub-name use-case]]
|
||||
(some #(= use-case %) use-cases)))
|
||||
@@ -3,6 +3,7 @@
|
||||
[re-frame.core :as re-frame]
|
||||
status-im.subs.activity-center
|
||||
status-im.subs.alert-banner
|
||||
status-im.subs.app
|
||||
status-im.subs.biometrics
|
||||
status-im.subs.bottom-sheet
|
||||
status-im.subs.chats
|
||||
@@ -191,3 +192,8 @@
|
||||
|
||||
;;keycard
|
||||
(reg-root-key-sub :keycard :keycard)
|
||||
|
||||
(reg-root-key-sub :ui :ui)
|
||||
(reg-root-key-sub :infra :infra)
|
||||
(reg-root-key-sub :app :app)
|
||||
(reg-root-key-sub :domain :domain)
|
||||
|
||||
@@ -205,40 +205,27 @@
|
||||
{:crypto (str crypto-formatted " " (:symbol token))
|
||||
:fiat fiat-formatted})))
|
||||
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/custom-tx-settings
|
||||
:wallet/tx-settings
|
||||
:<- [:wallet/wallet-send]
|
||||
:-> :custom-tx-settings)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/tx-settings-fee-mode-user
|
||||
:<- [:wallet/custom-tx-settings]
|
||||
:-> :tx-fee-mode)
|
||||
:-> :tx-settings)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/tx-settings-max-base-fee
|
||||
:<- [:wallet/custom-tx-settings]
|
||||
:<- [:wallet/tx-settings]
|
||||
:-> :max-base-fee)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/tx-settings-priority-fee
|
||||
:<- [:wallet/custom-tx-settings]
|
||||
:<- [:wallet/tx-settings]
|
||||
:-> :priority-fee)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/tx-settings-max-gas-amount
|
||||
:<- [:wallet/custom-tx-settings]
|
||||
:<- [:wallet/tx-settings]
|
||||
:-> :max-gas-amount)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/tx-settings-nonce
|
||||
:<- [:wallet/custom-tx-settings]
|
||||
:<- [:wallet/tx-settings]
|
||||
:-> :nonce)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/tx-fee-mode
|
||||
:<- [:wallet/send-route]
|
||||
:<- [:wallet/tx-settings-fee-mode-user]
|
||||
(fn [[route value-set-by-user]]
|
||||
(or value-set-by-user (:tx-fee-mode (first route)))))
|
||||
|
||||
@@ -260,7 +260,7 @@
|
||||
token-for-fees (first (filter #(= (string/lower-case (:symbol %))
|
||||
(string/lower-case token-symbol-for-fees))
|
||||
tokens))
|
||||
fee-in-native-token (send-utils/full-route-gas-fee [swap-proposal])
|
||||
fee-in-native-token (send-utils/calculate-full-route-gas-fee [swap-proposal])
|
||||
fee-in-fiat (utils/calculate-token-fiat-value
|
||||
{:currency currency
|
||||
:balance fee-in-native-token
|
||||
|
||||
@@ -120,9 +120,9 @@
|
||||
:approval-required true
|
||||
:approval-amount-required "0x10000"
|
||||
:gas-amount "25000"
|
||||
:gas-fees {:tx-max-fees-per-gas "4"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "0"}}
|
||||
:gas-fees {:max-fee-per-gas-medium "4"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "0"}}
|
||||
:error-response "Error"
|
||||
:loading-swap-proposal? false
|
||||
:max-slippage 0.5})
|
||||
|
||||
@@ -162,17 +162,6 @@
|
||||
:<- [:wallet/wallet-send]
|
||||
:-> :route)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/gas-fees
|
||||
:<- [:wallet/wallet-send-route]
|
||||
(fn [route]
|
||||
(:gas-fees (first route))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/suggested-gas-fees-for-setting
|
||||
:<- [:wallet/gas-fees]
|
||||
:-> :suggested-gas-fees-for-setting)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/wallet-send-enough-assets?
|
||||
:<- [:wallet/wallet-send]
|
||||
@@ -855,51 +844,22 @@
|
||||
:<- [:profile/currency]
|
||||
:<- [:profile/currency-symbol]
|
||||
:<- [:wallet/prices-per-token]
|
||||
(fn [[account route currency currency-symbol prices-per-token]]
|
||||
(let [token-symbol-for-fees (get-in (first route) [:from :native-currency-symbol])]
|
||||
(when token-symbol-for-fees
|
||||
(let [tokens (:tokens account)
|
||||
token-for-fees (first (filter #(= (string/lower-case (:symbol %))
|
||||
(string/lower-case token-symbol-for-fees))
|
||||
tokens))
|
||||
fee-in-native-token (send-utils/full-route-gas-fee route)
|
||||
fee-in-fiat (utils/calculate-token-fiat-value
|
||||
{:currency currency
|
||||
:balance fee-in-native-token
|
||||
:token token-for-fees
|
||||
:prices-per-token prices-per-token})
|
||||
fee-formatted (utils/fiat-formatted-for-ui
|
||||
currency-symbol
|
||||
fee-in-fiat)]
|
||||
fee-formatted)))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/wallet-send-transaction-setting-fiat-formatted
|
||||
:<- [:wallet/current-viewing-account]
|
||||
:<- [:wallet/wallet-send-route]
|
||||
:<- [:profile/currency]
|
||||
:<- [:profile/currency-symbol]
|
||||
:<- [:wallet/prices-per-token]
|
||||
:<- [:wallet/suggested-gas-fees-for-setting]
|
||||
(fn [[account route currency currency-symbol prices-per-token fees-for-settings]
|
||||
[_ transaction-setting]]
|
||||
(let [token-symbol-for-fees (get-in (first route) [:from :native-currency-symbol])]
|
||||
(when token-symbol-for-fees
|
||||
(let [tokens (:tokens account)
|
||||
token-for-fees (first (filter #(= (string/lower-case (:symbol %))
|
||||
(string/lower-case token-symbol-for-fees))
|
||||
tokens))
|
||||
gas-price (transaction-setting fees-for-settings)
|
||||
fee-in-native-token (send-utils/full-route-gas-fee-for-custom-gas-price route gas-price)
|
||||
fee-in-fiat (utils/calculate-token-fiat-value
|
||||
{:currency currency
|
||||
:balance fee-in-native-token
|
||||
:token token-for-fees
|
||||
:prices-per-token prices-per-token})
|
||||
fee-formatted (utils/fiat-formatted-for-ui
|
||||
currency-symbol
|
||||
fee-in-fiat)]
|
||||
fee-formatted)))))
|
||||
(fn [[account route currency currency-symbol prices-per-token] [_ token-symbol-for-fees]]
|
||||
(when token-symbol-for-fees
|
||||
(let [tokens (:tokens account)
|
||||
token-for-fees (first (filter #(= (string/lower-case (:symbol %))
|
||||
(string/lower-case token-symbol-for-fees))
|
||||
tokens))
|
||||
fee-in-native-token (send-utils/calculate-full-route-gas-fee route)
|
||||
fee-in-fiat (utils/calculate-token-fiat-value
|
||||
{:currency currency
|
||||
:balance fee-in-native-token
|
||||
:token token-for-fees
|
||||
:prices-per-token prices-per-token})
|
||||
fee-formatted (utils/fiat-formatted-for-ui
|
||||
currency-symbol
|
||||
fee-in-fiat)]
|
||||
fee-formatted))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/accounts-names
|
||||
|
||||
@@ -205,10 +205,9 @@
|
||||
|
||||
(def route-data
|
||||
[{:gas-amount "25000"
|
||||
:gas-fees {:tx-max-fees-per-gas "4"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "0"}
|
||||
:from {:native-currency-symbol "ETH"}}])
|
||||
:gas-fees {:max-fee-per-gas-medium "4"
|
||||
:eip-1559-enabled true
|
||||
:l-1-gas-fee "0"}}])
|
||||
|
||||
(h/deftest-sub :wallet/balances-in-selected-networks
|
||||
[sub-name]
|
||||
@@ -939,7 +938,9 @@
|
||||
(assoc-in [:profile/profile :currency] :usd)
|
||||
(assoc-in [:profile/profile :currency-symbol] "$")))
|
||||
|
||||
(is (match? (rf/sub [sub-name]) "$0.20"))))
|
||||
(let [token-symbol-for-fees "ETH"
|
||||
result (rf/sub [sub-name token-symbol-for-fees])]
|
||||
(is (match? result "$0.20")))))
|
||||
|
||||
(h/deftest-sub :wallet/zero-balance-in-all-non-watched-accounts?
|
||||
[sub-name]
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
(ns status-im.ui.core
|
||||
(:require [re-frame.db :as rf.db]
|
||||
[reagent.core :as reagent]
|
||||
#_[utils.re-frame :as rf]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "chore/bridge-estimated-gas-increase",
|
||||
"commit-sha1": "5e356ce505da6ca427366ff171733f0317ce3cfe",
|
||||
"src-sha256": "189k997g3n7kg3bxb2jbyk70wh3d1h01nlxhzq0k9c59b5bvlhab"
|
||||
"version": "v10.4.0",
|
||||
"commit-sha1": "1bfb0cef022afc1484a410cb3e0097e7523bb705",
|
||||
"src-sha256": "13cg07ld319g1fyaqpkjnpdw6iap389dwzwnh9g870ci8scpdy5m"
|
||||
}
|
||||
|
||||
+197
-3
@@ -1,15 +1,209 @@
|
||||
import datetime
|
||||
import re
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from _pytest.outcomes import Failed
|
||||
from selenium.common import NoSuchElementException, TimeoutException
|
||||
|
||||
from base_test_case import MultipleSharedDeviceTestCase, create_shared_drivers
|
||||
from tests import marks
|
||||
from support.api.network_api import NetworkApi
|
||||
from tests import marks, run_in_parallel
|
||||
from users import transaction_senders
|
||||
from views.sign_in_view import SignInView
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="new_four_2")
|
||||
@marks.nightly
|
||||
@marks.secured
|
||||
@marks.smoke
|
||||
class TestWalletMultipleDevice(MultipleSharedDeviceTestCase):
|
||||
|
||||
def prepare_devices(self):
|
||||
self.network_api = NetworkApi()
|
||||
self.drivers, self.loop = create_shared_drivers(2)
|
||||
self.sign_in_1, self.sign_in_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||
self.sender, self.receiver = transaction_senders['ETH_1'], transaction_senders['ETH_2']
|
||||
self.sender['wallet_address'] = '0x' + self.sender['address']
|
||||
self.receiver['wallet_address'] = '0x' + self.receiver['address']
|
||||
self.loop.run_until_complete(
|
||||
run_in_parallel(((self.sign_in_1.recover_access, {'passphrase': self.sender['passphrase']}),
|
||||
(self.sign_in_2.recover_access, {'passphrase': self.receiver['passphrase']}))))
|
||||
self.home_1, self.home_2 = self.sign_in_1.get_home_view(), self.sign_in_2.get_home_view()
|
||||
self.sender_username, self.receiver_username = self.home_1.get_username(), self.home_2.get_username()
|
||||
self.wallet_1, self.wallet_2 = self.sign_in_1.get_wallet_view(), self.sign_in_2.get_wallet_view()
|
||||
self.wallet_1.wallet_tab.click()
|
||||
self.wallet_2.wallet_tab.click()
|
||||
self.network = "Arbitrum"
|
||||
|
||||
def _get_balances_before_tx(self):
|
||||
# ToDo: Arbiscan API is down, looking for analogue
|
||||
# sender_balance = self.network_api.get_balance(self.sender['wallet_address'])
|
||||
# receiver_balance = self.network_api.get_balance(self.receiver['wallet_address'])
|
||||
self.wallet_1.just_fyi("Getting ETH amount in the wallet of the sender before transaction")
|
||||
self.wallet_1.get_account_element().click()
|
||||
eth_amount_sender = self.wallet_1.get_asset(asset_name='Ether').get_amount()
|
||||
self.wallet_2.just_fyi("Getting ETH amount in the wallet of the receiver before transaction")
|
||||
self.wallet_2.get_account_element().click()
|
||||
eth_amount_receiver = self.wallet_2.get_asset(asset_name='Ether').get_amount()
|
||||
# return sender_balance, receiver_balance, eth_amount_sender, eth_amount_receiver
|
||||
return eth_amount_sender, eth_amount_receiver
|
||||
|
||||
def _check_balances_after_tx(self, amount_to_send, sender_balance, receiver_balance, eth_amount_sender,
|
||||
eth_amount_receiver):
|
||||
# ToDo: Arbiscan API is down, looking for analogue
|
||||
# try:
|
||||
# self.network_api.wait_for_balance_to_be(address=self.sender['wallet_address'],
|
||||
# expected_balance=sender_balance - amount_to_send)
|
||||
# except TimeoutException as e:
|
||||
# self.errors.append("Sender " + e.msg)
|
||||
# try:
|
||||
# self.network_api.wait_for_balance_to_be(address=self.receiver['wallet_address'],
|
||||
# expected_balance=receiver_balance + amount_to_send)
|
||||
# except TimeoutException as e:
|
||||
# self.errors.append("Receiver " + e.msg)
|
||||
|
||||
def wait_for_wallet_balance_to_update(wallet_view, user_name, initial_eth_amount):
|
||||
wallet_view.just_fyi("Getting ETH amount in the wallet of the %s after transaction" % user_name)
|
||||
if user_name == self.sender_username:
|
||||
exp_amount = round(initial_eth_amount - amount_to_send, 4)
|
||||
else:
|
||||
exp_amount = round(initial_eth_amount + amount_to_send, 4)
|
||||
|
||||
# for _ in range(12): # ToDo: 120 sec wait time, enable when autoupdate feature is ready
|
||||
new_eth_amount = round(wallet_view.get_asset(asset_name='Ether').get_amount(), 4)
|
||||
if user_name == self.sender_username and new_eth_amount <= exp_amount:
|
||||
return
|
||||
if user_name == self.receiver_username and new_eth_amount >= exp_amount:
|
||||
return
|
||||
self.errors.append(wallet_view,
|
||||
"Eth amount in the %s's wallet is %s but should be %s" % (
|
||||
user_name, new_eth_amount, exp_amount))
|
||||
|
||||
# ToDo: disable relogin when autoupdate feature is ready
|
||||
self.home_1.just_fyi("Relogin for getting an updated balance")
|
||||
self.home_2.just_fyi("Relogin for getting an updated balance")
|
||||
for _ in range(6): # just waiting 1 minute here to be sure that balances are updated
|
||||
self.wallet_1.wallet_tab.is_element_displayed()
|
||||
self.wallet_2.wallet_tab.is_element_displayed()
|
||||
time.sleep(10)
|
||||
self.loop.run_until_complete(
|
||||
run_in_parallel(((self.home_1.reopen_app, {'user_name': self.sender_username}),
|
||||
(self.home_2.reopen_app, {'user_name': self.receiver_username}))))
|
||||
self.wallet_1.wallet_tab.wait_and_click()
|
||||
self.wallet_2.wallet_tab.wait_and_click()
|
||||
self.wallet_1.set_network_in_wallet(network_name=self.network)
|
||||
self.wallet_2.set_network_in_wallet(network_name=self.network)
|
||||
self.loop.run_until_complete(
|
||||
run_in_parallel(((wait_for_wallet_balance_to_update, {'wallet_view': self.wallet_1,
|
||||
'user_name': self.sender_username,
|
||||
'initial_eth_amount': eth_amount_sender}),
|
||||
(wait_for_wallet_balance_to_update, {'wallet_view': self.wallet_2,
|
||||
'user_name': self.receiver_username,
|
||||
'initial_eth_amount': eth_amount_receiver}))))
|
||||
|
||||
def _check_last_transaction_in_activity(self, wallet_view, device_time, amount_to_send, sender=True):
|
||||
wallet_view.get_account_element().click()
|
||||
wallet_view.activity_tab.click()
|
||||
wallet_view.just_fyi("Checking the transaction in the activity tab")
|
||||
current_time = datetime.datetime.strptime(device_time, "%Y-%m-%dT%H:%M:%S%z")
|
||||
expected_time = "Today %s" % current_time.strftime('%-I:%M %p')
|
||||
possible_times = [expected_time,
|
||||
"Today %s" % (current_time + datetime.timedelta(minutes=1)).strftime('%-I:%M %p')]
|
||||
sender_address_short = self.sender['wallet_address'].replace(self.sender['wallet_address'][5:-3], '...').lower()
|
||||
receiver_address_short = self.receiver['wallet_address'].replace(self.receiver['wallet_address'][5:-3],
|
||||
'...').lower()
|
||||
activity_element = wallet_view.get_activity_element()
|
||||
try:
|
||||
if not all((activity_element.header == 'Send' if sender else 'Receive',
|
||||
activity_element.timestamp in possible_times,
|
||||
activity_element.amount == '%s ETH' % amount_to_send,
|
||||
activity_element.from_text == sender_address_short,
|
||||
activity_element.to_text == receiver_address_short)):
|
||||
self.errors.append(
|
||||
wallet_view,
|
||||
"The last transaction is not listed in activity for the %s, expected timestamp is %s" %
|
||||
('sender' if sender else 'receiver', expected_time))
|
||||
except NoSuchElementException:
|
||||
self.errors.append(wallet_view,
|
||||
"Can't find the last transaction for the %s" % ('sender' if sender else 'receiver'))
|
||||
finally:
|
||||
wallet_view.close_account_button.click_until_presence_of_element(wallet_view.show_qr_code_button)
|
||||
|
||||
@marks.testrail_id(727229)
|
||||
def test_wallet_send_eth(self):
|
||||
self.wallet_1.set_network_in_wallet(network_name=self.network)
|
||||
self.wallet_2.set_network_in_wallet(network_name=self.network)
|
||||
# sender_balance, receiver_balance, eth_amount_sender, eth_amount_receiver = self._get_balances_before_tx()
|
||||
eth_amount_sender, eth_amount_receiver = self._get_balances_before_tx()
|
||||
|
||||
self.wallet_2.close_account_button.click()
|
||||
self.wallet_2.chats_tab.click()
|
||||
|
||||
self.wallet_1.just_fyi("Sending funds from wallet")
|
||||
amount_to_send = 0.0001
|
||||
device_time_before_sending = self.wallet_1.driver.device_time
|
||||
self.wallet_1.send_asset(address='arb1:' + self.receiver['wallet_address'],
|
||||
asset_name='Ether',
|
||||
amount=f"{amount_to_send:.4f}",
|
||||
network_name=self.network)
|
||||
# ToDo: Arbiscan API is down, looking for analogue
|
||||
# self.network_api.wait_for_confirmation_of_transaction(address=self.sender['wallet_address'],
|
||||
# tx_time=device_time_before_sending)
|
||||
|
||||
device_time_after_sending = self.wallet_1.driver.device_time
|
||||
|
||||
# self._check_balances_after_tx(amount_to_send, sender_balance, receiver_balance, eth_amount_sender,
|
||||
# eth_amount_receiver)
|
||||
self._check_balances_after_tx(amount_to_send, None, None, eth_amount_sender, eth_amount_receiver)
|
||||
|
||||
# ToDo: enable when issues 20807 and 20808 are fixed
|
||||
# self.loop.run_until_complete(
|
||||
# run_in_parallel(((self._check_last_transaction_in_activity, {'wallet_view': self.wallet_1,
|
||||
# 'device_time': device_time,
|
||||
# 'amount_to_send': amount_to_send}),
|
||||
# (self._check_last_transaction_in_activity, {'wallet_view': self.wallet_2,
|
||||
# 'device_time': device_time,
|
||||
# 'amount_to_send': amount_to_send,
|
||||
# 'sender': False}))))
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
@marks.testrail_id(727230)
|
||||
def test_wallet_send_asset_from_drawer(self):
|
||||
self.wallet_1.navigate_back_to_wallet_view()
|
||||
# sender_balance, receiver_balance, eth_amount_sender, eth_amount_receiver = self._get_balances_before_tx()
|
||||
eth_amount_sender, eth_amount_receiver = self._get_balances_before_tx()
|
||||
self.wallet_2.close_account_button.click_if_shown()
|
||||
self.wallet_2.chats_tab.click()
|
||||
|
||||
self.wallet_1.just_fyi("Sending asset from drawer")
|
||||
amount_to_send = 0.0001
|
||||
device_time_before_sending = self.wallet_1.driver.device_time
|
||||
self.wallet_1.send_asset_from_drawer(address='arb1:' + self.receiver['wallet_address'],
|
||||
asset_name='Ether',
|
||||
amount=f"{amount_to_send:.4f}",
|
||||
network_name=self.network)
|
||||
# ToDo: Arbiscan API is down, looking for analogue
|
||||
# self.network_api.wait_for_confirmation_of_transaction(address=self.sender['wallet_address'],
|
||||
# tx_time=device_time_before_sending)
|
||||
device_time_after_sending = self.wallet_1.driver.device_time
|
||||
|
||||
# self._check_balances_after_tx(amount_to_send, sender_balance, receiver_balance, eth_amount_sender,
|
||||
# eth_amount_receiver)
|
||||
self._check_balances_after_tx(amount_to_send, None, None, eth_amount_sender, eth_amount_receiver)
|
||||
|
||||
# ToDo: enable when issues 20807 and 20808 are fixed
|
||||
# self.loop.run_until_complete(
|
||||
# run_in_parallel(((self._check_last_transaction_in_activity, {'wallet_view': self.wallet_1,
|
||||
# 'device_time': device_time,
|
||||
# 'amount_to_send': amount_to_send}),
|
||||
# (self._check_last_transaction_in_activity, {'wallet_view': self.wallet_2,
|
||||
# 'device_time': device_time,
|
||||
# 'amount_to_send': amount_to_send,
|
||||
# 'sender': False}))))
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="new_one_2")
|
||||
@marks.nightly
|
||||
@marks.secured
|
||||
@@ -142,7 +336,7 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase):
|
||||
|
||||
self.wallet_view.slide_button_track.slide()
|
||||
if not self.wallet_view.password_input.is_element_displayed():
|
||||
self.errors.append(self.wallet_view, "%s on %s: can't confirm transaction" % (asset, network))
|
||||
self.errors.append("%s on %s: can't confirm transaction" % (asset, network))
|
||||
self.wallet_view.click_system_back_button_until_presence_of_element(
|
||||
element=self.wallet_view.element_by_text('Select token'), attempts=4)
|
||||
self.wallet_view.click_system_back_button_until_presence_of_element(
|
||||
@@ -343,7 +537,7 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase):
|
||||
network_from, network_to, key))
|
||||
self.wallet_view.slide_button_track.slide()
|
||||
if not self.wallet_view.password_input.is_element_displayed():
|
||||
self.errors.append(self.wallet_view, "%s to %s: can't confirm bridge" % (network_from, network_to))
|
||||
self.errors.append("%s to %s: can't confirm bridge" % (network_from, network_to))
|
||||
self.wallet_view.click_system_back_button(times=5)
|
||||
self.wallet_view.click_system_back_button_until_presence_of_element(
|
||||
element=self.wallet_view.add_account_button, attempts=6)
|
||||
@@ -1,185 +0,0 @@
|
||||
import re
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from selenium.common import TimeoutException
|
||||
|
||||
from base_test_case import MultipleSharedDeviceTestCase, create_shared_drivers
|
||||
from tests import marks
|
||||
from users import transaction_senders
|
||||
from views.sign_in_view import SignInView
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="new_one_2")
|
||||
@marks.nightly
|
||||
@marks.secured
|
||||
@marks.smoke
|
||||
class TestWalletCollectibles(MultipleSharedDeviceTestCase):
|
||||
|
||||
def prepare_devices(self):
|
||||
self.drivers, self.loop = create_shared_drivers(1)
|
||||
self.sign_in_view = SignInView(self.drivers[0])
|
||||
self.sender, self.receiver = transaction_senders['ETH_1'], transaction_senders['ETH_2']
|
||||
self.sender['wallet_address'] = '0x' + self.sender['address']
|
||||
self.receiver['wallet_address'] = '0x' + self.receiver['address']
|
||||
self.sign_in_view.recover_access(passphrase=self.sender['passphrase'])
|
||||
|
||||
self.home_view = self.sign_in_view.get_home_view()
|
||||
self.sender_username = self.home_view.get_username()
|
||||
self.profile_view = self.home_view.profile_button.click()
|
||||
self.profile_view.switch_network()
|
||||
self.sign_in_view.sign_in(user_name=self.sender_username)
|
||||
self.home_view.wallet_tab.click()
|
||||
self.wallet_view = self.home_view.get_wallet_view()
|
||||
self.account_name = 'Account 1'
|
||||
self.sender_short_address = self.sender['wallet_address'].replace(self.sender['wallet_address'][6:-3],
|
||||
'…').lower()
|
||||
self.receiver_short_address = self.receiver['wallet_address'].replace(self.receiver['wallet_address'][6:-3],
|
||||
'…').lower()
|
||||
|
||||
@marks.testrail_id(741839)
|
||||
def test_wallet_collectibles_balance(self):
|
||||
self.wallet_view.collectibles_tab.click()
|
||||
self.wallet_view.set_network_in_wallet('Base')
|
||||
collectibles = {
|
||||
"BVL": {"quantity": 2,
|
||||
"info": {"Account": "Account 1",
|
||||
"Network": "Base",
|
||||
"category": "Football Player",
|
||||
"rank": "Star",
|
||||
"type": "Modric"}},
|
||||
"Glitch Punks": {"quantity": 1,
|
||||
"info": {"Account": "Account 1",
|
||||
"Network": "Base",
|
||||
"Race": "Skull Blue",
|
||||
"Mouth": "Lipstick Green",
|
||||
"Eyes": "Femme Shade Eyes Variant 3",
|
||||
"Face": "Pipe",
|
||||
"Ear Accessory": "Silver Stud Cross Combo",
|
||||
"Nose": "Bot Nose 3",
|
||||
"Eye Accessory": "Nouns",
|
||||
"Head": "Double Spike"}}
|
||||
}
|
||||
for collectible_name, data in collectibles.items():
|
||||
self.wallet_view.just_fyi("Check %s collectible info and image" % collectible_name)
|
||||
try:
|
||||
element = self.wallet_view.get_collectible_element(collectible_name)
|
||||
element.wait_for_element()
|
||||
except TimeoutException:
|
||||
self.errors.append(self.wallet_view, "Collectible '%s' is not displayed" % collectible_name)
|
||||
continue
|
||||
if element.image_element.is_element_differs_from_template(
|
||||
'%s_collectible_image_template.png' % collectible_name):
|
||||
self.errors.append(self.wallet_view, "%s image doesn't match expected template" % collectible_name)
|
||||
if element.quantity != data['quantity']:
|
||||
self.errors.append(self.wallet_view, "%s quantity %s doesn't match expected %s" % (
|
||||
collectible_name, element.quantity, data['quantity']))
|
||||
self.wallet_view.just_fyi("Check %s collectible expanded info" % collectible_name)
|
||||
element.click()
|
||||
if self.wallet_view.expanded_collectible_image.is_element_differs_from_template(
|
||||
'%s_expanded_collectible_image_template.png' % collectible_name):
|
||||
self.errors.append(self.wallet_view,
|
||||
"%s expanded image doesn't match expected template" % collectible_name)
|
||||
self.wallet_view.driver.swipe(500, 2000, 500, 300)
|
||||
for item, expected_text in data['info'].items():
|
||||
try:
|
||||
text = self.wallet_view.get_data_item_element_text(item)
|
||||
if text != expected_text:
|
||||
self.errors.append(self.wallet_view, "%s: shown %s text '%s' doesn't match expected '%s'" % (
|
||||
collectible_name, item, text, expected_text))
|
||||
except TimeoutException:
|
||||
self.errors.append(self.wallet_view, "%s: %s data item is not shown" % (collectible_name, item))
|
||||
self.wallet_view.click_system_back_button()
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
@marks.testrail_id(741840)
|
||||
def test_wallet_send_collectible(self):
|
||||
self.wallet_view.reopen_app(user_name=self.sender_username)
|
||||
self.wallet_view.send_button.click()
|
||||
self.wallet_view.address_text_input.send_keys(self.receiver['wallet_address'])
|
||||
self.wallet_view.continue_button.click()
|
||||
self.wallet_view.collectibles_tab_on_select_token_view.click()
|
||||
time.sleep(5)
|
||||
self.wallet_view.get_collectible_element('BVL').click()
|
||||
self.wallet_view.amount_input_increase_button.click()
|
||||
self.wallet_view.confirm_button.click()
|
||||
expected_text = '2 BVL #47'
|
||||
for text in [self.account_name, self.sender_short_address, expected_text]:
|
||||
if not self.wallet_view.from_data_container.get_child_element_by_text(text).is_element_displayed():
|
||||
self.errors.append(self.wallet_view,
|
||||
"Text %s is not shown in 'From' container on the Review Send page" % text)
|
||||
for text in [self.receiver_short_address, expected_text]:
|
||||
if not self.wallet_view.to_data_container.get_child_element_by_text(text).is_element_displayed():
|
||||
self.errors.append(self.wallet_view,
|
||||
"Text %s is not shown in 'To' container on the Review Send page" % text)
|
||||
data_to_check = {
|
||||
'Est. time': ' min',
|
||||
'Max fees': r"[$]\d+.\d+",
|
||||
'Recipient gets': '2 '
|
||||
}
|
||||
for key, expected_value in data_to_check.items():
|
||||
try:
|
||||
text = self.wallet_view.get_data_item_element_text(data_item_name=key)
|
||||
if key == 'Max fees':
|
||||
if not re.findall(expected_value, text):
|
||||
self.errors.append(self.wallet_view,
|
||||
"Max fee is not a number - %s on the Review Send page" % text)
|
||||
else:
|
||||
if text != expected_value:
|
||||
self.errors.append(
|
||||
self.wallet_view,
|
||||
"%s text %s doesn't match expected %s on the Review Send page" % (
|
||||
key, text, expected_value))
|
||||
except TimeoutException:
|
||||
self.errors.append(self.wallet_view, "%s is not shown on the Review Send page" % key)
|
||||
|
||||
self.wallet_view.slide_button_track.slide()
|
||||
if not self.wallet_view.password_input.is_element_displayed():
|
||||
self.errors.append(self.wallet_view, "Can't confirm transaction")
|
||||
|
||||
self.wallet_view.click_system_back_button(times=6)
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
@marks.testrail_id(741841)
|
||||
def test_wallet_collectible_send_from_expanded_info_view(self):
|
||||
# self.wallet_view.reopen_app(user_name=self.sender_username)
|
||||
self.wallet_view.collectibles_tab.click()
|
||||
self.wallet_view.get_collectible_element('Glitch Punks').wait_for_element().click()
|
||||
self.wallet_view.send_from_collectible_info_button.click()
|
||||
self.wallet_view.address_text_input.send_keys(self.receiver['wallet_address'])
|
||||
self.wallet_view.continue_button.click()
|
||||
expected_text = '1 Glitch Punks #3422'
|
||||
for text in [self.account_name, self.sender_short_address, expected_text]:
|
||||
if not self.wallet_view.from_data_container.get_child_element_by_text(text).is_element_displayed():
|
||||
self.errors.append(self.wallet_view,
|
||||
"Text %s is not shown in 'From' container on the Review Send page" % text)
|
||||
for text in [self.receiver_short_address, expected_text]:
|
||||
if not self.wallet_view.to_data_container.get_child_element_by_text(text).is_element_displayed():
|
||||
self.errors.append(self.wallet_view,
|
||||
"Text %s is not shown in 'To' container on the Review Send page" % text)
|
||||
data_to_check = {
|
||||
'Est. time': ' min',
|
||||
'Max fees': r"[$]\d+.\d+",
|
||||
'Recipient gets': '1 '
|
||||
}
|
||||
for key, expected_value in data_to_check.items():
|
||||
try:
|
||||
text = self.wallet_view.get_data_item_element_text(data_item_name=key)
|
||||
if key == 'Max fees':
|
||||
if not re.findall(expected_value, text):
|
||||
self.errors.append(self.wallet_view,
|
||||
"Max fee is not a number - %s on the Review Send page" % text)
|
||||
else:
|
||||
if text != expected_value:
|
||||
self.errors.append(
|
||||
self.wallet_view,
|
||||
"'%s' text '%s' doesn't match expected '%s' on the Review Send page" % (
|
||||
key, text, expected_value))
|
||||
except TimeoutException:
|
||||
self.errors.append(self.wallet_view, "%s is not shown on the Review Send page" % key)
|
||||
|
||||
self.wallet_view.slide_button_track.slide()
|
||||
if not self.wallet_view.password_input.is_element_displayed():
|
||||
self.errors.append(self.wallet_view, "Can't confirm transaction")
|
||||
|
||||
self.errors.verify_no_errors()
|
||||
@@ -1,202 +0,0 @@
|
||||
import datetime
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from selenium.common import NoSuchElementException
|
||||
|
||||
from base_test_case import MultipleSharedDeviceTestCase, create_shared_drivers
|
||||
from support.api.network_api import NetworkApi
|
||||
from tests import marks, run_in_parallel
|
||||
from users import transaction_senders
|
||||
from views.sign_in_view import SignInView
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="new_four_2")
|
||||
@marks.nightly
|
||||
@marks.secured
|
||||
@marks.smoke
|
||||
class TestWalletMultipleDevice(MultipleSharedDeviceTestCase):
|
||||
|
||||
def prepare_devices(self):
|
||||
self.network_api = NetworkApi()
|
||||
self.drivers, self.loop = create_shared_drivers(2)
|
||||
self.sign_in_1, self.sign_in_2 = SignInView(self.drivers[0]), SignInView(self.drivers[1])
|
||||
self.sender, self.receiver = transaction_senders['ETH_1'], transaction_senders['ETH_2']
|
||||
self.sender['wallet_address'] = '0x' + self.sender['address']
|
||||
self.receiver['wallet_address'] = '0x' + self.receiver['address']
|
||||
self.loop.run_until_complete(
|
||||
run_in_parallel(((self.sign_in_1.recover_access, {'passphrase': self.sender['passphrase']}),
|
||||
(self.sign_in_2.recover_access, {'passphrase': self.receiver['passphrase']}))))
|
||||
self.home_1, self.home_2 = self.sign_in_1.get_home_view(), self.sign_in_2.get_home_view()
|
||||
self.sender_username, self.receiver_username = self.home_1.get_username(), self.home_2.get_username()
|
||||
self.wallet_1, self.wallet_2 = self.sign_in_1.get_wallet_view(), self.sign_in_2.get_wallet_view()
|
||||
self.wallet_1.wallet_tab.click()
|
||||
self.wallet_2.wallet_tab.click()
|
||||
self.network = "Arbitrum"
|
||||
|
||||
def _get_balances_before_tx(self):
|
||||
# ToDo: Arbiscan API is down, looking for analogue
|
||||
# sender_balance = self.network_api.get_balance(self.sender['wallet_address'])
|
||||
# receiver_balance = self.network_api.get_balance(self.receiver['wallet_address'])
|
||||
self.wallet_1.just_fyi("Getting ETH amount in the wallet of the sender before transaction")
|
||||
self.wallet_1.get_account_element().click()
|
||||
eth_amount_sender = self.wallet_1.get_asset(asset_name='Ether').get_amount()
|
||||
self.wallet_2.just_fyi("Getting ETH amount in the wallet of the receiver before transaction")
|
||||
self.wallet_2.get_account_element().click()
|
||||
eth_amount_receiver = self.wallet_2.get_asset(asset_name='Ether').get_amount()
|
||||
# return sender_balance, receiver_balance, eth_amount_sender, eth_amount_receiver
|
||||
return eth_amount_sender, eth_amount_receiver
|
||||
|
||||
def _check_balances_after_tx(self, amount_to_send, sender_balance, receiver_balance, eth_amount_sender,
|
||||
eth_amount_receiver):
|
||||
# ToDo: Arbiscan API is down, looking for analogue
|
||||
# try:
|
||||
# self.network_api.wait_for_balance_to_be(address=self.sender['wallet_address'],
|
||||
# expected_balance=sender_balance - amount_to_send)
|
||||
# except TimeoutException as e:
|
||||
# self.errors.append("Sender " + e.msg)
|
||||
# try:
|
||||
# self.network_api.wait_for_balance_to_be(address=self.receiver['wallet_address'],
|
||||
# expected_balance=receiver_balance + amount_to_send)
|
||||
# except TimeoutException as e:
|
||||
# self.errors.append("Receiver " + e.msg)
|
||||
|
||||
def wait_for_wallet_balance_to_update(wallet_view, user_name, initial_eth_amount):
|
||||
wallet_view.just_fyi("Getting ETH amount in the wallet of the %s after transaction" % user_name)
|
||||
if user_name == self.sender_username:
|
||||
exp_amount = round(initial_eth_amount - amount_to_send, 4)
|
||||
else:
|
||||
exp_amount = round(initial_eth_amount + amount_to_send, 4)
|
||||
|
||||
# for _ in range(12): # ToDo: 120 sec wait time, enable when autoupdate feature is ready
|
||||
new_eth_amount = round(wallet_view.get_asset(asset_name='Ether').get_amount(), 4)
|
||||
if user_name == self.sender_username and new_eth_amount <= exp_amount:
|
||||
return
|
||||
if user_name == self.receiver_username and new_eth_amount >= exp_amount:
|
||||
return
|
||||
self.errors.append(wallet_view,
|
||||
"Eth amount in the %s's wallet is %s but should be %s" % (
|
||||
user_name, new_eth_amount, exp_amount))
|
||||
|
||||
# ToDo: disable relogin when autoupdate feature is ready
|
||||
self.home_1.just_fyi("Relogin for getting an updated balance")
|
||||
self.home_2.just_fyi("Relogin for getting an updated balance")
|
||||
for _ in range(6): # just waiting 1 minute here to be sure that balances are updated
|
||||
self.wallet_1.wallet_tab.is_element_displayed()
|
||||
self.wallet_2.wallet_tab.is_element_displayed()
|
||||
time.sleep(10)
|
||||
self.loop.run_until_complete(
|
||||
run_in_parallel(((self.home_1.reopen_app, {'user_name': self.sender_username}),
|
||||
(self.home_2.reopen_app, {'user_name': self.receiver_username}))))
|
||||
self.wallet_1.wallet_tab.wait_and_click()
|
||||
self.wallet_2.wallet_tab.wait_and_click()
|
||||
self.wallet_1.set_network_in_wallet(network_name=self.network)
|
||||
self.wallet_2.set_network_in_wallet(network_name=self.network)
|
||||
self.loop.run_until_complete(
|
||||
run_in_parallel(((wait_for_wallet_balance_to_update, {'wallet_view': self.wallet_1,
|
||||
'user_name': self.sender_username,
|
||||
'initial_eth_amount': eth_amount_sender}),
|
||||
(wait_for_wallet_balance_to_update, {'wallet_view': self.wallet_2,
|
||||
'user_name': self.receiver_username,
|
||||
'initial_eth_amount': eth_amount_receiver}))))
|
||||
|
||||
def _check_last_transaction_in_activity(self, wallet_view, device_time, amount_to_send, sender=True):
|
||||
wallet_view.get_account_element().click()
|
||||
wallet_view.activity_tab.click()
|
||||
wallet_view.just_fyi("Checking the transaction in the activity tab")
|
||||
current_time = datetime.datetime.strptime(device_time, "%Y-%m-%dT%H:%M:%S%z")
|
||||
expected_time = "Today %s" % current_time.strftime('%-I:%M %p')
|
||||
possible_times = [expected_time,
|
||||
"Today %s" % (current_time + datetime.timedelta(minutes=1)).strftime('%-I:%M %p')]
|
||||
sender_address_short = self.sender['wallet_address'].replace(self.sender['wallet_address'][5:-3], '...').lower()
|
||||
receiver_address_short = self.receiver['wallet_address'].replace(self.receiver['wallet_address'][5:-3],
|
||||
'...').lower()
|
||||
activity_element = wallet_view.get_activity_element()
|
||||
try:
|
||||
if not all((activity_element.header == 'Send' if sender else 'Receive',
|
||||
activity_element.timestamp in possible_times,
|
||||
activity_element.amount == '%s ETH' % amount_to_send,
|
||||
activity_element.from_text == sender_address_short,
|
||||
activity_element.to_text == receiver_address_short)):
|
||||
self.errors.append(
|
||||
wallet_view,
|
||||
"The last transaction is not listed in activity for the %s, expected timestamp is %s" %
|
||||
('sender' if sender else 'receiver', expected_time))
|
||||
except NoSuchElementException:
|
||||
self.errors.append(wallet_view,
|
||||
"Can't find the last transaction for the %s" % ('sender' if sender else 'receiver'))
|
||||
finally:
|
||||
wallet_view.close_account_button.click_until_presence_of_element(wallet_view.show_qr_code_button)
|
||||
|
||||
@marks.testrail_id(727229)
|
||||
def test_wallet_send_eth(self):
|
||||
self.wallet_1.set_network_in_wallet(network_name=self.network)
|
||||
self.wallet_2.set_network_in_wallet(network_name=self.network)
|
||||
# sender_balance, receiver_balance, eth_amount_sender, eth_amount_receiver = self._get_balances_before_tx()
|
||||
eth_amount_sender, eth_amount_receiver = self._get_balances_before_tx()
|
||||
|
||||
self.wallet_2.close_account_button.click()
|
||||
self.wallet_2.chats_tab.click()
|
||||
|
||||
self.wallet_1.just_fyi("Sending funds from wallet")
|
||||
amount_to_send = 0.0001
|
||||
device_time_before_sending = self.wallet_1.driver.device_time
|
||||
self.wallet_1.send_asset(address='arb1:' + self.receiver['wallet_address'],
|
||||
asset_name='Ether',
|
||||
amount=f"{amount_to_send:.4f}",
|
||||
network_name=self.network)
|
||||
# ToDo: Arbiscan API is down, looking for analogue
|
||||
# self.network_api.wait_for_confirmation_of_transaction(address=self.sender['wallet_address'],
|
||||
# tx_time=device_time_before_sending)
|
||||
|
||||
device_time_after_sending = self.wallet_1.driver.device_time
|
||||
|
||||
# self._check_balances_after_tx(amount_to_send, sender_balance, receiver_balance, eth_amount_sender,
|
||||
# eth_amount_receiver)
|
||||
self._check_balances_after_tx(amount_to_send, None, None, eth_amount_sender, eth_amount_receiver)
|
||||
|
||||
# ToDo: enable when issues 20807 and 20808 are fixed
|
||||
# self.loop.run_until_complete(
|
||||
# run_in_parallel(((self._check_last_transaction_in_activity, {'wallet_view': self.wallet_1,
|
||||
# 'device_time': device_time,
|
||||
# 'amount_to_send': amount_to_send}),
|
||||
# (self._check_last_transaction_in_activity, {'wallet_view': self.wallet_2,
|
||||
# 'device_time': device_time,
|
||||
# 'amount_to_send': amount_to_send,
|
||||
# 'sender': False}))))
|
||||
self.errors.verify_no_errors()
|
||||
|
||||
@marks.testrail_id(727230)
|
||||
def test_wallet_send_asset_from_drawer(self):
|
||||
self.wallet_1.navigate_back_to_wallet_view()
|
||||
# sender_balance, receiver_balance, eth_amount_sender, eth_amount_receiver = self._get_balances_before_tx()
|
||||
eth_amount_sender, eth_amount_receiver = self._get_balances_before_tx()
|
||||
self.wallet_2.close_account_button.click_if_shown()
|
||||
self.wallet_2.chats_tab.click()
|
||||
|
||||
self.wallet_1.just_fyi("Sending asset from drawer")
|
||||
amount_to_send = 0.0001
|
||||
device_time_before_sending = self.wallet_1.driver.device_time
|
||||
self.wallet_1.send_asset_from_drawer(address='arb1:' + self.receiver['wallet_address'],
|
||||
asset_name='Ether',
|
||||
amount=f"{amount_to_send:.4f}",
|
||||
network_name=self.network)
|
||||
# ToDo: Arbiscan API is down, looking for analogue
|
||||
# self.network_api.wait_for_confirmation_of_transaction(address=self.sender['wallet_address'],
|
||||
# tx_time=device_time_before_sending)
|
||||
device_time_after_sending = self.wallet_1.driver.device_time
|
||||
|
||||
# self._check_balances_after_tx(amount_to_send, sender_balance, receiver_balance, eth_amount_sender,
|
||||
# eth_amount_receiver)
|
||||
self._check_balances_after_tx(amount_to_send, None, None, eth_amount_sender, eth_amount_receiver)
|
||||
|
||||
# ToDo: enable when issues 20807 and 20808 are fixed
|
||||
# self.loop.run_until_complete(
|
||||
# run_in_parallel(((self._check_last_transaction_in_activity, {'wallet_view': self.wallet_1,
|
||||
# 'device_time': device_time,
|
||||
# 'amount_to_send': amount_to_send}),
|
||||
# (self._check_last_transaction_in_activity, {'wallet_view': self.wallet_2,
|
||||
# 'device_time': device_time,
|
||||
# 'amount_to_send': amount_to_send,
|
||||
# 'sender': False}))))
|
||||
self.errors.verify_no_errors()
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 329 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.3 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 8.8 KiB |
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 21 KiB |
@@ -1,7 +1,6 @@
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from selenium.common import NoSuchElementException
|
||||
|
||||
from tests import common_password
|
||||
from views.base_element import Button, EditBox, Text, BaseElement
|
||||
@@ -31,24 +30,6 @@ class AssetElement(Button):
|
||||
pytest.fail("Cannot get %s amount" % self.asset_name)
|
||||
|
||||
|
||||
class CollectibleItemElement(Button):
|
||||
|
||||
def __init__(self, driver, collectible_name):
|
||||
self.collectible_name = collectible_name
|
||||
self.locator = "//*[@content-desc='collectible-list-item']//*[contains(@text,'%s')]/../.." % collectible_name
|
||||
super().__init__(driver=driver, xpath=self.locator)
|
||||
self.image_element = BaseElement(self.driver, xpath=self.locator + "//android.widget.ImageView")
|
||||
|
||||
@property
|
||||
def quantity(self):
|
||||
counter_element = BaseElement(
|
||||
self.driver, xpath=self.locator + "//*[@content-desc='collectible-counter']/android.widget.TextView")
|
||||
try:
|
||||
return int(counter_element.text.strip('x'))
|
||||
except NoSuchElementException:
|
||||
return 1
|
||||
|
||||
|
||||
class ActivityElement(BaseElement):
|
||||
def __init__(self, driver, index: int):
|
||||
self.locator = "(//*[@content-desc='wallet-activity'])[%s]" % index
|
||||
@@ -130,13 +111,11 @@ class WalletView(BaseView):
|
||||
|
||||
# Sending transaction
|
||||
self.address_text_input = EditBox(self.driver, accessibility_id='address-text-input')
|
||||
self.collectibles_tab_on_select_token_view = Button(self.driver, accessibility_id='Collectibles')
|
||||
self.amount_input = EditBox(self.driver, xpath="//android.widget.EditText")
|
||||
self.from_network_text = Text(
|
||||
self.driver, xpath="(//*[@content-desc='loading']/following-sibling::android.widget.TextView)[1]")
|
||||
self.confirm_button = Button(self.driver, accessibility_id='button-one')
|
||||
self.done_button = Button(self.driver, accessibility_id='done')
|
||||
self.amount_input_increase_button = Button(self.driver, accessibility_id='amount-input-inc-button')
|
||||
|
||||
# Review Send and Review Bridge screens
|
||||
self.from_data_container = ConfirmationViewInfoContainer(self.driver, label_name='from')
|
||||
@@ -174,11 +153,6 @@ class WalletView(BaseView):
|
||||
self.passphrase_word_number_container = Text(
|
||||
self.driver, xpath="//*[@content-desc='number-container']/android.widget.TextView")
|
||||
|
||||
# Collectible view
|
||||
self.expanded_collectible_image = BaseElement(
|
||||
self.driver, xpath="//*[@content-desc='expanded-collectible']//android.widget.ImageView")
|
||||
self.send_from_collectible_info_button = Button(self.driver, accessibility_id="icon, Send")
|
||||
|
||||
def set_network_in_wallet(self, network_name: str):
|
||||
self.network_drop_down.click()
|
||||
Button(self.driver, accessibility_id="%s, label-component" % network_name.capitalize()).click()
|
||||
@@ -192,9 +166,6 @@ class WalletView(BaseView):
|
||||
element.scroll_to_element(down_start_y=0.89, down_end_y=0.8)
|
||||
return element
|
||||
|
||||
def get_collectible_element(self, collectible_name: str):
|
||||
return CollectibleItemElement(driver=self.driver, collectible_name=collectible_name)
|
||||
|
||||
def select_asset(self, asset_name: str):
|
||||
Button(driver=self.driver,
|
||||
xpath="//*[@content-desc='token-network']/android.widget.TextView[@text='%s']" % asset_name).click()
|
||||
|
||||
Reference in New Issue
Block a user