Compare commits
32
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b532b8e839 | ||
|
|
0bcef84f04 | ||
|
|
fde7f3df93 | ||
|
|
d43e8881ef | ||
|
|
75c8437cc5 | ||
|
|
f1310c7e6c | ||
|
|
d7530dfbee | ||
|
|
0d6bd9c15d | ||
|
|
2da6d9dffb | ||
|
|
879a4067e5 | ||
|
|
e1317f503f | ||
|
|
ec00ddf10e | ||
|
|
c0e10b7c6f | ||
|
|
da449bcd17 | ||
|
|
ab93088d93 | ||
|
|
b4a0e74a4a | ||
|
|
379ba87c16 | ||
|
|
901dddc603 | ||
|
|
9300377c6c | ||
|
|
9445363467 | ||
|
|
5bad8de886 | ||
|
|
577dc16188 | ||
|
|
00d288fb94 | ||
|
|
6ea39b5096 | ||
|
|
d7c66319aa | ||
|
|
5193f981f8 | ||
|
|
615ad2f02b | ||
|
|
0d6c553f3f | ||
|
|
55ec84a5c3 | ||
|
|
2c6ab52a1a | ||
|
|
93e2c31a8f | ||
|
|
541b2e0909 |
@@ -0,0 +1,21 @@
|
||||
(ns cljs.test
|
||||
(:require [clj-kondo.hooks-api :as hooks]))
|
||||
|
||||
(defn deftest
|
||||
"Verify test name passed to `cljs.test/deftest` is suffixed with -test and not
|
||||
prefixed with test-."
|
||||
[{:keys [node]}]
|
||||
(let [[_ test-name-node & _] (:children node)
|
||||
test-name (str (hooks/sexpr test-name-node))]
|
||||
(when (and (hooks/token-node? test-name-node)
|
||||
(or (not (re-find #"^.*-test$" test-name))
|
||||
(re-find #"^test-.*$" test-name)))
|
||||
(hooks/reg-finding! (assoc (meta test-name-node)
|
||||
:message "Test name should be suffixed with -test"
|
||||
:type :status-im.linter/inconsistent-test-name)))))
|
||||
|
||||
(comment
|
||||
;; Invalid
|
||||
(deftest {:node (hooks/parse-string "(deftest foo-tes (println :hello))")})
|
||||
(deftest {:node (hooks/parse-string "(deftest test-foo-test (println :hello))")})
|
||||
)
|
||||
@@ -4,5 +4,8 @@
|
||||
test-helpers.component/get-all-by-translation-text utils.i18n/label
|
||||
test-helpers.component/get-by-translation-text utils.i18n/label
|
||||
test-helpers.component/query-all-by-translation-text utils.i18n/label
|
||||
test-helpers.component/query-by-translation-text utils.i18n/label}}
|
||||
:linters {:status-im.linter/invalid-translation-keyword {:level :error}}}
|
||||
test-helpers.component/query-by-translation-text utils.i18n/label
|
||||
|
||||
cljs.test/deftest cljs.test/deftest}}
|
||||
:linters {:status-im.linter/invalid-translation-keyword {:level :error}
|
||||
:status-im.linter/inconsistent-test-name {:level :error}}}
|
||||
|
||||
@@ -83,6 +83,9 @@ shim.js
|
||||
figwheel_server.log
|
||||
.nrepl-port
|
||||
|
||||
# FlowStorm (Clojure debugger)
|
||||
repl-client-debug
|
||||
|
||||
# Lein
|
||||
#
|
||||
.lein-failures
|
||||
|
||||
@@ -401,6 +401,17 @@ test-component: ##@test Run component tests once in NodeJS
|
||||
yarn shadow-cljs compile component-test && \
|
||||
jest --clearCache && jest --config=test/jest/jest.config.js --testEnvironment node
|
||||
|
||||
# Reference: https://flow-storm.github.io/flow-storm-debugger/user_guide.html#_debugging_react_native_applications
|
||||
run-flow-storm: export SHADOW_CLJS_BUILD_ID := :mobile
|
||||
run-flow-storm: export TARGET := clojure
|
||||
run-flow-storm: export GDK_DPI_SCALE := 1.0
|
||||
run-flow-storm: ##@run Start FlowStorm debugger
|
||||
clj -Sforce -Sdeps '{:deps {com.github.jpmonettas/flow-storm-dbg {:mvn/version "3.7.5"}}}' \
|
||||
-X flow-storm.debugger.main/start-debugger \
|
||||
:port 7888 \
|
||||
:repl-type :shadow \
|
||||
:build-id $(SHADOW_CLJS_BUILD_ID)
|
||||
|
||||
#--------------
|
||||
# Other
|
||||
#--------------
|
||||
@@ -423,11 +434,13 @@ android-clean: ##@prepare Clean Gradle state
|
||||
rm -rf ~/.gradle
|
||||
|
||||
|
||||
android-ports: export FLOWSTORM_PORT := 7722
|
||||
android-ports: export TARGET := android-sdk
|
||||
android-ports: ##@other Add proxies to Android Device/Simulator
|
||||
adb reverse tcp:8081 tcp:8081 && \
|
||||
adb reverse tcp:3449 tcp:3449 && \
|
||||
adb reverse tcp:4567 tcp:4567 && \
|
||||
adb reverse tcp:$(FLOWSTORM_PORT) tcp:$(FLOWSTORM_PORT) && \
|
||||
adb forward tcp:5561 tcp:5561
|
||||
|
||||
android-devices: export TARGET := android-sdk
|
||||
|
||||
@@ -123,7 +123,6 @@ pipeline {
|
||||
post {
|
||||
always { script {
|
||||
nix.shell('nix-store --optimize', pure: false)
|
||||
nix.shell('nix/scripts/clean.sh', pure: false)
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,39 @@ A server will be started at http://localhost:4567. It might show "not connected"
|
||||
|
||||
More details about re-frisk are on the [project page](https://github.com/flexsurfer/re-frisk).
|
||||
|
||||
## Debugging with FlowStorm
|
||||
|
||||
[FlowStorm](http://www.flow-storm.org/) is a free and open-source time-travel
|
||||
debugger for Clojure and ClojureScript. It is capable of recording almost any
|
||||
code execution path in the Status' mobile app.
|
||||
|
||||
FlowStorm is independent of editor/IDE, but a tighter [integration with
|
||||
Emacs](https://github.com/jpmonettas/cider-storm) is available.
|
||||
|
||||
If you are developing with Android, run `make android-ports` first. If you are
|
||||
behind a firewall, allow TCP traffic on port `7722`, then:
|
||||
|
||||
```bash
|
||||
make run-flow-storm
|
||||
```
|
||||
|
||||
You will know FlowStorm is correctly running if you see the status bar with
|
||||
green `REPL` and `RUNTIME` indicators.
|
||||
|
||||
With FlowStorm running, you can now add `#trace` on any top-level form, reload
|
||||
the code, or evaluate the traced form in the REPL, and FlowStorm will start
|
||||
recording data. Avoid `#rtrace` (with `r`) because it can cause massive spikes
|
||||
in CPU which will make the app hang and you might need to forcefully kill
|
||||
processes.
|
||||
|
||||
```clojure
|
||||
#trace ; => Add this line to tell FlowStorm to instrument the function.
|
||||
(defn say-hello []
|
||||
(str "Hello world"))
|
||||
```
|
||||
|
||||
There are other ways to debug, but this is a good start.
|
||||
|
||||
## Enabling debug logs
|
||||
Calls to `log/debug` will not be printed to the console by default. It can be enabled under "Advanced settings" in the app:
|
||||
|
||||
|
||||
+486
-27
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"path": "aopalliance/aopalliance/1.0/aopalliance-1.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "0235ba8b489512805ac13a8f9ea77a1ca5ebe3e8",
|
||||
"sha256": "023a6xwv1kd9c4dq9jrsbvvj6398hgbr302w7h8kzkgd1xkyrp8a"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "args4j/args4j/2.33/args4j-2.33",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -90,29 +99,20 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "cider/cider-nrepl/0.44.0/cider-nrepl-0.44.0",
|
||||
"path": "cider/cider-nrepl/0.31.0/cider-nrepl-0.31.0",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "c3d3a729beaa728d0ee6a3678a48c880b6bc95f1",
|
||||
"sha256": "0klcppvydxlx9ji376mvz40yv3s7awq6p9yd57wigpfy4m2yv0w6"
|
||||
"sha1": "1f28a4a834a7a46cf24def971b1a705a6795c73a",
|
||||
"sha256": "0h4pyzy8rzzh567khvimw2cs8jr640kqxgaxvbfx1s5yfp56fka2"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "cider/orchard/0.21.0/orchard-0.21.0",
|
||||
"path": "cider/piggieback/0.4.1/piggieback-0.4.1",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "073617f16a132c7f20608d971244753d4e704129",
|
||||
"sha256": "1n2afbyhw9x9kvfna4m4x6n6pwjiqsqcayql644bw2932i1isrkj"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "cider/piggieback/0.5.2/piggieback-0.5.2",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "ecfd5c286a85db3f059e75c37fca5722d9e26f79",
|
||||
"sha256": "1ps9yf3cxmlm447hqkidjb5xry90n0wl3jk0jn28fagq31lzylkl"
|
||||
"sha1": "0a02a3e2ecd7a126ab60d8a44793342f20ced79b",
|
||||
"sha256": "142vl5np33akcrnn6pksi0rjfsmmi528villxsj6cwcndvybiw4m"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -161,6 +161,42 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/cognitect/aws/api/0.8.612/api-0.8.612",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "6bf53a6a318693e086bec6246a63b193f981b386",
|
||||
"sha256": "174csbi2whfqqw1pnna1a7pxwfa3q39marrs0sqjrwsvzqkwakvl"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/cognitect/aws/endpoints/1.1.12.321/endpoints-1.1.12.321",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "3bec2d7c7fe3b22b709e3ef8244d8f34406f3a8d",
|
||||
"sha256": "18mz7n8f07ki35h5v7v60rw9fh02fayda9l9cfa7bjy7w4a1yl1f"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/cognitect/aws/s3/822.2.1145.0/s3-822.2.1145.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "0c4d7c1bc3baa4a05c7ebdf6b672259f56a16d7e",
|
||||
"sha256": "0fhgikpn4ns494gaq1y8gch95silx1snvkg1n62ysnf1zyk42ckh"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/cognitect/http-client/1.0.115/http-client-1.0.115",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "1a84a105c286d00557cc6c3e96932e40439b387a",
|
||||
"sha256": "0k2dnyx4jywgzfizz9i9yb2v04cvzbqvyhyp2nv1pll0blv8h38v"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/cognitect/transit-clj/1.0.329/transit-clj-1.0.329",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -233,6 +269,24 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/github/jpmonettas/flow-storm-inst/3.7.5/flow-storm-inst-3.7.5",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "c76d1e07f3914d3f1c669d1aadc469037e7cff00",
|
||||
"sha256": "0xzygzibqslhsl90zxfm6k2izmvzrm5wixrb0xzfcihf9bwn9nya"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/github/jpmonettas/hansel/0.1.78/hansel-0.1.78",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "a4d916f9882f748201003880d2ee440e448b912f",
|
||||
"sha256": "0d3x5pab6p4mykmxhspz17w4zwcp52g7gmzma3vqsn4ym24xr5qm"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/google/auto/value/auto-value-annotations/1.6/auto-value-annotations-1.6",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -305,6 +359,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/google/inject/guice/4.2.2/guice-4.2.2-no_aop",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "fa13659f9128f4c011c8e1d06f137083b4876377",
|
||||
"sha256": "1zxg79l9jv86ar71pmw3abr43dgrgjz2hwbzifrx5909hsr5ykqg"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -503,6 +566,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "io/github/clojure/tools.build/0.9.4/tools.build-0.9.4",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "5d0a9ffeae76e1afa5b14ecaf6faffadea77dffd",
|
||||
"sha256": "1vivf7p05f30bcsiqn175df9vlxfvfpyx0z1snnfgin5mf6nhniq"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "io/methvin/directory-watcher/0.17.1/directory-watcher-0.17.1",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -530,6 +602,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "934c04d3cfef185a8008e7bf34331b79730a9d43",
|
||||
"sha256": "16xbi6mz75r1maw116njab6ln7hm9mhwrxshav4msmfdbccsajz0"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "javax/annotation/jsr250-api/1.0/jsr250-api-1.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -539,6 +620,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "javax/inject/javax.inject/1/javax.inject-1",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "6975da39a7040257bd51d21a231b76c915872d38 /home/maven/repository-staging/to-ibiblio/maven2/javax/inject/javax.inject/1/javax.inject-1.jar",
|
||||
"sha256": "1zz7gnahy2352345411rjlhsf64ikkc6z49dqcv1cj0clm271iwi"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "javax/servlet/servlet-api/2.5/servlet-api-2.5",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -584,15 +674,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "mx/cider/logjam/0.1.1/logjam-0.1.1",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "0e9a1c08d4e80e46be8ed8b8cb894bef5e56f39d",
|
||||
"sha256": "1p6hnacyfjn365r0li639lf9fnqpgx1cs7jz7066cn566wjw46az"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "net/cgrand/macrovich/0.2.1/macrovich-0.2.1",
|
||||
"host": "https://repo.clojars.org",
|
||||
@@ -621,11 +702,11 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "nrepl/nrepl/1.1.0/nrepl-1.1.0",
|
||||
"path": "nrepl/nrepl/1.0.0/nrepl-1.0.0",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "69f138d4a778c199e5d72446ca25998222ba0862",
|
||||
"sha256": "0n29xczgwpqv98vz36sdic98mf07dmzhjawlxd63p2s2zafkp1ss"
|
||||
"sha1": "f47774c43493efdc879d36b95ebd67ea0d9c890a",
|
||||
"sha256": "1fx5ssmixgqmklliw0ng8fjz41kkhys56x8dbwv9yqrfzws9f2x3"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -656,6 +737,204 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "c6842c86792ff03b9f1d1fe2aab8dc23aa6c6f0e",
|
||||
"sha256": "0kp9qwqmqp45axxddf9h8ai9yap2j86dl4il366py0vc902dj6fr"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/httpcomponents/httpclient/4.5.13/httpclient-4.5.13",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "e5f6cae5ca7ecaac1ec2827a9e2d65ae2869cada",
|
||||
"sha256": "0hzp3vrxbnyc6w86v671wp0zchb634rgrwwcc00m0skcarm05sbg"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/httpcomponents/httpcore/4.4.15/httpcore-4.4.15",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "7f2e0c573eaa7a74bac2e89b359e1f73d92a0a1d",
|
||||
"sha256": "0hmi3c0p5a2m2v53i0fqmdqm3677q2fz6n6ydpwi16j9ih4fvfiw"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/maven-artifact/3.8.6/maven-artifact-3.8.6",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "1637b7e8fc392e389752e79b827b883629285626",
|
||||
"sha256": "0ar5p715427zbqdl6bvkkr926s7xmp9vpc93m1v15qsgyp3a88ny"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/maven-builder-support/3.8.6/maven-builder-support-3.8.6",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "4d22a3faa8880efef2e960bb8a00c2a0b351c46a",
|
||||
"sha256": "1kll3ln7mx7mvbnc8s718fadcc1qckz7nxgqcfg0723fyd9rfg9x"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/maven-core/3.8.6/maven-core-3.8.6",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "f945f1f19452214d360d453d9357275313f1cfd9",
|
||||
"sha256": "1qaqyrxr1b2sz6d6amllynxw8c6cviydy1k8pi6ghlalipd515a3"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/maven-model/3.8.6/maven-model-3.8.6",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "8ad31867c493c63ac60a3fa42356a72d20f8457b",
|
||||
"sha256": "1c129h6n5daibjksa652ywbzji0fy4pd53qwk46bvsp7s326v60k"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/maven-model-builder/3.8.6/maven-model-builder-3.8.6",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "8323a726c657becbffc8ea807970935dde3e3903",
|
||||
"sha256": "1fyf717l3aa1jzwq0qss2i4d1m1rrpg6chq0sw6fr5319vmp98sw"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/maven-plugin-api/3.8.6/maven-plugin-api-3.8.6",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "4138e2e9b39f364902ac263888feb7b2407a298e",
|
||||
"sha256": "02ppxjnx9zly3dq7hwvh3x7jsmapirhsfznl9grid7r185h7yc9c"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/maven-repository-metadata/3.8.6/maven-repository-metadata-3.8.6",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "c60a7640e1b829e60f8791b5edf3cf56a6556aca",
|
||||
"sha256": "1zgasjbx3k0l3k7x2m2bkjsbgwnp5z3ywa4d8vmp46x85xk1y3m7"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/maven-resolver-provider/3.8.6/maven-resolver-provider-3.8.6",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "c6dadedc9f6b5c1c02d0a93afd1857460b0f501d",
|
||||
"sha256": "1a9ymv2hy7509hgib75g95my1xh6i9l7pjzzl14l3a3b6kqapcgv"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/maven-settings/3.8.6/maven-settings-3.8.6",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "9ba5114c6c61c66fbc6b93c73085dc5b15585524",
|
||||
"sha256": "0qcakn4g2h68s4s8blllw2889bhiqs8cr5056ywj8i954yhyzp36"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/maven-settings-builder/3.8.6/maven-settings-builder-3.8.6",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "e5c92138dffd1f9e5454cd8224cf8e18253b1803",
|
||||
"sha256": "1f44w8kz8v8k8an2n3i6lk48pb6sgjal6lcprzywash5qn4khnar"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/resolver/maven-resolver-api/1.8.2/maven-resolver-api-1.8.2",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "af6c5d8660e3c127c3987c385069d301848800a2",
|
||||
"sha256": "0pziii8ys35i4zi0sxw652pd04d2chr3hilpagf0qqpnah2qdf7n"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/resolver/maven-resolver-connector-basic/1.8.2/maven-resolver-connector-basic-1.8.2",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "013b77ee054cd269a7e14667419d202799db18a2",
|
||||
"sha256": "0w7im7wimjlzsdnvwsfvbji2i9sjaqc9xydb86qk3l3mg3cg2cbn"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/resolver/maven-resolver-impl/1.8.2/maven-resolver-impl-1.8.2",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "5f08b1e7d0bc89d8254cd46881a5e228c98303df",
|
||||
"sha256": "0slzdrhjhxl41lghrg3b0cxj07zqmmgkf5kqh1g5hksbplyy00n7"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/resolver/maven-resolver-named-locks/1.8.2/maven-resolver-named-locks-1.8.2",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "6d81987c220cdb9672f15a1f2ee3e4ba9f80d50f",
|
||||
"sha256": "1wf3xzv4xd7d21km0328s519kivaw1953mc33yq0mpdyarwhb6il"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/resolver/maven-resolver-spi/1.8.2/maven-resolver-spi-1.8.2",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "0d0768a341173c2ef88e8dbcab2f30ebfe7ef526",
|
||||
"sha256": "111vahiwcbaa28w98ksy8q3r23m7gdkqrr4bpy2jxd3vrazaq0d3"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/resolver/maven-resolver-transport-file/1.8.2/maven-resolver-transport-file-1.8.2",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "b9a7004de9850fe9dcff8325c3d51ef4e387ef70",
|
||||
"sha256": "0li1332vq03w11wdbni52qgkl2k6qdhskmfsdycqdqh9xm7c3f4c"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/resolver/maven-resolver-transport-http/1.8.2/maven-resolver-transport-http-1.8.2",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "dbc0b6f022c51857fb801ba135c30af056b4c071",
|
||||
"sha256": "0q0hhvwwfilzkvrza6czv4qhvcjh9shxaych2yah0nd6kvmlslsh"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/resolver/maven-resolver-util/1.8.2/maven-resolver-util-1.8.2",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "cfb9b2e4c71d2a819aa4519800c9687c74b71584",
|
||||
"sha256": "0jkvz7z07qsyp4i8p36n6zb53vmkh765fj4d3q7p8rbhnc601k52"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/maven/shared/maven-shared-utils/3.3.4/maven-shared-utils-3.3.4",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "f87a61adb1e12a00dcc6cc6005a51e693aa7c4ac",
|
||||
"sha256": "1nkdvyywfzbpd2ikpcrqb3zbz71rxc9gdqzsp0j0s172l32xj9br"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/babashka/sci/0.8.41/sci-0.8.41",
|
||||
"host": "https://repo.clojars.org",
|
||||
@@ -746,6 +1025,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/data.int-map/1.2.1/data.int-map-1.2.1",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "9e7e4e17329ecd46e92384d9e8475d77800d204e",
|
||||
"sha256": "055ip8l2y9004cydzz4i08p1ihlm5dz5fpknrln87ds9z9i5hiqh"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/data.json/2.4.0/data.json-2.4.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -764,6 +1052,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/data.xml/0.2.0-alpha8/data.xml-0.2.0-alpha8",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "c3dd8907b0a63a67082bc3091e304d9e1676d4b0",
|
||||
"sha256": "159spfgsn0grlfszzybycyrg6apmv2622aqgc5nc6m7ndm7hrcdm"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -782,6 +1079,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/java.classpath/1.0.0/java.classpath-1.0.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "015d06d1b304ac23104333bc8492a11bcc2e87e4",
|
||||
"sha256": "0vvxzv3vagwhx3zw4w30xhz2kxf1zbggnhn75kymqpja6080wkn1"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/math.combinatorics/0.2.0/math.combinatorics-0.2.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -836,6 +1142,24 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/tools.deps/0.17.1297/tools.deps-0.17.1297",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "7f27f66575190ddd5a343a77bba6911b0b4ec620",
|
||||
"sha256": "0mlf7k0s26v4dx25hmix79002ghzar7jynnvcm9pcp56dsg4k78n"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/tools.gitlibs/2.5.190/tools.gitlibs-2.5.190",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "f300f872ac84711ba6df61cbba923c515c289068",
|
||||
"sha256": "1i3jqzgfqiysy7np21gwrds32aay6a5p1xfnc3xp1jv30nnqd4bs"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/tools.logging/1.2.4/tools.logging-1.2.4",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -854,6 +1178,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/tools.namespace/1.4.4/tools.namespace-1.4.4",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "ba1078e3fe6ebc33119a7c09722afa9f708aef1f",
|
||||
"sha256": "01b3v2mii51krravn2rh1b9ysg9ph0mlb9c2dfbv0k6mckynhy04"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/tools.reader/1.3.7/tools.reader-1.3.7",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -863,6 +1196,114 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/codehaus/plexus/plexus-cipher/2.0/plexus-cipher-2.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "425ea8e534716b4bff1ea90f39bd76be951d651b",
|
||||
"sha256": "0fi0x8dq1skmxy8w7yhij7kshxig592k31zxmlgddzwyb9f1nzws"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/codehaus/plexus/plexus-classworlds/2.6.0/plexus-classworlds-2.6.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "8587e80fcb38e70b70fae8d5914b6376bfad6259",
|
||||
"sha256": "0j9m9zbw152gdqvigwh2l922z4nrxzbdbgky86f7qy4zqig7rxsj"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/codehaus/plexus/plexus-component-annotations/2.1.0/plexus-component-annotations-2.1.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "2f2147a6cc6a119a1b51a96f31d45c557f6244b9",
|
||||
"sha256": "1b5c6ay7nbphafqs6h7apars9xis0j06011685cgkg5mx5y63qxx"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/codehaus/plexus/plexus-interpolation/1.26/plexus-interpolation-1.26",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "25b919c664b79795ccde0ede5cee0fd68b544197",
|
||||
"sha256": "0qi633bwjwwaadmsrzjg6i0abpxkkz7xzg34llz112bqw4n43ddk"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/codehaus/plexus/plexus-sec-dispatcher/2.0/plexus-sec-dispatcher-2.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "f89c5080614ffd0764e49861895dbedde1b47237",
|
||||
"sha256": "1szwmkvlw8jf4fcvprfwicc85gy4l81v1055vmv02y2c1jb3jcc7"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/codehaus/plexus/plexus-utils/3.3.1/plexus-utils-3.3.1",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "9b41b2b76b1bfe3774411fe22f5868058a9fc822",
|
||||
"sha256": "0aig48q1jihh02l2glj8wp1qi74a6llvkf9fklj4z2aspv6hymsb"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/eclipse/jetty/jetty-client/9.4.48.v20220622/jetty-client-9.4.48.v20220622",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "fc2e953a7030045e1ca467d57e200856a170848e",
|
||||
"sha256": "058x9p1k8r5miwyn2za86nz27mbnmnk956crfmi2jsyk004zx2bz"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/eclipse/jetty/jetty-http/9.4.48.v20220622/jetty-http-9.4.48.v20220622",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "8cb235e70bda0c5e97a41e7ee0ea33ee7f5bcc6a",
|
||||
"sha256": "0phpz22cj5n8950pdbb97fwbmr4f4l8h8lvh0kg8ya159j0196f9"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/eclipse/jetty/jetty-io/9.4.48.v20220622/jetty-io-9.4.48.v20220622",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "b09b55209d0a304e542f779750a01f6914dc55e7",
|
||||
"sha256": "0iwb1d3a18yl2x6sbawi2cl5k6d24gmx2rmj1fks01c96jh60bsd"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/eclipse/jetty/jetty-util/9.4.48.v20220622/jetty-util-9.4.48.v20220622",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "7efc06f7ec0ff33d8c219bcc8c7415280c103669",
|
||||
"sha256": "11rbr3mayczff851l34ccbmkpi71dzy2havrqalvxd54ki2gvji4"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/eclipse/sisu/org.eclipse.sisu.inject/0.3.5/org.eclipse.sisu.inject-0.3.5",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "d4265dd4f0f1d7a06d80df5a5f475d5ff9c17140",
|
||||
"sha256": "04ys5z436vd2m8ipn5fifmwbvpcif7250k9sc2yx5qfwph8416f5"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/eclipse/sisu/org.eclipse.sisu.plexus/0.3.5/org.eclipse.sisu.plexus-0.3.5",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "d71996bb2e536f966b3b70e647067fff3b73d32f",
|
||||
"sha256": "1157yqjxvr24wpgy4zi4mnjpm3jjlmcmrmd7ywh6z0khdl4n2k3y"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -872,6 +1313,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/java-websocket/Java-WebSocket/1.5.3/Java-WebSocket-1.5.3",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "9c26b6a6e732a1242db576a50dc3a12e446e2717",
|
||||
"sha256": "0gvsbr49lr8ylv4k8gsnd9wyfc4gs5wr15klrmnyfmxnr4fw4vsd"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jboss/logging/jboss-logging/3.4.3.Final/jboss-logging-3.4.3.Final",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -935,6 +1385,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/slf4j/jcl-over-slf4j/1.7.36/jcl-over-slf4j-1.7.36",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "d877e195a05aca4a2f1ad2ff14bfec1393af4b5e",
|
||||
"sha256": "15ci04f0g0avrfih736hb6pg1jsfx5ciy4jx6qbjqxr3sa7wlmxb"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/slf4j/slf4j-api/2.0.9/slf4j-api-2.0.9",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
aopalliance/aopalliance/1.0/aopalliance-1.0.jar
|
||||
args4j/args4j/2.33/args4j-2.33.jar
|
||||
babashka/fs/0.2.16/fs-0.2.16.jar
|
||||
bidi/bidi/2.1.6/bidi-2.1.6.jar
|
||||
@@ -8,14 +9,17 @@ borkdude/edamame/1.3.23/edamame-1.3.23.jar
|
||||
borkdude/sci.impl.reflector/0.0.1/sci.impl.reflector-0.0.1.jar
|
||||
camel-snake-kebab/camel-snake-kebab/0.4.3/camel-snake-kebab-0.4.3.jar
|
||||
cheshire/cheshire/5.11.0/cheshire-5.11.0.jar
|
||||
cider/cider-nrepl/0.44.0/cider-nrepl-0.44.0.jar
|
||||
cider/orchard/0.21.0/orchard-0.21.0.jar
|
||||
cider/piggieback/0.5.2/piggieback-0.5.2.jar
|
||||
cider/cider-nrepl/0.31.0/cider-nrepl-0.31.0.jar
|
||||
cider/piggieback/0.4.1/piggieback-0.4.1.jar
|
||||
clj-kondo/clj-kondo/2024.03.13/clj-kondo-2024.03.13.jar
|
||||
cljs-bean/cljs-bean/1.9.0/cljs-bean-1.9.0.jar
|
||||
clout/clout/2.1.2/clout-2.1.2.jar
|
||||
com/andrewmcveigh/cljs-time/0.5.2/cljs-time-0.5.2.jar
|
||||
com/bhauman/cljs-test-display/0.1.1/cljs-test-display-0.1.1.jar
|
||||
com/cognitect/aws/api/0.8.612/api-0.8.612.jar
|
||||
com/cognitect/aws/endpoints/1.1.12.321/endpoints-1.1.12.321.jar
|
||||
com/cognitect/aws/s3/822.2.1145.0/s3-822.2.1145.0.jar
|
||||
com/cognitect/http-client/1.0.115/http-client-1.0.115.jar
|
||||
com/cognitect/transit-clj/1.0.329/transit-clj-1.0.329.jar
|
||||
com/cognitect/transit-cljs/0.8.280/transit-cljs-0.8.280.jar
|
||||
com/cognitect/transit-java/1.0.362/transit-java-1.0.362.jar
|
||||
@@ -24,6 +28,8 @@ com/fasterxml/jackson/core/jackson-core/2.13.3/jackson-core-2.13.3.jar
|
||||
com/fasterxml/jackson/dataformat/jackson-dataformat-cbor/2.13.3/jackson-dataformat-cbor-2.13.3.jar
|
||||
com/fasterxml/jackson/dataformat/jackson-dataformat-smile/2.13.3/jackson-dataformat-smile-2.13.3.jar
|
||||
com/github/javaparser/javaparser-core/3.25.3/javaparser-core-3.25.3.jar
|
||||
com/github/jpmonettas/flow-storm-inst/3.7.5/flow-storm-inst-3.7.5.jar
|
||||
com/github/jpmonettas/hansel/0.1.78/hansel-0.1.78.jar
|
||||
com/google/auto/value/auto-value-annotations/1.6/auto-value-annotations-1.6.jar
|
||||
com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar
|
||||
com/google/code/gson/gson/2.9.1/gson-2.9.1.jar
|
||||
@@ -32,6 +38,7 @@ com/google/errorprone/error_prone_annotations/2.15.0/error_prone_annotations-2.1
|
||||
com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar
|
||||
com/google/guava/guava/31.0.1-jre/guava-31.0.1-jre.jar
|
||||
com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
|
||||
com/google/inject/guice/4.2.2/guice-4.2.2-no_aop.jar
|
||||
com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar
|
||||
com/google/javascript/closure-compiler-unshaded/v20230802/closure-compiler-unshaded-v20230802.jar
|
||||
com/google/protobuf/protobuf-java/3.21.12/protobuf-java-3.21.12.jar
|
||||
@@ -54,23 +61,47 @@ hiccup/hiccup/1.0.5/hiccup-1.0.5.jar
|
||||
http-kit/http-kit/2.2.0/http-kit-2.2.0.jar
|
||||
instaparse/instaparse/1.4.0/instaparse-1.4.0.jar
|
||||
io/aviso/pretty/1.4.4/pretty-1.4.4.jar
|
||||
io/github/clojure/tools.build/0.9.4/tools.build-0.9.4.jar
|
||||
io/methvin/directory-watcher/0.17.1/directory-watcher-0.17.1.jar
|
||||
io/replikativ/datalog-parser/0.2.25/datalog-parser-0.2.25.jar
|
||||
io/undertow/undertow-core/2.3.10.Final/undertow-core-2.3.10.Final.jar
|
||||
javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.jar
|
||||
javax/annotation/jsr250-api/1.0/jsr250-api-1.0.jar
|
||||
javax/inject/javax.inject/1/javax.inject-1.jar
|
||||
javax/servlet/servlet-api/2.5/servlet-api-2.5.jar
|
||||
javax/xml/bind/jaxb-api/2.3.0/jaxb-api-2.3.0.jar
|
||||
medley/medley/0.8.2/medley-0.8.2.jar
|
||||
metosin/malli/0.13.0/malli-0.13.0.jar
|
||||
mvxcvi/arrangement/2.1.0/arrangement-2.1.0.jar
|
||||
mx/cider/logjam/0.1.1/logjam-0.1.1.jar
|
||||
net/cgrand/macrovich/0.2.1/macrovich-0.2.1.jar
|
||||
net/java/dev/jna/jna/5.12.1/jna-5.12.1.jar
|
||||
nrepl/bencode/1.1.0/bencode-1.1.0.jar
|
||||
nrepl/nrepl/1.1.0/nrepl-1.1.0.jar
|
||||
nrepl/nrepl/1.0.0/nrepl-1.0.0.jar
|
||||
nubank/matcher-combinators/3.8.8/matcher-combinators-3.8.8.jar
|
||||
org/apache/ant/ant/1.10.11/ant-1.10.11.jar
|
||||
org/apache/ant/ant-launcher/1.10.11/ant-launcher-1.10.11.jar
|
||||
org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.jar
|
||||
org/apache/httpcomponents/httpclient/4.5.13/httpclient-4.5.13.jar
|
||||
org/apache/httpcomponents/httpcore/4.4.15/httpcore-4.4.15.jar
|
||||
org/apache/maven/maven-artifact/3.8.6/maven-artifact-3.8.6.jar
|
||||
org/apache/maven/maven-builder-support/3.8.6/maven-builder-support-3.8.6.jar
|
||||
org/apache/maven/maven-core/3.8.6/maven-core-3.8.6.jar
|
||||
org/apache/maven/maven-model/3.8.6/maven-model-3.8.6.jar
|
||||
org/apache/maven/maven-model-builder/3.8.6/maven-model-builder-3.8.6.jar
|
||||
org/apache/maven/maven-plugin-api/3.8.6/maven-plugin-api-3.8.6.jar
|
||||
org/apache/maven/maven-repository-metadata/3.8.6/maven-repository-metadata-3.8.6.jar
|
||||
org/apache/maven/maven-resolver-provider/3.8.6/maven-resolver-provider-3.8.6.jar
|
||||
org/apache/maven/maven-settings/3.8.6/maven-settings-3.8.6.jar
|
||||
org/apache/maven/maven-settings-builder/3.8.6/maven-settings-builder-3.8.6.jar
|
||||
org/apache/maven/resolver/maven-resolver-api/1.8.2/maven-resolver-api-1.8.2.jar
|
||||
org/apache/maven/resolver/maven-resolver-connector-basic/1.8.2/maven-resolver-connector-basic-1.8.2.jar
|
||||
org/apache/maven/resolver/maven-resolver-impl/1.8.2/maven-resolver-impl-1.8.2.jar
|
||||
org/apache/maven/resolver/maven-resolver-named-locks/1.8.2/maven-resolver-named-locks-1.8.2.jar
|
||||
org/apache/maven/resolver/maven-resolver-spi/1.8.2/maven-resolver-spi-1.8.2.jar
|
||||
org/apache/maven/resolver/maven-resolver-transport-file/1.8.2/maven-resolver-transport-file-1.8.2.jar
|
||||
org/apache/maven/resolver/maven-resolver-transport-http/1.8.2/maven-resolver-transport-http-1.8.2.jar
|
||||
org/apache/maven/resolver/maven-resolver-util/1.8.2/maven-resolver-util-1.8.2.jar
|
||||
org/apache/maven/shared/maven-shared-utils/3.3.4/maven-shared-utils-3.3.4.jar
|
||||
org/babashka/sci/0.8.41/sci-0.8.41.jar
|
||||
org/babashka/sci.impl.types/0.0.2/sci.impl.types-0.0.2.jar
|
||||
org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar
|
||||
@@ -81,20 +112,39 @@ org/clojure/core.cache/1.0.225/core.cache-1.0.225.jar
|
||||
org/clojure/core.memoize/1.0.253/core.memoize-1.0.253.jar
|
||||
org/clojure/core.rrb-vector/0.1.2/core.rrb-vector-0.1.2.jar
|
||||
org/clojure/core.specs.alpha/0.2.62/core.specs.alpha-0.2.62.jar
|
||||
org/clojure/data.int-map/1.2.1/data.int-map-1.2.1.jar
|
||||
org/clojure/data.json/2.4.0/data.json-2.4.0.jar
|
||||
org/clojure/data.priority-map/1.1.0/data.priority-map-1.1.0.jar
|
||||
org/clojure/data.xml/0.2.0-alpha8/data.xml-0.2.0-alpha8.jar
|
||||
org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar
|
||||
org/clojure/google-closure-library-third-party/0.0-20230227-c7c0a541/google-closure-library-third-party-0.0-20230227-c7c0a541.jar
|
||||
org/clojure/java.classpath/1.0.0/java.classpath-1.0.0.jar
|
||||
org/clojure/math.combinatorics/0.2.0/math.combinatorics-0.2.0.jar
|
||||
org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.jar
|
||||
org/clojure/test.check/1.1.1/test.check-1.1.1.jar
|
||||
org/clojure/tools.analyzer/1.1.0/tools.analyzer-1.1.0.jar
|
||||
org/clojure/tools.analyzer.jvm/1.2.2/tools.analyzer.jvm-1.2.2.jar
|
||||
org/clojure/tools.cli/1.0.206/tools.cli-1.0.206.jar
|
||||
org/clojure/tools.deps/0.17.1297/tools.deps-0.17.1297.jar
|
||||
org/clojure/tools.gitlibs/2.5.190/tools.gitlibs-2.5.190.jar
|
||||
org/clojure/tools.logging/1.2.4/tools.logging-1.2.4.jar
|
||||
org/clojure/tools.macro/0.1.5/tools.macro-0.1.5.jar
|
||||
org/clojure/tools.namespace/1.4.4/tools.namespace-1.4.4.jar
|
||||
org/clojure/tools.reader/1.3.7/tools.reader-1.3.7.jar
|
||||
org/codehaus/plexus/plexus-cipher/2.0/plexus-cipher-2.0.jar
|
||||
org/codehaus/plexus/plexus-classworlds/2.6.0/plexus-classworlds-2.6.0.jar
|
||||
org/codehaus/plexus/plexus-component-annotations/2.1.0/plexus-component-annotations-2.1.0.jar
|
||||
org/codehaus/plexus/plexus-interpolation/1.26/plexus-interpolation-1.26.jar
|
||||
org/codehaus/plexus/plexus-sec-dispatcher/2.0/plexus-sec-dispatcher-2.0.jar
|
||||
org/codehaus/plexus/plexus-utils/3.3.1/plexus-utils-3.3.1.jar
|
||||
org/eclipse/jetty/jetty-client/9.4.48.v20220622/jetty-client-9.4.48.v20220622.jar
|
||||
org/eclipse/jetty/jetty-http/9.4.48.v20220622/jetty-http-9.4.48.v20220622.jar
|
||||
org/eclipse/jetty/jetty-io/9.4.48.v20220622/jetty-io-9.4.48.v20220622.jar
|
||||
org/eclipse/jetty/jetty-util/9.4.48.v20220622/jetty-util-9.4.48.v20220622.jar
|
||||
org/eclipse/sisu/org.eclipse.sisu.inject/0.3.5/org.eclipse.sisu.inject-0.3.5.jar
|
||||
org/eclipse/sisu/org.eclipse.sisu.plexus/0.3.5/org.eclipse.sisu.plexus-0.3.5.jar
|
||||
org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA.jar
|
||||
org/java-websocket/Java-WebSocket/1.5.3/Java-WebSocket-1.5.3.jar
|
||||
org/jboss/logging/jboss-logging/3.4.3.Final/jboss-logging-3.4.3.Final.jar
|
||||
org/jboss/threads/jboss-threads/3.5.0.Final/jboss-threads-3.5.0.Final.jar
|
||||
org/jboss/xnio/xnio-api/3.8.8.Final/xnio-api-3.8.8.Final.jar
|
||||
@@ -102,6 +152,7 @@ org/jboss/xnio/xnio-nio/3.8.8.Final/xnio-nio-3.8.8.Final.jar
|
||||
org/jspecify/jspecify/0.2.0/jspecify-0.2.0.jar
|
||||
org/msgpack/msgpack/0.6.12/msgpack-0.6.12.jar
|
||||
org/ow2/asm/asm/9.4/asm-9.4.jar
|
||||
org/slf4j/jcl-over-slf4j/1.7.36/jcl-over-slf4j-1.7.36.jar
|
||||
org/slf4j/slf4j-api/2.0.9/slf4j-api-2.0.9.jar
|
||||
org/slf4j/slf4j-nop/2.0.9/slf4j-nop-2.0.9.jar
|
||||
org/wildfly/client/wildfly-client-config/1.0.1.Final/wildfly-client-config-1.0.1.Final.jar
|
||||
|
||||
@@ -62,7 +62,7 @@ findByRegex() {
|
||||
|
||||
# list of store entries to delete
|
||||
declare -a found
|
||||
|
||||
|
||||
# for each entry find the source and derivation
|
||||
for mainPath in ${drvPaths}; do
|
||||
findRelated "${mainPath}"
|
||||
@@ -87,7 +87,7 @@ nixResultPath="${1}"
|
||||
if [[ -n "${nixResultPath}" ]]; then
|
||||
# if provided we can narrow down what to clean based on result path
|
||||
toDelete=$(findByResult "${nixResultPath}")
|
||||
else
|
||||
else
|
||||
# use regular expression that should match all status-mobile build artifacts
|
||||
toDelete=$(findByRegex '.*-status-(mobile|go)-(shell|source|build|patched-npm-gradle-modules).*')
|
||||
fi
|
||||
|
||||
+2
-1
@@ -99,7 +99,8 @@
|
||||
"prettier": "^2.8.8",
|
||||
"process": "0.11.10",
|
||||
"react-test-renderer": "18.1.0",
|
||||
"shadow-cljs": "2.26.2"
|
||||
"shadow-cljs": "2.26.2",
|
||||
"websocket": "^1.0.35"
|
||||
},
|
||||
"binary": {
|
||||
"module_name": "status_nodejs_addon",
|
||||
|
||||
+5
-1
@@ -13,6 +13,7 @@
|
||||
[funcool/promesa "11.0.678"]
|
||||
|
||||
;; Dev dependencies
|
||||
[com.github.jpmonettas/flow-storm-inst "3.7.5"]
|
||||
[refactor-nrepl "3.9.1"]
|
||||
[cider/cider-nrepl "0.31.0"]
|
||||
[cider/piggieback "0.4.1"]
|
||||
@@ -53,7 +54,10 @@
|
||||
:dev {:devtools {:before-load-async status-im.setup.hot-reload/before-reload
|
||||
:after-load-async status-im.setup.hot-reload/reload
|
||||
:build-notify status-im.setup.hot-reload/build-notify
|
||||
:preloads [re-frisk-remote.preload
|
||||
:preloads [;; The official recommendation is to
|
||||
;; load the debugger preload first.
|
||||
flow-storm.api
|
||||
re-frisk-remote.preload
|
||||
status-im.setup.schema-preload
|
||||
;; In order to use component test helpers in the REPL we
|
||||
;; need to preload namespaces that are not normally required
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
(get-in result [:db :pagination-info chat-id :cursor-clock-value])))
|
||||
(is (= cursor (get-in result [:db :pagination-info chat-id :cursor]))))))))))
|
||||
|
||||
(deftest message-loaded?
|
||||
(deftest message-loaded?-test
|
||||
(testing "it returns false when it's not in loaded message"
|
||||
(is
|
||||
(not
|
||||
@@ -117,7 +117,7 @@
|
||||
"a"
|
||||
"message-id"))))
|
||||
|
||||
(deftest earlier-than-deleted-at?
|
||||
(deftest earlier-than-deleted-at?-test
|
||||
(testing "it returns true when the clock-value is the same as the deleted-clock-value in chat"
|
||||
(is (#'legacy.status-im.chat.models.message/earlier-than-deleted-at?
|
||||
{:chats {"a" {:deleted-at-clock-value 1}}}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
(def from
|
||||
"0x0424a68f89ba5fcd5e0640c1e1f591d561fa4125ca4e2a43592bc4123eca10ce064e522c254bb83079ba404327f6eafc01ec90a1444331fe769d3f3a7f90b0dde1")
|
||||
|
||||
(deftest message<-rpc
|
||||
(deftest message<-rpc-test
|
||||
(testing "message from RPC"
|
||||
(let [expected {:message-id message-id
|
||||
:content {:chat-id chat-id
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.ethereum.mnemonic :as mnemonic]))
|
||||
|
||||
(deftest valid-length?
|
||||
(deftest valid-length?-test
|
||||
(is (not (mnemonic/valid-length? "rate rate")))
|
||||
(is (not (mnemonic/valid-length? (string/join " " (repeat 13 "rate")))))
|
||||
(is (not (mnemonic/valid-length? (string/join " " (repeat 16 "rate")))))
|
||||
@@ -14,19 +14,19 @@
|
||||
(is (mnemonic/valid-length? (string/join " " (repeat 21 "rate"))))
|
||||
(is (mnemonic/valid-length? (string/join " " (repeat 24 "rate")))))
|
||||
|
||||
(deftest valid-words?
|
||||
(deftest valid-words?-test
|
||||
(is (not (mnemonic/valid-words? "rate! rate")))
|
||||
(is (not (mnemonic/valid-words? "rate rate rate rate rate rate rate rate rate rate rate rate?")))
|
||||
(is (mnemonic/valid-words? "rate rate rate rate rate rate rate rate rate rate rate rate")))
|
||||
|
||||
(deftest passphrase->words?
|
||||
(deftest passphrase->words?-test
|
||||
(is (= ["one" "two" "three" "for" "five" "six" "seven" "height" "nine" "ten" "eleven" "twelve"]
|
||||
(mnemonic/passphrase->words "one two three for five six seven height nine ten eleven twelve"))
|
||||
(= ["one" "two" "three" "for" "five" "six" "seven" "height" "nine" "ten" "eleven" "twelve"]
|
||||
(mnemonic/passphrase->words
|
||||
" one two three for five six seven height nine ten eleven twelve "))))
|
||||
|
||||
(deftest status-generate-phrase?
|
||||
(deftest status-generate-phrase?-test
|
||||
(is (mnemonic/status-generated-phrase?
|
||||
"game buzz method pretty olympic fat quit display velvet unveil marine crater"))
|
||||
(is (not (mnemonic/status-generated-phrase?
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[clojure.test :refer-macros [deftest is testing]]
|
||||
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]))
|
||||
|
||||
(deftest test-multiaccount-update
|
||||
(deftest multiaccount-update-test
|
||||
;;TODO this test case actually shows that we are doing a needless rpc call when
|
||||
;;there is no changes, but it is an edge case that shouldn't really happen
|
||||
(let [efx (multiaccounts.update/multiaccount-update
|
||||
@@ -15,7 +15,7 @@
|
||||
(is (json-rpc "settings_saveSetting"))
|
||||
(is (= (get-in efx [:db :profile/profile]) {:not-empty "would throw an error if was empty"}))))
|
||||
|
||||
(deftest test-clean-seed-phrase
|
||||
(deftest clean-seed-phrase-test
|
||||
(let [efx (multiaccounts.update/clean-seed-phrase
|
||||
{:db {:profile/profile {:mnemonic "lalalala"}}}
|
||||
{})
|
||||
@@ -23,7 +23,7 @@
|
||||
(is (json-rpc "settings_saveSetting"))
|
||||
(is (nil? (get-in efx [:db :profile/profile :mnemonic])))))
|
||||
|
||||
(deftest test-update-multiaccount-account-name
|
||||
(deftest update-multiaccount-account-name-test
|
||||
(let [cofx {:db {:profile/profile {:key-uid 1
|
||||
:name "name"
|
||||
:preferred-name "preferred-name"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[cljs.test :refer-macros [deftest is]]
|
||||
[legacy.status-im.utils.random :as random]))
|
||||
|
||||
(deftest test-seeded-rand-int
|
||||
(deftest seeded-rand-int-test
|
||||
;try with one seed
|
||||
(let [seed 0
|
||||
gen (random/rand-gen seed)]
|
||||
@@ -40,7 +40,7 @@
|
||||
(is (= (random/seeded-rand-int gen 10) 7))
|
||||
(is (= (random/seeded-rand-int gen 10) 8))))
|
||||
|
||||
(deftest test-seeded-rand-int-boundaries
|
||||
(deftest seeded-rand-int-boundaries-test
|
||||
(let [seed "6ec565f4fec866a54761524f603cf037e20c2bfa"
|
||||
n 10
|
||||
gen (random/rand-gen seed)
|
||||
@@ -53,7 +53,7 @@
|
||||
;calls got us the same number.
|
||||
(is (> (count sample) 1))))
|
||||
|
||||
(deftest test-seeded-rand-nth
|
||||
(deftest seeded-rand-nth-test
|
||||
(let [seed "6ec565f4fec866a54761524f603cf037e20c2bfa"
|
||||
gen (random/rand-gen seed)
|
||||
coll [:a :b :c :d :e :f :g]]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.utils.signing-phrase.core :refer [generate]]))
|
||||
|
||||
(deftest test-generate
|
||||
(deftest generate-test
|
||||
(doseq [_ (range 30)]
|
||||
(let [result (generate)]
|
||||
(is (not (string/starts-with? result " ")))
|
||||
|
||||
+20
-12
@@ -359,9 +359,11 @@
|
||||
|
||||
(defn sign-message
|
||||
"NOTE: beware, the password in rpcParams has to be sha3 hashed"
|
||||
[rpcParams callback]
|
||||
(log/debug "[native-module] sign-message")
|
||||
(.signMessage ^js (encryption) rpcParams callback))
|
||||
([rpcParams]
|
||||
(native-utils/promisify-native-module-call sign-message rpcParams))
|
||||
([rpcParams callback]
|
||||
(log/debug "[native-module] sign-message")
|
||||
(.signMessage ^js (encryption) rpcParams callback)))
|
||||
|
||||
(defn recover-message
|
||||
[rpcParams callback]
|
||||
@@ -376,15 +378,19 @@
|
||||
|
||||
(defn sign-typed-data
|
||||
"NOTE: beware, the password has to be sha3 hashed"
|
||||
[data account hashed-password callback]
|
||||
(log/debug "[native-module] sign-typed-data")
|
||||
(.signTypedData ^js (encryption) data account hashed-password callback))
|
||||
([data account hashed-password]
|
||||
(native-utils/promisify-native-module-call sign-typed-data data account hashed-password))
|
||||
([data account hashed-password callback]
|
||||
(log/debug "[native-module] sign-typed-data")
|
||||
(.signTypedData ^js (encryption) data account hashed-password callback)))
|
||||
|
||||
(defn sign-typed-data-v4
|
||||
"NOTE: beware, the password has to be sha3 hashed"
|
||||
[data account hashed-password callback]
|
||||
(log/debug "[native-module] sign-typed-data-v4")
|
||||
(.signTypedDataV4 ^js (encryption) data account hashed-password callback))
|
||||
([data account hashed-password]
|
||||
(native-utils/promisify-native-module-call sign-typed-data-v4 data account hashed-password))
|
||||
([data account hashed-password callback]
|
||||
(log/debug "[native-module] sign-typed-data-v4")
|
||||
(.signTypedDataV4 ^js (encryption) data account hashed-password callback)))
|
||||
|
||||
(defn send-logs
|
||||
[dbJson js-logs callback]
|
||||
@@ -521,9 +527,11 @@
|
||||
|
||||
(defn validate-mnemonic
|
||||
"Validate that a mnemonic conforms to BIP39 dictionary/checksum standards"
|
||||
[mnemonic callback]
|
||||
(log/debug "[native-module] validate-mnemonic")
|
||||
(.validateMnemonic ^js (utils) mnemonic callback))
|
||||
([mnemonic]
|
||||
(native-utils/promisify-native-module-call validate-mnemonic mnemonic))
|
||||
([mnemonic callback]
|
||||
(log/debug "[native-module] validate-mnemonic")
|
||||
(.validateMnemonic ^js (utils) mnemonic callback)))
|
||||
|
||||
(defn delete-multiaccount
|
||||
"Delete multiaccount from database, deletes multiaccount's database and
|
||||
|
||||
@@ -44,14 +44,14 @@
|
||||
:monospace? - boolean (default: false) - use monospace font
|
||||
:lowercase? - boolean (default: false) - lowercase text
|
||||
:neutral? - boolean (default: false) - use neutral colors variant"
|
||||
[{:keys [full-name customization-color size monospace? lowercase? neutral?]
|
||||
[{:keys [full-name customization-color size monospace? lowercase? neutral? container-style]
|
||||
:or {size biggest-possible}}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
circle-size (:size (size properties))
|
||||
small? (check-if-size-small size)
|
||||
initials (utils.string/get-initials full-name (if small? 1 2))]
|
||||
[rn/view
|
||||
{:style (style/container circle-size customization-color neutral? theme)}
|
||||
{:style (merge (style/container circle-size customization-color neutral? theme) container-style)}
|
||||
[text/text
|
||||
{:accessibility-label :wallet-user-avatar
|
||||
:size (:font-size (size properties))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[cljs.test :refer-macros [deftest is testing]]
|
||||
[quo.components.graph.utils :as utils]))
|
||||
|
||||
(deftest find-highest-value
|
||||
(deftest find-highest-value-test
|
||||
(testing "Find highest value with a single map"
|
||||
(let [data [{:value 5}]]
|
||||
(is (= (utils/find-highest-value data) 5))))
|
||||
@@ -24,7 +24,7 @@
|
||||
(let [data (vec (for [num (range 1000)] {:value num}))]
|
||||
(is (= (utils/find-highest-value data) 999)))))
|
||||
|
||||
(deftest find-lowest-value
|
||||
(deftest find-lowest-value-test
|
||||
(testing "Find lowest value with a single map"
|
||||
(let [data [{:value 5}]]
|
||||
(is (= (utils/find-lowest-value data) 5))))
|
||||
@@ -45,7 +45,7 @@
|
||||
(let [data (vec (for [num (range 1000)] {:value num}))]
|
||||
(is (= (utils/find-lowest-value data) 0)))))
|
||||
|
||||
(deftest downsample-data
|
||||
(deftest downsample-data-test
|
||||
(testing "Downsampling is applied correctly when needed"
|
||||
(let [input-data [1 2 3 4 5 6 7 8 9 10]
|
||||
max-array-size 5
|
||||
@@ -77,7 +77,7 @@
|
||||
; 1000
|
||||
(is (= (utils/downsample-data large-data max-array-size) expected-output)))))
|
||||
|
||||
(deftest format-compact-number
|
||||
(deftest format-compact-number-test
|
||||
(testing "Format a whole number less than 1000"
|
||||
(is (= (utils/format-compact-number 567) "567")))
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
(testing "Format a number in trillions"
|
||||
(is (= (utils/format-compact-number 1234567890000) "1.23T"))))
|
||||
|
||||
(deftest calculate-x-axis-labels
|
||||
(deftest calculate-x-axis-labels-test
|
||||
(testing "Calculate x-axis labels with a small array and fewer elements"
|
||||
(let [data [{:date "2023-01-01"} {:date "2023-01-02"} {:date "2023-01-03"} {:date "2023-01-04"}]]
|
||||
(is (= (utils/calculate-x-axis-labels data 2) '("2023-01-01" "2023-01-03")))))
|
||||
@@ -123,7 +123,7 @@
|
||||
(let [data (vec (for [i (range 10)] {:date (str "2023-01-0" (inc i))}))]
|
||||
(is (= (utils/calculate-x-axis-labels data 1) '("2023-01-01"))))))
|
||||
|
||||
(deftest calculate-y-axis-labels
|
||||
(deftest calculate-y-axis-labels-test
|
||||
(testing "Calculate y-axis labels with positive values"
|
||||
(is (= (utils/calculate-y-axis-labels 0 10 5) ["0" "10" "20" "30" "40" "50"])))
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
(testing "Calculate y-axis labels with large step value and number of steps"
|
||||
(is (= (utils/calculate-y-axis-labels 100 1000 3) ["100" "1.1k" "2.1k" "3.1k"]))))
|
||||
|
||||
(deftest calculate-rounded-max
|
||||
(deftest calculate-rounded-max-test
|
||||
(testing "Calculate rounded max with a whole number"
|
||||
(is (= (utils/calculate-rounded-max 100) 108)))
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
(testing "Calculate rounded max with a large number"
|
||||
(is (= (utils/calculate-rounded-max 1000) 1052))))
|
||||
|
||||
(deftest calculate-rounded-min
|
||||
(deftest calculate-rounded-min-test
|
||||
(testing "Calculate rounded min with a whole number"
|
||||
(is (= (utils/calculate-rounded-min 157) 100)))
|
||||
|
||||
|
||||
@@ -28,6 +28,19 @@
|
||||
:border colors/danger-50-opa-10
|
||||
:icon colors/danger-50
|
||||
:text colors/danger-50}
|
||||
:close-button colors/white}
|
||||
:shell {:default {:bg colors/white-opa-5
|
||||
:border colors/white-opa-10
|
||||
:icon colors/white-opa-70
|
||||
:text colors/white}
|
||||
:informative {:bg colors/primary-50-opa-5
|
||||
:border colors/primary-50-opa-10
|
||||
:icon colors/primary-50
|
||||
:text colors/white}
|
||||
:error {:bg colors/danger-50-opa-5
|
||||
:border colors/danger-50-opa-10
|
||||
:icon colors/danger-50
|
||||
:text colors/danger-50}
|
||||
:close-button colors/white}})
|
||||
|
||||
(defn get-color
|
||||
|
||||
@@ -53,11 +53,11 @@
|
||||
:button-label string
|
||||
:on-button-press function
|
||||
:on-close function"
|
||||
[{:keys [type closed? icon style button-label
|
||||
[{:keys [type closed? blur? icon style button-label
|
||||
on-button-press on-close no-icon-color? icon-size]}
|
||||
message]
|
||||
(when-not closed?
|
||||
(let [theme (quo.theme/use-theme)
|
||||
(let [theme (if blur? :shell (quo.theme/use-theme))
|
||||
include-button? (not (string/blank? button-label))]
|
||||
[rn/view
|
||||
{:accessibility-label :information-box
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
(defn recovery-phrase-input
|
||||
[{:keys [customization-color blur? on-focus on-blur mark-errors?
|
||||
error-pred-current-word error-pred-written-words word-limit
|
||||
container-style placeholder-text-color]
|
||||
container-style placeholder-text-color on-input-ref]
|
||||
:or {customization-color :blue
|
||||
word-limit ##Inf
|
||||
error-pred-current-word (constantly false)
|
||||
@@ -60,7 +60,8 @@
|
||||
extra-props (apply dissoc props custom-props)]
|
||||
[rn/view {:style (style/container container-style)}
|
||||
[rn/text-input
|
||||
(merge {:accessibility-label :recovery-phrase-input
|
||||
(merge {:ref on-input-ref
|
||||
:accessibility-label :recovery-phrase-input
|
||||
:style (style/input theme)
|
||||
:placeholder-text-color (or placeholder-text-color
|
||||
(style/placeholder-color state theme blur?))
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
(defn overlay-background
|
||||
[type]
|
||||
(let [background-color (case type
|
||||
:shell colors/neutral-80-opa-80-blur
|
||||
:shell colors/overlay-background-blur
|
||||
:drawer colors/neutral-100-opa-70-blur
|
||||
nil)]
|
||||
{:position :absolute
|
||||
|
||||
@@ -7,13 +7,12 @@
|
||||
{:left 0
|
||||
:right 0
|
||||
:padding-horizontal 20
|
||||
:padding-top (when label 12)
|
||||
:padding-top (if label 12 8)
|
||||
:padding-bottom 8})
|
||||
|
||||
(defn settings-items
|
||||
[{:keys [label blur?]} theme]
|
||||
{:margin-top (if label 12 4)
|
||||
:border-radius 16
|
||||
[{:keys [blur?]} theme]
|
||||
{:border-radius 16
|
||||
:background-color (if blur?
|
||||
colors/white-opa-5
|
||||
(colors/theme-colors colors/white colors/neutral-95 theme))
|
||||
@@ -24,9 +23,10 @@
|
||||
|
||||
(defn label
|
||||
[{:keys [blur?]} theme]
|
||||
{:color (if blur?
|
||||
colors/white-opa-40
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})
|
||||
{:margin-bottom 12
|
||||
:color (if blur?
|
||||
colors/white-opa-40
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})
|
||||
|
||||
(def reorder-items
|
||||
{:margin-top 12})
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def container
|
||||
{:flex-direction :row
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:justify-content :space-between})
|
||||
|
||||
(def right-counter
|
||||
|
||||
@@ -11,4 +11,4 @@
|
||||
|
||||
(defn alert-icon-color
|
||||
[theme]
|
||||
(colors/theme-colors colors/neutral-50 colors/white theme))
|
||||
(colors/theme-colors colors/neutral-80-opa-60 colors/white-70-blur theme))
|
||||
|
||||
@@ -12,29 +12,38 @@
|
||||
|
||||
(defn card
|
||||
[{:keys [customization-color type theme pressed? metrics?]}]
|
||||
{:width 161
|
||||
:height (if metrics? 88 68)
|
||||
:background-color (when (not= :watch-only type)
|
||||
(colors/theme-colors
|
||||
(colors/resolve-color customization-color
|
||||
theme
|
||||
(when (= :missing-keypair type) (if pressed? 20 10)))
|
||||
(colors/resolve-color customization-color
|
||||
theme
|
||||
(when (= :missing-keypair type) (if pressed? 30 20)))
|
||||
theme))
|
||||
:border-radius 16
|
||||
:border-width 1
|
||||
:border-color (if (or (= :missing-keypair type)
|
||||
(= :watch-only type))
|
||||
(colors/theme-colors
|
||||
(if pressed? colors/neutral-80-opa-10 colors/neutral-80-opa-5)
|
||||
(if pressed? colors/white-opa-10 colors/white-opa-5)
|
||||
theme)
|
||||
colors/neutral-80-opa-10)
|
||||
:padding-horizontal 12
|
||||
:padding-top 6
|
||||
:padding-bottom 9})
|
||||
(let [missing-keypair? (= :missing-keypair type)
|
||||
watch-only? (= :watch-only type)]
|
||||
{:width 161
|
||||
:height (if metrics? 88 68)
|
||||
:background-color (when (and (not missing-keypair?) (not watch-only?))
|
||||
(colors/theme-colors
|
||||
(colors/resolve-color customization-color
|
||||
theme
|
||||
(when missing-keypair? (if pressed? 20 10)))
|
||||
(colors/resolve-color customization-color
|
||||
theme
|
||||
(when missing-keypair? (if pressed? 30 20)))
|
||||
theme))
|
||||
:border-radius 16
|
||||
:border-style (if missing-keypair? :dashed :solid)
|
||||
:border-width 1
|
||||
:border-color (cond
|
||||
watch-only?
|
||||
(colors/theme-colors
|
||||
(if pressed? colors/neutral-80-opa-10 colors/neutral-80-opa-5)
|
||||
(if pressed? colors/white-opa-10 colors/white-opa-5)
|
||||
theme)
|
||||
missing-keypair?
|
||||
(colors/theme-colors
|
||||
(if pressed? colors/neutral-40 colors/neutral-30)
|
||||
(if pressed? colors/neutral-70 colors/neutral-80)
|
||||
theme)
|
||||
:else
|
||||
colors/neutral-80-opa-10)
|
||||
:padding-horizontal 12
|
||||
:padding-top 6
|
||||
:padding-bottom 9}))
|
||||
|
||||
(def profile-container
|
||||
{:margin-bottom 8
|
||||
@@ -100,10 +109,12 @@
|
||||
:line-height 20})
|
||||
|
||||
(defn loader-view
|
||||
[{:keys [width height watch-only? theme]}]
|
||||
[{:keys [width height watch-only? theme missing-keypair?]}]
|
||||
{:width width
|
||||
:height height
|
||||
:background-color (if (and watch-only? (= :light theme)) colors/neutral-80-opa-5 colors/white-opa-10)
|
||||
:background-color (if (and (or missing-keypair? watch-only?) (= :light theme))
|
||||
colors/neutral-80-opa-5
|
||||
colors/white-opa-10)
|
||||
:border-radius 6})
|
||||
|
||||
(def loader-container
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
|
||||
(defn- loading-view
|
||||
[{:keys [customization-color type theme metrics?]}]
|
||||
(let [watch-only? (= :watch-only type)
|
||||
empty-type? (= :empty type)]
|
||||
(let [missing-keypair? (= :missing-keypair type)
|
||||
watch-only? (= :watch-only type)
|
||||
empty-type? (= :empty type)]
|
||||
[rn/view
|
||||
{:accessibility-label :loading
|
||||
:style (style/card {:customization-color customization-color
|
||||
@@ -26,33 +27,37 @@
|
||||
:metrics? metrics?})}
|
||||
[rn/view {:style style/loader-container}
|
||||
[rn/view
|
||||
{:style (assoc (style/loader-view {:width 16
|
||||
:height 16
|
||||
:watch-only? watch-only?
|
||||
:theme theme})
|
||||
{:style (assoc (style/loader-view {:width 16
|
||||
:height 16
|
||||
:missing-keypair? missing-keypair?
|
||||
:watch-only? watch-only?
|
||||
:theme theme})
|
||||
:margin-right 8
|
||||
:margin-top 2)}]
|
||||
[rn/view {:style style/watch-only-container}
|
||||
[rn/view
|
||||
{:style (style/loader-view {:width 57
|
||||
:height 8
|
||||
:watch-only? watch-only?
|
||||
:theme theme})}]
|
||||
{:style (style/loader-view {:width 57
|
||||
:height 8
|
||||
:missing-keypair? missing-keypair?
|
||||
:watch-only? watch-only?
|
||||
:theme theme})}]
|
||||
(when watch-only? [icon/icon :i/reveal {:color colors/neutral-50 :size 12}])]]
|
||||
[rn/view
|
||||
{:style (assoc (style/loader-view {:width (if empty-type? 56 80)
|
||||
:height 16
|
||||
:watch-only? watch-only?
|
||||
:theme theme})
|
||||
{:style (assoc (style/loader-view {:width (if empty-type? 56 80)
|
||||
:height 16
|
||||
:missing-keypair? missing-keypair?
|
||||
:watch-only? watch-only?
|
||||
:theme theme})
|
||||
:margin-top
|
||||
13)}]
|
||||
(when metrics?
|
||||
[rn/view
|
||||
{:accessibility-label :metrics
|
||||
:style (assoc (style/loader-view {:width (if empty-type? 37 96)
|
||||
:height 8
|
||||
:watch-only? watch-only?
|
||||
:theme theme})
|
||||
:style (assoc (style/loader-view {:width (if empty-type? 37 96)
|
||||
:height 8
|
||||
:missing-keypair? missing-keypair?
|
||||
:watch-only? watch-only?
|
||||
:theme theme})
|
||||
:margin-top
|
||||
10)}])]))
|
||||
|
||||
@@ -154,7 +159,7 @@
|
||||
[gradient-overview theme customization-color])])))
|
||||
|
||||
(defn- add-account-view
|
||||
[{:keys [on-press customization-color metrics?]}]
|
||||
[{:keys [on-press metrics?]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
[pressed? set-pressed] (rn/use-state false)
|
||||
on-press-in (rn/use-callback #(set-pressed true))
|
||||
@@ -168,13 +173,12 @@
|
||||
:pressed? pressed?})}
|
||||
[button/button
|
||||
{:on-press on-press
|
||||
:type :primary
|
||||
:size 24
|
||||
:type :ghost
|
||||
:size 32
|
||||
:icon true
|
||||
:accessibility-label :add-account
|
||||
:pressed? pressed?
|
||||
:icon-only? true
|
||||
:customization-color customization-color}
|
||||
:icon-only? true}
|
||||
:i/add]]))
|
||||
|
||||
(defn- view-internal
|
||||
|
||||
@@ -141,6 +141,9 @@
|
||||
(def neutral-95-opa-70-blur neutral-95-opa-70)
|
||||
(def neutral-100-opa-70-blur (if platform/android? neutral-100-opa-70 "#0D1014B3"))
|
||||
|
||||
(def overlay-background-blur (if platform/android? (alpha "#192438" 0.8) "#242830cc"))
|
||||
(def bottom-sheet-background-blur (if platform/ios? "#ED9D1D0D" neutral-100-opa-90))
|
||||
|
||||
;;;;Black
|
||||
|
||||
;;Solid
|
||||
|
||||
@@ -30,5 +30,5 @@
|
||||
"when using opacity theme is ignored and uses the light suffix resolver"
|
||||
(is (colors/resolve-color :blue :light 10) (colors/resolve-color :blue :dark 10))))
|
||||
|
||||
(deftest test-account-colors-customization
|
||||
(deftest account-colors-customization-test
|
||||
(is (every? #(contains? colors/customization %) colors/account-colors)))
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
(ns react-native.wallet-connect
|
||||
(:require
|
||||
["@walletconnect/core" :refer [Core]]
|
||||
["@walletconnect/utils" :refer [buildApprovedNamespaces]]
|
||||
["@walletconnect/utils" :refer
|
||||
[buildApprovedNamespaces getSdkError parseUri]]
|
||||
["@walletconnect/web3wallet" :refer [Web3Wallet]]))
|
||||
|
||||
(defn- wallet-connect-core
|
||||
@@ -20,3 +21,13 @@
|
||||
(buildApprovedNamespaces
|
||||
(clj->js {:proposal proposal
|
||||
:supportedNamespaces supported-namespaces})))
|
||||
|
||||
(defn get-sdk-error
|
||||
[error-key]
|
||||
(getSdkError error-key))
|
||||
|
||||
(defn parse-uri
|
||||
[uri]
|
||||
(-> uri
|
||||
parseUri
|
||||
(js->clj :keywordize-keys true)))
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
matcher-combinators.test
|
||||
[status-im.common.alert-banner.events :as events]))
|
||||
|
||||
(deftest add-alert-banner
|
||||
(deftest add-alert-banner-test
|
||||
(testing "Alert banner is added"
|
||||
(is (match? {:db {:alert-banners
|
||||
{:alert {:text "Alert"
|
||||
@@ -14,7 +14,7 @@
|
||||
[{:text "Alert"
|
||||
:type :alert}])))))
|
||||
|
||||
(deftest remove-alert-banner
|
||||
(deftest remove-alert-banner-test
|
||||
(testing "Alert banner is removed"
|
||||
(is (match? {:db {}
|
||||
:hide-alert-banner [nil nil]}
|
||||
@@ -31,7 +31,7 @@
|
||||
:type :alert}}}}
|
||||
[:error])))))
|
||||
|
||||
(deftest remove-all-alert-banners
|
||||
(deftest remove-all-alert-banners-test
|
||||
(testing "All Alert banners are removed"
|
||||
(is (match? {:db {}
|
||||
:hide-alert-banner [nil nil]}
|
||||
|
||||
@@ -14,8 +14,7 @@
|
||||
:z-index 1
|
||||
:max-height max-height
|
||||
:border-top-left-radius sheet-border-radius
|
||||
:border-top-right-radius sheet-border-radius
|
||||
:overflow :hidden})
|
||||
:border-top-right-radius sheet-border-radius})
|
||||
|
||||
(def gradient-bg
|
||||
{:position :absolute
|
||||
@@ -23,13 +22,22 @@
|
||||
:left 0
|
||||
:right 0})
|
||||
|
||||
(def shell-bg
|
||||
{:position :absolute
|
||||
:background-color (if platform/ios? colors/white-opa-5 colors/neutral-100-opa-90)
|
||||
:left 0
|
||||
:right 0
|
||||
:top 0
|
||||
:bottom 0})
|
||||
(defn shell-bg
|
||||
[blur-background]
|
||||
{:background-color (if blur-background
|
||||
blur-background
|
||||
(if platform/ios? colors/white-opa-5 colors/neutral-100-opa-90))
|
||||
:flex 1})
|
||||
|
||||
(def shell-bg-container
|
||||
{:border-top-left-radius sheet-border-radius
|
||||
:border-top-right-radius sheet-border-radius
|
||||
:left 0
|
||||
:right 0
|
||||
:top 0
|
||||
:bottom 0
|
||||
:position :absolute
|
||||
:overflow :hidden})
|
||||
|
||||
(defn sheet-content
|
||||
[{:keys [theme padding-bottom shell?]}]
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
(defn view
|
||||
[{:keys [hide? insets]}
|
||||
{:keys [content selected-item padding-bottom-override border-radius on-close shell?
|
||||
gradient-cover? customization-color hide-handle? blur-radius]
|
||||
gradient-cover? customization-color hide-handle? blur-radius blur-background]
|
||||
:or {border-radius 12}}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
{window-height :height} (rn/get-window)
|
||||
@@ -133,12 +133,13 @@
|
||||
{:transform [{:translateY translate-y}]}
|
||||
(style/sheet {:max-height sheet-max-height}))}
|
||||
(when shell?
|
||||
[blur/ios-view
|
||||
{:style style/shell-bg
|
||||
:blur-radius (or blur-radius 20)
|
||||
:blur-amount 32
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent}])
|
||||
[rn/view {:style style/shell-bg-container}
|
||||
[blur/ios-view
|
||||
{:style (style/shell-bg blur-background)
|
||||
:blur-radius (or blur-radius 20)
|
||||
:blur-amount 32
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent}]])
|
||||
(when selected-item
|
||||
[rn/view
|
||||
{:on-layout handle-item-height
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
[react-native.reanimated :as reanimated]
|
||||
[status-im.constants :as constants]))
|
||||
|
||||
(defn container
|
||||
[padding-top]
|
||||
@@ -35,7 +36,7 @@
|
||||
{:left 0
|
||||
:right 0
|
||||
:top 0
|
||||
:height 20
|
||||
:height constants/sheet-screen-handle-height
|
||||
:z-index 2
|
||||
:position :absolute
|
||||
:justify-content :center
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
(def init-state
|
||||
{:value ""
|
||||
:error? false
|
||||
:upper-limit nil})
|
||||
:upper-limit nil
|
||||
:lower-limit nil})
|
||||
|
||||
(defn input-value
|
||||
[state]
|
||||
@@ -23,19 +24,31 @@
|
||||
[state error?]
|
||||
(assoc state :error? error?))
|
||||
|
||||
(defn- upper-limit
|
||||
(defn upper-limit
|
||||
[state]
|
||||
(:upper-limit state))
|
||||
|
||||
(defn lower-limit
|
||||
[state]
|
||||
(:lower-limit state))
|
||||
|
||||
(defn upper-limit-exceeded?
|
||||
[state]
|
||||
(and
|
||||
(upper-limit state)
|
||||
(> (numeric-value state) (upper-limit state))))
|
||||
|
||||
(defn lower-limit-exceeded?
|
||||
[state]
|
||||
(and
|
||||
(lower-limit state)
|
||||
(< (numeric-value state) (lower-limit state))))
|
||||
|
||||
(defn- recheck-errorness
|
||||
[state]
|
||||
(set-input-error state (upper-limit-exceeded? state)))
|
||||
(set-input-error state
|
||||
(or (upper-limit-exceeded? state)
|
||||
(lower-limit-exceeded? state))))
|
||||
|
||||
(defn set-input-value
|
||||
[state value]
|
||||
@@ -43,12 +56,33 @@
|
||||
(assoc :value value)
|
||||
recheck-errorness))
|
||||
|
||||
(defn set-numeric-value
|
||||
[state value]
|
||||
(set-input-value state (str value)))
|
||||
|
||||
(defn set-upper-limit
|
||||
[state limit]
|
||||
(when limit
|
||||
(-> state
|
||||
(assoc :upper-limit limit)
|
||||
recheck-errorness)))
|
||||
|
||||
(defn set-lower-limit
|
||||
[state limit]
|
||||
(-> state
|
||||
(assoc :upper-limit limit)
|
||||
(assoc :lower-limit limit)
|
||||
recheck-errorness))
|
||||
|
||||
(defn increase
|
||||
[state]
|
||||
(let [new-val (inc (numeric-value state))]
|
||||
(set-input-value state (str new-val))))
|
||||
|
||||
(defn decrease
|
||||
[state]
|
||||
(let [new-val (dec (numeric-value state))]
|
||||
(set-input-value state (str new-val))))
|
||||
|
||||
(def ^:private not-digits-or-dot-pattern
|
||||
#"[^0-9+\.]")
|
||||
|
||||
|
||||
@@ -31,10 +31,10 @@
|
||||
(comp not word-in-dictionary?))
|
||||
|
||||
(defn- header
|
||||
[seed-phrase-count]
|
||||
[text seed-phrase-count]
|
||||
[rn/view {:style style/header-container}
|
||||
[quo/text {:weight :semi-bold :size :heading-1}
|
||||
(i18n/label :t/use-recovery-phrase)]
|
||||
text]
|
||||
[rn/view {:style style/word-count-container}
|
||||
[quo/text
|
||||
{:style {:color colors/white-opa-40}
|
||||
@@ -51,34 +51,42 @@
|
||||
(string/replace #"\s+" " ")
|
||||
(string/trim)))
|
||||
|
||||
(defn- recovery-form
|
||||
[{:keys [seed-phrase word-count error-state? all-words-valid? on-change-seed-phrase
|
||||
keyboard-shown? on-submit]}]
|
||||
(let [button-disabled? (or error-state?
|
||||
(not (constants/seed-phrase-valid-length word-count))
|
||||
(not all-words-valid?))]
|
||||
[rn/view {:style style/form-container}
|
||||
[header word-count]
|
||||
[rn/view {:style style/input-container}
|
||||
[quo/recovery-phrase-input
|
||||
{:accessibility-label :passphrase-input
|
||||
:placeholder (i18n/label :t/seed-phrase-placeholder)
|
||||
:placeholder-text-color colors/white-opa-30
|
||||
:auto-capitalize :none
|
||||
:auto-correct false
|
||||
:auto-focus true
|
||||
:mark-errors? true
|
||||
:word-limit max-seed-phrase-length
|
||||
:error-pred-current-word partial-word-not-in-dictionary?
|
||||
:error-pred-written-words word-not-in-dictionary?
|
||||
:on-change-text on-change-seed-phrase}
|
||||
seed-phrase]]
|
||||
[quo/button
|
||||
{:container-style (style/continue-button keyboard-shown?)
|
||||
:type :primary
|
||||
:disabled? button-disabled?
|
||||
:on-press on-submit}
|
||||
(i18n/label :t/continue)]]))
|
||||
(defn- secure-clean-seed-phrase
|
||||
[seed-phrase]
|
||||
(-> seed-phrase
|
||||
security/safe-unmask-data
|
||||
clean-seed-phrase
|
||||
security/mask-data))
|
||||
|
||||
(defn- recovery-phrase-form
|
||||
[{:keys [keypair title seed-phrase word-count on-change-seed-phrase ref]} & children]
|
||||
(->> children
|
||||
(into
|
||||
[rn/view {:style style/form-container}
|
||||
[header title word-count]
|
||||
(when keypair
|
||||
[quo/context-tag
|
||||
{:type :icon
|
||||
:container-style {:padding-top 8}
|
||||
:icon :i/seed-phrase
|
||||
:size 24
|
||||
:blur? true
|
||||
:context (:name keypair)}])
|
||||
[rn/view {:style style/input-container}
|
||||
[quo/recovery-phrase-input
|
||||
{:accessibility-label :passphrase-input
|
||||
:ref ref
|
||||
:placeholder (i18n/label :t/seed-phrase-placeholder)
|
||||
:placeholder-text-color colors/white-opa-30
|
||||
:auto-capitalize :none
|
||||
:auto-correct false
|
||||
:auto-focus true
|
||||
:mark-errors? true
|
||||
:word-limit max-seed-phrase-length
|
||||
:error-pred-current-word partial-word-not-in-dictionary?
|
||||
:error-pred-written-words word-not-in-dictionary?
|
||||
:on-change-text on-change-seed-phrase}
|
||||
seed-phrase]]])))
|
||||
|
||||
(defn keyboard-suggestions
|
||||
[current-word]
|
||||
@@ -86,8 +94,8 @@
|
||||
(filter #(string/starts-with? % current-word))
|
||||
(take 7)))
|
||||
|
||||
(defn screen
|
||||
[recovering-keypair?]
|
||||
(defn recovery-phrase-screen
|
||||
[{:keys [keypair title recovering-keypair? render-controls]}]
|
||||
(reagent/with-let [keyboard-shown? (reagent/atom false)
|
||||
keyboard-show-listener (.addListener rn/keyboard
|
||||
"keyboardDidShow"
|
||||
@@ -96,6 +104,11 @@
|
||||
"keyboardDidHide"
|
||||
#(reset! keyboard-shown? false))
|
||||
invalid-seed-phrase? (reagent/atom false)
|
||||
input-ref (reagent/atom nil)
|
||||
focus-input (fn []
|
||||
(let [ref @input-ref]
|
||||
(when ref
|
||||
(.focus ref))))
|
||||
set-invalid-seed-phrase #(reset! invalid-seed-phrase? true)
|
||||
seed-phrase (reagent/atom "")
|
||||
on-change-seed-phrase (fn [new-phrase]
|
||||
@@ -139,16 +152,33 @@
|
||||
words-exceeded? (i18n/label :t/seed-phrase-words-exceeded)
|
||||
error-in-words? (i18n/label :t/seed-phrase-error)
|
||||
@invalid-seed-phrase? (i18n/label :t/seed-phrase-invalid)
|
||||
:else (i18n/label :t/seed-phrase-info))]
|
||||
:else (i18n/label :t/seed-phrase-info))
|
||||
error-state? (= suggestions-state :error)
|
||||
button-disabled? (or error-state?
|
||||
(not (constants/seed-phrase-valid-length word-count))
|
||||
(not all-words-valid?))]
|
||||
[:<>
|
||||
[recovery-form
|
||||
{:seed-phrase @seed-phrase
|
||||
:error-state? (= suggestions-state :error)
|
||||
:all-words-valid? all-words-valid?
|
||||
[recovery-phrase-form
|
||||
{:title title
|
||||
:keypair keypair
|
||||
:seed-phrase @seed-phrase
|
||||
:on-change-seed-phrase on-change-seed-phrase
|
||||
:word-count word-count
|
||||
:on-submit on-submit
|
||||
:keyboard-shown? @keyboard-shown?}]
|
||||
:ref #(reset! input-ref %)}
|
||||
(if (fn? render-controls)
|
||||
(render-controls {:submit-disabled? button-disabled?
|
||||
:keyboard-shown? @keyboard-shown?
|
||||
:container-style (style/continue-button @keyboard-shown?)
|
||||
:prepare-seed-phrase secure-clean-seed-phrase
|
||||
:focus-input focus-input
|
||||
:seed-phrase (security/mask-data @seed-phrase)
|
||||
:set-invalid-seed-phrase set-invalid-seed-phrase})
|
||||
[quo/button
|
||||
{:container-style (style/continue-button @keyboard-shown?)
|
||||
:type :primary
|
||||
:disabled? button-disabled?
|
||||
:on-press on-submit}
|
||||
(i18n/label :t/continue)])]
|
||||
(when @keyboard-shown?
|
||||
[rn/view {:style style/keyboard-container}
|
||||
[quo/predictive-keyboard
|
||||
@@ -161,16 +191,29 @@
|
||||
(.remove keyboard-show-listener)
|
||||
(.remove keyboard-hide-listener))))
|
||||
|
||||
(defn screen
|
||||
[{:keys [initial-insets title keypair navigation-icon recovering-keypair? render-controls]}]
|
||||
(let [{navigation-bar-top :top} initial-insets]
|
||||
[rn/view {:style style/full-layout}
|
||||
[rn/keyboard-avoiding-view {:style style/page-container}
|
||||
[quo/page-nav
|
||||
{:margin-top navigation-bar-top
|
||||
:background :blur
|
||||
:icon-name (or navigation-icon
|
||||
(if recovering-keypair? :i/close :i/arrow-left))
|
||||
:on-press #(rf/dispatch [:navigate-back])}]
|
||||
[recovery-phrase-screen
|
||||
{:title title
|
||||
:keypair keypair
|
||||
:render-controls render-controls
|
||||
:recovering-keypair? recovering-keypair?}]]]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{navigation-bar-top :top} (safe-area/get-insets)]
|
||||
(let [insets (safe-area/get-insets)]
|
||||
(fn []
|
||||
(let [{:keys [recovering-keypair?]} (rf/sub [:get-screen-params])]
|
||||
[rn/view {:style style/full-layout}
|
||||
[rn/keyboard-avoiding-view {:style style/page-container}
|
||||
[quo/page-nav
|
||||
{:margin-top navigation-bar-top
|
||||
:background :blur
|
||||
:icon-name (if recovering-keypair? :i/close :i/arrow-left)
|
||||
:on-press #(rf/dispatch [:navigate-back])}]
|
||||
[screen recovering-keypair?]]]))))
|
||||
[screen
|
||||
{:title (i18n/label :t/use-recovery-phrase)
|
||||
:initial-insets insets
|
||||
:recovering-keypair? recovering-keypair?}]))))
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
(ns status-im.common.raw-data-block.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def container
|
||||
{:flex 1
|
||||
:padding 10
|
||||
:margin-vertical 10.5
|
||||
:border-width 1
|
||||
:border-color colors/neutral-10
|
||||
:border-radius 16})
|
||||
|
||||
(def content
|
||||
{:padding-bottom 20})
|
||||
@@ -0,0 +1,14 @@
|
||||
(ns status-im.common.raw-data-block.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.raw-data-block.style :as style]))
|
||||
|
||||
(defn view
|
||||
[{:keys [data]}]
|
||||
[rn/scroll-view
|
||||
{:style style/container
|
||||
:content-container-style style/content}
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :code}
|
||||
data]])
|
||||
@@ -10,7 +10,7 @@
|
||||
(def chat-name-url "Test%20group%20chat")
|
||||
(def chat-name "Test group chat")
|
||||
|
||||
(deftest parse-uris
|
||||
(deftest parse-uris-test
|
||||
(are [uri expected] (= (cond-> (router/match-uri uri)
|
||||
(< (count expected) 3)
|
||||
(assoc :query-params nil))
|
||||
@@ -126,7 +126,7 @@
|
||||
|
||||
(def error {:error :invalid-group-chat-data})
|
||||
|
||||
(deftest match-group-chat-query
|
||||
(deftest match-group-chat-query-test
|
||||
(are [query-params expected] (= (router/match-group-chat {} query-params)
|
||||
expected)
|
||||
nil error
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
[:router/handle-uri :uri])
|
||||
"https://status.app/u#statuse2e"))))))
|
||||
|
||||
(deftest url-event-listener
|
||||
(deftest url-event-listener-test
|
||||
(testing "the url is not nil"
|
||||
(testing "it dispatches the url"
|
||||
(let [actual (atom nil)]
|
||||
@@ -39,7 +39,7 @@
|
||||
(links/url-event-listener #js {})
|
||||
(is (match? nil @actual)))))))
|
||||
|
||||
(deftest generate-profile-url
|
||||
(deftest generate-profile-url-test
|
||||
(testing "user has ens name"
|
||||
(testing "it calls the ens rpc method with ens name as param"
|
||||
(let [db {:profile/profile {:ens-name? true :public-key pubkey}}
|
||||
@@ -70,7 +70,7 @@
|
||||
"wakuext_shareUserURLWithData" (-> rst :json-rpc/call first :method)
|
||||
pubkey (-> rst :json-rpc/call first :params first))))))
|
||||
|
||||
(deftest save-profile-url
|
||||
(deftest save-profile-url-test
|
||||
(testing "given a contact public key and profile url"
|
||||
(testing "it updates the contact in db"
|
||||
(let [url "url"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[cljs.test :refer-macros [deftest testing is]]
|
||||
[status-im.common.validation.general :refer [valid-compressed-key?]]))
|
||||
|
||||
(deftest test-valid-compressed-key
|
||||
(deftest valid-compressed-key-test
|
||||
(testing "valid"
|
||||
(is (valid-compressed-key?
|
||||
"zQ3shWj4WaBdf2zYKCkXe6PHxDxNTzZyid1i75879Ue9cX9gA")))
|
||||
@@ -32,4 +32,3 @@
|
||||
(testing "contains l"
|
||||
(is (not (valid-compressed-key?
|
||||
"zQ3shWj4WaBdf2zYKCkXe6PHxDxNTzZyid1i75879Ue9cX9gl")))))
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
(goog-define ALCHEMY_OPTIMISM_MAINNET_TOKEN "")
|
||||
(goog-define ALCHEMY_OPTIMISM_GOERLI_TOKEN "")
|
||||
(goog-define ALCHEMY_OPTIMISM_SEPOLIA_TOKEN "")
|
||||
(goog-define WALLET_CONNECT_PROJECT_ID "")
|
||||
(goog-define WALLET_CONNECT_PROJECT_ID "87815d72a81d739d2a7ce15c2cfdefb3")
|
||||
|
||||
(def mainnet-rpc-url (str "https://eth-archival.rpc.grove.city/v1/" POKT_TOKEN))
|
||||
(def goerli-rpc-url (str "https://goerli-archival.gateway.pokt.network/v1/lb/" POKT_TOKEN))
|
||||
|
||||
@@ -263,10 +263,21 @@
|
||||
(def ^:const wallet-connect-metadata-icon
|
||||
"https://res.cloudinary.com/dhgck7ebz/image/upload/f_auto,c_limit,w_1080,q_auto/Brand/Logo%20Section/Mark/Mark_01")
|
||||
(def ^:const wallet-connect-metadata-url "https://status.app")
|
||||
(def ^:const optimism-crosschain-id "eip155:10")
|
||||
(def ^:const wallet-connect-supported-methods ["eth_sendTransaction" "personal_sign"])
|
||||
(def ^:const wallet-connect-supported-events ["accountsChanged" "chainChanged"])
|
||||
|
||||
(def ^:const wallet-connect-personal-sign-method "personal_sign")
|
||||
(def ^:const wallet-connect-eth-sign-method "eth_sign")
|
||||
(def ^:const wallet-connect-eth-send-transaction-method "eth_sendTransaction")
|
||||
(def ^:const wallet-connect-eth-sign-typed-method "eth_signTypedData")
|
||||
(def ^:const wallet-connect-eth-sign-typed-v4-method "eth_signTypedData_v4")
|
||||
(def ^:const wallet-connect-supported-methods
|
||||
#{wallet-connect-personal-sign-method
|
||||
wallet-connect-eth-sign-method
|
||||
wallet-connect-eth-send-transaction-method
|
||||
wallet-connect-eth-sign-typed-method
|
||||
wallet-connect-eth-sign-typed-v4-method})
|
||||
(def ^:const wallet-connect-supported-events #{"accountsChanged" "chainChanged"})
|
||||
(def ^:const wallet-connect-session-proposal-event "session_proposal")
|
||||
(def ^:const wallet-connect-session-request-event "session_request")
|
||||
|
||||
(def ^:const dapp-permission-contact-code "contact-code")
|
||||
(def ^:const dapp-permission-web3 "web3")
|
||||
@@ -522,6 +533,8 @@
|
||||
|
||||
(def ^:const alert-banner-height 40)
|
||||
|
||||
(def ^:const sheet-screen-handle-height 20)
|
||||
|
||||
(def ^:const status-hostname "status.app")
|
||||
|
||||
(def ^:const community-joined-notification-type "communityJoined")
|
||||
|
||||
@@ -202,7 +202,8 @@
|
||||
{:events [:chat/navigate-to-chat]}
|
||||
[{db :db :as cofx} chat-id animation]
|
||||
(rf/merge cofx
|
||||
{:dispatch [(if animation :shell/navigate-to :navigate-to) :chat chat-id animation]}
|
||||
(when-not (:current-chat-id db)
|
||||
{:dispatch [(if animation :shell/navigate-to :navigate-to) :chat chat-id animation]})
|
||||
(close-chat chat-id)
|
||||
(force-close-chat chat-id)
|
||||
(fn [{:keys [db]}]
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
(let [actual (chat/close-and-remove-chat cofx chat-id)]
|
||||
(is (= nil (get-in actual [:db :chats-home-list chat-id])))))))
|
||||
|
||||
(deftest multi-user-chat?
|
||||
(deftest multi-user-chat?-test
|
||||
(let [chat-id "1"]
|
||||
(testing "it returns true if it's a group chat"
|
||||
(let [cofx {:db {:chats {chat-id {:group-chat true}}}}]
|
||||
@@ -61,7 +61,7 @@
|
||||
(let [cofx {:db {:chats {chat-id {}}}}]
|
||||
(is (not (chat/multi-user-chat? cofx chat-id)))))))
|
||||
|
||||
(deftest group-chat?
|
||||
(deftest group-chat?-test
|
||||
(let [chat-id "1"]
|
||||
(testing "it returns true if it's a group chat"
|
||||
(let [cofx {:db {:chats {chat-id {:group-chat true}}}}]
|
||||
@@ -82,7 +82,7 @@
|
||||
"opened" {}
|
||||
"1-1" {}}})
|
||||
|
||||
(deftest navigate-to-chat
|
||||
(deftest navigate-to-chat-test
|
||||
(let [chat-id "test_chat"
|
||||
db {:pagination-info {chat-id {:all-loaded? true}}}]
|
||||
(testing "Pagination info should be reset on navigation"
|
||||
|
||||
@@ -115,6 +115,7 @@
|
||||
:resolve-ens {:db (assoc db :contacts/new-identity contact)
|
||||
:effects.contacts/resolve-public-key-from-ens
|
||||
{:ens ens
|
||||
:chain-id 1
|
||||
:on-success
|
||||
#(re-frame/dispatch [:contacts/set-new-identity-success
|
||||
{:input input
|
||||
|
||||
@@ -118,6 +118,7 @@
|
||||
:state :resolve-ens}))
|
||||
:effects.contacts/resolve-public-key-from-ens
|
||||
{:ens ens-stateofus-eth
|
||||
:chain-id 1
|
||||
:on-success [:contacts/set-new-identity-success ens]
|
||||
:on-error [:contacts/set-new-identity-error ens]}}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
(update-in effects [:json-rpc/call 0] dissoc :on-success :on-error)
|
||||
effects))
|
||||
|
||||
(deftest unfurl-urls
|
||||
(deftest unfurl-urls-test
|
||||
(testing "clear up state when text is empty"
|
||||
(let [cofx {:db {:chat/link-previews {:unfurled {}
|
||||
:cache {}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
(def mid "message-id")
|
||||
(def cid "chat-id")
|
||||
|
||||
(deftest delete
|
||||
(deftest delete-test
|
||||
(with-redefs [datetime/timestamp (constantly 1)]
|
||||
(let [db {:messages {cid {mid {:id mid :whisper-timestamp 1}}}}
|
||||
message {:message-id mid :chat-id cid}]
|
||||
@@ -57,7 +57,7 @@
|
||||
(testing "return nil if message not in db"
|
||||
(is (= (delete-message/delete {:db {:messages []}} message 1000) nil)))))))
|
||||
|
||||
(deftest undo-delete
|
||||
(deftest undo-delete-test
|
||||
(let [db {:messages {cid {mid {:id mid :whisper-timestamp 1}}}}
|
||||
message {:message-id mid :chat-id cid}]
|
||||
(testing "undo delete"
|
||||
@@ -84,7 +84,7 @@
|
||||
(testing "return nil if message not in db"
|
||||
(is (= (delete-message/undo {:db {:messages []}} message) nil))))))
|
||||
|
||||
(deftest delete-and-send
|
||||
(deftest delete-and-send-test
|
||||
(let [db {:messages {cid {mid {:id mid :deleted? true :deleted-undoable-till 0}}}}
|
||||
message {:message-id mid :chat-id cid}]
|
||||
(testing "delete and send"
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@
|
||||
(def mid "message-id")
|
||||
(def cid "chat-id")
|
||||
|
||||
(deftest delete-for-me
|
||||
(deftest delete-for-me-test
|
||||
(with-redefs [datetime/timestamp (constantly 1)]
|
||||
(let [db {:messages {cid {mid {:id mid :whisper-timestamp 1}}}}
|
||||
message {:message-id mid :chat-id cid}]
|
||||
@@ -60,7 +60,7 @@
|
||||
(is (= (delete-message-for-me/delete {:db {:messages []}} message 1000)
|
||||
nil)))))))
|
||||
|
||||
(deftest undo-delete-for-me
|
||||
(deftest undo-delete-for-me-test
|
||||
(let [db {:messages {cid {mid {:id mid :whisper-timestamp 1}}}}
|
||||
message {:message-id mid :chat-id cid}]
|
||||
(testing "undo delete for me"
|
||||
@@ -93,7 +93,7 @@
|
||||
(is (= (delete-message-for-me/undo {:db {:messages []}} message)
|
||||
nil))))))
|
||||
|
||||
(deftest delete-for-me-and-sync
|
||||
(deftest delete-for-me-and-sync-test
|
||||
(let [db {:messages {cid {mid {:id mid :deleted-for-me? true :deleted-for-me-undoable-till 0}}}}
|
||||
message {:message-id mid :chat-id cid}]
|
||||
(testing "delete for me and sync"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[status-im.contexts.chat.messenger.messages.list.events :as s]
|
||||
[taoensso.tufte :as tufte :refer-macros [defnp profile]]))
|
||||
|
||||
(deftest message-stream-tests
|
||||
(deftest message-stream-tests-test
|
||||
(testing "building the list"
|
||||
(let [m1 {:from "1"
|
||||
:clock-value 1
|
||||
@@ -87,7 +87,7 @@
|
||||
(tufte/add-basic-println-handler! {:format-pstats-opts {:columns [:n :mean :min :max :clock :sum]
|
||||
:format-id-fn name}})
|
||||
|
||||
(deftest ^:benchmark benchmark-list
|
||||
(deftest ^:benchmark benchmark-list-test
|
||||
(let [messages (sort-by
|
||||
:timestamp
|
||||
(mapv (fn [i]
|
||||
@@ -132,7 +132,7 @@
|
||||
:whisper-timestamp 1000
|
||||
:timestamp 1000}))))))
|
||||
|
||||
(deftest message-list
|
||||
(deftest message-list-test
|
||||
(let [current-messages [{:clock-value 109
|
||||
:message-id "109"
|
||||
:timestamp 9
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
:destination "https://foo.bar"}
|
||||
{:literal " , no worries"}]}])
|
||||
|
||||
(t/deftest test-resolve-message
|
||||
(t/deftest resolve-message-test
|
||||
(with-redefs [rf/sub sub]
|
||||
(t/testing ""
|
||||
(let [text (resolver/resolve-message parsed-text)]
|
||||
|
||||
@@ -22,17 +22,17 @@
|
||||
[{:keys [db]} [community-js]]
|
||||
(when community-js
|
||||
(let [{:keys [clock
|
||||
token-permissions-check joined id last-opened-at]
|
||||
token-permissions-check id last-opened-at]
|
||||
:as community} (data-store.communities/<-rpc community-js)
|
||||
previous-last-opened-at (get-in db [:communities id :last-opened-at])]
|
||||
(when (> clock (get-in db [:communities id :clock]))
|
||||
{:db (assoc-in db
|
||||
[:communities id]
|
||||
(assoc community :last-opened-at (max last-opened-at previous-last-opened-at)))
|
||||
;; NOTE(cammellos): these two looks suspicious, we should not check for permissions at
|
||||
;; every event signalled
|
||||
:fx [[:dispatch
|
||||
[:communities/check-permissions-to-join-community-with-all-addresses id]]
|
||||
(when (not joined)
|
||||
[:dispatch [:chat.ui/spectate-community id]])
|
||||
(when (nil? token-permissions-check)
|
||||
[:dispatch [:communities/check-permissions-to-join-community id]])]}))))
|
||||
|
||||
@@ -293,33 +293,23 @@
|
||||
[{:keys [db]} [{:keys [communities]}]]
|
||||
(when-let [community (first communities)]
|
||||
{:db (-> db
|
||||
(assoc-in [:communities (:id community) :spectated] true)
|
||||
(assoc-in [:communities (:id community) :spectating] false))
|
||||
(assoc-in [:communities (:id community) :spectated] true))
|
||||
:fx [[:dispatch [:communities/handle-community community]]
|
||||
[:dispatch [::mailserver/request-messages]]]}))
|
||||
|
||||
(rf/reg-event-fx :chat.ui/spectate-community-success spectate-community-success)
|
||||
|
||||
(defn spectate-community-failed
|
||||
[{:keys [db]} [community-id]]
|
||||
{:db (assoc-in db [:communities community-id :spectating] false)})
|
||||
|
||||
(rf/reg-event-fx :chat.ui/spectate-community-failed spectate-community-failed)
|
||||
|
||||
(defn spectate-community
|
||||
[{:keys [db]} [community-id]]
|
||||
(let [{:keys [spectated spectating joined]} (get-in db [:communities community-id])]
|
||||
(when (and (not joined) (not spectated) (not spectating))
|
||||
{:db (assoc-in db [:communities community-id :spectating] true)
|
||||
:json-rpc/call [{:method "wakuext_spectateCommunity"
|
||||
(let [{:keys [spectated joined]} (get-in db [:communities community-id])]
|
||||
(when (and (not joined) (not spectated))
|
||||
{:json-rpc/call [{:method "wakuext_spectateCommunity"
|
||||
:params [community-id]
|
||||
:on-success [:chat.ui/spectate-community-success]
|
||||
:on-error (fn [err]
|
||||
(log/error {:message
|
||||
"Failed to spectate community"
|
||||
:error err})
|
||||
(rf/dispatch [:chat.ui/spectate-community-failed
|
||||
community-id]))}]})))
|
||||
:error err}))}]})))
|
||||
|
||||
(schema/=> spectate-community
|
||||
[:=>
|
||||
@@ -329,7 +319,6 @@
|
||||
[:schema [:catn [:community-id [:? :string]]]]]]
|
||||
[:maybe
|
||||
[:map
|
||||
[:db map?]
|
||||
[:json-rpc/call :schema.common/rpc-call]]]])
|
||||
|
||||
(rf/reg-event-fx :chat.ui/spectate-community spectate-community)
|
||||
@@ -350,7 +339,8 @@
|
||||
(navigate-to-serialized-community community-id)
|
||||
(rf/merge
|
||||
cofx
|
||||
{:fx [[:dispatch
|
||||
{:fx [[:dispatch [:chat.ui/spectate-community community-id]]
|
||||
[:dispatch
|
||||
[:communities/fetch-community
|
||||
{:community-id community-id
|
||||
:update-last-opened-at? true}]]
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
(def community-id "community-id")
|
||||
|
||||
(deftest fetch-community
|
||||
(deftest fetch-community-test
|
||||
(testing "with community id"
|
||||
(testing "update fetching indicator in db"
|
||||
(is (match?
|
||||
@@ -26,7 +26,7 @@
|
||||
nil
|
||||
(events/fetch-community {} [{}]))))))
|
||||
|
||||
(deftest community-failed-to-fetch
|
||||
(deftest community-failed-to-fetch-test
|
||||
(testing "given a community id"
|
||||
(testing "remove community id from fetching indicator in db"
|
||||
(is (match?
|
||||
@@ -36,7 +36,7 @@
|
||||
[community-id])
|
||||
[:db :communities/fetching-communities community-id]))))))
|
||||
|
||||
(deftest community-fetched
|
||||
(deftest community-fetched-test
|
||||
(with-redefs [link-preview.events/community-link (fn [id] (str "community-link+" id))]
|
||||
(testing "given a community"
|
||||
(let [cofx {:db {:communities/fetching-communities {community-id true}}}
|
||||
@@ -82,7 +82,7 @@
|
||||
nil
|
||||
(events/community-fetched {} [community-id nil])))))))
|
||||
|
||||
(deftest spectate-community
|
||||
(deftest spectate-community-test
|
||||
(testing "given a joined community"
|
||||
(testing "do nothing"
|
||||
(is (match?
|
||||
@@ -95,35 +95,16 @@
|
||||
nil
|
||||
(events/spectate-community {:db {:communities {community-id {:spectated true}}}}
|
||||
[community-id])))))
|
||||
(testing "given a spectating community"
|
||||
(testing "do nothing"
|
||||
(is (match?
|
||||
nil
|
||||
(events/spectate-community {:db {:communities {community-id {:spectating true}}}}
|
||||
[community-id])))))
|
||||
|
||||
(testing "given a community"
|
||||
(testing "mark community spectating"
|
||||
(is (match?
|
||||
{:db {:communities {community-id {:spectating true}}}}
|
||||
(events/spectate-community {:db {:communities {community-id {}}}} [community-id]))))
|
||||
(testing "call spectate community rpc with correct community id"
|
||||
(is (match?
|
||||
{:json-rpc/call [{:method "wakuext_spectateCommunity"
|
||||
:params [community-id]}]}
|
||||
(events/spectate-community {:db {:communities {community-id {}}}} [community-id]))))))
|
||||
|
||||
(deftest spectate-community-failed
|
||||
(testing "mark community spectating false"
|
||||
(is (match?
|
||||
{:db {:communities {community-id {:spectating false}}}}
|
||||
(events/spectate-community-failed {} [community-id])))))
|
||||
|
||||
(deftest spectate-community-success
|
||||
(deftest spectate-community-success-test
|
||||
(testing "given communities"
|
||||
(testing "mark first community spectating false"
|
||||
(is (match?
|
||||
{:db {:communities {community-id {:spectating false}}}}
|
||||
(events/spectate-community-success {} [{:communities [{:id community-id}]}]))))
|
||||
(testing "mark first community spectated true"
|
||||
(is (match?
|
||||
{:db {:communities {community-id {:spectated true}}}}
|
||||
@@ -144,7 +125,7 @@
|
||||
nil
|
||||
(events/spectate-community-success {} []))))))
|
||||
|
||||
(deftest get-revealed-accounts
|
||||
(deftest get-revealed-accounts-test
|
||||
(let [community {:id community-id}]
|
||||
(testing "given a unjoined community"
|
||||
(is (match?
|
||||
@@ -169,7 +150,7 @@
|
||||
:params [community-id "profile-public-key"]}
|
||||
(-> effects :json-rpc/call first (select-keys [:method :params]))))))))
|
||||
|
||||
(deftest handle-community
|
||||
(deftest handle-community-test
|
||||
(let [community {:id community-id :clock 2}]
|
||||
(testing "given a unjoined community"
|
||||
(let [effects (events/handle-community {} [community])]
|
||||
@@ -178,7 +159,6 @@
|
||||
(is (match?
|
||||
[[:dispatch
|
||||
[:communities/check-permissions-to-join-community-with-all-addresses community-id]]
|
||||
[:dispatch [:chat.ui/spectate-community community-id]]
|
||||
[:dispatch [:communities/check-permissions-to-join-community community-id]]]
|
||||
(filter some? (:fx effects))))))
|
||||
|
||||
@@ -196,8 +176,7 @@
|
||||
effects (events/handle-community {} [community])]
|
||||
(is (match?
|
||||
[[:dispatch
|
||||
[:communities/check-permissions-to-join-community-with-all-addresses community-id]]
|
||||
[:dispatch [:chat.ui/spectate-community community-id]]]
|
||||
[:communities/check-permissions-to-join-community-with-all-addresses community-id]]]
|
||||
(filter some? (:fx effects))))))
|
||||
(testing "given a community with lower clock"
|
||||
(let [effects (events/handle-community {:db {:communities {community-id {:clock 3}}}} [community])]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
(ns status-im.contexts.onboarding.events
|
||||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
status-im.common.biometric.events
|
||||
[status-im.constants :as constants]
|
||||
@@ -9,19 +8,7 @@
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:multiaccount/validate-mnemonic
|
||||
(fn [[mnemonic on-success on-error]]
|
||||
(native-module/validate-mnemonic
|
||||
(security/safe-unmask-data mnemonic)
|
||||
(fn [result]
|
||||
(let [{:keys [error keyUID]} (transforms/json->clj result)]
|
||||
(if (seq error)
|
||||
(when on-error (on-error error))
|
||||
(on-success mnemonic keyUID)))))))
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/defn profile-data-set
|
||||
{:events [:onboarding/profile-data-set]}
|
||||
|
||||
@@ -57,5 +57,6 @@
|
||||
[quo/page-top
|
||||
{:title-accessibility-label :username
|
||||
:emoji-dash emoji-hash
|
||||
:description bio
|
||||
:description :text
|
||||
:description-text bio
|
||||
:title full-name}]]))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
(ns status-im.contexts.profile.settings.list-items
|
||||
(:require [status-im.common.not-implemented :as not-implemented]
|
||||
[status-im.config :as config]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -35,13 +34,12 @@
|
||||
:image :icon
|
||||
:blur? true
|
||||
:action :arrow}
|
||||
{:title (i18n/label :t/wallet)
|
||||
:on-press #(rf/dispatch [:open-modal :screen/settings.wallet])
|
||||
:image-props :i/wallet
|
||||
:image :icon
|
||||
:blur? true
|
||||
:action :arrow
|
||||
:feature-flag ::ff/settings.wallet-settings}
|
||||
{:title (i18n/label :t/wallet)
|
||||
:on-press #(rf/dispatch [:navigate-to-within-stack [:screen/settings.wallet :settings]])
|
||||
:image-props :i/wallet
|
||||
:image :icon
|
||||
:blur? true
|
||||
:action :arrow}
|
||||
(when config/show-not-implemented-features?
|
||||
{:title (i18n/label :t/dapps)
|
||||
:on-press not-implemented/alert
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[utils.security.core :as security]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(rf/reg-fx :effects.connection-string/export-keypair
|
||||
(rf/reg-fx :effects.syncing/export-keypairs-keystores
|
||||
(fn [{:keys [key-uid sha3-pwd keypair-key-uid on-success on-fail]}]
|
||||
(let [config-map (transforms/clj->json {:senderConfig {:loggedInKeyUid key-uid
|
||||
:keystorePath ""
|
||||
@@ -23,7 +23,7 @@
|
||||
"generic-error: failed to get connection string")))))
|
||||
(promesa/catch on-fail)))))
|
||||
|
||||
(rf/reg-fx :effects.connection-string/import-keypair
|
||||
(rf/reg-fx :effects.syncing/import-keypairs-keystores
|
||||
(fn [{:keys [key-uid sha3-pwd keypairs-key-uids connection-string on-success on-fail]}]
|
||||
(let [config-map (transforms/clj->json {:receiverConfig
|
||||
{:loggedInKeyUid key-uid
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
(ns status-im.contexts.settings.wallet.events
|
||||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[status-im.contexts.settings.wallet.data-store :as data-store]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/rename-keypair-success
|
||||
@@ -31,7 +33,7 @@
|
||||
(defn get-keypair-export-connection
|
||||
[{:keys [db]} [{:keys [sha3-pwd keypair-key-uid callback]}]]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{:fx [[:effects.connection-string/export-keypair
|
||||
{:fx [[:effects.syncing/export-keypairs-keystores
|
||||
{:key-uid key-uid
|
||||
:sha3-pwd sha3-pwd
|
||||
:keypair-key-uid keypair-key-uid
|
||||
@@ -88,7 +90,7 @@
|
||||
(defn connection-string-for-import-keypair
|
||||
[{:keys [db]} [{:keys [sha3-pwd keypairs-key-uids connection-string]}]]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{:fx [[:effects.connection-string/import-keypair
|
||||
{:fx [[:effects.syncing/import-keypairs-keystores
|
||||
{:key-uid key-uid
|
||||
:sha3-pwd sha3-pwd
|
||||
:keypairs-key-uids keypairs-key-uids
|
||||
@@ -117,3 +119,54 @@
|
||||
:sha3-pwd password}]))}]]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/success-keypair-qr-scan success-keypair-qr-scan)
|
||||
|
||||
(defn wallet-validate-seed-phrase
|
||||
[_ [seed-phrase on-success on-error]]
|
||||
{:fx [[:multiaccount/validate-mnemonic [seed-phrase on-success on-error]]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/validate-seed-phrase wallet-validate-seed-phrase)
|
||||
|
||||
(defn make-seed-phrase-keypair-fully-operable
|
||||
[_ [mnemonic password on-success on-error]]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "accounts_makeSeedPhraseKeypairFullyOperable"
|
||||
:params [(security/safe-unmask-data mnemonic)
|
||||
(-> password security/safe-unmask-data native-module/sha3)]
|
||||
:on-success on-success
|
||||
:on-error on-error}]]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/make-seed-phrase-keypair-fully-operable make-seed-phrase-keypair-fully-operable)
|
||||
|
||||
(defn import-keypair-by-seed-phrase
|
||||
[_ [{:keys [keypair-key-uid seed-phrase password on-success on-error]}]]
|
||||
{:fx [[:import-keypair-by-seed-phrase
|
||||
{:keypair-key-uid keypair-key-uid
|
||||
:seed-phrase seed-phrase
|
||||
:password password
|
||||
:on-success (fn []
|
||||
(rf/dispatch [:wallet/make-keypairs-accounts-fully-operable
|
||||
#{keypair-key-uid}])
|
||||
(cond
|
||||
(vector? on-success) (rf/dispatch (conj on-success))
|
||||
(fn? on-success) (on-success)))
|
||||
:on-error (fn [error]
|
||||
(rf/dispatch [:wallet/import-keypair-by-seed-phrase-failed error])
|
||||
(cond
|
||||
(vector? on-error) (rf/dispatch (conj on-error error))
|
||||
(fn? on-error) (on-error error)))}]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/import-keypair-by-seed-phrase import-keypair-by-seed-phrase)
|
||||
|
||||
(defn import-keypair-by-seed-phrase-failed
|
||||
[_ [error]]
|
||||
(let [error-type (-> error ex-message keyword)
|
||||
error-data (ex-data error)]
|
||||
(when-not (and (= error-type :import-keypair-by-seed-phrase/import-error)
|
||||
(= (:hint error-data) :incorrect-seed-phrase-for-keypair))
|
||||
{:fx [[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type :negative
|
||||
:theme :dark
|
||||
:text (:error error-data)}]]]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/import-keypair-by-seed-phrase-failed import-keypair-by-seed-phrase-failed)
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
(:require
|
||||
[cljs.test :refer-macros [deftest is testing]]
|
||||
matcher-combinators.test
|
||||
[status-im.contexts.settings.wallet.events :as sut]))
|
||||
[native-module.core :as native-module]
|
||||
[status-im.contexts.settings.wallet.events :as sut]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(def mock-key-uid "key-1")
|
||||
(defn mock-db
|
||||
@@ -32,7 +34,7 @@
|
||||
user-key-uid "test-key-uid"
|
||||
callback (fn [connect-string] (println "callback" connect-string))]
|
||||
(testing "get-keypair-export-connection"
|
||||
(let [expected {:fx [[:effects.connection-string/export-keypair
|
||||
(let [expected {:fx [[:effects.syncing/export-keypairs-keystores
|
||||
{:key-uid user-key-uid
|
||||
:sha3-pwd sha3-pwd
|
||||
:keypair-key-uid mock-key-uid
|
||||
@@ -74,7 +76,7 @@
|
||||
user-key-uid "test-key-uid"
|
||||
connection-string "test-connection-string"]
|
||||
(testing "connection-string-for-import-keypair"
|
||||
(let [expected {:fx [[:effects.connection-string/import-keypair
|
||||
(let [expected {:fx [[:effects.syncing/import-keypairs-keystores
|
||||
{:key-uid user-key-uid
|
||||
:sha3-pwd sha3-pwd
|
||||
:keypairs-key-uids [mock-key-uid]
|
||||
@@ -95,3 +97,33 @@
|
||||
(let [effects (sut/success-keypair-qr-scan nil [connection-string keypairs-key-uids])
|
||||
fx (:fx effects)]
|
||||
(is (some? fx))))))
|
||||
|
||||
(deftest wallet-validate-seed-phrase-test
|
||||
(let [cofx {:db {}}
|
||||
seed-phrase-masked (security/mask-data "seed phrase")
|
||||
on-success #(prn "success")
|
||||
on-error #(prn "error")
|
||||
expected {:fx [[:multiaccount/validate-mnemonic
|
||||
[seed-phrase-masked on-success on-error]]]}]
|
||||
(is (= expected
|
||||
(sut/wallet-validate-seed-phrase
|
||||
cofx
|
||||
[seed-phrase-masked on-success on-error])))))
|
||||
|
||||
(deftest make-seed-phrase-keypair-fully-operable-test
|
||||
(let [cofx {:db {}}
|
||||
mnemonic "seed phrase"
|
||||
password "password"
|
||||
mnemonic-masked (security/mask-data mnemonic)
|
||||
password-masked (security/mask-data password)
|
||||
on-success #(prn "success")
|
||||
on-error #(prn "error")
|
||||
expected {:fx [[:json-rpc/call
|
||||
[{:method "accounts_makeSeedPhraseKeypairFullyOperable"
|
||||
:params [mnemonic (native-module/sha3 password)]
|
||||
:on-success fn?
|
||||
:on-error fn?}]]]}]
|
||||
(is (match? expected
|
||||
(sut/make-seed-phrase-keypair-fully-operable
|
||||
cofx
|
||||
[mnemonic-masked password-masked on-success on-error])))))
|
||||
|
||||
@@ -1,44 +1,62 @@
|
||||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.actions.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.remove.view :as remove-key-pair]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn on-rename-key-pair
|
||||
[key-pair]
|
||||
(rf/dispatch [:open-modal :screen/settings.rename-keypair key-pair]))
|
||||
|
||||
(defn on-remove-key-pair
|
||||
[key-pair]
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:content (fn []
|
||||
[remove-key-pair/view key-pair])}]))
|
||||
|
||||
(defn on-show-qr
|
||||
[data]
|
||||
(rf/dispatch [:open-modal :screen/settings.encrypted-key-pair-qr data]))
|
||||
|
||||
(defn view
|
||||
[props key-pair]
|
||||
(let [has-paired-device (rf/sub [:pairing/has-paired-devices])]
|
||||
[{:keys [drawer-props keypair]}]
|
||||
(let [has-paired-device (rf/sub [:pairing/has-paired-devices])
|
||||
missing-keypair? (= (:stored drawer-props) :missing)
|
||||
on-scan-qr (rn/use-callback #(rf/dispatch [:open-modal
|
||||
:screen/settings.scan-keypair-qr
|
||||
[(:key-uid keypair)]])
|
||||
[keypair])
|
||||
on-show-qr (rn/use-callback #(rf/dispatch [:open-modal
|
||||
:screen/settings.encrypted-key-pair-qr
|
||||
keypair])
|
||||
[keypair])
|
||||
on-remove-keypair (rn/use-callback #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:content (fn []
|
||||
[remove-key-pair/view keypair])}])
|
||||
[keypair])
|
||||
on-rename-keypair (rn/use-callback #(rf/dispatch [:open-modal :screen/settings.rename-keypair
|
||||
keypair])
|
||||
[keypair])
|
||||
on-import-seed-phrase (rn/use-callback
|
||||
#(rf/dispatch [:open-modal :screen/settings.import-seed-phrase keypair])
|
||||
[keypair])]
|
||||
[:<>
|
||||
[quo/drawer-top props]
|
||||
[quo/drawer-top drawer-props]
|
||||
[quo/action-drawer
|
||||
[(when has-paired-device
|
||||
[{:icon :i/qr-code
|
||||
:accessibility-label :show-key-pr-qr
|
||||
:label (i18n/label :t/show-encrypted-qr-of-key-pairs)
|
||||
:on-press #(on-show-qr key-pair)}])
|
||||
(when (= (:type props) :keypair)
|
||||
(concat
|
||||
[{:icon :i/edit
|
||||
:accessibility-label :rename-key-pair
|
||||
:label (i18n/label :t/rename-key-pair)
|
||||
:on-press #(on-rename-key-pair key-pair)}]
|
||||
[{:icon :i/delete
|
||||
:accessibility-label :remove-key-pair
|
||||
:add-divider? true
|
||||
:danger? true
|
||||
:label (i18n/label :t/remove-key-pair-and-derived-accounts)
|
||||
:on-press #(on-remove-key-pair key-pair)}]))]]]))
|
||||
(if-not missing-keypair?
|
||||
[{:icon :i/qr-code
|
||||
:accessibility-label :show-key-pr-qr
|
||||
:label (i18n/label :t/show-encrypted-qr-of-key-pairs)
|
||||
:on-press on-show-qr}]
|
||||
[{:icon :i/scan
|
||||
:accessibility-label :import-by-scan-qr
|
||||
:label (i18n/label :t/import-by-scanning-encrypted-qr)
|
||||
:on-press on-scan-qr}]))
|
||||
(when (= (:type drawer-props) :keypair)
|
||||
[(when missing-keypair?
|
||||
(case (:type keypair)
|
||||
:seed {:icon :i/seed
|
||||
:accessibility-label :import-seed-phrase
|
||||
:label (i18n/label :t/import-by-entering-recovery-phrase)
|
||||
:on-press #(on-import-seed-phrase keypair)}
|
||||
nil))
|
||||
{:icon :i/edit
|
||||
:accessibility-label :rename-key-pair
|
||||
:label (i18n/label :t/rename-key-pair)
|
||||
:on-press on-rename-keypair}
|
||||
{:icon :i/delete
|
||||
:accessibility-label :remove-key-pair
|
||||
:add-divider? true
|
||||
:danger? true
|
||||
:label (i18n/label :t/remove-key-pair-and-derived-accounts)
|
||||
:on-press on-remove-keypair}])]]]))
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.import-seed-phrase.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.common.enter-seed-phrase.view :as enter-seed-phrase]
|
||||
[status-im.common.standard-authentication.core :as standard-auth]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn import-seed-phrase-controls
|
||||
[{:keys [submit-disabled?
|
||||
container-style
|
||||
prepare-seed-phrase
|
||||
seed-phrase
|
||||
set-invalid-seed-phrase
|
||||
focus-input]}]
|
||||
(let [keypair (rf/sub [:get-screen-params])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
show-errors (rn/use-callback
|
||||
#(js/setTimeout
|
||||
(fn []
|
||||
(focus-input)
|
||||
(reagent/next-tick set-invalid-seed-phrase))
|
||||
600))
|
||||
on-import-error (rn/use-callback
|
||||
(fn [_error]
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(show-errors)))
|
||||
on-import-success (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(rf/dispatch [:navigate-back])))
|
||||
on-auth-success (rn/use-callback
|
||||
(fn [password]
|
||||
(rf/dispatch [:wallet/import-keypair-by-seed-phrase
|
||||
{:keypair-key-uid (:key-uid keypair)
|
||||
:seed-phrase (prepare-seed-phrase seed-phrase)
|
||||
:password password
|
||||
:on-success on-import-success
|
||||
:on-error on-import-error}]))
|
||||
[keypair seed-phrase on-import-success on-import-error])]
|
||||
[standard-auth/slide-button
|
||||
{:blur? true
|
||||
:size :size-48
|
||||
:customization-color customization-color
|
||||
:track-text (i18n/label :t/slide-to-import)
|
||||
:on-auth-success on-auth-success
|
||||
:auth-button-label (i18n/label :t/import-key-pair)
|
||||
:auth-button-icon-left :i/seed
|
||||
:container-style container-style
|
||||
:disabled? submit-disabled?
|
||||
:dependencies [on-auth-success]}]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [keypair (rf/sub [:get-screen-params])]
|
||||
[quo/overlay {:type :shell}
|
||||
[enter-seed-phrase/screen
|
||||
{:keypair keypair
|
||||
:navigation-icon :i/close
|
||||
:render-controls import-seed-phrase-controls
|
||||
:title (i18n/label :t/enter-recovery-phrase)
|
||||
:initial-insets (safe-area/get-insets)}]]))
|
||||
@@ -1,7 +1,8 @@
|
||||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.style)
|
||||
|
||||
(def title-container
|
||||
{:padding-horizontal 20
|
||||
{:flex 0
|
||||
:padding-horizontal 20
|
||||
:margin-vertical 12})
|
||||
|
||||
(defn page-wrapper
|
||||
|
||||
@@ -14,11 +14,12 @@
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn on-options-press
|
||||
[{:keys [theme]
|
||||
:as props} keypair]
|
||||
[{:keys [drawer-props keypair]}]
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [actions/view props keypair])
|
||||
:theme theme}]))
|
||||
{:content (fn [] [actions/view
|
||||
{:drawer-props drawer-props
|
||||
:keypair keypair}])
|
||||
:theme (:theme drawer-props)}]))
|
||||
|
||||
(defn options-drawer-props
|
||||
[{{:keys [name]} :keypair
|
||||
@@ -48,15 +49,17 @@
|
||||
on-press (rn/use-callback
|
||||
(fn []
|
||||
(on-options-press
|
||||
(options-drawer-props
|
||||
{:theme theme
|
||||
:keypair item
|
||||
:type (if default-keypair? :default-keypair :keypair)
|
||||
:stored :on-device
|
||||
:shortened-key shortened-key
|
||||
:customization-color customization-color
|
||||
:profile-picture profile-picture})
|
||||
item))
|
||||
{:keypair item
|
||||
:drawer-props (options-drawer-props
|
||||
{:theme theme
|
||||
:keypair item
|
||||
:type (if default-keypair?
|
||||
:default-keypair
|
||||
:keypair)
|
||||
:stored :on-device
|
||||
:shortened-key shortened-key
|
||||
:customization-color customization-color
|
||||
:profile-picture profile-picture})}))
|
||||
[customization-color default-keypair? item
|
||||
profile-picture shortened-key theme])]
|
||||
[quo/keypair
|
||||
@@ -78,13 +81,13 @@
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:content (fn [] [actions/view
|
||||
(options-drawer-props
|
||||
{:theme :dark
|
||||
:type :keypair
|
||||
:stored :missing
|
||||
:blur? true
|
||||
:keypair keypair-data})
|
||||
keypair-data])}]))
|
||||
{:keypair keypair-data
|
||||
:drawer-props (options-drawer-props
|
||||
{:theme :dark
|
||||
:type :keypair
|
||||
:stored :missing
|
||||
:blur? true
|
||||
:keypair keypair-data})}])}]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
@@ -106,22 +109,22 @@
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press navigate-back}]
|
||||
[rn/view {:style style/title-container}
|
||||
[quo/standard-title
|
||||
{:title (i18n/label :t/keypairs-and-accounts)
|
||||
:accessibility-label :keypairs-and-accounts-header
|
||||
:customization-color customization-color}]]
|
||||
[quo/standard-title
|
||||
{:title (i18n/label :t/keypairs-and-accounts)
|
||||
:container-style style/title-container
|
||||
:accessibility-label :keypairs-and-accounts-header
|
||||
:customization-color customization-color}]
|
||||
[rn/view {:style style/settings-keypairs-container}
|
||||
(when (seq missing-keypairs)
|
||||
[quo/missing-keypairs
|
||||
{:blur? true
|
||||
:keypairs missing-keypairs
|
||||
:on-import-press on-import-press
|
||||
:container-style style/missing-keypairs-container-style
|
||||
:on-options-press on-missing-keypair-options-press}])
|
||||
[rn/flat-list
|
||||
{:data operable-keypairs
|
||||
:render-fn keypair
|
||||
:header (when (seq missing-keypairs)
|
||||
[quo/missing-keypairs
|
||||
{:blur? true
|
||||
:keypairs missing-keypairs
|
||||
:on-import-press on-import-press
|
||||
:container-style style/missing-keypairs-container-style
|
||||
:on-options-press on-missing-keypair-options-press}])
|
||||
:render-data {:profile-picture profile-picture
|
||||
:compressed-key compressed-key
|
||||
:customization-color customization-color}
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def title-container
|
||||
{:padding-horizontal 20
|
||||
:margin-vertical 12})
|
||||
{:flex 0
|
||||
:padding-horizontal 20
|
||||
:padding-vertical 12})
|
||||
|
||||
(defn page-wrapper
|
||||
[inset-top]
|
||||
|
||||
@@ -19,21 +19,24 @@
|
||||
(rf/dispatch [:profile.settings/profile-update :test-networks-enabled? enable? {:on-success logout}]))
|
||||
|
||||
(defn testnet-mode-confirm-change-sheet
|
||||
[{:keys [title description on-confirm on-cancel]}]
|
||||
[{:keys [title blur? description on-confirm on-cancel]}]
|
||||
(let [customization-color (rf/sub [:profile/customization-color])]
|
||||
[:<>
|
||||
[quo/drawer-top
|
||||
{:title title
|
||||
:blur? blur?
|
||||
:container-style style/drawer-top}]
|
||||
[quo/text {:style style/description} description]
|
||||
[rn/view {:style style/info-box-container}
|
||||
[quo/information-box
|
||||
{:type :default
|
||||
:icon :i/info}
|
||||
{:type :default
|
||||
:blur? blur?
|
||||
:icon :i/info}
|
||||
(i18n/label :t/change-testnet-mode-logout-info)]]
|
||||
[quo/bottom-actions
|
||||
{:container-style {:style style/bottom-actions-container}
|
||||
:actions :two-actions
|
||||
:blur? blur?
|
||||
:button-one-label (i18n/label :t/confirm)
|
||||
:button-one-props {:accessibility-label :confirm-testnet-mode-change
|
||||
:on-press on-confirm
|
||||
@@ -41,22 +44,24 @@
|
||||
:customization-color customization-color}
|
||||
:button-two-label (i18n/label :t/cancel)
|
||||
:button-two-props {:accessibility-label :cancel-testnet-mode-change
|
||||
:type :dark-grey
|
||||
:type :grey
|
||||
:on-press on-cancel}}]]))
|
||||
|
||||
(defn view
|
||||
[{:keys [enable?]}]
|
||||
[{:keys [enable? blur?]}]
|
||||
(let [on-confirm (rn/use-callback
|
||||
#(on-confirm-change enable?)
|
||||
[enable?])]
|
||||
(if enable?
|
||||
[testnet-mode-confirm-change-sheet
|
||||
{:title (i18n/label :t/turn-on-testnet-mode)
|
||||
{:blur? blur?
|
||||
:title (i18n/label :t/turn-on-testnet-mode)
|
||||
:description (i18n/label :t/testnet-mode-enable-description)
|
||||
:on-confirm on-confirm
|
||||
:on-cancel hide-bottom-sheet}]
|
||||
[testnet-mode-confirm-change-sheet
|
||||
{:title (i18n/label :t/turn-off-testnet-mode)
|
||||
{:blur? blur?
|
||||
:title (i18n/label :t/turn-off-testnet-mode)
|
||||
:description (i18n/label :t/testnet-mode-disable-description)
|
||||
:on-confirm on-confirm
|
||||
:on-cancel hide-bottom-sheet}])))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns status-im.contexts.settings.wallet.network-settings.view
|
||||
(:require [quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.foundations.resources :as resources]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
@@ -44,9 +45,7 @@
|
||||
:data (map make-network-settings-item
|
||||
[{:details (:optimism networks)
|
||||
:testnet-mode? testnet-mode?
|
||||
:testnet-label [quo/text
|
||||
{:style style/testnet-not-available}
|
||||
(i18n/label :t/testnet-not-available)]}
|
||||
:testnet-label (i18n/label :t/sepolia-active)}
|
||||
{:details (:arbitrum networks)
|
||||
:testnet-mode? testnet-mode?
|
||||
:testnet-label (i18n/label :t/sepolia-active)}])
|
||||
@@ -56,9 +55,9 @@
|
||||
(defn testnet-mode-setting
|
||||
[{:keys [testnet-mode? on-enable on-disable]}]
|
||||
(let [on-change-testnet (rn/use-callback
|
||||
(fn [active?]
|
||||
(if active? (on-enable) (on-disable)))
|
||||
[on-enable on-disable])]
|
||||
(fn []
|
||||
(if-not testnet-mode? (on-enable) (on-disable)))
|
||||
[testnet-mode? on-enable on-disable])]
|
||||
{:blur? true
|
||||
:title (i18n/label :t/testnet-mode)
|
||||
:action :selector
|
||||
@@ -79,25 +78,32 @@
|
||||
:list-type :settings}])
|
||||
|
||||
(defn on-change-testnet
|
||||
[{:keys [enable? theme]}]
|
||||
[{:keys [enable? blur? theme]}]
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [testnet/view {:enable? enable?}])
|
||||
:theme theme}]))
|
||||
{:content (fn [] [testnet/view
|
||||
{:enable? enable?
|
||||
:blur? blur?}])
|
||||
:theme theme
|
||||
:shell? blur?
|
||||
:blur-background colors/bottom-sheet-background-blur}]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [insets (safe-area/get-insets)
|
||||
(let [blur? true
|
||||
insets (safe-area/get-insets)
|
||||
theme (quo.theme/use-theme)
|
||||
networks-by-name (rf/sub [:wallet/network-details-by-network-name])
|
||||
testnet-mode? (rf/sub [:profile/test-networks-enabled?])
|
||||
enable-testnet (rn/use-callback
|
||||
(fn []
|
||||
(on-change-testnet {:theme theme
|
||||
:blur? blur?
|
||||
:enable? true}))
|
||||
[theme])
|
||||
disable-testnet (rn/use-callback
|
||||
(fn []
|
||||
(on-change-testnet {:theme theme
|
||||
:blur? blur?
|
||||
:enable? false}))
|
||||
[theme])]
|
||||
[quo/overlay
|
||||
@@ -108,10 +114,10 @@
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press navigate-back}]
|
||||
[rn/view {:style style/title-container}
|
||||
[quo/standard-title
|
||||
{:title (i18n/label :t/network-settings)
|
||||
:accessibility-label :network-settings-header}]]
|
||||
[quo/standard-title
|
||||
{:title (i18n/label :t/network-settings)
|
||||
:container-style style/title-container
|
||||
:accessibility-label :network-settings-header}]
|
||||
[rn/view {:style (style/settings-container (:bottom insets))}
|
||||
(when networks-by-name
|
||||
[rn/view {:style style/networks-container}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
(ns status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def header-container
|
||||
{:padding-bottom 8})
|
||||
|
||||
(def input-container
|
||||
{:flex-direction :row
|
||||
:margin-horizontal 20})
|
||||
|
||||
(def input
|
||||
{:flex 1
|
||||
:margin-right 12})
|
||||
|
||||
(def scan-button
|
||||
{:margin-top 26})
|
||||
|
||||
(def info-message
|
||||
{:margin-top 8
|
||||
:margin-left 20})
|
||||
|
||||
(def existing-saved-address-container
|
||||
{:padding-horizontal 20
|
||||
:padding-vertical 12})
|
||||
|
||||
(def existing-saved-address-text
|
||||
{:color colors/white-opa-40})
|
||||
|
||||
(def saved-address-item
|
||||
{:margin-top 4})
|
||||
@@ -0,0 +1,175 @@
|
||||
(ns status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[react-native.clipboard :as clipboard]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.style :as style]
|
||||
[status-im.contexts.wallet.common.validation :as validation]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- navigate-back
|
||||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn- validate-input
|
||||
[account-addresses saved-addresses user-input]
|
||||
(cond
|
||||
(or (nil? user-input) (= user-input ""))
|
||||
nil
|
||||
|
||||
(contains? saved-addresses user-input)
|
||||
:existing-saved-address
|
||||
|
||||
(contains? account-addresses user-input)
|
||||
:own-account
|
||||
|
||||
(not
|
||||
(or (validation/eth-address? user-input)
|
||||
(validation/ens-name? user-input)))
|
||||
:invalid-address-or-ens))
|
||||
|
||||
(defn- address-input
|
||||
[{:keys [input-value on-change-text paste-into-input clear-input]}]
|
||||
(let [empty-input? (string/blank? input-value)
|
||||
on-scan-address (rn/use-callback #(rf/dispatch [:open-modal :screen/wallet.scan-address
|
||||
{:on-result on-change-text}]))]
|
||||
[rn/view {:style style/input-container}
|
||||
[quo/input
|
||||
{:accessibility-label :add-address-to-save
|
||||
:placeholder (i18n/label :t/address-placeholder)
|
||||
:container-style style/input
|
||||
:blur? true
|
||||
:label (i18n/label :t/address-or-ens-name)
|
||||
:auto-capitalize :none
|
||||
:multiline? true
|
||||
:on-clear clear-input
|
||||
:return-key-type :done
|
||||
:clearable? (not empty-input?)
|
||||
:on-change-text on-change-text
|
||||
:button (when empty-input?
|
||||
{:on-press paste-into-input
|
||||
:text (i18n/label :t/paste)})
|
||||
:value input-value}]
|
||||
[quo/button
|
||||
{:type :outline
|
||||
:on-press on-scan-address
|
||||
:container-style style/scan-button
|
||||
:background :blur
|
||||
:size 40
|
||||
:icon-only? true}
|
||||
:i/scan]]))
|
||||
|
||||
(defn- error-view
|
||||
[{:keys [error]}]
|
||||
(let [error-msg (condp = error
|
||||
:existing-saved-address
|
||||
(i18n/label :t/this-address-is-already-saved)
|
||||
|
||||
:own-account
|
||||
(i18n/label :t/you-cannot-add-your-own-account-as-a-saved-address)
|
||||
|
||||
:invalid-address-or-ens
|
||||
(i18n/label :t/this-is-not-an-eth-address-or-ens-name)
|
||||
|
||||
:ens-not-registered
|
||||
(i18n/label :t/this-ens-name-is-not-registered-yet)
|
||||
nil)]
|
||||
(when error-msg
|
||||
[quo/info-message
|
||||
{:accessibility-label :error-message
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:type :error
|
||||
:style style/info-message}
|
||||
error-msg])))
|
||||
|
||||
(defn- existing-saved-address
|
||||
[{:keys [address]}]
|
||||
(let [{:keys [name customization-color chain-short-names ens has-ens?]}
|
||||
(rf/sub [:wallet/saved-address-by-address
|
||||
address])]
|
||||
[rn/view {:style style/existing-saved-address-container}
|
||||
[quo/text
|
||||
{:size :paragraph-1
|
||||
:weight :medium
|
||||
:style style/existing-saved-address-text}
|
||||
(i18n/label :t/existing-saved-address)]
|
||||
[quo/saved-address
|
||||
{:blur? true
|
||||
:active-state? true
|
||||
:user-props {:name name
|
||||
:address (str chain-short-names address)
|
||||
:ens (when has-ens? ens)
|
||||
:customization-color customization-color
|
||||
:blur? true}
|
||||
:container-style style/saved-address-item}]]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [profile-color (rf/sub [:profile/customization-color])
|
||||
accounts-addresses (rf/sub [:wallet/addresses])
|
||||
saved-addresses-addresses (rf/sub [:wallet/saved-addresses-addresses])
|
||||
[input-value set-input-value] (rn/use-state nil)
|
||||
[error set-error] (rn/use-state nil)
|
||||
error? (some? error)
|
||||
validate #(validate-input accounts-addresses
|
||||
saved-addresses-addresses
|
||||
%)
|
||||
clear-input (rn/use-callback
|
||||
(fn []
|
||||
(set-input-value nil)
|
||||
(set-error nil)))
|
||||
on-change-text (rn/use-callback
|
||||
(fn [new-value]
|
||||
(let [lowercase-value (string/lower-case new-value)]
|
||||
(set-error (validate lowercase-value))
|
||||
(set-input-value lowercase-value))))
|
||||
paste-into-input (rn/use-callback #(clipboard/get-string
|
||||
(fn [clipboard-text]
|
||||
(on-change-text clipboard-text))))
|
||||
on-press-continue (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:wallet/set-address-to-save
|
||||
{:address input-value}])
|
||||
(rf/dispatch
|
||||
[:navigate-to-within-stack
|
||||
[:screen/settings.save-address
|
||||
:screen/settings.add-address-to-save]]))
|
||||
[input-value])]
|
||||
(rn/use-unmount #(rf/dispatch [:wallet/clear-address-to-save]))
|
||||
[quo/overlay {:type :shell}
|
||||
[floating-button-page/view
|
||||
{:footer-container-padding 0
|
||||
:header [quo/page-nav
|
||||
{:type :no-title
|
||||
:icon-name :i/close
|
||||
:behind-overlay? true
|
||||
:on-press navigate-back
|
||||
:margin-top (safe-area/get-top)
|
||||
:accessibility-label :add-address-to-save-page-nav}]
|
||||
:footer [quo/button
|
||||
{:customization-color profile-color
|
||||
:disabled? (or (string/blank? input-value)
|
||||
error?)
|
||||
:on-press on-press-continue}
|
||||
(i18n/label :t/continue)]}
|
||||
[quo/page-top
|
||||
{:container-style style/header-container
|
||||
:blur? true
|
||||
:title (i18n/label :t/add-address)
|
||||
:description :text
|
||||
:description-text (i18n/label :t/add-address-to-save-description)}]
|
||||
[address-input
|
||||
{:input-value input-value
|
||||
:on-change-text on-change-text
|
||||
:paste-into-input paste-into-input
|
||||
:clear-input clear-input}]
|
||||
(when error?
|
||||
[:<>
|
||||
[error-view {:error error}]
|
||||
(when (= error :existing-saved-address)
|
||||
[existing-saved-address {:address input-value}])])]]))
|
||||
@@ -1,20 +1,12 @@
|
||||
(ns status-im.contexts.settings.wallet.saved-addresses.events
|
||||
(:require
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.data-store :as data-store]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn save-address
|
||||
[{:keys [db]}
|
||||
[{:keys [address name customization-color on-success on-error chain-short-names ens]
|
||||
:or {on-success (fn [])
|
||||
on-error (fn [])
|
||||
name ""
|
||||
customization-color constants/account-default-customization-color
|
||||
ens ""
|
||||
;; the chain short names should be a string like eth: or eth:arb:oeth:
|
||||
chain-short-names (str constants/mainnet-short-name ":")}}]]
|
||||
[{:keys [address name customization-color on-success on-error chain-short-names ens]}]]
|
||||
(let [test-networks-enabled? (boolean (get-in db [:profile/profile :test-networks-enabled?]))
|
||||
address-to-save {:address address
|
||||
:name name
|
||||
@@ -93,3 +85,39 @@
|
||||
:on-error [:wallet/delete-saved-address-failed]}]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/delete-saved-address delete-saved-address)
|
||||
|
||||
(defn add-saved-address-success
|
||||
[_ [toast-message]]
|
||||
{:fx [[:dispatch [:wallet/get-saved-addresses]]
|
||||
[:dispatch [:navigate-back-to :screen/settings.saved-addresses]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text toast-message}]}]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/add-saved-address-success add-saved-address-success)
|
||||
|
||||
(defn add-saved-address-failed
|
||||
[_ [error]]
|
||||
{:fx [[:dispatch [:wallet/saved-addresses-rpc-error :add-save-address error]]
|
||||
[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type :negative
|
||||
:theme :dark
|
||||
:text error}]]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/add-saved-address-failed add-saved-address-failed)
|
||||
|
||||
(defn set-address-to-save
|
||||
[{:keys [db]} [args]]
|
||||
{:db (assoc-in db [:wallet :ui :saved-address] args)})
|
||||
|
||||
(rf/reg-event-fx :wallet/set-address-to-save set-address-to-save)
|
||||
|
||||
(defn clear-address-to-save
|
||||
[{:keys [db]}]
|
||||
{:db (update-in db [:wallet :ui] dissoc :saved-address)})
|
||||
|
||||
(rf/reg-event-fx :wallet/clear-address-to-save clear-address-to-save)
|
||||
|
||||
@@ -56,9 +56,7 @@
|
||||
:mixedcase-address "0x2"
|
||||
:chain-short-names "eth:arb1:oeth:"
|
||||
:has-ens? false
|
||||
:network-preferences-names #{:arbitrum
|
||||
:optimism
|
||||
:mainnet}
|
||||
:network-preferences-names `(:mainnet :arbitrum :optimism)
|
||||
:name "Bob"
|
||||
:created-at 1716826714
|
||||
:ens ""
|
||||
@@ -76,9 +74,7 @@
|
||||
:address "0x2"
|
||||
:mixedcase-address "0x2"
|
||||
:chain-short-names "eth:arb1:oeth:"
|
||||
:network-preferences-names #{:arbitrum
|
||||
:optimism
|
||||
:mainnet}
|
||||
:network-preferences-names `(:mainnet :arbitrum :optimism)
|
||||
:has-ens? false
|
||||
:name "Bob"
|
||||
:created-at 1716826714
|
||||
@@ -89,9 +85,7 @@
|
||||
:address "0x1"
|
||||
:mixedcase-address "0x1"
|
||||
:chain-short-names "eth:arb1:oeth:"
|
||||
:network-preferences-names #{:arbitrum
|
||||
:optimism
|
||||
:mainnet}
|
||||
:network-preferences-names `(:mainnet :arbitrum :optimism)
|
||||
:has-ens? false
|
||||
:name "Amy"
|
||||
:created-at 1716826806
|
||||
@@ -150,3 +144,20 @@
|
||||
:on-success [:wallet/delete-saved-address-success toast-message]
|
||||
:on-error [:wallet/delete-saved-address-failed]}]]]]
|
||||
(is (match? expected-fx result-fx)))))
|
||||
|
||||
(deftest add-saved-address-success-test
|
||||
(testing "add saved address success test - gets saved addresses, dismiss modals and dispatch toast"
|
||||
(let [cofx {:db {}}
|
||||
toast-message "Address saved"
|
||||
effects (events/add-saved-address-success cofx [toast-message])
|
||||
result-fx (:fx effects)
|
||||
expected-fx [[:dispatch [:wallet/get-saved-addresses]]
|
||||
[:dispatch [:navigate-back-to :screen/settings.saved-addresses]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text toast-message}]}]]]
|
||||
(is (= (count result-fx) 3))
|
||||
(is (match? expected-fx result-fx)))))
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
(ns status-im.contexts.settings.wallet.saved-addresses.save-address.style)
|
||||
|
||||
(def title-input
|
||||
{:padding-horizontal 20
|
||||
:padding-top 12
|
||||
:padding-bottom 16})
|
||||
|
||||
(def avatar
|
||||
{:margin-horizontal 20
|
||||
:margin-top 12})
|
||||
|
||||
(def color-picker-top-divider
|
||||
{:margin-bottom 12})
|
||||
|
||||
(def section-label
|
||||
{:padding-horizontal 20
|
||||
:padding-bottom 4})
|
||||
|
||||
(def color-picker
|
||||
{:padding-horizontal 20
|
||||
:padding-vertical 12})
|
||||
|
||||
(def color-picker-bottom-divider
|
||||
{:margin-top 8
|
||||
:margin-bottom 12})
|
||||
|
||||
(def data-item
|
||||
{:margin-horizontal 20
|
||||
:padding-vertical 8
|
||||
:margin-top 8
|
||||
:margin-bottom 12})
|
||||
@@ -0,0 +1,146 @@
|
||||
(ns status-im.contexts.settings.wallet.saved-addresses.save-address.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.contexts.settings.wallet.saved-addresses.save-address.style :as style]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.contexts.wallet.sheets.network-preferences.view :as network-preferences]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- navigate-back
|
||||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn- network-preferences-sheet
|
||||
[{:keys [address color selected-networks set-selected-networks]}]
|
||||
(fn []
|
||||
[network-preferences/view
|
||||
{:title (i18n/label :t/add-network-preferences)
|
||||
:description (i18n/label :t/saved-address-network-preference-selection-description)
|
||||
:button-label (i18n/label :t/add-preferences)
|
||||
:blur? true
|
||||
:selected-networks (set selected-networks)
|
||||
:account {:address address
|
||||
:color color}
|
||||
:on-save (fn [chain-ids]
|
||||
(set-selected-networks (map network-utils/id->network chain-ids))
|
||||
(rf/dispatch [:hide-bottom-sheet]))}]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{:keys [address]} (rf/sub [:wallet/saved-address])
|
||||
[network-prefixes address-without-prefix] (utils/split-prefix-and-address address)
|
||||
[address-label set-address-label] (rn/use-state "")
|
||||
[address-color set-address-color] (rn/use-state (rand-nth colors/account-colors))
|
||||
[selected-networks set-selected-networks]
|
||||
(rn/use-state (network-utils/network-preference-prefix->network-names network-prefixes))
|
||||
chain-short-names (rn/use-memo
|
||||
#(network-utils/network-names->network-preference-prefix
|
||||
selected-networks)
|
||||
[selected-networks])
|
||||
placeholder (i18n/label :t/address-name)
|
||||
open-network-preferences (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:content (network-preferences-sheet
|
||||
{:address address-without-prefix
|
||||
:color address-color
|
||||
:selected-networks selected-networks
|
||||
:set-selected-networks
|
||||
set-selected-networks})}]))
|
||||
[address selected-networks address-color])
|
||||
on-press-save (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:wallet/save-address
|
||||
{:on-success
|
||||
[:wallet/add-saved-address-success
|
||||
(i18n/label :t/address-saved)]
|
||||
:on-error
|
||||
[:wallet/add-saved-address-failed]
|
||||
:name address-label
|
||||
:address address-without-prefix
|
||||
:customization-color address-color
|
||||
:chain-short-names chain-short-names}]))
|
||||
[address-without-prefix chain-short-names address-label
|
||||
address-color])]
|
||||
[quo/overlay {:type :shell}
|
||||
[floating-button-page/view
|
||||
{:footer-container-padding 0
|
||||
:header [quo/page-nav
|
||||
{:type :no-title
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press navigate-back
|
||||
:margin-top (safe-area/get-top)
|
||||
:accessibility-label :save-address-page-nav}]
|
||||
:footer [quo/button
|
||||
{:accessibility-label :save-address-button
|
||||
:type :primary
|
||||
:customization-color address-color
|
||||
:disabled? (string/blank? address-label)
|
||||
:on-press on-press-save}
|
||||
(i18n/label :t/save-address)]
|
||||
:customization-color address-color
|
||||
:gradient-cover? true}
|
||||
[quo/wallet-user-avatar
|
||||
{:full-name (if (string/blank? address-label)
|
||||
placeholder
|
||||
address-label)
|
||||
:customization-color address-color
|
||||
:blur? true
|
||||
:size :size-80
|
||||
:container-style style/avatar}]
|
||||
[quo/title-input
|
||||
{:blur? true
|
||||
:auto-focus true
|
||||
:max-length 24
|
||||
:size :heading-1
|
||||
:placeholder placeholder
|
||||
:default-value address-label
|
||||
:on-change-text set-address-label
|
||||
:customization-color address-color
|
||||
:container-style style/title-input}]
|
||||
[quo/divider-line
|
||||
{:blur? true
|
||||
:container-style style/color-picker-top-divider}]
|
||||
[quo/section-label
|
||||
{:section (i18n/label :t/colour)
|
||||
:blur? true
|
||||
:container-style style/section-label}]
|
||||
[quo/color-picker
|
||||
{:default-selected address-color
|
||||
:on-change set-address-color
|
||||
:blur? true
|
||||
:container-style style/color-picker}]
|
||||
[quo/divider-line
|
||||
{:blur? true
|
||||
:container-style style/color-picker-bottom-divider}]
|
||||
[quo/data-item
|
||||
{:status :default
|
||||
:size :default
|
||||
:subtitle-type :default
|
||||
:label :none
|
||||
:blur? true
|
||||
:icon-right? true
|
||||
:right-icon :i/advanced
|
||||
:card? true
|
||||
:title (i18n/label :t/address)
|
||||
:custom-subtitle (rn/use-callback
|
||||
(fn []
|
||||
[quo/address-text
|
||||
{:full-address? true
|
||||
:address (str chain-short-names address-without-prefix)
|
||||
:format :long}])
|
||||
[selected-networks address])
|
||||
:on-press open-network-preferences
|
||||
:container-style style/data-item}]]]))
|
||||
@@ -0,0 +1,10 @@
|
||||
(ns status-im.contexts.settings.wallet.saved-addresses.share-address.style)
|
||||
|
||||
(def screen-container
|
||||
{:flex 1})
|
||||
|
||||
(def top-container
|
||||
{:margin-bottom 8})
|
||||
|
||||
(def qr-wrapper
|
||||
{:padding-horizontal 20})
|
||||
@@ -0,0 +1,107 @@
|
||||
(ns status-im.contexts.settings.wallet.saved-addresses.share-address.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.contexts.settings.wallet.saved-addresses.share-address.style :as style]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.contexts.wallet.sheets.network-preferences.view :as network-preferences]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.image-server :as image-server]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def qr-size 500)
|
||||
|
||||
(defn- navigate-back
|
||||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn- share-action
|
||||
[address share-title]
|
||||
(rf/dispatch [:open-share
|
||||
{:options (if platform/ios?
|
||||
{:activityItemSources [{:placeholderItem {:type :text
|
||||
:content address}
|
||||
:item {:default {:type :text
|
||||
:content
|
||||
address}}
|
||||
:linkMetadata {:title share-title}}]}
|
||||
{:title share-title
|
||||
:subject share-title
|
||||
:message address
|
||||
:isNewTask true})}]))
|
||||
|
||||
(defn- open-preferences
|
||||
[{:keys [address color selected-networks set-selected-networks]}]
|
||||
(let [on-save (fn [chain-ids]
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(set-selected-networks (map network-utils/id->network chain-ids)))
|
||||
sheet-content (fn []
|
||||
[network-preferences/view
|
||||
{:description (i18n/label
|
||||
:t/saved-address-network-preference-selection-description)
|
||||
:button-label (i18n/label :t/display)
|
||||
:blur? true
|
||||
:selected-networks (set selected-networks)
|
||||
:account {:address address
|
||||
:color color}
|
||||
:on-save on-save}])]
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:content sheet-content}])))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{:keys [name address customization-color
|
||||
network-preferences-names]} (rf/sub [:get-screen-params])
|
||||
[wallet-type set-wallet-type] (rn/use-state :legacy)
|
||||
[selected-networks set-selected-networks] (rn/use-state network-preferences-names)
|
||||
on-settings-press (rn/use-callback
|
||||
#(open-preferences
|
||||
{:selected-networks selected-networks
|
||||
:set-selected-networks set-selected-networks
|
||||
:address address
|
||||
:color customization-color})
|
||||
[address customization-color selected-networks])
|
||||
on-legacy-press (rn/use-callback #(set-wallet-type :legacy))
|
||||
on-multichain-press (rn/use-callback #(set-wallet-type :multichain))
|
||||
share-title (str name " " (i18n/label :t/address))
|
||||
qr-url (rn/use-memo #(utils/get-wallet-qr
|
||||
{:wallet-type wallet-type
|
||||
:selected-networks selected-networks
|
||||
:address address})
|
||||
[wallet-type selected-networks address])
|
||||
qr-media-server-uri (rn/use-memo
|
||||
#(image-server/get-qr-image-uri-for-any-url
|
||||
{:url qr-url
|
||||
:port (rf/sub [:mediaserver/port])
|
||||
:qr-size qr-size
|
||||
:error-level :highest})
|
||||
[qr-url])]
|
||||
[quo/overlay
|
||||
{:type :shell
|
||||
:top-inset? true}
|
||||
[rn/view {:style style/screen-container}
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press navigate-back
|
||||
:background :blur
|
||||
:accessibility-label :top-bar}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/share-address)
|
||||
:container-style style/top-container}]
|
||||
[rn/view {:style style/qr-wrapper}
|
||||
[quo/share-qr-code
|
||||
{:type :saved-address
|
||||
:address wallet-type
|
||||
:qr-image-uri qr-media-server-uri
|
||||
:qr-data qr-url
|
||||
:networks selected-networks
|
||||
:on-share-press #(share-action qr-url share-title)
|
||||
:full-name name
|
||||
:customization-color customization-color
|
||||
:on-legacy-press on-legacy-press
|
||||
:on-multichain-press on-multichain-press
|
||||
:on-settings-press on-settings-press}]]]]))
|
||||
+5
-1
@@ -56,6 +56,10 @@
|
||||
:shell? true
|
||||
:content (fn []
|
||||
[remove-address/view opts])}])
|
||||
[opts])
|
||||
open-show-address-qr (rn/use-callback
|
||||
#(rf/dispatch [:open-modal
|
||||
:screen/settings.share-saved-address opts])
|
||||
[opts])]
|
||||
[quo/action-drawer
|
||||
[[{:icon :i/arrow-up
|
||||
@@ -91,7 +95,7 @@
|
||||
{:icon :i/qr-code
|
||||
:label (i18n/label :t/show-address-qr)
|
||||
:blur? true
|
||||
:on-press not-implemented/alert
|
||||
:on-press open-show-address-qr
|
||||
:accessibility-label :show-address-qr-code}
|
||||
{:icon :i/edit
|
||||
:label (i18n/label :t/edit-account)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
(ns status-im.contexts.settings.wallet.saved-addresses.style)
|
||||
|
||||
(def title-container
|
||||
{:padding-horizontal 20
|
||||
{:flex 0
|
||||
:padding-horizontal 20
|
||||
:margin-top 12
|
||||
:margin-bottom 16})
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
:container-style style/empty-container-style}]))
|
||||
|
||||
(defn- saved-address
|
||||
[{:keys [name address chain-short-names customization-color has-ens? ens]}]
|
||||
[{:keys [name address chain-short-names customization-color has-ens? ens network-preferences-names]}]
|
||||
(let [full-address (str chain-short-names address)
|
||||
on-press-saved-address (rn/use-callback
|
||||
#(rf/dispatch
|
||||
@@ -29,14 +29,16 @@
|
||||
:shell? true
|
||||
:content (fn []
|
||||
[address-options/view
|
||||
{:address address
|
||||
:chain-short-names chain-short-names
|
||||
:full-address full-address
|
||||
:name name
|
||||
:customization-color customization-color}])}])
|
||||
{:address address
|
||||
:chain-short-names chain-short-names
|
||||
:full-address full-address
|
||||
:name name
|
||||
:network-preferences-names network-preferences-names
|
||||
:customization-color customization-color}])}])
|
||||
[address chain-short-names full-address name customization-color])]
|
||||
[quo/saved-address
|
||||
{:user-props {:name name
|
||||
{:blur? true
|
||||
:user-props {:name name
|
||||
:address full-address
|
||||
:ens (when has-ens? ens)
|
||||
:customization-color customization-color
|
||||
@@ -59,6 +61,11 @@
|
||||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn- add-address-to-save
|
||||
[]
|
||||
(rf/dispatch [:navigate-to-within-stack
|
||||
[:screen/settings.add-address-to-save :screen/settings.saved-addresses]]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [inset-top (safe-area/get-top)
|
||||
@@ -72,13 +79,14 @@
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press navigate-back}]
|
||||
[rn/view {:style style/title-container}
|
||||
[quo/standard-title
|
||||
{:title (i18n/label :t/saved-addresses)
|
||||
:accessibility-label :saved-addresses-header
|
||||
:right :action
|
||||
:customization-color customization-color
|
||||
:icon :i/add}]]
|
||||
[quo/standard-title
|
||||
{:title (i18n/label :t/saved-addresses)
|
||||
:accessibility-label :saved-addresses-header
|
||||
:right :action
|
||||
:on-press add-address-to-save
|
||||
:customization-color customization-color
|
||||
:icon :i/add
|
||||
:container-style style/title-container}]
|
||||
[rn/section-list
|
||||
{:key-fn :title
|
||||
:sticky-section-headers-enabled false
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
(defn open-saved-addresses-settings-modal
|
||||
[]
|
||||
(rf/dispatch [:open-modal :screen/settings.saved-addresses]))
|
||||
(rf/dispatch [:navigate-to-within-stack [:screen/settings.saved-addresses :settings]]))
|
||||
|
||||
(defn open-keypairs-and-accounts-settings-modal
|
||||
[]
|
||||
(rf/dispatch [:open-modal :screen/settings.keypairs-and-accounts]))
|
||||
(rf/dispatch [:navigate-to-within-stack [:screen/settings.keypairs-and-accounts :settings]]))
|
||||
|
||||
(defn basic-settings-options
|
||||
[]
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
(defn open-network-settings-modal
|
||||
[]
|
||||
(rf/dispatch [:open-modal :screen/settings.network-settings]))
|
||||
(rf/dispatch [:navigate-to-within-stack [:screen/settings.network-settings :settings]]))
|
||||
|
||||
(defn advanced-settings-options
|
||||
[]
|
||||
@@ -49,13 +49,12 @@
|
||||
|
||||
(defn advanced-settings
|
||||
[]
|
||||
(when (ff/enabled? ::ff/settings.network-settings)
|
||||
[quo/category
|
||||
{:key :advanced-wallet-settings
|
||||
:label (i18n/label :t/advanced)
|
||||
:data (advanced-settings-options)
|
||||
:blur? true
|
||||
:list-type :settings}]))
|
||||
[quo/category
|
||||
{:key :advanced-wallet-settings
|
||||
:label (i18n/label :t/advanced)
|
||||
:data (advanced-settings-options)
|
||||
:blur? true
|
||||
:list-type :settings}])
|
||||
|
||||
(defn navigate-back
|
||||
[]
|
||||
@@ -75,5 +74,7 @@
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/wallet)
|
||||
:title-accessibility-label :wallet-settings-header}]
|
||||
[basic-settings]
|
||||
(when (or (ff/enabled? ::ff/settings.keypairs-and-accounts)
|
||||
(ff/enabled? ::ff/settings.saved-addresses))
|
||||
[basic-settings])
|
||||
[advanced-settings]]))
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
(ns status-im.contexts.shell.qr-reader.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[react-native.core :as rn]
|
||||
[react-native.hooks :as hooks]
|
||||
[status-im.common.router :as router]
|
||||
[status-im.common.scan-qr-code.view :as scan-qr-code]
|
||||
[status-im.common.validation.general :as validators]
|
||||
[status-im.contexts.communities.events]
|
||||
[status-im.contexts.wallet.common.validation :as wallet-validation]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.ethereum.eip.eip681 :as eip681]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.url :as url]))
|
||||
(:require [clojure.string :as string]
|
||||
[react-native.core :as rn]
|
||||
[react-native.hooks :as hooks]
|
||||
[status-im.common.router :as router]
|
||||
[status-im.common.scan-qr-code.view :as scan-qr-code]
|
||||
[status-im.common.validation.general :as validators]
|
||||
[status-im.contexts.communities.events]
|
||||
[status-im.contexts.wallet.common.validation :as wallet-validation]
|
||||
[status-im.contexts.wallet.wallet-connect.utils :as wc-utils]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.ethereum.eip.eip681 :as eip681]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.url :as url]))
|
||||
|
||||
(def invalid-qr-toast
|
||||
{:type :negative
|
||||
@@ -42,10 +43,6 @@
|
||||
[_]
|
||||
false)
|
||||
|
||||
(defn wallet-connect-code?
|
||||
[scanned-text]
|
||||
(string/starts-with? scanned-text "wc:"))
|
||||
|
||||
(defn url?
|
||||
[scanned-text]
|
||||
(url/url? scanned-text))
|
||||
@@ -68,6 +65,12 @@
|
||||
[:toasts/upsert invalid-qr-toast]
|
||||
300))
|
||||
|
||||
(defn- handle-wallet-connect
|
||||
[scanned-text]
|
||||
(debounce/debounce-and-dispatch
|
||||
[:wallet-connect/on-scan-connection scanned-text]
|
||||
300))
|
||||
|
||||
(defn on-qr-code-scanned
|
||||
[scanned-text]
|
||||
(cond
|
||||
@@ -100,9 +103,10 @@
|
||||
;; TODO: https://github.com/status-im/status-mobile/issues/18744
|
||||
nil
|
||||
|
||||
(wallet-connect-code? scanned-text)
|
||||
;; WalletConnect is not working yet, this flow should be updated once WalletConnect is ready
|
||||
nil
|
||||
(and
|
||||
(wc-utils/valid-uri? scanned-text)
|
||||
(ff/enabled? ::ff/wallet.wallet-connect))
|
||||
(handle-wallet-connect scanned-text)
|
||||
|
||||
(url? scanned-text)
|
||||
(debounce/debounce-and-dispatch [:browser.ui/open-url scanned-text] 300)
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
(defn view
|
||||
[]
|
||||
(let [padding-top (:top (safe-area/get-insets))
|
||||
wallet-type (reagent/atom :legacy)
|
||||
wallet-type (reagent/atom :multichain)
|
||||
selected-networks (reagent/atom constants/default-network-names)
|
||||
on-settings-press #(open-preferences selected-networks)
|
||||
on-legacy-press #(reset! wallet-type :legacy)
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
{:start-flow? true
|
||||
:flow-id :wallet-bridge-flow}]))
|
||||
:swap-action (when (ff/enabled? ::ff/wallet.swap)
|
||||
#(rf/dispatch [:wallet/start-swap]))}])
|
||||
#(rf/dispatch [:wallet.swap/start]))}])
|
||||
[quo/tabs
|
||||
{:style style/tabs
|
||||
:size 32
|
||||
|
||||
+1
-4
@@ -46,8 +46,6 @@
|
||||
:public-key ""}])}}
|
||||
[quo/data-item
|
||||
{:card? true
|
||||
:right-icon :i/advanced
|
||||
:icon-right? true
|
||||
:emoji @account-emoji
|
||||
:title (i18n/label :t/watched-address)
|
||||
:subtitle address
|
||||
@@ -60,5 +58,4 @@
|
||||
;; https://github.com/status-im/status-mobile/issues/17009
|
||||
:weight :monospace}
|
||||
address])
|
||||
:container-style style/data-item
|
||||
:on-press #(js/alert "To be implemented")}]]])))
|
||||
:container-style style/data-item}]]])))
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
(i18n/label :t/continue)]}
|
||||
[quo/page-top
|
||||
{:container-style style/header-container
|
||||
:title (i18n/label :t/add-address)
|
||||
:title (i18n/label :t/add-address-to-watch)
|
||||
:description :text
|
||||
:description-text (i18n/label :t/enter-eth)}]
|
||||
[:f> address-input
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[status-im.contexts.wallet.add-account.create-account.events :as events]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(deftest confirm-account-origin
|
||||
(deftest confirm-account-origin-test
|
||||
(let [db {:wallet {:ui {:create-account {}}}}
|
||||
props ["key-uid"]
|
||||
expected-db {:wallet {:ui {:create-account {:selected-keypair-uid "key-uid"}}}}
|
||||
@@ -14,7 +14,7 @@
|
||||
result-db (:db effects)]
|
||||
(is (match? result-db expected-db))))
|
||||
|
||||
(deftest store-seed-phrase
|
||||
(deftest store-seed-phrase-test
|
||||
(let [db {}
|
||||
props [{:seed-phrase "test-secret" :random-phrase "random-test"}]
|
||||
expected-db {:wallet {:ui {:create-account {:new-keypair {:seed-phrase "test-secret"
|
||||
@@ -23,7 +23,7 @@
|
||||
result-db (:db effects)]
|
||||
(is (match? result-db expected-db))))
|
||||
|
||||
(deftest store-account-generated
|
||||
(deftest store-account-generated-test
|
||||
(let [db {:wallet {:ui {:create-account
|
||||
{:new-keypair {:seed-phrase "test-secret"
|
||||
:random-phrase "random-test"}}}}}
|
||||
@@ -55,7 +55,7 @@
|
||||
(is (= (unmask-mnemonic result-db) (unmask-mnemonic expected-db)))))
|
||||
|
||||
|
||||
(deftest generate-account-for-keypair
|
||||
(deftest generate-account-for-keypair-test
|
||||
(let [db {:wallet {:ui {:create-account {:new-keypair {:seed-phrase "test-secret"}}}}}
|
||||
props [{:keypair-name "test-keypair"}]
|
||||
expected-effects [[:effects.wallet/create-account-from-mnemonic
|
||||
@@ -67,7 +67,7 @@
|
||||
{:fx expected-effects}))
|
||||
(is (some? (get-in effects [:fx 0 1 :on-success])))))
|
||||
|
||||
(deftest clear-create-account-data
|
||||
(deftest clear-create-account-data-test
|
||||
(let [db {:wallet {:ui {:create-account {:new-keypair "test-keypair"}}}}
|
||||
expected-db {:wallet {:ui {:create-account {}}}}
|
||||
effects (events/clear-create-account-data {:db db})]
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
"image/gif"
|
||||
"image/bmp"
|
||||
"image/png"
|
||||
"image/webp"})
|
||||
"image/webp"
|
||||
"image/avif"})
|
||||
|
||||
(defn supported-file?
|
||||
[collectible-type]
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
(def token-id "0xT")
|
||||
(def contract-address "0xC")
|
||||
|
||||
(deftest test-network->chain-id
|
||||
(deftest network->chain-id-test
|
||||
(testing "get-opensea-collectible-url mainnet"
|
||||
(is (= (utils/get-opensea-collectible-url {:chain-id constants/ethereum-mainnet-chain-id
|
||||
:contract-address contract-address
|
||||
@@ -66,5 +66,3 @@
|
||||
:test-networks-enabled? true
|
||||
:is-goerli-enabled? true})
|
||||
"https://testnets.opensea.io/assets/optimism-goerli/0xC/0xT"))))
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
(ns status-im.contexts.wallet.common.scan-account.view
|
||||
(:require [clojure.string :as string]
|
||||
[status-im.common.scan-qr-code.view :as scan-qr-code]
|
||||
[status-im.constants :as constants]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[status-im.common.scan-qr-code.view :as scan-qr-code]
|
||||
[status-im.constants :as constants]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def ^:private supported-networks #{:eth :arb1 :oeth})
|
||||
|
||||
|
||||
@@ -114,7 +114,17 @@
|
||||
[prefix]
|
||||
(as-> prefix $
|
||||
(string/split $ ":")
|
||||
(map short-name->network $)))
|
||||
(map short-name->network $)
|
||||
(remove nil? $)))
|
||||
|
||||
(defn network-names->network-preference-prefix
|
||||
[network-names]
|
||||
(if (empty? network-names)
|
||||
""
|
||||
(->> network-names
|
||||
(map network->short-name)
|
||||
(remove nil?)
|
||||
short-names->network-preference-prefix)))
|
||||
|
||||
(defn network-ids->formatted-text
|
||||
[network-ids]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils.networks :as utils]))
|
||||
|
||||
(deftest test-network->chain-id
|
||||
(deftest network->chain-id-test
|
||||
(testing "network->chain-id function"
|
||||
(is (= (utils/network->chain-id {:network :mainnet :testnet-enabled? false :goerli-enabled? false})
|
||||
constants/ethereum-mainnet-chain-id))
|
||||
@@ -21,15 +21,6 @@
|
||||
(is (= (utils/network->chain-id {:network :arbitrum :testnet-enabled? true :goerli-enabled? false})
|
||||
constants/arbitrum-sepolia-chain-id))))
|
||||
|
||||
(deftest test-network-preference-prefix->network-names
|
||||
(testing "network-preference-prefix->network-names function"
|
||||
(is (= (utils/network-preference-prefix->network-names "eth")
|
||||
(seq [:mainnet])))
|
||||
(is (= (utils/network-preference-prefix->network-names "eth:oeth")
|
||||
(seq [:mainnet :optimism])))
|
||||
(is (= (utils/network-preference-prefix->network-names "eth:oeth:arb1")
|
||||
(seq [:mainnet :optimism :arbitrum])))))
|
||||
|
||||
(deftest short-names->network-preference-prefix-test
|
||||
(are [expected short-names]
|
||||
(= expected (utils/short-names->network-preference-prefix short-names))
|
||||
@@ -42,9 +33,20 @@
|
||||
(= expected (utils/network-preference-prefix->network-names short-names))
|
||||
(seq [:mainnet]) "eth"
|
||||
(seq [:mainnet :optimism]) "eth:oeth"
|
||||
(seq [:mainnet :optimism :arbitrum]) "eth:oeth:arb1"))
|
||||
(seq [:mainnet :optimism :arbitrum]) "eth:oeth:arb1"
|
||||
(seq [:mainnet :arbitrum]) "eth:sol:arb1"))
|
||||
|
||||
(deftest test-network-ids->formatted-text
|
||||
(deftest network-names->network-preference-prefix-test
|
||||
(are [expected network-names]
|
||||
(= expected (utils/network-names->network-preference-prefix network-names))
|
||||
"eth:" [:mainnet]
|
||||
"eth:oeth:" [:mainnet :optimism]
|
||||
"eth:oeth:arb1:" [:mainnet :optimism :arbitrum]
|
||||
"eth:arb1:" [:mainnet :polygon :arbitrum]
|
||||
"" []
|
||||
"" nil))
|
||||
|
||||
(deftest network-ids->formatted-text-test
|
||||
(testing "Empty network-ids should return an empty string"
|
||||
(is (= "" (utils/network-ids->formatted-text []))))
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[utils.money :as money]))
|
||||
|
||||
(deftest test-get-first-name
|
||||
(deftest get-first-name-test
|
||||
(testing "get-first-name function"
|
||||
(is (= (utils/get-first-name "John Doe") "John"))
|
||||
(is (= (utils/get-first-name "Jane Smith xyz") "Jane"))))
|
||||
|
||||
(deftest test-prettify-balance
|
||||
(deftest prettify-balance-test
|
||||
(testing "prettify-balance function"
|
||||
(is (= (utils/prettify-balance "$" 100) "$100.00"))
|
||||
(is (= (utils/prettify-balance "$" 0.5) "$0.50"))
|
||||
@@ -17,25 +17,25 @@
|
||||
(is (= (utils/prettify-balance "$" nil) "$0.00"))
|
||||
(is (= (utils/prettify-balance "$" "invalid input") "$0.00"))))
|
||||
|
||||
(deftest test-get-derivation-path
|
||||
(deftest get-derivation-path-test
|
||||
(testing "get-derivation-path function"
|
||||
(is (= (utils/get-derivation-path 5) "m/44'/60'/0'/0/5"))
|
||||
(is (= (utils/get-derivation-path 0) "m/44'/60'/0'/0/0"))
|
||||
(is (= (utils/get-derivation-path 123) "m/44'/60'/0'/0/123"))))
|
||||
|
||||
(deftest test-format-derivation-path
|
||||
(deftest format-derivation-path-test
|
||||
(testing "format-derivation-path function"
|
||||
(is (= (utils/format-derivation-path "m/44'/60'/0'/0/5") "m / 44' / 60' / 0' / 0 / 5"))
|
||||
(is (= (utils/format-derivation-path "m/44'/60'/0'/0/0") "m / 44' / 60' / 0' / 0 / 0"))
|
||||
(is (= (utils/format-derivation-path "m/44'/60'/0'/0/123") "m / 44' / 60' / 0' / 0 / 123"))))
|
||||
|
||||
(deftest test-get-formatted-derivation-path
|
||||
(deftest get-formatted-derivation-path-test
|
||||
(testing "get-formatted-derivation-path function"
|
||||
(is (= (utils/get-formatted-derivation-path 5) "m / 44' / 60' / 0' / 0 / 5"))
|
||||
(is (= (utils/get-formatted-derivation-path 0) "m / 44' / 60' / 0' / 0 / 0"))
|
||||
(is (= (utils/get-formatted-derivation-path 123) "m / 44' / 60' / 0' / 0 / 123"))))
|
||||
|
||||
(deftest test-total-raw-balance-in-all-chains
|
||||
(deftest total-raw-balance-in-all-chains-test
|
||||
(testing "total-raw-balance-in-all-chains function"
|
||||
(let [balances-per-chain {1 {:raw-balance (money/bignumber 100)}
|
||||
10 {:raw-balance (money/bignumber 200)}
|
||||
@@ -43,13 +43,13 @@
|
||||
(is (money/equal-to (utils/total-raw-balance-in-all-chains balances-per-chain)
|
||||
(money/bignumber 600))))))
|
||||
|
||||
(deftest test-extract-exponent
|
||||
(deftest extract-exponent-test
|
||||
(testing "extract-exponent function"
|
||||
(is (= (utils/extract-exponent "123.456") nil))
|
||||
(is (= (utils/extract-exponent "2.5e-2") "2"))
|
||||
(is (= (utils/extract-exponent "4.567e-10") "10"))))
|
||||
|
||||
(deftest test-calc-max-crypto-decimals
|
||||
(deftest calc-max-crypto-decimals-test
|
||||
(testing "calc-max-crypto-decimals function"
|
||||
(is (= (utils/calc-max-crypto-decimals 0.00323) 2))
|
||||
(is (= (utils/calc-max-crypto-decimals 0.00123) 3))
|
||||
@@ -57,7 +57,7 @@
|
||||
(is (= (utils/calc-max-crypto-decimals 2.23e-6) 5))
|
||||
(is (= (utils/calc-max-crypto-decimals 1.13e-6) 6))))
|
||||
|
||||
(deftest test-get-standard-crypto-format
|
||||
(deftest get-standard-crypto-format-test
|
||||
(testing "get-standard-crypto-format function"
|
||||
(let [market-values-per-currency {:usd {:price 100}}
|
||||
token-units (money/bignumber 0.005)]
|
||||
@@ -70,7 +70,7 @@
|
||||
token-units)
|
||||
"<2")))))
|
||||
|
||||
(deftest test-calculate-total-token-balance
|
||||
(deftest calculate-total-token-balance-test
|
||||
(testing "calculate-total-token-balance function"
|
||||
(let [token {:balances-per-chain {1 {:raw-balance (money/bignumber 100)}
|
||||
10 {:raw-balance (money/bignumber 200)}
|
||||
@@ -78,7 +78,7 @@
|
||||
:decimals 2}]
|
||||
(is (money/equal-to (utils/calculate-total-token-balance token) 6.0)))))
|
||||
|
||||
(deftest test-get-account-by-address
|
||||
(deftest get-account-by-address-test
|
||||
(testing "get-account-by-address function"
|
||||
(let [accounts [{:address "0x123"}
|
||||
{:address "0x456"}
|
||||
@@ -92,7 +92,7 @@
|
||||
address-to-find "0x999"]
|
||||
(is (= (utils/get-account-by-address accounts address-to-find) nil)))))
|
||||
|
||||
(deftest test-get-wallet-qr
|
||||
(deftest get-wallet-qr-test
|
||||
(testing "Test get-wallet-qr function"
|
||||
(let [wallet-multichain {:wallet-type :multichain
|
||||
:selected-networks [:ethereum :optimism]
|
||||
@@ -107,7 +107,7 @@
|
||||
(is (= (utils/get-wallet-qr wallet-singlechain)
|
||||
"x000")))))
|
||||
|
||||
(deftest test-prettify-percentage-change
|
||||
(deftest prettify-percentage-change-test
|
||||
(testing "prettify-percentage-change function"
|
||||
(is (= (utils/prettify-percentage-change nil) "0.00"))
|
||||
(is (= (utils/prettify-percentage-change "") "0.00"))
|
||||
|
||||
@@ -138,18 +138,11 @@
|
||||
(let [renamed-data (sort-and-rename-keypairs keypairs)]
|
||||
(cske/transform-keys csk/->kebab-case-keyword renamed-data)))
|
||||
|
||||
(defn- network-short-names->full-names
|
||||
[short-names-string]
|
||||
(->> (string/split short-names-string constants/chain-id-separator)
|
||||
(map network-utils/short-name->network)
|
||||
(remove nil?)
|
||||
set))
|
||||
|
||||
(defn- add-keys-to-saved-address
|
||||
[saved-address]
|
||||
(-> saved-address
|
||||
(assoc :network-preferences-names
|
||||
(network-short-names->full-names (:chain-short-names saved-address)))
|
||||
(network-utils/network-preference-prefix->network-names (:chain-short-names saved-address)))
|
||||
(assoc :has-ens? (not (string/blank? (:ens saved-address))))))
|
||||
|
||||
(defn rpc->saved-address
|
||||
|
||||
@@ -6,4 +6,5 @@
|
||||
:selected-networks (set constants/default-network-names)})
|
||||
|
||||
(def defaults
|
||||
{:ui {:network-filter network-filter-defaults}})
|
||||
{:ui {:network-filter network-filter-defaults
|
||||
:tokens-loading? true}})
|
||||
|
||||
@@ -2,8 +2,16 @@
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[native-module.core :as native-module]
|
||||
[promesa.core :as promesa]
|
||||
[re-frame.core :as rf]
|
||||
[taoensso.timbre :as log]))
|
||||
[status-im.common.json-rpc.events :as json-rpc]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.security.core :as security]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(defn- error-message
|
||||
[kw]
|
||||
(-> kw symbol str))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet/create-account-from-mnemonic
|
||||
@@ -17,3 +25,66 @@
|
||||
{:MnemonicPhrase phrase
|
||||
:paths paths}
|
||||
on-success))))
|
||||
|
||||
(defn validate-mnemonic
|
||||
[mnemonic]
|
||||
(-> mnemonic
|
||||
(security/safe-unmask-data)
|
||||
(native-module/validate-mnemonic)
|
||||
(promesa/then (fn [result]
|
||||
(let [{:keys [keyUID]} (transforms/json->clj result)]
|
||||
{:key-uid keyUID})))))
|
||||
|
||||
(rf/reg-fx
|
||||
:multiaccount/validate-mnemonic
|
||||
(fn [[mnemonic on-success on-error]]
|
||||
(-> (validate-mnemonic mnemonic)
|
||||
(promesa/then (fn [{:keys [key-uid]}]
|
||||
(when (fn? on-success)
|
||||
(on-success mnemonic key-uid))))
|
||||
(promesa/catch (fn [error]
|
||||
(when (and error (fn? on-error))
|
||||
(on-error error)))))))
|
||||
|
||||
(defn make-seed-phrase-fully-operable
|
||||
[mnemonic password]
|
||||
(promesa/create
|
||||
(fn [resolver rejecter]
|
||||
(json-rpc/call {:method "accounts_makeSeedPhraseKeypairFullyOperable"
|
||||
:params [(security/safe-unmask-data mnemonic)
|
||||
(-> password security/safe-unmask-data native-module/sha3)]
|
||||
:on-error (fn [error]
|
||||
(rejecter (ex-info (str error) {:error error})))
|
||||
:on-success (fn [value]
|
||||
(resolver {:value value}))}))))
|
||||
|
||||
(defn import-keypair-by-seed-phrase
|
||||
[keypair-key-uid seed-phrase password]
|
||||
(-> (validate-mnemonic seed-phrase)
|
||||
(promesa/then
|
||||
(fn [{:keys [key-uid]}]
|
||||
(if (not= keypair-key-uid key-uid)
|
||||
(promesa/rejected
|
||||
(ex-info
|
||||
(error-message :import-keypair-by-seed-phrase/import-error)
|
||||
{:hint :incorrect-seed-phrase-for-keypair}))
|
||||
(make-seed-phrase-fully-operable seed-phrase password))))
|
||||
(promesa/catch
|
||||
(fn [error]
|
||||
(promesa/rejected
|
||||
(ex-info
|
||||
(error-message :import-keypair-by-seed-phrase/import-error)
|
||||
(ex-data error)))))))
|
||||
|
||||
(rf/reg-fx
|
||||
:import-keypair-by-seed-phrase
|
||||
(fn [{:keys [keypair-key-uid seed-phrase password on-success on-error]}]
|
||||
(-> (import-keypair-by-seed-phrase keypair-key-uid seed-phrase password)
|
||||
(promesa/then (fn [_result]
|
||||
(cond
|
||||
(vector? on-success) (rf/dispatch on-success)
|
||||
(fn? on-success) (on-success))))
|
||||
(promesa/catch (fn [error]
|
||||
(cond
|
||||
(vector? on-error) (rf/dispatch (conj on-error error))
|
||||
(fn? on-error) (on-error error)))))))
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
matcher-combinators.test
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.collectible.events :as collectible-events]
|
||||
[status-im.contexts.wallet.db :as db]
|
||||
[status-im.contexts.wallet.events :as events]))
|
||||
|
||||
(def address "0x2f88d65f3cb52605a54a833ae118fb1363acccd2")
|
||||
|
||||
(deftest scan-address-success
|
||||
(deftest scan-address-success-test
|
||||
(let [db {}]
|
||||
(testing "scan-address-success"
|
||||
(let [expected-db {:wallet {:ui {:scanned-address address}}}
|
||||
@@ -17,7 +16,7 @@
|
||||
result-db (:db effects)]
|
||||
(is (match? result-db expected-db))))))
|
||||
|
||||
(deftest clean-scanned-address
|
||||
(deftest clean-scanned-address-test
|
||||
(let [db {:wallet {:ui {:scanned-address address}}}]
|
||||
(testing "clean-scanned-address"
|
||||
(let [expected-db {:wallet {:ui {:send nil
|
||||
@@ -26,7 +25,7 @@
|
||||
result-db (:db effects)]
|
||||
(is (match? result-db expected-db))))))
|
||||
|
||||
(deftest store-collectibles
|
||||
(deftest store-collectibles-test
|
||||
(testing "flush-collectibles"
|
||||
(let [collectible-1 {:collectible-data {:image-url "https://..." :animation-url "https://..."}
|
||||
:ownership [{:address "0x1"
|
||||
@@ -51,7 +50,7 @@
|
||||
|
||||
(is (match? result-db expected-db)))))
|
||||
|
||||
(deftest clear-stored-collectibles
|
||||
(deftest clear-stored-collectibles-test
|
||||
(let [db {:wallet {:accounts {"0x1" {:collectibles [{:id 1} {:id 2}]}
|
||||
"0x2" {"some other stuff" "with any value"
|
||||
:collectibles [{:id 3}]}
|
||||
@@ -65,7 +64,7 @@
|
||||
|
||||
(is (match? result-db expected-db))))))
|
||||
|
||||
(deftest store-last-collectible-details
|
||||
(deftest store-last-collectible-details-test
|
||||
(testing "store-last-collectible-details"
|
||||
(let [db {:wallet {}}
|
||||
last-collectible {:description "Pandaria"
|
||||
@@ -77,15 +76,17 @@
|
||||
result-db (:db effects)]
|
||||
(is (match? result-db expected-db)))))
|
||||
|
||||
(deftest reset-selected-networks
|
||||
(deftest reset-selected-networks-test
|
||||
(testing "reset-selected-networks"
|
||||
(let [db {:wallet {}}
|
||||
expected-db {:wallet db/defaults}
|
||||
expected-db {:wallet {:ui {:network-filter {:selector-state :default
|
||||
:selected-networks
|
||||
(set constants/default-network-names)}}}}
|
||||
effects (events/reset-selected-networks {:db db})
|
||||
result-db (:db effects)]
|
||||
(is (match? result-db expected-db)))))
|
||||
|
||||
(deftest update-selected-networks
|
||||
(deftest update-selected-networks-test
|
||||
(testing "update-selected-networks"
|
||||
(let [db {:wallet {:ui {:network-filter {:selected-networks
|
||||
#{constants/optimism-network-name}
|
||||
@@ -101,7 +102,9 @@
|
||||
(is (match? result-db expected-db))))
|
||||
|
||||
(testing "update-selected-networks > if all networks is already selected, update to incoming network"
|
||||
(let [db {:wallet db/defaults}
|
||||
(let [db {:wallet {:ui {:network-filter {:selector-state :default
|
||||
:selected-networks
|
||||
(set constants/default-network-names)}}}}
|
||||
network-name constants/arbitrum-network-name
|
||||
expected-db {:wallet {:ui {:network-filter {:selected-networks #{network-name}
|
||||
:selector-state :changed}}}}
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
:on-press #(rf/dispatch [:navigate-to :screen/wallet.create-account])}
|
||||
{:icon :i/reveal
|
||||
:accessibility-label :add-a-contact
|
||||
:label (i18n/label :t/add-address)
|
||||
:sub-label (i18n/label :t/add-address-description)
|
||||
:label (i18n/label :t/add-address-to-watch)
|
||||
:sub-label (i18n/label :t/add-address-to-watch-description)
|
||||
:on-press #(rf/dispatch [:navigate-to :screen/wallet.add-address-to-watch])
|
||||
:add-divider? true}]]])
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
(ns status-im.contexts.wallet.save-address.style)
|
||||
|
||||
(def title-input-container
|
||||
{:padding-horizontal 20
|
||||
:padding-top 12
|
||||
:padding-bottom 16})
|
||||
|
||||
(def account-avatar-container
|
||||
{:padding-horizontal 20
|
||||
:padding-top 12})
|
||||
|
||||
(def color-picker-top-divider
|
||||
{:margin-bottom 12})
|
||||
|
||||
(def color-picker-container
|
||||
{:padding-vertical 12})
|
||||
|
||||
(def section-container
|
||||
{:padding-horizontal 20
|
||||
:padding-bottom 4})
|
||||
|
||||
(def color-picker
|
||||
{:padding-horizontal 20
|
||||
:padding-top 12})
|
||||
|
||||
(def color-picker-bottom-divider
|
||||
{:padding-top 8
|
||||
:padding-bottom 12})
|
||||
|
||||
(def save-address-button
|
||||
{:padding-horizontal 20})
|
||||
|
||||
(def data-item
|
||||
{:margin-horizontal 20
|
||||
:padding-vertical 8})
|
||||
|
||||
(def address-container
|
||||
{:padding-top 8
|
||||
:padding-bottom 12})
|
||||
@@ -1,90 +0,0 @@
|
||||
(ns status-im.contexts.wallet.save-address.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.contexts.wallet.save-address.style :as style]
|
||||
[status-im.contexts.wallet.sheets.network-preferences.view
|
||||
:as network-preferences]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- address-view
|
||||
[]
|
||||
(let [network-details (rf/sub [:wallet/network-preference-details])
|
||||
address (rf/sub [:wallet/wallet-send-to-address])]
|
||||
[rn/view {:style style/address-container}
|
||||
[quo/data-item
|
||||
{:status :default
|
||||
:size :default
|
||||
:subtitle-type :default
|
||||
:label :none
|
||||
:blur? false
|
||||
:icon-right? true
|
||||
:right-icon :i/advanced
|
||||
:card? true
|
||||
:title (i18n/label :t/address)
|
||||
:custom-subtitle (rn/use-callback
|
||||
(fn [] [quo/address-text
|
||||
{:networks network-details
|
||||
:address address
|
||||
:format :long}]))
|
||||
:on-press (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[network-preferences/view
|
||||
{:on-save (fn [])}])}])))
|
||||
:container-style style/data-item}]]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [[address-label set-address-label] (rn/use-state "")
|
||||
[address-color set-address-color] (rn/use-state :blue)
|
||||
placeholder (i18n/label :t/address-name)]
|
||||
[floating-button-page/view
|
||||
{:footer-container-padding 0
|
||||
:header [quo/page-nav
|
||||
{:type :no-title
|
||||
:background :blur
|
||||
:icon-name :i/close
|
||||
:on-press (rn/use-callback #(rf/dispatch [:navigate-back]))
|
||||
:accessibility-label :save-address-top-bar}]
|
||||
:footer [quo/button
|
||||
{:accessibility-label :save-address-button
|
||||
:type :primary
|
||||
:container-style style/save-address-button}
|
||||
(i18n/label :t/save-address)]
|
||||
:customization-color address-color
|
||||
:gradient-cover? true}
|
||||
[rn/view
|
||||
{:style style/account-avatar-container}
|
||||
[quo/user-avatar
|
||||
{:full-name (if (string/blank? address-label)
|
||||
placeholder
|
||||
address-label)
|
||||
:customization-color address-color
|
||||
:size :big}]]
|
||||
[quo/title-input
|
||||
{:blur? true
|
||||
:auto-focus true
|
||||
:max-length 24
|
||||
:size :heading-1
|
||||
:placeholder placeholder
|
||||
:default-value address-label
|
||||
:on-change-text set-address-label
|
||||
:customization-color address-color
|
||||
:container-style style/title-input-container}]
|
||||
[quo/divider-line {:container-style style/color-picker-top-divider}]
|
||||
[quo/section-label
|
||||
{:section (i18n/label :t/colour)
|
||||
:container-style style/section-container}]
|
||||
[quo/color-picker
|
||||
{:default-selected address-color
|
||||
:on-change set-address-color
|
||||
:container-style style/color-picker}]
|
||||
[quo/divider-line {:container-style style/color-picker-bottom-divider}]
|
||||
[address-view]]))
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user