Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74c38186a4 | ||
|
|
55c620e59d | ||
|
|
525609f0af | ||
|
|
90653955a6 | ||
|
|
d27ab756d0 | ||
|
|
c6a1db6334 | ||
|
|
73777e052e | ||
|
|
a6d3fc3742 | ||
|
|
a671c70838 | ||
|
|
a45991b6dc | ||
|
|
2e9fa22e4f |
@@ -215,15 +215,13 @@ build-fdroid: ##@build Build release for F-Droid
|
||||
build-android: export BUILD_ENV ?= prod
|
||||
build-android: export BUILD_TYPE ?= nightly
|
||||
build-android: export ORG_GRADLE_PROJECT_versionCode ?= $(TMP_BUILD_NUMBER)
|
||||
build-android: export ANDROID_ABI_SPLIT ?= false
|
||||
build-android: export ANDROID_ABI_INCLUDE ?= armeabi-v7a;arm64-v8a;x86
|
||||
build-android: ##@build Build unsigned Android APK
|
||||
@scripts/build-android.sh
|
||||
|
||||
release-android: export TARGET := keytool
|
||||
release-android: export KEYSTORE_PATH ?= $(HOME)/.gradle/status-im.keystore
|
||||
release-android: keystore build-android ##@build Build signed Android APK
|
||||
@scripts/sign-android.sh result/app-release-unsigned.apk
|
||||
@scripts/sign-android.sh result/app-arm64-v8a-release-unsigned.apk
|
||||
|
||||
release-ios: export TARGET := ios
|
||||
release-ios: export IOS_STATUS_GO_TARGETS := ios/arm64
|
||||
|
||||
@@ -211,7 +211,7 @@ android {
|
||||
reset()
|
||||
enable getEnvOrConfig('ANDROID_ABI_SPLIT').toBoolean()
|
||||
include getEnvOrConfig('ANDROID_ABI_INCLUDE').split(";")
|
||||
universalApk true
|
||||
universalApk false
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
|
||||
@@ -38,10 +38,10 @@ KEYSTORE_PASSWORD=password
|
||||
KEYSTORE_ALIAS=status
|
||||
KEYSTORE_KEY_PASSWORD=password
|
||||
|
||||
# By default we build a mostly universal APK
|
||||
ANDROID_ABI_SPLIT=false
|
||||
# Some platforms are excluded though
|
||||
ANDROID_ABI_INCLUDE=armeabi-v7a;arm64-v8a;x86;x86_64
|
||||
# Splitting by CPU Architecture produces smaller APKs.
|
||||
ANDROID_ABI_SPLIT=true
|
||||
# By default its better to only build apk for most recent devices.
|
||||
ANDROID_ABI_INCLUDE=arm64-v8a
|
||||
|
||||
org.gradle.jvmargs=-Xmx8704M -XX:+UseParallelGC
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
@@ -72,11 +72,7 @@ pipeline {
|
||||
stage('Upload') {
|
||||
steps { script {
|
||||
def urls = apks.collect { s5cmd.upload(it) }
|
||||
if (urls.size() > 1) { /* Return only the universal APK. */
|
||||
env.PKG_URL = urls.find { it.contains('universal') }
|
||||
} else { /* If no universal is available pick first. */
|
||||
env.PKG_URL = urls.first()
|
||||
}
|
||||
env.PKG_URL = urls.first()
|
||||
jenkins.setBuildDesc(APK: env.PKG_URL)
|
||||
} }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
|
||||
import groovy.json.JsonBuilder
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
|
||||
pipeline {
|
||||
agent { label params.AGENT_LABEL }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
library 'status-jenkins-lib@v1.9.3'
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
buildUrl ? lib.getEnvWithDefault "ORG_GRADLE_PROJECT_buildUrl" null,
|
||||
statusGoSrcOverride ? lib.getEnvWithDefault "STATUS_GO_SRC_OVERRIDE" null,
|
||||
# If APKs should be split based on architectures
|
||||
androidAbiSplit ? lib.getEnvWithDefault "ANDROID_ABI_SPLIT" "false",
|
||||
androidAbiSplit ? lib.getEnvWithDefault "ANDROID_ABI_SPLIT" "true",
|
||||
# Android architectures to build for
|
||||
# Used to detect end-to-end builds
|
||||
androidAbiInclude ? lib.getEnvWithDefault "ANDROID_ABI_INCLUDE" "armeabi-v7a;arm64-v8a;x86",
|
||||
androidAbiInclude ? lib.getEnvWithDefault "ANDROID_ABI_INCLUDE" "arm64-v8a",
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 424 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 752 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 547 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
@@ -13,7 +13,7 @@ export BUILD_TYPE=debug
|
||||
|
||||
# Install the APK on running emulator or android device.
|
||||
installAndLaunchApp() {
|
||||
adb install -r ./result/app-debug.apk > "${ADB_INSTALL_LOG_FILE}" 2>&1
|
||||
adb install -r ./result/app-arm64-v8a-debug.apk > "${ADB_INSTALL_LOG_FILE}" 2>&1
|
||||
"${GIT_ROOT}/scripts/wait-for-metro-port.sh" 2>&1
|
||||
# connected android devices need this port to be exposed for metro
|
||||
adb reverse "tcp:${RCT_METRO_PORT}" "tcp:${RCT_METRO_PORT}"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[legacy.status-im.ui.components.list.views :as list]
|
||||
[quo.core :as quo]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf])
|
||||
(:require-macros [legacy.status-im.utils.views :as views]))
|
||||
@@ -59,14 +60,14 @@
|
||||
:on-press
|
||||
#(re-frame/dispatch [:open-modal :peers-stats])
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title "Telemetry"
|
||||
:accessibility-label :telemetry-enabled
|
||||
:container-margin-bottom 8
|
||||
:on-press
|
||||
#(re-frame/dispatch [:profile.settings/toggle-telemetry])
|
||||
:accessory :switch
|
||||
:active telemetry-enabled?}
|
||||
(when (ff/enabled? ::ff/settings.telemetry)
|
||||
{:size :small
|
||||
:title "Telemetry"
|
||||
:accessibility-label :telemetry-enabled
|
||||
:container-margin-bottom 8
|
||||
:on-press #(re-frame/dispatch [:profile.settings/toggle-telemetry])
|
||||
:accessory :switch
|
||||
:active telemetry-enabled?})
|
||||
{:size :small
|
||||
:title (i18n/label :t/light-client-enabled)
|
||||
:accessibility-label :light-client-enabled
|
||||
|
||||
@@ -32,8 +32,7 @@
|
||||
|
||||
(def system-message-base-wrapper
|
||||
{:flex-direction :row
|
||||
:flex 1
|
||||
:align-items :center})
|
||||
:flex 1})
|
||||
|
||||
(def system-message-base-content-wrapper
|
||||
{:align-self :center
|
||||
|
||||
@@ -127,6 +127,14 @@
|
||||
(when incoming? [split-text "sent you a contact request" theme true])
|
||||
[sm-timestamp timestamp theme]]]))
|
||||
|
||||
(defn system-message-group
|
||||
[{:keys [customization-color child]}]
|
||||
[system-message-base
|
||||
{:icon {:icon :i/add-user
|
||||
:color (or customization-color :primary)
|
||||
:opacity 5}}
|
||||
[rn/view child]])
|
||||
|
||||
(defn system-message-pinned
|
||||
[{:keys [pinned-by child customization-color timestamp]}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
@@ -183,6 +191,7 @@
|
||||
:contact-request [system-message-contact-request data]
|
||||
:added [system-message-added data]
|
||||
:removed [system-message-removed data]
|
||||
:group [system-message-group data]
|
||||
nil)]))
|
||||
|
||||
(defn system-message
|
||||
|
||||
@@ -4,11 +4,37 @@
|
||||
[oops.core :as oops]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- add-keyboard-listener
|
||||
[listener callback]
|
||||
(oops/ocall rn/keyboard "addListener" listener callback))
|
||||
|
||||
(defn use-keyboard
|
||||
[]
|
||||
(let [kb (.useKeyboard hooks)]
|
||||
{:keyboard-shown (.-keyboardShown ^js kb)
|
||||
:keyboard-height (.-keyboardHeight ^js kb)}))
|
||||
(let [[keyboard-height set-keyboard-height] (rn/use-state 0)
|
||||
[did-show? set-did-show] (rn/use-state false)
|
||||
[will-show? set-will-show] (rn/use-state false)]
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
(let [will-show-listener (add-keyboard-listener "keyboardWillShow" #(set-will-show true))
|
||||
did-show-listener (add-keyboard-listener "keyboardDidShow"
|
||||
(fn [e]
|
||||
(set-did-show true)
|
||||
(set-keyboard-height
|
||||
(oops/oget e "endCoordinates.height"))))
|
||||
will-hide-listener (add-keyboard-listener "keyboardWillHide" #(set-will-show false))
|
||||
did-hide-listener (add-keyboard-listener "keyboardDidHide"
|
||||
(fn [e]
|
||||
(set-did-show false)
|
||||
(when e
|
||||
(oops/oget e "endCoordinates.height"))))]
|
||||
(fn []
|
||||
(oops/ocall will-show-listener "remove")
|
||||
(oops/ocall did-show-listener "remove")
|
||||
(oops/ocall will-hide-listener "remove")
|
||||
(oops/ocall did-hide-listener "remove")))))
|
||||
{:keyboard-shown did-show?
|
||||
:keyboard-will-show? will-show?
|
||||
:keyboard-height keyboard-height}))
|
||||
|
||||
(defn use-back-handler
|
||||
[handler]
|
||||
|
||||
@@ -3,21 +3,23 @@
|
||||
[react-native.safe-area :as safe-area]))
|
||||
|
||||
(defn content-container
|
||||
[blur? keyboard-shown?]
|
||||
[blur? keyboard-shown? {:keys [padding-vertical padding-horizontal]}]
|
||||
(let [margin-bottom (if keyboard-shown? 0 (safe-area/get-bottom))]
|
||||
(cond-> {:margin-top :auto
|
||||
:overflow :hidden
|
||||
:margin-bottom margin-bottom
|
||||
:padding-vertical 12
|
||||
:padding-horizontal 20}
|
||||
:padding-vertical (or padding-vertical 12)
|
||||
:padding-horizontal (or padding-horizontal 20)}
|
||||
blur? (dissoc :padding-vertical :padding-horizontal))))
|
||||
|
||||
(defn blur-inner-container
|
||||
[theme shell-overlay?]
|
||||
{:background-color (colors/theme-colors colors/white-70-blur
|
||||
(if shell-overlay?
|
||||
colors/neutral-80-opa-80-blur
|
||||
colors/neutral-95-opa-70-blur)
|
||||
theme)
|
||||
:padding-vertical 12
|
||||
:padding-horizontal 20})
|
||||
[{:keys [theme shell-overlay? padding-vertical padding-horizontal background-color]}]
|
||||
{:background-color (or background-color
|
||||
(colors/theme-colors
|
||||
colors/white-70-blur
|
||||
(if shell-overlay?
|
||||
colors/neutral-80-opa-80-blur
|
||||
colors/neutral-95-opa-70-blur)
|
||||
theme))
|
||||
:padding-vertical (or padding-vertical 12)
|
||||
:padding-horizontal (or padding-horizontal 20)})
|
||||
|
||||
@@ -6,20 +6,25 @@
|
||||
[status-im.common.floating-button-page.floating-container.style :as style]))
|
||||
|
||||
(defn- blur-container
|
||||
[child shell-overlay?]
|
||||
[shell-overlay? blur-options child]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[quo/blur
|
||||
{:blur-amount 20
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent}
|
||||
[rn/view {:style (style/blur-inner-container theme shell-overlay?)}
|
||||
(or blur-options
|
||||
{:blur-amount 20
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent})
|
||||
[rn/view
|
||||
{:style (style/blur-inner-container (assoc
|
||||
blur-options
|
||||
:theme theme
|
||||
:shell-overlay? shell-overlay?))}
|
||||
child]]))
|
||||
|
||||
(defn view
|
||||
[{:keys [on-layout keyboard-shown? blur? shell-overlay?]} child]
|
||||
[{:keys [on-layout keyboard-shown? blur? shell-overlay? blur-options]} child]
|
||||
[rn/view
|
||||
{:style (style/content-container blur? keyboard-shown?)
|
||||
{:style (style/content-container blur? keyboard-shown? blur-options)
|
||||
:on-layout on-layout}
|
||||
(if blur?
|
||||
[blur-container child shell-overlay?]
|
||||
[blur-container shell-overlay? blur-options child]
|
||||
child)])
|
||||
|
||||
@@ -13,3 +13,13 @@
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0})
|
||||
|
||||
(defn content-keyboard-avoiding-view
|
||||
[{:keys [top bottom]}]
|
||||
{:position :absolute
|
||||
:top top
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom bottom})
|
||||
|
||||
(def scroll-view-container {:flex 1})
|
||||
|
||||
@@ -30,13 +30,15 @@
|
||||
(reset! ratom height))))
|
||||
|
||||
(defn- init-keyboard-listeners
|
||||
[{:keys [on-did-show scroll-view-ref]}]
|
||||
[{:keys [on-did-show on-will-show scroll-view-ref]}]
|
||||
(let [keyboard-will-show? (reagent/atom false)
|
||||
keyboard-did-show? (reagent/atom false)
|
||||
add-listener (fn [listener callback]
|
||||
(oops/ocall rn/keyboard "addListener" listener callback))
|
||||
will-show-listener (add-listener "keyboardWillShow"
|
||||
#(reset! keyboard-will-show? true))
|
||||
(fn [e]
|
||||
(reset! keyboard-will-show? true)
|
||||
(when on-will-show (on-will-show e))))
|
||||
did-show-listener (add-listener "keyboardDidShow"
|
||||
(fn [e]
|
||||
(reset! keyboard-did-show? true)
|
||||
@@ -58,7 +60,8 @@
|
||||
|
||||
(defn view
|
||||
[{:keys [header footer customization-color footer-container-padding header-container-style
|
||||
content-container-style gradient-cover? keyboard-should-persist-taps shell-overlay?]
|
||||
content-container-style gradient-cover? keyboard-should-persist-taps shell-overlay?
|
||||
blur-options content-avoid-keyboard?]
|
||||
:or {footer-container-padding (safe-area/get-top)}}
|
||||
& children]
|
||||
(reagent/with-let [scroll-view-ref (atom nil)
|
||||
@@ -69,29 +72,34 @@
|
||||
content-container-height (reagent/atom 0)
|
||||
content-scroll-y (reagent/atom 0)
|
||||
keyboard-height (reagent/atom 0)
|
||||
reset-keyboard-height #(reset! keyboard-height (oops/oget
|
||||
%
|
||||
"endCoordinates.height"))
|
||||
{:keys [keyboard-will-show?
|
||||
keyboard-did-show?
|
||||
remove-listeners]} (init-keyboard-listeners
|
||||
{:scroll-view-ref scroll-view-ref
|
||||
:on-did-show
|
||||
(fn [e]
|
||||
(reset! keyboard-height
|
||||
(oops/oget e "endCoordinates.height")))})
|
||||
(cond-> {:scroll-view-ref scroll-view-ref}
|
||||
platform/ios?
|
||||
(assoc :on-will-show reset-keyboard-height)
|
||||
(not platform/ios?)
|
||||
(assoc :on-did-show reset-keyboard-height)))
|
||||
set-header-height (set-height-on-layout header-height)
|
||||
set-content-container-height (set-height-on-layout content-container-height)
|
||||
set-footer-container-height (set-height-on-layout footer-container-height)
|
||||
set-content-y-scroll (fn [event]
|
||||
(reset! content-scroll-y
|
||||
(oops/oget event "nativeEvent.contentOffset.y")))]
|
||||
(oops/oget event "nativeEvent.contentOffset.y")))
|
||||
bottom-safe-area (safe-area/get-bottom)]
|
||||
(let [keyboard-shown? (if platform/ios? @keyboard-will-show? @keyboard-did-show?)
|
||||
footer-container-padding (+ footer-container-padding (rf/sub [:alert-banners/top-margin]))
|
||||
show-background? (show-background {:window-height window-height
|
||||
:footer-container-height @footer-container-height
|
||||
:keyboard-height @keyboard-height
|
||||
:content-scroll-y @content-scroll-y
|
||||
:content-container-height @content-container-height
|
||||
:header-height @header-height
|
||||
:keyboard-shown? keyboard-shown?})]
|
||||
show-background? (show-background
|
||||
{:window-height window-height
|
||||
:footer-container-height @footer-container-height
|
||||
:keyboard-height @keyboard-height
|
||||
:content-scroll-y @content-scroll-y
|
||||
:content-container-height @content-container-height
|
||||
:header-height @header-height
|
||||
:keyboard-shown? keyboard-shown?})]
|
||||
[:<>
|
||||
(when gradient-cover?
|
||||
[quo/gradient-cover {:customization-color customization-color}])
|
||||
@@ -100,20 +108,28 @@
|
||||
{:on-layout set-header-height
|
||||
:style header-container-style}
|
||||
header]
|
||||
[gesture/scroll-view
|
||||
{:ref set-scroll-ref
|
||||
:on-scroll set-content-y-scroll
|
||||
:scroll-event-throttle 64
|
||||
:content-container-style {:flex-grow 1
|
||||
:padding-bottom (when @keyboard-did-show?
|
||||
@footer-container-height)}
|
||||
:always-bounce-vertical @keyboard-did-show?
|
||||
:shows-vertical-scroll-indicator false
|
||||
:keyboard-should-persist-taps keyboard-should-persist-taps}
|
||||
(into [rn/view
|
||||
{:style content-container-style
|
||||
:on-layout set-content-container-height}]
|
||||
children)]
|
||||
[(if content-avoid-keyboard? rn/keyboard-avoiding-view rn/view)
|
||||
{:style
|
||||
(if content-avoid-keyboard?
|
||||
(style/content-keyboard-avoiding-view
|
||||
{:top @header-height
|
||||
:bottom (if keyboard-shown?
|
||||
@footer-container-height
|
||||
(+ bottom-safe-area @footer-container-height))})
|
||||
style/scroll-view-container)}
|
||||
[gesture/scroll-view
|
||||
{:ref set-scroll-ref
|
||||
:on-scroll set-content-y-scroll
|
||||
:scroll-event-throttle 64
|
||||
:content-container-style {:flex-grow 1}
|
||||
:always-bounce-vertical @keyboard-did-show?
|
||||
:automatically-adjust-keyboard-insets true
|
||||
:shows-vertical-scroll-indicator false
|
||||
:keyboard-should-persist-taps keyboard-should-persist-taps}
|
||||
(into [rn/view
|
||||
{:style content-container-style
|
||||
:on-layout set-content-container-height}]
|
||||
children)]]
|
||||
[rn/keyboard-avoiding-view
|
||||
{:style style/keyboard-avoiding-view
|
||||
:keyboard-vertical-offset (if platform/ios? footer-container-padding 0)
|
||||
@@ -121,8 +137,9 @@
|
||||
[floating-container/view
|
||||
{:on-layout set-footer-container-height
|
||||
:keyboard-shown? keyboard-shown?
|
||||
:blur? show-background?
|
||||
:shell-overlay? shell-overlay?}
|
||||
:blur-options blur-options
|
||||
:shell-overlay? shell-overlay?
|
||||
:blur? show-background?}
|
||||
footer]]]])
|
||||
(finally
|
||||
(remove-listeners))))
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
{:dispatch (if user-in-sign-in-intro-screen?
|
||||
[:navigate-to-within-stack
|
||||
[:screen/onboarding.syncing-progress-intro :screen/onboarding.sign-in-intro]]
|
||||
[:navigate-to :screen/onboarding.syncing-progress])}
|
||||
[:open-modal :screen/onboarding.syncing-progress])}
|
||||
|
||||
(and completed-pairing? sender?)
|
||||
{:dispatch [:syncing/clear-states]}
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
:welcome-illustration (js/require "../resources/images/ui2/welcome_illustration.png")
|
||||
:notifications (js/require "../resources/images/ui2/notifications.png")
|
||||
:nfc-prompt (js/require "../resources/images/ui2/nfc-prompt.png")
|
||||
:nfc-success (js/require "../resources/images/ui2/nfc-success.png")})
|
||||
:nfc-success (js/require "../resources/images/ui2/nfc-success.png")
|
||||
:syncing-devices (js/require "../resources/images/ui2/syncing_devices.png")
|
||||
:syncing-wrong (js/require "../resources/images/ui2/syncing_wrong.png")})
|
||||
|
||||
(def ui-themed
|
||||
{:angry-man
|
||||
|
||||
@@ -38,6 +38,15 @@
|
||||
"wallet"
|
||||
{:fx [[:dispatch [:wallet/signal-received event-js]]]}
|
||||
|
||||
"wallet.sign.transactions"
|
||||
{:fx [[:dispatch
|
||||
[:standard-auth/authorize-with-keycard
|
||||
{:on-complete #(rf/dispatch [:keycard/sign-hash %
|
||||
(first (transforms/js->clj event-js))])}]]]}
|
||||
|
||||
"wallet.suggested.routes"
|
||||
{:fx [[:dispatch [:wallet/handle-suggested-routes (transforms/js->clj event-js)]]]}
|
||||
|
||||
"envelope.sent"
|
||||
(messages.transport/update-envelopes-status
|
||||
cofx
|
||||
|
||||
@@ -3,21 +3,35 @@
|
||||
[schema.core :as schema]
|
||||
[status-im.common.standard-authentication.enter-password.view :as enter-password]
|
||||
[status-im.common.standard-authentication.events-schema :as events-schema]
|
||||
[status-im.contexts.keycard.pin.view :as keycard.pin]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/reg-fx :effects.keycard/call-on-auth-success
|
||||
(fn [on-auth-success]
|
||||
(when on-auth-success (on-auth-success ""))))
|
||||
|
||||
(defn authorize
|
||||
[{:keys [db]} [args]]
|
||||
[{:keys [db]} [{:keys [on-auth-success keycard-supported?] :as args}]]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])
|
||||
keycard? (get-in db [:profile/profile :keycard-pairing])]
|
||||
{:fx [[:effects.biometric/check-if-available
|
||||
{:key-uid key-uid
|
||||
:on-success #(rf/dispatch [:standard-auth/authorize-with-biometric args])
|
||||
:on-fail (if keycard?
|
||||
#(rf/dispatch [:standard-auth/authorize-with-keycard args])
|
||||
#(rf/dispatch [:standard-auth/authorize-with-password args]))}]]}))
|
||||
{:fx
|
||||
[(if keycard?
|
||||
(if keycard-supported?
|
||||
[:effects.keycard/call-on-auth-success on-auth-success]
|
||||
[:effects.utils/show-popup
|
||||
{:title "This feature is not supported yet "
|
||||
:content
|
||||
"Keycard support is limited to logging in
|
||||
and signing the sending transaction.
|
||||
Use Status Desktop to access all functions."}])
|
||||
[:effects.biometric/check-if-available
|
||||
{:key-uid key-uid
|
||||
:on-success #(rf/dispatch [:standard-auth/authorize-with-biometric args])
|
||||
:on-fail #(rf/dispatch [:standard-auth/authorize-with-password args])}])]}))
|
||||
|
||||
(schema/=> authorize events-schema/?authorize)
|
||||
(rf/reg-event-fx :standard-auth/authorize authorize)
|
||||
@@ -94,6 +108,16 @@
|
||||
:button-icon-left auth-button-icon-left
|
||||
:button-label auth-button-label}])))
|
||||
|
||||
(defn authorize-with-keycard
|
||||
[_ [{:keys [on-complete]}]]
|
||||
{:fx [[:dispatch
|
||||
[:show-bottom-sheet
|
||||
{:hide-on-background-press? false
|
||||
:on-close #(rf/dispatch [:standard-auth/reset-login-password])
|
||||
:content (fn []
|
||||
[keycard.pin/auth {:on-complete on-complete}])}]]]})
|
||||
(rf/reg-event-fx :standard-auth/authorize-with-keycard authorize-with-keycard)
|
||||
|
||||
(defn authorize-with-password
|
||||
[_ [{:keys [on-close theme blur?] :as args}]]
|
||||
{:fx [[:dispatch [:standard-auth/reset-login-password]]
|
||||
@@ -110,7 +134,9 @@
|
||||
(rf/reg-event-fx
|
||||
:standard-auth/reset-login-password
|
||||
(fn [{:keys [db]}]
|
||||
{:db (update db :profile/login dissoc :password :error)}))
|
||||
{:db (-> db
|
||||
(update :profile/login dissoc :password :error)
|
||||
(update :keycard dissoc :pin))}))
|
||||
|
||||
(rf/reg-fx
|
||||
:standard-auth/on-close
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
(defn view
|
||||
[{:keys [track-text customization-color auth-button-label on-auth-success on-auth-fail
|
||||
auth-button-icon-left size blur? container-style disabled? dependencies]
|
||||
auth-button-icon-left size blur? container-style disabled? dependencies keycard-supported?]
|
||||
:or {container-style {:flex 1}}}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
auth-method (rf/sub [:auth-method])
|
||||
@@ -21,6 +21,7 @@
|
||||
:auth-button-icon-left auth-button-icon-left
|
||||
:theme theme
|
||||
:blur? blur?
|
||||
:keycard-supported? keycard-supported?
|
||||
:biometric-auth? biometric-auth?
|
||||
:on-auth-success on-auth-success
|
||||
:on-auth-fail on-auth-fail
|
||||
|
||||
@@ -291,6 +291,7 @@
|
||||
(def ^:const wallet-connect-session-delete-event "session_delete")
|
||||
(def ^:const wallet-connect-user-rejected-error-key "USER_REJECTED")
|
||||
(def ^:const wallet-connect-user-disconnected-reason-key "USER_DISCONNECTED")
|
||||
(def ^:const wallet-connect-user-rejected-chains-error-key "USER_REJECTED_CHAINS")
|
||||
|
||||
(def ^:const transaction-pending-type-wallet-connect-transfer "WalletConnectTransfer")
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
item])))))
|
||||
|
||||
(defn add-manage-members
|
||||
[{:keys [scroll-enabled? on-scroll]}]
|
||||
[{:keys [on-scroll]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
selected-participants (rf/sub [:group-chat/selected-participants])
|
||||
deselected-members (rf/sub [:group-chat/deselected-members])
|
||||
@@ -71,7 +71,6 @@
|
||||
(i18n/label (if admin? :t/manage-members :t/add-members))]
|
||||
[gesture/section-list
|
||||
{:key-fn :title
|
||||
:scroll-enabled @scroll-enabled?
|
||||
:on-scroll on-scroll
|
||||
:sticky-section-headers-enabled false
|
||||
:sections (rf/sub [:contacts/grouped-by-first-letter])
|
||||
|
||||
@@ -33,3 +33,7 @@
|
||||
(def drawer-message-container
|
||||
{:padding-top 4
|
||||
:padding-bottom 4})
|
||||
|
||||
(def group-member-mention
|
||||
{:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
@@ -126,14 +126,60 @@
|
||||
:photo-path photo-path
|
||||
:incoming? (not= public-key from)}]))
|
||||
|
||||
(defn group-member
|
||||
[literal]
|
||||
(let [[primary-name _] (rf/sub [:contacts/contact-two-names-by-identity literal])
|
||||
photo-path (rf/sub [:chats/photo-path literal])]
|
||||
[rn/view {:style style/group-member-mention}
|
||||
[quo/user-avatar
|
||||
{:full-name primary-name
|
||||
:profile-picture photo-path
|
||||
:status-indicator? false
|
||||
:size :xxxs
|
||||
:ring? false}]
|
||||
[quo/text
|
||||
{:weight :semi-bold
|
||||
:style {:margin-left 4}}
|
||||
primary-name]]))
|
||||
|
||||
|
||||
(defn resolve-group-system-message
|
||||
[{:keys [children]}]
|
||||
(reduce (fn [acc {:keys [type literal]}]
|
||||
(if (= type "mention")
|
||||
(conj acc [group-member literal])
|
||||
(conj acc
|
||||
[rn/view
|
||||
[quo/text literal]])))
|
||||
[:<>]
|
||||
children))
|
||||
|
||||
|
||||
(defn render-parsed-text
|
||||
[content]
|
||||
(reduce (fn [acc e]
|
||||
(conj acc (resolve-group-system-message e)))
|
||||
[quo/text]
|
||||
(:parsed-text content)))
|
||||
|
||||
(defn group-system-message
|
||||
[{:keys [chat-id timestamp-str content]} type]
|
||||
(let [{:keys [customization-color]} (rf/sub [:contacts/contact-by-address chat-id])]
|
||||
[quo/system-message
|
||||
{:type type
|
||||
:timestamp timestamp-str
|
||||
:customization-color customization-color
|
||||
:child (render-parsed-text content)}]))
|
||||
|
||||
(defn system-message-content
|
||||
[{:keys [content-type quoted-message] :as message-data}]
|
||||
|
||||
(if quoted-message
|
||||
[pin/pinned-message message-data]
|
||||
(condp = content-type
|
||||
|
||||
constants/content-type-system-text
|
||||
[system.text/text-content message-data]
|
||||
[group-system-message message-data :group]
|
||||
|
||||
constants/content-type-system-pinned-message
|
||||
[system.text/text-content message-data]
|
||||
|
||||
@@ -109,3 +109,22 @@
|
||||
[pairings]
|
||||
(keycard/set-pairings pairings))
|
||||
(rf/reg-fx :effects.keycard/set-pairing-to-keycard set-pairing-to-keycard)
|
||||
|
||||
(defn sign
|
||||
[{:keys [on-success on-failure] :as args}]
|
||||
(log/debug "[keycard] sign")
|
||||
(keycard/sign
|
||||
(assoc
|
||||
args
|
||||
:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] sign")
|
||||
(when on-success
|
||||
(on-success (transforms/js->clj response))))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/warn "[keycard response fail] sign"
|
||||
(error-object->map response))
|
||||
(when on-failure
|
||||
(on-failure (error-object->map response)))))))
|
||||
(rf/reg-fx :effects.keycard/sign sign)
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
status-im.contexts.keycard.login.events
|
||||
status-im.contexts.keycard.pin.events
|
||||
status-im.contexts.keycard.sheet.events
|
||||
status-im.contexts.keycard.sign.events
|
||||
[status-im.contexts.keycard.utils :as keycard.utils]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(rf/reg-event-fx :keycard/on-check-nfc-enabled-success
|
||||
@@ -55,3 +57,19 @@
|
||||
(fn [{:keys [db]} [{:keys [on-cancel-event-vector]}]]
|
||||
(log/debug "[keycard] nfc started success")
|
||||
{:db (assoc-in db [:keycard :on-nfc-cancelled-event-vector] on-cancel-event-vector)}))
|
||||
|
||||
(rf/reg-event-fx :keycard/on-action-with-pin-error
|
||||
(fn [{:keys [db]} [error]]
|
||||
(log/debug "[keycard] get keys error: " error)
|
||||
(let [tag-was-lost? (keycard.utils/tag-lost? (:error error))
|
||||
pin-retries-count (keycard.utils/pin-retries (:error error))]
|
||||
(if tag-was-lost?
|
||||
{:db (assoc-in db [:keycard :pin :status] nil)}
|
||||
(if (nil? pin-retries-count)
|
||||
{:effects.utils/show-popup {:title "wrong-keycard"}}
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries-count)
|
||||
(update-in [:keycard :pin] assoc :status :error))
|
||||
:fx [[:dispatch [:keycard/hide-connection-sheet]]
|
||||
(when (zero? pin-retries-count)
|
||||
[:effects.utils/show-popup {:title "frozen-keycard"}])]})))))
|
||||
|
||||
@@ -3,22 +3,6 @@
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/reg-event-fx :keycard.login/on-get-keys-error
|
||||
(fn [{:keys [db]} [error]]
|
||||
(log/debug "[keycard] get keys error: " error)
|
||||
(let [tag-was-lost? (keycard.utils/tag-lost? (:error error))
|
||||
pin-retries-count (keycard.utils/pin-retries (:error error))]
|
||||
(if tag-was-lost?
|
||||
{:db (assoc-in db [:keycard :pin :status] nil)}
|
||||
(if (nil? pin-retries-count)
|
||||
{:effects.utils/show-popup {:title "wrong-keycard"}}
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries-count)
|
||||
(update-in [:keycard :pin] assoc :status :error))
|
||||
:fx [[:dispatch [:keycard/hide-connection-sheet]]
|
||||
(when (zero? pin-retries-count)
|
||||
[:effects.utils/show-popup {:title "frozen-keycard"}])]})))))
|
||||
|
||||
(rf/reg-event-fx :keycard.login/on-get-keys-success
|
||||
(fn [{:keys [db]} [data]]
|
||||
(let [{:keys [key-uid encryption-public-key
|
||||
@@ -56,28 +40,25 @@
|
||||
:key-uid key-uid}]]}))))
|
||||
|
||||
(rf/reg-event-fx :keycard.login/on-get-application-info-success
|
||||
(fn [{:keys [db]} [application-info]]
|
||||
(let [profile (get-in db [:profile/profiles-overview (get-in db [:profile/login :key-uid])])
|
||||
pin (get-in db [:keycard :pin :text])
|
||||
error (keycard.utils/validate-application-info profile application-info)]
|
||||
(fn [{:keys [db]} [application-info {:keys [key-uid on-read-fx]}]]
|
||||
(let [error (keycard.utils/validate-application-info key-uid application-info)]
|
||||
(if error
|
||||
{:effects.utils/show-popup {:title (str error)}}
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :application-info] application-info)
|
||||
(assoc-in [:keycard :pin :status] :verifying))
|
||||
:effects.keycard/get-keys {:pin pin
|
||||
:on-success #(rf/dispatch [:keycard.login/on-get-keys-success %])
|
||||
:on-failure #(rf/dispatch [:keycard.login/on-get-keys-error %])}}))))
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :application-info] application-info)
|
||||
(assoc-in [:keycard :pin :status] :verifying))
|
||||
:fx on-read-fx}))))
|
||||
|
||||
(rf/reg-event-fx :keycard.login/cancel-reading-card
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc-in db [:keycard :on-card-connected-event-vector] nil)}))
|
||||
|
||||
(rf/reg-event-fx :keycard/read-card-and-login
|
||||
(fn [{:keys [db]}]
|
||||
(rf/reg-event-fx :keycard/read-card
|
||||
(fn [{:keys [db]} [args]]
|
||||
(let [connected? (get-in db [:keycard :card-connected?])
|
||||
event-vector [:keycard/get-application-info
|
||||
{:on-success #(rf/dispatch [:keycard.login/on-get-application-info-success %])}]]
|
||||
{:on-success #(rf/dispatch [:keycard.login/on-get-application-info-success %
|
||||
args])}]]
|
||||
(log/debug "[keycard] proceed-to-login")
|
||||
{:db (assoc-in db [:keycard :on-card-connected-event-vector] event-vector)
|
||||
:fx [[:dispatch
|
||||
|
||||
@@ -9,13 +9,17 @@
|
||||
(assoc-in [:keycard :pin :text] (.slice pin 0 -1))
|
||||
(assoc-in [:keycard :pin :status] nil))}))))
|
||||
|
||||
(rf/reg-fx :effects.keycard.pin/dispatch-on-complete
|
||||
(fn [[on-complete new-pin]]
|
||||
(on-complete new-pin)))
|
||||
|
||||
(rf/reg-event-fx :keycard.pin/number-pressed
|
||||
(fn [{:keys [db]} [number max-numbers on-complete-event]]
|
||||
(fn [{:keys [db]} [number max-numbers on-complete]]
|
||||
(let [pin (get-in db [:keycard :pin :text])
|
||||
new-pin (str pin number)]
|
||||
(when (<= (count new-pin) max-numbers)
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :pin :text] new-pin)
|
||||
(assoc-in [:keycard :pin :status] nil))
|
||||
:fx [(when (= (dec max-numbers) (count pin))
|
||||
[:dispatch [on-complete-event]])]}))))
|
||||
:fx [(when (and on-complete (= (dec max-numbers) (count pin)))
|
||||
[:effects.keycard.pin/dispatch-on-complete [on-complete new-pin]])]}))))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn auth
|
||||
[callback-event-key]
|
||||
[{:keys [on-complete]}]
|
||||
(let [{:keys [text status]} (rf/sub [:keycard/pin])
|
||||
pin-retry-counter (rf/sub [:keycard/pin-retry-counter])
|
||||
error? (= status :error)]
|
||||
@@ -23,4 +23,4 @@
|
||||
{:delete-key? true
|
||||
:on-delete #(rf/dispatch [:keycard.pin/delete-pressed])
|
||||
:on-press #(rf/dispatch [:keycard.pin/number-pressed % constants/pincode-length
|
||||
callback-event-key])}]]))
|
||||
on-complete])}]]))
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
(ns status-im.contexts.keycard.sign.events
|
||||
(:require [utils.address]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn get-signature-map
|
||||
[tx-hash signature]
|
||||
{tx-hash {:r (subs signature 0 64)
|
||||
:s (subs signature 64 128)
|
||||
:v (str (js/parseInt (subs signature 128 130) 16))}})
|
||||
|
||||
(rf/reg-event-fx :keycard/sign-hash
|
||||
(fn [{:keys [db]} [pin-text tx-hash]]
|
||||
(let [current-address (get-in db [:wallet :current-viewing-account-address])
|
||||
path (get-in db [:wallet :accounts current-address :path])
|
||||
key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{:fx [[:dispatch
|
||||
[:keycard/read-card
|
||||
{:key-uid key-uid
|
||||
:on-read-fx [[:effects.keycard/sign
|
||||
{:pin pin-text
|
||||
:path path
|
||||
:hash (utils.address/naked-address tx-hash)
|
||||
:on-success
|
||||
#(do
|
||||
(rf/dispatch [:keycard/hide-connection-sheet])
|
||||
(rf/dispatch
|
||||
[:wallet/proceed-with-transactions-signatures
|
||||
(get-signature-map tx-hash %)]))
|
||||
:on-failure #(rf/dispatch [:keycard/on-action-with-pin-error %])}]]}]]]})))
|
||||
@@ -16,8 +16,8 @@
|
||||
(re-matches #".*NFCError:100.*" error)))
|
||||
|
||||
(defn validate-application-info
|
||||
[profile {:keys [key-uid paired? pin-retry-counter puk-retry-counter] :as application-info}]
|
||||
(let [profile-mismatch? (or (nil? profile) (not= (:key-uid profile) key-uid))]
|
||||
[profile-key-uid {:keys [key-uid paired? pin-retry-counter puk-retry-counter] :as application-info}]
|
||||
(let [profile-mismatch? (or (nil? profile-key-uid) (not= profile-key-uid key-uid))]
|
||||
(log/debug "[keycard] login-with-keycard"
|
||||
"empty application info" (empty? application-info)
|
||||
"no key-uid" (empty? key-uid)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(def flex-fill {:flex 1})
|
||||
|
||||
(def heading {:margin-bottom 20})
|
||||
(def heading-subtitle {:color colors/white})
|
||||
(def heading-title (assoc heading-subtitle :margin-bottom 8))
|
||||
@@ -14,23 +12,15 @@
|
||||
(def space-between-inputs {:height 16})
|
||||
|
||||
(def password-tips
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:margin-horizontal 20})
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:padding-horizontal 20})
|
||||
|
||||
(def top-part
|
||||
{:margin-horizontal 20
|
||||
:margin-top 12})
|
||||
(def form-container
|
||||
{:justify-content :space-between
|
||||
:padding-top 12
|
||||
:padding-horizontal 20})
|
||||
|
||||
(def bottom-part
|
||||
{:flex 1
|
||||
:margin-top 12
|
||||
:justify-content :flex-end})
|
||||
|
||||
(def disclaimer-container
|
||||
{:margin-horizontal 20
|
||||
:margin-vertical 4})
|
||||
|
||||
(def button-container
|
||||
{:margin-horizontal 20
|
||||
:margin-vertical 12})
|
||||
(def disclaimer-container {:padding-horizontal 20})
|
||||
(def footer-container {:padding-bottom 12})
|
||||
(def footer-button-container {:margin-top 20 :padding-horizontal 20})
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
(ns status-im.contexts.onboarding.create-password.view
|
||||
(:require
|
||||
[oops.core :refer [ocall]]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.common.floating-button-page.view :as floating-button]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.onboarding.create-password.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
@@ -94,7 +94,7 @@
|
||||
[quo/tips {:completed? symbols?}
|
||||
(i18n/label :t/password-creation-tips-4)]]])
|
||||
|
||||
(defn password-validations
|
||||
(defn validate-password
|
||||
[password]
|
||||
(let [validations (juxt utils.string/has-lower-case?
|
||||
utils.string/has-upper-case?
|
||||
@@ -111,68 +111,25 @@
|
||||
(filter true?)
|
||||
count))
|
||||
|
||||
(defn password-form
|
||||
[]
|
||||
(let [password (reagent/atom "")
|
||||
repeat-password (reagent/atom "")
|
||||
accepts-disclaimer? (reagent/atom false)
|
||||
focused-input (reagent/atom nil)
|
||||
show-password-validation? (reagent/atom false)
|
||||
same-password-length? #(and (seq @password)
|
||||
(= (count @password) (count @repeat-password)))]
|
||||
(fn []
|
||||
(let [{user-color :color} (rf/sub [:onboarding/profile])
|
||||
{:keys [long-enough?]
|
||||
:as validations} (password-validations @password)
|
||||
password-strength (calc-password-strength validations)
|
||||
empty-password? (empty? @password)
|
||||
same-passwords? (and (not empty-password?) (= @password @repeat-password))
|
||||
meet-requirements? (and (not empty-password?)
|
||||
(utils.string/at-least-n-chars? @password 10)
|
||||
same-passwords?
|
||||
@accepts-disclaimer?)]
|
||||
[:<>
|
||||
[rn/view {:style style/top-part}
|
||||
[header]
|
||||
[password-inputs
|
||||
{:password-long-enough? long-enough?
|
||||
:passwords-match? same-passwords?
|
||||
:empty-password? empty-password?
|
||||
:show-password-validation? @show-password-validation?
|
||||
:on-input-focus #(reset! focused-input :password)
|
||||
:on-change-password (fn [new-value]
|
||||
(reset! password new-value)
|
||||
(when (same-password-length?)
|
||||
(reset! show-password-validation? true)))
|
||||
:on-change-repeat-password (fn [new-value]
|
||||
(reset! repeat-password new-value)
|
||||
(when (same-password-length?)
|
||||
(reset! show-password-validation? true)))
|
||||
:on-blur-repeat-password #(if empty-password?
|
||||
(reset! show-password-validation? false)
|
||||
(reset! show-password-validation? true))}]]
|
||||
(defn- use-password-checks
|
||||
[password]
|
||||
(rn/use-memo
|
||||
(fn []
|
||||
(let [{:keys [long-enough?]
|
||||
:as validations} (validate-password password)]
|
||||
{:password-long-enough? long-enough?
|
||||
:password-validations validations
|
||||
:password-strength (calc-password-strength validations)
|
||||
:empty-password? (empty? password)}))
|
||||
[password]))
|
||||
|
||||
[rn/view {:style style/bottom-part}
|
||||
(when same-passwords?
|
||||
[rn/view {:style style/disclaimer-container}
|
||||
[quo/disclaimer
|
||||
{:blur? true
|
||||
:on-change #(swap! accepts-disclaimer? not)
|
||||
:checked? @accepts-disclaimer?}
|
||||
(i18n/label :t/password-creation-disclaimer)]])
|
||||
(when (and (= @focused-input :password) (not same-passwords?))
|
||||
[help
|
||||
{:validations validations
|
||||
:password-strength password-strength}])
|
||||
|
||||
[rn/view {:style style/button-container}
|
||||
[quo/button
|
||||
{:disabled? (not meet-requirements?)
|
||||
:customization-color user-color
|
||||
:on-press #(rf/dispatch
|
||||
[:onboarding/password-set
|
||||
(security/mask-data @password)])}
|
||||
(i18n/label :t/password-creation-confirm)]]]]))))
|
||||
(defn- use-repeat-password-checks
|
||||
[password repeat-password]
|
||||
(rn/use-memo
|
||||
(fn []
|
||||
{:same-password-length? (and (seq password) (= (count password) (count repeat-password)))
|
||||
:same-passwords? (and (seq password) (= password repeat-password))})
|
||||
[password repeat-password]))
|
||||
|
||||
(defn create-password-doc
|
||||
[]
|
||||
@@ -183,38 +140,108 @@
|
||||
[quo/text {:size :paragraph-2}
|
||||
(i18n/label :t/create-profile-password-info-box-description)]]])
|
||||
|
||||
(defn- on-press-info
|
||||
[]
|
||||
(rn/dismiss-keyboard!)
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content create-password-doc
|
||||
:shell? true}]))
|
||||
|
||||
(defn- navigate-back
|
||||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn- page-nav
|
||||
[]
|
||||
(let [{:keys [top]} (safe-area/get-insets)]
|
||||
[quo/page-nav
|
||||
{:margin-top top
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press navigate-back
|
||||
:right-side [{:icon-name :i/info
|
||||
:on-press on-press-info}]}]))
|
||||
|
||||
(defn create-password
|
||||
[]
|
||||
(reagent/with-let [keyboard-shown? (reagent/atom false)
|
||||
{:keys [top bottom]} (safe-area/get-insets)
|
||||
will-show-listener (ocall rn/keyboard
|
||||
"addListener"
|
||||
"keyboardWillShow"
|
||||
#(reset! keyboard-shown? true))
|
||||
will-hide-listener (ocall rn/keyboard
|
||||
"addListener"
|
||||
"keyboardWillHide"
|
||||
#(reset! keyboard-shown? false))
|
||||
on-press-info (fn []
|
||||
(rn/dismiss-keyboard!)
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content create-password-doc
|
||||
:shell? true}]))]
|
||||
[:<>
|
||||
[rn/touchable-without-feedback
|
||||
{:on-press rn/dismiss-keyboard!
|
||||
:accessible false}
|
||||
[rn/view {:style style/flex-fill}
|
||||
[rn/keyboard-avoiding-view {:style style/flex-fill}
|
||||
[quo/page-nav
|
||||
{:margin-top top
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:right-side [{:icon-name :i/info
|
||||
:on-press on-press-info}]}]
|
||||
[password-form]
|
||||
[rn/view {:style {:height (if-not @keyboard-shown? bottom 0)}}]]]]]
|
||||
(finally
|
||||
(ocall will-show-listener "remove")
|
||||
(ocall will-hide-listener "remove"))))
|
||||
(let [[password set-password] (rn/use-state "")
|
||||
[repeat-password set-repeat-password] (rn/use-state "")
|
||||
[accepts-disclaimer? set-accepts-disclaimer?] (rn/use-state false)
|
||||
[focused-input set-focused-input] (rn/use-state nil)
|
||||
[show-password-validation?
|
||||
set-show-password-validation?] (rn/use-state false)
|
||||
{user-color :color} (rf/sub [:onboarding/profile])
|
||||
|
||||
|
||||
{:keys [password-long-enough?
|
||||
password-validations password-strength
|
||||
empty-password?]} (use-password-checks password)
|
||||
|
||||
{:keys [same-password-length? same-passwords?]} (use-repeat-password-checks password
|
||||
repeat-password)
|
||||
|
||||
meet-requirements? (rn/use-memo
|
||||
#(and (not empty-password?)
|
||||
(utils.string/at-least-n-chars? password
|
||||
10)
|
||||
same-passwords?
|
||||
accepts-disclaimer?)
|
||||
[password repeat-password
|
||||
accepts-disclaimer?])]
|
||||
|
||||
[floating-button/view
|
||||
{:header [page-nav]
|
||||
:keyboard-should-persist-taps :handled
|
||||
:content-avoid-keyboard? true
|
||||
:blur-options
|
||||
{:blur-amount 34
|
||||
:blur-radius 20
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent
|
||||
:background-color (if platform/android? colors/neutral-100 colors/neutral-80-opa-1-blur)
|
||||
:padding-vertical 0
|
||||
:padding-horizontal 0}
|
||||
:footer-container-padding 0
|
||||
:footer
|
||||
[rn/view
|
||||
{:style style/footer-container}
|
||||
(when same-passwords?
|
||||
[rn/view {:style style/disclaimer-container}
|
||||
[quo/disclaimer
|
||||
{:blur? true
|
||||
:on-change (partial set-accepts-disclaimer? not)
|
||||
:checked? accepts-disclaimer?}
|
||||
(i18n/label :t/password-creation-disclaimer)]])
|
||||
(when (and (= focused-input :password) (not same-passwords?))
|
||||
[help
|
||||
{:validations password-validations
|
||||
:password-strength password-strength}])
|
||||
[quo/button
|
||||
{:container-style style/footer-button-container
|
||||
:disabled? (not meet-requirements?)
|
||||
:customization-color user-color
|
||||
:on-press #(rf/dispatch
|
||||
[:onboarding/password-set
|
||||
(security/mask-data password)])}
|
||||
(i18n/label :t/password-creation-confirm)]]}
|
||||
|
||||
[rn/view {:style style/form-container}
|
||||
[header]
|
||||
[password-inputs
|
||||
{:password-long-enough? password-long-enough?
|
||||
:passwords-match? same-passwords?
|
||||
:empty-password? empty-password?
|
||||
:show-password-validation? show-password-validation?
|
||||
:on-input-focus #(set-focused-input :password)
|
||||
:on-change-password (fn [new-value]
|
||||
(set-password new-value)
|
||||
(when same-password-length?
|
||||
(set-show-password-validation? true)))
|
||||
|
||||
:on-change-repeat-password (fn [new-value]
|
||||
(set-repeat-password new-value)
|
||||
(when same-password-length?
|
||||
(set-show-password-validation? true)))
|
||||
:on-blur-repeat-password #(if empty-password?
|
||||
(set-show-password-validation? false)
|
||||
(set-show-password-validation? true))}]]]))
|
||||
|
||||
@@ -20,14 +20,13 @@
|
||||
:padding-bottom 20
|
||||
:background-color (when-not in-onboarding? colors/neutral-80-opa-80-blur)})
|
||||
|
||||
(def page-illustration
|
||||
{:flex 1
|
||||
:background-color colors/danger-50
|
||||
:align-items :center
|
||||
:margin-horizontal 20
|
||||
:border-radius 20
|
||||
:margin-top 20
|
||||
:justify-content :center})
|
||||
(defn page-illustration
|
||||
[width]
|
||||
{:flex 1
|
||||
:width width
|
||||
:align-items :center
|
||||
:align-self :center
|
||||
:justify-content :center})
|
||||
|
||||
(def try-again-button
|
||||
{:margin-top 20
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.config :as config]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.contexts.onboarding.common.background.view :as background]
|
||||
[status-im.contexts.onboarding.syncing.progress.style :as style]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -27,45 +26,39 @@
|
||||
:description-accessibility-label :progress-screen-sub-title}])
|
||||
|
||||
(defn try-again-button
|
||||
[profile-color in-onboarding? logged-in?]
|
||||
[profile-color]
|
||||
[quo/button
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:syncing/clear-states])
|
||||
(cond
|
||||
logged-in? (rf/dispatch [:navigate-back])
|
||||
in-onboarding? (rf/dispatch [:navigate-back-to
|
||||
:screen/onboarding.sign-in-intro])
|
||||
:else (do
|
||||
(rf/dispatch [:navigate-back])
|
||||
(debounce/throttle-and-dispatch
|
||||
[:open-modal
|
||||
:screen/onboarding.sign-in]
|
||||
1000))))
|
||||
(rf/dispatch [:navigate-back]))
|
||||
:accessibility-label :try-again-later-button
|
||||
:customization-color profile-color
|
||||
:size 40
|
||||
:container-style style/try-again-button}
|
||||
(i18n/label :t/try-again)])
|
||||
|
||||
(defn- illustration
|
||||
[pairing-progress?]
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:style (style/page-illustration (:width (rn/get-window)))
|
||||
:source (resources/get-image (if pairing-progress? :syncing-devices :syncing-wrong))}])
|
||||
|
||||
(defn view
|
||||
[in-onboarding?]
|
||||
(let [pairing-status (rf/sub [:pairing/pairing-status])
|
||||
profile-color (:color (rf/sub [:onboarding/profile]))
|
||||
logged-in? (rf/sub [:multiaccount/logged-in?])]
|
||||
(let [pairing-status (rf/sub [:pairing/pairing-status])
|
||||
pairing-progress? (pairing-progress pairing-status)
|
||||
profile-color (or (:color (rf/sub [:onboarding/profile]))
|
||||
(rf/sub [:profile/customization-color]))]
|
||||
[rn/view {:style (style/page-container in-onboarding?)}
|
||||
(when-not in-onboarding?
|
||||
[rn/view {:style style/absolute-fill}
|
||||
[background/view true]])
|
||||
[quo/page-nav {:type :no-title :background :blur}]
|
||||
[page-title (pairing-progress pairing-status)]
|
||||
(if config/show-not-implemented-features?
|
||||
(if (pairing-progress pairing-status)
|
||||
[rn/view {:style style/page-illustration}
|
||||
[quo/text "[Success here]"]]
|
||||
[rn/view {:style style/page-illustration}
|
||||
[quo/text "[Error here]"]])
|
||||
[rn/view {:flex 1}])
|
||||
[page-title pairing-progress?]
|
||||
[illustration pairing-progress?]
|
||||
(when-not (pairing-progress pairing-status)
|
||||
[try-again-button profile-color in-onboarding? logged-in?])]))
|
||||
[try-again-button profile-color])]))
|
||||
|
||||
(defn view-onboarding
|
||||
[]
|
||||
|
||||
@@ -239,7 +239,16 @@
|
||||
:profile-picture profile-picture
|
||||
:card-style style/login-profile-card}]
|
||||
(if keycard-pairing
|
||||
[keycard.pin/auth :keycard/read-card-and-login]
|
||||
[keycard.pin/auth
|
||||
{:on-complete
|
||||
(fn [pin-text]
|
||||
(rf/dispatch
|
||||
[:keycard/read-card
|
||||
{:key-uid key-uid
|
||||
:on-read-fx [[:effects.keycard/get-keys
|
||||
{:pin pin-text
|
||||
:on-success #(rf/dispatch [:keycard.login/on-get-keys-success %])
|
||||
:on-failure #(rf/dispatch [:keycard/on-action-with-pin-error %])}]]}]))}]
|
||||
[password-input])]
|
||||
(when-not keycard-pairing
|
||||
[quo/button
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
[]
|
||||
(let [compressed-key (rf/sub [:profile/compressed-key])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
keypairs (rf/sub [:wallet/keypairs-list])
|
||||
keypairs (rf/sub [:wallet/fully-operable-keypairs-list])
|
||||
selected-keypair (rf/sub [:wallet/selected-keypair-uid])
|
||||
profile-picture (rf/sub [:profile/image])
|
||||
[selected-key-uid set-selected-key-uid] (rn/use-state selected-keypair)]
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(hot-reload/use-safe-unmount #(rf/dispatch [:wallet/clean-routes-calculation]))
|
||||
(hot-reload/use-safe-unmount #(rf/dispatch [:wallet/stop-get-suggested-routes]))
|
||||
[rn/view {:style style/bridge-send-wrapper}
|
||||
[input-amount/view
|
||||
{:current-screen-id :screen/wallet.bridge-input-amount
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
(not watch-only?))
|
||||
{:icon-name :i/dapps
|
||||
:on-press #(rf/dispatch [:navigate-to :screen/wallet.connected-dapps])})
|
||||
|
||||
{:content-type :account-switcher
|
||||
:customization-color color
|
||||
:on-press #(on-dapps-press switcher-type)
|
||||
|
||||
@@ -84,10 +84,10 @@
|
||||
[]
|
||||
(let [{:keys [bottom]} (safe-area/get-insets)
|
||||
{:keys [color] :as wallet-account} (rf/sub [:wallet/current-viewing-account])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
sessions (rf/sub
|
||||
[:wallet-connect/sessions-for-current-account])
|
||||
theme (quo.theme/use-theme)
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
[:wallet-connect/sessions-for-current-account-and-networks])
|
||||
theme (quo.theme/use-theme)]
|
||||
[rn/view {:flex 1}
|
||||
[header
|
||||
{:title (i18n/label :t/connected-dapps)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[clojure.string :as string]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||
[utils.collection :as utils.collection]
|
||||
[utils.money :as money]
|
||||
[utils.number :as utils.number]
|
||||
@@ -188,3 +189,77 @@
|
||||
:removed-account-addresses removed-account-addresses
|
||||
:updated-keypairs-by-id updated-keypairs-by-id
|
||||
:updated-accounts-by-address updated-accounts-by-address}))
|
||||
|
||||
(defn- rename-keys-to-kebab-case
|
||||
[m]
|
||||
(set/rename-keys m (zipmap (keys m) (map transforms/->kebab-case-keyword (keys m)))))
|
||||
|
||||
(defn rpc->suggested-routes
|
||||
[suggested-routes]
|
||||
(cond
|
||||
(map? suggested-routes)
|
||||
(into {}
|
||||
(for [[k v] (rename-keys-to-kebab-case suggested-routes)]
|
||||
[k (rpc->suggested-routes v)]))
|
||||
|
||||
(vector? suggested-routes)
|
||||
(map rpc->suggested-routes suggested-routes)
|
||||
|
||||
:else suggested-routes))
|
||||
|
||||
(def ^:private precision 6)
|
||||
|
||||
(defn new->old-route-path
|
||||
[new-path]
|
||||
(let [bonder-fees (:tx-bonder-fees new-path)
|
||||
token-fees (+ (money/wei->ether bonder-fees)
|
||||
(money/wei->ether
|
||||
(:tx-token-fees new-path)))]
|
||||
{:from (:from-chain new-path)
|
||||
:amount-in-locked (:amount-in-locked new-path)
|
||||
:amount-in (:amount-in new-path)
|
||||
:max-amount-in "0x0"
|
||||
: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)
|
||||
: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)
|
||||
:approval-required (:approval-required new-path)
|
||||
:estimated-time (:estimated-time new-path)
|
||||
:approval-gas-fees (* (money/wei->ether (get-in new-path
|
||||
[:suggested-levels-for-max-fees-per-gas
|
||||
:medium]))
|
||||
(:approval-gas-amount new-path))
|
||||
:to (:to-chain new-path)
|
||||
:bonder-fees bonder-fees
|
||||
:approval-amount-required (:approval-amount-required new-path)
|
||||
;; :cost () ;; tbd not used on desktop
|
||||
:token-fees token-fees
|
||||
:gas-amount (:tx-gas-amount new-path)}))
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
(ns status-im.contexts.wallet.send.events
|
||||
(:require
|
||||
[camel-snake-kebab.extras :as cske]
|
||||
[clojure.string :as string]
|
||||
[native-module.core :as native-module]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.collectible.utils :as collectible.utils]
|
||||
[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.utils :as send-utils]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address :as address]
|
||||
[utils.money :as money]
|
||||
[utils.number]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.transforms :as transforms]))
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/reg-event-fx :wallet/clean-send-data
|
||||
(fn [{:keys [db]}]
|
||||
@@ -24,86 +23,82 @@
|
||||
{:db (assoc-in db [:wallet :ui :send :select-address-tab] tab)}))
|
||||
|
||||
(rf/reg-event-fx :wallet/suggested-routes-success
|
||||
(fn [{:keys [db]} [suggested-routes timestamp]]
|
||||
(when (= (get-in db [:wallet :ui :send :suggested-routes-call-timestamp]) timestamp)
|
||||
(let [suggested-routes-data (cske/transform-keys transforms/->kebab-case-keyword
|
||||
suggested-routes)
|
||||
chosen-route (:best suggested-routes-data)
|
||||
token (get-in db [:wallet :ui :send :token])
|
||||
collectible (get-in db [:wallet :ui :send :collectible])
|
||||
token-display-name (get-in db [:wallet :ui :send :token-display-name])
|
||||
receiver-networks (get-in db [:wallet :ui :send :receiver-networks])
|
||||
receiver-network-values (get-in db [:wallet :ui :send :receiver-network-values])
|
||||
sender-network-values (get-in db [:wallet :ui :send :sender-network-values])
|
||||
tx-type (get-in db [:wallet :ui :send :tx-type])
|
||||
disabled-from-chain-ids (get-in db [:wallet :ui :send :disabled-from-chain-ids] [])
|
||||
from-locked-amounts (get-in db [:wallet :ui :send :from-locked-amounts] {})
|
||||
token-decimals (if collectible 0 (:decimals token))
|
||||
native-token? (and token (= token-display-name "ETH"))
|
||||
routes-available? (pos? (count chosen-route))
|
||||
token-networks (:networks token)
|
||||
token-networks-ids (when token-networks (mapv #(:chain-id %) token-networks))
|
||||
from-network-amounts-by-chain (send-utils/network-amounts-by-chain {:route chosen-route
|
||||
:token-decimals
|
||||
token-decimals
|
||||
:native-token?
|
||||
native-token?
|
||||
:receiver? false})
|
||||
from-network-values-for-ui (send-utils/network-values-for-ui from-network-amounts-by-chain)
|
||||
to-network-amounts-by-chain (send-utils/network-amounts-by-chain {:route chosen-route
|
||||
:token-decimals
|
||||
token-decimals
|
||||
:native-token?
|
||||
native-token?
|
||||
:receiver? true})
|
||||
to-network-values-for-ui (send-utils/network-values-for-ui to-network-amounts-by-chain)
|
||||
sender-possible-chain-ids (mapv :chain-id sender-network-values)
|
||||
sender-network-values (if routes-available?
|
||||
(send-utils/network-amounts
|
||||
{:network-values
|
||||
(if (= tx-type :tx/bridge)
|
||||
from-network-values-for-ui
|
||||
(send-utils/add-zero-values-to-network-values
|
||||
from-network-values-for-ui
|
||||
sender-possible-chain-ids))
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:from-locked-amounts from-locked-amounts
|
||||
:tx-type tx-type
|
||||
:receiver? false})
|
||||
(fn [{:keys [db]} [suggested-routes-data]]
|
||||
(let [chosen-route (:best suggested-routes-data)
|
||||
{:keys [token collectible token-display-name
|
||||
receiver-networks
|
||||
receiver-network-values
|
||||
sender-network-values tx-type
|
||||
disabled-from-chain-ids
|
||||
from-locked-amounts]} (get-in db [:wallet :ui :send])
|
||||
token-decimals (if collectible 0 (:decimals token))
|
||||
native-token? (and token (= token-display-name "ETH"))
|
||||
routes-available? (pos? (count chosen-route))
|
||||
token-networks (:networks token)
|
||||
token-networks-ids (when token-networks
|
||||
(map #(:chain-id %) token-networks))
|
||||
from-network-amounts-by-chain (send-utils/network-amounts-by-chain
|
||||
{:route chosen-route
|
||||
:token-decimals token-decimals
|
||||
:native-token? native-token?
|
||||
:receiver? false})
|
||||
from-network-values-for-ui (send-utils/network-values-for-ui
|
||||
from-network-amounts-by-chain)
|
||||
to-network-amounts-by-chain (send-utils/network-amounts-by-chain
|
||||
{:route chosen-route
|
||||
:token-decimals token-decimals
|
||||
:native-token? native-token?
|
||||
:receiver? true})
|
||||
to-network-values-for-ui (send-utils/network-values-for-ui
|
||||
to-network-amounts-by-chain)
|
||||
sender-possible-chain-ids (map :chain-id sender-network-values)
|
||||
sender-network-values (if routes-available?
|
||||
(send-utils/network-amounts
|
||||
{:network-values
|
||||
(if (= tx-type :tx/bridge)
|
||||
from-network-values-for-ui
|
||||
(send-utils/add-zero-values-to-network-values
|
||||
from-network-values-for-ui
|
||||
sender-possible-chain-ids))
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:from-locked-amounts from-locked-amounts
|
||||
:tx-type tx-type
|
||||
:receiver? false})
|
||||
(send-utils/reset-loading-network-amounts-to-zero
|
||||
sender-network-values))
|
||||
receiver-network-values (if routes-available?
|
||||
(send-utils/network-amounts
|
||||
{:network-values to-network-values-for-ui
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:tx-type tx-type
|
||||
:receiver? true})
|
||||
(->
|
||||
(send-utils/reset-loading-network-amounts-to-zero
|
||||
sender-network-values))
|
||||
receiver-network-values (if routes-available?
|
||||
(send-utils/network-amounts
|
||||
{:network-values to-network-values-for-ui
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:tx-type tx-type
|
||||
:receiver? true})
|
||||
(->
|
||||
(send-utils/reset-loading-network-amounts-to-zero
|
||||
receiver-network-values)
|
||||
vec
|
||||
(conj {:type :edit})))
|
||||
|
||||
network-links (when routes-available?
|
||||
(send-utils/network-links chosen-route
|
||||
sender-network-values
|
||||
receiver-network-values))]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :suggested-routes] suggested-routes-data)
|
||||
(assoc-in [:wallet :ui :send :route] chosen-route)
|
||||
(assoc-in [:wallet :ui :send :from-values-by-chain] from-network-values-for-ui)
|
||||
(assoc-in [:wallet :ui :send :to-values-by-chain] to-network-values-for-ui)
|
||||
(assoc-in [:wallet :ui :send :sender-network-values] sender-network-values)
|
||||
(assoc-in [:wallet :ui :send :receiver-network-values] receiver-network-values)
|
||||
(assoc-in [:wallet :ui :send :network-links] network-links)
|
||||
(assoc-in [:wallet :ui :send :loading-suggested-routes?] false))}))))
|
||||
receiver-network-values)
|
||||
vec
|
||||
(conj {:type :edit})))
|
||||
network-links (when routes-available?
|
||||
(send-utils/network-links chosen-route
|
||||
sender-network-values
|
||||
receiver-network-values))]
|
||||
{:db (update-in db
|
||||
[:wallet :ui :send]
|
||||
assoc
|
||||
:suggested-routes suggested-routes-data
|
||||
:route chosen-route
|
||||
:from-values-by-chain from-network-values-for-ui
|
||||
:to-values-by-chain to-network-values-for-ui
|
||||
:sender-network-values sender-network-values
|
||||
:receiver-network-values receiver-network-values
|
||||
:network-links network-links
|
||||
:loading-suggested-routes? false)})))
|
||||
|
||||
(rf/reg-event-fx :wallet/suggested-routes-error
|
||||
(fn [{:keys [db]} [error]]
|
||||
(fn [{:keys [db]} [error-message]]
|
||||
(let [cleaned-sender-network-values (-> (get-in db [:wallet :ui :send :sender-network-values])
|
||||
(send-utils/reset-loading-network-amounts-to-zero))
|
||||
cleaned-receiver-network-values (-> (get-in db [:wallet :ui :send :receiver-network-values])
|
||||
@@ -120,7 +115,7 @@
|
||||
[:toasts/upsert
|
||||
{:id :send-transaction-error
|
||||
:type :negative
|
||||
:text (:message error)}]]]})))
|
||||
:text error-message}]]]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/clean-suggested-routes
|
||||
(fn [{:keys [db]}]
|
||||
@@ -135,8 +130,7 @@
|
||||
:sender-network-values
|
||||
:receiver-network-values
|
||||
:network-links
|
||||
:loading-suggested-routes?
|
||||
:suggested-routes-call-timestamp)}))
|
||||
:loading-suggested-routes?)}))
|
||||
|
||||
(rf/reg-event-fx :wallet/clean-send-address
|
||||
(fn [{:keys [db]}]
|
||||
@@ -177,7 +171,7 @@
|
||||
(assoc-in [:wallet :ui :send :receiver-preferred-networks] receiver-networks)
|
||||
(assoc-in [:wallet :ui :send :receiver-networks] receiver-networks))
|
||||
:fx [(when (and collectible-tx? one-collectible?)
|
||||
[:dispatch [:wallet/get-suggested-routes {:amount 1}]])
|
||||
[:dispatch [:wallet/start-get-suggested-routes {:amount 1}]])
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
@@ -189,7 +183,7 @@
|
||||
(fn [{:keys [db]} [selected-networks]]
|
||||
(let [amount (get-in db [:wallet :ui :send :amount])]
|
||||
{:db (assoc-in db [:wallet :ui :send :receiver-networks] selected-networks)
|
||||
:fx [[:dispatch [:wallet/get-suggested-routes {:amount amount}]]]})))
|
||||
:fx [[:dispatch [:wallet/start-get-suggested-routes {:amount amount}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/set-token-to-send
|
||||
@@ -300,7 +294,7 @@
|
||||
one-collectible?
|
||||
(assoc-in [:wallet :ui :send :amount] 1))
|
||||
:fx [(when (and one-collectible? recipient-set?)
|
||||
[:dispatch [:wallet/get-suggested-routes {:amount 1}]])
|
||||
[:dispatch [:wallet/start-get-suggested-routes {:amount 1}]])
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen current-screen
|
||||
@@ -311,7 +305,7 @@
|
||||
:wallet/set-collectible-amount-to-send
|
||||
(fn [{db :db} [{:keys [stack-id amount]}]]
|
||||
{:db (assoc-in db [:wallet :ui :send :amount] amount)
|
||||
:fx [[:dispatch [:wallet/get-suggested-routes {:amount amount}]]
|
||||
:fx [[:dispatch [:wallet/start-get-suggested-routes {:amount amount}]]
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
@@ -347,7 +341,7 @@
|
||||
(fn [{:keys [db]}]
|
||||
(let [keys-to-remove [:to-values-by-chain :network-links :sender-network-values :route
|
||||
:receiver-network-values :suggested-routes :from-values-by-chain
|
||||
:loading-suggested-routes? :suggested-routes-call-timestamp]]
|
||||
:loading-suggested-routes?]]
|
||||
{:db (update-in db [:wallet :ui :send] #(apply dissoc % keys-to-remove))})))
|
||||
|
||||
(rf/reg-event-fx :wallet/disable-from-networks
|
||||
@@ -382,74 +376,67 @@
|
||||
(when (empty? sender-network-values) :sender-network-values)
|
||||
(when (empty? receiver-network-values) :receiver-network-values)))})))
|
||||
|
||||
(rf/reg-event-fx :wallet/get-suggested-routes
|
||||
(fn [{:keys [db now]} [{:keys [amount updated-token]}]]
|
||||
(rf/reg-event-fx :wallet/start-get-suggested-routes
|
||||
(fn [{:keys [db]} [{:keys [amount amount-out updated-token] :as args :or {amount-out "0"}}]]
|
||||
(let [wallet-address (get-in db [:wallet :current-viewing-account-address])
|
||||
token (or updated-token (get-in db [:wallet :ui :send :token]))
|
||||
transaction-type (get-in db [:wallet :ui :send :tx-type])
|
||||
collectible (get-in db [:wallet :ui :send :collectible])
|
||||
to-address (get-in db [:wallet :ui :send :to-address])
|
||||
receiver-networks (get-in db [:wallet :ui :send :receiver-networks])
|
||||
disabled-from-chain-ids (or (get-in db [:wallet :ui :send :disabled-from-chain-ids]) [])
|
||||
from-locked-amounts (or (get-in db [:wallet :ui :send :from-locked-amounts]) {})
|
||||
{:keys [token tx-type collectible to-address
|
||||
receiver-networks disabled-from-chain-ids
|
||||
from-locked-amounts bridge-to-chain-id]
|
||||
:or {token updated-token}} (get-in db [:wallet :ui :send])
|
||||
test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?])
|
||||
networks ((if test-networks-enabled? :test :prod)
|
||||
(get-in db [:wallet :networks]))
|
||||
network-chain-ids (map :chain-id networks)
|
||||
bridge-to-chain-id (get-in db [:wallet :ui :send :bridge-to-chain-id])
|
||||
token-decimal (when token (:decimals token))
|
||||
token-id (utils/format-token-id token collectible)
|
||||
to-token-id ""
|
||||
network-preferences (if token [] [(get-in collectible [:id :contract-id :chain-id])])
|
||||
gas-rates constants/gas-rate-medium
|
||||
to-hex (fn [v] (send-utils/amount-in-hex v (if token token-decimal 0)))
|
||||
amount-in (to-hex amount)
|
||||
amount-out (to-hex amount-out)
|
||||
from-address wallet-address
|
||||
disabled-from-chain-ids disabled-from-chain-ids
|
||||
disabled-to-chain-ids (if (= transaction-type :tx/bridge)
|
||||
disabled-to-chain-ids (if (= tx-type :tx/bridge)
|
||||
(filter #(not= % bridge-to-chain-id) network-chain-ids)
|
||||
(filter (fn [chain-id]
|
||||
(not (some #(= chain-id %)
|
||||
receiver-networks)))
|
||||
network-chain-ids))
|
||||
from-locked-amount (update-vals from-locked-amounts to-hex)
|
||||
transaction-type-param (case transaction-type
|
||||
:tx/collectible-erc-721 constants/send-type-erc-721-transfer
|
||||
:tx/collectible-erc-1155 constants/send-type-erc-1155-transfer
|
||||
:tx/bridge constants/send-type-bridge
|
||||
constants/send-type-transfer)
|
||||
transaction-type (case tx-type
|
||||
:tx/collectible-erc-721 constants/send-type-erc-721-transfer
|
||||
:tx/collectible-erc-1155 constants/send-type-erc-1155-transfer
|
||||
:tx/bridge constants/send-type-bridge
|
||||
constants/send-type-transfer)
|
||||
balances-per-chain (when token (:balances-per-chain token))
|
||||
sender-token-available-networks-for-suggested-routes
|
||||
(when token
|
||||
(send-utils/token-available-networks-for-suggested-routes {:balances-per-chain
|
||||
balances-per-chain
|
||||
:disabled-chain-ids
|
||||
disabled-from-chain-ids
|
||||
:only-with-balance? true}))
|
||||
(send-utils/token-available-networks-for-suggested-routes
|
||||
{:balances-per-chain balances-per-chain
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:only-with-balance? true}))
|
||||
receiver-token-available-networks-for-suggested-routes
|
||||
(when token
|
||||
(send-utils/token-available-networks-for-suggested-routes {:balances-per-chain
|
||||
balances-per-chain
|
||||
:disabled-chain-ids
|
||||
disabled-from-chain-ids
|
||||
:only-with-balance? false}))
|
||||
token-networks-ids (when token (mapv #(:chain-id %) (:networks token)))
|
||||
(send-utils/token-available-networks-for-suggested-routes
|
||||
{:balances-per-chain balances-per-chain
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:only-with-balance? false}))
|
||||
token-networks-ids (when token (map #(:chain-id %) (:networks token)))
|
||||
sender-network-values (when sender-token-available-networks-for-suggested-routes
|
||||
(send-utils/loading-network-amounts
|
||||
{:valid-networks
|
||||
(if (= transaction-type :tx/bridge)
|
||||
(if (= tx-type :tx/bridge)
|
||||
(remove #(= bridge-to-chain-id %)
|
||||
sender-token-available-networks-for-suggested-routes)
|
||||
sender-token-available-networks-for-suggested-routes)
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:tx-type transaction-type
|
||||
:tx-type tx-type
|
||||
:receiver? false}))
|
||||
receiver-network-values (when receiver-token-available-networks-for-suggested-routes
|
||||
(send-utils/loading-network-amounts
|
||||
{:valid-networks
|
||||
(if (= transaction-type :tx/bridge)
|
||||
(if (= tx-type :tx/bridge)
|
||||
(filter
|
||||
#(= bridge-to-chain-id %)
|
||||
receiver-token-available-networks-for-suggested-routes)
|
||||
@@ -457,40 +444,70 @@
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:tx-type transaction-type
|
||||
:tx-type tx-type
|
||||
:receiver? true}))
|
||||
request-params [transaction-type-param
|
||||
from-address
|
||||
to-address
|
||||
amount-in
|
||||
token-id
|
||||
to-token-id
|
||||
disabled-from-chain-ids
|
||||
disabled-to-chain-ids
|
||||
network-preferences
|
||||
gas-rates
|
||||
from-locked-amount]]
|
||||
{:db (cond-> db
|
||||
:always (assoc-in [:wallet :ui :send :amount] amount)
|
||||
:always (assoc-in [:wallet :ui :send :loading-suggested-routes?] true)
|
||||
:always (assoc-in [:wallet :ui :send :sender-network-values]
|
||||
sender-network-values)
|
||||
:always (assoc-in [:wallet :ui :send :receiver-network-values]
|
||||
receiver-network-values)
|
||||
:always (assoc-in [:wallet :ui :send :suggested-routes-call-timestamp] now)
|
||||
:always (update-in [:wallet :ui :send] dissoc :network-links)
|
||||
token (assoc-in [:wallet :ui :send :token] token))
|
||||
:json-rpc/call [{:method "wallet_getSuggestedRoutes"
|
||||
:params request-params
|
||||
:on-success (fn [suggested-routes]
|
||||
(rf/dispatch [:wallet/suggested-routes-success suggested-routes
|
||||
now]))
|
||||
:on-error (fn [error]
|
||||
params [{:uuid (str (random-uuid))
|
||||
:sendType transaction-type
|
||||
:addrFrom from-address
|
||||
:addrTo to-address
|
||||
:amountIn amount-in
|
||||
:amountOut amount-out
|
||||
:tokenID token-id
|
||||
:toTokenID to-token-id
|
||||
:disabledFromChainIDs disabled-from-chain-ids
|
||||
:disabledToChainIDs disabled-to-chain-ids
|
||||
:gasFeeMode gas-rates
|
||||
:fromLockedAmount from-locked-amount
|
||||
:username (:username args)
|
||||
:publicKey (:publicKey args)
|
||||
:packID (:packID args)}]]
|
||||
(when (and to-address from-address amount-in token-id)
|
||||
{:db (update-in db
|
||||
[:wallet :ui :send]
|
||||
#(-> %
|
||||
(assoc :amount amount
|
||||
:loading-suggested-routes? true
|
||||
:sender-network-values sender-network-values
|
||||
:receiver-network-values receiver-network-values)
|
||||
(dissoc :network-links)
|
||||
(cond-> token (assoc :token token))))
|
||||
:json-rpc/call [{:method "wallet_getSuggestedRoutesV2Async"
|
||||
:params params
|
||||
:on-error (fn [error]
|
||||
(rf/dispatch [:wallet/suggested-routes-error error])
|
||||
(log/error "failed to get suggested routes"
|
||||
{:event :wallet/get-suggested-routes
|
||||
:error error
|
||||
:params request-params}))}]})))
|
||||
(log/error "failed to get suggested routes (async)"
|
||||
{:event :wallet/start-get-suggested-routes
|
||||
:error (:message error)
|
||||
:params params}))}]}))))
|
||||
|
||||
(rf/reg-event-fx :wallet/stop-get-suggested-routes
|
||||
(fn []
|
||||
{:fx [[:dispatch [:wallet/clean-routes-calculation]]]
|
||||
:json-rpc/call [{:method "wallet_stopSuggestedRoutesV2AsyncCalcualtion"
|
||||
:params []
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to stop suggested routes calculation"
|
||||
{:event :wallet/stop-get-suggested-routes
|
||||
:error error}))}]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/handle-suggested-routes
|
||||
(fn [_ data]
|
||||
(if-let [error (some-> data
|
||||
first
|
||||
:ErrorResponse
|
||||
(#(if (= (:code %) "0") "An error occurred" (:details %))))]
|
||||
(do
|
||||
(log/error "failed to get suggested routes (async)"
|
||||
{:event :wallet/handle-suggested-routes
|
||||
:error error})
|
||||
{:fx [[:dispatch [:wallet/suggested-routes-error error]]]})
|
||||
(let [suggested-routes-new-data (data-store/rpc->suggested-routes data)
|
||||
suggested-routes (-> suggested-routes-new-data
|
||||
first
|
||||
(update :best #(map data-store/new->old-route-path %))
|
||||
(update :candidates #(map data-store/new->old-route-path %)))]
|
||||
{:fx [[:dispatch
|
||||
[:wallet/suggested-routes-success suggested-routes]]]}))))
|
||||
|
||||
(rf/reg-event-fx :wallet/add-authorized-transaction
|
||||
(fn [{:keys [db]} [transaction]]
|
||||
@@ -677,11 +694,13 @@
|
||||
:transfer-type transaction-type-param})
|
||||
transaction-paths
|
||||
sha3-pwd]]
|
||||
(log/info "multi transaction called")
|
||||
{:json-rpc/call [{:method "wallet_createMultiTransaction"
|
||||
:params request-params
|
||||
:on-success (fn [result]
|
||||
(rf/dispatch [:wallet/add-authorized-transaction result])
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
(when result
|
||||
(rf/dispatch [:wallet/add-authorized-transaction result])
|
||||
(rf/dispatch [:hide-bottom-sheet])))
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to send transaction"
|
||||
{:event :wallet/send-transaction
|
||||
@@ -692,6 +711,23 @@
|
||||
:type :negative
|
||||
:text (:message error)}]))}]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/proceed-with-transactions-signatures
|
||||
(fn [_ [signatures]]
|
||||
{:json-rpc/call [{:method "wallet_proceedWithTransactionsSignatures"
|
||||
:params [signatures]
|
||||
:on-success (fn [result]
|
||||
(when result
|
||||
(rf/dispatch [:wallet/add-authorized-transaction result])
|
||||
(rf/dispatch [:hide-bottom-sheet])))
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to proceed-with-transactions-signatures"
|
||||
{:event :wallet/proceed-with-transactions-signatures
|
||||
:error error})
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :send-transaction-error
|
||||
:type :negative
|
||||
:text (:message error)}]))}]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/select-from-account
|
||||
(fn [{db :db} [{:keys [address stack-id network-details start-flow?]}]]
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
(h/deftest-event :wallet/set-collectible-amount-to-send
|
||||
[event-id dispatch]
|
||||
(let [initial-db {:wallet {:ui {:send nil}}}
|
||||
expected-fx [[:dispatch [:wallet/get-suggested-routes {:amount 10}]]
|
||||
expected-fx [[:dispatch [:wallet/start-get-suggested-routes {:amount 10}]]
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen nil :flow-id :wallet-send-flow}]]]
|
||||
@@ -273,19 +273,18 @@
|
||||
[event-id dispatch]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send
|
||||
{:other-props :value
|
||||
:suggested-routes ["1" "2"]
|
||||
:route "1"
|
||||
:amount 10
|
||||
:from-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
|
||||
:to-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
|
||||
:sender-network-values [:eth :arb1]
|
||||
:receiver-network-values [:eth :arb1]
|
||||
:network-links [{:from-chain-id 1
|
||||
:to-chain-id 10
|
||||
:position-diff 1}]
|
||||
:loading-suggested-routes? false
|
||||
:suggested-routes-call-timestamp ["1" "2"]}}}})
|
||||
{:other-props :value
|
||||
:suggested-routes ["1" "2"]
|
||||
:route "1"
|
||||
:amount 10
|
||||
:from-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
|
||||
:to-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
|
||||
:sender-network-values [:eth :arb1]
|
||||
:receiver-network-values [:eth :arb1]
|
||||
:network-links [{:from-chain-id 1
|
||||
:to-chain-id 10
|
||||
:position-diff 1}]
|
||||
:loading-suggested-routes? false}}}})
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :suggested-routes)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :route)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :amount)))
|
||||
@@ -296,8 +295,6 @@
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :network-links)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send])
|
||||
:loading-suggested-routes?)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send])
|
||||
:suggested-routes-call-timestamp)))
|
||||
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
|
||||
|
||||
(h/deftest-event :wallet/suggested-routes-error
|
||||
@@ -324,7 +321,7 @@
|
||||
:receiver-network-values receiver-network-amounts
|
||||
:route :values
|
||||
:loading-suggested-routes? true}}}})
|
||||
(is (match? expected-result (dispatch [event-id {:message "error"}])))))
|
||||
(is (match? expected-result (dispatch [event-id "error"])))))
|
||||
|
||||
(h/deftest-event :wallet/reset-network-amounts-to-zero
|
||||
[event-id dispatch]
|
||||
@@ -438,7 +435,7 @@
|
||||
:collectible collectible}}}
|
||||
:profile/profile {:test-networks-enabled? false
|
||||
:is-goerli-enabled? false}}
|
||||
:fx [[:dispatch [:wallet/get-suggested-routes {:amount 1}]]
|
||||
:fx [[:dispatch [:wallet/start-get-suggested-routes {:amount 1}]]
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
[{:keys [amount bounce-duration-ms token valid-input?]}]
|
||||
(if valid-input?
|
||||
(debounce/debounce-and-dispatch
|
||||
[:wallet/get-suggested-routes
|
||||
[:wallet/start-get-suggested-routes
|
||||
{:amount amount
|
||||
:updated-token token}]
|
||||
bounce-duration-ms)
|
||||
@@ -396,7 +396,7 @@
|
||||
(and (not should-try-again?) confirm-disabled?))
|
||||
:on-press (cond
|
||||
should-try-again?
|
||||
#(rf/dispatch [:wallet/get-suggested-routes
|
||||
#(rf/dispatch [:wallet/start-get-suggested-routes
|
||||
{:amount amount-in-crypto
|
||||
:updated-token token-by-symbol}])
|
||||
sending-to-unpreferred-networks?
|
||||
|
||||
@@ -257,7 +257,8 @@
|
||||
:transaction-type transaction-type}]
|
||||
(when (and (not loading-suggested-routes?) route (seq route))
|
||||
[standard-auth/slide-button
|
||||
{:size :size-48
|
||||
{:keycard-supported? true
|
||||
:size :size-48
|
||||
:track-text (if (= transaction-type :tx/bridge)
|
||||
(i18n/label :t/slide-to-bridge)
|
||||
(i18n/label :t/slide-to-send))
|
||||
@@ -265,8 +266,7 @@
|
||||
:customization-color account-color
|
||||
:on-auth-success #(rf/dispatch
|
||||
[:wallet/send-transaction
|
||||
(security/safe-unmask-data
|
||||
%)])
|
||||
(security/safe-unmask-data %)])
|
||||
:auth-button-label (i18n/label :t/confirm)}])]
|
||||
:gradient-cover? true
|
||||
:customization-color (:color account)}
|
||||
|
||||
@@ -242,3 +242,10 @@
|
||||
(defn tx-type-collectible?
|
||||
[tx-type]
|
||||
(contains? collectible-tx-set tx-type))
|
||||
|
||||
(defn convert-to-gwei
|
||||
[n precision]
|
||||
(-> n
|
||||
money/wei->gwei
|
||||
(money/with-precision precision)
|
||||
(str)))
|
||||
|
||||
@@ -134,6 +134,7 @@
|
||||
:iconUrl (get-in session [:peer :metadata :icons 0])
|
||||
:url (get-in session [:peer :metadata :url])
|
||||
:accounts (get-in session [:namespaces :eip155 :accounts])
|
||||
:chains (get-in session [:namespaces :eip155 :chains])
|
||||
:disconnected false})
|
||||
|
||||
(defn filter-operable-accounts
|
||||
|
||||
@@ -79,7 +79,6 @@
|
||||
(if (and (not-empty session-networks) required-networks-supported?)
|
||||
{:db (update db
|
||||
:wallet-connect/current-proposal assoc
|
||||
:response-sent? false
|
||||
:request proposal
|
||||
:session-networks session-networks
|
||||
:address (or current-viewing-address
|
||||
@@ -89,23 +88,30 @@
|
||||
:fx [[:dispatch
|
||||
[:open-modal :screen/wallet.wallet-connect-session-proposal]]]}
|
||||
{:fx [[:dispatch
|
||||
[:wallet-connect/session-networks-unsupported proposal]]]}))))
|
||||
[:wallet-connect/show-session-networks-unsupported-toast proposal]]
|
||||
[:dispatch
|
||||
[:wallet-connect/reject-session-proposal proposal]]]}))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/session-networks-unsupported
|
||||
:wallet-connect/show-session-networks-unsupported-toast
|
||||
(fn [{:keys [db]} [proposal]]
|
||||
(let [{:keys [name]} (wallet-connect-core/get-session-dapp-metadata proposal)]
|
||||
(let [{:keys [name url]} (wallet-connect-core/get-session-dapp-metadata proposal)]
|
||||
{:fx [[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type :negative
|
||||
:theme (:theme db)
|
||||
:text (i18n/label :t/wallet-connect-networks-not-supported {:dapp name})}]]]})))
|
||||
:text (i18n/label :t/wallet-connect-networks-not-supported
|
||||
{:dapp (wallet-connect-core/compute-dapp-name name url)})}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-session-request
|
||||
(fn [{:keys [db]} [event]]
|
||||
(when (wallet-connect-core/event-should-be-handled? db event)
|
||||
{:fx [[:dispatch [:wallet-connect/process-session-request event]]]})))
|
||||
(if (wallet-connect-core/event-should-be-handled? db event)
|
||||
{:fx [[:dispatch [:wallet-connect/process-session-request event]]]}
|
||||
{:fx [[:dispatch
|
||||
[:wallet-connect/send-response
|
||||
{:error (wallet-connect/get-sdk-error
|
||||
constants/wallet-connect-user-rejected-chains-error-key)}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-session-delete
|
||||
|
||||
@@ -146,10 +146,25 @@
|
||||
[:dispatch [:wallet-connect/dismiss-request-modal]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/reject-session-proposal
|
||||
:wallet-connect/dismiss-request-modal
|
||||
(fn [{:keys [db]} _]
|
||||
(let [screen (-> db
|
||||
(get-in [:wallet-connect/current-request :event])
|
||||
wallet-connect-core/get-request-method
|
||||
wallet-connect-core/method-to-screen)]
|
||||
{:fx [[:dispatch [:dismiss-modal screen]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/finish-session-request
|
||||
(fn [_ [result]]
|
||||
{:fx [[:dispatch [:wallet-connect/send-response {:result result}]]
|
||||
[:dispatch [:wallet-connect/dismiss-request-modal]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/reject-session-proposal
|
||||
(fn [{:keys [db]} [proposal]]
|
||||
(let [web3-wallet (get db :wallet-connect/web3-wallet)
|
||||
{:keys [request response-sent?]} (:wallet-connect/current-proposal db)]
|
||||
{:keys [request response-sent?]} (or proposal (:wallet-connect/current-proposal db))]
|
||||
{:fx [(when-not response-sent?
|
||||
[:effects.wallet-connect/reject-session-proposal
|
||||
{:web3-wallet web3-wallet
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
;; works and we may re-enable it by default.
|
||||
::profile-pictures-visibility (enabled-in-env? :FLAG_PROFILE_PICTURES_VISIBILITY_ENABLED)
|
||||
|
||||
::settings.telemetry (enabled-in-env? :FLAG_TELEMETRY_ENABLED)
|
||||
::settings.import-all-keypairs (enabled-in-env?
|
||||
:FLAG_WALLET_SETTINGS_IMPORT_ALL_KEYPAIRS)
|
||||
::shell.jump-to (enabled-in-env? :ENABLE_JUMP_TO)
|
||||
|
||||
::wallet.advanced-sending (enabled-in-env? :FLAG_ADVANCED_SENDING)
|
||||
::wallet.assets-modal-hide (enabled-in-env? :FLAG_ASSETS_MODAL_HIDE)
|
||||
::wallet.assets-modal-manage-tokens (enabled-in-env? :FLAG_ASSETS_MODAL_MANAGE_TOKENS)
|
||||
|
||||
@@ -82,10 +82,11 @@
|
||||
{})})
|
||||
|
||||
(def dark-screen
|
||||
{:theme :dark
|
||||
:layout {:componentBackgroundColor colors/neutral-95
|
||||
:orientation ["portrait"]
|
||||
:backgroundColor colors/neutral-95}})
|
||||
{:theme :dark
|
||||
:modalPresentationStyle :overCurrentContext
|
||||
:layout {:componentBackgroundColor colors/neutral-95
|
||||
:orientation ["portrait"]
|
||||
:backgroundColor colors/neutral-95}})
|
||||
|
||||
(def lightbox
|
||||
{:topBar {:visible false}
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
:component shell/shell-stack}
|
||||
|
||||
{:name :shell-qr-reader
|
||||
:options (assoc options/dark-screen :modalPresentationStyle :overCurrentContext)
|
||||
:options options/dark-screen
|
||||
:component shell-qr-reader/view}
|
||||
|
||||
{:name :chat
|
||||
@@ -369,7 +369,7 @@
|
||||
:popStackOnPress false}}}
|
||||
|
||||
{:name :scan-sync-code-page
|
||||
:options options/dark-screen
|
||||
:options options/transparent-modal-screen-options
|
||||
:component scan-sync-code-page/view}
|
||||
|
||||
{:name :screen/onboarding.sign-in-intro
|
||||
@@ -387,9 +387,9 @@
|
||||
:component sign-in/view}
|
||||
|
||||
{:name :screen/onboarding.syncing-progress
|
||||
:options {:theme :dark
|
||||
:layout options/onboarding-layout
|
||||
:popGesture false}
|
||||
:options (assoc options/dark-screen
|
||||
:popGesture
|
||||
false)
|
||||
:component syncing-devices/view}
|
||||
|
||||
{:name :screen/onboarding.syncing-progress-intro
|
||||
@@ -513,9 +513,7 @@
|
||||
:component wallet-transaction-progress/view}
|
||||
|
||||
{:name :screen/wallet.scan-address
|
||||
:options (merge
|
||||
options/dark-screen
|
||||
{:modalPresentationStyle :overCurrentContext})
|
||||
:options options/dark-screen
|
||||
:component wallet-scan-address/view}
|
||||
|
||||
{:name :screen/wallet.swap-select-asset-to-pay
|
||||
@@ -536,9 +534,7 @@
|
||||
:component wallet-swap-set-spending-cap/view}
|
||||
|
||||
{:name :scan-profile-qr-code
|
||||
:options (merge
|
||||
options/dark-screen
|
||||
{:modalPresentationStyle :overCurrentContext})
|
||||
:options options/dark-screen
|
||||
:component scan-profile-qr-page/view}
|
||||
|
||||
{:name :invite-people-community
|
||||
@@ -564,9 +560,7 @@
|
||||
:component wallet-connected-dapps/view}
|
||||
|
||||
{:name :screen/wallet.scan-dapp
|
||||
:options (merge
|
||||
options/dark-screen
|
||||
{:modalPresentationStyle :overCurrentContext})
|
||||
:options options/dark-screen
|
||||
:component wallet-scan-dapp/view}
|
||||
|
||||
;; Settings
|
||||
|
||||
@@ -115,13 +115,13 @@
|
||||
(comp :network-name first))
|
||||
address-activities (->> (get activities current-viewing-account-address)
|
||||
(vals)
|
||||
(sort :timestamp))]
|
||||
(sort-by :timestamp))]
|
||||
(->> address-activities
|
||||
(keep #(process-activity-by-type chain-id->network-name %))
|
||||
(group-by (fn [{:keys [timestamp]}]
|
||||
(datetime/timestamp->relative-short-date (* timestamp 1000))))
|
||||
(map (fn [[date activities]]
|
||||
{:title date
|
||||
:data activities
|
||||
:data (reverse activities)
|
||||
:timestamp (:timestamp (first activities))}))
|
||||
(sort-by (fn [{:keys [timestamp]}] (- timestamp)))))))
|
||||
|
||||
@@ -38,48 +38,79 @@
|
||||
:amount-out "0x1"
|
||||
:sender "acc1"
|
||||
:recipient "acc4"
|
||||
:timestamp 1588464000}}
|
||||
"acc3" {4 {:activity-type constants/wallet-activity-type-receive
|
||||
:timestamp 1588464000}
|
||||
4 {:activity-type constants/wallet-activity-type-send
|
||||
:amount-out "0x1"
|
||||
:sender "acc1"
|
||||
:recipient "acc4"
|
||||
:timestamp 1588464100}
|
||||
5 {:activity-type constants/wallet-activity-type-send
|
||||
:amount-out "0x1"
|
||||
:sender "acc1"
|
||||
:recipient "acc4"
|
||||
:timestamp 1588464050}}
|
||||
"acc3" {6 {:activity-type constants/wallet-activity-type-receive
|
||||
:amount-in "0x1"
|
||||
:sender "acc4"
|
||||
:recipient "acc3"
|
||||
:timestamp 1588464000}}})
|
||||
(assoc-in [:wallet :current-viewing-account-address] "acc1"))))
|
||||
(is
|
||||
(match? [{:title "May 3, 2020"
|
||||
:timestamp 1588464000
|
||||
:data [{:relative-date "May 3, 2020"
|
||||
:amount "0"
|
||||
:network-logo nil
|
||||
:recipient "acc4"
|
||||
:transaction :send
|
||||
:token nil
|
||||
:network-name nil
|
||||
:status nil
|
||||
:sender "acc1"
|
||||
:timestamp 1588464000}]}
|
||||
{:title "May 2, 2020"
|
||||
:timestamp 1588377600
|
||||
:data [{:relative-date "May 2, 2020"
|
||||
:amount "0"
|
||||
:network-logo nil
|
||||
:recipient "acc1"
|
||||
:transaction :receive
|
||||
:token nil
|
||||
:network-name nil
|
||||
:status nil
|
||||
:sender "acc2"
|
||||
:timestamp 1588377600}]}
|
||||
{:title "May 1, 2020"
|
||||
:timestamp 1588291200
|
||||
:data [{:relative-date "May 1, 2020"
|
||||
:amount "0"
|
||||
:network-logo nil
|
||||
:recipient "acc2"
|
||||
:transaction :send
|
||||
:token nil
|
||||
:network-name nil
|
||||
:status nil
|
||||
:sender "acc1"
|
||||
:timestamp 1588291200}]}]
|
||||
(rf/sub [sub-name])))))
|
||||
(match?
|
||||
[{:title "May 3, 2020"
|
||||
:timestamp 1588464000
|
||||
:data [{:relative-date "May 3, 2020"
|
||||
:amount "0"
|
||||
:network-logo nil
|
||||
:recipient "acc4"
|
||||
:transaction :send
|
||||
:token nil
|
||||
:network-name nil
|
||||
:status nil
|
||||
:sender "acc1"
|
||||
:timestamp 1588464100}
|
||||
{:relative-date "May 3, 2020"
|
||||
:amount "0"
|
||||
:network-logo nil
|
||||
:recipient "acc4"
|
||||
:transaction :send
|
||||
:token nil
|
||||
:network-name nil
|
||||
:status nil
|
||||
:sender "acc1"
|
||||
:timestamp 1588464050}
|
||||
{:relative-date "May 3, 2020"
|
||||
:amount "0"
|
||||
:network-logo nil
|
||||
:recipient "acc4"
|
||||
:transaction :send
|
||||
:token nil
|
||||
:network-name nil
|
||||
:status nil
|
||||
:sender "acc1"
|
||||
:timestamp 1588464000}]}
|
||||
{:title "May 2, 2020"
|
||||
:timestamp 1588377600
|
||||
:data [{:relative-date "May 2, 2020"
|
||||
:amount "0"
|
||||
:network-logo nil
|
||||
:recipient "acc1"
|
||||
:transaction :receive
|
||||
:token nil
|
||||
:network-name nil
|
||||
:status nil
|
||||
:sender "acc2"
|
||||
:timestamp 1588377600}]}
|
||||
{:title "May 1, 2020"
|
||||
:timestamp 1588291200
|
||||
:data [{:relative-date "May 1, 2020"
|
||||
:amount "0"
|
||||
:network-logo nil
|
||||
:recipient "acc2"
|
||||
:transaction :send
|
||||
:token nil
|
||||
:network-name nil
|
||||
:status nil
|
||||
:sender "acc1"
|
||||
:timestamp 1588291200}]}]
|
||||
(rf/sub [sub-name])))))
|
||||
|
||||
@@ -207,6 +207,12 @@
|
||||
(fn [{:keys [keypairs]}]
|
||||
(vals keypairs)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/fully-operable-keypairs-list
|
||||
:<- [:wallet/keypairs-list]
|
||||
(fn [keypairs]
|
||||
(filter #(= :fully (:lowest-operability %)) keypairs)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/keypair-names
|
||||
:<- [:wallet/keypairs-list]
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
(ns status-im.subs.wallet.wallet-connect
|
||||
(:require [clojure.string :as string]
|
||||
(:require [clojure.set :as set]
|
||||
[clojure.string :as string]
|
||||
[re-frame.core :as rf]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils :as wallet-utils]
|
||||
[status-im.contexts.wallet.wallet-connect.core :as wallet-connect-core]
|
||||
[status-im.contexts.wallet.wallet-connect.transactions :as transactions]
|
||||
@@ -58,6 +60,24 @@
|
||||
(some #(string/includes? % address) accounts))
|
||||
sessions)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/sessions-for-current-account-and-networks
|
||||
:<- [:wallet-connect/sessions-for-current-account]
|
||||
:<- [:profile/test-networks-enabled?]
|
||||
(fn [[sessions testnet-mode?]]
|
||||
(filter
|
||||
(fn [{:keys [chains]}]
|
||||
(let [chain-ids (set (map (fn [chain]
|
||||
(-> chain
|
||||
(string/split ":")
|
||||
second
|
||||
js/parseInt))
|
||||
chains))]
|
||||
(if testnet-mode?
|
||||
(set/subset? chain-ids (set/union constants/sepolia-chain-ids constants/goerli-chain-ids))
|
||||
(set/subset? chain-ids constants/mainnet-chain-ids))))
|
||||
sessions)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet-connect/chain-id
|
||||
:<- [:wallet-connect/current-request]
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "v0.182.37",
|
||||
"commit-sha1": "4a43b2b2bebe45df2100d1a5c5034105d93e50b8",
|
||||
"src-sha256": "0f5mm7lx6s2qcy9xpa9v7piqb60yazi6p677fy105yz7hg731cw6"
|
||||
"version": "v0.182.38",
|
||||
"commit-sha1": "2bbdb35f6cabd1a4f7775e180e0647b70ce8d1aa",
|
||||
"src-sha256": "03bksi5gn44ky76kblikpr6j3x69baid81ghfk27a4qx9hnc0qgc"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user